Commit a079e297 authored by Sam Lantinga's avatar Sam Lantinga

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
parent 7ddaf6cf
...@@ -32,18 +32,6 @@ static char rcsid = ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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 = ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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); ...@@ -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) ...@@ -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;
...@@ -759,6 +761,18 @@ static SDL_Surface *FB_SetVideoMode(_THIS, SDL_Surface *current, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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; ...@@ -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,16 +1009,13 @@ static void FB_FreeHWSurface(_THIS, SDL_Surface *surface) ...@@ -970,16 +1009,13 @@ 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 */ /* Add the memory back to the total */
#ifdef FBCON_DEBUG #ifdef DGA_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;
...@@ -987,7 +1023,7 @@ static void FB_FreeHWSurface(_THIS, SDL_Surface *surface) ...@@ -987,7 +1023,7 @@ static void FB_FreeHWSurface(_THIS, SDL_Surface *surface)
/* 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;
...@@ -999,7 +1035,7 @@ static void FB_FreeHWSurface(_THIS, SDL_Surface *surface) ...@@ -999,7 +1035,7 @@ static void FB_FreeHWSurface(_THIS, SDL_Surface *surface)
free(freeable); free(freeable);
} }
if ( bucket->prev && ! bucket->prev->used ) { if ( bucket->prev && ! bucket->prev->used ) {
#ifdef FBCON_DEBUG #ifdef DGA_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;
...@@ -1010,18 +1046,27 @@ static void FB_FreeHWSurface(_THIS, SDL_Surface *surface) ...@@ -1010,18 +1046,27 @@ static void FB_FreeHWSurface(_THIS, SDL_Surface *surface)
} }
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) ...@@ -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 = ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment