[v2 PATCH] d2d1: Return device context pointer for render targets.

Nikolay Sivov nsivov at codeweavers.com
Mon Sep 10 09:38:43 CDT 2018


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

v2: call back on EndDraw/Flush.

 dlls/d2d1/bitmap_render_target.c |  7 +++++-
 dlls/d2d1/d2d1_private.h         | 13 +++++++++--
 dlls/d2d1/dc_render_target.c     | 34 ++++++++++++++--------------
 dlls/d2d1/device.c               | 38 ++++++++++++++++++++++----------
 dlls/d2d1/hwnd_render_target.c   | 21 ++++++++++--------
 dlls/d2d1/wic_render_target.c    | 37 ++++++++++++++++---------------
 6 files changed, 91 insertions(+), 59 deletions(-)

diff --git a/dlls/d2d1/bitmap_render_target.c b/dlls/d2d1/bitmap_render_target.c
index c106e211d6..5ae155d430 100644
--- a/dlls/d2d1/bitmap_render_target.c
+++ b/dlls/d2d1/bitmap_render_target.c
@@ -733,6 +733,7 @@ HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_ta
         D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options)
 {
     D2D1_RENDER_TARGET_PROPERTIES dxgi_rt_desc;
+    struct outer_target_desc outer_desc;
     D2D1_BITMAP_PROPERTIES bitmap_desc;
     D3D10_TEXTURE2D_DESC texture_desc;
     IDXGISurface *dxgi_surface;
@@ -810,8 +811,12 @@ HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_ta
         return hr;
     }
 
+    outer_desc.outer_unknown = (IUnknown *)&render_target->ID2D1BitmapRenderTarget_iface;
+    outer_desc.data = NULL;
+    outer_desc.present = NULL;
+
     if (FAILED(hr = d2d_d3d_create_render_target(parent_target->factory, dxgi_surface,
-            (IUnknown *)&render_target->ID2D1BitmapRenderTarget_iface, &dxgi_rt_desc, &render_target->dxgi_target)))
+            &outer_desc, &dxgi_rt_desc, &render_target->dxgi_target)))
     {
         WARN("Failed to create DXGI surface render target, hr %#x.\n", hr);
         IDXGISurface_Release(dxgi_surface);
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h
index e00b942797..49d1475ed4 100644
--- a/dlls/d2d1/d2d1_private.h
+++ b/dlls/d2d1/d2d1_private.h
@@ -117,6 +117,15 @@ struct d2d_ps_cb
     struct d2d_brush_cb opacity_brush;
 };
 
+typedef HRESULT (*outer_target_present_func)(const void *data);
+
+struct outer_target_desc
+{
+    IUnknown *outer_unknown;
+    const void *data;
+    outer_target_present_func present;
+};
+
 struct d2d_device_context
 {
     ID2D1DeviceContext ID2D1DeviceContext_iface;
@@ -124,7 +133,7 @@ struct d2d_device_context
     IDWriteTextRenderer IDWriteTextRenderer_iface;
     LONG refcount;
 
-    IUnknown *outer_unknown;
+    struct outer_target_desc outer_target;
 
     ID2D1Factory *factory;
     ID3D10Device *device;
@@ -148,7 +157,7 @@ struct d2d_device_context
     struct d2d_clip_stack clip_stack;
 };
 
-HRESULT d2d_d3d_create_render_target(ID2D1Factory *factory, IDXGISurface *surface, IUnknown *outer_unknown,
+HRESULT d2d_d3d_create_render_target(ID2D1Factory *factory, IDXGISurface *surface, const struct outer_target_desc *outer,
         const D2D1_RENDER_TARGET_PROPERTIES *desc, ID2D1RenderTarget **render_target) DECLSPEC_HIDDEN;
 HRESULT d2d_d3d_render_target_create_rtv(ID2D1RenderTarget *render_target, IDXGISurface1 *surface) DECLSPEC_HIDDEN;
 
diff --git a/dlls/d2d1/dc_render_target.c b/dlls/d2d1/dc_render_target.c
index d5e4f47e6d..f5276bfbb4 100644
--- a/dlls/d2d1/dc_render_target.c
+++ b/dlls/d2d1/dc_render_target.c
@@ -24,17 +24,20 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(d2d);
 
-static void sync_bitmap(struct d2d_dc_render_target *render_target)
+static HRESULT sync_bitmap(struct d2d_dc_render_target *render_target)
 {
     const RECT *dst_rect = &render_target->dst_rect;
     RECT empty_rect;
     HDC src_hdc;
     HRESULT hr;
 
+    if (!render_target->hdc)
+        return D2DERR_WRONG_STATE;
+
     if (FAILED(hr = IDXGISurface1_GetDC(render_target->dxgi_surface, FALSE, &src_hdc)))
     {
         WARN("GetDC() failed, %#x.\n", hr);
-        return;
+        return S_OK;
     }
 
     BitBlt(render_target->hdc, dst_rect->left, dst_rect->top, dst_rect->right - dst_rect->left,
@@ -42,6 +45,8 @@ static void sync_bitmap(struct d2d_dc_render_target *render_target)
 
     SetRectEmpty(&empty_rect);
     IDXGISurface1_ReleaseDC(render_target->dxgi_surface, &empty_rect);
+
+    return S_OK;
 }
 
 static inline struct d2d_dc_render_target *impl_from_ID2D1DCRenderTarget(ID2D1DCRenderTarget *iface)
@@ -64,7 +69,8 @@ static HRESULT STDMETHODCALLTYPE d2d_dc_render_target_QueryInterface(ID2D1DCRend
         *out = iface;
         return S_OK;
     }
-    else if (IsEqualGUID(iid, &IID_ID2D1GdiInteropRenderTarget))
+    else if (IsEqualGUID(iid, &IID_ID2D1GdiInteropRenderTarget)
+            || IsEqualGUID(iid, &IID_ID2D1DeviceContext))
         return ID2D1RenderTarget_QueryInterface(render_target->dxgi_target, iid, out);
 
     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
@@ -524,14 +530,10 @@ static void STDMETHODCALLTYPE d2d_dc_render_target_PopLayer(ID2D1DCRenderTarget
 static HRESULT STDMETHODCALLTYPE d2d_dc_render_target_Flush(ID2D1DCRenderTarget *iface, D2D1_TAG *tag1, D2D1_TAG *tag2)
 {
     struct d2d_dc_render_target *render_target = impl_from_ID2D1DCRenderTarget(iface);
-    HRESULT hr;
 
     TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2);
 
-    hr = ID2D1RenderTarget_Flush(render_target->dxgi_target, tag1, tag2);
-    sync_bitmap(render_target);
-
-    return hr;
+    return ID2D1RenderTarget_Flush(render_target->dxgi_target, tag1, tag2);
 }
 
 static void STDMETHODCALLTYPE d2d_dc_render_target_SaveDrawingState(ID2D1DCRenderTarget *iface,
@@ -595,17 +597,10 @@ static HRESULT STDMETHODCALLTYPE d2d_dc_render_target_EndDraw(ID2D1DCRenderTarge
         D2D1_TAG *tag1, D2D1_TAG *tag2)
 {
     struct d2d_dc_render_target *render_target = impl_from_ID2D1DCRenderTarget(iface);
-    HRESULT hr;
 
     TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2);
 
-    if (!render_target->hdc)
-        return D2DERR_WRONG_STATE;
-
-    hr = ID2D1RenderTarget_EndDraw(render_target->dxgi_target, tag1, tag2);
-    sync_bitmap(render_target);
-
-    return hr;
+    return ID2D1RenderTarget_EndDraw(render_target->dxgi_target, tag1, tag2);
 }
 
 static D2D1_PIXEL_FORMAT * STDMETHODCALLTYPE d2d_dc_render_target_GetPixelFormat(ID2D1DCRenderTarget *iface,
@@ -816,6 +811,7 @@ static const struct ID2D1DCRenderTargetVtbl d2d_dc_render_target_vtbl =
 HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID2D1Factory *factory,
         ID3D10Device1 *device, const D2D1_RENDER_TARGET_PROPERTIES *desc)
 {
+    struct outer_target_desc outer_desc;
     D3D10_TEXTURE2D_DESC texture_desc;
     ID3D10Texture2D *texture;
     HRESULT hr;
@@ -867,8 +863,12 @@ HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID
         return hr;
     }
 
+    outer_desc.outer_unknown = (IUnknown *)&render_target->ID2D1DCRenderTarget_iface;
+    outer_desc.data = render_target;
+    outer_desc.present = (outer_target_present_func)sync_bitmap;
+
     if (FAILED(hr = d2d_d3d_create_render_target(factory, (IDXGISurface *)render_target->dxgi_surface,
-            (IUnknown *)&render_target->ID2D1DCRenderTarget_iface, desc, &render_target->dxgi_target)))
+            &outer_desc, desc, &render_target->dxgi_target)))
     {
         WARN("Failed to create DXGI surface render target, hr %#x.\n", hr);
         IDXGISurface1_Release(render_target->dxgi_surface);
diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c
index bba4870dd4..3980e35280 100644
--- a/dlls/d2d1/device.c
+++ b/dlls/d2d1/device.c
@@ -1448,8 +1448,13 @@ static void STDMETHODCALLTYPE d2d_device_context_PopLayer(ID2D1DeviceContext *if
 
 static HRESULT STDMETHODCALLTYPE d2d_device_context_Flush(ID2D1DeviceContext *iface, D2D1_TAG *tag1, D2D1_TAG *tag2)
 {
+    struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface);
+
     FIXME("iface %p, tag1 %p, tag2 %p stub!\n", iface, tag1, tag2);
 
+    if (context->outer_target.present)
+        context->outer_target.present(context->outer_target.data);
+
     return E_NOTIMPL;
 }
 
@@ -1615,16 +1620,23 @@ static void STDMETHODCALLTYPE d2d_device_context_BeginDraw(ID2D1DeviceContext *i
 static HRESULT STDMETHODCALLTYPE d2d_device_context_EndDraw(ID2D1DeviceContext *iface,
         D2D1_TAG *tag1, D2D1_TAG *tag2)
 {
-    struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
+    struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface);
+    HRESULT hr;
 
     TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2);
 
     if (tag1)
-        *tag1 = render_target->error.tag1;
+        *tag1 = context->error.tag1;
     if (tag2)
-        *tag2 = render_target->error.tag2;
+        *tag2 = context->error.tag2;
 
-    return render_target->error.code;
+    if (context->outer_target.present)
+    {
+        if (FAILED(hr = context->outer_target.present(context->outer_target.data)))
+            context->error.code = hr;
+    }
+
+    return context->error.code;
 }
 
 static D2D1_PIXEL_FORMAT * STDMETHODCALLTYPE d2d_device_context_GetPixelFormat(ID2D1DeviceContext *iface,
@@ -2381,7 +2393,7 @@ static HRESULT STDMETHODCALLTYPE d2d_gdi_interop_render_target_QueryInterface(ID
 
     TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
 
-    return IUnknown_QueryInterface(render_target->outer_unknown, iid, out);
+    return IUnknown_QueryInterface(render_target->outer_target.outer_unknown, iid, out);
 }
 
 static ULONG STDMETHODCALLTYPE d2d_gdi_interop_render_target_AddRef(ID2D1GdiInteropRenderTarget *iface)
@@ -2390,7 +2402,7 @@ static ULONG STDMETHODCALLTYPE d2d_gdi_interop_render_target_AddRef(ID2D1GdiInte
 
     TRACE("iface %p.\n", iface);
 
-    return IUnknown_AddRef(render_target->outer_unknown);
+    return IUnknown_AddRef(render_target->outer_target.outer_unknown);
 }
 
 static ULONG STDMETHODCALLTYPE d2d_gdi_interop_render_target_Release(ID2D1GdiInteropRenderTarget *iface)
@@ -2399,7 +2411,7 @@ static ULONG STDMETHODCALLTYPE d2d_gdi_interop_render_target_Release(ID2D1GdiInt
 
     TRACE("iface %p.\n", iface);
 
-    return IUnknown_Release(render_target->outer_unknown);
+    return IUnknown_Release(render_target->outer_target.outer_unknown);
 }
 
 static HRESULT d2d_device_context_get_surface(struct d2d_device_context *render_target, IDXGISurface1 **surface)
@@ -2469,7 +2481,7 @@ static const struct ID2D1GdiInteropRenderTargetVtbl d2d_gdi_interop_render_targe
 };
 
 static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, ID2D1Factory *factory,
-        IDXGISurface *surface, IUnknown *outer_unknown, const D2D1_RENDER_TARGET_PROPERTIES *desc)
+        IDXGISurface *surface, const struct outer_target_desc *outer, const D2D1_RENDER_TARGET_PROPERTIES *desc)
 {
     D3D10_SUBRESOURCE_DATA buffer_data;
     D3D10_STATE_BLOCK_MASK state_mask;
@@ -3355,8 +3367,10 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target,
     render_target->factory = factory;
     ID2D1Factory_AddRef(render_target->factory);
 
-    render_target->outer_unknown = outer_unknown ? outer_unknown :
-            (IUnknown *)&render_target->ID2D1DeviceContext_iface;
+    if (outer)
+        render_target->outer_target = *outer;
+    else
+        render_target->outer_target.outer_unknown = (IUnknown *)&render_target->ID2D1DeviceContext_iface;
 
     if (FAILED(hr = IDXGISurface_GetDevice(surface, &IID_ID3D10Device, (void **)&render_target->device)))
     {
@@ -3554,7 +3568,7 @@ err:
     return hr;
 }
 
-HRESULT d2d_d3d_create_render_target(ID2D1Factory *factory, IDXGISurface *surface, IUnknown *outer_unknown,
+HRESULT d2d_d3d_create_render_target(ID2D1Factory *factory, IDXGISurface *surface, const struct outer_target_desc *outer,
         const D2D1_RENDER_TARGET_PROPERTIES *desc, ID2D1RenderTarget **render_target)
 {
     struct d2d_device_context *object;
@@ -3563,7 +3577,7 @@ HRESULT d2d_d3d_create_render_target(ID2D1Factory *factory, IDXGISurface *surfac
     if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
-    if (FAILED(hr = d2d_device_context_init(object, factory, surface, outer_unknown, desc)))
+    if (FAILED(hr = d2d_device_context_init(object, factory, surface, outer, desc)))
     {
         WARN("Failed to initialize render target, hr %#x.\n", hr);
         heap_free(object);
diff --git a/dlls/d2d1/hwnd_render_target.c b/dlls/d2d1/hwnd_render_target.c
index 04d33536a6..112e6a98a2 100644
--- a/dlls/d2d1/hwnd_render_target.c
+++ b/dlls/d2d1/hwnd_render_target.c
@@ -24,12 +24,14 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(d2d);
 
-static void render_target_present(struct d2d_hwnd_render_target *render_target)
+static HRESULT render_target_present(struct d2d_hwnd_render_target *render_target)
 {
     HRESULT hr;
 
     if (FAILED(hr = IDXGISwapChain_Present(render_target->swapchain, render_target->sync_interval, 0)))
         WARN("Present failed, %#x.\n", hr);
+
+    return S_OK;
 }
 
 static inline struct d2d_hwnd_render_target *impl_from_ID2D1HwndRenderTarget(ID2D1HwndRenderTarget *iface)
@@ -53,7 +55,8 @@ static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_QueryInterface(ID2D1Hwnd
         *out = iface;
         return S_OK;
     }
-    else if (IsEqualGUID(iid, &IID_ID2D1GdiInteropRenderTarget))
+    else if (IsEqualGUID(iid, &IID_ID2D1GdiInteropRenderTarget)
+            || IsEqualGUID(iid, &IID_ID2D1DeviceContext))
         return ID2D1RenderTarget_QueryInterface(render_target->dxgi_target, iid, out);
 
     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
@@ -516,14 +519,10 @@ static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_Flush(ID2D1HwndRenderTar
         D2D1_TAG *tag2)
 {
     struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface);
-    HRESULT hr;
 
     TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2);
 
-    hr = ID2D1RenderTarget_Flush(render_target->dxgi_target, tag1, tag2);
-    render_target_present(render_target);
-
-    return hr;
+    return ID2D1RenderTarget_Flush(render_target->dxgi_target, tag1, tag2);
 }
 
 static void STDMETHODCALLTYPE d2d_hwnd_render_target_SaveDrawingState(ID2D1HwndRenderTarget *iface,
@@ -782,6 +781,7 @@ HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target
 {
     D2D1_RENDER_TARGET_PROPERTIES dxgi_rt_desc;
     DXGI_SWAP_CHAIN_DESC swapchain_desc;
+    struct outer_target_desc outer_desc;
     IDXGIAdapter *dxgi_adapter;
     IDXGIFactory *dxgi_factory;
     IDXGISurface *dxgi_surface;
@@ -860,9 +860,12 @@ HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target
         return hr;
     }
 
+    outer_desc.outer_unknown = (IUnknown *)&render_target->ID2D1HwndRenderTarget_iface;
+    outer_desc.data = render_target;
+    outer_desc.present = (outer_target_present_func)render_target_present;
+
     render_target->ID2D1HwndRenderTarget_iface.lpVtbl = &d2d_hwnd_render_target_vtbl;
-    hr = d2d_d3d_create_render_target(factory, dxgi_surface, (IUnknown *)&render_target->ID2D1HwndRenderTarget_iface,
-            &dxgi_rt_desc, &render_target->dxgi_target);
+    hr = d2d_d3d_create_render_target(factory, dxgi_surface, &outer_desc, &dxgi_rt_desc, &render_target->dxgi_target);
     IDXGISurface_Release(dxgi_surface);
     if (FAILED(hr))
     {
diff --git a/dlls/d2d1/wic_render_target.c b/dlls/d2d1/wic_render_target.c
index 5642fd44ff..ede9d811d7 100644
--- a/dlls/d2d1/wic_render_target.c
+++ b/dlls/d2d1/wic_render_target.c
@@ -25,7 +25,7 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(d2d);
 
-static void sync_bitmap(struct d2d_wic_render_target *render_target)
+static HRESULT sync_bitmap(struct d2d_wic_render_target *render_target)
 {
     D3D10_MAPPED_TEXTURE2D mapped_texture;
     ID3D10Resource *src_resource;
@@ -41,7 +41,7 @@ static void sync_bitmap(struct d2d_wic_render_target *render_target)
             &IID_ID3D10Resource, (void **)&src_resource)))
     {
         ERR("Failed to get source resource interface, hr %#x.\n", hr);
-        return;
+        goto end;
     }
 
     ID3D10Texture2D_GetDevice(render_target->readback_texture, &device);
@@ -56,28 +56,28 @@ static void sync_bitmap(struct d2d_wic_render_target *render_target)
     if (FAILED(hr = IWICBitmap_Lock(render_target->bitmap, &dst_rect, WICBitmapLockWrite, &bitmap_lock)))
     {
         ERR("Failed to lock destination bitmap, hr %#x.\n", hr);
-        return;
+        goto end;
     }
 
     if (FAILED(hr = IWICBitmapLock_GetDataPointer(bitmap_lock, &dst_size, &dst)))
     {
         ERR("Failed to get data pointer, hr %#x.\n", hr);
         IWICBitmapLock_Release(bitmap_lock);
-        return;
+        goto end;
     }
 
     if (FAILED(hr = IWICBitmapLock_GetStride(bitmap_lock, &dst_pitch)))
     {
         ERR("Failed to get stride, hr %#x.\n", hr);
         IWICBitmapLock_Release(bitmap_lock);
-        return;
+        goto end;
     }
 
     if (FAILED(hr = ID3D10Texture2D_Map(render_target->readback_texture, 0, D3D10_MAP_READ, 0, &mapped_texture)))
     {
         ERR("Failed to map readback texture, hr %#x.\n", hr);
         IWICBitmapLock_Release(bitmap_lock);
-        return;
+        goto end;
     }
 
     src = mapped_texture.pData;
@@ -91,6 +91,9 @@ static void sync_bitmap(struct d2d_wic_render_target *render_target)
 
     ID3D10Texture2D_Unmap(render_target->readback_texture, 0);
     IWICBitmapLock_Release(bitmap_lock);
+
+end:
+    return S_OK;
 }
 
 static inline struct d2d_wic_render_target *impl_from_ID2D1RenderTarget(ID2D1RenderTarget *iface)
@@ -112,7 +115,8 @@ static HRESULT STDMETHODCALLTYPE d2d_wic_render_target_QueryInterface(ID2D1Rende
         *out = iface;
         return S_OK;
     }
-    else if (IsEqualGUID(iid, &IID_ID2D1GdiInteropRenderTarget))
+    else if (IsEqualGUID(iid, &IID_ID2D1GdiInteropRenderTarget)
+            || IsEqualGUID(iid, &IID_ID2D1DeviceContext))
         return ID2D1RenderTarget_QueryInterface(render_target->dxgi_target, iid, out);
 
     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
@@ -574,14 +578,10 @@ static void STDMETHODCALLTYPE d2d_wic_render_target_PopLayer(ID2D1RenderTarget *
 static HRESULT STDMETHODCALLTYPE d2d_wic_render_target_Flush(ID2D1RenderTarget *iface, D2D1_TAG *tag1, D2D1_TAG *tag2)
 {
     struct d2d_wic_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
-    HRESULT hr;
 
     TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2);
 
-    hr = ID2D1RenderTarget_Flush(render_target->dxgi_target, tag1, tag2);
-    sync_bitmap(render_target);
-
-    return hr;
+    return ID2D1RenderTarget_Flush(render_target->dxgi_target, tag1, tag2);
 }
 
 static void STDMETHODCALLTYPE d2d_wic_render_target_SaveDrawingState(ID2D1RenderTarget *iface,
@@ -645,14 +645,10 @@ static HRESULT STDMETHODCALLTYPE d2d_wic_render_target_EndDraw(ID2D1RenderTarget
         D2D1_TAG *tag1, D2D1_TAG *tag2)
 {
     struct d2d_wic_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
-    HRESULT hr;
 
     TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2);
 
-    hr = ID2D1RenderTarget_EndDraw(render_target->dxgi_target, tag1, tag2);
-    sync_bitmap(render_target);
-
-    return hr;
+    return ID2D1RenderTarget_EndDraw(render_target->dxgi_target, tag1, tag2);
 }
 
 static D2D1_PIXEL_FORMAT * STDMETHODCALLTYPE d2d_wic_render_target_GetPixelFormat(ID2D1RenderTarget *iface,
@@ -788,6 +784,7 @@ static const struct ID2D1RenderTargetVtbl d2d_wic_render_target_vtbl =
 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)
 {
+    struct outer_target_desc outer_desc;
     D3D10_TEXTURE2D_DESC texture_desc;
     ID3D10Texture2D *texture;
     HRESULT hr;
@@ -874,8 +871,12 @@ HRESULT d2d_wic_render_target_init(struct d2d_wic_render_target *render_target,
         return hr;
     }
 
+    outer_desc.outer_unknown = (IUnknown *)&render_target->ID2D1RenderTarget_iface;
+    outer_desc.data = render_target;
+    outer_desc.present = (outer_target_present_func)sync_bitmap;
+
     if (FAILED(hr = d2d_d3d_create_render_target(factory, render_target->dxgi_surface,
-            (IUnknown *)&render_target->ID2D1RenderTarget_iface, desc, &render_target->dxgi_target)))
+            &outer_desc, desc, &render_target->dxgi_target)))
     {
         WARN("Failed to create DXGI surface render target, hr %#x.\n", hr);
         ID3D10Texture2D_Release(render_target->readback_texture);
-- 
2.18.0




More information about the wine-devel mailing list