comparison src/video/x11/SDL_x11render.c @ 4593:3892fe2f6537

Fixed so many things. See the changelog listed below. 1. Use SDL_X11_HAVE_XRENDER to check for RENDER at runtime. 2. Added lots of comments. 3. Added checks and lots of calls to SDL_SetError(). 4. Fixed X11_CreateTexture() so that the pixmap and image created are for the format specified by the user and not the window format. This is only for the RENDER case. 5. The above change required that functions to convert SDL pixel format enums to Visuals and XRenderPictFormats be added. 6. Fixed lots of 'style' issues.
author Sunny Sachanandani <sunnysachanandani@gmail.com>
date Sat, 17 Jul 2010 15:38:24 +0530
parents 1e998db9b597
children f28c23cc1a08
comparison
equal deleted inserted replaced
4592:ccdde189a3c5 4593:3892fe2f6537
118 typedef struct 118 typedef struct
119 { 119 {
120 SDL_SW_YUVTexture *yuv; 120 SDL_SW_YUVTexture *yuv;
121 Uint32 format; 121 Uint32 format;
122 Pixmap pixmap; 122 Pixmap pixmap;
123 int depth;
124 Visual *visual;
125 GC gc;
123 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 126 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
124 Picture picture; 127 Picture picture;
125 XRenderPictFormat* picture_fmt; 128 XRenderPictFormat* picture_fmt;
126 int blend_op; 129 int blend_op;
127 // SDL_bool use_xrender; 130 // SDL_bool use_xrender;
241 renderer->driverdata = data; 244 renderer->driverdata = data;
242 245
243 renderer->info.flags = SDL_RENDERER_ACCELERATED; 246 renderer->info.flags = SDL_RENDERER_ACCELERATED;
244 247
245 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 248 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
246 int event_basep, error_basep; 249 data->use_xrender = SDL_FALSE;
247 if(XRenderQueryExtension(data->display, 250 if (SDL_X11_HAVE_XRENDER) {
248 &event_basep, 251 // Query the extension. This is the server runtime check.
249 &error_basep) == True) { 252 int event_basep, error_basep;
250 data->use_xrender = SDL_TRUE; 253 if(XRenderQueryExtension(data->display,
254 &event_basep, &error_basep) == True)
255 data->use_xrender = SDL_TRUE;
256 }
257 if (data->use_xrender) {
258 // Find the PictFormat from the visual.
259 // Should be an RGB PictFormat most of the time.
251 data->xwindow_pict_fmt = XRenderFindVisualFormat(data->display, 260 data->xwindow_pict_fmt = XRenderFindVisualFormat(data->display,
252 data->visual); 261 data->visual);
262 if (!data->xwindow_pict_fmt) {
263 SDL_SetError("XRenderFindVisualFormat() failed");
264 return NULL;
265 }
253 data->xwindow_pict = XRenderCreatePicture(data->display, 266 data->xwindow_pict = XRenderCreatePicture(data->display,
254 data->xwindow, 267 data->xwindow,
255 data->xwindow_pict_fmt, 268 data->xwindow_pict_fmt,
256 0, NULL); 269 0, NULL);
270 if (!data->xwindow_pict) {
271 SDL_SetError("XRenderCreatePicture() failed");
272 return NULL;
273 }
274 // FIXME: Clear the window. Is this required?
257 XRenderComposite(data->display, 275 XRenderComposite(data->display,
258 PictOpClear, 276 PictOpClear,
259 data->xwindow_pict, 277 data->xwindow_pict,
260 None, 278 None,
261 data->xwindow_pict, 279 data->xwindow_pict,
262 0, 0, 280 0, 0,
263 0, 0, 281 0, 0,
264 0, 0, 282 0, 0,
265 window->w, window->h); 283 window->w, window->h);
284 // Add some blending modes to the list of supported blending modes
266 renderer->info.blend_modes |= 285 renderer->info.blend_modes |=
267 (SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MASK); 286 (SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MASK);
268 // Create a 1 bit depth mask 287 // Create a clip mask that is used for rendering primitives.
269 data->mask = XCreatePixmap(data->display, data->xwindow, 288 data->mask = XCreatePixmap(data->display, data->xwindow,
270 window->w, window->h, 1); 289 window->w, window->h, 1);
290 if (!data->mask) {
291 SDL_SetError("XCreatePixmap() failed");
292 return NULL;
293 }
271 data->mask_pict = 294 data->mask_pict =
272 XRenderCreatePicture(data->display, data->mask, 295 XRenderCreatePicture(data->display, data->mask,
273 XRenderFindStandardFormat(data->display, 296 XRenderFindStandardFormat(data->display,
274 PictStandardA1), 297 PictStandardA1),
275 0, NULL); 298 0, NULL);
299 if (!data->mask_pict) {
300 SDL_SetError("XRenderCreatePicture() failed");
301 return NULL;
302 }
303 // Create the GC for the clip mask.
276 XGCValues gcv_mask; 304 XGCValues gcv_mask;
277 gcv_mask.foreground = 1; 305 gcv_mask.foreground = 1;
278 gcv_mask.background = 0; 306 gcv_mask.background = 0;
279 data->mask_gc = XCreateGC(data->display, data->mask, 307 data->mask_gc = XCreateGC(data->display, data->mask,
280 GCBackground | GCForeground, &gcv_mask); 308 GCBackground | GCForeground, &gcv_mask);
309 if (!data->mask_gc) {
310 SDL_SetError("XCreateGC() failed");
311 return NULL;
312 }
313 // Set the default blending mode.
281 renderer->blendMode = SDL_BLENDMODE_BLEND; 314 renderer->blendMode = SDL_BLENDMODE_BLEND;
282 data->blend_op = PictOpOver; 315 data->blend_op = PictOpOver;
283 }
284 else {
285 data->use_xrender = SDL_FALSE;
286 } 316 }
287 #endif 317 #endif
288 318
289 if (flags & SDL_RENDERER_SINGLEBUFFER) { 319 if (flags & SDL_RENDERER_SINGLEBUFFER) {
290 renderer->info.flags |= 320 renderer->info.flags |=
320 X11_DestroyRenderer(renderer); 350 X11_DestroyRenderer(renderer);
321 SDL_SetError("XCreatePixmap() failed"); 351 SDL_SetError("XCreatePixmap() failed");
322 return NULL; 352 return NULL;
323 } 353 }
324 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 354 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
325 if(data->use_xrender == SDL_TRUE) { 355 if (data->use_xrender) {
356 // Create xrender pictures for each of the pixmaps
357 // and clear the pixmaps.
326 data->pixmap_picts[i] = 358 data->pixmap_picts[i] =
327 XRenderCreatePicture(data->display, 359 XRenderCreatePicture(data->display,
328 data->pixmaps[i], 360 data->pixmaps[i],
329 XRenderFindStandardFormat(data->display, 361 XRenderFindStandardFormat(data->display,
330 PictStandardARGB32), 362 PictStandardARGB32),
331 0, None); 363 0, None);
332 XRenderComposite(data->display, 364 if (!data->pixmap_picts[i]) {
333 PictOpClear, 365 SDL_SetError("XRenderCreatePicture() failed");
334 data->pixmap_picts[i], 366 return NULL;
335 None, 367 }
336 data->pixmap_picts[i], 368
337 0, 0,
338 0, 0,
339 0, 0,
340 window->w, window->h);
341
342 }
343 #endif
344 }
345 if (n > 0) {
346 data->drawable = data->pixmaps[0];
347 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
348 if(data->use_xrender == SDL_TRUE)
349 data->drawable_pict = data->pixmap_picts[0];
350 #endif
351 data->makedirty = SDL_TRUE;
352 } else {
353 data->drawable = data->xwindow;
354 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
355 if(data->use_xrender == SDL_TRUE)
356 data->drawable_pict = data->xwindow_pict;
357 #endif
358 data->makedirty = SDL_FALSE;
359 }
360 data->current_pixmap = 0;
361
362 /* Get the format of the window */
363 if (!SDL_PixelFormatEnumToMasks
364 (display->current_mode.format, &bpp, &Rmask, &Gmask, &Bmask,
365 &Amask)) {
366 SDL_SetError("Unknown display format");
367 X11_DestroyRenderer(renderer);
368 return NULL;
369 }
370 SDL_InitFormat(&data->format, bpp, Rmask, Gmask, Bmask, Amask);
371
372 /* Create the drawing context */
373 gcv.graphics_exposures = False;
374 data->gc =
375 XCreateGC(data->display, data->xwindow, GCGraphicsExposures, &gcv);
376 if (!data->gc) {
377 X11_DestroyRenderer(renderer);
378 SDL_SetError("XCreateGC() failed");
379 return NULL;
380 }
381
382 return renderer;
383 }
384
385 static int
386 X11_DisplayModeChanged(SDL_Renderer * renderer)
387 {
388 X11_RenderData *data = (X11_RenderData *) renderer->driverdata;
389 SDL_Window *window = renderer->window;
390 int i, n;
391
392 if (renderer->info.flags & SDL_RENDERER_SINGLEBUFFER) {
393 n = 0;
394 } else if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP2) {
395 n = 2;
396 } else if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP3) {
397 n = 3;
398 } else {
399 n = 1;
400 }
401 for (i = 0; i < n; ++i) {
402 if (data->pixmaps[i] != None) {
403 XFreePixmap(data->display, data->pixmaps[i]);
404 data->pixmaps[i] = None;
405 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
406 data->pixmap_picts[i] = None;
407 #endif
408 }
409 }
410 for (i = 0; i < n; ++i) {
411 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
412 if (data->use_xrender) {
413 data->pixmaps[i] =
414 XCreatePixmap(data->display,
415 data->xwindow,
416 window->w,
417 window->h,
418 32);
419 }
420 else
421 #endif
422 {
423 data->pixmaps[i] =
424 XCreatePixmap(data->display, data->xwindow, window->w, window->h,
425 data->depth);
426 }
427 if (data->pixmaps[i] == None) {
428 SDL_SetError("XCreatePixmap() failed");
429 return -1;
430 }
431 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
432 if(data->use_xrender == SDL_TRUE) {
433 data->pixmap_picts[i] =
434 XRenderCreatePicture(data->display,
435 data->pixmaps[i],
436 XRenderFindStandardFormat(data->display,
437 PictStandardARGB32),
438 0, None);
439 XRenderComposite(data->display, 369 XRenderComposite(data->display,
440 PictOpClear, 370 PictOpClear,
441 data->pixmap_picts[i], 371 data->pixmap_picts[i],
442 None, 372 None,
443 data->pixmap_picts[i], 373 data->pixmap_picts[i],
444 0, 0, 374 0, 0,
445 0, 0, 375 0, 0,
446 0, 0, 376 0, 0,
447 window->w, window->h); 377 window->w, window->h);
448 378 }
449 }
450 #endif 379 #endif
451 } 380 }
452 if (n > 0) { 381 if (n > 0) {
453 data->drawable = data->pixmaps[0]; 382 data->drawable = data->pixmaps[0];
454 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 383 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
384 if(data->use_xrender == SDL_TRUE)
385 data->drawable_pict = data->pixmap_picts[0];
386 #endif
387 data->makedirty = SDL_TRUE;
388 } else {
389 data->drawable = data->xwindow;
390 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
391 if(data->use_xrender == SDL_TRUE)
392 data->drawable_pict = data->xwindow_pict;
393 #endif
394 data->makedirty = SDL_FALSE;
395 }
396 data->current_pixmap = 0;
397
398 /* Get the format of the window */
399 if (!SDL_PixelFormatEnumToMasks
400 (display->current_mode.format, &bpp, &Rmask, &Gmask, &Bmask,
401 &Amask)) {
402 SDL_SetError("Unknown display format");
403 X11_DestroyRenderer(renderer);
404 return NULL;
405 }
406 SDL_InitFormat(&data->format, bpp, Rmask, Gmask, Bmask, Amask);
407
408 /* Create the drawing context */
409 gcv.graphics_exposures = False;
410 data->gc =
411 XCreateGC(data->display, data->xwindow, GCGraphicsExposures, &gcv);
412 if (!data->gc) {
413 X11_DestroyRenderer(renderer);
414 SDL_SetError("XCreateGC() failed");
415 return NULL;
416 }
417
418 return renderer;
419 }
420
421 static int
422 X11_DisplayModeChanged(SDL_Renderer * renderer)
423 {
424 X11_RenderData *data = (X11_RenderData *) renderer->driverdata;
425 SDL_Window *window = renderer->window;
426 int i, n;
427
428 if (renderer->info.flags & SDL_RENDERER_SINGLEBUFFER) {
429 n = 0;
430 } else if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP2) {
431 n = 2;
432 } else if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP3) {
433 n = 3;
434 } else {
435 n = 1;
436 }
437 for (i = 0; i < n; ++i) {
438 if (data->pixmaps[i] != None) {
439 XFreePixmap(data->display, data->pixmaps[i]);
440 data->pixmaps[i] = None;
441 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
442 data->pixmap_picts[i] = None;
443 #endif
444 }
445 }
446 for (i = 0; i < n; ++i) {
447 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
448 if (data->use_xrender) {
449 data->pixmaps[i] =
450 XCreatePixmap(data->display,
451 data->xwindow,
452 window->w,
453 window->h,
454 32);
455 }
456 else
457 #endif
458 {
459 data->pixmaps[i] =
460 XCreatePixmap(data->display, data->xwindow, window->w, window->h,
461 data->depth);
462 }
463 if (data->pixmaps[i] == None) {
464 SDL_SetError("XCreatePixmap() failed");
465 return -1;
466 }
467 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
468 if (data->use_xrender) {
469 data->pixmap_picts[i] =
470 XRenderCreatePicture(data->display,
471 data->pixmaps[i],
472 XRenderFindStandardFormat(data->display,
473 PictStandardARGB32),
474 0, None);
475 if (!data->pixmap_picts[i]) {
476 SDL_SetError("XRenderCreatePicture() failed");
477 return -1;
478 }
479 XRenderComposite(data->display,
480 PictOpClear,
481 data->pixmap_picts[i],
482 None,
483 data->pixmap_picts[i],
484 0, 0,
485 0, 0,
486 0, 0,
487 window->w, window->h);
488
489 }
490 #endif
491 }
492 if (n > 0) {
493 data->drawable = data->pixmaps[0];
494 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
455 data->drawable_pict = data->pixmap_picts[0]; 495 data->drawable_pict = data->pixmap_picts[0];
456 #endif 496 #endif
457 } 497 }
458 data->current_pixmap = 0; 498 data->current_pixmap = 0;
459 499
460 return 0; 500 return 0;
461 } 501 }
502
503 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
504 static void
505 SDLMaskToXRenderMask(Uint32 sdl_mask, short *comp, short *compMask) {
506 (*comp) = 0;
507 (*compMask) = 0;
508 while(!(sdl_mask & 1)) {
509 (*comp)++;
510 sdl_mask >>= 1;
511 }
512 while(sdl_mask & 1) {
513 (*compMask) = ((*compMask) << 1) | 1;
514 sdl_mask >>= 1;
515 }
516 }
517
518 static XRenderPictFormat*
519 PixelFormatEnumToXRenderPictFormat(SDL_Renderer * renderer, Uint32 format) {
520 XRenderPictFormat* pict_fmt = NULL;
521 X11_RenderData *data = (X11_RenderData *) renderer->driverdata;
522
523 if (data->use_xrender) {
524
525 int bpp;
526 Uint32 Amask, Rmask, Gmask, Bmask;
527 SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask);
528
529 XRenderPictFormat templ;
530 unsigned long mask = (PictFormatType | PictFormatDepth | PictFormatRed |
531 PictFormatRedMask | PictFormatGreen | PictFormatGreenMask |
532 PictFormatBlue | PictFormatBlueMask | PictFormatAlpha |
533 PictFormatAlphaMask);
534
535 templ.type = PictTypeDirect;
536 templ.depth = bpp;
537 SDLMaskToXRenderMask(Amask, &(templ.direct.alpha), &(templ.direct.alphaMask));
538 SDLMaskToXRenderMask(Rmask, &(templ.direct.red), &(templ.direct.redMask));
539 SDLMaskToXRenderMask(Gmask, &(templ.direct.green), &(templ.direct.greenMask));
540 SDLMaskToXRenderMask(Bmask, &(templ.direct.blue), &(templ.direct.blueMask));
541
542 pict_fmt = XRenderFindFormat(data->display, mask, &templ, 0);
543 }
544
545 return pict_fmt;
546 }
547
548
549 static Visual*
550 PixelFormatEnumToVisual(SDL_Renderer * renderer, Uint32 format) {
551 X11_RenderData *data = (X11_RenderData *) renderer->driverdata;
552
553 if (data->use_xrender) {
554 int bpp;
555 Uint32 Amask, Rmask, Gmask, Bmask;
556 SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask);
557
558 XVisualInfo vinfo_templ;
559 long vinfo_mask;
560 int nitems_return;
561
562 vinfo_mask = (VisualDepthMask | VisualRedMaskMask |
563 VisualGreenMaskMask | VisualBlueMaskMask);
564 vinfo_templ.depth = bpp;
565 vinfo_templ.red_mask = Rmask;
566 vinfo_templ.green_mask = Gmask;
567 vinfo_templ.blue_mask = Bmask;
568
569 XVisualInfo * ret = XGetVisualInfo(data->display, vinfo_mask,
570 &vinfo_templ, &nitems_return);
571
572 if (nitems_return) {
573 return ret[0].visual;
574 }
575 }
576
577 return NULL;
578 }
579 #endif
462 580
463 static int 581 static int
464 X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) 582 X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
465 { 583 {
466 X11_RenderData *renderdata = (X11_RenderData *) renderer->driverdata; 584 X11_RenderData *renderdata = (X11_RenderData *) renderer->driverdata;
467 SDL_Window *window = renderer->window; 585 SDL_Window *window = renderer->window;
468 SDL_VideoDisplay *display = window->display; 586 SDL_VideoDisplay *display = window->display;
469 X11_TextureData *data; 587 X11_TextureData *data;
470 int pitch_alignmask = ((renderdata->scanline_pad / 8) - 1); 588 int pitch_alignmask = ((renderdata->scanline_pad / 8) - 1);
471 589 XGCValues gcv;
590
472 data = (X11_TextureData *) SDL_calloc(1, sizeof(*data)); 591 data = (X11_TextureData *) SDL_calloc(1, sizeof(*data));
473 if (!data) { 592 if (!data) {
474 SDL_OutOfMemory(); 593 SDL_OutOfMemory();
475 return -1; 594 return -1;
476 } 595 }
596 data->depth = renderdata->depth;
597 data->visual = renderdata->visual;
598 data->gc = renderdata->gc;
477 599
478 texture->driverdata = data; 600 texture->driverdata = data;
479 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { 601 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
480 data->yuv = 602 data->yuv =
481 SDL_SW_CreateYUVTexture(texture->format, texture->w, texture->h); 603 SDL_SW_CreateYUVTexture(texture->format, texture->w, texture->h);
492 if (renderdata->use_xrender == SDL_FALSE) { 614 if (renderdata->use_xrender == SDL_FALSE) {
493 if (texture->format != display->current_mode.format) { 615 if (texture->format != display->current_mode.format) {
494 SDL_SetError("Texture format doesn't match window format"); 616 SDL_SetError("Texture format doesn't match window format");
495 return -1; 617 return -1;
496 } 618 }
619 } else {
620 Uint32 Amask, Rmask, Gmask, Bmask;
621 SDL_PixelFormatEnumToMasks(texture->format, &(data->depth),
622 &Rmask, &Gmask, &Bmask, &Amask);
623 data->visual = PixelFormatEnumToVisual(renderer, texture->format);
497 } 624 }
498 #else 625 #else
499 /* The image/pixmap depth must be the same as the window or you 626 /* The image/pixmap depth must be the same as the window or you
500 get a BadMatch error when trying to putimage or copyarea. 627 get a BadMatch error when trying to putimage or copyarea.
501 This BadMatch error 628 This BadMatch error
538 } 665 }
539 if (!shm_error) { 666 if (!shm_error) {
540 data->pixels = shminfo->shmaddr; 667 data->pixels = shminfo->shmaddr;
541 data->pixmap = 668 data->pixmap =
542 XCreatePixmap(renderdata->display, renderdata->xwindow, texture->w, 669 XCreatePixmap(renderdata->display, renderdata->xwindow, texture->w,
543 texture->h, renderdata->depth); 670 texture->h, data->depth);
544 if (data->pixmap == None) { 671 if (data->pixmap == None) {
545 X11_DestroyTexture(renderer, texture); 672 X11_DestroyTexture(renderer, texture);
546 SDL_SetError("XCreatePixmap() failed"); 673 SDL_SetError("XCreatePixmap() failed");
547 return -1; 674 return -1;
548 } 675 }
549
550 data->image = 676 data->image =
551 XShmCreateImage(renderdata->display, renderdata->visual, 677 XShmCreateImage(renderdata->display, data->visual,
552 renderdata->depth, ZPixmap, shminfo->shmaddr, 678 data->depth, ZPixmap, shminfo->shmaddr,
553 shminfo, texture->w, texture->h); 679 shminfo, texture->w, texture->h);
554 680
555 if (!data->image) { 681 if (!data->image) {
556 XShmDetach(renderdata->display, shminfo); 682 XShmDetach(renderdata->display, shminfo);
557 XSync(renderdata->display, False); 683 XSync(renderdata->display, False);
580 return -1; 706 return -1;
581 } 707 }
582 708
583 data->pixmap = 709 data->pixmap =
584 XCreatePixmap(renderdata->display, renderdata->xwindow, texture->w, 710 XCreatePixmap(renderdata->display, renderdata->xwindow, texture->w,
585 texture->h, renderdata->depth); 711 texture->h, data->depth);
586 if (data->pixmap == None) { 712 if (data->pixmap == None) {
587 X11_DestroyTexture(renderer, texture); 713 X11_DestroyTexture(renderer, texture);
588 SDL_SetError("XCreatePixmap() failed"); 714 SDL_SetError("XCreatePixmap() failed");
589 return -1; 715 return -1;
590 } 716 }
591 data->image = 717 data->image =
592 XCreateImage(renderdata->display, renderdata->visual, 718 XCreateImage(renderdata->display, data->visual,
593 renderdata->depth, ZPixmap, 0, data->pixels, 719 data->depth, ZPixmap, 0, data->pixels,
594 texture->w, texture->h, 720 texture->w, texture->h,
595 SDL_BYTESPERPIXEL(data->format) * 8, 721 SDL_BYTESPERPIXEL(data->format) * 8,
596 data->pitch); 722 data->pitch);
597 if (!data->image) { 723 if (!data->image) {
598 X11_DestroyTexture(renderer, texture); 724 X11_DestroyTexture(renderer, texture);
602 } 728 }
603 } 729 }
604 else { 730 else {
605 data->pixmap = 731 data->pixmap =
606 XCreatePixmap(renderdata->display, renderdata->xwindow, texture->w, 732 XCreatePixmap(renderdata->display, renderdata->xwindow, texture->w,
607 texture->h, renderdata->depth); 733 texture->h, data->depth);
608 if (data->pixmap == None) { 734 if (data->pixmap == None) {
609 X11_DestroyTexture(renderer, texture); 735 X11_DestroyTexture(renderer, texture);
610 SDL_SetError("XCreatePixmap() failed"); 736 SDL_SetError("XCreatePixmap() failed");
611 return -1; 737 return -1;
612 } 738 }
613 data->image = 739 data->image =
614 XCreateImage(renderdata->display, renderdata->visual, 740 XCreateImage(renderdata->display, data->visual,
615 renderdata->depth, ZPixmap, 0, NULL, 741 data->depth, ZPixmap, 0, NULL,
616 texture->w, texture->h, 742 texture->w, texture->h,
617 SDL_BYTESPERPIXEL(data->format) * 8, 743 SDL_BYTESPERPIXEL(data->format) * 8,
618 data->pitch); 744 data->pitch);
619 if (!data->image) { 745 if (!data->image) {
620 X11_DestroyTexture(renderer, texture); 746 X11_DestroyTexture(renderer, texture);
622 return -1; 748 return -1;
623 } 749 }
624 } 750 }
625 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 751 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
626 if(renderdata->use_xrender) { 752 if(renderdata->use_xrender) {
627 data->picture_fmt = renderdata->xwindow_pict_fmt; 753 gcv.graphics_exposures = False;
754 data->gc =
755 XCreateGC(renderdata->display, data->pixmap, GCGraphicsExposures, &gcv);
756 if (!data->gc) {
757 SDL_SetError("XCreateGC() failed");
758 return -1;
759 }
760 data->picture_fmt =
761 PixelFormatEnumToXRenderPictFormat(renderer, texture->format);
762 if (data->picture_fmt == NULL) {
763 X11_DestroyTexture(renderer, texture);
764 SDL_SetError("Texture format not supported by driver");
765 return -1;
766 }
628 data->picture = 767 data->picture =
629 XRenderCreatePicture(renderdata->display, data->pixmap, 768 XRenderCreatePicture(renderdata->display, data->pixmap,
630 data->picture_fmt, 0, NULL); 769 data->picture_fmt, 0, NULL);
631 } 770 if (!data->picture) {
632 /* We thought we could render the texture with Xrender but this was 771 X11_DestroyTexture(renderer, texture);
633 not possible for some reason. Now we must ensure that texture 772 SDL_SetError("XRenderCreatePicture() failed");
634 format and window format match to avoid a BadMatch error when
635 rendering using the old pipeline.
636 if(data->use_xrender == SDL_FALSE) {
637 if (texture->format != display->current_mode.format) {
638 SDL_SetError("Texture format doesn't match window format");
639 return -1; 773 return -1;
640 } 774 }
641 }*/ 775 }
642 #endif 776 #endif
643 return 0; 777 return 0;
644 } 778 }
645 779
646 static int 780 static int
740 } else { 874 } else {
741 data->image->width = rect->w; 875 data->image->width = rect->w;
742 data->image->height = rect->h; 876 data->image->height = rect->h;
743 data->image->data = (char *) pixels; 877 data->image->data = (char *) pixels;
744 data->image->bytes_per_line = pitch; 878 data->image->bytes_per_line = pitch;
745 XPutImage(renderdata->display, data->pixmap, renderdata->gc, 879 XPutImage(renderdata->display, data->pixmap, data->gc,
746 data->image, 0, 0, rect->x, rect->y, rect->w, rect->h); 880 data->image, 0, 0, rect->x, rect->y, rect->w, rect->h);
747 } 881 }
748 return 0; 882 return 0;
749 } 883 }
750 } 884 }
911 XDrawPoints(data->display, data->mask, data->mask_gc, xpoints, xcount, 1045 XDrawPoints(data->display, data->mask, data->mask_gc, xpoints, xcount,
912 CoordModeOrigin); 1046 CoordModeOrigin);
913 XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes); 1047 XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes);
914 Picture fill = 1048 Picture fill =
915 XRenderCreateSolidFill(data->display, &foreground); 1049 XRenderCreateSolidFill(data->display, &foreground);
1050 if (!fill) {
1051 SDL_SetError("XRenderCreateSolidFill() failed");
1052 return -1;
1053 }
916 1054
917 XRenderComposite(data->display, data->blend_op, fill, data->mask_pict, 1055 XRenderComposite(data->display, data->blend_op, fill, data->mask_pict,
918 data->drawable_pict, 0, 0, 0, 0, 0, 0, window->w, window->h); 1056 data->drawable_pict, 0, 0, 0, 0, 0, 0, window->w, window->h);
919 1057
920 // Reset the clip_mask 1058 // Reset the clip_mask
1095 XRenderPictureAttributes attributes; 1233 XRenderPictureAttributes attributes;
1096 attributes.clip_mask = data->mask; 1234 attributes.clip_mask = data->mask;
1097 unsigned long valuemask = CPClipMask; 1235 unsigned long valuemask = CPClipMask;
1098 XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes); 1236 XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes);
1099 Picture fill = XRenderCreateSolidFill(data->display, &xrforeground); 1237 Picture fill = XRenderCreateSolidFill(data->display, &xrforeground);
1238 if (!fill) {
1239 SDL_SetError("XRenderCreateSolidFill() failed");
1240 return -1;
1241 }
1100 XRenderComposite(data->display, data->blend_op, fill, data->mask_pict, 1242 XRenderComposite(data->display, data->blend_op, fill, data->mask_pict,
1101 data->drawable_pict, 0, 0, 0, 0, 0, 0, window->w, window->h); 1243 data->drawable_pict, 0, 0, 0, 0, 0, 0, window->w, window->h);
1102 attributes.clip_mask = None; 1244 attributes.clip_mask = None;
1103 XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes); 1245 XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes);
1104 XRenderFreePicture(data->display, fill); 1246 XRenderFreePicture(data->display, fill);
1156 0, 0, 0, 0, 0, 0, window->w, window->h); 1298 0, 0, 0, 0, 0, 0, window->w, window->h);
1157 XDrawRectangles(data->display, data->mask, data->mask_gc, xrects, xcount); 1299 XDrawRectangles(data->display, data->mask, data->mask_gc, xrects, xcount);
1158 XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes); 1300 XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes);
1159 Picture fill = 1301 Picture fill =
1160 XRenderCreateSolidFill(data->display, &foreground); 1302 XRenderCreateSolidFill(data->display, &foreground);
1303 if (!fill) {
1304 SDL_SetError("XRenderCreateSolidFill() failed");
1305 return -1;
1306 }
1161 XRenderComposite(data->display, data->blend_op, fill, data->mask_pict, 1307 XRenderComposite(data->display, data->blend_op, fill, data->mask_pict,
1162 data->drawable_pict, 0, 0, 0, 0, 0, 0, window->w, window->h); 1308 data->drawable_pict, 0, 0, 0, 0, 0, 0, window->w, window->h);
1163 attributes.clip_mask = None; 1309 attributes.clip_mask = None;
1164 XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes); 1310 XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes);
1165 XRenderFreePicture(data->display, fill); 1311 XRenderFreePicture(data->display, fill);
1227 0, 0, 0, 0, 0, 0, window->w, window->h); 1373 0, 0, 0, 0, 0, 0, window->w, window->h);
1228 XFillRectangles(data->display, data->mask, data->mask_gc, 1374 XFillRectangles(data->display, data->mask, data->mask_gc,
1229 xrects, xcount); 1375 xrects, xcount);
1230 1376
1231 XRenderChangePicture(data->display, data->drawable_pict, CPClipMask, &attributes); 1377 XRenderChangePicture(data->display, data->drawable_pict, CPClipMask, &attributes);
1232 Picture fill_pict = XRenderCreateSolidFill(data->display, 1378 Picture fill = XRenderCreateSolidFill(data->display,
1233 &foreground); 1379 &foreground);
1234 XRenderComposite(data->display, data->blend_op, fill_pict, None, 1380 if (!fill) {
1381 SDL_SetError("XRenderCreateSolidFill() failed");
1382 return -1;
1383 }
1384 XRenderComposite(data->display, data->blend_op, fill, None,
1235 data->drawable_pict, 0, 0, 0, 0, 0, 0, window->w, window->h); 1385 data->drawable_pict, 0, 0, 0, 0, 0, 0, window->w, window->h);
1236 attributes.clip_mask = None; 1386 attributes.clip_mask = None;
1237 XRenderChangePicture(data->display, data->drawable_pict, CPClipMask, &attributes); 1387 XRenderChangePicture(data->display, data->drawable_pict, CPClipMask, &attributes);
1238 XRenderFreePicture(data->display, fill_pict); 1388 XRenderFreePicture(data->display, fill);
1239 } 1389 }
1240 else 1390 else
1241 #endif 1391 #endif
1242 { 1392 {
1243 unsigned long foreground; 1393 unsigned long foreground;
1291 XRenderComposite(data->display, texturedata->blend_op, texturedata->picture, 1441 XRenderComposite(data->display, texturedata->blend_op, texturedata->picture,
1292 pict, data->drawable_pict, srcrect->x, srcrect->y, 1442 pict, data->drawable_pict, srcrect->x, srcrect->y,
1293 srcrect->x, srcrect->y, dstrect->x, dstrect->y, 1443 srcrect->x, srcrect->y, dstrect->x, dstrect->y,
1294 srcrect->w, srcrect->h); 1444 srcrect->w, srcrect->h);
1295 } else { 1445 } else {
1296 Pixmap scaling_pixmap = 1446 /*Pixmap scaling_pixmap =
1297 XCreatePixmap(data->display, texturedata->pixmap, dstrect->w, dstrect->h, 1447 XCreatePixmap(data->display, texturedata->pixmap, dstrect->w, dstrect->h,
1298 data->depth); 1448 data->depth);
1449 if (!scaling_pixmap) {
1450 SDL_SetError("XCreatePixmap() failed");
1451 return -1;
1452 }
1299 Picture scaling_picture = 1453 Picture scaling_picture =
1300 XRenderCreatePicture(data->display, scaling_pixmap, texturedata->picture_fmt, 1454 XRenderCreatePicture(data->display, scaling_pixmap, texturedata->picture_fmt,
1301 0, NULL); 1455 0, NULL);
1456 if (!scaling_picture) {
1457 SDL_SetError("XRenderCreatePicture() failed");
1458 return -1;
1459 }
1302 XRenderComposite(data->display, PictOpClear, scaling_picture, None, scaling_picture, 1460 XRenderComposite(data->display, PictOpClear, scaling_picture, None, scaling_picture,
1303 0, 0, 0, 0, 0, 0, dstrect->w, dstrect->h); 1461 0, 0, 0, 0, 0, 0, dstrect->w, dstrect->h);
1304 XRenderComposite(data->display, PictOpSrc, texturedata->picture, pict, scaling_picture, 1462 XRenderComposite(data->display, PictOpSrc, texturedata->picture, pict, scaling_picture,
1305 srcrect->x, srcrect->y, 0, 0, 0, 0, srcrect->w, srcrect->h); 1463 srcrect->x, srcrect->y, 0, 0, 0, 0, srcrect->w, srcrect->h);*/
1306 double xscale = ((double) dstrect->w) / srcrect->w; 1464 double xscale = ((double) dstrect->w) / srcrect->w;
1307 double yscale = ((double) dstrect->h) / srcrect->h; 1465 double yscale = ((double) dstrect->h) / srcrect->h;
1308 XTransform xform = 1466 XTransform xform = {{
1309 {{{XDoubleToFixed(xscale), XDoubleToFixed(0), XDoubleToFixed(0)}, 1467 {XDoubleToFixed(xscale), XDoubleToFixed(0), XDoubleToFixed(0)},
1310 {XDoubleToFixed(0), XDoubleToFixed(yscale), XDoubleToFixed(0)}, 1468 {XDoubleToFixed(0), XDoubleToFixed(yscale), XDoubleToFixed(0)},
1311 {XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(xscale * yscale)}}}; 1469 {XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(xscale * yscale)}}};
1312 XRenderSetPictureTransform(data->display, scaling_picture, &xform); 1470 XRenderSetPictureTransform(data->display, texturedata->picture, &xform);
1313 XRenderComposite(data->display, texturedata->blend_op, scaling_picture, None, data->drawable_pict, 1471
1314 0, 0, 0, 0, dstrect->x, dstrect->y, dstrect->w, dstrect->h); 1472 XRenderComposite(data->display, texturedata->blend_op,
1315 XRenderFreePicture(data->display, scaling_picture); 1473 texturedata->picture, None, data->drawable_pict,
1316 XFreePixmap(data->display, scaling_pixmap); 1474 0, 0, 0, 0, dstrect->x, dstrect->y,
1475 dstrect->w, dstrect->h);
1476
1477 XTransform identity = {{
1478 {XDoubleToFixed(1), XDoubleToFixed(0), XDoubleToFixed(0)},
1479 {XDoubleToFixed(0), XDoubleToFixed(1), XDoubleToFixed(0)},
1480 {XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1)}}};
1481 XRenderSetPictureTransform(data->display, texturedata->picture, &identity);
1482
1483 /*XRenderFreePicture(data->display, scaling_picture);
1484 XFreePixmap(data->display, scaling_pixmap);*/
1317 } 1485 }
1318 } 1486 }
1319 else 1487 else
1320 #endif 1488 #endif
1321 { 1489 {