From 5a0a302d0a8e0904642be59ff3966577909b6cc5 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 18 Jan 2002 22:02:03 +0000 Subject: [PATCH] From: "Mattias Engdeg?rd" 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 | 271 ++++++++++------------------------- src/video/x11/SDL_x11video.c | 14 +- src/video/x11/SDL_x11video.h | 2 - 3 files changed, 76 insertions(+), 211 deletions(-) diff --git a/src/video/x11/SDL_x11image.c b/src/video/x11/SDL_x11image.c index d23b9a037..50cd83225 100644 --- a/src/video/x11/SDL_x11image.c +++ b/src/video/x11/SDL_x11image.c @@ -44,109 +44,92 @@ static int (*X_handler)(Display *, XErrorEvent *) = NULL; 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)); } -#endif /* ! NO_SHARED_MEMORY */ - -/* Various screen update functions available */ -static void X11_NormalUpdate(_THIS, int numrects, SDL_Rect *rects); -static void X11_MITSHMUpdate(_THIS, int numrects, SDL_Rect *rects); -int X11_SetupImage(_THIS, SDL_Surface *screen) +static void try_mitshm(_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); + 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; } - if ( shm_error == True ) - use_mitshm = 0; - } - if ( use_mitshm ) { - screen->pixels = shminfo.shmaddr; + shmctl(shminfo.shmid, IPC_RMID, NULL); } else { - screen->pixels = malloc(screen->h*screen->pitch); - } -#endif /* NO_SHARED_MEMORY */ - if ( screen->pixels == NULL ) { - SDL_OutOfMemory(); - return(-1); + shm_error = True; } + if ( shm_error ) + use_mitshm = 0; + if ( use_mitshm ) + screen->pixels = shminfo.shmaddr; +} +#endif /* ! NO_SHARED_MEMORY */ -#ifdef NO_SHARED_MEMORY - { - 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); - } -#else - if ( use_mitshm ) { +/* Various screen update functions available */ +static void X11_NormalUpdate(_THIS, int numrects, SDL_Rect *rects); +static void X11_MITSHMUpdate(_THIS, int numrects, SDL_Rect *rects); + +int X11_SetupImage(_THIS, SDL_Surface *screen) +{ +#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); - } 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 ) { + if(!SDL_Ximage) { XShmDetach(SDL_Display, &shminfo); XSync(SDL_Display, False); shmdt(shminfo.shmaddr); screen->pixels = NULL; + goto error; } -#endif /* ! NO_SHARED_MEMORY */ - return(-1); - } - screen->pitch = SDL_Ximage->bytes_per_line; - - /* Determine what blit function to use */ -#ifdef NO_SHARED_MEMORY - this->UpdateRects = X11_NormalUpdate; -#else - if ( use_mitshm ) { this->UpdateRects = X11_MITSHMUpdate; - } else { + } +#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, + 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; } -#endif + screen->pitch = SDL_Ximage->bytes_per_line; return(0); + +error: + SDL_SetError("Couldn't create XImage"); + return 1; } void X11_DestroyImage(_THIS, SDL_Surface *screen) @@ -250,115 +233,21 @@ int X11_FlipHWSurface(_THIS, SDL_Surface *surface) 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; yh; ++y ) { - spot = (Uint16 *) ((Uint8 *)screen->pixels + - y * screen->pitch); - for ( x=0; xw; ++x, ++spot ) { - *spot = SDL_Swap16(*spot); - } - } - } - break; - - case 4: { - Uint32 *spot; - for ( y=0; yh; ++y ) { - spot = (Uint32 *) ((Uint8 *)screen->pixels + - y * screen->pitch); - for ( x=0; xw; ++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; ypixels + - y * screen->pitch + minx * 2); - for ( x=minx; xx; - maxx = rect->x + rect->w; - miny = rect->y; - maxy = rect->y + rect->h; - for ( y=miny; ypixels + - y * screen->pitch + minx * 4); - for ( x=minx; xscreen->format->BytesPerPixel%2) == 0) ) { - for ( i=0; iscreen, 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); - } - } else { - for ( i=0; iflags & SDL_ASYNCBLIT ) { XFlush(GFX_Display); - ++blit_queued; + blit_queued = 1; } else { XSync(GFX_Display, False); } @@ -370,7 +259,7 @@ static void X11_MITSHMUpdate(_THIS, int numrects, SDL_Rect *rects) int i; for ( i=0; iflags & SDL_ASYNCBLIT ) { XFlush(GFX_Display); - ++blit_queued; + blit_queued = 1; } else { XSync(GFX_Display, False); } @@ -419,21 +308,11 @@ void X11_RefreshDisplay(_THIS) 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); } diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index 3bed59c8d..95550d030 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -404,26 +404,14 @@ static int X11_VideoInit(_THIS, SDL_PixelFormat *vformat) /* use default screen (from $DISPLAY) */ SDL_Screen = DefaultScreen(SDL_Display); + use_mitshm = 0; #ifndef NO_SHARED_MEMORY /* Check for MIT shared memory extension */ - use_mitshm = 0; if ( local_X11 ) { use_mitshm = XShmQueryExtension(SDL_Display); } #endif /* NO_SHARED_MEMORY */ - /* See whether or not we need to swap pixels */ - swap_pixels = 0; - if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) { - if ( XImageByteOrder(SDL_Display) == MSBFirst ) { - swap_pixels = 1; - } - } else { - if ( XImageByteOrder(SDL_Display) == LSBFirst ) { - swap_pixels = 1; - } - } - /* Get the available video modes */ if(X11_GetVideoModes(this) < 0) return -1; diff --git a/src/video/x11/SDL_x11video.h b/src/video/x11/SDL_x11video.h index 8728510fd..2122cc26c 100644 --- a/src/video/x11/SDL_x11video.h +++ b/src/video/x11/SDL_x11video.h @@ -85,7 +85,6 @@ struct SDL_PrivateVideoData { /* The variables used for displaying graphics */ XImage *Ximage; /* The X image for our window */ GC gc; /* The graphic context for drawing */ - int swap_pixels; /* Flag: true if display is swapped endian */ /* The current width and height of the fullscreen mode */ int current_w; @@ -171,7 +170,6 @@ struct SDL_PrivateVideoData { #define shminfo (this->hidden->shminfo) #define SDL_Ximage (this->hidden->Ximage) #define SDL_GC (this->hidden->gc) -#define swap_pixels (this->hidden->swap_pixels) #define current_w (this->hidden->current_w) #define current_h (this->hidden->current_h) #define mouse_last (this->hidden->mouse_last)