diff src/video/directfb/SDL_DirectFB_render.c @ 2737:140a7edcf2bd

Date: Sun, 31 Aug 2008 17:53:59 +0200 From: Couriersud Subject: Re: Updated DirectFB driver for SDL1.3 attached is a patch which brings the directfb driver in line with current svn. In addition: * driver now is in line with the structure of the X11 driver. This adds a couple of files. * driver now supports relative mouse movements
author Sam Lantinga <slouken@libsdl.org>
date Sun, 31 Aug 2008 16:04:32 +0000
parents 91f1706b27be
children 8133d1d278da
line wrap: on
line diff
--- a/src/video/directfb/SDL_DirectFB_render.c	Sun Aug 31 16:03:55 2008 +0000
+++ b/src/video/directfb/SDL_DirectFB_render.c	Sun Aug 31 16:04:32 2008 +0000
@@ -29,11 +29,15 @@
 #include "../SDL_rect_c.h"
 #include "../SDL_yuv_sw_c.h"
 
+/* the following is not yet tested ... */
+#define USE_DISPLAY_PALETTE			(0)
+
 /* GDI renderer implementation */
 
 static SDL_Renderer *DirectFB_CreateRenderer(SDL_Window * window,
                                              Uint32 flags);
 static int DirectFB_DisplayModeChanged(SDL_Renderer * renderer);
+static int DirectFB_ActivateRenderer(SDL_Renderer * renderer);
 static int DirectFB_CreateTexture(SDL_Renderer * renderer,
                                   SDL_Texture * texture);
 static int DirectFB_QueryTexturePixels(SDL_Renderer * renderer,
@@ -89,11 +93,12 @@
      (SDL_TEXTUREBLENDMODE_NONE | SDL_TEXTUREBLENDMODE_MASK |
       SDL_TEXTUREBLENDMODE_BLEND | SDL_TEXTUREBLENDMODE_ADD |
       SDL_TEXTUREBLENDMODE_MOD),
-     (SDL_TEXTURESCALEMODE_NONE | SDL_TEXTURESCALEMODE_FAST),
+     (SDL_TEXTURESCALEMODE_NONE | SDL_TEXTURESCALEMODE_FAST |
+      SDL_TEXTURESCALEMODE_SLOW | SDL_TEXTURESCALEMODE_BEST),
      14,
      {
+      SDL_PIXELFORMAT_INDEX4LSB,
       SDL_PIXELFORMAT_INDEX8,
-      SDL_PIXELFORMAT_INDEX4LSB,
       SDL_PIXELFORMAT_RGB332,
       SDL_PIXELFORMAT_RGB555,
       SDL_PIXELFORMAT_RGB565,
@@ -115,19 +120,32 @@
     IDirectFBSurface *surface;
     DFBSurfaceFlipFlags flipflags;
     int isyuvdirect;
+    int size_changed;
 } DirectFB_RenderData;
 
 typedef struct
 {
-    IDirectFBDisplayLayer *vidlayer;
     IDirectFBSurface *surface;
     Uint32 format;
     void *pixels;
     int pitch;
     IDirectFBPalette *palette;
-    DFB_DisplayData *display;
+    SDL_VideoDisplay *display;
+    SDL_DirtyRectList dirty;
+#if (DIRECTFB_MAJOR_VERSION == 1) && (DIRECTFB_MINOR_VERSION >= 2)
+    DFBSurfaceRenderOptions render_options;
+#endif
 } DirectFB_TextureData;
 
+static __inline__ void
+SDLtoDFBRect(const SDL_Rect * sr, DFBRectangle * dr)
+{
+    dr->x = sr->x;
+    dr->y = sr->y;
+    dr->h = sr->h;
+    dr->w = sr->w;
+}
+
 void
 DirectFB_AddRenderDriver(_THIS)
 {
@@ -136,24 +154,53 @@
         SDL_AddRenderDriver(i, &DirectFB_RenderDriver);
 }
 
+static int
+DisplayPaletteChanged(void *userdata, SDL_Palette * palette)
+{
+#if USE_DISPLAY_PALETTE
+    DirectFB_RenderData *data = (DirectFB_RenderData *) userdata;
+    IDirectFBPalette *surfpal;
+
+    int ret;
+    int i;
+    int ncolors;
+    DFBColor entries[256];
+
+    SDL_DFB_CHECKERR(data->surface->GetPalette(data->surface, &surfpal));
+
+    /* FIXME: number of colors */
+    ncolors = (palette->ncolors < 256 ? palette->ncolors : 256);
+
+    for (i = 0; i < ncolors; ++i) {
+        entries[i].r = palette->colors[i].r;
+        entries[i].g = palette->colors[i].g;
+        entries[i].b = palette->colors[i].b;
+        entries[i].a = palette->colors[i].unused;
+    }
+    SDL_DFB_CHECKERR(surfpal->SetEntries(surfpal, entries, ncolors, 0));
+    return 0;
+  error:
+#endif
+    return -1;
+}
+
+
 SDL_Renderer *
 DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags)
 {
     SDL_DFB_WINDOWDATA(window);
     SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
-    SDL_DFB_DEVICEDATA(display->device);
     SDL_Renderer *renderer = NULL;
     DirectFB_RenderData *data = NULL;
     DFBResult ret;
-    DFBSurfaceDescription dsc;
     DFBSurfaceCapabilities scaps;
     char *p;
-    int i, n;
 
     SDL_DFB_CALLOC(renderer, 1, sizeof(*renderer));
     SDL_DFB_CALLOC(data, 1, sizeof(*data));
 
     renderer->DisplayModeChanged = DirectFB_DisplayModeChanged;
+    renderer->ActivateRenderer = DirectFB_ActivateRenderer;
     renderer->CreateTexture = DirectFB_CreateTexture;
     renderer->QueryTexturePixels = DirectFB_QueryTexturePixels;
     renderer->SetTexturePalette = DirectFB_SetTexturePalette;
@@ -179,14 +226,16 @@
         SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTDISCARD;
 
     data->surface = windata->surface;
-    data->flipflags = 0;
+    data->surface->AddRef(data->surface);
+
+    data->flipflags = DSFLIP_PIPELINE | DSFLIP_BLIT;
 
     if (flags & SDL_RENDERER_PRESENTVSYNC) {
         data->flipflags = DSFLIP_ONSYNC;
         renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
     }
 
-    data->surface->GetCapabilities(data->surface, &scaps);
+    SDL_DFB_CHECKERR(data->surface->GetCapabilities(data->surface, &scaps));
     if (scaps & DSCAPS_DOUBLE)
         renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2;
     else if (scaps & DSCAPS_TRIPLE)
@@ -194,11 +243,16 @@
     else
         renderer->info.flags |= SDL_RENDERER_SINGLEBUFFER;
 
-    data->isyuvdirect = 1;      /* default is on! */
-    p = getenv("SDL_DIRECTFB_YUV_DIRECT");
+    data->isyuvdirect = 0;      /* default is off! */
+    p = getenv(DFBENV_USE_YUV_DIRECT);
     if (p)
         data->isyuvdirect = atoi(p);
 
+    /* Set up a palette watch on the display palette */
+    if (display->palette) {
+        SDL_AddPaletteWatch(display->palette, DisplayPaletteChanged, data);
+    }
+
     return renderer;
 
   error:
@@ -267,26 +321,38 @@
 }
 
 static int
-DirectFB_DisplayModeChanged(SDL_Renderer * renderer)
+DirectFB_ActivateRenderer(SDL_Renderer * renderer)
 {
     SDL_DFB_RENDERERDATA(renderer);
     SDL_Window *window = SDL_GetWindowFromID(renderer->window);
     SDL_DFB_WINDOWDATA(window);
-    SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
-    SDL_DFB_DEVICEDATA(display->device);
-    DFBResult ret;
-    DFBSurfaceDescription dsc;
-    int i, n;
+
+    if (renddata->size_changed) {
+        int cw, ch;
+        int ret;
 
-    /*
-     * Nothing to do here
-     */
+        SDL_DFB_CHECKERR(windata->surface->
+                         GetSize(windata->surface, &cw, &ch));
+        if (cw != window->w || ch != window->h)
+            SDL_DFB_CHECKERR(windata->window->
+                             ResizeSurface(windata->window, window->w,
+                                           window->h));
+    }
     return 0;
   error:
     return -1;
 }
 
 static int
+DirectFB_DisplayModeChanged(SDL_Renderer * renderer)
+{
+    SDL_DFB_RENDERERDATA(renderer);
+
+    renddata->size_changed = SDL_TRUE;
+    return 0;
+}
+
+static int
 DirectFB_AcquireVidLayer(SDL_Renderer * renderer, SDL_Texture * texture)
 {
     SDL_DFB_RENDERERDATA(renderer);
@@ -301,36 +367,42 @@
     if (renddata->isyuvdirect && (dispdata->vidID >= 0)
         && (!dispdata->vidIDinuse)
         && SDL_ISPIXELFORMAT_FOURCC(data->format)) {
-        layconf.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT;
+        layconf.flags =
+            DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT |
+            DLCONF_SURFACE_CAPS;
         layconf.width = texture->w;
         layconf.height = texture->h;
         layconf.pixelformat = SDLToDFBPixelFormat(data->format);
+        layconf.surface_caps = DSCAPS_VIDEOONLY | DSCAPS_DOUBLE;
 
         SDL_DFB_CHECKERR(devdata->dfb->
                          GetDisplayLayer(devdata->dfb, dispdata->vidID,
-                                         &data->vidlayer));
-        SDL_DFB_CHECKERR(data->vidlayer->
-                         SetCooperativeLevel(data->vidlayer,
+                                         &dispdata->vidlayer));
+        SDL_DFB_CHECKERR(dispdata->vidlayer->
+                         SetCooperativeLevel(dispdata->vidlayer,
                                              DLSCL_EXCLUSIVE));
-        SDL_DFB_CHECKERR(data->vidlayer->
-                         SetConfiguration(data->vidlayer, &layconf));
-        SDL_DFB_CHECKERR(data->vidlayer->
-                         GetSurface(data->vidlayer, &data->surface));
-        //SDL_DFB_CHECKERR(data->vidlayer->GetDescription(data->vidlayer, laydsc));
+
+        if (devdata->use_yuv_underlays) {
+            ret = dispdata->vidlayer->SetLevel(dispdata->vidlayer, -1);
+            if (ret != DFB_OK)
+                SDL_DFB_DEBUG("Underlay Setlevel not supported\n");
+        }
+        SDL_DFB_CHECKERR(dispdata->vidlayer->
+                         SetConfiguration(dispdata->vidlayer, &layconf));
+        SDL_DFB_CHECKERR(dispdata->vidlayer->
+                         GetSurface(dispdata->vidlayer, &data->surface));
         dispdata->vidIDinuse = 1;
-        data->display = dispdata;
-        SDL_DFB_DEBUG("Created HW YUV surface\n");
-
+        data->display = display;
         return 0;
     }
     return 1;
   error:
-    if (data->vidlayer) {
+    if (dispdata->vidlayer) {
         SDL_DFB_RELEASE(data->surface);
-        SDL_DFB_CHECKERR(data->vidlayer->
-                         SetCooperativeLevel(data->vidlayer,
+        SDL_DFB_CHECKERR(dispdata->vidlayer->
+                         SetCooperativeLevel(dispdata->vidlayer,
                                              DLSCL_ADMINISTRATIVE));
-        SDL_DFB_RELEASE(data->vidlayer);
+        SDL_DFB_RELEASE(dispdata->vidlayer);
     }
     return 1;
 }
@@ -338,23 +410,18 @@
 static int
 DirectFB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
 {
-    SDL_DFB_RENDERERDATA(renderer);
     SDL_Window *window = SDL_GetWindowFromID(renderer->window);
-    SDL_DFB_WINDOWDATA(window);
     SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
     SDL_DFB_DEVICEDATA(display->device);
     DirectFB_TextureData *data;
     DFBResult ret;
     DFBSurfaceDescription dsc;
-    DFBDisplayLayerDescription laydsc;
-    DFBDisplayLayerConfig layconf;
 
     SDL_DFB_CALLOC(data, 1, sizeof(*data));
     texture->driverdata = data;
 
     data->format = texture->format;
     data->pitch = (texture->w * SDL_BYTESPERPIXEL(data->format));
-    data->vidlayer = NULL;
 
     if (DirectFB_AcquireVidLayer(renderer, texture) != 0) {
         /* fill surface description */
@@ -365,13 +432,15 @@
         /* <1.2 Never use DSCAPS_VIDEOONLY here. It kills performance
          * No DSCAPS_SYSTEMONLY either - let dfb decide
          * 1.2: DSCAPS_SYSTEMONLY boosts performance by factor ~8
+         * Depends on other settings as well. Let dfb decide.
          */
         dsc.caps = DSCAPS_PREMULTIPLIED;
-
+#if 0
         if (texture->access == SDL_TEXTUREACCESS_STREAMING)
             dsc.caps |= DSCAPS_SYSTEMONLY;
         else
             dsc.caps |= DSCAPS_VIDEOONLY;
+#endif
 
         /* find the right pixelformat */
 
@@ -393,6 +462,15 @@
         }
 
     }
+#if (DIRECTFB_MAJOR_VERSION == 1) && (DIRECTFB_MINOR_VERSION >= 2)
+    data->render_options = DSRO_NONE;
+#endif
+
+    if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
+        data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
+        SDL_DFB_CALLOC(data->pixels, 1, texture->h * data->pitch);
+    }
+
     return 0;
 
   error:
@@ -406,13 +484,16 @@
 DirectFB_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture,
                             void **pixels, int *pitch)
 {
-    DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
+    DirectFB_TextureData *texturedata =
+        (DirectFB_TextureData *) texture->driverdata;
 
-    /*
-     * Always fail here so in compat mode SDL_HWSURFACE is set !
-     */
-
-    return -1;
+    if (texturedata->display) {
+        return -1;
+    } else {
+        *pixels = texturedata->pixels;
+        *pitch = texturedata->pitch;
+    }
+    return 0;
 }
 
 static int
@@ -420,8 +501,6 @@
                            const SDL_Color * colors, int firstcolor,
                            int ncolors)
 {
-    DirectFB_RenderData *renderdata =
-        (DirectFB_RenderData *) renderer->driverdata;
     DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
     DFBResult ret;
 
@@ -468,6 +547,7 @@
             colors[i].r = entries[i].r;
             colors[i].g = entries[i].g;
             colors[i].b = entries[i].b;
+            colors->unused = SDL_ALPHA_OPAQUE;
         }
         return 0;
     } else {
@@ -510,20 +590,29 @@
 static int
 DirectFB_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture)
 {
+#if (DIRECTFB_MAJOR_VERSION == 1) && (DIRECTFB_MINOR_VERSION >= 2)
+
+    DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
+
     switch (texture->scaleMode) {
     case SDL_TEXTURESCALEMODE_NONE:
     case SDL_TEXTURESCALEMODE_FAST:
-        return 0;
+        data->render_options = DSRO_NONE;
+        break;
     case SDL_TEXTURESCALEMODE_SLOW:
+        data->render_options = DSRO_SMOOTH_UPSCALE | DSRO_SMOOTH_DOWNSCALE;
+        break;
     case SDL_TEXTURESCALEMODE_BEST:
-        SDL_Unsupported();
-        texture->scaleMode = SDL_TEXTURESCALEMODE_FAST;
-        return -1;
+        data->render_options =
+            DSRO_SMOOTH_UPSCALE | DSRO_SMOOTH_DOWNSCALE | DSRO_ANTIALIAS;
+        break;
     default:
         SDL_Unsupported();
+        data->render_options = DSRO_NONE;
         texture->scaleMode = SDL_TEXTURESCALEMODE_NONE;
         return -1;
     }
+#endif
     return 0;
 }
 
@@ -532,8 +621,6 @@
                        const SDL_Rect * rect, const void *pixels, int pitch)
 {
     DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
-    DirectFB_RenderData *renderdata =
-        (DirectFB_RenderData *) renderer->driverdata;
     DFBResult ret;
     Uint8 *dpixels;
     int dpitch;
@@ -566,37 +653,32 @@
                      const SDL_Rect * rect, int markDirty, void **pixels,
                      int *pitch)
 {
-    DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
+    DirectFB_TextureData *texturedata =
+        (DirectFB_TextureData *) texture->driverdata;
     DFBResult ret;
-    void *fdata;
-    int fpitch;
-
-    SDL_DFB_CHECKERR(data->surface->Lock(data->surface,
-                                         DSLF_WRITE | DSLF_READ, &fdata,
-                                         &fpitch));
-    data->pixels = fdata;
-    data->pitch = fpitch;
 
-    switch (texture->format) {
-    case SDL_PIXELFORMAT_YV12:
-    case SDL_PIXELFORMAT_IYUV:
-        if (rect
-            && (rect->x != 0 || rect->y != 0 || rect->w != texture->w
-                || rect->h != texture->h)) {
-            SDL_SetError
-                ("YV12 and IYUV textures only support full surface locks");
-            return -1;
-        }
-        break;
-    default:
-        /* Only one plane, no worries */
-        break;
+    if (markDirty) {
+        SDL_AddDirtyRect(&texturedata->dirty, rect);
     }
 
-    *pitch = data->pitch;
-    *pixels = data->pixels;
+    if (texturedata->display) {
+        void *fdata;
+        int fpitch;
 
+        SDL_DFB_CHECKERR(texturedata->surface->Lock(texturedata->surface,
+                                                    DSLF_WRITE | DSLF_READ,
+                                                    &fdata, &fpitch));
+        *pitch = fpitch;
+        *pixels = fdata;
+    } else {
+        *pixels =
+            (void *) ((Uint8 *) texturedata->pixels +
+                      rect->y * texturedata->pitch +
+                      rect->x * SDL_BYTESPERPIXEL(texture->format));
+        *pitch = texturedata->pitch;
+    }
     return 0;
+
   error:
     return -1;
 }
@@ -604,17 +686,25 @@
 static void
 DirectFB_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
 {
-    DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
+    DirectFB_TextureData *texturedata =
+        (DirectFB_TextureData *) texture->driverdata;
 
-    data->surface->Unlock(data->surface);
-    data->pixels = NULL;
+    if (texturedata->display) {
+        texturedata->surface->Unlock(texturedata->surface);
+        texturedata->pixels = NULL;
+    }
 }
 
 static void
 DirectFB_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
                       int numrects, const SDL_Rect * rects)
 {
-    //TODO: DirtyTexture
+    DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
+    int i;
+
+    for (i = 0; i < numrects; ++i) {
+        SDL_AddDirtyRect(&data->dirty, &rects[i]);
+    }
 }
 
 static int
@@ -643,36 +733,51 @@
         (DirectFB_TextureData *) texture->driverdata;
     DFBResult ret;
 
-    if (texturedata->vidlayer) {
+    if (texturedata->display) {
         int px, py;
         SDL_Window *window = SDL_GetWindowFromID(renderer->window);
-        SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
-        SDL_DFB_DEVICEDATA(display->device);
+        SDL_DFB_WINDOWDATA(window);
+        SDL_VideoDisplay *display = texturedata->display;
         DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
-        SDL_DFB_WINDOWDATA(window);
 
-        SDL_DFB_CHECKERR(texturedata->vidlayer->
-                         SetSourceRectangle(texturedata->vidlayer, srcrect->x,
+        SDL_DFB_CHECKERR(dispdata->vidlayer->
+                         SetSourceRectangle(dispdata->vidlayer, srcrect->x,
                                             srcrect->y, srcrect->w,
                                             srcrect->h));
         windata->window->GetPosition(windata->window, &px, &py);
-        SDL_DFB_CHECKERR(texturedata->vidlayer->
-                         SetScreenRectangle(texturedata->vidlayer,
+        SDL_DFB_CHECKERR(dispdata->vidlayer->
+                         SetScreenRectangle(dispdata->vidlayer,
                                             px + dstrect->x, py + dstrect->y,
                                             dstrect->w, dstrect->h));
     } else {
         DFBRectangle sr, dr;
         DFBSurfaceBlittingFlags flags = 0;
 
-        sr.x = srcrect->x;
-        sr.y = srcrect->y;
-        sr.w = srcrect->w;
-        sr.h = srcrect->h;
+        if (texturedata->dirty.list) {
+            SDL_DirtyRect *dirty;
+            void *pixels;
+            int bpp = SDL_BYTESPERPIXEL(texture->format);
+            int pitch = texturedata->pitch;
 
-        dr.x = dstrect->x;
-        dr.y = dstrect->y;
-        dr.w = dstrect->w;
-        dr.h = dstrect->h;
+            for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) {
+                SDL_Rect *rect = &dirty->rect;
+                pixels =
+                    (void *) ((Uint8 *) texturedata->pixels +
+                              rect->y * pitch + rect->x * bpp);
+                DirectFB_UpdateTexture(renderer, texture, rect,
+                                       texturedata->pixels,
+                                       texturedata->pitch);
+            }
+            SDL_ClearDirtyRects(&texturedata->dirty);
+        }
+#if (DIRECTFB_MAJOR_VERSION == 1) && (DIRECTFB_MINOR_VERSION >= 2)
+        SDL_DFB_CHECKERR(data->surface->SetRenderOptions(data->surface,
+                                                         texturedata->
+                                                         render_options));
+#endif
+
+        SDLtoDFBRect(srcrect, &sr);
+        SDLtoDFBRect(dstrect, &dr);
 
         if (texture->
             modMode & (SDL_TEXTUREMODULATE_COLOR | SDL_TEXTUREMODULATE_ALPHA))
@@ -695,6 +800,7 @@
 
         switch (texture->blendMode) {
         case SDL_TEXTUREBLENDMODE_NONE:
+                                       /**< No blending */
             flags |= DSBLIT_NOFX;
             data->surface->SetSrcBlendFunction(data->surface, DSBF_ONE);
             data->surface->SetDstBlendFunction(data->surface, DSBF_ZERO);
@@ -725,10 +831,11 @@
 
         SDL_DFB_CHECKERR(data->surface->
                          SetBlittingFlags(data->surface, flags));
+
         if (srcrect->w == dstrect->w && srcrect->h == dstrect->h) {
             SDL_DFB_CHECKERR(data->surface->
-                             Blit(data->surface, texturedata->surface, &sr,
-                                  dr.x, dr.y));
+                             Blit(data->surface, texturedata->surface,
+                                  &sr, dr.x, dr.y));
         } else {
             SDL_DFB_CHECKERR(data->surface->
                              StretchBlit(data->surface, texturedata->surface,
@@ -746,7 +853,6 @@
     DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
     SDL_Window *window = SDL_GetWindowFromID(renderer->window);
 
-    SDL_DirtyRect *dirty;
     DFBRectangle sr;
     DFBResult ret;
 
@@ -757,7 +863,7 @@
 
     /* Send the data to the display */
     SDL_DFB_CHECKERR(data->surface->
-                     Flip(data->surface, NULL, data->flipflags));
+                     Flip(data->surface, NULL, 0 * data->flipflags));
 
     return;
   error:
@@ -775,11 +881,15 @@
     SDL_DFB_RELEASE(data->palette);
     SDL_DFB_RELEASE(data->surface);
     if (data->display) {
-        data->display->vidIDinuse = 0;
-        data->vidlayer->SetCooperativeLevel(data->vidlayer,
-                                            DLSCL_ADMINISTRATIVE);
+        DFB_DisplayData *dispdata =
+            (DFB_DisplayData *) data->display->driverdata;
+        dispdata->vidIDinuse = 0;
+        dispdata->vidlayer->SetCooperativeLevel(dispdata->vidlayer,
+                                                DLSCL_ADMINISTRATIVE);
+        SDL_DFB_RELEASE(dispdata->vidlayer);
     }
-    SDL_DFB_RELEASE(data->vidlayer);
+    SDL_FreeDirtyRects(&data->dirty);
+    SDL_DFB_FREE(data->pixels);
     SDL_free(data);
     texture->driverdata = NULL;
 }
@@ -788,10 +898,9 @@
 DirectFB_DestroyRenderer(SDL_Renderer * renderer)
 {
     DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
-    int i;
 
     if (data) {
-        data->surface = NULL;
+        SDL_DFB_RELEASE(data->surface);
         SDL_free(data);
     }
     SDL_free(renderer);