comparison src/video/directfb/SDL_DirectFB_render.c @ 3335:b8d313de8a65

Adam Strzelecki to SDL Since current DirectFB implementation is incomplete for YUV surfaces (actually causes segmentation faults when trying Lock and use YUV planar textures) I decided to fix it a bit. Here's a patch that should make DirectFB properly support YUV both packed and planar (3 planes). (1) Removed SDL_BYTESPERPIXEL at all in favor of DFB_BYTES_PER_PIXEL(SDLToDFBPixelFormat(fmt)) which does return always proper BPP for YUVs too, coz SDL_BYTESPERPIXEL returns incorrect values for FOURCCs (2) Fixed data->pixels allocation for planar YUVs in CreateTexture, it should allocate 150% more space (3) Copy other planes for planar YUVs in UpdateTexture (4) Moved checking if format is supported at all with DirectFB on CreateTexture at the beginning of the code Waiting for comments, -- Adam Strzelecki | nanoant.com
author Sam Lantinga <slouken@libsdl.org>
date Sun, 04 Oct 2009 04:03:37 +0000
parents 62d4992e5a92
children 4b594623401b
comparison
equal deleted inserted replaced
3334:61ea9005fddf 3335:b8d313de8a65
497 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); 497 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
498 SDL_DFB_DEVICEDATA(display->device); 498 SDL_DFB_DEVICEDATA(display->device);
499 DirectFB_TextureData *data; 499 DirectFB_TextureData *data;
500 DFBResult ret; 500 DFBResult ret;
501 DFBSurfaceDescription dsc; 501 DFBSurfaceDescription dsc;
502 DFBSurfacePixelFormat pixelformat;
502 503
503 SDL_DFB_CALLOC(data, 1, sizeof(*data)); 504 SDL_DFB_CALLOC(data, 1, sizeof(*data));
504 texture->driverdata = data; 505 texture->driverdata = data;
505 506
507 /* find the right pixelformat */
508 pixelformat = SDLToDFBPixelFormat(texture->format);
509 if (pixelformat == DSPF_UNKNOWN) {
510 SDL_SetError("Unknown pixel format %d\n", data->format);
511 goto error;
512 }
513
506 data->format = texture->format; 514 data->format = texture->format;
507 data->pitch = (texture->w * SDL_BYTESPERPIXEL(data->format)); 515 data->pitch = texture->w * DFB_BYTES_PER_PIXEL(pixelformat);
508 516
509 if (DirectFB_AcquireVidLayer(renderer, texture) != 0) { 517 if (DirectFB_AcquireVidLayer(renderer, texture) != 0) {
510 /* fill surface description */ 518 /* fill surface description */
511 dsc.flags = 519 dsc.flags =
512 DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS; 520 DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
523 dsc.caps |= DSCAPS_SYSTEMONLY; 531 dsc.caps |= DSCAPS_SYSTEMONLY;
524 else 532 else
525 dsc.caps |= DSCAPS_VIDEOONLY; 533 dsc.caps |= DSCAPS_VIDEOONLY;
526 #endif 534 #endif
527 535
528 /* find the right pixelformat */ 536 dsc.pixelformat = pixelformat;
529
530 dsc.pixelformat = SDLToDFBPixelFormat(data->format);
531 if (dsc.pixelformat == DSPF_UNKNOWN) {
532 SDL_SetError("Unknown pixel format %d\n", data->format);
533 goto error;
534 }
535
536 data->pixels = NULL; 537 data->pixels = NULL;
537 538
538 /* Create the surface */ 539 /* Create the surface */
539 SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc, 540 SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
540 &data->surface)); 541 &data->surface));
548 #if (DFB_VERSION_ATLEAST(1,2,0)) 549 #if (DFB_VERSION_ATLEAST(1,2,0))
549 data->render_options = DSRO_NONE; 550 data->render_options = DSRO_NONE;
550 #endif 551 #endif
551 552
552 if (texture->access == SDL_TEXTUREACCESS_STREAMING) { 553 if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
553 data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format); 554 /* 3 plane YUVs return 1 bpp, but we need more space for other planes */
554 SDL_DFB_CALLOC(data->pixels, 1, texture->h * data->pitch); 555 if(texture->format == SDL_PIXELFORMAT_YV12 ||
556 texture->format == SDL_PIXELFORMAT_IYUV) {
557 SDL_DFB_CALLOC(data->pixels, 1, (texture->h * data->pitch * 3 + texture->h * data->pitch * 3 % 2) / 2);
558 } else {
559 SDL_DFB_CALLOC(data->pixels, 1, texture->h * data->pitch);
560 }
555 } 561 }
556 562
557 return 0; 563 return 0;
558 564
559 error: 565 error:
724 for (row = 0; row < rect->h; ++row) { 730 for (row = 0; row < rect->h; ++row) {
725 SDL_memcpy(dst, src, length); 731 SDL_memcpy(dst, src, length);
726 src += pitch; 732 src += pitch;
727 dst += dpitch; 733 dst += dpitch;
728 } 734 }
735 /* copy other planes for 3 plane formats */
736 if (texture->format == SDL_PIXELFORMAT_YV12 ||
737 texture->format == SDL_PIXELFORMAT_IYUV) {
738 src = (Uint8 *) pixels + texture->h * pitch;
739 dst = (Uint8 *) dpixels + texture->h * dpitch + rect->y * dpitch / 4 + rect->x * bpp / 2;
740 for (row = 0; row < rect->h / 2; ++row) {
741 SDL_memcpy(dst, src, length / 2);
742 src += pitch / 2;
743 dst += dpitch / 2;
744 }
745 src = (Uint8 *) pixels + texture->h * pitch + texture->h * pitch / 4;
746 dst = (Uint8 *) dpixels + texture->h * dpitch + texture->h * dpitch / 4 + rect->y * dpitch / 4 + rect->x * bpp / 2;
747 for (row = 0; row < rect->h / 2; ++row) {
748 SDL_memcpy(dst, src, length / 2);
749 src += pitch / 2;
750 dst += dpitch / 2;
751 }
752 }
729 SDL_DFB_CHECKERR(data->surface->Unlock(data->surface)); 753 SDL_DFB_CHECKERR(data->surface->Unlock(data->surface));
730 return 0; 754 return 0;
731 error: 755 error:
732 return 1; 756 return 1;
733 757
757 *pixels = fdata; 781 *pixels = fdata;
758 } else { 782 } else {
759 *pixels = 783 *pixels =
760 (void *) ((Uint8 *) texturedata->pixels + 784 (void *) ((Uint8 *) texturedata->pixels +
761 rect->y * texturedata->pitch + 785 rect->y * texturedata->pitch +
762 rect->x * SDL_BYTESPERPIXEL(texture->format)); 786 rect->x * DFB_BYTES_PER_PIXEL(SDLToDFBPixelFormat(texture->format)));
763 *pitch = texturedata->pitch; 787 *pitch = texturedata->pitch;
764 } 788 }
765 return 0; 789 return 0;
766 790
767 error: 791 error:
914 DFBSurfaceBlittingFlags flags = 0; 938 DFBSurfaceBlittingFlags flags = 0;
915 939
916 if (texturedata->dirty.list) { 940 if (texturedata->dirty.list) {
917 SDL_DirtyRect *dirty; 941 SDL_DirtyRect *dirty;
918 void *pixels; 942 void *pixels;
919 int bpp = SDL_BYTESPERPIXEL(texture->format); 943 int bpp = DFB_BYTES_PER_PIXEL(SDLToDFBPixelFormat(texture->format));
920 int pitch = texturedata->pitch; 944 int pitch = texturedata->pitch;
921 945
922 for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) { 946 for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) {
923 SDL_Rect *rect = &dirty->rect; 947 SDL_Rect *rect = &dirty->rect;
924 pixels = 948 pixels =