# HG changeset patch # User Sam Lantinga # Date 1011391323 0 # Node ID 37fa1484f71bd0b04f6580531e38d7a6d8bca79d # Parent 4125b9859c7193e73c4c4617f568aadf9b91eddc 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 :-) diff -r 4125b9859c71 -r 37fa1484f71b src/video/x11/SDL_x11image.c --- 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; 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); + + for (i = 0; i < numrects; ++i) { + if ( rects[i].w == 0 || rects[i].h == 0 ) { /* Clipped? */ + continue; } - } else { - for ( i=0; iflags & SDL_ASYNCBLIT ) { XFlush(GFX_Display); - ++blit_queued; + blit_queued = 1; } else { XSync(GFX_Display, False); } @@ -370,7 +259,7 @@ 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 @@ 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 -r 4125b9859c71 -r 37fa1484f71b src/video/x11/SDL_x11video.c --- a/src/video/x11/SDL_x11video.c Fri Jan 18 19:41:59 2002 +0000 +++ b/src/video/x11/SDL_x11video.c Fri Jan 18 22:02:03 2002 +0000 @@ -404,26 +404,14 @@ /* 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 -r 4125b9859c71 -r 37fa1484f71b src/video/x11/SDL_x11video.h --- a/src/video/x11/SDL_x11video.h Fri Jan 18 19:41:59 2002 +0000 +++ b/src/video/x11/SDL_x11video.h Fri Jan 18 22:02:03 2002 +0000 @@ -85,7 +85,6 @@ /* 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 @@ #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)