Mercurial > sdl-ios-xcode
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, |