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