Merged DGA video surface handling improvements, unified locking code.
Fixed matrox blit bug where src Y less than dst Y Fixed hardware surface init when no resolution change --HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%40107
This commit is contained in:
parent
7ddaf6cf9a
commit
a079e29715
4 changed files with 179 additions and 113 deletions
|
@ -32,18 +32,6 @@ static char rcsid =
|
||||||
#include "3dfx_mmio.h"
|
#include "3dfx_mmio.h"
|
||||||
|
|
||||||
|
|
||||||
static int LockHWSurface(_THIS, SDL_Surface *surface)
|
|
||||||
{
|
|
||||||
if ( surface == SDL_VideoSurface ) {
|
|
||||||
tdfx_waitidle();
|
|
||||||
}
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
static void UnlockHWSurface(_THIS, SDL_Surface *surface)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wait for vertical retrace */
|
/* Wait for vertical retrace */
|
||||||
static void WaitVBL(_THIS)
|
static void WaitVBL(_THIS)
|
||||||
{
|
{
|
||||||
|
@ -55,6 +43,10 @@ static void WaitVBL(_THIS)
|
||||||
while( (tdfx_in32(TDFX_STATUS) & STATUS_RETRACE) == 0 )
|
while( (tdfx_in32(TDFX_STATUS) & STATUS_RETRACE) == 0 )
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
static void WaitIdle(_THIS)
|
||||||
|
{
|
||||||
|
tdfx_waitidle();
|
||||||
|
}
|
||||||
|
|
||||||
/* Sets video mem colorkey and accelerated blit function */
|
/* Sets video mem colorkey and accelerated blit function */
|
||||||
static int SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key)
|
static int SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key)
|
||||||
|
@ -86,6 +78,9 @@ static int FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color)
|
||||||
tdfx_out32(COMMAND_2D, COMMAND_2D_FILLRECT);
|
tdfx_out32(COMMAND_2D, COMMAND_2D_FILLRECT);
|
||||||
tdfx_out32(DSTSIZE, rect->w | (rect->h << 16));
|
tdfx_out32(DSTSIZE, rect->w | (rect->h << 16));
|
||||||
tdfx_out32(LAUNCH_2D, dstX | (dstY << 16));
|
tdfx_out32(LAUNCH_2D, dstX | (dstY << 16));
|
||||||
|
|
||||||
|
FB_AddBusySurface(dst);
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,6 +146,9 @@ static int HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
|
||||||
tdfx_out32(DSTXY, dstX | (dstY << 16));
|
tdfx_out32(DSTXY, dstX | (dstY << 16));
|
||||||
tdfx_out32(LAUNCH_2D, srcX | (srcY << 16));
|
tdfx_out32(LAUNCH_2D, srcX | (srcY << 16));
|
||||||
|
|
||||||
|
FB_AddBusySurface(src);
|
||||||
|
FB_AddBusySurface(dst);
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,9 +183,8 @@ void FB_3DfxAccel(_THIS, __u32 card)
|
||||||
{
|
{
|
||||||
/* We have hardware accelerated surface functions */
|
/* We have hardware accelerated surface functions */
|
||||||
this->CheckHWBlit = CheckHWBlit;
|
this->CheckHWBlit = CheckHWBlit;
|
||||||
this->LockHWSurface = LockHWSurface;
|
|
||||||
this->UnlockHWSurface = UnlockHWSurface;
|
|
||||||
wait_vbl = WaitVBL;
|
wait_vbl = WaitVBL;
|
||||||
|
wait_idle = WaitIdle;
|
||||||
|
|
||||||
/* Reset the 3Dfx controller */
|
/* Reset the 3Dfx controller */
|
||||||
tdfx_out32(BRESERROR0, 0);
|
tdfx_out32(BRESERROR0, 0);
|
||||||
|
|
|
@ -32,18 +32,6 @@ static char rcsid =
|
||||||
#include "matrox_mmio.h"
|
#include "matrox_mmio.h"
|
||||||
|
|
||||||
|
|
||||||
static int LockHWSurface(_THIS, SDL_Surface *surface)
|
|
||||||
{
|
|
||||||
if ( surface == SDL_VideoSurface ) {
|
|
||||||
mga_waitidle();
|
|
||||||
}
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
static void UnlockHWSurface(_THIS, SDL_Surface *surface)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wait for vertical retrace - taken from the XFree86 Matrox driver */
|
/* Wait for vertical retrace - taken from the XFree86 Matrox driver */
|
||||||
static void WaitVBL(_THIS)
|
static void WaitVBL(_THIS)
|
||||||
{
|
{
|
||||||
|
@ -60,6 +48,10 @@ static void WaitVBL(_THIS)
|
||||||
while ( mga_in32(0x1E20) < count )
|
while ( mga_in32(0x1E20) < count )
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
static void WaitIdle(_THIS)
|
||||||
|
{
|
||||||
|
mga_waitidle();
|
||||||
|
}
|
||||||
|
|
||||||
/* Sets video mem colorkey and accelerated blit function */
|
/* Sets video mem colorkey and accelerated blit function */
|
||||||
static int SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key)
|
static int SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key)
|
||||||
|
@ -91,8 +83,7 @@ static int FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up the X/Y base coordinates */
|
/* Set up the X/Y base coordinates */
|
||||||
dstX = 0;
|
FB_dst_to_xy(this, dst, &dstX, &dstY);
|
||||||
dstY = ((char *)dst->pixels - mapped_mem) / SDL_VideoSurface->pitch;
|
|
||||||
|
|
||||||
/* Adjust for the current rectangle */
|
/* Adjust for the current rectangle */
|
||||||
dstX += rect->x;
|
dstX += rect->x;
|
||||||
|
@ -104,19 +95,6 @@ static int FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color)
|
||||||
/* Set up the Y boundaries */
|
/* Set up the Y boundaries */
|
||||||
ydstlen = (rect->h | (dstY << 16));
|
ydstlen = (rect->h | (dstY << 16));
|
||||||
|
|
||||||
#if 0 /* This old way doesn't work on the Matrox G450 */
|
|
||||||
/* Set up for color fill operation */
|
|
||||||
fillop = MGADWG_TRAP | MGADWG_SOLID |
|
|
||||||
MGADWG_ARZERO | MGADWG_SGNZERO | MGADWG_SHIFTZERO |
|
|
||||||
MGADWG_BFCOL | MGADWG_BLK;
|
|
||||||
|
|
||||||
/* Execute the operations! */
|
|
||||||
mga_wait(4);
|
|
||||||
mga_out32(MGAREG_FCOL, color);
|
|
||||||
mga_out32(MGAREG_FXBNDRY, fxbndry);
|
|
||||||
mga_out32(MGAREG_YDSTLEN, ydstlen);
|
|
||||||
mga_out32(MGAREG_DWGCTL + MGAREG_EXEC, fillop);
|
|
||||||
#else
|
|
||||||
/* Set up for color fill operation */
|
/* Set up for color fill operation */
|
||||||
fillop = MGADWG_TRAP | MGADWG_SOLID |
|
fillop = MGADWG_TRAP | MGADWG_SOLID |
|
||||||
MGADWG_ARZERO | MGADWG_SGNZERO | MGADWG_SHIFTZERO;
|
MGADWG_ARZERO | MGADWG_SGNZERO | MGADWG_SHIFTZERO;
|
||||||
|
@ -127,7 +105,8 @@ static int FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color)
|
||||||
mga_out32(MGAREG_FCOL, color);
|
mga_out32(MGAREG_FCOL, color);
|
||||||
mga_out32(MGAREG_FXBNDRY, fxbndry);
|
mga_out32(MGAREG_FXBNDRY, fxbndry);
|
||||||
mga_out32(MGAREG_YDSTLEN + MGAREG_EXEC, ydstlen);
|
mga_out32(MGAREG_YDSTLEN + MGAREG_EXEC, ydstlen);
|
||||||
#endif
|
|
||||||
|
FB_AddBusySurface(dst);
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
@ -136,12 +115,12 @@ static int HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
|
||||||
SDL_Surface *dst, SDL_Rect *dstrect)
|
SDL_Surface *dst, SDL_Rect *dstrect)
|
||||||
{
|
{
|
||||||
SDL_VideoDevice *this;
|
SDL_VideoDevice *this;
|
||||||
int bpp;
|
int pitch, w, h;
|
||||||
int srcX, srcY;
|
int srcX, srcY;
|
||||||
int dstX, dstY;
|
int dstX, dstY;
|
||||||
Uint32 sign;
|
Uint32 sign;
|
||||||
Uint32 sstart, sstop;
|
Uint32 start, stop;
|
||||||
int sskip;
|
int skip;
|
||||||
Uint32 blitop;
|
Uint32 blitop;
|
||||||
|
|
||||||
/* FIXME: For now, only blit to display surface */
|
/* FIXME: For now, only blit to display surface */
|
||||||
|
@ -151,16 +130,17 @@ static int HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
|
||||||
|
|
||||||
/* Calculate source and destination base coordinates (in pixels) */
|
/* Calculate source and destination base coordinates (in pixels) */
|
||||||
this = current_video;
|
this = current_video;
|
||||||
srcX= 0; /* FIXME: Calculate this from memory offset */
|
w = dstrect->w;
|
||||||
srcY = ((char *)src->pixels - mapped_mem) / SDL_VideoSurface->pitch;
|
h = dstrect->h;
|
||||||
dstX = 0; /* FIXME: Calculate this from memory offset */
|
FB_dst_to_xy(this, src, &srcX, &srcY);
|
||||||
dstY = ((char *)dst->pixels - mapped_mem) / SDL_VideoSurface->pitch;
|
FB_dst_to_xy(this, dst, &dstX, &dstY);
|
||||||
|
|
||||||
/* Adjust for the current blit rectangles */
|
/* Adjust for the current blit rectangles */
|
||||||
srcX += srcrect->x;
|
srcX += srcrect->x;
|
||||||
srcY += srcrect->y;
|
srcY += srcrect->y;
|
||||||
dstX += dstrect->x;
|
dstX += dstrect->x;
|
||||||
dstY += dstrect->y;
|
dstY += dstrect->y;
|
||||||
|
pitch = dst->pitch/dst->format->BytesPerPixel;
|
||||||
|
|
||||||
/* Set up the blit direction (sign) flags */
|
/* Set up the blit direction (sign) flags */
|
||||||
sign = 0;
|
sign = 0;
|
||||||
|
@ -169,19 +149,21 @@ static int HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
|
||||||
}
|
}
|
||||||
if ( srcY < dstY ) {
|
if ( srcY < dstY ) {
|
||||||
sign |= 4;
|
sign |= 4;
|
||||||
|
srcY += (h - 1);
|
||||||
|
dstY += (h - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up the blit source row start, end, and skip (in pixels) */
|
/* Set up the blit source row start, end, and skip (in pixels) */
|
||||||
bpp = src->format->BytesPerPixel;
|
stop = start = (srcY * pitch) + srcX;
|
||||||
sstop = sstart = ((srcY * SDL_VideoSurface->pitch)/bpp) + srcX;
|
|
||||||
if ( srcX < dstX ) {
|
if ( srcX < dstX ) {
|
||||||
sstart += (dstrect->w - 1);
|
start += (w - 1);
|
||||||
} else {
|
} else {
|
||||||
sstop += (dstrect->w - 1);
|
stop += (w - 1);
|
||||||
}
|
}
|
||||||
sskip = src->pitch/bpp;
|
|
||||||
if ( srcY < dstY ) {
|
if ( srcY < dstY ) {
|
||||||
sskip = -sskip;
|
skip = -pitch;
|
||||||
|
} else {
|
||||||
|
skip = pitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up the blit operation */
|
/* Set up the blit operation */
|
||||||
|
@ -209,13 +191,16 @@ static int HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
|
||||||
}
|
}
|
||||||
mga_wait(7);
|
mga_wait(7);
|
||||||
mga_out32(MGAREG_SGN, sign);
|
mga_out32(MGAREG_SGN, sign);
|
||||||
mga_out32(MGAREG_AR3, sstart);
|
mga_out32(MGAREG_AR3, start);
|
||||||
mga_out32(MGAREG_AR0, sstop);
|
mga_out32(MGAREG_AR0, stop);
|
||||||
mga_out32(MGAREG_AR5, sskip);
|
mga_out32(MGAREG_AR5, skip);
|
||||||
mga_out32(MGAREG_FXBNDRY, (dstX | ((dstX + dstrect->w-1) << 16)));
|
mga_out32(MGAREG_FXBNDRY, (dstX | ((dstX + w-1) << 16)));
|
||||||
mga_out32(MGAREG_YDSTLEN, (dstY << 16) | dstrect->h);
|
mga_out32(MGAREG_YDSTLEN, (dstY << 16) | h);
|
||||||
mga_out32(MGAREG_DWGCTL + MGAREG_EXEC, blitop);
|
mga_out32(MGAREG_DWGCTL + MGAREG_EXEC, blitop);
|
||||||
|
|
||||||
|
FB_AddBusySurface(src);
|
||||||
|
FB_AddBusySurface(dst);
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,9 +235,8 @@ void FB_MatroxAccel(_THIS, __u32 card)
|
||||||
{
|
{
|
||||||
/* We have hardware accelerated surface functions */
|
/* We have hardware accelerated surface functions */
|
||||||
this->CheckHWBlit = CheckHWBlit;
|
this->CheckHWBlit = CheckHWBlit;
|
||||||
this->LockHWSurface = LockHWSurface;
|
|
||||||
this->UnlockHWSurface = UnlockHWSurface;
|
|
||||||
wait_vbl = WaitVBL;
|
wait_vbl = WaitVBL;
|
||||||
|
wait_idle = WaitIdle;
|
||||||
|
|
||||||
/* The Matrox has an accelerated color fill */
|
/* The Matrox has an accelerated color fill */
|
||||||
this->info.blit_fill = 1;
|
this->info.blit_fill = 1;
|
||||||
|
|
|
@ -133,13 +133,14 @@ static int FB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
|
||||||
static void FB_VideoQuit(_THIS);
|
static void FB_VideoQuit(_THIS);
|
||||||
|
|
||||||
/* Hardware surface functions */
|
/* Hardware surface functions */
|
||||||
static int FB_InitHWSurfaces(_THIS, char *base, int size);
|
static int FB_InitHWSurfaces(_THIS, SDL_Surface *screen, char *base, int size);
|
||||||
static void FB_FreeHWSurfaces(_THIS);
|
static void FB_FreeHWSurfaces(_THIS);
|
||||||
static int FB_AllocHWSurface(_THIS, SDL_Surface *surface);
|
static int FB_AllocHWSurface(_THIS, SDL_Surface *surface);
|
||||||
static int FB_LockHWSurface(_THIS, SDL_Surface *surface);
|
static int FB_LockHWSurface(_THIS, SDL_Surface *surface);
|
||||||
static void FB_UnlockHWSurface(_THIS, SDL_Surface *surface);
|
static void FB_UnlockHWSurface(_THIS, SDL_Surface *surface);
|
||||||
static void FB_FreeHWSurface(_THIS, SDL_Surface *surface);
|
static void FB_FreeHWSurface(_THIS, SDL_Surface *surface);
|
||||||
static void FB_WaitVBL(_THIS);
|
static void FB_WaitVBL(_THIS);
|
||||||
|
static void FB_WaitIdle(_THIS);
|
||||||
static int FB_FlipHWSurface(_THIS, SDL_Surface *surface);
|
static int FB_FlipHWSurface(_THIS, SDL_Surface *surface);
|
||||||
|
|
||||||
/* Internal palette functions */
|
/* Internal palette functions */
|
||||||
|
@ -191,6 +192,7 @@ static SDL_VideoDevice *FB_CreateDevice(int devindex)
|
||||||
}
|
}
|
||||||
memset(this->hidden, 0, (sizeof *this->hidden));
|
memset(this->hidden, 0, (sizeof *this->hidden));
|
||||||
wait_vbl = FB_WaitVBL;
|
wait_vbl = FB_WaitVBL;
|
||||||
|
wait_idle = FB_WaitIdle;
|
||||||
mouse_fd = -1;
|
mouse_fd = -1;
|
||||||
keyboard_fd = -1;
|
keyboard_fd = -1;
|
||||||
|
|
||||||
|
@ -665,7 +667,7 @@ static SDL_Surface *FB_SetVGA16Mode(_THIS, SDL_Surface *current,
|
||||||
if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) {
|
if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) {
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
current->format->palette->ncolors = 16;
|
current->format->palette->ncolors = 16;
|
||||||
|
|
||||||
/* Get the fixed information about the console hardware.
|
/* Get the fixed information about the console hardware.
|
||||||
This is necessary since finfo.line_length changes.
|
This is necessary since finfo.line_length changes.
|
||||||
|
@ -759,6 +761,18 @@ static SDL_Surface *FB_SetVideoMode(_THIS, SDL_Surface *current,
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
int maxheight;
|
||||||
|
|
||||||
|
/* Figure out how much video memory is available */
|
||||||
|
if ( flags & SDL_DOUBLEBUF ) {
|
||||||
|
maxheight = height*2;
|
||||||
|
} else {
|
||||||
|
maxheight = height;
|
||||||
|
}
|
||||||
|
if ( vinfo.yres_virtual > maxheight ) {
|
||||||
|
vinfo.yres_virtual = maxheight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cache_vinfo = vinfo;
|
cache_vinfo = vinfo;
|
||||||
#ifdef FBCON_DEBUG
|
#ifdef FBCON_DEBUG
|
||||||
|
@ -803,6 +817,13 @@ static SDL_Surface *FB_SetVideoMode(_THIS, SDL_Surface *current,
|
||||||
current->pitch = finfo.line_length;
|
current->pitch = finfo.line_length;
|
||||||
current->pixels = mapped_mem+mapped_offset;
|
current->pixels = mapped_mem+mapped_offset;
|
||||||
|
|
||||||
|
/* Set up the information for hardware surfaces */
|
||||||
|
surfaces_mem = (char *)current->pixels +
|
||||||
|
vinfo.yres_virtual*current->pitch;
|
||||||
|
surfaces_len = (mapped_memlen-(surfaces_mem-mapped_mem));
|
||||||
|
FB_FreeHWSurfaces(this);
|
||||||
|
FB_InitHWSurfaces(this, current, surfaces_mem, surfaces_len);
|
||||||
|
|
||||||
/* Let the application know we have a hardware palette */
|
/* Let the application know we have a hardware palette */
|
||||||
switch (finfo.visual) {
|
switch (finfo.visual) {
|
||||||
case FB_VISUAL_PSEUDOCOLOR:
|
case FB_VISUAL_PSEUDOCOLOR:
|
||||||
|
@ -820,17 +841,12 @@ static SDL_Surface *FB_SetVideoMode(_THIS, SDL_Surface *current,
|
||||||
flip_address[0] = (char *)current->pixels;
|
flip_address[0] = (char *)current->pixels;
|
||||||
flip_address[1] = (char *)current->pixels+
|
flip_address[1] = (char *)current->pixels+
|
||||||
current->h*current->pitch;
|
current->h*current->pitch;
|
||||||
|
this->screen = current;
|
||||||
FB_FlipHWSurface(this, current);
|
FB_FlipHWSurface(this, current);
|
||||||
|
this->screen = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up the information for hardware surfaces */
|
|
||||||
surfaces_mem = (char *)current->pixels +
|
|
||||||
vinfo.yres_virtual*current->pitch;
|
|
||||||
surfaces_len = (mapped_memlen-(surfaces_mem-mapped_mem));
|
|
||||||
FB_FreeHWSurfaces(this);
|
|
||||||
FB_InitHWSurfaces(this, surfaces_mem, surfaces_len);
|
|
||||||
|
|
||||||
/* Set the update rectangle function */
|
/* Set the update rectangle function */
|
||||||
this->UpdateRects = FB_DirectUpdate;
|
this->UpdateRects = FB_DirectUpdate;
|
||||||
|
|
||||||
|
@ -867,15 +883,36 @@ void FB_DumpHWSurfaces(_THIS)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int FB_InitHWSurfaces(_THIS, char *base, int size)
|
static int FB_InitHWSurfaces(_THIS, SDL_Surface *screen, char *base, int size)
|
||||||
{
|
{
|
||||||
surfaces.prev = NULL;
|
vidmem_bucket *bucket;
|
||||||
surfaces.used = 0;
|
|
||||||
surfaces.base = base;
|
|
||||||
surfaces.size = size;
|
|
||||||
surfaces.next = NULL;
|
|
||||||
surfaces_memtotal = size;
|
surfaces_memtotal = size;
|
||||||
surfaces_memleft = size;
|
surfaces_memleft = size;
|
||||||
|
|
||||||
|
if ( surfaces_memleft > 0 ) {
|
||||||
|
bucket = (vidmem_bucket *)malloc(sizeof(*bucket));
|
||||||
|
if ( bucket == NULL ) {
|
||||||
|
SDL_OutOfMemory();
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
bucket->prev = &surfaces;
|
||||||
|
bucket->used = 0;
|
||||||
|
bucket->dirty = 0;
|
||||||
|
bucket->base = base;
|
||||||
|
bucket->size = size;
|
||||||
|
bucket->next = NULL;
|
||||||
|
} else {
|
||||||
|
bucket = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
surfaces.prev = NULL;
|
||||||
|
surfaces.used = 1;
|
||||||
|
surfaces.dirty = 0;
|
||||||
|
surfaces.base = screen->pixels;
|
||||||
|
surfaces.size = (unsigned int)((long)base - (long)surfaces.base);
|
||||||
|
surfaces.next = bucket;
|
||||||
|
screen->hwdata = (struct private_hwdata *)&surfaces;
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
static void FB_FreeHWSurfaces(_THIS)
|
static void FB_FreeHWSurfaces(_THIS)
|
||||||
|
@ -956,12 +993,14 @@ surface->pitch = SDL_VideoSurface->pitch;
|
||||||
/* Set the current bucket values and return it! */
|
/* Set the current bucket values and return it! */
|
||||||
bucket->used = 1;
|
bucket->used = 1;
|
||||||
bucket->size = size;
|
bucket->size = size;
|
||||||
|
bucket->dirty = 0;
|
||||||
#ifdef FBCON_DEBUG
|
#ifdef FBCON_DEBUG
|
||||||
fprintf(stderr, "Allocated %d bytes at %p\n", bucket->size, bucket->base);
|
fprintf(stderr, "Allocated %d bytes at %p\n", bucket->size, bucket->base);
|
||||||
#endif
|
#endif
|
||||||
surfaces_memleft -= size;
|
surfaces_memleft -= size;
|
||||||
surface->flags |= SDL_HWSURFACE;
|
surface->flags |= SDL_HWSURFACE;
|
||||||
surface->pixels = bucket->base;
|
surface->pixels = bucket->base;
|
||||||
|
surface->hwdata = (struct private_hwdata *)bucket;
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
static void FB_FreeHWSurface(_THIS, SDL_Surface *surface)
|
static void FB_FreeHWSurface(_THIS, SDL_Surface *surface)
|
||||||
|
@ -970,58 +1009,64 @@ static void FB_FreeHWSurface(_THIS, SDL_Surface *surface)
|
||||||
|
|
||||||
/* Look for the bucket in the current list */
|
/* Look for the bucket in the current list */
|
||||||
for ( bucket=&surfaces; bucket; bucket=bucket->next ) {
|
for ( bucket=&surfaces; bucket; bucket=bucket->next ) {
|
||||||
if ( bucket->base == (char *)surface->pixels ) {
|
if ( bucket == (vidmem_bucket *)surface->hwdata ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( (bucket == NULL) || ! bucket->used ) {
|
if ( bucket && bucket->used ) {
|
||||||
return;
|
/* Add the memory back to the total */
|
||||||
}
|
#ifdef DGA_DEBUG
|
||||||
|
|
||||||
/* Add the memory back to the total */
|
|
||||||
#ifdef FBCON_DEBUG
|
|
||||||
printf("Freeing bucket of %d bytes\n", bucket->size);
|
printf("Freeing bucket of %d bytes\n", bucket->size);
|
||||||
#endif
|
#endif
|
||||||
surfaces_memleft += bucket->size;
|
surfaces_memleft += bucket->size;
|
||||||
|
|
||||||
/* Can we merge the space with surrounding buckets? */
|
/* Can we merge the space with surrounding buckets? */
|
||||||
bucket->used = 0;
|
bucket->used = 0;
|
||||||
if ( bucket->next && ! bucket->next->used ) {
|
if ( bucket->next && ! bucket->next->used ) {
|
||||||
#ifdef FBCON_DEBUG
|
#ifdef DGA_DEBUG
|
||||||
printf("Merging with next bucket, for %d total bytes\n", bucket->size+bucket->next->size);
|
printf("Merging with next bucket, for %d total bytes\n", bucket->size+bucket->next->size);
|
||||||
#endif
|
#endif
|
||||||
freeable = bucket->next;
|
freeable = bucket->next;
|
||||||
bucket->size += bucket->next->size;
|
bucket->size += bucket->next->size;
|
||||||
bucket->next = bucket->next->next;
|
bucket->next = bucket->next->next;
|
||||||
if ( bucket->next ) {
|
if ( bucket->next ) {
|
||||||
bucket->next->prev = bucket;
|
bucket->next->prev = bucket;
|
||||||
|
}
|
||||||
|
free(freeable);
|
||||||
}
|
}
|
||||||
free(freeable);
|
if ( bucket->prev && ! bucket->prev->used ) {
|
||||||
}
|
#ifdef DGA_DEBUG
|
||||||
if ( bucket->prev && ! bucket->prev->used ) {
|
|
||||||
#ifdef FBCON_DEBUG
|
|
||||||
printf("Merging with previous bucket, for %d total bytes\n", bucket->prev->size+bucket->size);
|
printf("Merging with previous bucket, for %d total bytes\n", bucket->prev->size+bucket->size);
|
||||||
#endif
|
#endif
|
||||||
freeable = bucket;
|
freeable = bucket;
|
||||||
bucket->prev->size += bucket->size;
|
bucket->prev->size += bucket->size;
|
||||||
bucket->prev->next = bucket->next;
|
bucket->prev->next = bucket->next;
|
||||||
if ( bucket->next ) {
|
if ( bucket->next ) {
|
||||||
bucket->next->prev = bucket->prev;
|
bucket->next->prev = bucket->prev;
|
||||||
|
}
|
||||||
|
free(freeable);
|
||||||
}
|
}
|
||||||
free(freeable);
|
|
||||||
}
|
}
|
||||||
surface->pixels = NULL;
|
surface->pixels = NULL;
|
||||||
|
surface->hwdata = NULL;
|
||||||
}
|
}
|
||||||
static int FB_LockHWSurface(_THIS, SDL_Surface *surface)
|
static int FB_LockHWSurface(_THIS, SDL_Surface *surface)
|
||||||
{
|
{
|
||||||
if ( surface == SDL_VideoSurface ) {
|
if ( surface == this->screen ) {
|
||||||
SDL_mutexP(hw_lock);
|
SDL_mutexP(hw_lock);
|
||||||
|
if ( FB_IsSurfaceBusy(surface) ) {
|
||||||
|
FB_WaitBusySurfaces(this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ( FB_IsSurfaceBusy(surface) ) {
|
||||||
|
FB_WaitBusySurfaces(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
static void FB_UnlockHWSurface(_THIS, SDL_Surface *surface)
|
static void FB_UnlockHWSurface(_THIS, SDL_Surface *surface)
|
||||||
{
|
{
|
||||||
if ( surface == SDL_VideoSurface ) {
|
if ( surface == this->screen ) {
|
||||||
SDL_mutexV(hw_lock);
|
SDL_mutexV(hw_lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1034,10 +1079,18 @@ static void FB_WaitVBL(_THIS)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void FB_WaitIdle(_THIS)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static int FB_FlipHWSurface(_THIS, SDL_Surface *surface)
|
static int FB_FlipHWSurface(_THIS, SDL_Surface *surface)
|
||||||
{
|
{
|
||||||
/* Wait for vertical retrace and then flip display */
|
/* Wait for vertical retrace and then flip display */
|
||||||
cache_vinfo.yoffset = flip_page*surface->h;
|
cache_vinfo.yoffset = flip_page*surface->h;
|
||||||
|
if ( FB_IsSurfaceBusy(this->screen) ) {
|
||||||
|
FB_WaitBusySurfaces(this);
|
||||||
|
}
|
||||||
wait_vbl(this);
|
wait_vbl(this);
|
||||||
if ( ioctl(console_fd, FBIOPAN_DISPLAY, &cache_vinfo) < 0 ) {
|
if ( ioctl(console_fd, FBIOPAN_DISPLAY, &cache_vinfo) < 0 ) {
|
||||||
SDL_SetError("ioctl(FBIOPAN_DISPLAY) failed");
|
SDL_SetError("ioctl(FBIOPAN_DISPLAY) failed");
|
||||||
|
|
|
@ -43,18 +43,13 @@ static char rcsid =
|
||||||
/* This is the structure we use to keep track of video memory */
|
/* This is the structure we use to keep track of video memory */
|
||||||
typedef struct vidmem_bucket {
|
typedef struct vidmem_bucket {
|
||||||
struct vidmem_bucket *prev;
|
struct vidmem_bucket *prev;
|
||||||
unsigned int used;
|
int used;
|
||||||
|
int dirty;
|
||||||
char *base;
|
char *base;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
struct vidmem_bucket *next;
|
struct vidmem_bucket *next;
|
||||||
} vidmem_bucket;
|
} vidmem_bucket;
|
||||||
|
|
||||||
/* Information about the location of the surface in hardware memory */
|
|
||||||
struct private_hwdata {
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Private display data */
|
/* Private display data */
|
||||||
struct SDL_PrivateVideoData {
|
struct SDL_PrivateVideoData {
|
||||||
int console_fd;
|
int console_fd;
|
||||||
|
@ -90,6 +85,7 @@ struct SDL_PrivateVideoData {
|
||||||
SDL_mutex *hw_lock;
|
SDL_mutex *hw_lock;
|
||||||
|
|
||||||
void (*wait_vbl)(_THIS);
|
void (*wait_vbl)(_THIS);
|
||||||
|
void (*wait_idle)(_THIS);
|
||||||
};
|
};
|
||||||
/* Old variable names */
|
/* Old variable names */
|
||||||
#define console_fd (this->hidden->console_fd)
|
#define console_fd (this->hidden->console_fd)
|
||||||
|
@ -117,6 +113,7 @@ struct SDL_PrivateVideoData {
|
||||||
#define surfaces_memleft (this->hidden->surfaces_memleft)
|
#define surfaces_memleft (this->hidden->surfaces_memleft)
|
||||||
#define hw_lock (this->hidden->hw_lock)
|
#define hw_lock (this->hidden->hw_lock)
|
||||||
#define wait_vbl (this->hidden->wait_vbl)
|
#define wait_vbl (this->hidden->wait_vbl)
|
||||||
|
#define wait_idle (this->hidden->wait_idle)
|
||||||
|
|
||||||
/* Accelerator types that are supported by the driver, but are not
|
/* Accelerator types that are supported by the driver, but are not
|
||||||
necessarily in the kernel headers on the system we compile on.
|
necessarily in the kernel headers on the system we compile on.
|
||||||
|
@ -132,4 +129,39 @@ struct SDL_PrivateVideoData {
|
||||||
extern void FB_SavePaletteTo(_THIS, int palette_len, __u16 *area);
|
extern void FB_SavePaletteTo(_THIS, int palette_len, __u16 *area);
|
||||||
extern void FB_RestorePaletteFrom(_THIS, int palette_len, __u16 *area);
|
extern void FB_RestorePaletteFrom(_THIS, int palette_len, __u16 *area);
|
||||||
|
|
||||||
|
/* These are utility functions for working with video surfaces */
|
||||||
|
|
||||||
|
static __inline__ void FB_AddBusySurface(SDL_Surface *surface)
|
||||||
|
{
|
||||||
|
((vidmem_bucket *)surface->hwdata)->dirty = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ int FB_IsSurfaceBusy(SDL_Surface *surface)
|
||||||
|
{
|
||||||
|
return ((vidmem_bucket *)surface->hwdata)->dirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ void FB_WaitBusySurfaces(_THIS)
|
||||||
|
{
|
||||||
|
vidmem_bucket *bucket;
|
||||||
|
|
||||||
|
/* Wait for graphic operations to complete */
|
||||||
|
wait_idle(this);
|
||||||
|
|
||||||
|
/* Clear all surface dirty bits */
|
||||||
|
for ( bucket=&surfaces; bucket; bucket=bucket->next ) {
|
||||||
|
bucket->dirty = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ void FB_dst_to_xy(_THIS, SDL_Surface *dst, int *x, int *y)
|
||||||
|
{
|
||||||
|
*x = (long)((char *)dst->pixels - mapped_mem)%this->screen->pitch;
|
||||||
|
*y = (long)((char *)dst->pixels - mapped_mem)/this->screen->pitch;
|
||||||
|
if ( dst == this->screen ) {
|
||||||
|
*x += this->offset_x;
|
||||||
|
*y += this->offset_y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _SDL_fbvideo_h */
|
#endif /* _SDL_fbvideo_h */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue