Commit 4915ca09 authored by Sunny Sachanandani's avatar Sunny Sachanandani

Make the SW renderer work properly by fixing support for textures with no alpha channels.

parent 96843660
...@@ -671,15 +671,20 @@ X11_DisplayModeChanged(SDL_Renderer * renderer) ...@@ -671,15 +671,20 @@ X11_DisplayModeChanged(SDL_Renderer * renderer)
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
static void static void
SDLMaskToXRenderMask(Uint32 sdl_mask, short *comp, short *compMask) { SDLMaskToXRenderMask(Uint32 sdl_mask, short *comp, short *compMask) {
(*comp) = 0; if (sdl_mask == 0) {
(*compMask) = 0; *comp = 0;
while(!(sdl_mask & 1)) { *compMask = 0;
(*comp)++; } else {
sdl_mask >>= 1; (*comp) = 0;
} (*compMask) = 0;
while(sdl_mask & 1) { while(!(sdl_mask & 1)) {
(*compMask) = ((*compMask) << 1) | 1; (*comp)++;
sdl_mask >>= 1; sdl_mask >>= 1;
}
while(sdl_mask & 1) {
(*compMask) = ((*compMask) << 1) | 1;
sdl_mask >>= 1;
}
} }
} }
...@@ -687,13 +692,15 @@ static XRenderPictFormat* ...@@ -687,13 +692,15 @@ static XRenderPictFormat*
PixelFormatEnumToXRenderPictFormat(SDL_Renderer * renderer, Uint32 format) { PixelFormatEnumToXRenderPictFormat(SDL_Renderer * renderer, Uint32 format) {
XRenderPictFormat* pict_fmt = NULL; XRenderPictFormat* pict_fmt = NULL;
X11_RenderData *data = (X11_RenderData *) renderer->driverdata; X11_RenderData *data = (X11_RenderData *) renderer->driverdata;
if (data->use_xrender) { if (data->use_xrender) {
int bpp; int bpp;
Uint32 Amask, Rmask, Gmask, Bmask; 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; XRenderPictFormat templ;
unsigned long mask = (PictFormatType | PictFormatDepth | PictFormatRed | unsigned long mask = (PictFormatType | PictFormatDepth | PictFormatRed |
PictFormatRedMask | PictFormatGreen | PictFormatGreenMask | PictFormatRedMask | PictFormatGreen | PictFormatGreenMask |
...@@ -706,7 +713,6 @@ PixelFormatEnumToXRenderPictFormat(SDL_Renderer * renderer, Uint32 format) { ...@@ -706,7 +713,6 @@ PixelFormatEnumToXRenderPictFormat(SDL_Renderer * renderer, Uint32 format) {
SDLMaskToXRenderMask(Rmask, &(templ.direct.red), &(templ.direct.redMask)); SDLMaskToXRenderMask(Rmask, &(templ.direct.red), &(templ.direct.redMask));
SDLMaskToXRenderMask(Gmask, &(templ.direct.green), &(templ.direct.greenMask)); SDLMaskToXRenderMask(Gmask, &(templ.direct.green), &(templ.direct.greenMask));
SDLMaskToXRenderMask(Bmask, &(templ.direct.blue), &(templ.direct.blueMask)); SDLMaskToXRenderMask(Bmask, &(templ.direct.blue), &(templ.direct.blueMask));
pict_fmt = XRenderFindFormat(data->display, mask, &templ, 0); pict_fmt = XRenderFindFormat(data->display, mask, &templ, 0);
} }
...@@ -774,37 +780,27 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ...@@ -774,37 +780,27 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
} }
data->format = display->current_mode.format; data->format = display->current_mode.format;
} else { } 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 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if (renderdata->use_xrender == SDL_FALSE) { if (renderdata->use_xrender)
if (texture->format != display->current_mode.format) { {
SDL_SetError("Texture format doesn't match window format");
return -1;
}
} else {
Uint32 Amask, Rmask, Gmask, Bmask; Uint32 Amask, Rmask, Gmask, Bmask;
SDL_PixelFormatEnumToMasks(texture->format, &(data->depth), SDL_PixelFormatEnumToMasks(texture->format, &(data->depth),
&Rmask, &Gmask, &Bmask, &Amask); &Rmask, &Gmask, &Bmask, &Amask);
printf("%d %x %x %x %x\n", data->depth, Rmask, Gmask, Bmask, Amask);
data->visual = PixelFormatEnumToVisual(renderer, texture->format); data->visual = PixelFormatEnumToVisual(renderer, texture->format);
} }
#else 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;
}
#endif #endif
{
if (texture->format != display->current_mode.format)
{
SDL_SetError("Texture format doesn't match window format");
return -1;
}
}
data->format = texture->format; 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) { if (data->yuv || texture->access == SDL_TEXTUREACCESS_STREAMING) {
#ifndef NO_SHARED_MEMORY #ifndef NO_SHARED_MEMORY
XShmSegmentInfo *shminfo = &data->shminfo; XShmSegmentInfo *shminfo = &data->shminfo;
...@@ -812,45 +808,42 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ...@@ -812,45 +808,42 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
shm_error = True; shm_error = True;
if (SDL_X11_HAVE_SHM) { 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 = data->image =
XShmCreateImage(renderdata->display, data->visual, XShmCreateImage(renderdata->display, data->visual,
data->depth, ZPixmap, shminfo->shmaddr, data->depth, ZPixmap, NULL,
shminfo, texture->w, texture->h); shminfo, texture->w, texture->h);
if (data->image) {
if (!data->image) { shminfo->shmid =
XShmDetach(renderdata->display, shminfo); shmget(IPC_PRIVATE, texture->h * data->image->bytes_per_line,
XSync(renderdata->display, False); IPC_CREAT | 0777);
shmdt(shminfo->shmaddr); if (shminfo->shmid >= 0) {
shm_error = True; 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) { if (shm_error) {
...@@ -859,13 +852,24 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ...@@ -859,13 +852,24 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
if (!data->image) if (!data->image)
#endif /* not NO_SHARED_MEMORY */ #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) { if (!data->pixels) {
X11_DestroyTexture(renderer, texture); X11_DestroyTexture(renderer, texture);
SDL_OutOfMemory(); SDL_OutOfMemory();
return -1; return -1;
} }
data->image->data = data->pixels;
data->pixmap = data->pixmap =
XCreatePixmap(renderdata->display, renderdata->xwindow, texture->w, XCreatePixmap(renderdata->display, renderdata->xwindow, texture->w,
texture->h, data->depth); texture->h, data->depth);
...@@ -874,40 +878,32 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ...@@ -874,40 +878,32 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
SDL_SetError("XCreatePixmap() failed"); SDL_SetError("XCreatePixmap() failed");
return -1; 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 { 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 = data->image =
XCreateImage(renderdata->display, data->visual, XCreateImage(renderdata->display, data->visual,
data->depth, ZPixmap, 0, NULL, data->depth, ZPixmap, 0, NULL,
texture->w, texture->h, texture->w, texture->h,
SDL_BYTESPERPIXEL(data->format) * 8, SDL_BYTESPERPIXEL(data->format) * 8,
data->pitch); 0);
if (!data->image) { if (!data->image) {
X11_DestroyTexture(renderer, texture); X11_DestroyTexture(renderer, texture);
SDL_SetError("XCreateImage() failed"); SDL_SetError("XCreateImage() failed");
return -1; 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 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if(renderdata->use_xrender) { if(renderdata->use_xrender) {
gcv.graphics_exposures = False; gcv.graphics_exposures = False;
...@@ -932,6 +928,8 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ...@@ -932,6 +928,8 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
SDL_SetError("XRenderCreatePicture() failed"); SDL_SetError("XRenderCreatePicture() failed");
return -1; return -1;
} }
texture->blendMode = SDL_BLENDMODE_NONE;
data->blend_op = PictOpSrc;
} }
#endif #endif
return 0; return 0;
...@@ -1713,7 +1711,7 @@ X11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, ...@@ -1713,7 +1711,7 @@ X11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
if(texture->access == SDL_TEXTUREACCESS_STREAMING) { if(texture->access == SDL_TEXTUREACCESS_STREAMING) {
#ifndef NO_SHARED_MEMORY #ifndef NO_SHARED_MEMORY
if(texturedata->shminfo.shmaddr) { if(texturedata->shminfo.shmaddr) {
XShmPutImage(data->display, texturedata->pixmap, data->gc, XShmPutImage(data->display, texturedata->pixmap, texturedata->gc,
texturedata->image, srcrect->x, srcrect->y, texturedata->image, srcrect->x, srcrect->y,
srcrect->x, srcrect->y, srcrect->w, srcrect->h, srcrect->x, srcrect->y, srcrect->w, srcrect->h,
False); False);
...@@ -1721,10 +1719,11 @@ X11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, ...@@ -1721,10 +1719,11 @@ X11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
else else
#endif #endif
if (texturedata->pixels) { if (texturedata->pixels) {
XPutImage(data->display, texturedata->pixmap, data->gc, XPutImage(data->display, texturedata->pixmap, texturedata->gc,
texturedata->image, srcrect->x, srcrect->y, dstrect->x, texturedata->image, srcrect->x, srcrect->y, srcrect->x,
dstrect->y, srcrect->w, srcrect->h); srcrect->y, srcrect->w, srcrect->h);
} }
XSync(data->display, False);
} }
Picture mask; Picture mask;
XRenderPictureAttributes attr; XRenderPictureAttributes attr;
......
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