Fixed bug 1750 - Directfb renderer does not support SDL_RENDERER_TARGETTEXTURE
authorSam Lantinga <slouken@libsdl.org>
Sun, 10 Mar 2013 09:09:31 -0700
changeset 6989 be9c51af4f94
parent 6988 2aed1beaf5bc
child 6990 2514368c2aaf
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
--- a/src/video/directfb/SDL_DirectFB_render.c	Sun Mar 10 09:07:23 2013 -0700
+++ b/src/video/directfb/SDL_DirectFB_render.c	Sun Mar 10 09:09:31 2013 -0700
@@ -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_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_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_SCALEMODE_SLOW | SDL_SCALEMODE_BEST),*/
      0,
      {
-    		 /* formats filled in later */
+             /* formats filled in later */
      },
      0,
      0}
@@ -149,6 +150,7 @@
     int lastBlendMode;
     DFBSurfaceBlittingFlags blitFlags;
     DFBSurfaceDrawingFlags drawFlags;
+    IDirectFBSurface* target;
 } DirectFB_RenderData;
 
 typedef struct
@@ -191,7 +193,7 @@
     /* 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 @@
 
 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 @@
             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 @@
 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 @@
 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 @@
     /* 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 @@
     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 @@
 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 @@
             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 @@
         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 @@
         (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 @@
 }
 #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 @@
                                 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 @@
                                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 @@
 #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 @@
 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 @@
     PrepareDraw(renderer);
 
     for (i=0; i<count; i++)
-    	SDL_DFB_CHECKERR(destsurf->DrawRectangle(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 @@
 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 @@
     PrepareDraw(renderer);
 
     for (i=0; i<count; i++)
-    	SDL_DFB_CHECKERR(destsurf->FillRectangle(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 @@
                     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 @@
     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 @@
         }
 
         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_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 @@
 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 @@
                      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 @@
     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,