Mercurial > sdl-ios-xcode
comparison src/video/x11/SDL_x11render.c @ 4586:e479c1e57c52
SDL_Textures should work with XRender now provided that the texture format and screen format match. This is only a temporary limitation.
author | Sunny Sachanandani <sunnysachanandani@gmail.com> |
---|---|
date | Wed, 16 Jun 2010 10:50:01 +0530 |
parents | 21600c6d6445 |
children | 25391ccf16a0 |
comparison
equal
deleted
inserted
replaced
4585:21600c6d6445 | 4586:e479c1e57c52 |
---|---|
120 Uint32 format; | 120 Uint32 format; |
121 Pixmap pixmap; | 121 Pixmap pixmap; |
122 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER | 122 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER |
123 Picture picture; | 123 Picture picture; |
124 XRenderPictFormat* picture_fmt; | 124 XRenderPictFormat* picture_fmt; |
125 XRenderPictureAttributes picture_attr; | |
126 unsigned int picture_attr_valuemask; | |
127 SDL_bool use_xrender; | 125 SDL_bool use_xrender; |
128 #endif | 126 #endif |
129 XImage *image; | 127 XImage *image; |
130 #ifndef NO_SHARED_MEMORY | 128 #ifndef NO_SHARED_MEMORY |
131 /* MIT shared memory extension information */ | 129 /* MIT shared memory extension information */ |
433 can be no BadMatch error since Xrender takes care of that. | 431 can be no BadMatch error since Xrender takes care of that. |
434 */ | 432 */ |
435 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER | 433 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER |
436 // Assume the texture is supported by Xrender | 434 // Assume the texture is supported by Xrender |
437 data->use_xrender = SDL_TRUE; | 435 data->use_xrender = SDL_TRUE; |
438 if(renderdata->use_xrender == SDL_FALSE) { | 436 if (renderdata->use_xrender == SDL_FALSE) { |
439 if (texture->format != display->current_mode.format) { | 437 if (texture->format != display->current_mode.format) { |
440 SDL_SetError("Texture format doesn't match window format"); | 438 SDL_SetError("Texture format doesn't match window format"); |
441 return -1; | 439 return -1; |
442 } | 440 } |
443 } | 441 } |
488 data->image = | 486 data->image = |
489 XShmCreateImage(renderdata->display, renderdata->visual, | 487 XShmCreateImage(renderdata->display, renderdata->visual, |
490 renderdata->depth, ZPixmap, shminfo->shmaddr, | 488 renderdata->depth, ZPixmap, shminfo->shmaddr, |
491 shminfo, texture->w, texture->h); | 489 shminfo, texture->w, texture->h); |
492 | 490 |
493 // This Pixmap is used by Xrender | 491 if (!data->image) { |
494 data->pixmap = | |
495 XShmCreatePixmap(renderdata->display, renderdata->xwindow, shminfo->shmaddr, | |
496 shminfo, texture->w, texture->h, renderdata->depth); | |
497 | |
498 if (!(data->pixmap && data->image)) { | |
499 XShmDetach(renderdata->display, shminfo); | 492 XShmDetach(renderdata->display, shminfo); |
500 XSync(renderdata->display, False); | 493 XSync(renderdata->display, False); |
501 shmdt(shminfo->shmaddr); | 494 shmdt(shminfo->shmaddr); |
502 shm_error = True; | 495 shm_error = True; |
503 } | 496 } |
558 } | 551 } |
559 } | 552 } |
560 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER | 553 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER |
561 if(renderdata->use_xrender && data->pixmap) { | 554 if(renderdata->use_xrender && data->pixmap) { |
562 data->use_xrender = SDL_TRUE; | 555 data->use_xrender = SDL_TRUE; |
563 unsigned long x11_fmt_mask; // Format mask | 556 /*unsigned long x11_fmt_mask; // Format mask |
564 XRenderPictFormat x11_templ_fmt; // Format template | 557 XRenderPictFormat x11_templ_fmt; // Format template |
565 x11_fmt_mask = | 558 x11_fmt_mask = |
566 (PictFormatDepth | PictFormatRedMask | PictFormatGreenMask | 559 (PictFormatRedMask | PictFormatGreenMask |
567 | PictFormatBlueMask); | 560 | PictFormatBlueMask | PictFormatAlphaMask); |
568 Uint32 Rmask, Gmask, Bmask, Amask; | 561 Uint32 Rmask, Gmask, Bmask, Amask; |
569 int bpp; | 562 int bpp; |
570 SDL_PixelFormatEnumToMasks(data->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); | 563 SDL_PixelFormatEnumToMasks(data->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); |
571 x11_templ_fmt.depth = bpp; | 564 x11_templ_fmt.depth = bpp; |
572 x11_templ_fmt.direct.redMask = Rmask; | 565 x11_templ_fmt.type = PictTypeDirect; |
573 x11_templ_fmt.direct.greenMask = Gmask; | 566 x11_templ_fmt.direct.red = Rmask / 0xff; |
574 x11_templ_fmt.direct.blueMask = Bmask; | 567 x11_templ_fmt.direct.green = Gmask / 0xff; |
575 x11_templ_fmt.direct.alphaMask = Amask; | 568 x11_templ_fmt.direct.blue = Bmask / 0xff; |
576 /* Return one matching XRenderPictFormat */ | 569 x11_templ_fmt.direct.alpha = Amask / 0xff; |
570 printf("%d %d %d %d\n", Rmask/0xff, Gmask/0xff, Bmask/0xff, Amask/0xff); | |
571 // Return a matching XRenderPictFormat | |
577 data->picture_fmt = | 572 data->picture_fmt = |
578 XRenderFindFormat(renderdata->display, x11_fmt_mask, &x11_templ_fmt, 1); | 573 XRenderFindFormat(renderdata->display, x11_fmt_mask, &x11_templ_fmt, 0);*/ |
574 data->picture_fmt = | |
575 XRenderFindVisualFormat(renderdata->display, renderdata->visual); | |
579 if(!data->picture_fmt) { | 576 if(!data->picture_fmt) { |
577 printf("XRenderFindFormat failed!\n"); | |
580 data->use_xrender = SDL_FALSE; | 578 data->use_xrender = SDL_FALSE; |
581 } | 579 } |
582 data->picture_attr_valuemask = CPGraphicsExposure; | |
583 (data->picture_attr).graphics_exposures = False; | |
584 data->picture = | 580 data->picture = |
585 XRenderCreatePicture(renderdata->display, data->pixmap, data->picture_fmt, | 581 XRenderCreatePicture(renderdata->display, data->pixmap, |
586 data->picture_attr_valuemask, &(data->picture_attr)); | 582 data->picture_fmt, 0, NULL); |
587 if(!data->picture) { | 583 if(!data->picture) { |
588 data->use_xrender = SDL_FALSE; | 584 data->use_xrender = SDL_FALSE; |
589 } | 585 } |
590 } | 586 } |
591 /* We thought we could render the texture with Xrender but this was | 587 /* We thought we could render the texture with Xrender but this was |
592 not possible for some reason. Now we must ensure that texture | 588 not possible for some reason. Now we must ensure that texture |
593 format and window format match to avoid a BadMatch error. | 589 format and window format match to avoid a BadMatch error when |
590 rendering using the old pipeline. | |
594 */ | 591 */ |
595 if(data->use_xrender == SDL_FALSE) { | 592 if(data->use_xrender == SDL_FALSE) { |
596 if (texture->format != display->current_mode.format) { | 593 if (texture->format != display->current_mode.format) { |
597 SDL_SetError("Texture format doesn't match window format"); | 594 SDL_SetError("Texture format doesn't match window format"); |
598 return -1; | 595 return -1; |
683 src += pitch; | 680 src += pitch; |
684 dst += data->pitch; | 681 dst += data->pitch; |
685 } | 682 } |
686 /* If this is a static texture we would use Xrender for it | 683 /* If this is a static texture we would use Xrender for it |
687 but this requires that the server side Pixmap associated | 684 but this requires that the server side Pixmap associated |
688 with this texture be updated with the data as well and | 685 with this texture be updated with the data as well. |
689 that the pixmap is not a shared memory pixmap. | |
690 Hopefully the user will not update static textures so | 686 Hopefully the user will not update static textures so |
691 frequently as to cause a slowdown. | 687 frequently as to cause a slowdown. |
692 */ | 688 */ |
693 if (texture->access == SDL_TEXTUREACCESS_STATIC) { | 689 if (texture->access == SDL_TEXTUREACCESS_STATIC) { |
694 #ifndef NO_SHARED_MEMORY | |
695 if(!data->shminfo.shmaddr) | |
696 #endif | |
697 { | |
698 XPutImage(renderdata->display, data->pixmap, renderdata->gc, | 690 XPutImage(renderdata->display, data->pixmap, renderdata->gc, |
699 data->image, 0, 0, rect->x, rect->y, rect->w, rect->h); | 691 data->image, 0, 0, rect->x, rect->y, rect->w, rect->h); |
700 } | |
701 } | 692 } |
702 | 693 |
703 } else { | 694 } else { |
704 data->image->width = rect->w; | 695 data->image->width = rect->w; |
705 data->image->height = rect->h; | 696 data->image->height = rect->h; |
1209 X11_TextureData *texturedata = (X11_TextureData *) texture->driverdata; | 1200 X11_TextureData *texturedata = (X11_TextureData *) texture->driverdata; |
1210 | 1201 |
1211 if (data->makedirty) { | 1202 if (data->makedirty) { |
1212 SDL_AddDirtyRect(&data->dirty, dstrect); | 1203 SDL_AddDirtyRect(&data->dirty, dstrect); |
1213 } | 1204 } |
1214 if (srcrect->w == dstrect->w && srcrect->h == dstrect->h) { | 1205 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER |
1206 if (data->use_xrender && texturedata->use_xrender && texture->access == SDL_TEXTUREACCESS_STATIC) { | |
1207 if(srcrect->w == dstrect->w && srcrect->h == dstrect->h) { | |
1208 XRenderComposite(data->display, PictOpOver, texturedata->picture, None, data->drawable_pict, | |
1209 srcrect->x, srcrect->y, 0, 0, dstrect->x, dstrect->y, srcrect->w, srcrect->h); | |
1210 } else { | |
1211 Pixmap scaling_pixmap = | |
1212 XCreatePixmap(data->display, texturedata->pixmap, dstrect->w, dstrect->h, | |
1213 data->depth); | |
1214 Picture scaling_picture = | |
1215 XRenderCreatePicture(data->display, scaling_pixmap, texturedata->picture_fmt, | |
1216 0, NULL); | |
1217 XRenderComposite(data->display, PictOpClear, scaling_picture, None, scaling_picture, | |
1218 0, 0, 0, 0, 0, 0, dstrect->w, dstrect->h); | |
1219 XRenderComposite(data->display, PictOpSrc, texturedata->picture, None, scaling_picture, | |
1220 srcrect->x, srcrect->y, 0, 0, 0, 0, srcrect->w, srcrect->h); | |
1221 double xscale = ((double) dstrect->w) / srcrect->w; | |
1222 double yscale = ((double) dstrect->h) / srcrect->h; | |
1223 XTransform xform = | |
1224 {{{XDoubleToFixed(xscale), XDoubleToFixed(0), XDoubleToFixed(0)}, | |
1225 {XDoubleToFixed(0), XDoubleToFixed(yscale), XDoubleToFixed(0)}, | |
1226 {XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(xscale * yscale)}}}; | |
1227 XRenderSetPictureTransform(data->display, scaling_picture, &xform); | |
1228 XRenderComposite(data->display, PictOpOver, scaling_picture, None, data->drawable_pict, | |
1229 0, 0, 0, 0, dstrect->x, dstrect->y, dstrect->w, dstrect->h); | |
1230 XRenderFreePicture(data->display, scaling_picture); | |
1231 XFreePixmap(data->display, scaling_pixmap); | |
1232 } | |
1233 } | |
1234 else | |
1235 #endif | |
1236 { | |
1237 if (srcrect->w == dstrect->w && srcrect->h == dstrect->h) { | |
1215 #ifndef NO_SHARED_MEMORY | 1238 #ifndef NO_SHARED_MEMORY |
1216 if (texturedata->shminfo.shmaddr) { | 1239 if (texturedata->shminfo.shmaddr) { |
1217 XShmPutImage(data->display, data->drawable, data->gc, | 1240 XShmPutImage(data->display, data->drawable, data->gc, |
1218 texturedata->image, srcrect->x, srcrect->y, | 1241 texturedata->image, srcrect->x, srcrect->y, |
1219 dstrect->x, dstrect->y, srcrect->w, srcrect->h, | 1242 dstrect->x, dstrect->y, srcrect->w, srcrect->h, |
1220 False); | 1243 False); |
1221 } else | 1244 } else |
1222 #endif | 1245 #endif |
1223 if (texturedata->pixels) { | 1246 if (texturedata->pixels) { |
1224 XPutImage(data->display, data->drawable, data->gc, | 1247 XPutImage(data->display, data->drawable, data->gc, |
1225 texturedata->image, srcrect->x, srcrect->y, dstrect->x, | 1248 texturedata->image, srcrect->x, srcrect->y, dstrect->x, |
1226 dstrect->y, srcrect->w, srcrect->h); | 1249 dstrect->y, srcrect->w, srcrect->h); |
1250 } else { | |
1251 XCopyArea(data->display, texturedata->pixmap, data->drawable, | |
1252 data->gc, srcrect->x, srcrect->y, dstrect->w, | |
1253 dstrect->h, dstrect->x, dstrect->y); | |
1254 } | |
1255 } else if (texturedata->yuv | |
1256 || texture->access == SDL_TEXTUREACCESS_STREAMING) { | |
1257 SDL_Surface src, dst; | |
1258 SDL_PixelFormat fmt; | |
1259 SDL_Rect rect; | |
1260 XImage *image = texturedata->scaling_image; | |
1261 | |
1262 if (!image) { | |
1263 void *pixels; | |
1264 int pitch; | |
1265 | |
1266 pitch = dstrect->w * SDL_BYTESPERPIXEL(texturedata->format); | |
1267 pixels = SDL_malloc(dstrect->h * pitch); | |
1268 if (!pixels) { | |
1269 SDL_OutOfMemory(); | |
1270 return -1; | |
1271 } | |
1272 | |
1273 image = | |
1274 XCreateImage(data->display, data->visual, data->depth, | |
1275 ZPixmap, 0, pixels, dstrect->w, dstrect->h, | |
1276 SDL_BYTESPERPIXEL(texturedata->format) * 8, | |
1277 pitch); | |
1278 if (!image) { | |
1279 SDL_SetError("XCreateImage() failed"); | |
1280 return -1; | |
1281 } | |
1282 texturedata->scaling_image = image; | |
1283 | |
1284 } else if (image->width != dstrect->w || image->height != dstrect->h | |
1285 || !image->data) { | |
1286 image->width = dstrect->w; | |
1287 image->height = dstrect->h; | |
1288 image->bytes_per_line = | |
1289 image->width * SDL_BYTESPERPIXEL(texturedata->format); | |
1290 image->data = | |
1291 (char *) SDL_realloc(image->data, | |
1292 image->height * image->bytes_per_line); | |
1293 if (!image->data) { | |
1294 SDL_OutOfMemory(); | |
1295 return -1; | |
1296 } | |
1297 } | |
1298 | |
1299 /* Set up fake surfaces for SDL_SoftStretch() */ | |
1300 SDL_zero(src); | |
1301 src.format = &fmt; | |
1302 src.w = texture->w; | |
1303 src.h = texture->h; | |
1304 #ifndef NO_SHARED_MEMORY | |
1305 if (texturedata->shminfo.shmaddr) { | |
1306 src.pixels = texturedata->shminfo.shmaddr; | |
1307 } else | |
1308 #endif | |
1309 src.pixels = texturedata->pixels; | |
1310 src.pitch = texturedata->pitch; | |
1311 | |
1312 SDL_zero(dst); | |
1313 dst.format = &fmt; | |
1314 dst.w = image->width; | |
1315 dst.h = image->height; | |
1316 dst.pixels = image->data; | |
1317 dst.pitch = image->bytes_per_line; | |
1318 | |
1319 fmt.BytesPerPixel = SDL_BYTESPERPIXEL(texturedata->format); | |
1320 | |
1321 rect.x = 0; | |
1322 rect.y = 0; | |
1323 rect.w = dstrect->w; | |
1324 rect.h = dstrect->h; | |
1325 if (SDL_SoftStretch(&src, srcrect, &dst, &rect) < 0) { | |
1326 return -1; | |
1327 } | |
1328 XPutImage(data->display, data->drawable, data->gc, image, 0, 0, | |
1329 dstrect->x, dstrect->y, dstrect->w, dstrect->h); | |
1227 } else { | 1330 } else { |
1228 XCopyArea(data->display, texturedata->pixmap, data->drawable, | 1331 XCopyArea(data->display, texturedata->pixmap, data->drawable, |
1229 data->gc, srcrect->x, srcrect->y, dstrect->w, | 1332 data->gc, srcrect->x, srcrect->y, dstrect->w, dstrect->h, |
1230 dstrect->h, dstrect->x, dstrect->y); | 1333 srcrect->x, srcrect->y); |
1231 } | 1334 } |
1232 } else if (texturedata->yuv | |
1233 || texture->access == SDL_TEXTUREACCESS_STREAMING) { | |
1234 SDL_Surface src, dst; | |
1235 SDL_PixelFormat fmt; | |
1236 SDL_Rect rect; | |
1237 XImage *image = texturedata->scaling_image; | |
1238 | |
1239 if (!image) { | |
1240 void *pixels; | |
1241 int pitch; | |
1242 | |
1243 pitch = dstrect->w * SDL_BYTESPERPIXEL(texturedata->format); | |
1244 pixels = SDL_malloc(dstrect->h * pitch); | |
1245 if (!pixels) { | |
1246 SDL_OutOfMemory(); | |
1247 return -1; | |
1248 } | |
1249 | |
1250 image = | |
1251 XCreateImage(data->display, data->visual, data->depth, | |
1252 ZPixmap, 0, pixels, dstrect->w, dstrect->h, | |
1253 SDL_BYTESPERPIXEL(texturedata->format) * 8, | |
1254 pitch); | |
1255 if (!image) { | |
1256 SDL_SetError("XCreateImage() failed"); | |
1257 return -1; | |
1258 } | |
1259 texturedata->scaling_image = image; | |
1260 | |
1261 } else if (image->width != dstrect->w || image->height != dstrect->h | |
1262 || !image->data) { | |
1263 image->width = dstrect->w; | |
1264 image->height = dstrect->h; | |
1265 image->bytes_per_line = | |
1266 image->width * SDL_BYTESPERPIXEL(texturedata->format); | |
1267 image->data = | |
1268 (char *) SDL_realloc(image->data, | |
1269 image->height * image->bytes_per_line); | |
1270 if (!image->data) { | |
1271 SDL_OutOfMemory(); | |
1272 return -1; | |
1273 } | |
1274 } | |
1275 | |
1276 /* Set up fake surfaces for SDL_SoftStretch() */ | |
1277 SDL_zero(src); | |
1278 src.format = &fmt; | |
1279 src.w = texture->w; | |
1280 src.h = texture->h; | |
1281 #ifndef NO_SHARED_MEMORY | |
1282 if (texturedata->shminfo.shmaddr) { | |
1283 src.pixels = texturedata->shminfo.shmaddr; | |
1284 } else | |
1285 #endif | |
1286 src.pixels = texturedata->pixels; | |
1287 src.pitch = texturedata->pitch; | |
1288 | |
1289 SDL_zero(dst); | |
1290 dst.format = &fmt; | |
1291 dst.w = image->width; | |
1292 dst.h = image->height; | |
1293 dst.pixels = image->data; | |
1294 dst.pitch = image->bytes_per_line; | |
1295 | |
1296 fmt.BytesPerPixel = SDL_BYTESPERPIXEL(texturedata->format); | |
1297 | |
1298 rect.x = 0; | |
1299 rect.y = 0; | |
1300 rect.w = dstrect->w; | |
1301 rect.h = dstrect->h; | |
1302 if (SDL_SoftStretch(&src, srcrect, &dst, &rect) < 0) { | |
1303 return -1; | |
1304 } | |
1305 XPutImage(data->display, data->drawable, data->gc, image, 0, 0, | |
1306 dstrect->x, dstrect->y, dstrect->w, dstrect->h); | |
1307 } else { | |
1308 XCopyArea(data->display, texturedata->pixmap, data->drawable, | |
1309 data->gc, srcrect->x, srcrect->y, dstrect->w, dstrect->h, | |
1310 srcrect->x, srcrect->y); | |
1311 } | 1335 } |
1312 return 0; | 1336 return 0; |
1313 } | 1337 } |
1314 | 1338 |
1315 static int | 1339 static int |