Make the SW renderer work properly by fixing support for textures with no alpha channels.
This commit is contained in:
parent
9684366030
commit
4915ca0980
1 changed files with 98 additions and 99 deletions
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -692,8 +697,10 @@ PixelFormatEnumToXRenderPictFormat(SDL_Renderer * renderer, Uint32 format) {
|
||||||
|
|
||||||
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) {
|
||||||
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,36 +780,26 @@ 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
|
||||||
|
@ -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)
|
||||||
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,20 +878,20 @@ 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->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->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);
|
||||||
|
@ -896,18 +900,10 @@ 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, NULL,
|
|
||||||
texture->w, texture->h,
|
|
||||||
SDL_BYTESPERPIXEL(data->format) * 8,
|
|
||||||
data->pitch);
|
|
||||||
if (!data->image) {
|
|
||||||
X11_DestroyTexture(renderer, texture);
|
|
||||||
SDL_SetError("XCreateImage() 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)
|
||||||
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,
|
||||||
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,
|
||||||
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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue