diff src/video/directfb/SDL_DirectFB_render.c @ 5202:164f20ba08eb

Updated the DirectFB support, from Couriersud attached is a working directfb driver diff which works with the current changes. There are a number of changes around it as well, e.g. configure.in. The directfb renderdriver right now still depends on a some "includes" from src/video/directfb. That's why it is not yet moved to the new render folder.
author Sam Lantinga <slouken@libsdl.org>
date Sat, 05 Feb 2011 16:07:10 -0800
parents fb424691cfc7
children 58265e606e4e
line wrap: on
line diff
--- a/src/video/directfb/SDL_DirectFB_render.c	Sat Feb 05 16:02:30 2011 -0800
+++ b/src/video/directfb/SDL_DirectFB_render.c	Sat Feb 05 16:07:10 2011 -0800
@@ -18,47 +18,74 @@
 
     Sam Lantinga
     slouken@libsdl.org
-    
-    SDL1.3 implementation by couriersud@arcor.de
-    
+
+    SDL1.3 DirectFB driver by couriersud@arcor.de
+	
 */
-#include "SDL_config.h"
+#include "SDL_DirectFB_video.h"
+#include "SDL_DirectFB_window.h"
+#include "SDL_DirectFB_modes.h"
 
-#include "SDL_DirectFB_video.h"
-#include "SDL_DirectFB_render.h"
-#include "../SDL_yuv_sw_c.h"
+#include "SDL_DirectFB_shape.h"
+
+#include "../SDL_sysvideo.h"
+#include "../../render/SDL_sysrender.h"
+//#include "../SDL_rect_c.h"
+//#include "../SDL_yuv_sw_c.h"
 
 /* the following is not yet tested ... */
 #define USE_DISPLAY_PALETTE			(0)
 
+
+#define SDL_DFB_RENDERERDATA(rend) DirectFB_RenderData *renddata = ((rend) ? (DirectFB_RenderData *) (rend)->driverdata : NULL)
+
+
 /* 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 void DirectFB_ActivateRenderer(SDL_Renderer * renderer);
 static int DirectFB_CreateTexture(SDL_Renderer * renderer,
                                   SDL_Texture * texture);
 static int DirectFB_QueryTexturePixels(SDL_Renderer * renderer,
                                        SDL_Texture * texture,
                                        void **pixels, int *pitch);
+static int DirectFB_SetTexturePalette(SDL_Renderer * renderer,
+                                      SDL_Texture * texture,
+                                      const SDL_Color * colors,
+                                      int firstcolor, int ncolors);
+static int DirectFB_GetTexturePalette(SDL_Renderer * renderer,
+                                      SDL_Texture * texture,
+                                      SDL_Color * colors,
+                                      int firstcolor, int ncolors);
+static int DirectFB_SetTextureAlphaMod(SDL_Renderer * renderer,
+                                       SDL_Texture * texture);
+static int DirectFB_SetTextureColorMod(SDL_Renderer * renderer,
+                                       SDL_Texture * texture);
+static int DirectFB_SetTextureBlendMode(SDL_Renderer * renderer,
+                                        SDL_Texture * texture);
+static int DirectFB_SetTextureScaleMode(SDL_Renderer * renderer,
+                                        SDL_Texture * texture);
 static int DirectFB_UpdateTexture(SDL_Renderer * renderer,
                                   SDL_Texture * texture,
                                   const SDL_Rect * rect,
                                   const void *pixels, int pitch);
 static int DirectFB_LockTexture(SDL_Renderer * renderer,
                                 SDL_Texture * texture,
-                                const SDL_Rect * rect, int markDirty,
+                                const SDL_Rect * rect,
                                 void **pixels, int *pitch);
 static void DirectFB_UnlockTexture(SDL_Renderer * renderer,
                                    SDL_Texture * texture);
 static void DirectFB_DirtyTexture(SDL_Renderer * renderer,
                                   SDL_Texture * texture, int numrects,
                                   const SDL_Rect * rects);
+static int DirectFB_SetDrawBlendMode(SDL_Renderer * renderer);
 static int DirectFB_RenderDrawPoints(SDL_Renderer * renderer,
                                 const SDL_Point * points, int count);
 static int DirectFB_RenderDrawLines(SDL_Renderer * renderer,
                                const SDL_Point * points, int count);
+static int DirectFB_RenderDrawRects(SDL_Renderer * renderer,
+		const SDL_Rect ** rects, int count);
 static int DirectFB_RenderFillRects(SDL_Renderer * renderer,
 		const SDL_Rect ** rects, int count);
 static int DirectFB_RenderCopy(SDL_Renderer * renderer,
@@ -69,6 +96,11 @@
 static void DirectFB_DestroyTexture(SDL_Renderer * renderer,
                                     SDL_Texture * texture);
 static void DirectFB_DestroyRenderer(SDL_Renderer * renderer);
+static int DirectFB_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+                     Uint32 format, void * pixels, int pitch);
+static int DirectFB_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+                      Uint32 format, const void * pixels, int pitch);
+
 
 #define SDL_DFB_WINDOWSURFACE(win)  IDirectFBSurface *destsurf = ((DFB_WindowData *) ((win)->driverdata))->surface;
 
@@ -77,20 +109,16 @@
     {
      "directfb",
      (SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED),
-     12,
+     /* (SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_COLOR |
+      SDL_TEXTUREMODULATE_ALPHA),
+      (SDL_BLENDMODE_NONE | SDL_BLENDMODE_MASK | SDL_BLENDMODE_BLEND |
+      SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD),
+     (SDL_SCALEMODE_NONE | SDL_SCALEMODE_FAST |
+      SDL_SCALEMODE_SLOW | SDL_SCALEMODE_BEST),*/
+     0,
      {
-      SDL_PIXELFORMAT_RGB332,
-      SDL_PIXELFORMAT_RGB555,
-      SDL_PIXELFORMAT_RGB565,
-      SDL_PIXELFORMAT_RGB888,
-      SDL_PIXELFORMAT_ARGB8888,
-      SDL_PIXELFORMAT_ARGB4444,
-      SDL_PIXELFORMAT_ARGB1555,
-      SDL_PIXELFORMAT_RGB24,
-      SDL_PIXELFORMAT_YV12,
-      SDL_PIXELFORMAT_IYUV,
-      SDL_PIXELFORMAT_YUY2,
-      SDL_PIXELFORMAT_UYVY},
+    		 /* formats filled in later */
+     },
      0,
      0}
 };
@@ -99,7 +127,6 @@
 {
     SDL_Window *window;
     DFBSurfaceFlipFlags flipflags;
-    int isyuvdirect;
     int size_changed;
     int lastBlendMode;
     DFBSurfaceBlittingFlags blitFlags;
@@ -112,8 +139,11 @@
     Uint32 format;
     void *pixels;
     int pitch;
-    SDL_VideoDisplay *display;
-    SDL_DirtyRectList dirty;
+    IDirectFBPalette *palette;
+    int isDirty;
+
+    SDL_VideoDisplay *display;      /* only for yuv textures */
+
 #if (DFB_VERSION_ATLEAST(1,2,0))
     DFBSurfaceRenderOptions render_options;
 #endif
@@ -135,7 +165,12 @@
     /* Drawing primitive ? */
     if (!data)
         return 0;
+        
+    return (DFB_PIXELFORMAT_HAS_ALPHA(DirectFB_SDLToDFBPixelFormat(data->format)) ? 1 : 0);
+#if 0
     switch (data->format) {
+    case SDL_PIXELFORMAT_INDEX4LSB:
+    case SDL_PIXELFORMAT_INDEX4MSB:
     case SDL_PIXELFORMAT_ARGB4444:
     case SDL_PIXELFORMAT_ARGB1555:
     case SDL_PIXELFORMAT_ARGB8888:
@@ -143,10 +178,11 @@
     case SDL_PIXELFORMAT_ABGR8888:
     case SDL_PIXELFORMAT_BGRA8888:
     case SDL_PIXELFORMAT_ARGB2101010:
-        return 1;
+       return 1;
     default:
         return 0;
     }
+#endif
 }
 
 static void
@@ -165,6 +201,14 @@
             SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_ONE));
             SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_ZERO));
             break;
+#if 0
+        case SDL_BLENDMODE_MASK:
+            data->blitFlags =  DSBLIT_BLEND_ALPHACHANNEL;
+            data->drawFlags = DSDRAW_BLEND;
+            SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_SRCALPHA));
+            SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_INVSRCALPHA));
+            break;
+#endif
         case SDL_BLENDMODE_BLEND:
             data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
             data->drawFlags = DSDRAW_BLEND;
@@ -183,19 +227,74 @@
                 SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_ONE));
             SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_ONE));
             break;
+        case SDL_BLENDMODE_MOD:
+            data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
+            data->drawFlags = DSDRAW_BLEND;
+            //SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_DESTCOLOR));
+            //SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_ZERO));
+            //data->glBlendFunc(GL_ZERO, GL_SRC_COLOR);
+            SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_ZERO));
+            SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_SRCCOLOR));
+
+            break;
         }
         data->lastBlendMode = blendMode;
     }
 }
 
-void
-DirectFB_AddRenderDriver(_THIS)
+static int
+DisplayPaletteChanged(void *userdata, SDL_Palette * palette)
 {
+#if USE_DISPLAY_PALETTE
+    DirectFB_RenderData *data = (DirectFB_RenderData *) userdata;
+    SDL_DFB_WINDOWSURFACE(data->window);
+    IDirectFBPalette *surfpal;
+
     int i;
+    int ncolors;
+    DFBColor entries[256];
 
-    for (i = 0; i < _this->num_displays; ++i) {
-        SDL_AddRenderDriver(&_this->displays[i], &DirectFB_RenderDriver);
+    SDL_DFB_CHECKERR(destsurf->GetPalette(destsurf, &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:
+#else
+    SDL_Unsupported();
+#endif
+    return -1;
+}
+
+static void
+DirectFB_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
+{
+    SDL_DFB_RENDERERDATA(renderer);
+
+    if (event->event == SDL_WINDOWEVENT_RESIZED) {
+        /* Rebind the context to the window area and update matrices */
+        //SDL_CurrentContext = NULL;
+        //data->updateSize = SDL_TRUE;
+        renddata->size_changed = SDL_TRUE;
+   }
+}
+
+int
+DirectFB_RenderClear(SDL_Renderer * renderer)
+{
+    SDL_DFB_RENDERERDATA(renderer);
+
+    DirectFB_ActivateRenderer(renderer);
+
+    return 0;
 }
 
 SDL_Renderer *
@@ -205,35 +304,53 @@
     SDL_VideoDisplay *display = window->display;
     SDL_Renderer *renderer = NULL;
     DirectFB_RenderData *data = NULL;
-    char *p;
+    DFBSurfaceCapabilities scaps;
+    //char *p;
 
-    SDL_DFB_CALLOC(renderer, 1, sizeof(*renderer));
-    SDL_DFB_CALLOC(data, 1, sizeof(*data));
+    SDL_DFB_ALLOC_CLEAR(renderer, sizeof(*renderer));
+    SDL_DFB_ALLOC_CLEAR(data, sizeof(*data));
 
-    renderer->DisplayModeChanged = DirectFB_DisplayModeChanged;
-    renderer->ActivateRenderer = DirectFB_ActivateRenderer;
+    renderer->WindowEvent = DirectFB_WindowEvent;
     renderer->CreateTexture = DirectFB_CreateTexture;
-    renderer->QueryTexturePixels = DirectFB_QueryTexturePixels;
+    renderer->SetTextureAlphaMod = DirectFB_SetTextureAlphaMod;
+    renderer->SetTextureColorMod = DirectFB_SetTextureColorMod;
+    renderer->SetTextureBlendMode = DirectFB_SetTextureBlendMode;
     renderer->UpdateTexture = DirectFB_UpdateTexture;
     renderer->LockTexture = DirectFB_LockTexture;
+    renderer->RenderClear = DirectFB_RenderClear;
     renderer->UnlockTexture = DirectFB_UnlockTexture;
-    renderer->DirtyTexture = DirectFB_DirtyTexture;
     renderer->RenderDrawPoints = DirectFB_RenderDrawPoints;
     renderer->RenderDrawLines = DirectFB_RenderDrawLines;
+    /* SetDrawColor - no needed */
     renderer->RenderFillRects = DirectFB_RenderFillRects;
     /* RenderDrawEllipse - no reference implementation yet */
     /* RenderFillEllipse - no reference implementation yet */
     renderer->RenderCopy = DirectFB_RenderCopy;
     renderer->RenderPresent = DirectFB_RenderPresent;
-    /* RenderReadPixels is difficult to implement */
-    /* RenderWritePixels is difficult to implement */
+    
+    /* FIXME: Yet to be tested */
+    renderer->RenderReadPixels = DirectFB_RenderReadPixels;
+    //renderer->RenderWritePixels = DirectFB_RenderWritePixels;
+    
     renderer->DestroyTexture = DirectFB_DestroyTexture;
     renderer->DestroyRenderer = DirectFB_DestroyRenderer;
+
+#if 0
+    renderer->QueryTexturePixels = DirectFB_QueryTexturePixels;
+    renderer->SetTexturePalette = DirectFB_SetTexturePalette;
+    renderer->GetTexturePalette = DirectFB_GetTexturePalette;
+    renderer->SetTextureScaleMode = DirectFB_SetTextureScaleMode;
+    renderer->DirtyTexture = DirectFB_DirtyTexture;
+    renderer->SetDrawBlendMode = DirectFB_SetDrawBlendMode;
+    renderer->RenderDrawRects = DirectFB_RenderDrawRects;
+#endif
+
     renderer->info = DirectFB_RenderDriver.info;
     renderer->window = window;      /* SDL window */
     renderer->driverdata = data;
 
-    renderer->info.flags = SDL_RENDERER_ACCELERATED;
+    renderer->info.flags =
+        SDL_RENDERER_ACCELERATED;
 
     data->window = window;
 
@@ -245,10 +362,26 @@
     } else
         data->flipflags |= DSFLIP_ONSYNC;
 
-    data->isyuvdirect = 0;      /* default is off! */
-    p = SDL_getenv(DFBENV_USE_YUV_DIRECT);
-    if (p)
-        data->isyuvdirect = atoi(p);
+    SDL_DFB_CHECKERR(windata->surface->
+                     GetCapabilities(windata->surface, &scaps));
+
+#if 0
+    if (scaps & DSCAPS_DOUBLE)
+        renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2;
+    else if (scaps & DSCAPS_TRIPLE)
+        renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3;
+    else
+        renderer->info.flags |= SDL_RENDERER_SINGLEBUFFER;
+#endif
+
+    DirectFB_SetSupportedPixelFormats(&renderer->info);
+
+#if 0
+    /* Set up a palette watch on the display palette */
+    if (display->palette) {
+        SDL_AddPaletteWatch(display->palette, DisplayPaletteChanged, data);
+    }
+#endif
 
     return renderer;
 
@@ -258,58 +391,7 @@
     return NULL;
 }
 
-static DFBSurfacePixelFormat
-SDLToDFBPixelFormat(Uint32 format)
-{
-    switch (format) {
-    case SDL_PIXELFORMAT_RGB332:
-        return DSPF_RGB332;
-    case SDL_PIXELFORMAT_RGB555:
-        return DSPF_ARGB1555;
-    case SDL_PIXELFORMAT_ARGB4444:
-        return DSPF_ARGB4444;
-    case SDL_PIXELFORMAT_ARGB1555:
-        return DSPF_ARGB1555;
-    case SDL_PIXELFORMAT_RGB565:
-        return DSPF_RGB16;
-    case SDL_PIXELFORMAT_RGB24:
-        return DSPF_RGB24;
-    case SDL_PIXELFORMAT_RGB888:
-        return DSPF_RGB32;
-    case SDL_PIXELFORMAT_ARGB8888:
-        return DSPF_ARGB;
-    case SDL_PIXELFORMAT_YV12:
-        return DSPF_YV12;       /* Planar mode: Y + V + U  (3 planes) */
-    case SDL_PIXELFORMAT_IYUV:
-        return DSPF_I420;       /* Planar mode: Y + U + V  (3 planes) */
-    case SDL_PIXELFORMAT_YUY2:
-        return DSPF_YUY2;       /* Packed mode: Y0+U0+Y1+V0 (1 plane) */
-    case SDL_PIXELFORMAT_UYVY:
-        return DSPF_UYVY;       /* Packed mode: U0+Y0+V0+Y1 (1 plane) */
-    case SDL_PIXELFORMAT_YVYU:
-        return DSPF_UNKNOWN;    /* Packed mode: Y0+V0+Y1+U0 (1 plane) */
-#if (DFB_VERSION_ATLEAST(1,2,0))
-    case SDL_PIXELFORMAT_RGB444:
-        return DSPF_RGB444;
-#endif
-    case SDL_PIXELFORMAT_BGR24:
-        return DSPF_UNKNOWN;
-    case SDL_PIXELFORMAT_BGR888:
-        return DSPF_UNKNOWN;
-    case SDL_PIXELFORMAT_RGBA8888:
-        return DSPF_UNKNOWN;
-    case SDL_PIXELFORMAT_ABGR8888:
-        return DSPF_UNKNOWN;
-    case SDL_PIXELFORMAT_BGRA8888:
-        return DSPF_UNKNOWN;
-    case SDL_PIXELFORMAT_ARGB2101010:
-        return DSPF_UNKNOWN;
-    default:
-        return DSPF_UNKNOWN;
-    }
-}
-
-static int
+static void
 DirectFB_ActivateRenderer(SDL_Renderer * renderer)
 {
     SDL_DFB_RENDERERDATA(renderer);
@@ -317,24 +399,15 @@
     SDL_DFB_WINDOWDATA(window);
 
     if (renddata->size_changed || windata->wm_needs_redraw) {
-//        DirectFB_AdjustWindowSurface(window);
+        DirectFB_AdjustWindowSurface(window);
     }
-    return 0;
 }
 
-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);
+    //SDL_DFB_RENDERERDATA(renderer);
     SDL_Window *window = renderer->window;
     SDL_VideoDisplay *display = window->display;
     SDL_DFB_DEVICEDATA(display->device);
@@ -343,7 +416,7 @@
     DFBDisplayLayerConfig layconf;
     DFBResult ret;
 
-    if (renddata->isyuvdirect && (dispdata->vidID >= 0)
+    if (devdata->use_yuv_direct && (dispdata->vidID >= 0)
         && (!dispdata->vidIDinuse)
         && SDL_ISPIXELFORMAT_FOURCC(data->format)) {
         layconf.flags =
@@ -351,7 +424,7 @@
             DLCONF_SURFACE_CAPS;
         layconf.width = texture->w;
         layconf.height = texture->h;
-        layconf.pixelformat = SDLToDFBPixelFormat(data->format);
+        layconf.pixelformat = DirectFB_SDLToDFBPixelFormat(data->format);
         layconf.surface_caps = DSCAPS_VIDEOONLY | DSCAPS_DOUBLE;
 
         SDL_DFB_CHECKERR(devdata->dfb->GetDisplayLayer(devdata->dfb,
@@ -362,7 +435,7 @@
                                                        DLSCL_EXCLUSIVE));
 
         if (devdata->use_yuv_underlays) {
-            ret = SDL_DFB_CHECK(dispdata->vidlayer->SetLevel(dispdata->vidlayer, -1));
+            ret = dispdata->vidlayer->SetLevel(dispdata->vidlayer, -1);
             if (ret != DFB_OK)
                 SDL_DFB_DEBUG("Underlay Setlevel not supported\n");
         }
@@ -398,11 +471,13 @@
     DFBSurfaceDescription dsc;
     DFBSurfacePixelFormat pixelformat;
 
-    SDL_DFB_CALLOC(data, 1, sizeof(*data));
+    DirectFB_ActivateRenderer(renderer);
+
+    SDL_DFB_ALLOC_CLEAR(data, sizeof(*data));
     texture->driverdata = data;
 
     /* find the right pixelformat */
-    pixelformat = SDLToDFBPixelFormat(texture->format);
+    pixelformat = DirectFB_SDLToDFBPixelFormat(texture->format);
     if (pixelformat == DSPF_UNKNOWN) {
         SDL_SetError("Unknown pixel format %d\n", data->format);
         goto error;
@@ -417,6 +492,12 @@
             DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
         dsc.width = texture->w;
         dsc.height = texture->h;
+        if(texture->format == SDL_PIXELFORMAT_YV12 ||
+           texture->format == SDL_PIXELFORMAT_IYUV) {
+           /* dfb has problems with odd sizes -make them even internally */
+           dsc.width += (dsc.width % 2);
+           dsc.height += (dsc.height % 2);
+        }
         /* <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
@@ -436,18 +517,33 @@
         /* Create the surface */
         SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
                                                      &data->surface));
+        if (SDL_ISPIXELFORMAT_INDEXED(data->format)
+            && !SDL_ISPIXELFORMAT_FOURCC(data->format)) {
+#if 1
+            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));
+#endif
+        }
+
     }
 #if (DFB_VERSION_ATLEAST(1,2,0))
     data->render_options = DSRO_NONE;
 #endif
-
     if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
         /* 3 plane YUVs return 1 bpp, but we need more space for other planes */
         if(texture->format == SDL_PIXELFORMAT_YV12 ||
            texture->format == SDL_PIXELFORMAT_IYUV) {
-            SDL_DFB_CALLOC(data->pixels, 1, (texture->h * data->pitch * 3 + texture->h * data->pitch * 3 % 2) / 2);
+            SDL_DFB_ALLOC_CLEAR(data->pixels, (texture->h * data->pitch  + ((texture->h + texture->h % 2) * (data->pitch + data->pitch % 2) * 2) / 4));
         } else {
-            SDL_DFB_CALLOC(data->pixels, 1, texture->h * data->pitch);
+            SDL_DFB_ALLOC_CLEAR(data->pixels, texture->h * data->pitch);
         }
     }
 
@@ -477,6 +573,116 @@
 }
 
 static int
+DirectFB_SetTexturePalette(SDL_Renderer * renderer,
+                           SDL_Texture * texture,
+                           const SDL_Color * colors, int firstcolor,
+                           int ncolors)
+{
+    DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
+    if (SDL_ISPIXELFORMAT_INDEXED(data->format)
+        && !SDL_ISPIXELFORMAT_FOURCC(data->format)) {
+        DFBColor entries[256];
+        int i;
+
+        if (ncolors > 256)
+        	ncolors = 256;
+
+        for (i = 0; i < ncolors; ++i) {
+            entries[i].r = colors[i].r;
+            entries[i].g = colors[i].g;
+            entries[i].b = colors[i].b;
+            entries[i].a = 0xff;
+        }
+        SDL_DFB_CHECKERR(data->
+                         palette->SetEntries(data->palette, entries, ncolors, firstcolor));
+        return 0;
+    } else {
+        SDL_SetError("YUV textures don't have a palette");
+        return -1;
+    }
+  error:
+    return -1;
+}
+
+static int
+DirectFB_GetTexturePalette(SDL_Renderer * renderer,
+                           SDL_Texture * texture, SDL_Color * colors,
+                           int firstcolor, int ncolors)
+{
+    DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
+
+    if (SDL_ISPIXELFORMAT_INDEXED(data->format)
+        && !SDL_ISPIXELFORMAT_FOURCC(data->format)) {
+        DFBColor entries[256];
+        int i;
+
+        SDL_DFB_CHECKERR(data->
+                         palette->GetEntries(data->palette, entries, ncolors,
+                                             firstcolor));
+
+        for (i = 0; i < ncolors; ++i) {
+            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 {
+        SDL_SetError("YUV textures don't have a palette");
+        return -1;
+    }
+  error:
+    return -1;
+}
+
+static int
+DirectFB_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+    return 0;
+}
+
+static int
+DirectFB_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+    return 0;
+}
+
+static int
+DirectFB_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+    switch (texture->blendMode) {
+    case SDL_BLENDMODE_NONE:
+    //case SDL_BLENDMODE_MASK:
+    case SDL_BLENDMODE_BLEND:
+    case SDL_BLENDMODE_ADD:
+    case SDL_BLENDMODE_MOD:
+        return 0;
+    default:
+        SDL_Unsupported();
+        texture->blendMode = SDL_BLENDMODE_NONE;
+        return -1;
+    }
+}
+
+static int
+DirectFB_SetDrawBlendMode(SDL_Renderer * renderer)
+{
+    switch (renderer->blendMode) {
+    case SDL_BLENDMODE_NONE:
+    //case SDL_BLENDMODE_MASK:
+    case SDL_BLENDMODE_BLEND:
+    case SDL_BLENDMODE_ADD:
+    case SDL_BLENDMODE_MOD:
+        return 0;
+    default:
+        SDL_Unsupported();
+        renderer->blendMode = SDL_BLENDMODE_NONE;
+        return -1;
+    }
+}
+
+#if 0
+static int
 DirectFB_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture)
 {
 #if (DFB_VERSION_ATLEAST(1,2,0))
@@ -504,6 +710,7 @@
 #endif
     return 0;
 }
+#endif
 
 static int
 DirectFB_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
@@ -515,9 +722,16 @@
     Uint8 *src, *dst;
     int row;
     size_t length;
-    int bpp = DFB_BYTES_PER_PIXEL(SDLToDFBPixelFormat(texture->format));
+    int bpp = DFB_BYTES_PER_PIXEL(DirectFB_SDLToDFBPixelFormat(texture->format));
     // FIXME: SDL_BYTESPERPIXEL(texture->format) broken for yuv yv12 3 planes
 
+    DirectFB_ActivateRenderer(renderer);
+
+    if ((texture->format == SDL_PIXELFORMAT_YV12) ||
+        (texture->format == SDL_PIXELFORMAT_IYUV)) {
+        bpp = 1;
+    }
+    
     SDL_DFB_CHECKERR(data->surface->Lock(data->surface,
                                          DSLF_WRITE | DSLF_READ,
                                          ((void **) &dpixels), &dpitch));
@@ -530,24 +744,25 @@
         dst += dpitch;
     }
     /* copy other planes for 3 plane formats */
-    if (texture->format == SDL_PIXELFORMAT_YV12 ||
-        texture->format == SDL_PIXELFORMAT_IYUV) {
+    if ((texture->format == SDL_PIXELFORMAT_YV12) ||
+        (texture->format == SDL_PIXELFORMAT_IYUV)) {
         src = (Uint8 *) pixels + texture->h * pitch;
         dst = (Uint8 *) dpixels + texture->h * dpitch + rect->y * dpitch / 4 + rect->x * bpp / 2;
-        for (row = 0; row < rect->h / 2; ++row) {
+        for (row = 0; row < rect->h / 2 + (rect->h & 1); ++row) {
             SDL_memcpy(dst, src, length / 2);
             src += pitch / 2;
             dst += dpitch / 2;
         }
         src = (Uint8 *) pixels + texture->h * pitch + texture->h * pitch / 4;
         dst = (Uint8 *) dpixels + texture->h * dpitch + texture->h * dpitch / 4 + rect->y * dpitch / 4 + rect->x * bpp / 2;
-        for (row = 0; row < rect->h / 2; ++row) {
+        for (row = 0; row < rect->h / 2 + (rect->h & 1); ++row) {
             SDL_memcpy(dst, src, length / 2);
             src += pitch / 2;
             dst += dpitch / 2;
         }
     }
     SDL_DFB_CHECKERR(data->surface->Unlock(data->surface));
+    data->isDirty = 0;
     return 0;
   error:
     return 1;
@@ -556,15 +771,18 @@
 
 static int
 DirectFB_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
-                     const SDL_Rect * rect, int markDirty,
-                     void **pixels, int *pitch)
+                     const SDL_Rect * rect, void **pixels, int *pitch)
 {
     DirectFB_TextureData *texturedata =
         (DirectFB_TextureData *) texture->driverdata;
 
+    DirectFB_ActivateRenderer(renderer);
+
+#if 0
     if (markDirty) {
         SDL_AddDirtyRect(&texturedata->dirty, rect);
     }
+#endif
 
     if (texturedata->display) {
         void *fdata;
@@ -579,8 +797,9 @@
         *pixels =
             (void *) ((Uint8 *) texturedata->pixels +
                       rect->y * texturedata->pitch +
-                      rect->x * DFB_BYTES_PER_PIXEL(SDLToDFBPixelFormat(texture->format)));
+                      rect->x * DFB_BYTES_PER_PIXEL(DirectFB_SDLToDFBPixelFormat(texture->format)));
         *pitch = texturedata->pitch;
+        texturedata->isDirty = 1;
     }
     return 0;
 
@@ -594,12 +813,15 @@
     DirectFB_TextureData *texturedata =
         (DirectFB_TextureData *) texture->driverdata;
 
+    DirectFB_ActivateRenderer(renderer);
+
     if (texturedata->display) {
         SDL_DFB_CHECK(texturedata->surface->Unlock(texturedata->surface));
         texturedata->pixels = NULL;
     }
 }
 
+#if 0
 static void
 DirectFB_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
                       int numrects, const SDL_Rect * rects)
@@ -611,6 +833,7 @@
         SDL_AddDirtyRect(&data->dirty, &rects[i]);
     }
 }
+#endif
 
 static int
 PrepareDraw(SDL_Renderer * renderer)
@@ -630,9 +853,11 @@
 
     switch (renderer->blendMode) {
     case SDL_BLENDMODE_NONE:
+    //case SDL_BLENDMODE_MASK:
     case SDL_BLENDMODE_BLEND:
         break;
     case SDL_BLENDMODE_ADD:
+    case SDL_BLENDMODE_MOD:
         r = ((int) r * (int) a) / 255;
         g = ((int) g * (int) a) / 255;
         b = ((int) b * (int) a) / 255;
@@ -653,6 +878,8 @@
     SDL_DFB_WINDOWSURFACE(data->window);
     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));
@@ -668,6 +895,8 @@
     SDL_DFB_WINDOWSURFACE(data->window);
     int i;
 
+    DirectFB_ActivateRenderer(renderer);
+
     PrepareDraw(renderer);
     /* Use antialiasing when available */
 #if (DFB_VERSION_ATLEAST(1,2,0))
@@ -683,12 +912,34 @@
 }
 
 static int
+DirectFB_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
+{
+    DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
+    SDL_DFB_WINDOWSURFACE(data->window);
+    int i;
+
+    DirectFB_ActivateRenderer(renderer);
+
+    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));
+
+    return 0;
+  error:
+    return -1;
+}
+
+static int
 DirectFB_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
 {
     DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
     SDL_DFB_WINDOWSURFACE(data->window);
     int i;
 
+    DirectFB_ActivateRenderer(renderer);
+
     PrepareDraw(renderer);
 
     for (i=0; i<count; i++)
@@ -708,7 +959,9 @@
     SDL_DFB_WINDOWSURFACE(data->window);
     DirectFB_TextureData *texturedata =
         (DirectFB_TextureData *) texture->driverdata;
-    Uint8 alpha = 0xFF;
+    Uint8 alpha, r, g, b;
+
+    DirectFB_ActivateRenderer(renderer);
 
     if (texturedata->display) {
         int px, py;
@@ -722,7 +975,7 @@
                                                       srcrect->x, srcrect->y,
                                                       srcrect->w,
                                                       srcrect->h));
-        SDL_DFB_CHECK(windata->window->GetPosition(windata->window, &px, &py));
+        SDL_DFB_CHECK(windata->dfbwin->GetPosition(windata->dfbwin, &px, &py));
         px += windata->client.x;
         py += windata->client.y;
         SDL_DFB_CHECKERR(dispdata->
@@ -735,10 +988,11 @@
         DFBRectangle sr, dr;
         DFBSurfaceBlittingFlags flags = 0;
 
+#if 0
         if (texturedata->dirty.list) {
             SDL_DirtyRect *dirty;
             void *pixels;
-            int bpp = DFB_BYTES_PER_PIXEL(SDLToDFBPixelFormat(texture->format));
+            int bpp = DFB_BYTES_PER_PIXEL(DirectFB_SDLToDFBPixelFormat(texture->format));
             int pitch = texturedata->pitch;
 
             for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) {
@@ -747,38 +1001,43 @@
                     (void *) ((Uint8 *) texturedata->pixels +
                               rect->y * pitch + rect->x * bpp);
                 DirectFB_UpdateTexture(renderer, texture, rect,
-                                       texturedata->pixels,
+                                       pixels,
                                        texturedata->pitch);
             }
             SDL_ClearDirtyRects(&texturedata->dirty);
         }
+#endif
+        if (texturedata->isDirty)
+        {
+            SDL_Rect rect;
+
+            rect.x = 0;
+            rect.y = 0;
+            rect.w = texture->w;
+            rect.h = texture->h;
+
+            DirectFB_UpdateTexture(renderer, texture, &rect, texturedata->pixels, texturedata->pitch);
+        }
 
         SDLtoDFBRect(srcrect, &sr);
         SDLtoDFBRect(dstrect, &dr);
 
-        SDL_DFB_CHECKERR(destsurf->
-                         SetColor(destsurf, 0xFF, 0xFF, 0xFF, 0xFF));
-        if (texture->
-            modMode & (SDL_TEXTUREMODULATE_COLOR | SDL_TEXTUREMODULATE_ALPHA))
-        {
-            if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA) {
-                alpha = texture->a;
-                SDL_DFB_CHECKERR(destsurf->SetColor(destsurf, 0xFF, 0xFF,
-                                                    0xFF, alpha));
-            }
-            if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) {
+        alpha = r = g = b = 0xff;
+		if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA){
+			alpha = texture->a;
+        	flags |= DSBLIT_BLEND_COLORALPHA;
+		}
 
-                SDL_DFB_CHECKERR(destsurf->SetColor(destsurf,
-                                                    texture->r,
-                                                    texture->g,
-                                                    texture->b, alpha));
-                flags |= DSBLIT_COLORIZE;
-            }
-            if (alpha < 0xFF)
-                flags |= DSBLIT_SRC_PREMULTCOLOR;
-        } else
-            SDL_DFB_CHECKERR(destsurf->SetColor(destsurf, 0xFF, 0xFF,
-                                                0xFF, 0xFF));
+        if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) {
+            r = texture->r;
+            g = texture->g;
+            b = texture->b;
+            flags |= DSBLIT_COLORIZE;
+        }
+        SDL_DFB_CHECKERR(destsurf->
+                         SetColor(destsurf, r, g, b, alpha));
+
+        // ???? flags |= DSBLIT_SRC_PREMULTCOLOR;
 
         SetBlendMode(data, texture->blendMode, texturedata);
 
@@ -812,13 +1071,27 @@
     DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
     SDL_Window *window = renderer->window;
     SDL_DFB_WINDOWDATA(window);
+    SDL_ShapeData *shape_data = (window->shaper ? window->shaper->driverdata : NULL);
 
-    DFBRectangle sr;
+    DirectFB_ActivateRenderer(renderer);
 
-    sr.x = 0;
-    sr.y = 0;
-    sr.w = window->w;
-    sr.h = window->h;
+    if (shape_data && shape_data->surface) {
+        /* saturate the window surface alpha channel */
+        SDL_DFB_CHECK(windata->window_surface->SetSrcBlendFunction(windata->window_surface, DSBF_ONE));
+        SDL_DFB_CHECK(windata->window_surface->SetDstBlendFunction(windata->window_surface, DSBF_ONE));
+        SDL_DFB_CHECK(windata->window_surface->SetDrawingFlags(windata->window_surface, DSDRAW_BLEND));
+        SDL_DFB_CHECK(windata->window_surface->SetColor(windata->window_surface, 0, 0, 0, 0xff));
+        SDL_DFB_CHECK(windata->window_surface->FillRectangle(windata->window_surface, 0,0, windata->size.w, windata->size.h));
+
+        /* blit the mask */
+        SDL_DFB_CHECK(windata->surface->SetSrcBlendFunction(windata->surface, DSBF_DESTCOLOR));
+        SDL_DFB_CHECK(windata->surface->SetDstBlendFunction(windata->surface, DSBF_ZERO));
+        SDL_DFB_CHECK(windata->surface->SetBlittingFlags(windata->surface, DSBLIT_BLEND_ALPHACHANNEL));
+#if (DFB_VERSION_ATLEAST(1,2,0))
+        SDL_DFB_CHECK(windata->surface->SetRenderOptions(windata->surface, DSRO_NONE));
+#endif
+        SDL_DFB_CHECK(windata->surface->Blit(windata->surface, shape_data->surface, NULL, 0, 0));
+    }
 
     /* Send the data to the display */
     SDL_DFB_CHECK(windata->window_surface->Flip(windata->window_surface, NULL,
@@ -830,9 +1103,12 @@
 {
     DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
 
+    DirectFB_ActivateRenderer(renderer);
+
     if (!data) {
         return;
     }
+    //SDL_FreeDirtyRects(&data->dirty);
     SDL_DFB_RELEASE(data->palette);
     SDL_DFB_RELEASE(data->surface);
     if (data->display) {
@@ -844,7 +1120,6 @@
                                                 DLSCL_ADMINISTRATIVE));
         SDL_DFB_RELEASE(dispdata->vidlayer);
     }
-    SDL_FreeDirtyRects(&data->dirty);
     SDL_DFB_FREE(data->pixels);
     SDL_free(data);
     texture->driverdata = NULL;
@@ -854,6 +1129,13 @@
 DirectFB_DestroyRenderer(SDL_Renderer * renderer)
 {
     DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
+    SDL_VideoDisplay *display = renderer->window->display;
+
+#if 0
+    if (display->palette) {
+        SDL_DelPaletteWatch(display->palette, DisplayPaletteChanged, data);
+    }
+#endif
 
     if (data) {
         SDL_free(data);
@@ -861,4 +1143,58 @@
     SDL_free(renderer);
 }
 
+static int
+DirectFB_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+                     Uint32 format, void * pixels, int pitch)
+{
+    SDL_Window *window = renderer->window;
+    SDL_DFB_WINDOWDATA(window);
+    Uint32 sdl_format;
+   	void * laypixels;
+   	int laypitch;
+  	DFBSurfacePixelFormat dfb_format;
+
+    DirectFB_ActivateRenderer(renderer);
+
+    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_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);
+
+    SDL_DFB_CHECK(windata->surface->Unlock(windata->surface));
+    
+    return 0;
+}
+
+static int
+DirectFB_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+                      Uint32 format, const void * pixels, int pitch)
+{
+    SDL_Window *window = renderer->window;
+    SDL_DFB_WINDOWDATA(window);
+    Uint32 sdl_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,
+                      sdl_format, laypixels, laypitch);
+
+    SDL_DFB_CHECK(windata->surface->Unlock(windata->surface));
+
+    return 0;
+}
+
+
 /* vi: set ts=4 sw=4 expandtab: */