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