comparison src/video/x11/SDL_x11render.c @ 4573:6399178be313

Completed work on X11_CreateTexture. Added lots of safety features. These include support for drawing a texture using the core protocol while other textures are drawn using Xrender if Xrender does not support the color format of the said texture or any other fault with Xrender.
author Sunny Sachanandani <sunnysachanandani@gmail.com>
date Fri, 28 May 2010 20:40:09 +0530
parents 266ec93f49af
children bfb4933c0efa
comparison
equal deleted inserted replaced
4572:266ec93f49af 4573:6399178be313
120 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 120 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
121 Picture picture; 121 Picture picture;
122 XRenderPictFormat* picture_fmt; 122 XRenderPictFormat* picture_fmt;
123 XRenderPictureAttributes picture_attr; 123 XRenderPictureAttributes picture_attr;
124 unsigned int picture_attr_valuemask; 124 unsigned int picture_attr_valuemask;
125 SDL_bool xrender_available;
125 #endif 126 #endif
126 XImage *image; 127 XImage *image;
127 #ifndef NO_SHARED_MEMORY 128 #ifndef NO_SHARED_MEMORY
128 /* MIT shared memory extension information */ 129 /* MIT shared memory extension information */
129 XShmSegmentInfo shminfo; 130 XShmSegmentInfo shminfo;
216 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 217 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
217 int event_basep, error_basep; 218 int event_basep, error_basep;
218 if(XRenderQueryExtension(data->display, &event_basep, &error_basep) == True) { 219 if(XRenderQueryExtension(data->display, &event_basep, &error_basep) == True) {
219 data->xrender_available = SDL_TRUE; 220 data->xrender_available = SDL_TRUE;
220 data->xwindow_pict_fmt = XRenderFindVisualFormat(data->display, data->visual); 221 data->xwindow_pict_fmt = XRenderFindVisualFormat(data->display, data->visual);
222 if(!xwindow_pict_fmt) {
223 data->xrender_available = SDL_FALSE;
224 }
221 data->xwindow_pict_attr.graphics_exposures = False; 225 data->xwindow_pict_attr.graphics_exposures = False;
222 data->xwindow_pict_attr_valuemask = CPGraphicsExposure; 226 data->xwindow_pict_attr_valuemask = CPGraphicsExposure;
223 data->xwindow_pict = XRenderCreatePicture(data->display, data->xwindow, data->xwindow_pict_fmt, 227 data->xwindow_pict = XRenderCreatePicture(data->display, data->xwindow, data->xwindow_pict_fmt,
224 data->xwindow_pict_attr_valuemask, &data->xwindow_pict_attr); 228 data->xwindow_pict_attr_valuemask, &data->xwindow_pict_attr);
229 if(!data->xwindow_pict) {
230 data->xrender_available = SDL_FALSE;
231 }
225 } 232 }
226 else { 233 else {
227 data->xrender_available = SDL_FALSE; 234 data->xrender_available = SDL_FALSE;
228 } 235 }
229 #endif 236 #endif
273 if (data->pixmaps[i] == None) { 280 if (data->pixmaps[i] == None) {
274 X11_DestroyRenderer(renderer); 281 X11_DestroyRenderer(renderer);
275 SDL_SetError("XCreatePixmap() failed"); 282 SDL_SetError("XCreatePixmap() failed");
276 return NULL; 283 return NULL;
277 } 284 }
278 data->pixmap_picts[i] = 285 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
279 XCreatePicture(data->display, data->pixmap[i], data->xwindow_pict_fmt, 286 if(data->xrender_available == SDL_TRUE) {
280 data->xwindow_pict_attr_valuemask, &xwindow_pict_attr); 287 data->pixmap_picts[i] =
288 XCreatePicture(data->display, data->pixmap[i], data->xwindow_pict_fmt,
289 data->xwindow_pict_attr_valuemask, &xwindow_pict_attr);
290 if(!data->pixmap_picts[i]) {
291 data->xrender_available = SDL_FALSE;
292 }
293 }
294 #endif
281 } 295 }
282 if (n > 0) { 296 if (n > 0) {
283 data->drawable = data->pixmaps[0]; 297 data->drawable = data->pixmaps[0];
284 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 298 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
285 if(data->xrender_available == SDL_TRUE) 299 if(data->xrender_available == SDL_TRUE)
351 if (data->pixmaps[i] == None) { 365 if (data->pixmaps[i] == None) {
352 SDL_SetError("XCreatePixmap() failed"); 366 SDL_SetError("XCreatePixmap() failed");
353 return -1; 367 return -1;
354 } 368 }
355 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 369 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
356 data->pictures[i] = 370 if(data->xrender_available == SDL_TRUE) {
357 XCreatePicture(data->display, data->pixmap[i], data->xwindow_pict_fmt, 371 data->pictures[i] =
358 data->xwindow_pict_attr_valuemask, &data->xwindow_pict_attr); 372 XCreatePicture(data->display, data->pixmap[i], data->xwindow_pict_fmt,
373 data->xwindow_pict_attr_valuemask, &data->xwindow_pict_attr);
374 if(!data->pictures[i]) {
375 data->xrender_available = SDL_FALSE;
376 }
377 }
359 #endif 378 #endif
360 } 379 }
361 if (n > 0) { 380 if (n > 0) {
362 data->drawable = data->pixmaps[0]; 381 data->drawable = data->pixmaps[0];
363 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 382 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
375 X11_RenderData *renderdata = (X11_RenderData *) renderer->driverdata; 394 X11_RenderData *renderdata = (X11_RenderData *) renderer->driverdata;
376 SDL_Window *window = renderer->window; 395 SDL_Window *window = renderer->window;
377 SDL_VideoDisplay *display = window->display; 396 SDL_VideoDisplay *display = window->display;
378 X11_TextureData *data; 397 X11_TextureData *data;
379 int pitch_alignmask = ((renderdata->scanline_pad / 8) - 1); 398 int pitch_alignmask = ((renderdata->scanline_pad / 8) - 1);
399
380 400
381 data = (X11_TextureData *) SDL_calloc(1, sizeof(*data)); 401 data = (X11_TextureData *) SDL_calloc(1, sizeof(*data));
382 if (!data) { 402 if (!data) {
383 SDL_OutOfMemory(); 403 SDL_OutOfMemory();
384 return -1; 404 return -1;
391 if (!data->yuv) { 411 if (!data->yuv) {
392 return -1; 412 return -1;
393 } 413 }
394 data->format = display->current_mode.format; 414 data->format = display->current_mode.format;
395 } else { 415 } else {
396 /* The image/pixmap depth must be the same as the window or you 416 /* If Xrender support is builtin we only need to check whether
397 get a BadMatch error when trying to putimage or copyarea. 417 Xrender is available at runtime. If it is available there
398 This BadMatch error 418 can be no BadMatch error since Xrender takes care of that.
399 */ 419 */
400 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 420 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
401 if(renderdata->xrender_available == SDL_False) { 421 if(renderdata->xrender_available == SDL_False) {
402 if (texture->format != display->current_mode.format) { 422 if (texture->format != display->current_mode.format) {
403 SDL_SetError("Texture format doesn't match window format"); 423 SDL_SetError("Texture format doesn't match window format");
404 return -1; 424 return -1;
405 } 425 }
406 } 426 }
407 #else 427 #else
428 /* The image/pixmap depth must be the same as the window or you
429 get a BadMatch error when trying to putimage or copyarea.
430 This BadMatch error
431 */
408 if (texture->format != display->current_mode.format) { 432 if (texture->format != display->current_mode.format) {
409 SDL_SetError("Texture format doesn't match window format"); 433 SDL_SetError("Texture format doesn't match window format");
410 return -1; 434 return -1;
411 } 435 }
412 #endif 436 #endif
489 SDL_SetError("XCreatePixmap() failed"); 513 SDL_SetError("XCreatePixmap() failed");
490 return -1; 514 return -1;
491 } 515 }
492 516
493 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 517 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
494 data->picture_fmt = 518 if(renderdata->xrender_available) {
495 XRenderFindVisualFormat(renderdata->display, 519 data->xrender_available = SDL_TRUE;
496 data->picture = 520 unsigned long x11_fmt_mask; // Format mask
497 XCreatePicture(renderdata->display, data->pixmap, 521 XRenderPictFormat x11_templ_fmt; // Format template
498 522 x11_fmt_mask =
523 (PictFormatDepth | PictFormatRedMask | PictFormatGreenMask
524 | PictFormatBlueMask);
525 x11_templ_fmt.depth = (data->format).BitsPerPixel;
526 x11_temp_fmt.direct.redMask = (data->format).Rmask;
527 x11_temp_fmt.direct.greenMask = (data->format).Gmask;
528 x11_temp_fmt.direct.blueMask = (data->format).Bmask;
529 x11_temp_fmt.direct.alphaMask = (data->format).Amask;
530 /* Return one matching XRenderPictFormat */
531 data->pict_fmt =
532 XRenderFindFormat(renderdata->display, x11_fmt_mask, &x11_templ_fmt, 1);
533 if(!data->pict_fmt) {
534 data->xrender_available = SDL_FALSE;
535 }
536 data->picture_attr_valuemask = CPGraphicsExposure;
537 (data->picture_attr).graphics_exposures = False;
538 data->picture =
539 XCreatePicture(renderdata->display, data->pixmap, data->picture_fmt,
540 data->picture_attr_valuemask, &(data->picture_attr));
541 if(!data->picture) {
542 data->xrender_available = SDL_FALSE;
543 }
544 }
545 /* We thought we could render the texture with Xrender but this was
546 not possible for some reason. Now we must ensure that texture
547 format and window format match to avoid a BadMatch error.
548 */
549 if(data->xrender_available == SDL_FALSE) {
550 if (texture->format != display->current_mode.format) {
551 SDL_SetError("Texture format doesn't match window format");
552 return -1;
553 }
554 }
555 #endif
499 data->image = 556 data->image =
500 XCreateImage(renderdata->display, renderdata->visual, 557 XCreateImage(renderdata->display, renderdata->visual,
501 renderdata->depth, ZPixmap, 0, NULL, texture->w, 558 renderdata->depth, ZPixmap, 0, NULL, texture->w,
502 texture->h, SDL_BYTESPERPIXEL(data->format) * 8, 559 texture->h, SDL_BYTESPERPIXEL(data->format) * 8,
503 data->pitch); 560 data->pitch);