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

Commit

Permalink
Fix so many things that there is little place in this column to list …
Browse files Browse the repository at this point in the history
…them all but the result is that blending modes just work now for drawing primitives.

Fixes involved:
1. Fix handling of alpha channel when SDL_BLENDMODE_NONE is set.
2. Make xrendercolor use floating-point values for color channels and then convert to 16 bit ints.
3. Fix handling of visuals in SDL_x11modes.c so that a 32 bit ARGB visual is used.
4. Fix the background pixel value in SDL_x11window.c so that the window background has an alpha value of 0xFF and not 0.
  • Loading branch information
sunnyps committed Jul 9, 2010
1 parent d12b66d commit 8446602
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 56 deletions.
24 changes: 20 additions & 4 deletions src/video/x11/SDL_x11modes.c
Expand Up @@ -23,7 +23,7 @@

#include "SDL_x11video.h"

//#define X11MODES_DEBUG
#define X11MODES_DEBUG
#undef SDL_VIDEO_DRIVER_X11_XINERAMA
#undef SDL_VIDEO_DRIVER_X11_XRANDR
#undef SDL_VIDEO_DRIVER_X11_VIDMODE
Expand All @@ -33,11 +33,12 @@ get_visualinfo(Display * display, int screen, XVisualInfo * vinfo)
{
const char *visual_id = SDL_getenv("SDL_VIDEO_X11_VISUALID");
int depth;
XVisualInfo *vi;
int nvis;

/* Look for an exact visual, if requested */
if (visual_id) {
XVisualInfo *vi, template;
int nvis;
XVisualInfo template;

SDL_zero(template);
template.visualid = SDL_strtol(visual_id, NULL, 0);
Expand All @@ -48,7 +49,22 @@ get_visualinfo(Display * display, int screen, XVisualInfo * vinfo)
return 0;
}
}

#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
depth = 32;
long vinfo_mask;
XVisualInfo vinfo_templ;
vinfo_mask = (VisualDepthMask | VisualRedMaskMask | VisualGreenMaskMask | VisualBlueMaskMask);
vinfo_templ.depth = 32;
vinfo_templ.red_mask = 0xFF0000;
vinfo_templ.green_mask = 0xFF00;
vinfo_templ.blue_mask = 0xFF;
vi = XGetVisualInfo(display, vinfo_mask, &vinfo_templ, &nvis);
if(vi) {
*vinfo = *vi;
XFree(vi);
return 0;
}
#endif
depth = DefaultDepth(display, screen);
if ((X11_UseDirectColorVisuals() &&
XMatchVisualInfo(display, screen, depth, DirectColor, vinfo)) ||
Expand Down
119 changes: 67 additions & 52 deletions src/video/x11/SDL_x11render.c
Expand Up @@ -215,11 +215,37 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags)
data->depth = displaydata->depth;
data->scanline_pad = displaydata->scanline_pad;
data->xwindow = windowdata->xwindow;

renderer->DisplayModeChanged = X11_DisplayModeChanged;
renderer->CreateTexture = X11_CreateTexture;
renderer->QueryTexturePixels = X11_QueryTexturePixels;
renderer->SetTextureBlendMode = X11_SetTextureBlendMode;
renderer->SetTextureScaleMode = X11_SetTextureScaleMode;
renderer->UpdateTexture = X11_UpdateTexture;
renderer->LockTexture = X11_LockTexture;
renderer->UnlockTexture = X11_UnlockTexture;
renderer->SetDrawBlendMode = X11_SetDrawBlendMode;
renderer->RenderDrawPoints = X11_RenderDrawPoints;
renderer->RenderDrawLines = X11_RenderDrawLines;
renderer->RenderDrawRects = X11_RenderDrawRects;
renderer->RenderFillRects = X11_RenderFillRects;
renderer->RenderCopy = X11_RenderCopy;
renderer->RenderReadPixels = X11_RenderReadPixels;
renderer->RenderWritePixels = X11_RenderWritePixels;
renderer->RenderPresent = X11_RenderPresent;
renderer->DestroyTexture = X11_DestroyTexture;
renderer->DestroyRenderer = X11_DestroyRenderer;
renderer->info = X11_RenderDriver.info;
renderer->window = window;
renderer->driverdata = data;

renderer->info.flags = SDL_RENDERER_ACCELERATED;

#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
int event_basep, error_basep;
if(XRenderQueryExtension(data->display, &event_basep, &error_basep) == True) {
data->use_xrender = SDL_TRUE;
data->xwindow_pict_fmt = XRenderFindVisualFormat(data->display, data->visual);
data->xwindow_pict_fmt = XRenderFindStandardFormat(data->display, PictStandardARGB32);
if(!data->xwindow_pict_fmt) {
data->use_xrender = SDL_FALSE;
goto fallback;
Expand All @@ -230,6 +256,8 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags)
data->use_xrender = SDL_FALSE;
goto fallback;
}
renderer->info.blend_modes |=
(SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MASK);
// Create a 1 bit depth mask
data->mask = XCreatePixmap(data->display, data->xwindow,
window->w, window->h, 1);
Expand All @@ -241,37 +269,15 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags)
gcv_mask.foreground = 1;
gcv_mask.background = 0;
data->mask_gc = XCreateGC(data->display, data->mask, GCBackground | GCForeground, &gcv_mask);
renderer->blendMode = SDL_BLENDMODE_BLEND;
data->blend_op = PictOpOver;
}
else {
data->use_xrender = SDL_FALSE;
}
fallback:
#endif
renderer->DisplayModeChanged = X11_DisplayModeChanged;
renderer->CreateTexture = X11_CreateTexture;
renderer->QueryTexturePixels = X11_QueryTexturePixels;
renderer->SetTextureBlendMode = X11_SetTextureBlendMode;
renderer->SetTextureScaleMode = X11_SetTextureScaleMode;
renderer->UpdateTexture = X11_UpdateTexture;
renderer->LockTexture = X11_LockTexture;
renderer->UnlockTexture = X11_UnlockTexture;
renderer->SetDrawBlendMode = X11_SetDrawBlendMode;
renderer->RenderDrawPoints = X11_RenderDrawPoints;
renderer->RenderDrawLines = X11_RenderDrawLines;
renderer->RenderDrawRects = X11_RenderDrawRects;
renderer->RenderFillRects = X11_RenderFillRects;
renderer->RenderCopy = X11_RenderCopy;
renderer->RenderReadPixels = X11_RenderReadPixels;
renderer->RenderWritePixels = X11_RenderWritePixels;
renderer->RenderPresent = X11_RenderPresent;
renderer->DestroyTexture = X11_DestroyTexture;
renderer->DestroyRenderer = X11_DestroyRenderer;
renderer->info = X11_RenderDriver.info;
renderer->window = window;
renderer->driverdata = data;

renderer->info.flags = SDL_RENDERER_ACCELERATED;


if (flags & SDL_RENDERER_SINGLEBUFFER) {
renderer->info.flags |=
(SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY);
Expand Down Expand Up @@ -734,26 +740,30 @@ X11_SetDrawBlendMode(SDL_Renderer * renderer)
switch (renderer->blendMode) {
case SDL_BLENDMODE_NONE:
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
//PictOpSrc
data->blend_op = PictOpSrc;
return 0;
case SDL_BLENDMODE_MASK: // Use src pict as mask
data->blend_op = PictOpSrc;
case SDL_BLENDMODE_BLEND: // PictOpOver
data->blend_op = PictOpOver;
return 0;
case SDL_BLENDMODE_ADD: // PictOpAdd
data->blend_op = PictOpAdd;
return 0;
case SDL_BLENDMODE_BLEND: // PictOpOver
data->blend_op = PictOpOver;
return 0;
/* FIXME case SDL_BLENDMODE_MOD: */
#endif
return 0;
default:
SDL_Unsupported();
renderer->blendMode = SDL_BLENDMODE_NONE;
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
data->blend_op = PictOpSrc;
if(data->use_xrender) {
renderer->blendMode = SDL_BLENDMODE_BLEND;
data->blend_op = PictOpOver;
}
else
#endif
{
renderer->blendMode = SDL_BLENDMODE_NONE;
}
return -1;
}
}
Expand All @@ -779,10 +789,20 @@ xrenderdrawcolor(SDL_Renderer *renderer)
{
// Premultiply the color channels as well as modulate them to a 16 bit color space
XRenderColor xrender_color;
xrender_color.red = ((unsigned short)renderer->r + 1) * ((unsigned short)renderer->a + 1) - 1;
xrender_color.green = ((unsigned short)renderer->g + 1) * ((unsigned short)renderer->a + 1) - 1;
xrender_color.blue = ((unsigned short)renderer->b + 1) * ((unsigned short)renderer->a + 1) - 1;
xrender_color.alpha = ((unsigned short)renderer->a + 1) * ((unsigned short)renderer->a + 1) - 1;
double alphad;
if(renderer->blendMode == SDL_BLENDMODE_NONE)
alphad = 1.0;
else
alphad = (renderer->a) / 255.0;

xrender_color.alpha = (unsigned short) (alphad * 0xFFFF);

xrender_color.red =
(unsigned short) ((renderer->r / 255.0) * alphad * 0xFFFF);
xrender_color.green =
(unsigned short) ((renderer->g / 255.0) * alphad * 0xFFFF);
xrender_color.blue =
(unsigned short) ((renderer->b / 255.0) * alphad * 0xFFFF);
return xrender_color;
}

Expand Down Expand Up @@ -1050,6 +1070,12 @@ X11_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
XRectangle *xrects, *xrect;
xrect = xrects = SDL_stack_alloc(XRectangle, count);
xcount = 0;

clip.x = 0;
clip.y = 0;
clip.w = window->w;
clip.h = window->h;

for (i = 0; i < count; ++i) {
if (!SDL_IntersectRect(rects[i], &clip, &rect)) {
continue;
Expand All @@ -1066,11 +1092,7 @@ X11_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
SDL_AddDirtyRect(&data->dirty, &rect);
}
}
clip.x = 0;
clip.y = 0;
clip.w = window->w;
clip.h = window->h;


#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if(data->use_xrender == SDL_TRUE) {
XRenderColor foreground;
Expand Down Expand Up @@ -1151,7 +1173,6 @@ X11_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
unsigned long valuemask;

foreground = xrenderdrawcolor(renderer);
attributes.clip_mask = data->mask;
valuemask = CPClipMask;
attributes.clip_mask = data->mask;

Expand Down Expand Up @@ -1424,15 +1445,9 @@ X11_RenderPresent(SDL_Renderer * renderer)
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if(data->use_xrender == SDL_TRUE)
{
if(renderer->blendMode == SDL_BLENDMODE_MASK)
XRenderComposite(data->display, data->blend_op, data->drawable_pict,
data->drawable_pict, data->xwindow_pict, rect->x, rect->y,
0, 0, rect->x, rect->y, rect->w, rect->h);
else
XRenderComposite(data->display, data->blend_op, data->drawable_pict, None,
data->xwindow_pict, rect->x, rect->y, 0, 0, rect->x, rect->y,
rect->w, rect->h);

XRenderComposite(data->display, PictOpOver, data->drawable_pict, None,
data->xwindow_pict, rect->x, rect->y, 0, 0, rect->x, rect->y,
rect->w+1, rect->h+1);
}
else
#endif
Expand Down
3 changes: 3 additions & 0 deletions src/video/x11/SDL_x11window.c
Expand Up @@ -513,6 +513,9 @@ X11_CreateWindow(_THIS, SDL_Window * window)
} else {
y = window->y;
}
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
xattr.background_pixel = 0xFF000000;
#endif

w = XCreateWindow(data->display,
RootWindow(data->display, displaydata->screen), x, y,
Expand Down

0 comments on commit 8446602

Please sign in to comment.