comparison src/video/x11/SDL_x11render.c @ 4590:1ad70fb49fcb

Fix so many things that there is little place in this column to list 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.
author Sunny Sachanandani <sunnysachanandani@gmail.com>
date Fri, 09 Jul 2010 21:36:41 +0530
parents 8d8a889530eb
children 1e998db9b597
comparison
equal deleted inserted replaced
4589:8d8a889530eb 4590:1ad70fb49fcb
213 data->screen = displaydata->screen; 213 data->screen = displaydata->screen;
214 data->visual = displaydata->visual; 214 data->visual = displaydata->visual;
215 data->depth = displaydata->depth; 215 data->depth = displaydata->depth;
216 data->scanline_pad = displaydata->scanline_pad; 216 data->scanline_pad = displaydata->scanline_pad;
217 data->xwindow = windowdata->xwindow; 217 data->xwindow = windowdata->xwindow;
218 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 218
219 int event_basep, error_basep;
220 if(XRenderQueryExtension(data->display, &event_basep, &error_basep) == True) {
221 data->use_xrender = SDL_TRUE;
222 data->xwindow_pict_fmt = XRenderFindVisualFormat(data->display, data->visual);
223 if(!data->xwindow_pict_fmt) {
224 data->use_xrender = SDL_FALSE;
225 goto fallback;
226 }
227 data->xwindow_pict = XRenderCreatePicture(data->display, data->xwindow, data->xwindow_pict_fmt,
228 0, NULL);
229 if(!data->xwindow_pict) {
230 data->use_xrender = SDL_FALSE;
231 goto fallback;
232 }
233 // Create a 1 bit depth mask
234 data->mask = XCreatePixmap(data->display, data->xwindow,
235 window->w, window->h, 1);
236 data->mask_pict = XRenderCreatePicture(data->display, data->mask,
237 XRenderFindStandardFormat(data->display,
238 PictStandardA1),
239 0, NULL);
240 XGCValues gcv_mask;
241 gcv_mask.foreground = 1;
242 gcv_mask.background = 0;
243 data->mask_gc = XCreateGC(data->display, data->mask, GCBackground | GCForeground, &gcv_mask);
244 }
245 else {
246 data->use_xrender = SDL_FALSE;
247 }
248 fallback:
249 #endif
250 renderer->DisplayModeChanged = X11_DisplayModeChanged; 219 renderer->DisplayModeChanged = X11_DisplayModeChanged;
251 renderer->CreateTexture = X11_CreateTexture; 220 renderer->CreateTexture = X11_CreateTexture;
252 renderer->QueryTexturePixels = X11_QueryTexturePixels; 221 renderer->QueryTexturePixels = X11_QueryTexturePixels;
253 renderer->SetTextureBlendMode = X11_SetTextureBlendMode; 222 renderer->SetTextureBlendMode = X11_SetTextureBlendMode;
254 renderer->SetTextureScaleMode = X11_SetTextureScaleMode; 223 renderer->SetTextureScaleMode = X11_SetTextureScaleMode;
270 renderer->window = window; 239 renderer->window = window;
271 renderer->driverdata = data; 240 renderer->driverdata = data;
272 241
273 renderer->info.flags = SDL_RENDERER_ACCELERATED; 242 renderer->info.flags = SDL_RENDERER_ACCELERATED;
274 243
244 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
245 int event_basep, error_basep;
246 if(XRenderQueryExtension(data->display, &event_basep, &error_basep) == True) {
247 data->use_xrender = SDL_TRUE;
248 data->xwindow_pict_fmt = XRenderFindStandardFormat(data->display, PictStandardARGB32);
249 if(!data->xwindow_pict_fmt) {
250 data->use_xrender = SDL_FALSE;
251 goto fallback;
252 }
253 data->xwindow_pict = XRenderCreatePicture(data->display, data->xwindow, data->xwindow_pict_fmt,
254 0, NULL);
255 if(!data->xwindow_pict) {
256 data->use_xrender = SDL_FALSE;
257 goto fallback;
258 }
259 renderer->info.blend_modes |=
260 (SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MASK);
261 // Create a 1 bit depth mask
262 data->mask = XCreatePixmap(data->display, data->xwindow,
263 window->w, window->h, 1);
264 data->mask_pict = XRenderCreatePicture(data->display, data->mask,
265 XRenderFindStandardFormat(data->display,
266 PictStandardA1),
267 0, NULL);
268 XGCValues gcv_mask;
269 gcv_mask.foreground = 1;
270 gcv_mask.background = 0;
271 data->mask_gc = XCreateGC(data->display, data->mask, GCBackground | GCForeground, &gcv_mask);
272 renderer->blendMode = SDL_BLENDMODE_BLEND;
273 data->blend_op = PictOpOver;
274 }
275 else {
276 data->use_xrender = SDL_FALSE;
277 }
278 fallback:
279 #endif
280
275 if (flags & SDL_RENDERER_SINGLEBUFFER) { 281 if (flags & SDL_RENDERER_SINGLEBUFFER) {
276 renderer->info.flags |= 282 renderer->info.flags |=
277 (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY); 283 (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY);
278 n = 0; 284 n = 0;
279 } else if (flags & SDL_RENDERER_PRESENTFLIP2) { 285 } else if (flags & SDL_RENDERER_PRESENTFLIP2) {
732 { 738 {
733 X11_RenderData *data = (X11_RenderData *) renderer->driverdata; 739 X11_RenderData *data = (X11_RenderData *) renderer->driverdata;
734 switch (renderer->blendMode) { 740 switch (renderer->blendMode) {
735 case SDL_BLENDMODE_NONE: 741 case SDL_BLENDMODE_NONE:
736 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 742 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
743 //PictOpSrc
737 data->blend_op = PictOpSrc; 744 data->blend_op = PictOpSrc;
738 return 0; 745 return 0;
739 case SDL_BLENDMODE_MASK: // Use src pict as mask 746 case SDL_BLENDMODE_BLEND: // PictOpOver
740 data->blend_op = PictOpSrc; 747 data->blend_op = PictOpOver;
741 return 0; 748 return 0;
742 case SDL_BLENDMODE_ADD: // PictOpAdd 749 case SDL_BLENDMODE_ADD: // PictOpAdd
743 data->blend_op = PictOpAdd; 750 data->blend_op = PictOpAdd;
744 return 0; 751 return 0;
745 case SDL_BLENDMODE_BLEND: // PictOpOver
746 data->blend_op = PictOpOver;
747 return 0;
748 /* FIXME case SDL_BLENDMODE_MOD: */ 752 /* FIXME case SDL_BLENDMODE_MOD: */
749 #endif 753 #endif
750 return 0; 754 return 0;
751 default: 755 default:
752 SDL_Unsupported(); 756 SDL_Unsupported();
753 renderer->blendMode = SDL_BLENDMODE_NONE; 757 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
754 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 758 if(data->use_xrender) {
755 data->blend_op = PictOpSrc; 759 renderer->blendMode = SDL_BLENDMODE_BLEND;
756 #endif 760 data->blend_op = PictOpOver;
761 }
762 else
763 #endif
764 {
765 renderer->blendMode = SDL_BLENDMODE_NONE;
766 }
757 return -1; 767 return -1;
758 } 768 }
759 } 769 }
760 770
761 static Uint32 771 static Uint32
777 static XRenderColor 787 static XRenderColor
778 xrenderdrawcolor(SDL_Renderer *renderer) 788 xrenderdrawcolor(SDL_Renderer *renderer)
779 { 789 {
780 // Premultiply the color channels as well as modulate them to a 16 bit color space 790 // Premultiply the color channels as well as modulate them to a 16 bit color space
781 XRenderColor xrender_color; 791 XRenderColor xrender_color;
782 xrender_color.red = ((unsigned short)renderer->r + 1) * ((unsigned short)renderer->a + 1) - 1; 792 double alphad;
783 xrender_color.green = ((unsigned short)renderer->g + 1) * ((unsigned short)renderer->a + 1) - 1; 793 if(renderer->blendMode == SDL_BLENDMODE_NONE)
784 xrender_color.blue = ((unsigned short)renderer->b + 1) * ((unsigned short)renderer->a + 1) - 1; 794 alphad = 1.0;
785 xrender_color.alpha = ((unsigned short)renderer->a + 1) * ((unsigned short)renderer->a + 1) - 1; 795 else
796 alphad = (renderer->a) / 255.0;
797
798 xrender_color.alpha = (unsigned short) (alphad * 0xFFFF);
799
800 xrender_color.red =
801 (unsigned short) ((renderer->r / 255.0) * alphad * 0xFFFF);
802 xrender_color.green =
803 (unsigned short) ((renderer->g / 255.0) * alphad * 0xFFFF);
804 xrender_color.blue =
805 (unsigned short) ((renderer->b / 255.0) * alphad * 0xFFFF);
786 return xrender_color; 806 return xrender_color;
787 } 807 }
788 808
789 static int 809 static int
790 X11_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, 810 X11_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
1048 SDL_Rect clip, rect; 1068 SDL_Rect clip, rect;
1049 int i, xcount; 1069 int i, xcount;
1050 XRectangle *xrects, *xrect; 1070 XRectangle *xrects, *xrect;
1051 xrect = xrects = SDL_stack_alloc(XRectangle, count); 1071 xrect = xrects = SDL_stack_alloc(XRectangle, count);
1052 xcount = 0; 1072 xcount = 0;
1073
1074 clip.x = 0;
1075 clip.y = 0;
1076 clip.w = window->w;
1077 clip.h = window->h;
1078
1053 for (i = 0; i < count; ++i) { 1079 for (i = 0; i < count; ++i) {
1054 if (!SDL_IntersectRect(rects[i], &clip, &rect)) { 1080 if (!SDL_IntersectRect(rects[i], &clip, &rect)) {
1055 continue; 1081 continue;
1056 } 1082 }
1057 1083
1064 1090
1065 if (data->makedirty) { 1091 if (data->makedirty) {
1066 SDL_AddDirtyRect(&data->dirty, &rect); 1092 SDL_AddDirtyRect(&data->dirty, &rect);
1067 } 1093 }
1068 } 1094 }
1069 clip.x = 0; 1095
1070 clip.y = 0;
1071 clip.w = window->w;
1072 clip.h = window->h;
1073
1074 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 1096 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
1075 if(data->use_xrender == SDL_TRUE) { 1097 if(data->use_xrender == SDL_TRUE) {
1076 XRenderColor foreground; 1098 XRenderColor foreground;
1077 XRenderPictureAttributes attributes; 1099 XRenderPictureAttributes attributes;
1078 unsigned long valuemask; 1100 unsigned long valuemask;
1149 XRenderColor foreground; 1171 XRenderColor foreground;
1150 XRenderPictureAttributes attributes; 1172 XRenderPictureAttributes attributes;
1151 unsigned long valuemask; 1173 unsigned long valuemask;
1152 1174
1153 foreground = xrenderdrawcolor(renderer); 1175 foreground = xrenderdrawcolor(renderer);
1154 attributes.clip_mask = data->mask;
1155 valuemask = CPClipMask; 1176 valuemask = CPClipMask;
1156 attributes.clip_mask = data->mask; 1177 attributes.clip_mask = data->mask;
1157 1178
1158 XRenderComposite(data->display, PictOpClear, data->mask_pict, None, data->mask_pict, 1179 XRenderComposite(data->display, PictOpClear, data->mask_pict, None, data->mask_pict,
1159 0, 0, 0, 0, 0, 0, window->w, window->h); 1180 0, 0, 0, 0, 0, 0, window->w, window->h);
1422 for (dirty = data->dirty.list; dirty; dirty = dirty->next) { 1443 for (dirty = data->dirty.list; dirty; dirty = dirty->next) {
1423 const SDL_Rect *rect = &dirty->rect; 1444 const SDL_Rect *rect = &dirty->rect;
1424 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 1445 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
1425 if(data->use_xrender == SDL_TRUE) 1446 if(data->use_xrender == SDL_TRUE)
1426 { 1447 {
1427 if(renderer->blendMode == SDL_BLENDMODE_MASK) 1448 XRenderComposite(data->display, PictOpOver, data->drawable_pict, None,
1428 XRenderComposite(data->display, data->blend_op, data->drawable_pict, 1449 data->xwindow_pict, rect->x, rect->y, 0, 0, rect->x, rect->y,
1429 data->drawable_pict, data->xwindow_pict, rect->x, rect->y, 1450 rect->w+1, rect->h+1);
1430 0, 0, rect->x, rect->y, rect->w, rect->h);
1431 else
1432 XRenderComposite(data->display, data->blend_op, data->drawable_pict, None,
1433 data->xwindow_pict, rect->x, rect->y, 0, 0, rect->x, rect->y,
1434 rect->w, rect->h);
1435
1436 } 1451 }
1437 else 1452 else
1438 #endif 1453 #endif
1439 { 1454 {
1440 XCopyArea(data->display, data->drawable, data->xwindow, 1455 XCopyArea(data->display, data->drawable, data->xwindow,