diff src/video/x11/SDL_x11image.c @ 270:37fa1484f71b

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 :-)
author Sam Lantinga <slouken@libsdl.org>
date Fri, 18 Jan 2002 22:02:03 +0000
parents e8157fcb3114
children f6ffac90895c
line wrap: on
line diff
--- a/src/video/x11/SDL_x11image.c	Fri Jan 18 19:41:59 2002 +0000
+++ b/src/video/x11/SDL_x11image.c	Fri Jan 18 22:02:03 2002 +0000
@@ -44,11 +44,41 @@
 static int shm_errhandler(Display *d, XErrorEvent *e)
 {
         if ( e->error_code == BadAccess ) {
-        	++shm_error;
+        	shm_error = 1;
         	return(0);
         } else
 		return(X_handler(d,e));
 }
+
+static void try_mitshm(_THIS, SDL_Surface *screen)
+{
+	if(!use_mitshm)
+		return;
+	shminfo.shmid = shmget(IPC_PRIVATE, screen->h*screen->pitch,
+			       IPC_CREAT | 0777);
+	if ( shminfo.shmid >= 0 ) {
+		shminfo.shmaddr = (char *)shmat(shminfo.shmid, 0, 0);
+		shminfo.readOnly = False;
+		if ( shminfo.shmaddr != (char *)-1 ) {
+			shm_error = False;
+			X_handler = XSetErrorHandler(shm_errhandler);
+			XShmAttach(SDL_Display, &shminfo);
+			XSync(SDL_Display, True);
+			XSetErrorHandler(X_handler);
+			if (shm_error)
+				shmdt(shminfo.shmaddr);
+		} else {
+			shm_error = True;
+		}
+		shmctl(shminfo.shmid, IPC_RMID, NULL);
+	} else {
+		shm_error = True;
+	}
+	if ( shm_error )
+		use_mitshm = 0;
+	if ( use_mitshm )
+		screen->pixels = shminfo.shmaddr;
+}
 #endif /* ! NO_SHARED_MEMORY */
 
 /* Various screen update functions available */
@@ -57,96 +87,49 @@
 
 int X11_SetupImage(_THIS, SDL_Surface *screen)
 {
-#ifdef NO_SHARED_MEMORY
-	screen->pixels = malloc(screen->h*screen->pitch);
-#else
-	/* Allocate shared memory if possible */
-	if ( use_mitshm ) {
-		shminfo.shmid = shmget(IPC_PRIVATE, screen->h*screen->pitch,
-								IPC_CREAT|0777);
-		if ( shminfo.shmid >= 0 ) {
-			shminfo.shmaddr = (char *)shmat(shminfo.shmid, 0, 0);
-			shminfo.readOnly = False;
-			if ( shminfo.shmaddr != (char *)-1 ) {
-				shm_error = False;
-				X_handler = XSetErrorHandler(shm_errhandler);
-				XShmAttach(SDL_Display, &shminfo);
-				XSync(SDL_Display, True);
-				XSetErrorHandler(X_handler);
-				if ( shm_error == True )
-					shmdt(shminfo.shmaddr);
-			} else {
-				shm_error = True;
-			}
-			shmctl(shminfo.shmid, IPC_RMID, NULL);
-		} else {
-			shm_error = True;
+#ifndef NO_SHARED_MEMORY
+	try_mitshm(this, screen);
+	if(use_mitshm) {
+		SDL_Ximage = XShmCreateImage(SDL_Display, SDL_Visual,
+					     this->hidden->depth, ZPixmap,
+					     shminfo.shmaddr, &shminfo, 
+					     screen->w, screen->h);
+		if(!SDL_Ximage) {
+			XShmDetach(SDL_Display, &shminfo);
+			XSync(SDL_Display, False);
+			shmdt(shminfo.shmaddr);
+			screen->pixels = NULL;
+			goto error;
 		}
-		if ( shm_error == True )
-			use_mitshm = 0;
-	}
-	if ( use_mitshm ) {
-		screen->pixels = shminfo.shmaddr;
-	} else {
-		screen->pixels = malloc(screen->h*screen->pitch);
+		this->UpdateRects = X11_MITSHMUpdate;
 	}
-#endif /* NO_SHARED_MEMORY */
-	if ( screen->pixels == NULL ) {
-		SDL_OutOfMemory();
-		return(-1);
-	}
-
-#ifdef NO_SHARED_MEMORY
-	{
- 	        int bpp = screen->format->BytesPerPixel;
+#endif /* not NO_SHARED_MEMORY */
+	if(!use_mitshm) {
+		int bpp;
+		screen->pixels = malloc(screen->h*screen->pitch);
+		if ( screen->pixels == NULL ) {
+			SDL_OutOfMemory();
+			return -1;
+		}
+ 	        bpp = screen->format->BytesPerPixel;
 		SDL_Ximage = XCreateImage(SDL_Display, SDL_Visual,
 					  this->hidden->depth, ZPixmap, 0,
 					  (char *)screen->pixels, 
 					  screen->w, screen->h,
-					  (bpp == 3) ? 32 : bpp * 8,
-					  0);
-	}
-#else
-	if ( use_mitshm ) {
-		SDL_Ximage = XShmCreateImage(SDL_Display, SDL_Visual,
-					     this->hidden->depth, ZPixmap,
-					     shminfo.shmaddr, &shminfo, 
-					     screen->w, screen->h);
-	} else {
- 	        int bpp = screen->format->BytesPerPixel;
-		SDL_Ximage = XCreateImage(SDL_Display, SDL_Visual,
-					  this->hidden->depth, ZPixmap, 0,
-					  (char *)screen->pixels, 
-					  screen->w, screen->h,
-					  (bpp == 3) ? 32 : bpp * 8,
-					  0);
-	}
-#endif /* NO_SHARED_MEMORY */
-	if ( SDL_Ximage == NULL ) {
-		SDL_SetError("Couldn't create XImage");
-#ifndef NO_SHARED_MEMORY
-		if ( use_mitshm ) {
-			XShmDetach(SDL_Display, &shminfo);
-			XSync(SDL_Display, False);
-			shmdt(shminfo.shmaddr);
-			screen->pixels = NULL;
-		}
-#endif /* ! NO_SHARED_MEMORY */
-		return(-1);
+					  32, 0);
+		if ( SDL_Ximage == NULL )
+			goto error;
+		/* XPutImage will convert byte sex automatically */
+		SDL_Ximage->byte_order = (SDL_BYTEORDER == SDL_BIG_ENDIAN)
+			                 ? MSBFirst : LSBFirst;
+		this->UpdateRects = X11_NormalUpdate;
 	}
 	screen->pitch = SDL_Ximage->bytes_per_line;
+	return(0);
 
-	/* Determine what blit function to use */
-#ifdef NO_SHARED_MEMORY
-	this->UpdateRects = X11_NormalUpdate;
-#else
-	if ( use_mitshm ) {
-		this->UpdateRects = X11_MITSHMUpdate;
-	} else {
-		this->UpdateRects = X11_NormalUpdate;
-	}
-#endif
-	return(0);
+error:
+	SDL_SetError("Couldn't create XImage");
+	return 1;
 }
 
 void X11_DestroyImage(_THIS, SDL_Surface *screen)
@@ -250,115 +233,21 @@
 	return(0);
 }
 
-/* Byte-swap the pixels in the display image */
-static void X11_SwapAllPixels(SDL_Surface *screen)
-{
-	int x, y;
-
-	switch (screen->format->BytesPerPixel) {
-	    case 2: {
-		Uint16 *spot;
-		for ( y=0; y<screen->h; ++y ) {
-			spot = (Uint16 *) ((Uint8 *)screen->pixels +
-						y * screen->pitch);
-			for ( x=0; x<screen->w; ++x, ++spot ) {
-				*spot = SDL_Swap16(*spot);
-			}
-		}
-	    }
-	    break;
-
-	    case 4: {
-		Uint32 *spot;
-		for ( y=0; y<screen->h; ++y ) {
-			spot = (Uint32 *) ((Uint8 *)screen->pixels +
-						y * screen->pitch);
-			for ( x=0; x<screen->w; ++x, ++spot ) {
-				*spot = SDL_Swap32(*spot);
-			}
-		}
-	    }
-	    break;
-
-	    default:
-		/* should never get here */
-		break;
-	}
-}
-static void X11_SwapPixels(SDL_Surface *screen, SDL_Rect *rect)
-{
-	int x, minx, maxx;
-	int y, miny, maxy;
-
-	switch (screen->format->BytesPerPixel) {
-	    case 2: {
-		Uint16 *spot;
-		minx = rect->x;
-		maxx = rect->x + rect->w;
-		miny = rect->y;
-		maxy = rect->y + rect->h;
-		for ( y=miny; y<maxy; ++y ) {
-		    spot = (Uint16 *) ((Uint8 *)screen->pixels +
-				       y * screen->pitch + minx * 2);
-		    for ( x=minx; x<maxx; ++x, ++spot ) {
-			*spot = SDL_Swap16(*spot);
-		    }
-		}
-	    }
-	    break;
-
-	    case 4: {
-		Uint32 *spot;
-		minx = rect->x;
-		maxx = rect->x + rect->w;
-		miny = rect->y;
-		maxy = rect->y + rect->h;
-		for ( y=miny; y<maxy; ++y ) {
-		    spot = (Uint32 *) ((Uint8 *)screen->pixels +
-				       y * screen->pitch + minx * 4);
-		    for ( x=minx; x<maxx; ++x, ++spot ) {
-			*spot = SDL_Swap32(*spot);
-		    }
-		}
-	    }
-	    break;
-
-	    default:
-		/* should never get here */
-		break;
-	}
-}
-
 static void X11_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
 {
 	int i;
-
-	/* Check for endian-swapped X server, swap if necessary (VERY slow!) */
-	if ( swap_pixels &&
-	     ((this->screen->format->BytesPerPixel%2) == 0) ) {
-		for ( i=0; i<numrects; ++i ) {
-			if ( ! rects[i].w ) { /* Clipped? */
-				continue;
-			}
-		        X11_SwapPixels(this->screen, rects + i);
-			XPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage,
-				rects[i].x, rects[i].y,
-				rects[i].x, rects[i].y, rects[i].w, rects[i].h);
-			X11_SwapPixels(this->screen, rects + i);
+	
+	for (i = 0; i < numrects; ++i) {
+		if ( rects[i].w == 0 || rects[i].h == 0 ) { /* Clipped? */
+			continue;
 		}
-	} else {
-		for ( i=0; i<numrects; ++i ) {
-			if ( ! rects[i].w ) { /* Clipped? */
-				continue;
-			}
-			XPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage,
-				rects[i].x, rects[i].y,
-				rects[i].x, rects[i].y, rects[i].w, rects[i].h);
-		}
+		XPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage,
+			  rects[i].x, rects[i].y,
+			  rects[i].x, rects[i].y, rects[i].w, rects[i].h);
 	}
 	if ( SDL_VideoSurface->flags & SDL_ASYNCBLIT ) {
 		XFlush(GFX_Display);
-		++blit_queued;
+		blit_queued = 1;
 	} else {
 		XSync(GFX_Display, False);
 	}
@@ -370,7 +259,7 @@
 	int i;
 
 	for ( i=0; i<numrects; ++i ) {
-		if ( ! rects[i].w ) { /* Clipped? */
+		if ( rects[i].w == 0 || rects[i].h == 0 ) { /* Clipped? */
 			continue;
 		}
 		XShmPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage,
@@ -380,7 +269,7 @@
 	}
 	if ( SDL_VideoSurface->flags & SDL_ASYNCBLIT ) {
 		XFlush(GFX_Display);
-		++blit_queued;
+		blit_queued = 1;
 	} else {
 		XSync(GFX_Display, False);
 	}
@@ -419,21 +308,11 @@
 		XShmPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage,
 				0, 0, 0, 0, this->screen->w, this->screen->h,
 				False);
-	} else {
-#else
-	{
+	} else
 #endif /* ! NO_SHARED_MEMORY */
-		/* Check for endian-swapped X server, swap if necessary */
-		if ( swap_pixels &&
-		     ((this->screen->format->BytesPerPixel%2) == 0) ) {
-			X11_SwapAllPixels(this->screen);
-			XPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage,
-				0, 0, 0, 0, this->screen->w, this->screen->h);
-			X11_SwapAllPixels(this->screen);
-		} else {
-			XPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage,
-				0, 0, 0, 0, this->screen->w, this->screen->h);
-		}
+	{
+		XPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage,
+			  0, 0, 0, 0, this->screen->w, this->screen->h);
 	}
 	XSync(SDL_Display, False);
 }