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