Prefer the D3D renderer over GDI, at least for testing.
authorSam Lantinga <slouken@libsdl.org>
Fri, 14 Jul 2006 08:22:45 +0000
changeset 1905 36d52b1f0504
parent 1904 1a713f9d1f71
child 1906 0c49855a7a3e
Prefer the D3D renderer over GDI, at least for testing. Added support for the SDL_VIDEO_RENDERER environment variable to pick the desired render driver. Implemented WritePixels support for the D3D renderer.
src/video/SDL_video.c
src/video/win32/SDL_d3drender.c
src/video/win32/SDL_gdirender.c
src/video/win32/SDL_win32video.c
--- a/src/video/SDL_video.c	Fri Jul 14 07:41:16 2006 +0000
+++ b/src/video/SDL_video.c	Fri Jul 14 08:22:45 2006 +0000
@@ -1296,18 +1296,25 @@
     }
 
     if (index < 0) {
+        const char *override = SDL_getenv("SDL_VIDEO_RENDERER");
         int n = SDL_GetNumRenderers();
         for (index = 0; index < n; ++index) {
             SDL_RenderDriver *driver =
                 &SDL_CurrentDisplay.render_drivers[index];
 
-            /* Skip minimal drivers in automatic scans */
-            if (!(flags & SDL_Renderer_Minimal)
-                && (driver->info.flags & SDL_Renderer_Minimal)) {
-                continue;
-            }
-            if ((driver->info.flags & flags) == flags) {
-                break;
+            if (override) {
+                if (SDL_strcasecmp(override, driver->info.name) == 0) {
+                    break;
+                }
+            } else {
+                /* Skip minimal drivers in automatic scans */
+                if (!(flags & SDL_Renderer_Minimal)
+                    && (driver->info.flags & SDL_Renderer_Minimal)) {
+                    continue;
+                }
+                if ((driver->info.flags & flags) == flags) {
+                    break;
+                }
             }
         }
         if (index == n) {
--- a/src/video/win32/SDL_d3drender.c	Fri Jul 14 07:41:16 2006 +0000
+++ b/src/video/win32/SDL_d3drender.c	Fri Jul 14 08:22:45 2006 +0000
@@ -74,10 +74,9 @@
     SDL_D3D_CreateRenderer,
     {
      "d3d",
-     (                          //SDL_Renderer_Minimal |
-         SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy |
-         SDL_Renderer_PresentFlip2 | SDL_Renderer_PresentFlip3 |
-         SDL_Renderer_PresentDiscard | SDL_Renderer_RenderTarget),
+     (SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy |
+      SDL_Renderer_PresentFlip2 | SDL_Renderer_PresentFlip3 |
+      SDL_Renderer_PresentDiscard | SDL_Renderer_RenderTarget),
      (SDL_TextureBlendMode_None |
       SDL_TextureBlendMode_Mask | SDL_TextureBlendMode_Blend),
      (SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast),
@@ -102,6 +101,8 @@
 typedef struct
 {
     IDirect3DDevice9 *device;
+    IDirect3DSurface9 *surface;
+    IDirect3DSurface9 *offscreen;
     SDL_bool beginScene;
 } SDL_D3D_RenderData;
 
@@ -530,6 +531,8 @@
 SDL_D3D_SelectRenderTexture(SDL_Renderer * renderer, SDL_Texture * texture)
 {
     SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata;
+
+    /* FIXME */
 }
 
 static int
@@ -640,6 +643,7 @@
 {
     SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata;
 
+    /* FIXME */
     return 0;
 }
 
@@ -647,7 +651,75 @@
 SDL_D3D_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
                           const void *pixels, int pitch)
 {
+    SDL_Window *window = SDL_GetWindowFromID(renderer->window);
+    SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
     SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata;
+    RECT d3drect;
+    POINT point;
+    D3DLOCKED_RECT locked;
+    const Uint8 *src;
+    Uint8 *dst;
+    int row, length;
+    HRESULT result;
+
+    if (!data->surface) {
+        result =
+            IDirect3DDevice9_GetBackBuffer(data->device, 0, 0,
+                                           D3DBACKBUFFER_TYPE_MONO,
+                                           &data->surface);
+        if (FAILED(result)) {
+            D3D_SetError("GetBackBuffer()", result);
+            return -1;
+        }
+    }
+    if (!data->offscreen) {
+        result =
+            IDirect3DDevice9_CreateOffscreenPlainSurface(data->device,
+                                                         window->w, window->h,
+                                                         PixelFormatToD3DFMT
+                                                         (display->
+                                                          current_mode.
+                                                          format),
+                                                         D3DPOOL_SYSTEMMEM,
+                                                         &data->offscreen,
+                                                         NULL);
+        if (FAILED(result)) {
+            D3D_SetError("CreateOffscreenPlainSurface()", result);
+            return -1;
+        }
+    }
+
+    d3drect.left = rect->x;
+    d3drect.right = rect->x + rect->w;
+    d3drect.top = rect->y;
+    d3drect.bottom = rect->y + rect->h;
+
+    result =
+        IDirect3DSurface9_LockRect(data->offscreen, &locked, &d3drect, 0);
+    if (FAILED(result)) {
+        D3D_SetError("LockRect()", result);
+        return -1;
+    }
+
+    src = pixels;
+    dst = locked.pBits;
+    length = rect->w * SDL_BYTESPERPIXEL(display->current_mode.format);
+    for (row = 0; row < rect->h; ++row) {
+        SDL_memcpy(dst, src, length);
+        src += pitch;
+        dst += locked.Pitch;
+    }
+    IDirect3DSurface9_UnlockRect(data->offscreen);
+
+    point.x = rect->x;
+    point.y = rect->y;
+    result =
+        IDirect3DDevice9_UpdateSurface(data->device, data->offscreen,
+                                       &d3drect, data->surface, &point);
+    if (FAILED(result)) {
+        D3D_SetError("UpdateSurface()", result);
+        return -1;
+    }
 
     return 0;
 }
@@ -693,6 +765,12 @@
         if (data->device) {
             IDirect3DDevice9_Release(data->device);
         }
+        if (data->surface) {
+            IDirect3DSurface9_Release(data->surface);
+        }
+        if (data->offscreen) {
+            IDirect3DSurface9_Release(data->offscreen);
+        }
         SDL_free(data);
     }
     SDL_free(renderer);
--- a/src/video/win32/SDL_gdirender.c	Fri Jul 14 07:41:16 2006 +0000
+++ b/src/video/win32/SDL_gdirender.c	Fri Jul 14 08:22:45 2006 +0000
@@ -79,8 +79,7 @@
     SDL_GDI_CreateRenderer,
     {
      "gdi",
-     (SDL_Renderer_Minimal |
-      SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy |
+     (SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy |
       SDL_Renderer_PresentFlip2 | SDL_Renderer_PresentFlip3 |
       SDL_Renderer_PresentDiscard | SDL_Renderer_RenderTarget),
      (SDL_TextureBlendMode_None | SDL_TextureBlendMode_Mask |
--- a/src/video/win32/SDL_win32video.c	Fri Jul 14 07:41:16 2006 +0000
+++ b/src/video/win32/SDL_win32video.c	Fri Jul 14 08:22:45 2006 +0000
@@ -140,12 +140,12 @@
 {
     WIN_InitModes(_this);
 
+#if SDL_VIDEO_RENDER_D3D
+    D3D_AddRenderDriver(_this);
+#endif
 #if SDL_VIDEO_RENDER_GDI
     GDI_AddRenderDriver(_this);
 #endif
-#if SDL_VIDEO_RENDER_D3D
-    D3D_AddRenderDriver(_this);
-#endif
 
     WIN_InitKeyboard(_this);
     WIN_InitMouse(_this);