comparison src/video/x11/SDL_x11render.c @ 4597:95be206b3cb7 experimental

Start experimental branch for client-side rasterization.
author Sunny Sachanandani <sunnysachanandani@gmail.com>
date Sun, 18 Jul 2010 12:43:04 +0530
parents dc26c37ad70e
children 66e13a224bd6
comparison
equal deleted inserted replaced
4596:dc26c37ad70e 4597:95be206b3cb7
28 28
29 #include "SDL_x11video.h" 29 #include "SDL_x11video.h"
30 #include "../SDL_rect_c.h" 30 #include "../SDL_rect_c.h"
31 #include "../SDL_pixels_c.h" 31 #include "../SDL_pixels_c.h"
32 #include "../SDL_yuv_sw_c.h" 32 #include "../SDL_yuv_sw_c.h"
33 #include "SDL_surface.h"
33 34
34 /* X11 renderer implementation */ 35 /* X11 renderer implementation */
35 36
36 static SDL_Renderer *X11_CreateRenderer(SDL_Window * window, Uint32 flags); 37 static SDL_Renderer *X11_CreateRenderer(SDL_Window * window, Uint32 flags);
37 static int X11_DisplayModeChanged(SDL_Renderer * renderer); 38 static int X11_DisplayModeChanged(SDL_Renderer * renderer);
95 int depth; 96 int depth;
96 int scanline_pad; 97 int scanline_pad;
97 Window xwindow; 98 Window xwindow;
98 Pixmap pixmaps[3]; 99 Pixmap pixmaps[3];
99 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 100 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
100 Pixmap mask; 101 Pixmap stencil;
102 Pixmap brush;
103 Picture brush_pict;
104 #ifndef NO_SHARED_MEMORY
105 XImage *stencil_image;
106 SDL_Surface *stencil_surface;
107 XShmSegmentInfo stencil_shminfo;
108 #endif
101 Picture xwindow_pict; 109 Picture xwindow_pict;
102 Picture pixmap_picts[3]; 110 Picture pixmap_picts[3];
103 Picture drawable_pict; 111 Picture drawable_pict;
112 Picture stencil_pict;
104 int blend_op; 113 int blend_op;
105 XRenderPictFormat* xwindow_pict_fmt; 114 XRenderPictFormat* xwindow_pict_fmt;
106 GC mask_gc; 115 GC stencil_gc;
107 SDL_bool use_xrender; 116 SDL_bool use_xrender;
108 #endif 117 #endif
109 int current_pixmap; 118 int current_pixmap;
110 Drawable drawable; 119 Drawable drawable;
111 SDL_PixelFormat format; 120 SDL_PixelFormat format;
284 window->w, window->h); 293 window->w, window->h);
285 // Add some blending modes to the list of supported blending modes 294 // Add some blending modes to the list of supported blending modes
286 renderer->info.blend_modes |= 295 renderer->info.blend_modes |=
287 (SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MASK); 296 (SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MASK);
288 // Create a clip mask that is used for rendering primitives. 297 // Create a clip mask that is used for rendering primitives.
289 data->mask = XCreatePixmap(data->display, data->xwindow, 298 data->stencil = XCreatePixmap(data->display, data->xwindow,
290 window->w, window->h, 1); 299 window->w, window->h, 8);
291 if (!data->mask) { 300
292 SDL_SetError("XCreatePixmap() failed");
293 return NULL;
294 }
295 // Create the GC for the clip mask. 301 // Create the GC for the clip mask.
296 data->mask_gc = XCreateGC(data->display, data->mask, 302 data->stencil_gc = XCreateGC(data->display, data->stencil,
297 GCGraphicsExposures, &gcv); 303 GCGraphicsExposures, &gcv);
298 if (!data->mask_gc) { 304 XSetBackground(data->display, data->stencil_gc, 0x00);
299 SDL_SetError("XCreateGC() failed"); 305 XSetForeground(data->display, data->stencil_gc, 0xFF);
300 return NULL; 306 data->stencil_pict =
301 } 307 XRenderCreatePicture(data->display, data->stencil,
302 XSetBackground(data->display, data->mask_gc, 0); 308 XRenderFindStandardFormat(data->display,
303 XSetForeground(data->display, data->mask_gc, 1); 309 PictStandardA8),
310 0, NULL);
311 data->brush =
312 XCreatePixmap(data->display, data->xwindow, 1, 1, 32);
313 XRenderPictureAttributes brush_attr;
314 brush_attr.repeat = RepeatNormal;
315 data->brush_pict =
316 XRenderCreatePicture(data->display, data->brush,
317 XRenderFindStandardFormat(data->display,
318 PictStandardARGB32),
319 CPRepeat, &brush_attr);
320 #ifndef NO_SHARED_MEMORY
321 /* Create a mask image using MIT-SHM */
322 data->stencil_image = NULL;
323 data->stencil_surface = NULL;
324 XShmSegmentInfo *shminfo = &data->stencil_shminfo;
325 while (SDL_X11_HAVE_SHM) {
326 data->stencil_image =
327 XShmCreateImage(data->display, data->visual, 8, ZPixmap,
328 NULL, shminfo, window->w, window->h);
329 if (!data->stencil_image) {
330 printf("XShmCreateImage() failed");
331 break;
332 } else {
333 printf("image created\n");
334 }
335 shminfo->shmid = shmget(IPC_PRIVATE,
336 data->stencil_image->bytes_per_line *
337 data->stencil_image->height,
338 IPC_CREAT|0777);
339 if (!shminfo->shmid) {
340 printf("shmget() failed");
341 break;
342 } else {
343 printf("shmid aquired\n");
344 }
345 shminfo->shmaddr = data->stencil_image->data = shmat(shminfo->shmid, 0, 0);
346 shminfo->readOnly = False;
347 XShmAttach(data->display, shminfo);
348 XSync(data->display, False);
349 shmctl(shminfo->shmid, IPC_RMID, NULL);
350 data->stencil_surface =
351 SDL_CreateRGBSurfaceFrom(shminfo->shmaddr,
352 data->stencil_image->width,
353 data->stencil_image->height,
354 8,
355 data->stencil_image->bytes_per_line,
356 0, 0, 0, 0xFF);
357 if (!data->stencil_surface) {
358 printf("SDL_CreateRGBSurfaceFrom() failed");
359 break;
360 } else {
361 printf("surface created\n");
362 }
363 break;
364 }
365 #endif
304 // Set the default blending mode. 366 // Set the default blending mode.
305 renderer->blendMode = SDL_BLENDMODE_BLEND; 367 renderer->blendMode = SDL_BLENDMODE_BLEND;
306 data->blend_op = PictOpOver; 368 data->blend_op = PictOpOver;
307 } 369 }
308 #endif 370 #endif
691 shminfo->shmaddr = NULL; 753 shminfo->shmaddr = NULL;
692 } 754 }
693 if (!data->image) 755 if (!data->image)
694 #endif /* not NO_SHARED_MEMORY */ 756 #endif /* not NO_SHARED_MEMORY */
695 { 757 {
696 /* This is the case where the server does not have
697 shared memory support and the texture is streaming.
698 It does not make sense to use Xrender here because
699 we would have to copy the data onto a server side
700 pixmap with XPutImage first and only then can we
701 use Xrender
702 */
703
704 data->pixels = SDL_malloc(texture->h * data->pitch); 758 data->pixels = SDL_malloc(texture->h * data->pitch);
705 if (!data->pixels) { 759 if (!data->pixels) {
706 X11_DestroyTexture(renderer, texture); 760 X11_DestroyTexture(renderer, texture);
707 SDL_OutOfMemory(); 761 SDL_OutOfMemory();
708 return -1; 762 return -1;
997 { 1051 {
998 X11_RenderData *data = (X11_RenderData *) renderer->driverdata; 1052 X11_RenderData *data = (X11_RenderData *) renderer->driverdata;
999 SDL_Window *window = renderer->window; 1053 SDL_Window *window = renderer->window;
1000 XPoint *xpoints, *xpoint; 1054 XPoint *xpoints, *xpoint;
1001 int i, xcount; 1055 int i, xcount;
1002 1056 SDL_Rect clip, rect;
1003 if (data->makedirty) { 1057
1004 SDL_Rect rect; 1058 clip.x = 0;
1005 1059 clip.y = 0;
1006 /* Get the smallest rectangle that contains everything */ 1060 clip.w = window->w;
1007 rect.x = 0; 1061 clip.h = window->h;
1008 rect.y = 0; 1062
1009 rect.w = window->w; 1063 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
1010 rect.h = window->h; 1064 #ifndef NO_SHARED_MEMORY
1011 if (!SDL_EnclosePoints(points, count, &rect, &rect)) { 1065 if (data->use_xrender && data->stencil_image && data->stencil_surface) {
1012 /* Nothing to draw */ 1066 SDL_FillRect(data->stencil_surface, NULL, 0x00);
1013 return 0; 1067
1014 } 1068 SDL_SetClipRect(data->stencil_surface, NULL);
1015 SDL_AddDirtyRect(&data->dirty, &rect); 1069 SDL_DrawPoints(data->stencil_surface, points, count, 0xFF);
1016 } 1070
1017 1071 XShmPutImage(data->display, data->stencil, data->stencil_gc, data->stencil_image,
1018 xpoint = xpoints = SDL_stack_alloc(XPoint, count); 1072 0, 0, 0, 0, window->w, window->h, False);
1019 xcount = 0; 1073 } else
1020 for (i = 0; i < count; ++i) { 1074 #endif
1021 int x = points[i].x; 1075 #endif
1022 int y = points[i].y; 1076 {
1023 if (x < 0 || x >= window->w || y < 0 || y >= window->h) { 1077 if (data->makedirty) {
1024 continue; 1078
1025 } 1079 /* Get the smallest rectangle that contains everything */
1026 xpoint->x = (short)x; 1080 rect.x = 0;
1027 xpoint->y = (short)y; 1081 rect.y = 0;
1028 ++xpoint; 1082 rect.w = window->w;
1029 ++xcount; 1083 rect.h = window->h;
1030 } 1084 if (!SDL_EnclosePoints(points, count, &rect, &rect)) {
1031 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 1085 /* Nothing to draw */
1032 if (data->use_xrender == SDL_TRUE) { 1086 return 0;
1087 }
1088 SDL_AddDirtyRect(&data->dirty, &rect);
1089 }
1090
1091 xpoint = xpoints = SDL_stack_alloc(XPoint, count);
1092 xcount = 0;
1093 for (i = 0; i < count; ++i) {
1094 int x = points[i].x;
1095 int y = points[i].y;
1096 if (x < 0 || x >= window->w || y < 0 || y >= window->h) {
1097 continue;
1098 }
1099 xpoint->x = (short)x;
1100 xpoint->y = (short)y;
1101 ++xpoint;
1102 ++xcount;
1103 }
1104 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
1105 if (data->use_xrender) {
1106 XSetForeground(data->display, data->stencil_gc, 0x00);
1107 XFillRectangle(data->display, data->stencil, data->stencil_gc,
1108 0, 0, window->w, window->h);
1109 XSetForeground(data->display, data->stencil_gc, 0xFF);
1110 XDrawPoints(data->display, data->stencil, data->stencil_gc, xpoints, xcount,
1111 CoordModeOrigin);
1112 }
1113 #endif
1114 }
1115 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
1116 if (data->use_xrender) {
1033 XRenderColor foreground; 1117 XRenderColor foreground;
1034 XRenderPictureAttributes attributes;
1035 unsigned long valuemask;
1036
1037 foreground = xrenderdrawcolor(renderer); 1118 foreground = xrenderdrawcolor(renderer);
1038 /* Set the clip mask to restrict rendering to 1119 XRenderFillRectangle(data->display, PictOpSrc, data->brush_pict,
1039 * the primitive being drawn 1120 &foreground, 0, 0, 1, 1);
1040 */ 1121 XRenderComposite(data->display, data->blend_op, data->brush_pict,
1041 attributes.clip_mask = data->mask; 1122 data->stencil_pict, data->drawable_pict,
1042 valuemask = CPClipMask; 1123 0, 0, 0, 0, 0, 0, window->w, window->h);
1043
1044 XSetForeground(data->display, data->mask_gc, 0);
1045 XFillRectangle(data->display, data->mask, data->mask_gc,
1046 0, 0, window->w, window->h);
1047 XSetForeground(data->display, data->mask_gc, 1);
1048
1049 XDrawPoints(data->display, data->mask, data->mask_gc, xpoints, xcount,
1050 CoordModeOrigin);
1051 XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes);
1052 /*XRenderFillRectangle(data->display, data->blend_op, data->drawable_pict,
1053 &foreground, 0, 0, window->w, window->h);*/
1054 // Reset the clip_mask
1055 attributes.clip_mask = None;
1056 XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes);
1057 } 1124 }
1058 else 1125 else
1059 #endif 1126 #endif
1060 { 1127 {
1061 unsigned long foreground = renderdrawcolor(renderer, 1); 1128 unsigned long foreground = renderdrawcolor(renderer, 1);
1065 if (xcount > 0) { 1132 if (xcount > 0) {
1066 XDrawPoints(data->display, data->drawable, data->gc, xpoints, xcount, 1133 XDrawPoints(data->display, data->drawable, data->gc, xpoints, xcount,
1067 CoordModeOrigin); 1134 CoordModeOrigin);
1068 } 1135 }
1069 } 1136 }
1137
1070 SDL_stack_free(xpoints); 1138 SDL_stack_free(xpoints);
1071 1139
1072 return 0; 1140 return 0;
1073 } 1141 }
1074 1142
1087 1155
1088 clip.x = 0; 1156 clip.x = 0;
1089 clip.y = 0; 1157 clip.y = 0;
1090 clip.w = window->w; 1158 clip.w = window->w;
1091 clip.h = window->h; 1159 clip.h = window->h;
1092 1160 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
1093 Pixmap drawable; 1161 #ifndef NO_SHARED_MEMORY
1094 GC gc; 1162 if (data->use_xrender && data->stencil_image && data->stencil_surface) {
1095 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 1163 SDL_FillRect(data->stencil_surface, NULL, 0x00);
1096 if (data->use_xrender == SDL_TRUE) { 1164
1097 drawable = data->mask; 1165 SDL_SetClipRect(data->stencil_surface, NULL);
1098 gc = data->mask_gc; 1166 SDL_DrawLines(data->stencil_surface, points, count, 0xFF);
1099 XSetForeground(data->display, data->mask_gc, 0); 1167
1100 XFillRectangle(data->display, data->mask, data->mask_gc, 1168 XShmPutImage(data->display, data->stencil, data->stencil_gc, data->stencil_image,
1101 0, 0, window->w, window->h); 1169 0, 0, 0, 0, window->w, window->h, False);
1102 XSetForeground(data->display, data->mask_gc, 1); 1170 } else
1103 } 1171 #endif
1104 else
1105 #endif 1172 #endif
1106 { 1173 {
1107 drawable = data->drawable; 1174 Pixmap drawable;
1108 gc = data->gc; 1175 GC gc;
1109 } 1176 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
1110 1177 if (data->use_xrender) {
1111 foreground = renderdrawcolor(renderer, 1); 1178 drawable = data->stencil;
1112 XSetForeground(data->display, data->gc, foreground); 1179 gc = data->stencil_gc;
1113 1180 XSetForeground(data->display, data->stencil_gc, 0x00);
1114 xpoint = xpoints = SDL_stack_alloc(XPoint, count); 1181 XFillRectangle(data->display, data->stencil, data->stencil_gc,
1115 xcount = 0; 1182 0, 0, window->w, window->h);
1116 minx = INT_MAX; 1183 XSetForeground(data->display, data->stencil_gc, 0xFF);
1117 miny = INT_MAX; 1184 }
1118 maxx = INT_MIN; 1185 else
1119 maxy = INT_MIN; 1186 #endif
1120 for (i = 0; i < count; ++i) { 1187 {
1121 int x = points[i].x; 1188 drawable = data->drawable;
1122 int y = points[i].y; 1189 gc = data->gc;
1123 1190 }
1124 /* If the point is inside the window, add it to the list */ 1191
1125 if (x >= 0 && x < window->w && y >= 0 && y < window->h) { 1192 foreground = renderdrawcolor(renderer, 1);
1126 if (x < minx) { 1193 XSetForeground(data->display, data->gc, foreground);
1127 minx = x; 1194
1128 } else if (x > maxx) { 1195 xpoint = xpoints = SDL_stack_alloc(XPoint, count);
1129 maxx = x; 1196 xcount = 0;
1130 } 1197 minx = INT_MAX;
1131 if (y < miny) { 1198 miny = INT_MAX;
1132 miny = y; 1199 maxx = INT_MIN;
1133 } else if (y > maxy) { 1200 maxy = INT_MIN;
1134 maxy = y; 1201 for (i = 0; i < count; ++i) {
1135 } 1202 int x = points[i].x;
1136 xpoint->x = (short)x; 1203 int y = points[i].y;
1137 xpoint->y = (short)y; 1204
1138 ++xpoint; 1205 /* If the point is inside the window, add it to the list */
1139 ++xcount; 1206 if (x >= 0 && x < window->w && y >= 0 && y < window->h) {
1140 continue; 1207 if (x < minx) {
1141 } 1208 minx = x;
1142 1209 } else if (x > maxx) {
1143 /* We need to clip the line segments joined by this point */ 1210 maxx = x;
1144 if (xcount > 0) {
1145 int x1 = xpoint[-1].x;
1146 int y1 = xpoint[-1].y;
1147 int x2 = x;
1148 int y2 = y;
1149 if (SDL_IntersectRectAndLine(&clip, &x1, &y1, &x2, &y2)) {
1150 if (x2 < minx) {
1151 minx = x2;
1152 } else if (x2 > maxx) {
1153 maxx = x2;
1154 } 1211 }
1155 if (y2 < miny) { 1212 if (y < miny) {
1156 miny = y2; 1213 miny = y;
1157 } else if (y2 > maxy) { 1214 } else if (y > maxy) {
1158 maxy = y2; 1215 maxy = y;
1159 } 1216 }
1160 xpoint->x = (short)x2; 1217 xpoint->x = (short)x;
1161 xpoint->y = (short)y2; 1218 xpoint->y = (short)y;
1162 ++xpoint; 1219 ++xpoint;
1163 ++xcount; 1220 ++xcount;
1164 } 1221 continue;
1165 XDrawLines(data->display, drawable, gc, 1222 }
1166 xpoints, xcount, CoordModeOrigin); 1223
1224 /* We need to clip the line segments joined by this point */
1225 if (xcount > 0) {
1226 int x1 = xpoint[-1].x;
1227 int y1 = xpoint[-1].y;
1228 int x2 = x;
1229 int y2 = y;
1230 if (SDL_IntersectRectAndLine(&clip, &x1, &y1, &x2, &y2)) {
1231 if (x2 < minx) {
1232 minx = x2;
1233 } else if (x2 > maxx) {
1234 maxx = x2;
1235 }
1236 if (y2 < miny) {
1237 miny = y2;
1238 } else if (y2 > maxy) {
1239 maxy = y2;
1240 }
1241 xpoint->x = (short)x2;
1242 xpoint->y = (short)y2;
1243 ++xpoint;
1244 ++xcount;
1245 }
1246 XDrawLines(data->display, drawable, gc,
1247 xpoints, xcount, CoordModeOrigin);
1248 if (xpoints[0].x != x2 || xpoints[0].y != y2) {
1249 XDrawPoint(data->display, drawable, gc, x2, y2);
1250 }
1251 if (data->makedirty) {
1252 SDL_Rect rect;
1253
1254 rect.x = minx;
1255 rect.y = miny;
1256 rect.w = (maxx - minx) + 1;
1257 rect.h = (maxy - miny) + 1;
1258 SDL_AddDirtyRect(&data->dirty, &rect);
1259 }
1260 xpoint = xpoints;
1261 xcount = 0;
1262 minx = INT_MAX;
1263 miny = INT_MAX;
1264 maxx = INT_MIN;
1265 maxy = INT_MIN;
1266 }
1267 if (i < (count-1)) {
1268 int x1 = x;
1269 int y1 = y;
1270 int x2 = points[i+1].x;
1271 int y2 = points[i+1].y;
1272 if (SDL_IntersectRectAndLine(&clip, &x1, &y1, &x2, &y2)) {
1273 if (x1 < minx) {
1274 minx = x1;
1275 } else if (x1 > maxx) {
1276 maxx = x1;
1277 }
1278 if (y1 < miny) {
1279 miny = y1;
1280 } else if (y1 > maxy) {
1281 maxy = y1;
1282 }
1283 xpoint->x = (short)x1;
1284 xpoint->y = (short)y1;
1285 ++xpoint;
1286 ++xcount;
1287 }
1288 }
1289 }
1290 if (xcount > 1) {
1291 int x2 = xpoint[-1].x;
1292 int y2 = xpoint[-1].y;
1293 XDrawLines(data->display, drawable, gc, xpoints, xcount,
1294 CoordModeOrigin);
1167 if (xpoints[0].x != x2 || xpoints[0].y != y2) { 1295 if (xpoints[0].x != x2 || xpoints[0].y != y2) {
1168 XDrawPoint(data->display, drawable, gc, x2, y2); 1296 XDrawPoint(data->display, drawable, gc, x2, y2);
1169 } 1297 }
1170 if (data->makedirty) { 1298 if (data->makedirty) {
1171 SDL_Rect rect; 1299 SDL_Rect rect;
1174 rect.y = miny; 1302 rect.y = miny;
1175 rect.w = (maxx - minx) + 1; 1303 rect.w = (maxx - minx) + 1;
1176 rect.h = (maxy - miny) + 1; 1304 rect.h = (maxy - miny) + 1;
1177 SDL_AddDirtyRect(&data->dirty, &rect); 1305 SDL_AddDirtyRect(&data->dirty, &rect);
1178 } 1306 }
1179 xpoint = xpoints; 1307 }
1180 xcount = 0; 1308 }
1181 minx = INT_MAX; 1309 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
1182 miny = INT_MAX; 1310 if (data->use_xrender) {
1183 maxx = INT_MIN;
1184 maxy = INT_MIN;
1185 }
1186 if (i < (count-1)) {
1187 int x1 = x;
1188 int y1 = y;
1189 int x2 = points[i+1].x;
1190 int y2 = points[i+1].y;
1191 if (SDL_IntersectRectAndLine(&clip, &x1, &y1, &x2, &y2)) {
1192 if (x1 < minx) {
1193 minx = x1;
1194 } else if (x1 > maxx) {
1195 maxx = x1;
1196 }
1197 if (y1 < miny) {
1198 miny = y1;
1199 } else if (y1 > maxy) {
1200 maxy = y1;
1201 }
1202 xpoint->x = (short)x1;
1203 xpoint->y = (short)y1;
1204 ++xpoint;
1205 ++xcount;
1206 }
1207 }
1208 }
1209 if (xcount > 1) {
1210 int x2 = xpoint[-1].x;
1211 int y2 = xpoint[-1].y;
1212 XDrawLines(data->display, drawable, gc, xpoints, xcount,
1213 CoordModeOrigin);
1214 if (xpoints[0].x != x2 || xpoints[0].y != y2) {
1215 XDrawPoint(data->display, drawable, gc, x2, y2);
1216 }
1217 if (data->makedirty) {
1218 SDL_Rect rect;
1219
1220 rect.x = minx;
1221 rect.y = miny;
1222 rect.w = (maxx - minx) + 1;
1223 rect.h = (maxy - miny) + 1;
1224 SDL_AddDirtyRect(&data->dirty, &rect);
1225 }
1226 }
1227 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
1228 if(data->use_xrender == SDL_TRUE) {
1229 XRenderColor xrforeground = xrenderdrawcolor(renderer); 1311 XRenderColor xrforeground = xrenderdrawcolor(renderer);
1230 XRenderPictureAttributes attributes; 1312 XRenderFillRectangle(data->display, PictOpSrc, data->brush_pict,
1231 attributes.clip_mask = data->mask; 1313 &xrforeground, 0, 0, 1, 1);
1232 unsigned long valuemask = CPClipMask; 1314 XRenderComposite(data->display, data->blend_op, data->brush_pict,
1233 XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes); 1315 data->stencil_pict, data->drawable_pict,
1234 /*XRenderFillRectangle(data->display, data->blend_op, data->drawable_pict, 1316 0, 0, 0, 0, 0, 0, window->w, window->h);
1235 &xrforeground, 0, 0, window->w, window->h);*/
1236 attributes.clip_mask = None;
1237 XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes);
1238 } 1317 }
1239 #endif 1318 #endif
1240 SDL_stack_free(xpoints); 1319 SDL_stack_free(xpoints);
1241 1320
1242 return 0; 1321 return 0;
1256 clip.x = 0; 1335 clip.x = 0;
1257 clip.y = 0; 1336 clip.y = 0;
1258 clip.w = window->w; 1337 clip.w = window->w;
1259 clip.h = window->h; 1338 clip.h = window->h;
1260 1339
1261 for (i = 0; i < count; ++i) { 1340 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
1262 if (!SDL_IntersectRect(rects[i], &clip, &rect)) { 1341 #ifndef NO_SHARED_MEMORY
1263 continue; 1342 if (data->use_xrender && data->stencil_image && data->stencil_surface) {
1264 } 1343 SDL_FillRect(data->stencil_surface, NULL, 0x00);
1265 1344
1266 xrect->x = (short)rect.x; 1345 SDL_SetClipRect(data->stencil_surface, NULL);
1267 xrect->y = (short)rect.y; 1346 SDL_DrawRects(data->stencil_surface, rects, count, 1);
1268 xrect->width = (unsigned short)rect.w; 1347
1269 xrect->height = (unsigned short)rect.h; 1348 XShmPutImage(data->display, data->stencil, data->stencil_gc, data->stencil_image,
1270 ++xrect; 1349 0, 0, 0, 0, window->w, window->h, False);
1271 ++xcount; 1350 }
1272 1351 else
1273 if (data->makedirty) { 1352 #endif
1274 SDL_AddDirtyRect(&data->dirty, &rect); 1353 #endif
1275 } 1354 {
1276 } 1355
1277 1356 for (i = 0; i < count; ++i) {
1278 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 1357 if (!SDL_IntersectRect(rects[i], &clip, &rect)) {
1279 if(data->use_xrender == SDL_TRUE) { 1358 continue;
1359 }
1360
1361 xrect->x = (short)rect.x;
1362 xrect->y = (short)rect.y;
1363 xrect->width = (unsigned short)rect.w;
1364 xrect->height = (unsigned short)rect.h;
1365 ++xrect;
1366 ++xcount;
1367
1368 if (data->makedirty) {
1369 SDL_AddDirtyRect(&data->dirty, &rect);
1370 }
1371 }
1372 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
1373 if (data->use_xrender) {
1374 XSetForeground(data->display, data->stencil_gc, 0x00);
1375 XFillRectangle(data->display, data->stencil, data->stencil_gc,
1376 0, 0, window->w, window->h);
1377 XSetForeground(data->display, data->stencil_gc, 0xFF);
1378
1379 XDrawRectangles(data->display, data->stencil, data->stencil_gc, xrects, xcount);
1380 }
1381 #endif
1382 }
1383 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
1384 if (data->use_xrender) {
1280 XRenderColor foreground; 1385 XRenderColor foreground;
1281 XRenderPictureAttributes attributes;
1282 unsigned long valuemask;
1283
1284 foreground = xrenderdrawcolor(renderer); 1386 foreground = xrenderdrawcolor(renderer);
1285 valuemask = CPClipMask; 1387
1286 attributes.clip_mask = data->mask; 1388 XRenderFillRectangle(data->display, PictOpSrc, data->brush_pict,
1287 1389 &foreground, 0, 0, 1, 1);
1288 XSetForeground(data->display, data->mask_gc, 0); 1390
1289 XFillRectangle(data->display, data->mask, data->mask_gc, 1391 XRenderComposite(data->display, data->blend_op, data->brush_pict,
1290 0, 0, window->w, window->h); 1392 data->stencil_pict, data->drawable_pict,
1291 XSetForeground(data->display, data->mask_gc, 1); 1393 0, 0, 0, 0, 0, 0, window->w, window->h);
1292
1293 XDrawRectangles(data->display, data->mask, data->mask_gc, xrects, xcount);
1294 XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes);
1295 /*XRenderFillRectangle(data->display, data->blend_op, data->drawable_pict,
1296 &foreground, 0, 0, window->w, window->h);*/
1297 attributes.clip_mask = None;
1298 XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes);
1299 } 1394 }
1300 else 1395 else
1301 #endif 1396 #endif
1302 { 1397 {
1303 unsigned long foreground; 1398 unsigned long foreground;
1324 1419
1325 clip.x = 0; 1420 clip.x = 0;
1326 clip.y = 0; 1421 clip.y = 0;
1327 clip.w = window->w; 1422 clip.w = window->w;
1328 clip.h = window->h; 1423 clip.h = window->h;
1329 1424
1330 int i, xcount; 1425 int i, xcount;
1331 XRectangle *xrects, *xrect; 1426 XRectangle *xrects, *xrect;
1332 xrect = xrects = SDL_stack_alloc(XRectangle, count); 1427 xrect = xrects = SDL_stack_alloc(XRectangle, count);
1333 xcount = 0; 1428 xcount = 0;
1334 for (i = 0; i < count; ++i) { 1429 for (i = 0; i < count; ++i) {
1347 SDL_AddDirtyRect(&data->dirty, &rect); 1442 SDL_AddDirtyRect(&data->dirty, &rect);
1348 } 1443 }
1349 } 1444 }
1350 1445
1351 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 1446 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
1352 if(data->use_xrender == SDL_TRUE) { 1447 if (data->use_xrender) {
1353 XRenderColor foreground; 1448 XRenderColor foreground;
1354 XRenderPictureAttributes attributes;
1355
1356 foreground = xrenderdrawcolor(renderer); 1449 foreground = xrenderdrawcolor(renderer);
1357 attributes.clip_mask = data->mask; 1450 XRenderFillRectangles(data->display, data->blend_op, data->drawable_pict,
1358 1451 &foreground, xrects, xcount);
1359 XSetForeground(data->display, data->mask_gc, 0);
1360 XFillRectangle(data->display, data->mask, data->mask_gc,
1361 0, 0, window->w, window->h);
1362 XSetForeground(data->display, data->mask_gc, 1);
1363
1364 XFillRectangles(data->display, data->mask, data->mask_gc,
1365 xrects, xcount);
1366
1367 XRenderChangePicture(data->display, data->drawable_pict, CPClipMask, &attributes);
1368 /*XRenderFillRectangle(data->display, data->blend_op, data->drawable_pict,
1369 &foreground, 0, 0, window->w, window->h);*/
1370 attributes.clip_mask = None;
1371 XRenderChangePicture(data->display, data->drawable_pict, CPClipMask, &attributes);
1372 } 1452 }
1373 else 1453 else
1374 #endif 1454 #endif
1375 { 1455 {
1376 unsigned long foreground; 1456 unsigned long foreground;
1381 XFillRectangles(data->display, data->drawable, data->gc, 1461 XFillRectangles(data->display, data->drawable, data->gc,
1382 xrects, xcount); 1462 xrects, xcount);
1383 } 1463 }
1384 1464
1385 SDL_stack_free(xrects); 1465 SDL_stack_free(xrects);
1386
1387 return 0; 1466 return 0;
1388 } 1467 }
1389 1468
1390 static int 1469 static int
1391 X11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, 1470 X11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
1724 } 1803 }
1725 if (data->gc) { 1804 if (data->gc) {
1726 XFreeGC(data->display, data->gc); 1805 XFreeGC(data->display, data->gc);
1727 } 1806 }
1728 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 1807 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
1729 if (data->mask_gc) { 1808 if (data->stencil_gc) {
1730 XFreeGC(data->display, data->mask_gc); 1809 XFreeGC(data->display, data->stencil_gc);
1731 } 1810 }
1732 if (data->mask) { 1811 if (data->stencil) {
1733 XFreePixmap(data->display, data->mask); 1812 XFreePixmap(data->display, data->stencil);
1734 } 1813 }
1735 if (data->drawable_pict) { 1814 if (data->drawable_pict) {
1736 XRenderFreePicture(data->display, data->drawable_pict); 1815 XRenderFreePicture(data->display, data->drawable_pict);
1737 } 1816 }
1738 if (data->xwindow_pict) { 1817 if (data->xwindow_pict) {