Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Make the SW renderer work properly by fixing support for textures wit…
Browse files Browse the repository at this point in the history
…h no alpha channels.
  • Loading branch information
sunnyps committed Jul 21, 2010
1 parent cee756f commit 3d32d92
Showing 1 changed file with 96 additions and 97 deletions.
193 changes: 96 additions & 97 deletions src/video/x11/SDL_x11render.c
Expand Up @@ -671,29 +671,36 @@ X11_DisplayModeChanged(SDL_Renderer * renderer)
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
static void
SDLMaskToXRenderMask(Uint32 sdl_mask, short *comp, short *compMask) {
(*comp) = 0;
(*compMask) = 0;
while(!(sdl_mask & 1)) {
(*comp)++;
sdl_mask >>= 1;
}
while(sdl_mask & 1) {
(*compMask) = ((*compMask) << 1) | 1;
sdl_mask >>= 1;
if (sdl_mask == 0) {
*comp = 0;
*compMask = 0;
} else {
(*comp) = 0;
(*compMask) = 0;
while(!(sdl_mask & 1)) {
(*comp)++;
sdl_mask >>= 1;
}
while(sdl_mask & 1) {
(*compMask) = ((*compMask) << 1) | 1;
sdl_mask >>= 1;
}
}
}

static XRenderPictFormat*
PixelFormatEnumToXRenderPictFormat(SDL_Renderer * renderer, Uint32 format) {
XRenderPictFormat* pict_fmt = NULL;
X11_RenderData *data = (X11_RenderData *) renderer->driverdata;

if (data->use_xrender) {

int bpp;
Uint32 Amask, Rmask, Gmask, Bmask;
SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask);

if(!SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
SDL_SetError("Unknown pixel format");
return NULL;
}
XRenderPictFormat templ;
unsigned long mask = (PictFormatType | PictFormatDepth | PictFormatRed |
PictFormatRedMask | PictFormatGreen | PictFormatGreenMask |
Expand All @@ -706,7 +713,6 @@ PixelFormatEnumToXRenderPictFormat(SDL_Renderer * renderer, Uint32 format) {
SDLMaskToXRenderMask(Rmask, &(templ.direct.red), &(templ.direct.redMask));
SDLMaskToXRenderMask(Gmask, &(templ.direct.green), &(templ.direct.greenMask));
SDLMaskToXRenderMask(Bmask, &(templ.direct.blue), &(templ.direct.blueMask));

pict_fmt = XRenderFindFormat(data->display, mask, &templ, 0);
}

Expand Down Expand Up @@ -774,83 +780,70 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
}
data->format = display->current_mode.format;
} else {
/* If Xrender support is builtin we only need to check whether
Xrender is available at runtime. If it is available there
can be no BadMatch error since Xrender takes care of that.
*/
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if (renderdata->use_xrender == SDL_FALSE) {
if (texture->format != display->current_mode.format) {
SDL_SetError("Texture format doesn't match window format");
return -1;
}
} else {
if (renderdata->use_xrender)
{
Uint32 Amask, Rmask, Gmask, Bmask;
SDL_PixelFormatEnumToMasks(texture->format, &(data->depth),
&Rmask, &Gmask, &Bmask, &Amask);
printf("%d %x %x %x %x\n", data->depth, Rmask, Gmask, Bmask, Amask);
data->visual = PixelFormatEnumToVisual(renderer, texture->format);
}
#else
/* The image/pixmap depth must be the same as the window or you
get a BadMatch error when trying to putimage or copyarea.
This BadMatch error
*/
if (texture->format != display->current_mode.format) {
SDL_SetError("Texture format doesn't match window format");
return -1;
}
else
#endif
{
if (texture->format != display->current_mode.format)
{
SDL_SetError("Texture format doesn't match window format");
return -1;
}
}
data->format = texture->format;
}
data->pitch = texture->w * SDL_BYTESPERPIXEL(data->format);
data->pitch = (data->pitch + pitch_alignmask) & ~pitch_alignmask;


if (data->yuv || texture->access == SDL_TEXTUREACCESS_STREAMING) {
#ifndef NO_SHARED_MEMORY
XShmSegmentInfo *shminfo = &data->shminfo;

shm_error = True;

if (SDL_X11_HAVE_SHM) {
shminfo->shmid =
shmget(IPC_PRIVATE, texture->h * data->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(renderdata->display, shminfo);
XSync(renderdata->display, False);
XSetErrorHandler(X_handler);
if (shm_error) {
shmdt(shminfo->shmaddr);
}
}
shmctl(shminfo->shmid, IPC_RMID, NULL);
}
}
if (!shm_error) {
data->pixels = shminfo->shmaddr;
data->pixmap =
XCreatePixmap(renderdata->display, renderdata->xwindow, texture->w,
texture->h, data->depth);
if (data->pixmap == None) {
X11_DestroyTexture(renderer, texture);
SDL_SetError("XCreatePixmap() failed");
return -1;
}
data->image =
XShmCreateImage(renderdata->display, data->visual,
data->depth, ZPixmap, shminfo->shmaddr,
data->depth, ZPixmap, NULL,
shminfo, texture->w, texture->h);

if (!data->image) {
XShmDetach(renderdata->display, shminfo);
XSync(renderdata->display, False);
shmdt(shminfo->shmaddr);
shm_error = True;
if (data->image) {
shminfo->shmid =
shmget(IPC_PRIVATE, texture->h * data->image->bytes_per_line,
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(renderdata->display, shminfo);
XSync(renderdata->display, False);
XSetErrorHandler(X_handler);
if (shm_error) {
XShmDetach(renderdata->display, shminfo);
shmdt(shminfo->shmaddr);
XDestroyImage(data->image);
XSync(renderdata->display, False);
}
else {
data->pixels = data->image->data = shminfo->shmaddr;
shmctl(shminfo->shmid, IPC_RMID, NULL);
data->pixmap =
XCreatePixmap(renderdata->display, renderdata->xwindow,
texture->w, texture->h, data->depth);
if (!data->pixmap) {
SDL_SetError("XCreatePixmap() failed");
return -1;
}
}
}
}
}
}
if (shm_error) {
Expand All @@ -859,13 +852,24 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
if (!data->image)
#endif /* not NO_SHARED_MEMORY */
{
data->pixels = SDL_malloc(texture->h * data->pitch);
data->image =
XCreateImage(renderdata->display, data->visual,
data->depth, ZPixmap, 0, NULL,
texture->w, texture->h,
SDL_BYTESPERPIXEL(data->format) * 8,
0);
if (!data->image) {
X11_DestroyTexture(renderer, texture);
SDL_SetError("XCreateImage() failed");
return -1;
}
data->pixels = SDL_malloc(texture->h * data->image->bytes_per_line);
if (!data->pixels) {
X11_DestroyTexture(renderer, texture);
SDL_OutOfMemory();
return -1;
}

data->image->data = data->pixels;
data->pixmap =
XCreatePixmap(renderdata->display, renderdata->xwindow, texture->w,
texture->h, data->depth);
Expand All @@ -874,40 +878,32 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
SDL_SetError("XCreatePixmap() failed");
return -1;
}
data->image =
XCreateImage(renderdata->display, data->visual,
data->depth, ZPixmap, 0, data->pixels,
texture->w, texture->h,
SDL_BYTESPERPIXEL(data->format) * 8,
data->pitch);
if (!data->image) {
X11_DestroyTexture(renderer, texture);
SDL_SetError("XCreateImage() failed");
return -1;
}
}
}
else {
data->pixmap =
XCreatePixmap(renderdata->display, renderdata->xwindow, texture->w,
texture->h, data->depth);
if (data->pixmap == None) {
X11_DestroyTexture(renderer, texture);
SDL_SetError("XCreatePixmap() failed");
return -1;
}
data->image =
XCreateImage(renderdata->display, data->visual,
data->depth, ZPixmap, 0, NULL,
texture->w, texture->h,
SDL_BYTESPERPIXEL(data->format) * 8,
data->pitch);
0);
if (!data->image) {
X11_DestroyTexture(renderer, texture);
SDL_SetError("XCreateImage() failed");
return -1;
}
data->pixmap =
XCreatePixmap(renderdata->display, renderdata->xwindow, texture->w,
texture->h, data->depth);
if (data->pixmap == None) {
X11_DestroyTexture(renderer, texture);
SDL_SetError("XCreatePixmap() failed");
return -1;
}
}

data->pitch = data->image->bytes_per_line;

#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if(renderdata->use_xrender) {
gcv.graphics_exposures = False;
Expand All @@ -932,6 +928,8 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
SDL_SetError("XRenderCreatePicture() failed");
return -1;
}
texture->blendMode = SDL_BLENDMODE_NONE;
data->blend_op = PictOpSrc;
}
#endif
return 0;
Expand Down Expand Up @@ -1713,18 +1711,19 @@ X11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
if(texture->access == SDL_TEXTUREACCESS_STREAMING) {
#ifndef NO_SHARED_MEMORY
if(texturedata->shminfo.shmaddr) {
XShmPutImage(data->display, texturedata->pixmap, data->gc,
XShmPutImage(data->display, texturedata->pixmap, texturedata->gc,
texturedata->image, srcrect->x, srcrect->y,
srcrect->x, srcrect->y, srcrect->w, srcrect->h,
False);
}
else
#endif
if (texturedata->pixels) {
XPutImage(data->display, texturedata->pixmap, data->gc,
texturedata->image, srcrect->x, srcrect->y, dstrect->x,
dstrect->y, srcrect->w, srcrect->h);
XPutImage(data->display, texturedata->pixmap, texturedata->gc,
texturedata->image, srcrect->x, srcrect->y, srcrect->x,
srcrect->y, srcrect->w, srcrect->h);
}
XSync(data->display, False);
}
Picture mask;
XRenderPictureAttributes attr;
Expand Down

0 comments on commit 3d32d92

Please sign in to comment.