[v2 PATCH] d2d1: Initial implementation of DC render target

Nikolay Sivov nsivov at codeweavers.com
Sun Sep 11 15:24:36 CDT 2016


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

v2: skip test if device creation fails

 dlls/d2d1/Makefile.in     |  3 ++-
 dlls/d2d1/d2d1_private.h  | 16 +++++++++++++++
 dlls/d2d1/factory.c       | 50 ++++++++++++++++++++++++++++++++++++++---------
 dlls/d2d1/render_target.c | 36 ++++++++++++++++++++++++++++++++++
 dlls/d2d1/tests/d2d1.c    | 18 ++++++++++++-----
 5 files changed, 108 insertions(+), 15 deletions(-)

diff --git a/dlls/d2d1/Makefile.in b/dlls/d2d1/Makefile.in
index 8a6618d..06f7bde 100644
--- a/dlls/d2d1/Makefile.in
+++ b/dlls/d2d1/Makefile.in
@@ -1,11 +1,12 @@
 MODULE    = d2d1.dll
 IMPORTLIB = d2d1
-IMPORTS   = d3d10_1 dxguid uuid
+IMPORTS   = d3d10_1 dxguid uuid gdi32
 DELAYIMPORTS = dwrite
 
 C_SRCS = \
 	bitmap.c \
 	brush.c \
+	dc_render_target.c \
 	factory.c \
 	geometry.c \
 	mesh.c \
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h
index f0577ed..fa7e464 100644
--- a/dlls/d2d1/d2d1_private.h
+++ b/dlls/d2d1/d2d1_private.h
@@ -96,6 +96,7 @@ struct d2d_d3d_render_target
 
 HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target, ID2D1Factory *factory,
         IDXGISurface *surface, const D2D1_RENDER_TARGET_PROPERTIES *desc) DECLSPEC_HIDDEN;
+HRESULT d2d_d3d_render_target_update_surface(ID2D1RenderTarget *render_target, IDXGISurface1 *surface) DECLSPEC_HIDDEN;
 
 struct d2d_wic_render_target
 {
@@ -115,6 +116,21 @@ struct d2d_wic_render_target
 HRESULT d2d_wic_render_target_init(struct d2d_wic_render_target *render_target, ID2D1Factory *factory,
         ID3D10Device1 *device, IWICBitmap *bitmap, const D2D1_RENDER_TARGET_PROPERTIES *desc) DECLSPEC_HIDDEN;
 
+struct d2d_dc_render_target
+{
+    ID2D1DCRenderTarget ID2D1DCRenderTarget_iface;
+    LONG refcount;
+
+    IDXGISurface1 *dxgi_surface;
+    ID2D1RenderTarget *dxgi_target;
+
+    RECT dst_rect;
+    HDC hdc;
+};
+
+HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID2D1Factory *factory,
+        ID3D10Device1 *device, const D2D1_RENDER_TARGET_PROPERTIES *desc) DECLSPEC_HIDDEN;
+
 struct d2d_gradient
 {
     ID2D1GradientStopCollection ID2D1GradientStopCollection_iface;
diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c
index d63add5..66ed25b 100644
--- a/dlls/d2d1/factory.c
+++ b/dlls/d2d1/factory.c
@@ -29,7 +29,7 @@ struct d2d_factory
     ID2D1Factory ID2D1Factory_iface;
     LONG refcount;
 
-    ID3D10Device1 *wic_device;
+    ID3D10Device1 *device;
 };
 
 static inline struct d2d_factory *impl_from_ID2D1Factory(ID2D1Factory *iface)
@@ -74,8 +74,8 @@ static ULONG STDMETHODCALLTYPE d2d_factory_Release(ID2D1Factory *iface)
 
     if (!refcount)
     {
-        if (factory->wic_device)
-            ID3D10Device1_Release(factory->wic_device);
+        if (factory->device)
+            ID3D10Device1_Release(factory->device);
         HeapFree(GetProcessHeap(), 0, factory);
     }
 
@@ -223,11 +223,24 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDrawingStateBlock(ID2D1Factor
     return S_OK;
 }
 
+static HRESULT d2d_factory_get_device(struct d2d_factory *factory, ID3D10Device1 **device)
+{
+    HRESULT hr = S_OK;
+
+    if (!factory->device && FAILED(hr = D3D10CreateDevice1(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, D3D10_CREATE_DEVICE_BGRA_SUPPORT,
+            D3D10_FEATURE_LEVEL_10_0, D3D10_1_SDK_VERSION, &factory->device)))
+        WARN("Failed to create device, hr %#x.\n", hr);
+
+    *device = factory->device;
+    return hr;
+}
+
 static HRESULT STDMETHODCALLTYPE d2d_factory_CreateWicBitmapRenderTarget(ID2D1Factory *iface,
         IWICBitmap *target, const D2D1_RENDER_TARGET_PROPERTIES *desc, ID2D1RenderTarget **render_target)
 {
     struct d2d_factory *factory = impl_from_ID2D1Factory(iface);
     struct d2d_wic_render_target *object;
+    ID3D10Device1 *device;
     HRESULT hr;
 
     TRACE("iface %p, target %p, desc %p, render_target %p.\n", iface, target, desc, render_target);
@@ -235,15 +248,13 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateWicBitmapRenderTarget(ID2D1Fa
     if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
         return E_OUTOFMEMORY;
 
-    if (!factory->wic_device && FAILED(hr = D3D10CreateDevice1(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL,
-            D3D10_CREATE_DEVICE_BGRA_SUPPORT, D3D10_FEATURE_LEVEL_10_0, D3D10_1_SDK_VERSION, &factory->wic_device)))
+    if (FAILED(hr = d2d_factory_get_device(factory, &device)))
     {
-        WARN("Failed to create device, hr %#x.\n", hr);
         HeapFree(GetProcessHeap(), 0, object);
         return hr;
     }
 
-    if (FAILED(hr = d2d_wic_render_target_init(object, iface, factory->wic_device, target, desc)))
+    if (FAILED(hr = d2d_wic_render_target_init(object, iface, device, target, desc)))
     {
         WARN("Failed to initialize render target, hr %#x.\n", hr);
         HeapFree(GetProcessHeap(), 0, object);
@@ -292,9 +303,30 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDxgiSurfaceRenderTarget(ID2D1
 static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDCRenderTarget(ID2D1Factory *iface,
         const D2D1_RENDER_TARGET_PROPERTIES *desc, ID2D1DCRenderTarget **render_target)
 {
-    FIXME("iface %p, desc %p, render_target %p stub!\n", iface, desc, render_target);
+    struct d2d_factory *factory = impl_from_ID2D1Factory(iface);
+    struct d2d_dc_render_target *object;
+    ID3D10Device1 *device;
+    HRESULT hr;
 
-    return E_NOTIMPL;
+    TRACE("iface %p, desc %p, render_target %p.\n", iface, desc, render_target);
+
+    if (FAILED(hr = d2d_factory_get_device(factory, &device)))
+        return hr;
+
+    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+        return E_OUTOFMEMORY;
+
+    if (FAILED(hr = d2d_dc_render_target_init(object, iface, device, desc)))
+    {
+        WARN("Failed to initialize render target, hr %#x.\n", hr);
+        HeapFree(GetProcessHeap(), 0, object);
+        return hr;
+    }
+
+    TRACE("Created render target %p.\n", object);
+    *render_target = &object->ID2D1DCRenderTarget_iface;
+
+    return S_OK;
 }
 
 static const struct ID2D1FactoryVtbl d2d_factory_vtbl =
diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c
index 5005840..6824e9f 100644
--- a/dlls/d2d1/render_target.c
+++ b/dlls/d2d1/render_target.c
@@ -2180,3 +2180,39 @@ err:
     ID2D1Factory_Release(render_target->factory);
     return hr;
 }
+
+HRESULT d2d_d3d_render_target_update_surface(ID2D1RenderTarget *iface, IDXGISurface1 *surface)
+{
+    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
+    DXGI_SURFACE_DESC surface_desc;
+    ID3D10RenderTargetView *view;
+    ID3D10Resource *resource;
+    HRESULT hr;
+
+    if (FAILED(hr = IDXGISurface1_GetDesc(surface, &surface_desc)))
+    {
+        WARN("Failed to get surface desc, hr %#x.\n", hr);
+        return hr;
+    }
+
+    if (FAILED(hr = IDXGISurface1_QueryInterface(surface, &IID_ID3D10Resource, (void **)&resource)))
+    {
+        WARN("Failed to get ID3D10Resource interface, hr %#x.\n", hr);
+        return hr;
+    }
+
+    hr = ID3D10Device_CreateRenderTargetView(render_target->device, resource, NULL, &view);
+    ID3D10Resource_Release(resource);
+    if (FAILED(hr))
+    {
+        WARN("Failed to create rendertarget view, hr %#x.\n", hr);
+        return hr;
+    }
+
+    render_target->pixel_size.width = surface_desc.Width;
+    render_target->pixel_size.height = surface_desc.Height;
+    ID3D10RenderTargetView_Release(render_target->view);
+    render_target->view = view;
+
+    return S_OK;
+}
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c
index 0a81013..a4b123d 100644
--- a/dlls/d2d1/tests/d2d1.c
+++ b/dlls/d2d1/tests/d2d1.c
@@ -2661,8 +2661,10 @@ static void test_dc_target(void)
     ID2D1SolidColorBrush *brush;
     ID2D1DCRenderTarget *rt;
     ID2D1Factory *factory;
+    ID3D10Device1 *device;
     FLOAT dpi_x, dpi_y;
     D2D1_COLOR_F color;
+    D2D1_SIZE_U sizeu;
     D2D1_SIZE_F size;
     D2D1_TAG t1, t2;
     unsigned int i;
@@ -2672,6 +2674,12 @@ static void test_dc_target(void)
     HRESULT hr;
     RECT rect;
 
+    if (!(device = create_device()))
+    {
+        skip("Failed to create device, skipping tests.\n");
+        return;
+    }
+
     hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
     ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
 
@@ -2685,7 +2693,6 @@ static void test_dc_target(void)
         desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
 
         hr = ID2D1Factory_CreateDCRenderTarget(factory, &desc, &rt);
-    todo_wine
         ok(hr == D2DERR_UNSUPPORTED_PIXEL_FORMAT, "Got unexpected hr %#x.\n", hr);
     }
 
@@ -2697,14 +2704,16 @@ static void test_dc_target(void)
     desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
     desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
     hr = ID2D1Factory_CreateDCRenderTarget(factory, &desc, &rt);
-todo_wine
     ok(SUCCEEDED(hr), "Failed to create target, hr %#x.\n", hr);
-if (SUCCEEDED(hr))
-{
+
     size = ID2D1DCRenderTarget_GetSize(rt);
     ok(size.width == 0.0f, "got width %.08e.\n", size.width);
     ok(size.height == 0.0f, "got height %.08e.\n", size.height);
 
+    sizeu = ID2D1DCRenderTarget_GetPixelSize(rt);
+    ok(sizeu.width == 0.0f, "got width %u.\n", sizeu.width);
+    ok(sizeu.height == 0.0f, "got height %u.\n", sizeu.height);
+
     /* object creation methods work without BindDC() */
     set_color(&color, 0.0f, 0.0f, 0.0f, 0.0f);
     hr = ID2D1DCRenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush);
@@ -2818,7 +2827,6 @@ if (SUCCEEDED(hr))
     DeleteDC(hdc);
     DeleteDC(hdc2);
     ID2D1DCRenderTarget_Release(rt);
-}
     ID2D1Factory_Release(factory);
 }
 
-- 
2.9.3




More information about the wine-patches mailing list