[PATCH 2/2] wined3d: Clip software cursor blits.

Stefan Dösinger stefandoesinger at gmx.at
Thu Dec 10 14:02:35 CST 2015


This prevents the SW cursor from disappearing when it is at the edge of
the screen. Described in bug 38580, although that part isn't a a recent
regression.

I haven't named the parameters of wined3d_clip_blit src and dst because
the function doesn't care about the direction of the blit.

Signed-off-by: Stefan Dösinger <stefandoesinger at gmx.at>
---
 dlls/wined3d/swapchain.c       | 12 ++++++++++--
 dlls/wined3d/utils.c           | 22 ++++++++++++++++++++++
 dlls/wined3d/wined3d_private.h |  1 +
 3 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index e45fe17..069b071 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -467,13 +467,21 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT
             swapchain->device->xScreenSpace + swapchain->device->cursorWidth - swapchain->device->xHotSpot,
             swapchain->device->yScreenSpace + swapchain->device->cursorHeight - swapchain->device->yHotSpot,
         };
+        RECT src_rect =
+        {
+            0, 0,
+            swapchain->device->cursor_texture->resource.width,
+            swapchain->device->cursor_texture->resource.height
+        };
+        const RECT clip_rect = {0, 0, back_buffer->resource.width, back_buffer->resource.height};
 
         TRACE("Rendering the software cursor.\n");
 
         if (swapchain->desc.windowed)
             MapWindowPoints(NULL, swapchain->win_handle, (POINT *)&destRect, 2);
-        wined3d_surface_blt(back_buffer, &destRect, cursor, NULL, WINEDDBLT_ALPHATEST,
-                NULL, WINED3D_TEXF_POINT);
+        if (wined3d_clip_blit(&clip_rect, &destRect, &src_rect))
+            wined3d_surface_blt(back_buffer, &destRect, cursor, &src_rect, WINEDDBLT_ALPHATEST,
+                    NULL, WINED3D_TEXF_POINT);
     }
 
     TRACE("Presenting HDC %p.\n", context->hdc);
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 17ac29d..4406067 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -4994,3 +4994,25 @@ void wined3d_release_dc(HWND window, HDC dc)
     else if (!ReleaseDC(window, dc))
         ERR("Failed to release device context %p, last error %#x.\n", dc, GetLastError());
 }
+
+BOOL wined3d_clip_blit(const RECT *clip_rect, RECT *clipped, RECT *other)
+{
+    RECT orig = *clipped;
+    float scale_x = (float)(orig.right - orig.left) / (float)(other->right - other->left);
+    float scale_y = (float)(orig.bottom - orig.top) / (float)(other->bottom - other->top);
+
+    IntersectRect(clipped, clipped, clip_rect);
+
+    if (IsRectEmpty(clipped))
+    {
+        SetRectEmpty(other);
+        return FALSE;
+    }
+
+    other->left += (LONG)((clipped->left - orig.left) / scale_x);
+    other->top += (LONG)((clipped->top - orig.top) / scale_y);
+    other->right -= (LONG)((orig.right - clipped->right) / scale_x);
+    other->bottom -= (LONG)((orig.bottom - clipped->bottom) / scale_y);
+
+    return TRUE;
+}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 464bdf6..53ef63e 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1396,6 +1396,7 @@ extern const struct blit_shader ffp_blit DECLSPEC_HIDDEN;
 extern const struct blit_shader arbfp_blit DECLSPEC_HIDDEN;
 extern const struct blit_shader cpu_blit DECLSPEC_HIDDEN;
 
+BOOL wined3d_clip_blit(const RECT *clip_rect, RECT *clipped, RECT *other) DECLSPEC_HIDDEN;
 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info,
         const struct wined3d_d3d_info *d3d_info, enum wined3d_blit_op blit_op,
         const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
-- 
2.4.10




More information about the wine-patches mailing list