[PATCH 2/2] d2d1: Added support for ID2D1GdiInteropRenderTarget interface
Nikolay Sivov
nsivov at codeweavers.com
Fri Feb 10 06:00:19 CST 2017
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/d2d1/bitmap_render_target.c | 4 ++
dlls/d2d1/d2d1_private.h | 1 +
dlls/d2d1/dc_render_target.c | 4 ++
dlls/d2d1/hwnd_render_target.c | 4 ++
dlls/d2d1/render_target.c | 105 +++++++++++++++++++++++++++++++++++++++
dlls/d2d1/tests/d2d1.c | 25 ++++++++++
dlls/d2d1/wic_render_target.c | 4 ++
7 files changed, 147 insertions(+)
diff --git a/dlls/d2d1/bitmap_render_target.c b/dlls/d2d1/bitmap_render_target.c
index 67b0713376..3ac5c77d36 100644
--- a/dlls/d2d1/bitmap_render_target.c
+++ b/dlls/d2d1/bitmap_render_target.c
@@ -32,6 +32,8 @@ static inline struct d2d_bitmap_render_target *impl_from_ID2D1BitmapRenderTarget
static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_QueryInterface(ID2D1BitmapRenderTarget *iface,
REFIID iid, void **out)
{
+ struct d2d_bitmap_render_target *render_target = impl_from_ID2D1BitmapRenderTarget(iface);
+
TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
if (IsEqualGUID(iid, &IID_ID2D1BitmapRenderTarget)
@@ -43,6 +45,8 @@ static HRESULT STDMETHODCALLTYPE d2d_bitmap_render_target_QueryInterface(ID2D1Bi
*out = iface;
return S_OK;
}
+ else if (IsEqualGUID(iid, &IID_ID2D1GdiInteropRenderTarget))
+ return ID2D1RenderTarget_QueryInterface(render_target->dxgi_target, iid, out);
WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h
index 336be96a07..e80b1b9384 100644
--- a/dlls/d2d1/d2d1_private.h
+++ b/dlls/d2d1/d2d1_private.h
@@ -69,6 +69,7 @@ struct d2d_shape_resources
struct d2d_d3d_render_target
{
ID2D1RenderTarget ID2D1RenderTarget_iface;
+ ID2D1GdiInteropRenderTarget ID2D1GdiInteropRenderTarget_iface;
IDWriteTextRenderer IDWriteTextRenderer_iface;
LONG refcount;
diff --git a/dlls/d2d1/dc_render_target.c b/dlls/d2d1/dc_render_target.c
index 1cf2c8d381..04b8e71dc5 100644
--- a/dlls/d2d1/dc_render_target.c
+++ b/dlls/d2d1/dc_render_target.c
@@ -51,6 +51,8 @@ static inline struct d2d_dc_render_target *impl_from_ID2D1DCRenderTarget(ID2D1DC
static HRESULT STDMETHODCALLTYPE d2d_dc_render_target_QueryInterface(ID2D1DCRenderTarget *iface, REFIID iid, void **out)
{
+ struct d2d_dc_render_target *render_target = impl_from_ID2D1DCRenderTarget(iface);
+
TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
if (IsEqualGUID(iid, &IID_ID2D1DCRenderTarget)
@@ -62,6 +64,8 @@ static HRESULT STDMETHODCALLTYPE d2d_dc_render_target_QueryInterface(ID2D1DCRend
*out = iface;
return S_OK;
}
+ else if (IsEqualGUID(iid, &IID_ID2D1GdiInteropRenderTarget))
+ return ID2D1RenderTarget_QueryInterface(render_target->dxgi_target, iid, out);
WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
diff --git a/dlls/d2d1/hwnd_render_target.c b/dlls/d2d1/hwnd_render_target.c
index 2ce7b713b5..027189693d 100644
--- a/dlls/d2d1/hwnd_render_target.c
+++ b/dlls/d2d1/hwnd_render_target.c
@@ -40,6 +40,8 @@ static inline struct d2d_hwnd_render_target *impl_from_ID2D1HwndRenderTarget(ID2
static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_QueryInterface(ID2D1HwndRenderTarget *iface,
REFIID iid, void **out)
{
+ struct d2d_hwnd_render_target *render_target = impl_from_ID2D1HwndRenderTarget(iface);
+
TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
if (IsEqualGUID(iid, &IID_ID2D1HwndRenderTarget)
@@ -51,6 +53,8 @@ static HRESULT STDMETHODCALLTYPE d2d_hwnd_render_target_QueryInterface(ID2D1Hwnd
*out = iface;
return S_OK;
}
+ else if (IsEqualGUID(iid, &IID_ID2D1GdiInteropRenderTarget))
+ return ID2D1RenderTarget_QueryInterface(render_target->dxgi_target, iid, out);
WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c
index 0f372643af..93d8183473 100644
--- a/dlls/d2d1/render_target.c
+++ b/dlls/d2d1/render_target.c
@@ -207,6 +207,8 @@ static inline struct d2d_d3d_render_target *impl_from_ID2D1RenderTarget(ID2D1Ren
static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_QueryInterface(ID2D1RenderTarget *iface, REFIID iid, void **out)
{
+ struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
+
TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
if (IsEqualGUID(iid, &IID_ID2D1RenderTarget)
@@ -217,6 +219,12 @@ static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_QueryInterface(ID2D1Rende
*out = iface;
return S_OK;
}
+ else if (IsEqualGUID(iid, &IID_ID2D1GdiInteropRenderTarget))
+ {
+ ID2D1GdiInteropRenderTarget_AddRef(&render_target->ID2D1GdiInteropRenderTarget_iface);
+ *out = &render_target->ID2D1GdiInteropRenderTarget_iface;
+ return S_OK;
+ }
WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
@@ -1866,6 +1874,102 @@ static const struct IDWriteTextRendererVtbl d2d_text_renderer_vtbl =
d2d_text_renderer_DrawInlineObject,
};
+static inline struct d2d_d3d_render_target *impl_from_ID2D1GdiInteropRenderTarget(ID2D1GdiInteropRenderTarget *iface)
+{
+ return CONTAINING_RECORD(iface, struct d2d_d3d_render_target, ID2D1GdiInteropRenderTarget_iface);
+}
+
+static HRESULT STDMETHODCALLTYPE d2d_gdi_interop_render_target_QueryInterface(ID2D1GdiInteropRenderTarget *iface,
+ REFIID iid, void **out)
+{
+ struct d2d_d3d_render_target *render_target = impl_from_ID2D1GdiInteropRenderTarget(iface);
+
+ TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
+
+ return d2d_d3d_render_target_QueryInterface(&render_target->ID2D1RenderTarget_iface, iid, out);
+}
+
+static ULONG STDMETHODCALLTYPE d2d_gdi_interop_render_target_AddRef(ID2D1GdiInteropRenderTarget *iface)
+{
+ struct d2d_d3d_render_target *render_target = impl_from_ID2D1GdiInteropRenderTarget(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ return d2d_d3d_render_target_AddRef(&render_target->ID2D1RenderTarget_iface);
+}
+
+static ULONG STDMETHODCALLTYPE d2d_gdi_interop_render_target_Release(ID2D1GdiInteropRenderTarget *iface)
+{
+ struct d2d_d3d_render_target *render_target = impl_from_ID2D1GdiInteropRenderTarget(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ return d2d_d3d_render_target_Release(&render_target->ID2D1RenderTarget_iface);
+}
+
+static HRESULT d2d_d3d_render_target_get_surface(struct d2d_d3d_render_target *render_target, IDXGISurface1 **surface)
+{
+ ID3D10Resource *resource;
+ HRESULT hr;
+
+ ID3D10RenderTargetView_GetResource(render_target->view, &resource);
+ hr = ID3D10Resource_QueryInterface(resource, &IID_IDXGISurface1, (void **)surface);
+ ID3D10Resource_Release(resource);
+ if (FAILED(hr))
+ {
+ *surface = NULL;
+ WARN("Failed to get DXGI surface, %#x.\n", hr);
+ return hr;
+ }
+
+ return hr;
+}
+
+static HRESULT STDMETHODCALLTYPE d2d_gdi_interop_render_target_GetDC(ID2D1GdiInteropRenderTarget *iface,
+ D2D1_DC_INITIALIZE_MODE mode, HDC *dc)
+{
+ struct d2d_d3d_render_target *render_target = impl_from_ID2D1GdiInteropRenderTarget(iface);
+ IDXGISurface1 *surface;
+ HRESULT hr;
+
+ TRACE("iface %p, mode %d, dc %p.\n", iface, mode, dc);
+
+ if (FAILED(hr = d2d_d3d_render_target_get_surface(render_target, &surface)))
+ return hr;
+
+ hr = IDXGISurface1_GetDC(surface, mode != D2D1_DC_INITIALIZE_MODE_COPY, dc);
+ IDXGISurface1_Release(surface);
+
+ return hr;
+}
+
+static HRESULT STDMETHODCALLTYPE d2d_gdi_interop_render_target_ReleaseDC(ID2D1GdiInteropRenderTarget *iface,
+ const RECT *update)
+{
+ struct d2d_d3d_render_target *render_target = impl_from_ID2D1GdiInteropRenderTarget(iface);
+ IDXGISurface1 *surface;
+ HRESULT hr;
+
+ TRACE("iface %p, update rect %s.\n", iface, wine_dbgstr_rect(update));
+
+ if (FAILED(hr = d2d_d3d_render_target_get_surface(render_target, &surface)))
+ return hr;
+
+ hr = IDXGISurface1_ReleaseDC(surface, update);
+ IDXGISurface1_Release(surface);
+
+ return hr;
+}
+
+static const struct ID2D1GdiInteropRenderTargetVtbl d2d_gdi_interop_render_target_vtbl =
+{
+ d2d_gdi_interop_render_target_QueryInterface,
+ d2d_gdi_interop_render_target_AddRef,
+ d2d_gdi_interop_render_target_Release,
+ d2d_gdi_interop_render_target_GetDC,
+ d2d_gdi_interop_render_target_ReleaseDC,
+};
+
HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target, ID2D1Factory *factory,
IDXGISurface *surface, const D2D1_RENDER_TARGET_PROPERTIES *desc)
{
@@ -2314,6 +2418,7 @@ HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target,
WARN("Ignoring feature level %#x.\n", desc->minLevel);
render_target->ID2D1RenderTarget_iface.lpVtbl = &d2d_d3d_render_target_vtbl;
+ render_target->ID2D1GdiInteropRenderTarget_iface.lpVtbl = &d2d_gdi_interop_render_target_vtbl;
render_target->IDWriteTextRenderer_iface.lpVtbl = &d2d_text_renderer_vtbl;
render_target->refcount = 1;
render_target->factory = factory;
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c
index 7dccbd7d97..194001d2fa 100644
--- a/dlls/d2d1/tests/d2d1.c
+++ b/dlls/d2d1/tests/d2d1.c
@@ -2248,6 +2248,7 @@ static void test_shared_bitmap(void)
{
IDXGISwapChain *swapchain1, *swapchain2;
IWICBitmap *wic_bitmap1, *wic_bitmap2;
+ ID2D1GdiInteropRenderTarget *interop;
D2D1_RENDER_TARGET_PROPERTIES desc;
D2D1_BITMAP_PROPERTIES bitmap_desc;
IDXGISurface *surface1, *surface2;
@@ -2366,6 +2367,10 @@ static void test_shared_bitmap(void)
hr = ID2D1RenderTarget_CreateBitmap(rt1, size, NULL, 0, &bitmap_desc, &bitmap1);
ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
+ hr = ID2D1RenderTarget_QueryInterface(rt1, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
+ ok(SUCCEEDED(hr), "Failed to get interop target, hr %#x.\n", hr);
+ ID2D1GdiInteropRenderTarget_Release(interop);
+
hr = ID2D1Factory_CreateWicBitmapRenderTarget(factory2, wic_bitmap2, &desc, &rt2);
ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_ID2D1Bitmap, bitmap1, NULL, &bitmap2);
@@ -2764,6 +2769,7 @@ static void test_create_target(void)
for (i = 0; i < sizeof(create_dpi_tests) / sizeof(*create_dpi_tests); ++i)
{
+ ID2D1GdiInteropRenderTarget *interop;
D2D1_RENDER_TARGET_PROPERTIES desc;
float dpi_x, dpi_y;
@@ -2782,6 +2788,10 @@ static void test_create_target(void)
if (FAILED(hr))
continue;
+ hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
+ ok(SUCCEEDED(hr), "Failed to get interop target, hr %#x.\n", hr);
+ ID2D1GdiInteropRenderTarget_Release(interop);
+
ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
ok(dpi_x == create_dpi_tests[i].rt_dpi_x, "Wrong dpi_x %.8e, expected %.8e, test %u\n",
dpi_x, create_dpi_tests[i].rt_dpi_x, i);
@@ -2946,6 +2956,7 @@ static void test_dc_target(void)
{ DXGI_FORMAT_R8G8B8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED },
};
D2D1_TEXT_ANTIALIAS_MODE text_aa_mode;
+ ID2D1GdiInteropRenderTarget *interop;
D2D1_RENDER_TARGET_PROPERTIES desc;
D2D1_MATRIX_3X2_F matrix, matrix2;
D2D1_ANTIALIAS_MODE aa_mode;
@@ -2998,6 +3009,10 @@ static void test_dc_target(void)
hr = ID2D1Factory_CreateDCRenderTarget(factory, &desc, &rt);
ok(SUCCEEDED(hr), "Failed to create target, hr %#x.\n", hr);
+ hr = ID2D1DCRenderTarget_QueryInterface(rt, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
+ ok(SUCCEEDED(hr), "Failed to get interop target, hr %#x.\n", hr);
+ ID2D1GdiInteropRenderTarget_Release(interop);
+
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);
@@ -3125,6 +3140,7 @@ static void test_dc_target(void)
static void test_hwnd_target(void)
{
D2D1_HWND_RENDER_TARGET_PROPERTIES hwnd_rt_desc;
+ ID2D1GdiInteropRenderTarget *interop;
D2D1_RENDER_TARGET_PROPERTIES desc;
ID2D1HwndRenderTarget *rt;
ID2D1Factory *factory;
@@ -3167,6 +3183,10 @@ static void test_hwnd_target(void)
hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt);
ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
+ hr = ID2D1HwndRenderTarget_QueryInterface(rt, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
+ ok(SUCCEEDED(hr), "Failed to get interop target, hr %#x.\n", hr);
+ ID2D1GdiInteropRenderTarget_Release(interop);
+
size.width = 128;
size.height = 64;
hr = ID2D1HwndRenderTarget_Resize(rt, &size);
@@ -3181,6 +3201,7 @@ static void test_hwnd_target(void)
static void test_bitmap_target(void)
{
D2D1_HWND_RENDER_TARGET_PROPERTIES hwnd_rt_desc;
+ ID2D1GdiInteropRenderTarget *interop;
D2D1_SIZE_U pixel_size, pixel_size2;
D2D1_RENDER_TARGET_PROPERTIES desc;
ID2D1HwndRenderTarget *hwnd_rt;
@@ -3226,6 +3247,10 @@ static void test_bitmap_target(void)
D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt);
ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
+ hr = ID2D1BitmapRenderTarget_QueryInterface(rt, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
+ ok(SUCCEEDED(hr), "Failed to get interop target, hr %#x.\n", hr);
+ ID2D1GdiInteropRenderTarget_Release(interop);
+
/* See if parent target is referenced. */
ID2D1HwndRenderTarget_AddRef(hwnd_rt);
refcount = ID2D1HwndRenderTarget_Release(hwnd_rt);
diff --git a/dlls/d2d1/wic_render_target.c b/dlls/d2d1/wic_render_target.c
index 07a19ee3b8..278958b2cc 100644
--- a/dlls/d2d1/wic_render_target.c
+++ b/dlls/d2d1/wic_render_target.c
@@ -100,6 +100,8 @@ static inline struct d2d_wic_render_target *impl_from_ID2D1RenderTarget(ID2D1Ren
static HRESULT STDMETHODCALLTYPE d2d_wic_render_target_QueryInterface(ID2D1RenderTarget *iface, REFIID iid, void **out)
{
+ struct d2d_wic_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
+
TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
if (IsEqualGUID(iid, &IID_ID2D1RenderTarget)
@@ -110,6 +112,8 @@ static HRESULT STDMETHODCALLTYPE d2d_wic_render_target_QueryInterface(ID2D1Rende
*out = iface;
return S_OK;
}
+ else if (IsEqualGUID(iid, &IID_ID2D1GdiInteropRenderTarget))
+ return ID2D1RenderTarget_QueryInterface(render_target->dxgi_target, iid, out);
WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
--
2.11.0
More information about the wine-patches
mailing list