From: "Mattias Engdeg�rd" <f91-men@nada.kth.se>
authorSam Lantinga <slouken@libsdl.org>
Fri, 18 Jan 2002 22:02:03 +0000
changeset 27037fa1484f71b
parent 269 4125b9859c71
child 271 9631db4d9ee1
From: "Mattias Engdeg�rd" <f91-men@nada.kth.se>
To: slouken@devolution.com
Subject: Re: [SDL] Question about SDL_FillRect()

I benchmarked with and without clipping UpdateRects and was unable to find
any difference on my moderately slow machine. Anyway, I haven't added
clipping in this patch, but fixed a couple of bugs and generally cleaned
up some of the X11 image code. Most importantly, UpdateRects now checks
for both zero height and width. Also, I eliminated the entire code to
byteswap X11 images since X11 can do that automatically if you ask it
nicely :-)
src/video/x11/SDL_x11image.c
src/video/x11/SDL_x11video.c
src/video/x11/SDL_x11video.h
     1.1 --- a/src/video/x11/SDL_x11image.c	Fri Jan 18 19:41:59 2002 +0000
     1.2 +++ b/src/video/x11/SDL_x11image.c	Fri Jan 18 22:02:03 2002 +0000
     1.3 @@ -44,11 +44,41 @@
     1.4  static int shm_errhandler(Display *d, XErrorEvent *e)
     1.5  {
     1.6          if ( e->error_code == BadAccess ) {
     1.7 -        	++shm_error;
     1.8 +        	shm_error = 1;
     1.9          	return(0);
    1.10          } else
    1.11  		return(X_handler(d,e));
    1.12  }
    1.13 +
    1.14 +static void try_mitshm(_THIS, SDL_Surface *screen)
    1.15 +{
    1.16 +	if(!use_mitshm)
    1.17 +		return;
    1.18 +	shminfo.shmid = shmget(IPC_PRIVATE, screen->h*screen->pitch,
    1.19 +			       IPC_CREAT | 0777);
    1.20 +	if ( shminfo.shmid >= 0 ) {
    1.21 +		shminfo.shmaddr = (char *)shmat(shminfo.shmid, 0, 0);
    1.22 +		shminfo.readOnly = False;
    1.23 +		if ( shminfo.shmaddr != (char *)-1 ) {
    1.24 +			shm_error = False;
    1.25 +			X_handler = XSetErrorHandler(shm_errhandler);
    1.26 +			XShmAttach(SDL_Display, &shminfo);
    1.27 +			XSync(SDL_Display, True);
    1.28 +			XSetErrorHandler(X_handler);
    1.29 +			if (shm_error)
    1.30 +				shmdt(shminfo.shmaddr);
    1.31 +		} else {
    1.32 +			shm_error = True;
    1.33 +		}
    1.34 +		shmctl(shminfo.shmid, IPC_RMID, NULL);
    1.35 +	} else {
    1.36 +		shm_error = True;
    1.37 +	}
    1.38 +	if ( shm_error )
    1.39 +		use_mitshm = 0;
    1.40 +	if ( use_mitshm )
    1.41 +		screen->pixels = shminfo.shmaddr;
    1.42 +}
    1.43  #endif /* ! NO_SHARED_MEMORY */
    1.44  
    1.45  /* Various screen update functions available */
    1.46 @@ -57,96 +87,49 @@
    1.47  
    1.48  int X11_SetupImage(_THIS, SDL_Surface *screen)
    1.49  {
    1.50 -#ifdef NO_SHARED_MEMORY
    1.51 -	screen->pixels = malloc(screen->h*screen->pitch);
    1.52 -#else
    1.53 -	/* Allocate shared memory if possible */
    1.54 -	if ( use_mitshm ) {
    1.55 -		shminfo.shmid = shmget(IPC_PRIVATE, screen->h*screen->pitch,
    1.56 -								IPC_CREAT|0777);
    1.57 -		if ( shminfo.shmid >= 0 ) {
    1.58 -			shminfo.shmaddr = (char *)shmat(shminfo.shmid, 0, 0);
    1.59 -			shminfo.readOnly = False;
    1.60 -			if ( shminfo.shmaddr != (char *)-1 ) {
    1.61 -				shm_error = False;
    1.62 -				X_handler = XSetErrorHandler(shm_errhandler);
    1.63 -				XShmAttach(SDL_Display, &shminfo);
    1.64 -				XSync(SDL_Display, True);
    1.65 -				XSetErrorHandler(X_handler);
    1.66 -				if ( shm_error == True )
    1.67 -					shmdt(shminfo.shmaddr);
    1.68 -			} else {
    1.69 -				shm_error = True;
    1.70 -			}
    1.71 -			shmctl(shminfo.shmid, IPC_RMID, NULL);
    1.72 -		} else {
    1.73 -			shm_error = True;
    1.74 +#ifndef NO_SHARED_MEMORY
    1.75 +	try_mitshm(this, screen);
    1.76 +	if(use_mitshm) {
    1.77 +		SDL_Ximage = XShmCreateImage(SDL_Display, SDL_Visual,
    1.78 +					     this->hidden->depth, ZPixmap,
    1.79 +					     shminfo.shmaddr, &shminfo, 
    1.80 +					     screen->w, screen->h);
    1.81 +		if(!SDL_Ximage) {
    1.82 +			XShmDetach(SDL_Display, &shminfo);
    1.83 +			XSync(SDL_Display, False);
    1.84 +			shmdt(shminfo.shmaddr);
    1.85 +			screen->pixels = NULL;
    1.86 +			goto error;
    1.87  		}
    1.88 -		if ( shm_error == True )
    1.89 -			use_mitshm = 0;
    1.90 +		this->UpdateRects = X11_MITSHMUpdate;
    1.91  	}
    1.92 -	if ( use_mitshm ) {
    1.93 -		screen->pixels = shminfo.shmaddr;
    1.94 -	} else {
    1.95 +#endif /* not NO_SHARED_MEMORY */
    1.96 +	if(!use_mitshm) {
    1.97 +		int bpp;
    1.98  		screen->pixels = malloc(screen->h*screen->pitch);
    1.99 -	}
   1.100 -#endif /* NO_SHARED_MEMORY */
   1.101 -	if ( screen->pixels == NULL ) {
   1.102 -		SDL_OutOfMemory();
   1.103 -		return(-1);
   1.104 -	}
   1.105 -
   1.106 -#ifdef NO_SHARED_MEMORY
   1.107 -	{
   1.108 - 	        int bpp = screen->format->BytesPerPixel;
   1.109 +		if ( screen->pixels == NULL ) {
   1.110 +			SDL_OutOfMemory();
   1.111 +			return -1;
   1.112 +		}
   1.113 + 	        bpp = screen->format->BytesPerPixel;
   1.114  		SDL_Ximage = XCreateImage(SDL_Display, SDL_Visual,
   1.115  					  this->hidden->depth, ZPixmap, 0,
   1.116  					  (char *)screen->pixels, 
   1.117  					  screen->w, screen->h,
   1.118 -					  (bpp == 3) ? 32 : bpp * 8,
   1.119 -					  0);
   1.120 -	}
   1.121 -#else
   1.122 -	if ( use_mitshm ) {
   1.123 -		SDL_Ximage = XShmCreateImage(SDL_Display, SDL_Visual,
   1.124 -					     this->hidden->depth, ZPixmap,
   1.125 -					     shminfo.shmaddr, &shminfo, 
   1.126 -					     screen->w, screen->h);
   1.127 -	} else {
   1.128 - 	        int bpp = screen->format->BytesPerPixel;
   1.129 -		SDL_Ximage = XCreateImage(SDL_Display, SDL_Visual,
   1.130 -					  this->hidden->depth, ZPixmap, 0,
   1.131 -					  (char *)screen->pixels, 
   1.132 -					  screen->w, screen->h,
   1.133 -					  (bpp == 3) ? 32 : bpp * 8,
   1.134 -					  0);
   1.135 -	}
   1.136 -#endif /* NO_SHARED_MEMORY */
   1.137 -	if ( SDL_Ximage == NULL ) {
   1.138 -		SDL_SetError("Couldn't create XImage");
   1.139 -#ifndef NO_SHARED_MEMORY
   1.140 -		if ( use_mitshm ) {
   1.141 -			XShmDetach(SDL_Display, &shminfo);
   1.142 -			XSync(SDL_Display, False);
   1.143 -			shmdt(shminfo.shmaddr);
   1.144 -			screen->pixels = NULL;
   1.145 -		}
   1.146 -#endif /* ! NO_SHARED_MEMORY */
   1.147 -		return(-1);
   1.148 +					  32, 0);
   1.149 +		if ( SDL_Ximage == NULL )
   1.150 +			goto error;
   1.151 +		/* XPutImage will convert byte sex automatically */
   1.152 +		SDL_Ximage->byte_order = (SDL_BYTEORDER == SDL_BIG_ENDIAN)
   1.153 +			                 ? MSBFirst : LSBFirst;
   1.154 +		this->UpdateRects = X11_NormalUpdate;
   1.155  	}
   1.156  	screen->pitch = SDL_Ximage->bytes_per_line;
   1.157 +	return(0);
   1.158  
   1.159 -	/* Determine what blit function to use */
   1.160 -#ifdef NO_SHARED_MEMORY
   1.161 -	this->UpdateRects = X11_NormalUpdate;
   1.162 -#else
   1.163 -	if ( use_mitshm ) {
   1.164 -		this->UpdateRects = X11_MITSHMUpdate;
   1.165 -	} else {
   1.166 -		this->UpdateRects = X11_NormalUpdate;
   1.167 -	}
   1.168 -#endif
   1.169 -	return(0);
   1.170 +error:
   1.171 +	SDL_SetError("Couldn't create XImage");
   1.172 +	return 1;
   1.173  }
   1.174  
   1.175  void X11_DestroyImage(_THIS, SDL_Surface *screen)
   1.176 @@ -250,115 +233,21 @@
   1.177  	return(0);
   1.178  }
   1.179  
   1.180 -/* Byte-swap the pixels in the display image */
   1.181 -static void X11_SwapAllPixels(SDL_Surface *screen)
   1.182 -{
   1.183 -	int x, y;
   1.184 -
   1.185 -	switch (screen->format->BytesPerPixel) {
   1.186 -	    case 2: {
   1.187 -		Uint16 *spot;
   1.188 -		for ( y=0; y<screen->h; ++y ) {
   1.189 -			spot = (Uint16 *) ((Uint8 *)screen->pixels +
   1.190 -						y * screen->pitch);
   1.191 -			for ( x=0; x<screen->w; ++x, ++spot ) {
   1.192 -				*spot = SDL_Swap16(*spot);
   1.193 -			}
   1.194 -		}
   1.195 -	    }
   1.196 -	    break;
   1.197 -
   1.198 -	    case 4: {
   1.199 -		Uint32 *spot;
   1.200 -		for ( y=0; y<screen->h; ++y ) {
   1.201 -			spot = (Uint32 *) ((Uint8 *)screen->pixels +
   1.202 -						y * screen->pitch);
   1.203 -			for ( x=0; x<screen->w; ++x, ++spot ) {
   1.204 -				*spot = SDL_Swap32(*spot);
   1.205 -			}
   1.206 -		}
   1.207 -	    }
   1.208 -	    break;
   1.209 -
   1.210 -	    default:
   1.211 -		/* should never get here */
   1.212 -		break;
   1.213 -	}
   1.214 -}
   1.215 -static void X11_SwapPixels(SDL_Surface *screen, SDL_Rect *rect)
   1.216 -{
   1.217 -	int x, minx, maxx;
   1.218 -	int y, miny, maxy;
   1.219 -
   1.220 -	switch (screen->format->BytesPerPixel) {
   1.221 -	    case 2: {
   1.222 -		Uint16 *spot;
   1.223 -		minx = rect->x;
   1.224 -		maxx = rect->x + rect->w;
   1.225 -		miny = rect->y;
   1.226 -		maxy = rect->y + rect->h;
   1.227 -		for ( y=miny; y<maxy; ++y ) {
   1.228 -		    spot = (Uint16 *) ((Uint8 *)screen->pixels +
   1.229 -				       y * screen->pitch + minx * 2);
   1.230 -		    for ( x=minx; x<maxx; ++x, ++spot ) {
   1.231 -			*spot = SDL_Swap16(*spot);
   1.232 -		    }
   1.233 -		}
   1.234 -	    }
   1.235 -	    break;
   1.236 -
   1.237 -	    case 4: {
   1.238 -		Uint32 *spot;
   1.239 -		minx = rect->x;
   1.240 -		maxx = rect->x + rect->w;
   1.241 -		miny = rect->y;
   1.242 -		maxy = rect->y + rect->h;
   1.243 -		for ( y=miny; y<maxy; ++y ) {
   1.244 -		    spot = (Uint32 *) ((Uint8 *)screen->pixels +
   1.245 -				       y * screen->pitch + minx * 4);
   1.246 -		    for ( x=minx; x<maxx; ++x, ++spot ) {
   1.247 -			*spot = SDL_Swap32(*spot);
   1.248 -		    }
   1.249 -		}
   1.250 -	    }
   1.251 -	    break;
   1.252 -
   1.253 -	    default:
   1.254 -		/* should never get here */
   1.255 -		break;
   1.256 -	}
   1.257 -}
   1.258 -
   1.259  static void X11_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
   1.260  {
   1.261  	int i;
   1.262 -
   1.263 -	/* Check for endian-swapped X server, swap if necessary (VERY slow!) */
   1.264 -	if ( swap_pixels &&
   1.265 -	     ((this->screen->format->BytesPerPixel%2) == 0) ) {
   1.266 -		for ( i=0; i<numrects; ++i ) {
   1.267 -			if ( ! rects[i].w ) { /* Clipped? */
   1.268 -				continue;
   1.269 -			}
   1.270 -		        X11_SwapPixels(this->screen, rects + i);
   1.271 -			XPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage,
   1.272 -				rects[i].x, rects[i].y,
   1.273 -				rects[i].x, rects[i].y, rects[i].w, rects[i].h);
   1.274 -			X11_SwapPixels(this->screen, rects + i);
   1.275 +	
   1.276 +	for (i = 0; i < numrects; ++i) {
   1.277 +		if ( rects[i].w == 0 || rects[i].h == 0 ) { /* Clipped? */
   1.278 +			continue;
   1.279  		}
   1.280 -	} else {
   1.281 -		for ( i=0; i<numrects; ++i ) {
   1.282 -			if ( ! rects[i].w ) { /* Clipped? */
   1.283 -				continue;
   1.284 -			}
   1.285 -			XPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage,
   1.286 -				rects[i].x, rects[i].y,
   1.287 -				rects[i].x, rects[i].y, rects[i].w, rects[i].h);
   1.288 -		}
   1.289 +		XPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage,
   1.290 +			  rects[i].x, rects[i].y,
   1.291 +			  rects[i].x, rects[i].y, rects[i].w, rects[i].h);
   1.292  	}
   1.293  	if ( SDL_VideoSurface->flags & SDL_ASYNCBLIT ) {
   1.294  		XFlush(GFX_Display);
   1.295 -		++blit_queued;
   1.296 +		blit_queued = 1;
   1.297  	} else {
   1.298  		XSync(GFX_Display, False);
   1.299  	}
   1.300 @@ -370,7 +259,7 @@
   1.301  	int i;
   1.302  
   1.303  	for ( i=0; i<numrects; ++i ) {
   1.304 -		if ( ! rects[i].w ) { /* Clipped? */
   1.305 +		if ( rects[i].w == 0 || rects[i].h == 0 ) { /* Clipped? */
   1.306  			continue;
   1.307  		}
   1.308  		XShmPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage,
   1.309 @@ -380,7 +269,7 @@
   1.310  	}
   1.311  	if ( SDL_VideoSurface->flags & SDL_ASYNCBLIT ) {
   1.312  		XFlush(GFX_Display);
   1.313 -		++blit_queued;
   1.314 +		blit_queued = 1;
   1.315  	} else {
   1.316  		XSync(GFX_Display, False);
   1.317  	}
   1.318 @@ -419,21 +308,11 @@
   1.319  		XShmPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage,
   1.320  				0, 0, 0, 0, this->screen->w, this->screen->h,
   1.321  				False);
   1.322 -	} else {
   1.323 -#else
   1.324 +	} else
   1.325 +#endif /* ! NO_SHARED_MEMORY */
   1.326  	{
   1.327 -#endif /* ! NO_SHARED_MEMORY */
   1.328 -		/* Check for endian-swapped X server, swap if necessary */
   1.329 -		if ( swap_pixels &&
   1.330 -		     ((this->screen->format->BytesPerPixel%2) == 0) ) {
   1.331 -			X11_SwapAllPixels(this->screen);
   1.332 -			XPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage,
   1.333 -				0, 0, 0, 0, this->screen->w, this->screen->h);
   1.334 -			X11_SwapAllPixels(this->screen);
   1.335 -		} else {
   1.336 -			XPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage,
   1.337 -				0, 0, 0, 0, this->screen->w, this->screen->h);
   1.338 -		}
   1.339 +		XPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage,
   1.340 +			  0, 0, 0, 0, this->screen->w, this->screen->h);
   1.341  	}
   1.342  	XSync(SDL_Display, False);
   1.343  }
     2.1 --- a/src/video/x11/SDL_x11video.c	Fri Jan 18 19:41:59 2002 +0000
     2.2 +++ b/src/video/x11/SDL_x11video.c	Fri Jan 18 22:02:03 2002 +0000
     2.3 @@ -404,26 +404,14 @@
     2.4  	/* use default screen (from $DISPLAY) */
     2.5  	SDL_Screen = DefaultScreen(SDL_Display);
     2.6  
     2.7 +	use_mitshm = 0;
     2.8  #ifndef NO_SHARED_MEMORY
     2.9  	/* Check for MIT shared memory extension */
    2.10 -	use_mitshm = 0;
    2.11  	if ( local_X11 ) {
    2.12  		use_mitshm = XShmQueryExtension(SDL_Display);
    2.13  	}
    2.14  #endif /* NO_SHARED_MEMORY */
    2.15  
    2.16 -	/* See whether or not we need to swap pixels */
    2.17 -	swap_pixels = 0;
    2.18 -	if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) {
    2.19 -		if ( XImageByteOrder(SDL_Display) == MSBFirst ) {
    2.20 -			swap_pixels = 1;
    2.21 -		}
    2.22 -	} else {
    2.23 -		if ( XImageByteOrder(SDL_Display) == LSBFirst ) {
    2.24 -			swap_pixels = 1;
    2.25 -		}
    2.26 -	}
    2.27 -
    2.28  	/* Get the available video modes */
    2.29  	if(X11_GetVideoModes(this) < 0)
    2.30  	    return -1;
     3.1 --- a/src/video/x11/SDL_x11video.h	Fri Jan 18 19:41:59 2002 +0000
     3.2 +++ b/src/video/x11/SDL_x11video.h	Fri Jan 18 22:02:03 2002 +0000
     3.3 @@ -85,7 +85,6 @@
     3.4      /* The variables used for displaying graphics */
     3.5      XImage *Ximage;		/* The X image for our window */
     3.6      GC	gc;			/* The graphic context for drawing */
     3.7 -    int swap_pixels;		/* Flag: true if display is swapped endian */
     3.8  
     3.9      /* The current width and height of the fullscreen mode */
    3.10      int current_w;
    3.11 @@ -171,7 +170,6 @@
    3.12  #define shminfo			(this->hidden->shminfo)
    3.13  #define SDL_Ximage		(this->hidden->Ximage)
    3.14  #define SDL_GC			(this->hidden->gc)
    3.15 -#define swap_pixels		(this->hidden->swap_pixels)
    3.16  #define current_w		(this->hidden->current_w)
    3.17  #define current_h		(this->hidden->current_h)
    3.18  #define mouse_last		(this->hidden->mouse_last)