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