Merged DGA video surface handling improvements, unified locking code.
authorSam Lantinga <slouken@lokigames.com>
Fri, 13 Jul 2001 10:19:51 +0000
changeset 10663ec24e0575f
parent 105 2136ea8953f9
child 107 01fcac5d146e
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
src/video/fbcon/SDL_fb3dfx.c
src/video/fbcon/SDL_fbmatrox.c
src/video/fbcon/SDL_fbvideo.c
src/video/fbcon/SDL_fbvideo.h
     1.1 --- a/src/video/fbcon/SDL_fb3dfx.c	Fri Jul 13 10:15:52 2001 +0000
     1.2 +++ b/src/video/fbcon/SDL_fb3dfx.c	Fri Jul 13 10:19:51 2001 +0000
     1.3 @@ -32,18 +32,6 @@
     1.4  #include "3dfx_mmio.h"
     1.5  
     1.6  
     1.7 -static int LockHWSurface(_THIS, SDL_Surface *surface)
     1.8 -{
     1.9 -	if ( surface == SDL_VideoSurface ) {
    1.10 -		tdfx_waitidle();
    1.11 -	}
    1.12 -	return(0);
    1.13 -}
    1.14 -static void UnlockHWSurface(_THIS, SDL_Surface *surface)
    1.15 -{
    1.16 -	return;
    1.17 -}
    1.18 -
    1.19  /* Wait for vertical retrace */
    1.20  static void WaitVBL(_THIS)
    1.21  {
    1.22 @@ -55,6 +43,10 @@
    1.23  	while( (tdfx_in32(TDFX_STATUS) & STATUS_RETRACE) == 0 )
    1.24  		; 
    1.25  }
    1.26 +static void WaitIdle(_THIS)
    1.27 +{
    1.28 +	tdfx_waitidle();
    1.29 +}
    1.30  
    1.31  /* Sets video mem colorkey and accelerated blit function */
    1.32  static int SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key)
    1.33 @@ -86,6 +78,9 @@
    1.34  	tdfx_out32(COMMAND_2D, COMMAND_2D_FILLRECT);
    1.35  	tdfx_out32(DSTSIZE, rect->w | (rect->h << 16));
    1.36  	tdfx_out32(LAUNCH_2D, dstX | (dstY << 16));
    1.37 +
    1.38 +	FB_AddBusySurface(dst);
    1.39 +
    1.40  	return(0);
    1.41  }
    1.42  
    1.43 @@ -151,6 +146,9 @@
    1.44  	tdfx_out32(DSTXY, dstX | (dstY << 16));
    1.45  	tdfx_out32(LAUNCH_2D, srcX | (srcY << 16));
    1.46  
    1.47 +	FB_AddBusySurface(src);
    1.48 +	FB_AddBusySurface(dst);
    1.49 +
    1.50  	return(0);
    1.51  }
    1.52  
    1.53 @@ -185,9 +183,8 @@
    1.54  {
    1.55  	/* We have hardware accelerated surface functions */
    1.56  	this->CheckHWBlit = CheckHWBlit;
    1.57 -	this->LockHWSurface = LockHWSurface;
    1.58 -	this->UnlockHWSurface = UnlockHWSurface;
    1.59  	wait_vbl = WaitVBL;
    1.60 +	wait_idle = WaitIdle;
    1.61  
    1.62  	/* Reset the 3Dfx controller */
    1.63  	tdfx_out32(BRESERROR0, 0);
     2.1 --- a/src/video/fbcon/SDL_fbmatrox.c	Fri Jul 13 10:15:52 2001 +0000
     2.2 +++ b/src/video/fbcon/SDL_fbmatrox.c	Fri Jul 13 10:19:51 2001 +0000
     2.3 @@ -32,18 +32,6 @@
     2.4  #include "matrox_mmio.h"
     2.5  
     2.6  
     2.7 -static int LockHWSurface(_THIS, SDL_Surface *surface)
     2.8 -{
     2.9 -	if ( surface == SDL_VideoSurface ) {
    2.10 -		mga_waitidle();
    2.11 -	}
    2.12 -	return(0);
    2.13 -}
    2.14 -static void UnlockHWSurface(_THIS, SDL_Surface *surface)
    2.15 -{
    2.16 -	return;
    2.17 -}
    2.18 -
    2.19  /* Wait for vertical retrace - taken from the XFree86 Matrox driver */
    2.20  static void WaitVBL(_THIS)
    2.21  {
    2.22 @@ -60,6 +48,10 @@
    2.23  	while ( mga_in32(0x1E20) < count )
    2.24  		;
    2.25  }
    2.26 +static void WaitIdle(_THIS)
    2.27 +{
    2.28 +	mga_waitidle();
    2.29 +}
    2.30  
    2.31  /* Sets video mem colorkey and accelerated blit function */
    2.32  static int SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key)
    2.33 @@ -91,8 +83,7 @@
    2.34  	}
    2.35  
    2.36  	/* Set up the X/Y base coordinates */
    2.37 -	dstX = 0;
    2.38 -	dstY = ((char *)dst->pixels - mapped_mem) / SDL_VideoSurface->pitch;
    2.39 +	FB_dst_to_xy(this, dst, &dstX, &dstY);
    2.40  
    2.41  	/* Adjust for the current rectangle */
    2.42  	dstX += rect->x;
    2.43 @@ -104,19 +95,6 @@
    2.44  	/* Set up the Y boundaries */
    2.45  	ydstlen = (rect->h | (dstY << 16));
    2.46  
    2.47 -#if 0	/* This old way doesn't work on the Matrox G450 */
    2.48 -	/* Set up for color fill operation */
    2.49 -	fillop = MGADWG_TRAP | MGADWG_SOLID |
    2.50 -	         MGADWG_ARZERO | MGADWG_SGNZERO | MGADWG_SHIFTZERO |
    2.51 -	         MGADWG_BFCOL | MGADWG_BLK;
    2.52 -
    2.53 -	/* Execute the operations! */
    2.54 -	mga_wait(4);
    2.55 -	mga_out32(MGAREG_FCOL, color);
    2.56 -	mga_out32(MGAREG_FXBNDRY, fxbndry);
    2.57 -	mga_out32(MGAREG_YDSTLEN, ydstlen);
    2.58 -	mga_out32(MGAREG_DWGCTL + MGAREG_EXEC, fillop);
    2.59 -#else
    2.60  	/* Set up for color fill operation */
    2.61  	fillop = MGADWG_TRAP | MGADWG_SOLID |
    2.62  	         MGADWG_ARZERO | MGADWG_SGNZERO | MGADWG_SHIFTZERO;
    2.63 @@ -127,7 +105,8 @@
    2.64  	mga_out32(MGAREG_FCOL, color);
    2.65  	mga_out32(MGAREG_FXBNDRY, fxbndry);
    2.66  	mga_out32(MGAREG_YDSTLEN + MGAREG_EXEC, ydstlen);
    2.67 -#endif
    2.68 +
    2.69 +	FB_AddBusySurface(dst);
    2.70  
    2.71  	return(0);
    2.72  }
    2.73 @@ -136,12 +115,12 @@
    2.74                         SDL_Surface *dst, SDL_Rect *dstrect)
    2.75  {
    2.76  	SDL_VideoDevice *this;
    2.77 -	int bpp;
    2.78 +	int pitch, w, h;
    2.79  	int srcX, srcY;
    2.80  	int dstX, dstY;
    2.81  	Uint32 sign;
    2.82 -	Uint32 sstart, sstop;
    2.83 -	int sskip;
    2.84 +	Uint32 start, stop;
    2.85 +	int skip;
    2.86  	Uint32 blitop;
    2.87  
    2.88  	/* FIXME: For now, only blit to display surface */
    2.89 @@ -151,16 +130,17 @@
    2.90  
    2.91  	/* Calculate source and destination base coordinates (in pixels) */
    2.92  	this = current_video;
    2.93 -	srcX= 0;	/* FIXME: Calculate this from memory offset */
    2.94 -	srcY = ((char *)src->pixels - mapped_mem) / SDL_VideoSurface->pitch;
    2.95 -	dstX = 0;	/* FIXME: Calculate this from memory offset */
    2.96 -	dstY = ((char *)dst->pixels - mapped_mem) / SDL_VideoSurface->pitch;
    2.97 +	w = dstrect->w;
    2.98 +	h = dstrect->h;
    2.99 +	FB_dst_to_xy(this, src, &srcX, &srcY);
   2.100 +	FB_dst_to_xy(this, dst, &dstX, &dstY);
   2.101  
   2.102  	/* Adjust for the current blit rectangles */
   2.103  	srcX += srcrect->x;
   2.104  	srcY += srcrect->y;
   2.105  	dstX += dstrect->x;
   2.106  	dstY += dstrect->y;
   2.107 +	pitch = dst->pitch/dst->format->BytesPerPixel;
   2.108  
   2.109  	/* Set up the blit direction (sign) flags */
   2.110  	sign = 0;
   2.111 @@ -169,19 +149,21 @@
   2.112  	}
   2.113  	if ( srcY < dstY ) {
   2.114  		sign |= 4;
   2.115 +		srcY += (h - 1);
   2.116 +		dstY += (h - 1);
   2.117  	}
   2.118  
   2.119  	/* Set up the blit source row start, end, and skip (in pixels) */
   2.120 -	bpp = src->format->BytesPerPixel;
   2.121 -	sstop = sstart = ((srcY * SDL_VideoSurface->pitch)/bpp) + srcX;
   2.122 +	stop = start = (srcY * pitch) + srcX;
   2.123  	if ( srcX < dstX ) {
   2.124 -		sstart += (dstrect->w - 1);
   2.125 +		start += (w - 1);
   2.126  	} else {
   2.127 -		sstop += (dstrect->w - 1);
   2.128 +		stop  += (w - 1);
   2.129  	}
   2.130 -	sskip = src->pitch/bpp;
   2.131  	if ( srcY < dstY ) {
   2.132 -		sskip = -sskip;
   2.133 +		skip = -pitch;
   2.134 +	} else {
   2.135 +		skip = pitch;
   2.136  	}
   2.137  
   2.138  	/* Set up the blit operation */
   2.139 @@ -209,13 +191,16 @@
   2.140  	}
   2.141  	mga_wait(7);
   2.142  	mga_out32(MGAREG_SGN, sign);
   2.143 -	mga_out32(MGAREG_AR3, sstart);
   2.144 -	mga_out32(MGAREG_AR0, sstop);
   2.145 -	mga_out32(MGAREG_AR5, sskip);
   2.146 -	mga_out32(MGAREG_FXBNDRY, (dstX | ((dstX + dstrect->w-1) << 16)));
   2.147 -	mga_out32(MGAREG_YDSTLEN, (dstY << 16) | dstrect->h);
   2.148 +	mga_out32(MGAREG_AR3, start);
   2.149 +	mga_out32(MGAREG_AR0, stop);
   2.150 +	mga_out32(MGAREG_AR5, skip);
   2.151 +	mga_out32(MGAREG_FXBNDRY, (dstX | ((dstX + w-1) << 16)));
   2.152 +	mga_out32(MGAREG_YDSTLEN, (dstY << 16) | h);
   2.153  	mga_out32(MGAREG_DWGCTL + MGAREG_EXEC, blitop);
   2.154  
   2.155 +	FB_AddBusySurface(src);
   2.156 +	FB_AddBusySurface(dst);
   2.157 +
   2.158  	return(0);
   2.159  }
   2.160  
   2.161 @@ -250,9 +235,8 @@
   2.162  {
   2.163  	/* We have hardware accelerated surface functions */
   2.164  	this->CheckHWBlit = CheckHWBlit;
   2.165 -	this->LockHWSurface = LockHWSurface;
   2.166 -	this->UnlockHWSurface = UnlockHWSurface;
   2.167  	wait_vbl = WaitVBL;
   2.168 +	wait_idle = WaitIdle;
   2.169  
   2.170  	/* The Matrox has an accelerated color fill */
   2.171  	this->info.blit_fill = 1;
     3.1 --- a/src/video/fbcon/SDL_fbvideo.c	Fri Jul 13 10:15:52 2001 +0000
     3.2 +++ b/src/video/fbcon/SDL_fbvideo.c	Fri Jul 13 10:19:51 2001 +0000
     3.3 @@ -133,13 +133,14 @@
     3.4  static void FB_VideoQuit(_THIS);
     3.5  
     3.6  /* Hardware surface functions */
     3.7 -static int FB_InitHWSurfaces(_THIS, char *base, int size);
     3.8 +static int FB_InitHWSurfaces(_THIS, SDL_Surface *screen, char *base, int size);
     3.9  static void FB_FreeHWSurfaces(_THIS);
    3.10  static int FB_AllocHWSurface(_THIS, SDL_Surface *surface);
    3.11  static int FB_LockHWSurface(_THIS, SDL_Surface *surface);
    3.12  static void FB_UnlockHWSurface(_THIS, SDL_Surface *surface);
    3.13  static void FB_FreeHWSurface(_THIS, SDL_Surface *surface);
    3.14  static void FB_WaitVBL(_THIS);
    3.15 +static void FB_WaitIdle(_THIS);
    3.16  static int FB_FlipHWSurface(_THIS, SDL_Surface *surface);
    3.17  
    3.18  /* Internal palette functions */
    3.19 @@ -191,6 +192,7 @@
    3.20  	}
    3.21  	memset(this->hidden, 0, (sizeof *this->hidden));
    3.22  	wait_vbl = FB_WaitVBL;
    3.23 +	wait_idle = FB_WaitIdle;
    3.24  	mouse_fd = -1;
    3.25  	keyboard_fd = -1;
    3.26  
    3.27 @@ -665,7 +667,7 @@
    3.28  	if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) {
    3.29  		return(NULL);
    3.30  	}
    3.31 -    current->format->palette->ncolors = 16;
    3.32 +	current->format->palette->ncolors = 16;
    3.33  
    3.34  	/* Get the fixed information about the console hardware.
    3.35  	   This is necessary since finfo.line_length changes.
    3.36 @@ -759,6 +761,18 @@
    3.37  				return(NULL);
    3.38  			}
    3.39  		}
    3.40 +	} else {
    3.41 +		int maxheight;
    3.42 +
    3.43 +		/* Figure out how much video memory is available */
    3.44 +		if ( flags & SDL_DOUBLEBUF ) {
    3.45 +			maxheight = height*2;
    3.46 +		} else {
    3.47 +			maxheight = height;
    3.48 +		}
    3.49 +		if ( vinfo.yres_virtual > maxheight ) {
    3.50 +			vinfo.yres_virtual = maxheight;
    3.51 +		}
    3.52  	}
    3.53  	cache_vinfo = vinfo;
    3.54  #ifdef FBCON_DEBUG
    3.55 @@ -803,6 +817,13 @@
    3.56  	current->pitch = finfo.line_length;
    3.57  	current->pixels = mapped_mem+mapped_offset;
    3.58  
    3.59 +	/* Set up the information for hardware surfaces */
    3.60 +	surfaces_mem = (char *)current->pixels +
    3.61 +	                        vinfo.yres_virtual*current->pitch;
    3.62 +	surfaces_len = (mapped_memlen-(surfaces_mem-mapped_mem));
    3.63 +	FB_FreeHWSurfaces(this);
    3.64 +	FB_InitHWSurfaces(this, current, surfaces_mem, surfaces_len);
    3.65 +
    3.66  	/* Let the application know we have a hardware palette */
    3.67  	switch (finfo.visual) {
    3.68  	    case FB_VISUAL_PSEUDOCOLOR:
    3.69 @@ -820,17 +841,12 @@
    3.70  			flip_address[0] = (char *)current->pixels;
    3.71  			flip_address[1] = (char *)current->pixels+
    3.72  			                          current->h*current->pitch;
    3.73 +			this->screen = current;
    3.74  			FB_FlipHWSurface(this, current);
    3.75 +			this->screen = NULL;
    3.76  		}
    3.77  	}
    3.78  
    3.79 -	/* Set up the information for hardware surfaces */
    3.80 -	surfaces_mem = (char *)current->pixels +
    3.81 -	                        vinfo.yres_virtual*current->pitch;
    3.82 -	surfaces_len = (mapped_memlen-(surfaces_mem-mapped_mem));
    3.83 -	FB_FreeHWSurfaces(this);
    3.84 -	FB_InitHWSurfaces(this, surfaces_mem, surfaces_len);
    3.85 -
    3.86  	/* Set the update rectangle function */
    3.87  	this->UpdateRects = FB_DirectUpdate;
    3.88  
    3.89 @@ -867,15 +883,36 @@
    3.90  }
    3.91  #endif
    3.92  
    3.93 -static int FB_InitHWSurfaces(_THIS, char *base, int size)
    3.94 +static int FB_InitHWSurfaces(_THIS, SDL_Surface *screen, char *base, int size)
    3.95  {
    3.96 -	surfaces.prev = NULL;
    3.97 -	surfaces.used = 0;
    3.98 -	surfaces.base = base;
    3.99 -	surfaces.size = size;
   3.100 -	surfaces.next = NULL;
   3.101 +	vidmem_bucket *bucket;
   3.102 +
   3.103  	surfaces_memtotal = size;
   3.104  	surfaces_memleft = size;
   3.105 +
   3.106 +	if ( surfaces_memleft > 0 ) {
   3.107 +		bucket = (vidmem_bucket *)malloc(sizeof(*bucket));
   3.108 +		if ( bucket == NULL ) {
   3.109 +			SDL_OutOfMemory();
   3.110 +			return(-1);
   3.111 +		}
   3.112 +		bucket->prev = &surfaces;
   3.113 +		bucket->used = 0;
   3.114 +		bucket->dirty = 0;
   3.115 +		bucket->base = base;
   3.116 +		bucket->size = size;
   3.117 +		bucket->next = NULL;
   3.118 +	} else {
   3.119 +		bucket = NULL;
   3.120 +	}
   3.121 +
   3.122 +	surfaces.prev = NULL;
   3.123 +	surfaces.used = 1;
   3.124 +	surfaces.dirty = 0;
   3.125 +	surfaces.base = screen->pixels;
   3.126 +	surfaces.size = (unsigned int)((long)base - (long)surfaces.base);
   3.127 +	surfaces.next = bucket;
   3.128 +	screen->hwdata = (struct private_hwdata *)&surfaces;
   3.129  	return(0);
   3.130  }
   3.131  static void FB_FreeHWSurfaces(_THIS)
   3.132 @@ -956,12 +993,14 @@
   3.133  	/* Set the current bucket values and return it! */
   3.134  	bucket->used = 1;
   3.135  	bucket->size = size;
   3.136 +	bucket->dirty = 0;
   3.137  #ifdef FBCON_DEBUG
   3.138  	fprintf(stderr, "Allocated %d bytes at %p\n", bucket->size, bucket->base);
   3.139  #endif
   3.140  	surfaces_memleft -= size;
   3.141  	surface->flags |= SDL_HWSURFACE;
   3.142  	surface->pixels = bucket->base;
   3.143 +	surface->hwdata = (struct private_hwdata *)bucket;
   3.144  	return(0);
   3.145  }
   3.146  static void FB_FreeHWSurface(_THIS, SDL_Surface *surface)
   3.147 @@ -970,58 +1009,64 @@
   3.148  
   3.149  	/* Look for the bucket in the current list */
   3.150  	for ( bucket=&surfaces; bucket; bucket=bucket->next ) {
   3.151 -		if ( bucket->base == (char *)surface->pixels ) {
   3.152 +		if ( bucket == (vidmem_bucket *)surface->hwdata ) {
   3.153  			break;
   3.154  		}
   3.155  	}
   3.156 -	if ( (bucket == NULL) || ! bucket->used ) {
   3.157 -		return;
   3.158 -	}
   3.159 -
   3.160 -	/* Add the memory back to the total */
   3.161 -#ifdef FBCON_DEBUG
   3.162 +	if ( bucket && bucket->used ) {
   3.163 +		/* Add the memory back to the total */
   3.164 +#ifdef DGA_DEBUG
   3.165  	printf("Freeing bucket of %d bytes\n", bucket->size);
   3.166  #endif
   3.167 -	surfaces_memleft += bucket->size;
   3.168 +		surfaces_memleft += bucket->size;
   3.169  
   3.170 -	/* Can we merge the space with surrounding buckets? */
   3.171 -	bucket->used = 0;
   3.172 -	if ( bucket->next && ! bucket->next->used ) {
   3.173 -#ifdef FBCON_DEBUG
   3.174 +		/* Can we merge the space with surrounding buckets? */
   3.175 +		bucket->used = 0;
   3.176 +		if ( bucket->next && ! bucket->next->used ) {
   3.177 +#ifdef DGA_DEBUG
   3.178  	printf("Merging with next bucket, for %d total bytes\n", bucket->size+bucket->next->size);
   3.179  #endif
   3.180 -		freeable = bucket->next;
   3.181 -		bucket->size += bucket->next->size;
   3.182 -		bucket->next = bucket->next->next;
   3.183 -		if ( bucket->next ) {
   3.184 -			bucket->next->prev = bucket;
   3.185 +			freeable = bucket->next;
   3.186 +			bucket->size += bucket->next->size;
   3.187 +			bucket->next = bucket->next->next;
   3.188 +			if ( bucket->next ) {
   3.189 +				bucket->next->prev = bucket;
   3.190 +			}
   3.191 +			free(freeable);
   3.192  		}
   3.193 -		free(freeable);
   3.194 -	}
   3.195 -	if ( bucket->prev && ! bucket->prev->used ) {
   3.196 -#ifdef FBCON_DEBUG
   3.197 +		if ( bucket->prev && ! bucket->prev->used ) {
   3.198 +#ifdef DGA_DEBUG
   3.199  	printf("Merging with previous bucket, for %d total bytes\n", bucket->prev->size+bucket->size);
   3.200  #endif
   3.201 -		freeable = bucket;
   3.202 -		bucket->prev->size += bucket->size;
   3.203 -		bucket->prev->next = bucket->next;
   3.204 -		if ( bucket->next ) {
   3.205 -			bucket->next->prev = bucket->prev;
   3.206 +			freeable = bucket;
   3.207 +			bucket->prev->size += bucket->size;
   3.208 +			bucket->prev->next = bucket->next;
   3.209 +			if ( bucket->next ) {
   3.210 +				bucket->next->prev = bucket->prev;
   3.211 +			}
   3.212 +			free(freeable);
   3.213  		}
   3.214 -		free(freeable);
   3.215  	}
   3.216  	surface->pixels = NULL;
   3.217 +	surface->hwdata = NULL;
   3.218  }
   3.219  static int FB_LockHWSurface(_THIS, SDL_Surface *surface)
   3.220  {
   3.221 -	if ( surface == SDL_VideoSurface ) {
   3.222 +	if ( surface == this->screen ) {
   3.223  		SDL_mutexP(hw_lock);
   3.224 +		if ( FB_IsSurfaceBusy(surface) ) {
   3.225 +			FB_WaitBusySurfaces(this);
   3.226 +		}
   3.227 +	} else {
   3.228 +		if ( FB_IsSurfaceBusy(surface) ) {
   3.229 +			FB_WaitBusySurfaces(this);
   3.230 +		}
   3.231  	}
   3.232  	return(0);
   3.233  }
   3.234  static void FB_UnlockHWSurface(_THIS, SDL_Surface *surface)
   3.235  {
   3.236 -	if ( surface == SDL_VideoSurface ) {
   3.237 +	if ( surface == this->screen ) {
   3.238  		SDL_mutexV(hw_lock);
   3.239  	}
   3.240  }
   3.241 @@ -1034,10 +1079,18 @@
   3.242  	return;
   3.243  }
   3.244  
   3.245 +static void FB_WaitIdle(_THIS)
   3.246 +{
   3.247 +	return;
   3.248 +}
   3.249 +
   3.250  static int FB_FlipHWSurface(_THIS, SDL_Surface *surface)
   3.251  {
   3.252  	/* Wait for vertical retrace and then flip display */
   3.253  	cache_vinfo.yoffset = flip_page*surface->h;
   3.254 +	if ( FB_IsSurfaceBusy(this->screen) ) {
   3.255 +		FB_WaitBusySurfaces(this);
   3.256 +	}
   3.257  	wait_vbl(this);
   3.258  	if ( ioctl(console_fd, FBIOPAN_DISPLAY, &cache_vinfo) < 0 ) {
   3.259  		SDL_SetError("ioctl(FBIOPAN_DISPLAY) failed");
     4.1 --- a/src/video/fbcon/SDL_fbvideo.h	Fri Jul 13 10:15:52 2001 +0000
     4.2 +++ b/src/video/fbcon/SDL_fbvideo.h	Fri Jul 13 10:19:51 2001 +0000
     4.3 @@ -43,18 +43,13 @@
     4.4  /* This is the structure we use to keep track of video memory */
     4.5  typedef struct vidmem_bucket {
     4.6  	struct vidmem_bucket *prev;
     4.7 -	unsigned int used;
     4.8 +	int used;
     4.9 +	int dirty;
    4.10  	char *base;
    4.11  	unsigned int size;
    4.12  	struct vidmem_bucket *next;
    4.13  } vidmem_bucket;
    4.14  
    4.15 -/* Information about the location of the surface in hardware memory */
    4.16 -struct private_hwdata {
    4.17 -	int x;
    4.18 -	int y;
    4.19 -};
    4.20 -
    4.21  /* Private display data */
    4.22  struct SDL_PrivateVideoData {
    4.23  	int console_fd;
    4.24 @@ -90,6 +85,7 @@
    4.25  	SDL_mutex *hw_lock;
    4.26  
    4.27  	void (*wait_vbl)(_THIS);
    4.28 +	void (*wait_idle)(_THIS);
    4.29  };
    4.30  /* Old variable names */
    4.31  #define console_fd		(this->hidden->console_fd)
    4.32 @@ -117,6 +113,7 @@
    4.33  #define surfaces_memleft	(this->hidden->surfaces_memleft)
    4.34  #define hw_lock			(this->hidden->hw_lock)
    4.35  #define wait_vbl		(this->hidden->wait_vbl)
    4.36 +#define wait_idle		(this->hidden->wait_idle)
    4.37  
    4.38  /* Accelerator types that are supported by the driver, but are not
    4.39     necessarily in the kernel headers on the system we compile on.
    4.40 @@ -132,4 +129,39 @@
    4.41  extern void FB_SavePaletteTo(_THIS, int palette_len, __u16 *area);
    4.42  extern void FB_RestorePaletteFrom(_THIS, int palette_len, __u16 *area);
    4.43  
    4.44 +/* These are utility functions for working with video surfaces */
    4.45 +
    4.46 +static __inline__ void FB_AddBusySurface(SDL_Surface *surface)
    4.47 +{
    4.48 +	((vidmem_bucket *)surface->hwdata)->dirty = 1;
    4.49 +}
    4.50 +
    4.51 +static __inline__ int FB_IsSurfaceBusy(SDL_Surface *surface)
    4.52 +{
    4.53 +	return ((vidmem_bucket *)surface->hwdata)->dirty;
    4.54 +}
    4.55 +
    4.56 +static __inline__ void FB_WaitBusySurfaces(_THIS)
    4.57 +{
    4.58 +	vidmem_bucket *bucket;
    4.59 +
    4.60 +	/* Wait for graphic operations to complete */
    4.61 +	wait_idle(this);
    4.62 +
    4.63 +	/* Clear all surface dirty bits */
    4.64 +	for ( bucket=&surfaces; bucket; bucket=bucket->next ) {
    4.65 +		bucket->dirty = 0;
    4.66 +	}
    4.67 +}
    4.68 +
    4.69 +static __inline__ void FB_dst_to_xy(_THIS, SDL_Surface *dst, int *x, int *y)
    4.70 +{
    4.71 +	*x = (long)((char *)dst->pixels - mapped_mem)%this->screen->pitch;
    4.72 +	*y = (long)((char *)dst->pixels - mapped_mem)/this->screen->pitch;
    4.73 +	if ( dst == this->screen ) {
    4.74 +		*x += this->offset_x;
    4.75 +		*y += this->offset_y;
    4.76 +	}
    4.77 +}
    4.78 +
    4.79  #endif /* _SDL_fbvideo_h */