Nikolay Sivov : d2d1: Implement bitmap mapping.

Alexandre Julliard julliard at winehq.org
Mon May 30 15:34:58 CDT 2022


Module: wine
Branch: master
Commit: 5e25a4546c812eb174d142a41c28cf83ef2b567e
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=5e25a4546c812eb174d142a41c28cf83ef2b567e

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Sun May 29 15:18:53 2022 +0300

d2d1: Implement bitmap mapping.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>

---

 dlls/d2d1/bitmap.c       | 72 +++++++++++++++++++++++++++++++++++++++++++++---
 dlls/d2d1/d2d1_private.h |  1 +
 dlls/d2d1/tests/d2d1.c   | 21 +-------------
 3 files changed, 70 insertions(+), 24 deletions(-)

diff --git a/dlls/d2d1/bitmap.c b/dlls/d2d1/bitmap.c
index 904d44cc075..6a02279b91b 100644
--- a/dlls/d2d1/bitmap.c
+++ b/dlls/d2d1/bitmap.c
@@ -26,6 +26,25 @@ static inline struct d2d_bitmap *impl_from_ID2D1Bitmap1(ID2D1Bitmap1 *iface)
     return CONTAINING_RECORD(iface, struct d2d_bitmap, ID2D1Bitmap1_iface);
 }
 
+static HRESULT d2d_bitmap_unmap(struct d2d_bitmap *bitmap)
+{
+    ID3D11DeviceContext *context;
+    ID3D11Device *device;
+
+    if (!bitmap->mapped_resource.pData)
+        return D2DERR_WRONG_STATE;
+
+    ID3D11Resource_GetDevice(bitmap->resource, &device);
+    ID3D11Device_GetImmediateContext(device, &context);
+    ID3D11DeviceContext_Unmap(context, bitmap->resource, 0);
+    ID3D11DeviceContext_Release(context);
+    ID3D11Device_Release(device);
+
+    memset(&bitmap->mapped_resource, 0, sizeof(bitmap->mapped_resource));
+
+    return S_OK;
+}
+
 static HRESULT STDMETHODCALLTYPE d2d_bitmap_QueryInterface(ID2D1Bitmap1 *iface, REFIID iid, void **out)
 {
     TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
@@ -229,16 +248,61 @@ static HRESULT STDMETHODCALLTYPE d2d_bitmap_GetSurface(ID2D1Bitmap1 *iface, IDXG
 static HRESULT STDMETHODCALLTYPE d2d_bitmap_Map(ID2D1Bitmap1 *iface, D2D1_MAP_OPTIONS options,
         D2D1_MAPPED_RECT *mapped_rect)
 {
-    FIXME("iface %p, options %#x, mapped_rect %p stub!\n", iface, options, mapped_rect);
+    struct d2d_bitmap *bitmap = impl_from_ID2D1Bitmap1(iface);
+    D3D11_MAPPED_SUBRESOURCE mapped_resource;
+    ID3D11DeviceContext *context;
+    ID3D11Device *device;
+    D3D11_MAP map_type;
+    HRESULT hr;
 
-    return E_NOTIMPL;
+    TRACE("iface %p, options %#x, mapped_rect %p.\n", iface, options, mapped_rect);
+
+    if (bitmap->mapped_resource.pData)
+        return D2DERR_WRONG_STATE;
+
+    if (options == D2D1_MAP_OPTIONS_READ)
+        map_type = D3D11_MAP_READ;
+    else if (options == D2D1_MAP_OPTIONS_WRITE)
+        map_type = D3D11_MAP_WRITE;
+    else if (options == (D2D1_MAP_OPTIONS_READ | D2D1_MAP_OPTIONS_WRITE))
+        map_type = D3D11_MAP_READ_WRITE;
+    else if (options == (D2D1_MAP_OPTIONS_WRITE | D2D1_MAP_OPTIONS_DISCARD))
+        map_type = D3D11_MAP_WRITE_DISCARD;
+    else
+    {
+        WARN("Invalid mapping options %#x.\n", options);
+        return E_INVALIDARG;
+    }
+
+    ID3D11Resource_GetDevice(bitmap->resource, &device);
+    ID3D11Device_GetImmediateContext(device, &context);
+    if (SUCCEEDED(hr = ID3D11DeviceContext_Map(context, bitmap->resource, 0, map_type,
+            0, &mapped_resource)))
+    {
+        bitmap->mapped_resource = mapped_resource;
+    }
+    ID3D11DeviceContext_Release(context);
+    ID3D11Device_Release(device);
+
+    if (FAILED(hr))
+    {
+        WARN("Failed to map resource, hr %#lx.\n", hr);
+        return E_INVALIDARG;
+    }
+
+    mapped_rect->pitch = bitmap->mapped_resource.RowPitch;
+    mapped_rect->bits  = bitmap->mapped_resource.pData;
+
+    return S_OK;
 }
 
 static HRESULT STDMETHODCALLTYPE d2d_bitmap_Unmap(ID2D1Bitmap1 *iface)
 {
-    FIXME("iface %p stub!\n", iface);
+    struct d2d_bitmap *bitmap = impl_from_ID2D1Bitmap1(iface);
 
-    return E_NOTIMPL;
+    TRACE("iface %p.\n", iface);
+
+    return d2d_bitmap_unmap(bitmap);
 }
 
 static const struct ID2D1Bitmap1Vtbl d2d_bitmap_vtbl =
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h
index 8edfa030ee1..48649f6a916 100644
--- a/dlls/d2d1/d2d1_private.h
+++ b/dlls/d2d1/d2d1_private.h
@@ -395,6 +395,7 @@ struct d2d_bitmap
     ID3D11RenderTargetView *rtv;
     IDXGISurface *surface;
     ID3D11Resource *resource;
+    D3D11_MAPPED_SUBRESOURCE mapped_resource;
     D2D1_SIZE_U pixel_size;
     D2D1_PIXEL_FORMAT format;
     float dpi_x;
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c
index ac96c1a0d50..807a7be5ae6 100644
--- a/dlls/d2d1/tests/d2d1.c
+++ b/dlls/d2d1/tests/d2d1.c
@@ -11634,13 +11634,10 @@ static void test_bitmap_map(BOOL d3d11)
         ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
 
         hr = ID2D1Bitmap1_Map(bitmap, D2D1_MAP_OPTIONS_NONE, &mapped_rect);
-        todo_wine
         ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
         hr = ID2D1Bitmap1_Map(bitmap, D2D1_MAP_OPTIONS_READ, &mapped_rect);
-        todo_wine
         ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
         hr = ID2D1Bitmap1_Map(bitmap, D2D1_MAP_OPTIONS_WRITE, &mapped_rect);
-        todo_wine
         ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
 
         hr = ID2D1Bitmap1_GetSurface(bitmap, &surface);
@@ -11672,37 +11669,28 @@ static void test_bitmap_map(BOOL d3d11)
         ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
 
         hr = ID2D1Bitmap1_Map(bitmap, D2D1_MAP_OPTIONS_NONE, &mapped_rect);
-        todo_wine
         ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
 
         hr = ID2D1Bitmap1_Map(bitmap, D2D1_MAP_OPTIONS_READ, &mapped_rect);
-        todo_wine
         ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
         hr = ID2D1Bitmap1_Map(bitmap, D2D1_MAP_OPTIONS_READ, &mapped_rect);
-        todo_wine
         ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#lx.\n", hr);
         hr = ID2D1Bitmap1_Map(bitmap, D2D1_MAP_OPTIONS_WRITE, &mapped_rect);
         todo_wine
         ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
 
         hr = ID2D1Bitmap1_Unmap(bitmap);
-        todo_wine
         ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
         hr = ID2D1Bitmap1_Unmap(bitmap);
-        todo_wine
         ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#lx.\n", hr);
 
         hr = ID2D1Bitmap1_Map(bitmap, D2D1_MAP_OPTIONS_WRITE, &mapped_rect);
-        todo_wine
         ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
         hr = ID2D1Bitmap1_Map(bitmap, D2D1_MAP_OPTIONS_READ | D2D1_MAP_OPTIONS_DISCARD, &mapped_rect);
-        todo_wine
         ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
         hr = ID2D1Bitmap1_Map(bitmap, D2D1_MAP_OPTIONS_WRITE | D2D1_MAP_OPTIONS_DISCARD, &mapped_rect);
-        todo_wine
         ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
         hr = ID2D1Bitmap1_Map(bitmap, D2D1_MAP_OPTIONS_READ | D2D1_MAP_OPTIONS_WRITE, &mapped_rect);
-        todo_wine
         ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
 
         hr = ID2D1Bitmap1_GetSurface(bitmap, &surface);
@@ -11748,34 +11736,27 @@ static void test_bitmap_map(BOOL d3d11)
     ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
 
     hr = ID2D1Bitmap1_Map(bitmap, D2D1_MAP_OPTIONS_READ | D2D1_MAP_OPTIONS_DISCARD, &mapped_rect);
-    todo_wine
     ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
     hr = ID2D1Bitmap1_Map(bitmap, D2D1_MAP_OPTIONS_READ, &mapped_rect);
-    todo_wine
     ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
     hr = ID2D1Bitmap1_Unmap(bitmap);
-    todo_wine
     ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
 
     hr = ID2D1Bitmap1_Map(bitmap, D2D1_MAP_OPTIONS_WRITE, &mapped_rect);
-    todo_wine
     ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
     hr = ID2D1Bitmap1_Unmap(bitmap);
-    todo_wine
     ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
 
     hr = ID2D1Bitmap1_Map(bitmap, D2D1_MAP_OPTIONS_WRITE | D2D1_MAP_OPTIONS_READ, &mapped_rect);
-    todo_wine
     ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
     hr = ID2D1Bitmap1_Unmap(bitmap);
-    todo_wine
     ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
 
     hr = ID2D1Bitmap1_Map(bitmap, D2D1_MAP_OPTIONS_WRITE | D2D1_MAP_OPTIONS_DISCARD, &mapped_rect);
     todo_wine
     ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
+    if (SUCCEEDED(hr)) ID2D1Bitmap1_Unmap(bitmap);
     hr = ID2D1Bitmap1_Map(bitmap, D2D1_MAP_OPTIONS_WRITE | D2D1_MAP_OPTIONS_READ | D2D1_MAP_OPTIONS_DISCARD, &mapped_rect);
-    todo_wine
     ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
 
     ID2D1Bitmap1_Release(bitmap);




More information about the wine-cvs mailing list