mirror of
https://github.com/reactos/wine.git
synced 2025-02-26 07:45:37 +00:00
d2d1: Added support for ID2D1GdiInteropRenderTarget interface.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
826b1e9c78
commit
74ed5c7067
@ -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));
|
||||
|
||||
@ -806,8 +810,8 @@ HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_ta
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (FAILED(hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(parent_target->factory, dxgi_surface, &dxgi_rt_desc,
|
||||
&render_target->dxgi_target)))
|
||||
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)))
|
||||
{
|
||||
WARN("Failed to create DXGI surface render target, hr %#x.\n", hr);
|
||||
IDXGISurface_Release(dxgi_surface);
|
||||
|
@ -69,9 +69,12 @@ struct d2d_shape_resources
|
||||
struct d2d_d3d_render_target
|
||||
{
|
||||
ID2D1RenderTarget ID2D1RenderTarget_iface;
|
||||
ID2D1GdiInteropRenderTarget ID2D1GdiInteropRenderTarget_iface;
|
||||
IDWriteTextRenderer IDWriteTextRenderer_iface;
|
||||
LONG refcount;
|
||||
|
||||
IUnknown *outer_unknown;
|
||||
|
||||
ID2D1Factory *factory;
|
||||
ID3D10Device *device;
|
||||
ID3D10RenderTargetView *view;
|
||||
@ -93,8 +96,8 @@ struct d2d_d3d_render_target
|
||||
struct d2d_clip_stack clip_stack;
|
||||
};
|
||||
|
||||
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_create_render_target(ID2D1Factory *factory, IDXGISurface *surface, IUnknown *outer_unknown,
|
||||
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;
|
||||
|
||||
struct d2d_wic_render_target
|
||||
|
@ -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));
|
||||
|
||||
@ -863,8 +867,8 @@ HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (FAILED(hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory,
|
||||
(IDXGISurface *)render_target->dxgi_surface, desc, &render_target->dxgi_target)))
|
||||
if (FAILED(hr = d2d_d3d_create_render_target(factory, (IDXGISurface *)render_target->dxgi_surface,
|
||||
(IUnknown *)&render_target->ID2D1DCRenderTarget_iface, desc, &render_target->dxgi_target)))
|
||||
{
|
||||
WARN("Failed to create DXGI surface render target, hr %#x.\n", hr);
|
||||
IDXGISurface1_Release(render_target->dxgi_surface);
|
||||
|
@ -331,25 +331,9 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateHwndRenderTarget(ID2D1Factory
|
||||
static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDxgiSurfaceRenderTarget(ID2D1Factory *iface,
|
||||
IDXGISurface *surface, const D2D1_RENDER_TARGET_PROPERTIES *desc, ID2D1RenderTarget **render_target)
|
||||
{
|
||||
struct d2d_d3d_render_target *object;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("iface %p, surface %p, desc %p, render_target %p.\n", iface, surface, desc, render_target);
|
||||
|
||||
if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if (FAILED(hr = d2d_d3d_render_target_init(object, iface, surface, 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->ID2D1RenderTarget_iface;
|
||||
|
||||
return S_OK;
|
||||
return d2d_d3d_create_render_target(iface, surface, NULL, desc, render_target);
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDCRenderTarget(ID2D1Factory *iface,
|
||||
|
@ -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));
|
||||
|
||||
@ -856,7 +860,9 @@ HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory, dxgi_surface, &dxgi_rt_desc, &render_target->dxgi_target);
|
||||
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);
|
||||
IDXGISurface_Release(dxgi_surface);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
|
@ -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,8 +1874,107 @@ static const struct IDWriteTextRendererVtbl d2d_text_renderer_vtbl =
|
||||
d2d_text_renderer_DrawInlineObject,
|
||||
};
|
||||
|
||||
HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target, ID2D1Factory *factory,
|
||||
IDXGISurface *surface, const D2D1_RENDER_TARGET_PROPERTIES *desc)
|
||||
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 IUnknown_QueryInterface(render_target->outer_unknown, 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 IUnknown_AddRef(render_target->outer_unknown);
|
||||
}
|
||||
|
||||
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 IUnknown_Release(render_target->outer_unknown);
|
||||
}
|
||||
|
||||
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;
|
||||
RECT update_rect;
|
||||
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;
|
||||
|
||||
if (update)
|
||||
update_rect = *update;
|
||||
hr = IDXGISurface1_ReleaseDC(surface, update ? &update_rect : NULL);
|
||||
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,
|
||||
};
|
||||
|
||||
static HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target, ID2D1Factory *factory,
|
||||
IDXGISurface *surface, IUnknown *outer_unknown, const D2D1_RENDER_TARGET_PROPERTIES *desc)
|
||||
{
|
||||
D3D10_SUBRESOURCE_DATA buffer_data;
|
||||
D3D10_STATE_BLOCK_MASK state_mask;
|
||||
@ -2308,11 +2415,15 @@ 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;
|
||||
ID2D1Factory_AddRef(render_target->factory);
|
||||
|
||||
render_target->outer_unknown = outer_unknown ? outer_unknown :
|
||||
(IUnknown *)&render_target->ID2D1RenderTarget_iface;
|
||||
|
||||
if (FAILED(hr = IDXGISurface_GetDevice(surface, &IID_ID3D10Device, (void **)&render_target->device)))
|
||||
{
|
||||
WARN("Failed to get device interface, hr %#x.\n", hr);
|
||||
@ -2557,6 +2668,28 @@ err:
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT d2d_d3d_create_render_target(ID2D1Factory *factory, IDXGISurface *surface, IUnknown *outer_unknown,
|
||||
const D2D1_RENDER_TARGET_PROPERTIES *desc, ID2D1RenderTarget **render_target)
|
||||
{
|
||||
struct d2d_d3d_render_target *object;
|
||||
HRESULT hr;
|
||||
|
||||
if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if (FAILED(hr = d2d_d3d_render_target_init(object, factory, surface, outer_unknown, 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->ID2D1RenderTarget_iface;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT d2d_d3d_render_target_create_rtv(ID2D1RenderTarget *iface, IDXGISurface1 *surface)
|
||||
{
|
||||
struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
|
||||
|
@ -250,6 +250,33 @@ static BOOL compare_surface(IDXGISurface *surface, const char *ref_sha1)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL compare_wic_bitmap(IWICBitmap *bitmap, const char *ref_sha1)
|
||||
{
|
||||
UINT stride, width, height, buffer_size;
|
||||
IWICBitmapLock *lock;
|
||||
BYTE *data;
|
||||
HRESULT hr;
|
||||
BOOL ret;
|
||||
|
||||
hr = IWICBitmap_Lock(bitmap, NULL, WICBitmapLockRead, &lock);
|
||||
ok(SUCCEEDED(hr), "Failed to lock bitmap, hr %#x.\n", hr);
|
||||
|
||||
hr = IWICBitmapLock_GetDataPointer(lock, &buffer_size, &data);
|
||||
ok(SUCCEEDED(hr), "Failed to get bitmap data, hr %#x.\n", hr);
|
||||
|
||||
hr = IWICBitmapLock_GetStride(lock, &stride);
|
||||
ok(SUCCEEDED(hr), "Failed to get bitmap stride, hr %#x.\n", hr);
|
||||
|
||||
hr = IWICBitmapLock_GetSize(lock, &width, &height);
|
||||
ok(SUCCEEDED(hr), "Failed to get bitmap size, hr %#x.\n", hr);
|
||||
|
||||
ret = compare_sha1(data, stride, 4, width, height, ref_sha1);
|
||||
|
||||
IWICBitmapLock_Release(lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void serialize_figure(struct figure *figure)
|
||||
{
|
||||
static const char lookup[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
@ -2248,15 +2275,16 @@ 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;
|
||||
ID2D1RenderTarget *rt1, *rt2, *rt3;
|
||||
IDXGISurface *surface1, *surface2;
|
||||
ID2D1Factory *factory1, *factory2;
|
||||
ID3D10Device1 *device1, *device2;
|
||||
IWICImagingFactory *wic_factory;
|
||||
ID2D1Bitmap *bitmap1, *bitmap2;
|
||||
DXGI_SURFACE_DESC surface_desc;
|
||||
ID2D1RenderTarget *rt1, *rt2;
|
||||
D2D1_SIZE_U size = {4, 4};
|
||||
IDXGISurface1 *surface3;
|
||||
HWND window1, window2;
|
||||
@ -2366,6 +2394,14 @@ 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);
|
||||
hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1RenderTarget, (void **)&rt3);
|
||||
ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
|
||||
ok(rt3 == rt1, "Unexpected render target\n");
|
||||
ID2D1RenderTarget_Release(rt3);
|
||||
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,8 +2800,11 @@ 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;
|
||||
ID2D1RenderTarget *rt2;
|
||||
float dpi_x, dpi_y;
|
||||
IUnknown *unk;
|
||||
|
||||
desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
|
||||
desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
|
||||
@ -2782,6 +2821,19 @@ static void test_create_target(void)
|
||||
if (FAILED(hr))
|
||||
continue;
|
||||
|
||||
hr = ID2D1RenderTarget_QueryInterface(rt, &IID_IUnknown, (void **)&unk);
|
||||
ok(SUCCEEDED(hr), "Failed to get IUnknown, hr %#x.\n", hr);
|
||||
ok(unk == (IUnknown *)rt, "Expected same interface pointer.\n");
|
||||
IUnknown_Release(unk);
|
||||
|
||||
hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
|
||||
ok(SUCCEEDED(hr), "Failed to get interop target, hr %#x.\n", hr);
|
||||
hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1RenderTarget, (void **)&rt2);
|
||||
ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
|
||||
ok(rt2 == rt, "Unexpected render target\n");
|
||||
ID2D1RenderTarget_Release(rt2);
|
||||
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,11 +2998,13 @@ 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;
|
||||
ID2D1DCRenderTarget *rt, *rt2;
|
||||
D2D1_ANTIALIAS_MODE aa_mode;
|
||||
ID2D1SolidColorBrush *brush;
|
||||
ID2D1DCRenderTarget *rt;
|
||||
ID2D1RenderTarget *rt3;
|
||||
ID2D1Factory *factory;
|
||||
ID3D10Device1 *device;
|
||||
FLOAT dpi_x, dpi_y;
|
||||
@ -2998,6 +3052,18 @@ 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);
|
||||
hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1RenderTarget, (void **)&rt3);
|
||||
ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
|
||||
ok(rt3 == (ID2D1RenderTarget *)rt, "Unexpected render target\n");
|
||||
ID2D1RenderTarget_Release(rt3);
|
||||
hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1DCRenderTarget, (void **)&rt2);
|
||||
ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
|
||||
ok(rt2 == rt, "Unexpected render target\n");
|
||||
ID2D1DCRenderTarget_Release(rt2);
|
||||
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,8 +3191,10 @@ 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;
|
||||
ID2D1HwndRenderTarget *rt, *rt2;
|
||||
ID2D1RenderTarget *rt3;
|
||||
ID2D1Factory *factory;
|
||||
ID3D10Device1 *device;
|
||||
D2D1_SIZE_U size;
|
||||
@ -3167,6 +3235,18 @@ 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);
|
||||
hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1RenderTarget, (void **)&rt3);
|
||||
ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
|
||||
ok(rt3 == (ID2D1RenderTarget *)rt, "Unexpected render target\n");
|
||||
ID2D1RenderTarget_Release(rt3);
|
||||
hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1HwndRenderTarget, (void **)&rt2);
|
||||
ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
|
||||
ok(rt2 == rt, "Unexpected render target\n");
|
||||
ID2D1HwndRenderTarget_Release(rt2);
|
||||
ID2D1GdiInteropRenderTarget_Release(interop);
|
||||
|
||||
size.width = 128;
|
||||
size.height = 64;
|
||||
hr = ID2D1HwndRenderTarget_Resize(rt, &size);
|
||||
@ -3181,13 +3261,15 @@ 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;
|
||||
ID2D1BitmapRenderTarget *rt, *rt2;
|
||||
ID2D1HwndRenderTarget *hwnd_rt;
|
||||
ID2D1Bitmap *bitmap, *bitmap2;
|
||||
ID2D1BitmapRenderTarget *rt;
|
||||
ID2D1DCRenderTarget *dc_rt;
|
||||
D2D1_SIZE_F size, size2;
|
||||
ID2D1RenderTarget *rt3;
|
||||
ID2D1Factory *factory;
|
||||
ID3D10Device1 *device;
|
||||
float dpi[2], dpi2[2];
|
||||
@ -3226,6 +3308,18 @@ 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);
|
||||
hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1RenderTarget, (void **)&rt3);
|
||||
ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
|
||||
ok(rt3 == (ID2D1RenderTarget *)rt, "Unexpected render target\n");
|
||||
ID2D1RenderTarget_Release(rt3);
|
||||
hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1BitmapRenderTarget, (void **)&rt2);
|
||||
ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
|
||||
ok(rt2 == rt, "Unexpected render target\n");
|
||||
ID2D1BitmapRenderTarget_Release(rt2);
|
||||
ID2D1GdiInteropRenderTarget_Release(interop);
|
||||
|
||||
/* See if parent target is referenced. */
|
||||
ID2D1HwndRenderTarget_AddRef(hwnd_rt);
|
||||
refcount = ID2D1HwndRenderTarget_Release(hwnd_rt);
|
||||
@ -3872,6 +3966,112 @@ static void test_draw_geometry(void)
|
||||
DestroyWindow(window);
|
||||
}
|
||||
|
||||
static void test_gdi_interop(void)
|
||||
{
|
||||
ID2D1GdiInteropRenderTarget *interop;
|
||||
D2D1_RENDER_TARGET_PROPERTIES desc;
|
||||
IWICImagingFactory *wic_factory;
|
||||
IWICBitmap *wic_bitmap;
|
||||
ID2D1RenderTarget *rt;
|
||||
ID2D1Factory *factory;
|
||||
ID3D10Device1 *device;
|
||||
D2D1_COLOR_F color;
|
||||
HRESULT hr;
|
||||
BOOL match;
|
||||
RECT rect;
|
||||
HDC dc;
|
||||
|
||||
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);
|
||||
|
||||
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
|
||||
&IID_IWICImagingFactory, (void **)&wic_factory);
|
||||
ok(SUCCEEDED(hr), "Failed to create WIC imaging factory, hr %#x.\n", hr);
|
||||
hr = IWICImagingFactory_CreateBitmap(wic_factory, 16, 16,
|
||||
&GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &wic_bitmap);
|
||||
ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
|
||||
IWICImagingFactory_Release(wic_factory);
|
||||
|
||||
/* WIC target, default usage */
|
||||
desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
|
||||
desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
|
||||
desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
|
||||
desc.dpiX = 0.0f;
|
||||
desc.dpiY = 0.0f;
|
||||
desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
|
||||
desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
|
||||
|
||||
hr = ID2D1Factory_CreateWicBitmapRenderTarget(factory, wic_bitmap, &desc, &rt);
|
||||
ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
|
||||
|
||||
hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
|
||||
ok(SUCCEEDED(hr), "Failed to get gdi interop interface, hr %#x.\n", hr);
|
||||
|
||||
ID2D1RenderTarget_BeginDraw(rt);
|
||||
dc = (void *)0xdeadbeef;
|
||||
hr = ID2D1GdiInteropRenderTarget_GetDC(interop, D2D1_DC_INITIALIZE_MODE_COPY, &dc);
|
||||
ok(FAILED(hr), "GetDC() was expected to fail, hr %#x.\n", hr);
|
||||
todo_wine
|
||||
ok(dc == NULL, "Expected NULL dc, got %p.\n", dc);
|
||||
ID2D1GdiInteropRenderTarget_Release(interop);
|
||||
ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
|
||||
|
||||
ID2D1RenderTarget_Release(rt);
|
||||
|
||||
/* WIC target, gdi compatible */
|
||||
desc.usage = D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE;
|
||||
|
||||
hr = ID2D1Factory_CreateWicBitmapRenderTarget(factory, wic_bitmap, &desc, &rt);
|
||||
ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
|
||||
|
||||
hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
|
||||
ok(SUCCEEDED(hr), "Failed to get gdi interop interface, hr %#x.\n", hr);
|
||||
|
||||
ID2D1RenderTarget_BeginDraw(rt);
|
||||
dc = NULL;
|
||||
hr = ID2D1GdiInteropRenderTarget_GetDC(interop, D2D1_DC_INITIALIZE_MODE_COPY, &dc);
|
||||
ok(SUCCEEDED(hr), "GetDC() was expected to succeed, hr %#x.\n", hr);
|
||||
ok(dc != NULL, "Expected NULL dc, got %p.\n", dc);
|
||||
ID2D1GdiInteropRenderTarget_ReleaseDC(interop, NULL);
|
||||
ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
|
||||
|
||||
ID2D1RenderTarget_BeginDraw(rt);
|
||||
set_color(&color, 1.0f, 0.0f, 0.0f, 1.0f);
|
||||
ID2D1RenderTarget_Clear(rt, &color);
|
||||
ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
|
||||
|
||||
match = compare_wic_bitmap(wic_bitmap, "54034063dbc1c1bb61cb60ec57e4498678dc2b13");
|
||||
ok(match, "Bitmap does not match.\n");
|
||||
|
||||
/* Do solid fill using GDI */
|
||||
ID2D1RenderTarget_BeginDraw(rt);
|
||||
|
||||
hr = ID2D1GdiInteropRenderTarget_GetDC(interop, D2D1_DC_INITIALIZE_MODE_COPY, &dc);
|
||||
ok(SUCCEEDED(hr), "GetDC() was expected to succeed, hr %#x.\n", hr);
|
||||
|
||||
SetRect(&rect, 0, 0, 16, 16);
|
||||
FillRect(dc, &rect, GetStockObject(BLACK_BRUSH));
|
||||
ID2D1GdiInteropRenderTarget_ReleaseDC(interop, NULL);
|
||||
|
||||
ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
|
||||
|
||||
match = compare_wic_bitmap(wic_bitmap, "60cacbf3d72e1e7834203da608037b1bf83b40e8");
|
||||
ok(match, "Bitmap does not match.\n");
|
||||
|
||||
ID2D1GdiInteropRenderTarget_Release(interop);
|
||||
ID2D1RenderTarget_Release(rt);
|
||||
|
||||
IWICBitmap_Release(wic_bitmap);
|
||||
ID2D1Factory_Release(factory);
|
||||
}
|
||||
|
||||
START_TEST(d2d1)
|
||||
{
|
||||
test_clip();
|
||||
@ -3895,4 +4095,5 @@ START_TEST(d2d1)
|
||||
test_stroke_style();
|
||||
test_gradient();
|
||||
test_draw_geometry();
|
||||
test_gdi_interop();
|
||||
}
|
||||
|
@ -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));
|
||||
|
||||
@ -870,8 +874,8 @@ HRESULT d2d_wic_render_target_init(struct d2d_wic_render_target *render_target,
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (FAILED(hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory,
|
||||
render_target->dxgi_surface, desc, &render_target->dxgi_target)))
|
||||
if (FAILED(hr = d2d_d3d_create_render_target(factory, render_target->dxgi_surface,
|
||||
(IUnknown *)&render_target->ID2D1RenderTarget_iface, desc, &render_target->dxgi_target)))
|
||||
{
|
||||
WARN("Failed to create DXGI surface render target, hr %#x.\n", hr);
|
||||
ID3D10Texture2D_Release(render_target->readback_texture);
|
||||
|
Loading…
x
Reference in New Issue
Block a user