Commit a3b1aa2d authored by Sam Lantinga's avatar Sam Lantinga

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 :-)

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%40271
parent 84a88103
...@@ -44,109 +44,92 @@ static int (*X_handler)(Display *, XErrorEvent *) = NULL; ...@@ -44,109 +44,92 @@ static int (*X_handler)(Display *, XErrorEvent *) = NULL;
static int shm_errhandler(Display *d, XErrorEvent *e) static int shm_errhandler(Display *d, XErrorEvent *e)
{ {
if ( e->error_code == BadAccess ) { if ( e->error_code == BadAccess ) {
++shm_error; shm_error = 1;
return(0); return(0);
} else } else
return(X_handler(d,e)); 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 if(!use_mitshm)
screen->pixels = malloc(screen->h*screen->pitch); return;
#else shminfo.shmid = shmget(IPC_PRIVATE, screen->h*screen->pitch,
/* Allocate shared memory if possible */ IPC_CREAT | 0777);
if ( use_mitshm ) { if ( shminfo.shmid >= 0 ) {
shminfo.shmid = shmget(IPC_PRIVATE, screen->h*screen->pitch, shminfo.shmaddr = (char *)shmat(shminfo.shmid, 0, 0);
IPC_CREAT|0777); shminfo.readOnly = False;
if ( shminfo.shmid >= 0 ) { if ( shminfo.shmaddr != (char *)-1 ) {
shminfo.shmaddr = (char *)shmat(shminfo.shmid, 0, 0); shm_error = False;
shminfo.readOnly = False; X_handler = XSetErrorHandler(shm_errhandler);
if ( shminfo.shmaddr != (char *)-1 ) { XShmAttach(SDL_Display, &shminfo);
shm_error = False; XSync(SDL_Display, True);
X_handler = XSetErrorHandler(shm_errhandler); XSetErrorHandler(X_handler);
XShmAttach(SDL_Display, &shminfo); if (shm_error)
XSync(SDL_Display, True); shmdt(shminfo.shmaddr);
XSetErrorHandler(X_handler);
if ( shm_error == True )
shmdt(shminfo.shmaddr);
} else {
shm_error = True;
}
shmctl(shminfo.shmid, IPC_RMID, NULL);
} else { } else {
shm_error = True; shm_error = True;
} }
if ( shm_error == True ) shmctl(shminfo.shmid, IPC_RMID, NULL);
use_mitshm = 0;
}
if ( use_mitshm ) {
screen->pixels = shminfo.shmaddr;
} else { } else {
screen->pixels = malloc(screen->h*screen->pitch); shm_error = True;
}
#endif /* NO_SHARED_MEMORY */
if ( screen->pixels == NULL ) {
SDL_OutOfMemory();
return(-1);
} }
if ( shm_error )
use_mitshm = 0;
if ( use_mitshm )
screen->pixels = shminfo.shmaddr;
}
#endif /* ! NO_SHARED_MEMORY */
#ifdef NO_SHARED_MEMORY /* Various screen update functions available */
{ static void X11_NormalUpdate(_THIS, int numrects, SDL_Rect *rects);
int bpp = screen->format->BytesPerPixel; static void X11_MITSHMUpdate(_THIS, int numrects, SDL_Rect *rects);
SDL_Ximage = XCreateImage(SDL_Display, SDL_Visual,
this->hidden->depth, ZPixmap, 0, int X11_SetupImage(_THIS, SDL_Surface *screen)
(char *)screen->pixels, {
screen->w, screen->h, #ifndef NO_SHARED_MEMORY
(bpp == 3) ? 32 : bpp * 8, try_mitshm(this, screen);
0); if(use_mitshm) {
}
#else
if ( use_mitshm ) {
SDL_Ximage = XShmCreateImage(SDL_Display, SDL_Visual, SDL_Ximage = XShmCreateImage(SDL_Display, SDL_Visual,
this->hidden->depth, ZPixmap, this->hidden->depth, ZPixmap,
shminfo.shmaddr, &shminfo, shminfo.shmaddr, &shminfo,
screen->w, screen->h); screen->w, screen->h);
} else { if(!SDL_Ximage) {
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); XShmDetach(SDL_Display, &shminfo);
XSync(SDL_Display, False); XSync(SDL_Display, False);
shmdt(shminfo.shmaddr); shmdt(shminfo.shmaddr);
screen->pixels = NULL; 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; 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; this->UpdateRects = X11_NormalUpdate;
} }
#endif screen->pitch = SDL_Ximage->bytes_per_line;
return(0); return(0);
error:
SDL_SetError("Couldn't create XImage");
return 1;
} }
void X11_DestroyImage(_THIS, SDL_Surface *screen) void X11_DestroyImage(_THIS, SDL_Surface *screen)
...@@ -250,115 +233,21 @@ int X11_FlipHWSurface(_THIS, SDL_Surface *surface) ...@@ -250,115 +233,21 @@ int X11_FlipHWSurface(_THIS, SDL_Surface *surface)
return(0); 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) static void X11_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
{ {
int i; int i;
/* Check for endian-swapped X server, swap if necessary (VERY slow!) */ for (i = 0; i < numrects; ++i) {
if ( swap_pixels && if ( rects[i].w == 0 || rects[i].h == 0 ) { /* Clipped? */
((this->screen->format->BytesPerPixel%2) == 0) ) { continue;
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);
}
} 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 ) { if ( SDL_VideoSurface->flags & SDL_ASYNCBLIT ) {
XFlush(GFX_Display); XFlush(GFX_Display);
++blit_queued; blit_queued = 1;
} else { } else {
XSync(GFX_Display, False); XSync(GFX_Display, False);
} }
...@@ -370,7 +259,7 @@ static void X11_MITSHMUpdate(_THIS, int numrects, SDL_Rect *rects) ...@@ -370,7 +259,7 @@ static void X11_MITSHMUpdate(_THIS, int numrects, SDL_Rect *rects)
int i; int i;
for ( i=0; i<numrects; ++i ) { for ( i=0; i<numrects; ++i ) {
if ( ! rects[i].w ) { /* Clipped? */ if ( rects[i].w == 0 || rects[i].h == 0 ) { /* Clipped? */
continue; continue;
} }
XShmPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage, XShmPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage,
...@@ -380,7 +269,7 @@ static void X11_MITSHMUpdate(_THIS, int numrects, SDL_Rect *rects) ...@@ -380,7 +269,7 @@ static void X11_MITSHMUpdate(_THIS, int numrects, SDL_Rect *rects)
} }
if ( SDL_VideoSurface->flags & SDL_ASYNCBLIT ) { if ( SDL_VideoSurface->flags & SDL_ASYNCBLIT ) {
XFlush(GFX_Display); XFlush(GFX_Display);
++blit_queued; blit_queued = 1;
} else { } else {
XSync(GFX_Display, False); XSync(GFX_Display, False);
} }
...@@ -419,21 +308,11 @@ void X11_RefreshDisplay(_THIS) ...@@ -419,21 +308,11 @@ void X11_RefreshDisplay(_THIS)
XShmPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage, XShmPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage,
0, 0, 0, 0, this->screen->w, this->screen->h, 0, 0, 0, 0, this->screen->w, this->screen->h,
False); False);
} else { } else
#else
{
#endif /* ! NO_SHARED_MEMORY */ #endif /* ! NO_SHARED_MEMORY */
/* Check for endian-swapped X server, swap if necessary */ {
if ( swap_pixels && XPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage,
((this->screen->format->BytesPerPixel%2) == 0) ) { 0, 0, 0, 0, this->screen->w, this->screen->h);
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);
}
} }
XSync(SDL_Display, False); XSync(SDL_Display, False);
} }
...@@ -404,26 +404,14 @@ static int X11_VideoInit(_THIS, SDL_PixelFormat *vformat) ...@@ -404,26 +404,14 @@ static int X11_VideoInit(_THIS, SDL_PixelFormat *vformat)
/* use default screen (from $DISPLAY) */ /* use default screen (from $DISPLAY) */
SDL_Screen = DefaultScreen(SDL_Display); SDL_Screen = DefaultScreen(SDL_Display);
use_mitshm = 0;
#ifndef NO_SHARED_MEMORY #ifndef NO_SHARED_MEMORY
/* Check for MIT shared memory extension */ /* Check for MIT shared memory extension */
use_mitshm = 0;
if ( local_X11 ) { if ( local_X11 ) {
use_mitshm = XShmQueryExtension(SDL_Display); use_mitshm = XShmQueryExtension(SDL_Display);
} }
#endif /* NO_SHARED_MEMORY */ #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 */ /* Get the available video modes */
if(X11_GetVideoModes(this) < 0) if(X11_GetVideoModes(this) < 0)
return -1; return -1;
......
...@@ -85,7 +85,6 @@ struct SDL_PrivateVideoData { ...@@ -85,7 +85,6 @@ struct SDL_PrivateVideoData {
/* The variables used for displaying graphics */ /* The variables used for displaying graphics */
XImage *Ximage; /* The X image for our window */ XImage *Ximage; /* The X image for our window */
GC gc; /* The graphic context for drawing */ 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 */ /* The current width and height of the fullscreen mode */
int current_w; int current_w;
...@@ -171,7 +170,6 @@ struct SDL_PrivateVideoData { ...@@ -171,7 +170,6 @@ struct SDL_PrivateVideoData {
#define shminfo (this->hidden->shminfo) #define shminfo (this->hidden->shminfo)
#define SDL_Ximage (this->hidden->Ximage) #define SDL_Ximage (this->hidden->Ximage)
#define SDL_GC (this->hidden->gc) #define SDL_GC (this->hidden->gc)
#define swap_pixels (this->hidden->swap_pixels)
#define current_w (this->hidden->current_w) #define current_w (this->hidden->current_w)
#define current_h (this->hidden->current_h) #define current_h (this->hidden->current_h)
#define mouse_last (this->hidden->mouse_last) #define mouse_last (this->hidden->mouse_last)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment