From f0d5200b5c67bd61be995b554a75acd7a2d8dfab Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 10 Mar 2013 09:09:31 -0700 Subject: [PATCH] Fixed bug 1750 - Directfb renderer does not support SDL_RENDERER_TARGETTEXTURE tomaszewski.p DirectFB renderer does not support SDL_RENDERER_TARGETTEXTURE what makes it incompatible with GL or GLES(2) renderers. Attached patched: - adds support for SDL_RENDERER_TARGETTEXTURE, - DirectFB RenderCopy converts destination rectangle from floats to ints, - fixes whitespaces to be the same in whole file. --- src/video/directfb/SDL_DirectFB_render.c | 165 +++++++++++++---------- 1 file changed, 93 insertions(+), 72 deletions(-) diff --git a/src/video/directfb/SDL_DirectFB_render.c b/src/video/directfb/SDL_DirectFB_render.c index c3b810d10..4a1d52798 100644 --- a/src/video/directfb/SDL_DirectFB_render.c +++ b/src/video/directfb/SDL_DirectFB_render.c @@ -35,21 +35,21 @@ #ifndef DFB_VERSION_ATLEAST -#define DFB_VERSIONNUM(X, Y, Z) \ - ((X)*1000 + (Y)*100 + (Z)) +#define DFB_VERSIONNUM(X, Y, Z) \ + ((X)*1000 + (Y)*100 + (Z)) #define DFB_COMPILEDVERSION \ - DFB_VERSIONNUM(DIRECTFB_MAJOR_VERSION, DIRECTFB_MINOR_VERSION, DIRECTFB_MICRO_VERSION) + DFB_VERSIONNUM(DIRECTFB_MAJOR_VERSION, DIRECTFB_MINOR_VERSION, DIRECTFB_MICRO_VERSION) #define DFB_VERSION_ATLEAST(X, Y, Z) \ - (DFB_COMPILEDVERSION >= DFB_VERSIONNUM(X, Y, Z)) + (DFB_COMPILEDVERSION >= DFB_VERSIONNUM(X, Y, Z)) -#define SDL_DFB_CHECK(x) x +#define SDL_DFB_CHECK(x) x #endif /* the following is not yet tested ... */ -#define USE_DISPLAY_PALETTE (0) +#define USE_DISPLAY_PALETTE (0) #define SDL_DFB_RENDERERDATA(rend) DirectFB_RenderData *renddata = ((rend) ? (DirectFB_RenderData *) (rend)->driverdata : NULL) @@ -100,9 +100,9 @@ static int DirectFB_RenderDrawPoints(SDL_Renderer * renderer, static int DirectFB_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points, int count); static int DirectFB_RenderDrawRects(SDL_Renderer * renderer, - const SDL_Rect ** rects, int count); + const SDL_Rect ** rects, int count); static int DirectFB_RenderFillRects(SDL_Renderer * renderer, - const SDL_FRect * rects, int count); + const SDL_FRect * rects, int count); static int DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, @@ -116,6 +116,7 @@ static int DirectFB_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * r static int DirectFB_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 format, const void * pixels, int pitch); static int DirectFB_UpdateViewport(SDL_Renderer * renderer); +static int DirectFB_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture); static int PrepareDraw(SDL_Renderer * renderer); @@ -135,7 +136,7 @@ SDL_RenderDriver DirectFB_RenderDriver = { SDL_SCALEMODE_SLOW | SDL_SCALEMODE_BEST),*/ 0, { - /* formats filled in later */ + /* formats filled in later */ }, 0, 0} @@ -149,6 +150,7 @@ typedef struct int lastBlendMode; DFBSurfaceBlittingFlags blitFlags; DFBSurfaceDrawingFlags drawFlags; + IDirectFBSurface* target; } DirectFB_RenderData; typedef struct @@ -191,7 +193,7 @@ TextureHasAlpha(DirectFB_TextureData * data) /* Drawing primitive ? */ if (!data) return 0; - + return (DFB_PIXELFORMAT_HAS_ALPHA(DirectFB_SDLToDFBPixelFormat(data->format)) ? 1 : 0); #if 0 switch (data->format) { @@ -213,31 +215,31 @@ TextureHasAlpha(DirectFB_TextureData * data) static inline IDirectFBSurface *get_dfb_surface(SDL_Window *window) { - SDL_SysWMinfo wm_info; + SDL_SysWMinfo wm_info; SDL_memset(&wm_info, 0, sizeof(SDL_SysWMinfo)); - SDL_VERSION(&wm_info.version); - SDL_GetWindowWMInfo(window, &wm_info); + SDL_VERSION(&wm_info.version); + SDL_GetWindowWMInfo(window, &wm_info); - return wm_info.info.dfb.surface; + return wm_info.info.dfb.surface; } static inline IDirectFBWindow *get_dfb_window(SDL_Window *window) { - SDL_SysWMinfo wm_info; + SDL_SysWMinfo wm_info; SDL_memset(&wm_info, 0, sizeof(SDL_SysWMinfo)); - SDL_VERSION(&wm_info.version); - SDL_GetWindowWMInfo(window, &wm_info); + SDL_VERSION(&wm_info.version); + SDL_GetWindowWMInfo(window, &wm_info); - return wm_info.info.dfb.window; + return wm_info.info.dfb.window; } static void SetBlendMode(DirectFB_RenderData * data, int blendMode, DirectFB_TextureData * source) { - IDirectFBSurface *destsurf = get_dfb_surface(data->window); + IDirectFBSurface *destsurf = data->target; //FIXME: check for format change if (1 || data->lastBlendMode != blendMode) { @@ -268,7 +270,7 @@ SetBlendMode(DirectFB_RenderData * data, int blendMode, data->drawFlags = DSDRAW_BLEND; // FIXME: SRCALPHA kills performance on radeon ... // It will be cheaper to copy the surface to - // a temporay surface and premultiply + // a temporay surface and premultiply if (source && TextureHasAlpha(source)) SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_SRCALPHA)); else @@ -339,7 +341,7 @@ int DirectFB_RenderClear(SDL_Renderer * renderer) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; - IDirectFBSurface *destsurf = get_dfb_surface(data->window); + IDirectFBSurface *destsurf = data->target; DirectFB_ActivateRenderer(renderer); @@ -354,7 +356,7 @@ DirectFB_RenderClear(SDL_Renderer * renderer) SDL_Renderer * DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags) { - IDirectFBSurface *winsurf = get_dfb_surface(window); + IDirectFBSurface *winsurf = get_dfb_surface(window); SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); SDL_Renderer *renderer = NULL; DirectFB_RenderData *data = NULL; @@ -382,14 +384,15 @@ DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags) /* RenderFillEllipse - no reference implementation yet */ renderer->RenderCopy = DirectFB_RenderCopy; renderer->RenderPresent = DirectFB_RenderPresent; - + /* FIXME: Yet to be tested */ renderer->RenderReadPixels = DirectFB_RenderReadPixels; //renderer->RenderWritePixels = DirectFB_RenderWritePixels; - + renderer->DestroyTexture = DirectFB_DestroyTexture; renderer->DestroyRenderer = DirectFB_DestroyRenderer; renderer->UpdateViewport = DirectFB_UpdateViewport; + renderer->SetRenderTarget = DirectFB_SetRenderTarget; #if 0 renderer->QueryTexturePixels = DirectFB_QueryTexturePixels; @@ -406,9 +409,10 @@ DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->driverdata = data; renderer->info.flags = - SDL_RENDERER_ACCELERATED; + SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE; data->window = window; + data->target = winsurf; data->flipflags = DSFLIP_PIPELINE | DSFLIP_BLIT; @@ -449,14 +453,13 @@ DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags) static void DirectFB_ActivateRenderer(SDL_Renderer * renderer) { - SDL_DFB_RENDERERDATA(renderer); SDL_Window *window = renderer->window; SDL_DFB_WINDOWDATA(window); if (renddata->size_changed /*|| windata->wm_needs_redraw*/) { //DirectFB_AdjustWindowSurface(window); - renddata->size_changed = SDL_FALSE; + renddata->size_changed = SDL_FALSE; } } @@ -580,13 +583,13 @@ DirectFB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) SDL_DFB_CHECKERR(data->surface->GetPalette(data->surface, &data->palette)); #else /* DFB has issues with blitting LUT8 surfaces. - * Creating a new palette does not help. - */ - DFBPaletteDescription pal_desc; - pal_desc.flags = DPDESC_SIZE; // | DPDESC_ENTRIES - pal_desc.size = 256; - SDL_DFB_CHECKERR(devdata->dfb->CreatePalette(devdata->dfb, &pal_desc,&data->palette)); - SDL_DFB_CHECKERR(data->surface->SetPalette(data->surface, data->palette)); + * Creating a new palette does not help. + */ + DFBPaletteDescription pal_desc; + pal_desc.flags = DPDESC_SIZE; // | DPDESC_ENTRIES + pal_desc.size = 256; + SDL_DFB_CHECKERR(devdata->dfb->CreatePalette(devdata->dfb, &pal_desc,&data->palette)); + SDL_DFB_CHECKERR(data->surface->SetPalette(data->surface, data->palette)); #endif } @@ -642,7 +645,7 @@ DirectFB_SetTexturePalette(SDL_Renderer * renderer, int i; if (ncolors > 256) - ncolors = 256; + ncolors = 256; for (i = 0; i < ncolors; ++i) { entries[i].r = colors[i].r; @@ -788,7 +791,7 @@ DirectFB_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, (texture->format == SDL_PIXELFORMAT_IYUV)) { bpp = 1; } - + SDL_DFB_CHECKERR(data->surface->Lock(data->surface, DSLF_WRITE | DSLF_READ, ((void **) &dpixels), &dpitch)); @@ -892,11 +895,28 @@ DirectFB_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, } #endif +static int DirectFB_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) +{ + DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; + DirectFB_TextureData *tex_data = NULL; + + DirectFB_ActivateRenderer(renderer); + if (texture) { + tex_data = (DirectFB_TextureData *) texture->driverdata; + data->target = tex_data->surface; + } else { + data->target = get_dfb_surface(data->window); + } + data->lastBlendMode = 0; + return 0; +} + + static int PrepareDraw(SDL_Renderer * renderer) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; - IDirectFBSurface *destsurf = get_dfb_surface(data->window); + IDirectFBSurface *destsurf = data->target; Uint8 r, g, b, a; @@ -932,14 +952,14 @@ static int DirectFB_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points, int count) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; - IDirectFBSurface *destsurf = get_dfb_surface(data->window); + IDirectFBSurface *destsurf = data->target; int i; DirectFB_ActivateRenderer(renderer); PrepareDraw(renderer); for (i=0; i < count; i++) - SDL_DFB_CHECKERR(destsurf->DrawLine(destsurf, points[i].x, points[i].y, points[i].x, points[i].y)); + SDL_DFB_CHECKERR(destsurf->DrawLine(destsurf, points[i].x, points[i].y, points[i].x, points[i].y)); return 0; error: return -1; @@ -949,7 +969,7 @@ static int DirectFB_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points, int count) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; - IDirectFBSurface *destsurf = get_dfb_surface(data->window); + IDirectFBSurface *destsurf = data->target; int i; DirectFB_ActivateRenderer(renderer); @@ -961,7 +981,7 @@ static int DirectFB_RenderDrawLines(SDL_Renderer * renderer, #endif for (i=0; i < count - 1; i++) - SDL_DFB_CHECKERR(destsurf->DrawLine(destsurf, points[i].x, points[i].y, points[i+1].x, points[i+1].y)); + SDL_DFB_CHECKERR(destsurf->DrawLine(destsurf, points[i].x, points[i].y, points[i+1].x, points[i+1].y)); return 0; error: @@ -972,7 +992,7 @@ static int DirectFB_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; - IDirectFBSurface *destsurf = get_dfb_surface(data->window); + IDirectFBSurface *destsurf = data->target; int i; DirectFB_ActivateRenderer(renderer); @@ -980,8 +1000,8 @@ DirectFB_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int c PrepareDraw(renderer); for (i=0; iDrawRectangle(destsurf, rects[i]->x, rects[i]->y, - rects[i]->w, rects[i]->h)); + SDL_DFB_CHECKERR(destsurf->DrawRectangle(destsurf, rects[i]->x, rects[i]->y, + rects[i]->w, rects[i]->h)); return 0; error: @@ -992,7 +1012,7 @@ static int DirectFB_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int count) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; - IDirectFBSurface *destsurf = get_dfb_surface(data->window); + IDirectFBSurface *destsurf = data->target; int i; DirectFB_ActivateRenderer(renderer); @@ -1000,8 +1020,8 @@ DirectFB_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int c PrepareDraw(renderer); for (i=0; iFillRectangle(destsurf, rects[i].x, rects[i].y, - rects[i].w, rects[i].h)); + SDL_DFB_CHECKERR(destsurf->FillRectangle(destsurf, rects[i].x, rects[i].y, + rects[i].w, rects[i].h)); return 0; error: @@ -1013,7 +1033,7 @@ DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_FRect * dstrect) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; - IDirectFBSurface *destsurf = get_dfb_surface(data->window); + IDirectFBSurface *destsurf = data->target; DirectFB_TextureData *texturedata = (DirectFB_TextureData *) texture->driverdata; Uint8 alpha, r, g, b; @@ -1027,7 +1047,7 @@ DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, if (texturedata->display) { int px, py; SDL_Window *window = renderer->window; - IDirectFBWindow *dfbwin = get_dfb_window(window); + IDirectFBWindow *dfbwin = get_dfb_window(window); SDL_DFB_WINDOWDATA(window); SDL_VideoDisplay *display = texturedata->display; DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata; @@ -1079,13 +1099,13 @@ DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, } SDLtoDFBRect(srcrect, &sr); - SDLtoDFBRect(dstrect, &dr); + SDLtoDFBRect_Float(dstrect, &dr); alpha = r = g = b = 0xff; - if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA){ - alpha = texture->a; - flags |= DSBLIT_BLEND_COLORALPHA; - } + if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA){ + alpha = texture->a; + flags |= DSBLIT_BLEND_COLORALPHA; + } if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) { r = texture->r; @@ -1189,7 +1209,6 @@ DirectFB_DestroyRenderer(SDL_Renderer * renderer) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; SDL_VideoDisplay *display = SDL_GetDisplayForWindow(data->window); - #if 0 if (display->palette) { SDL_DelPaletteWatch(display->palette, DisplayPaletteChanged, data); @@ -1205,15 +1224,16 @@ DirectFB_DestroyRenderer(SDL_Renderer * renderer) static int DirectFB_UpdateViewport(SDL_Renderer * renderer) { - IDirectFBSurface *winsurf = get_dfb_surface(renderer->window); - DFBRegion dreg; + DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; + IDirectFBSurface *winsurf = data->target; + DFBRegion dreg; - dreg.x1 = renderer->viewport.x; - dreg.y1 = renderer->viewport.y; - dreg.x2 = dreg.x1 + renderer->viewport.w - 1; - dreg.y2 = dreg.y1 + renderer->viewport.h - 1; + dreg.x1 = renderer->viewport.x; + dreg.y1 = renderer->viewport.y; + dreg.x2 = dreg.x1 + renderer->viewport.w - 1; + dreg.y2 = dreg.y1 + renderer->viewport.h - 1; - winsurf->SetClip(winsurf, &dreg); + winsurf->SetClip(winsurf, &dreg); return 0; } @@ -1222,24 +1242,25 @@ DirectFB_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 format, void * pixels, int pitch) { Uint32 sdl_format; - void * laypixels; - int laypitch; - DFBSurfacePixelFormat dfb_format; - IDirectFBSurface *winsurf = get_dfb_surface(renderer->window); + void * laypixels; + int laypitch; + DFBSurfacePixelFormat dfb_format; + DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; + IDirectFBSurface *winsurf = data->target; DirectFB_ActivateRenderer(renderer); winsurf->GetPixelFormat(winsurf, &dfb_format); sdl_format = DirectFB_DFBToSDLPixelFormat(dfb_format); winsurf->Lock(winsurf, DSLF_READ, (void **) &laypixels, &laypitch); - + laypixels += (rect->y * laypitch + rect->x * SDL_BYTESPERPIXEL(sdl_format) ); SDL_ConvertPixels(rect->w, rect->h, sdl_format, laypixels, laypitch, format, pixels, pitch); winsurf->Unlock(winsurf); - + return 0; } @@ -1251,15 +1272,15 @@ DirectFB_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, SDL_Window *window = renderer->window; SDL_DFB_WINDOWDATA(window); Uint32 sdl_format; - void * laypixels; - int laypitch; - DFBSurfacePixelFormat dfb_format; + void * laypixels; + int laypitch; + DFBSurfacePixelFormat dfb_format; SDL_DFB_CHECK(windata->surface->GetPixelFormat(windata->surface, &dfb_format)); sdl_format = DirectFB_DFBToSDLPixelFormat(dfb_format); SDL_DFB_CHECK(windata->surface->Lock(windata->surface, DSLF_WRITE, (void **) &laypixels, &laypitch)); - + laypixels += (rect->y * laypitch + rect->x * SDL_BYTESPERPIXEL(sdl_format) ); SDL_ConvertPixels(rect->w, rect->h, format, pixels, pitch,