[PATCH v4 0/2] MR1183: d2d1: Update to ID2D1Device1.
-- v4: d2d1: Implement ID2D1Device1::CreateDeviceContext. d2d1: Update to ID2D1Device1. https://gitlab.winehq.org/wine/wine/-/merge_requests/1183
From: Vladislav Timonin <timoninvlad(a)yandex.ru> --- dlls/d2d1/device.c | 39 +++++++++++++++++++++++++++++++-------- dlls/d2d1/tests/d2d1.c | 4 ++-- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c index 3347514bb21..ae5247a79da 100644 --- a/dlls/d2d1/device.c +++ b/dlls/d2d1/device.c @@ -4534,14 +4534,11 @@ static void WINAPI d2d_device_GetFactory(ID2D1Device1 *iface, ID2D1Factory **fac ID2D1Factory1_AddRef(device->factory); } -static HRESULT WINAPI d2d_device_CreateDeviceContext(ID2D1Device1 *iface, D2D1_DEVICE_CONTEXT_OPTIONS options, - ID2D1DeviceContext **context) -{ +static HRESULT d2d_device_create_device_context(ID2D1Device1 *iface, D2D1_DEVICE_CONTEXT_OPTIONS options, + ID2D1DeviceContext1 **context) { struct d2d_device_context *object; HRESULT hr; - TRACE("iface %p, options %#x, context %p.\n", iface, options, context); - if (options) FIXME("Options are ignored %#x.\n", options); @@ -4556,7 +4553,24 @@ static HRESULT WINAPI d2d_device_CreateDeviceContext(ID2D1Device1 *iface, D2D1_D } TRACE("Created device context %p.\n", object); - *context = (ID2D1DeviceContext *)&object->ID2D1DeviceContext1_iface; + *context = &object->ID2D1DeviceContext1_iface; + + return S_OK; +} + +static HRESULT WINAPI d2d_device_CreateDeviceContext(ID2D1Device1 *iface, D2D1_DEVICE_CONTEXT_OPTIONS options, + ID2D1DeviceContext **context) +{ + ID2D1DeviceContext1 *context1 = NULL; + HRESULT hr; + + TRACE("iface %p, options %#x, context %p.\n", iface, options, context); + + if (FAILED(hr = d2d_device_create_device_context(iface, options, &context1))) { + return hr; + } + + *context = (ID2D1DeviceContext *)context1; return S_OK; } @@ -4605,9 +4619,18 @@ static void WINAPI d2d_device_SetRenderingPriority(ID2D1Device1 *iface, D2D1_REN static HRESULT WINAPI d2d_device_CreateDeviceContext1(ID2D1Device1 *iface, D2D1_DEVICE_CONTEXT_OPTIONS options, ID2D1DeviceContext1 **context) { - FIXME("iface %p, options %#x, context %p.\n", iface, options, context); + ID2D1DeviceContext1 *context1 = NULL; + HRESULT hr; - return E_NOTIMPL; + TRACE("iface %p, options %#x, context %p.\n", iface, options, context); + + if (FAILED(hr = d2d_device_create_device_context(iface, options, &context1))) { + return hr; + } + + *context = context1; + + return S_OK; } static const struct ID2D1Device1Vtbl d2d_device_vtbl = diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 172dd0e8140..e7860cb4bf4 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -9198,9 +9198,9 @@ static void test_device_context(BOOL d3d11) ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); hr = ID2D1Device1_CreateDeviceContext(device1, D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &device_context1); - todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - if (hr == S_OK) ID2D1DeviceContext1_Release(device_context1); + ID2D1DeviceContext1_Release(device_context1); ID2D1Device1_Release(device1); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/1183
From: Vladislav Timonin <timoninvlad(a)yandex.ru> --- dlls/d2d1/d2d1_private.h | 2 +- dlls/d2d1/device.c | 68 +++++++++++++++++++++++++++------------- dlls/d2d1/factory.c | 39 ++++++++++++++++++----- dlls/d2d1/tests/d2d1.c | 14 +++++++++ 4 files changed, 92 insertions(+), 31 deletions(-) diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 085febe95e7..5dab3fbb2a8 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -590,7 +590,7 @@ struct d2d_geometry *unsafe_impl_from_ID2D1Geometry(ID2D1Geometry *iface) DECLSP struct d2d_device { - ID2D1Device ID2D1Device_iface; + ID2D1Device1 ID2D1Device1_iface; LONG refcount; ID2D1Factory1 *factory; IDXGIDevice *dxgi_device; diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c index 32519f662c9..3347514bb21 100644 --- a/dlls/d2d1/device.c +++ b/dlls/d2d1/device.c @@ -35,12 +35,12 @@ struct d2d_draw_text_layout_ctx D2D1_DRAW_TEXT_OPTIONS options; }; -static inline struct d2d_device *impl_from_ID2D1Device(ID2D1Device *iface) +static inline struct d2d_device *impl_from_ID2D1Device(ID2D1Device1 *iface) { - return CONTAINING_RECORD(iface, struct d2d_device, ID2D1Device_iface); + return CONTAINING_RECORD(iface, struct d2d_device, ID2D1Device1_iface); } -static struct d2d_device *unsafe_impl_from_ID2D1Device(ID2D1Device *iface); +static struct d2d_device *unsafe_impl_from_ID2D1Device(ID2D1Device1 *iface); static ID2D1Brush *d2d_draw_get_text_brush(struct d2d_draw_text_layout_ctx *context, IUnknown *effect) { @@ -2336,8 +2336,8 @@ static void STDMETHODCALLTYPE d2d_device_context_GetDevice(ID2D1DeviceContext1 * TRACE("iface %p, device %p.\n", iface, device); - *device = context->device; - ID2D1Device_AddRef(*device); + *device = (ID2D1Device *)context->device; + ID2D1Device1_AddRef((ID2D1Device1 *)*device); } static void d2d_device_context_reset_target(struct d2d_device_context *context) @@ -4238,7 +4238,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, render_target->outer_unknown = outer_unknown ? outer_unknown : &render_target->IUnknown_iface; render_target->ops = ops; - device_impl = unsafe_impl_from_ID2D1Device(device); + device_impl = unsafe_impl_from_ID2D1Device((ID2D1Device1 *)device); if (FAILED(hr = IDXGIDevice_QueryInterface(device_impl->dxgi_device, &IID_ID3D11Device1, (void **)&render_target->d3d_device))) { @@ -4477,15 +4477,16 @@ HRESULT d2d_d3d_create_render_target(ID2D1Device *device, IDXGISurface *surface, return S_OK; } -static HRESULT WINAPI d2d_device_QueryInterface(ID2D1Device *iface, REFIID iid, void **out) +static HRESULT WINAPI d2d_device_QueryInterface(ID2D1Device1 *iface, REFIID iid, void **out) { TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); - if (IsEqualGUID(iid, &IID_ID2D1Device) + if (IsEqualGUID(iid, &IID_ID2D1Device1) + || IsEqualGUID(iid, &IID_ID2D1Device) || IsEqualGUID(iid, &IID_ID2D1Resource) || IsEqualGUID(iid, &IID_IUnknown)) { - ID2D1Device_AddRef(iface); + ID2D1Device1_AddRef(iface); *out = iface; return S_OK; } @@ -4496,7 +4497,7 @@ static HRESULT WINAPI d2d_device_QueryInterface(ID2D1Device *iface, REFIID iid, return E_NOINTERFACE; } -static ULONG WINAPI d2d_device_AddRef(ID2D1Device *iface) +static ULONG WINAPI d2d_device_AddRef(ID2D1Device1 *iface) { struct d2d_device *device = impl_from_ID2D1Device(iface); ULONG refcount = InterlockedIncrement(&device->refcount); @@ -4506,7 +4507,7 @@ static ULONG WINAPI d2d_device_AddRef(ID2D1Device *iface) return refcount; } -static ULONG WINAPI d2d_device_Release(ID2D1Device *iface) +static ULONG WINAPI d2d_device_Release(ID2D1Device1 *iface) { struct d2d_device *device = impl_from_ID2D1Device(iface); ULONG refcount = InterlockedDecrement(&device->refcount); @@ -4523,7 +4524,7 @@ static ULONG WINAPI d2d_device_Release(ID2D1Device *iface) return refcount; } -static void WINAPI d2d_device_GetFactory(ID2D1Device *iface, ID2D1Factory **factory) +static void WINAPI d2d_device_GetFactory(ID2D1Device1 *iface, ID2D1Factory **factory) { struct d2d_device *device = impl_from_ID2D1Device(iface); @@ -4533,7 +4534,7 @@ static void WINAPI d2d_device_GetFactory(ID2D1Device *iface, ID2D1Factory **fact ID2D1Factory1_AddRef(device->factory); } -static HRESULT WINAPI d2d_device_CreateDeviceContext(ID2D1Device *iface, D2D1_DEVICE_CONTEXT_OPTIONS options, +static HRESULT WINAPI d2d_device_CreateDeviceContext(ID2D1Device1 *iface, D2D1_DEVICE_CONTEXT_OPTIONS options, ID2D1DeviceContext **context) { struct d2d_device_context *object; @@ -4547,7 +4548,7 @@ static HRESULT WINAPI d2d_device_CreateDeviceContext(ID2D1Device *iface, D2D1_DE if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; - if (FAILED(hr = d2d_device_context_init(object, iface, NULL, NULL))) + if (FAILED(hr = d2d_device_context_init(object, (ID2D1Device *)iface, NULL, NULL))) { WARN("Failed to initialise device context, hr %#lx.\n", hr); free(object); @@ -4560,7 +4561,7 @@ static HRESULT WINAPI d2d_device_CreateDeviceContext(ID2D1Device *iface, D2D1_DE return S_OK; } -static HRESULT WINAPI d2d_device_CreatePrintControl(ID2D1Device *iface, IWICImagingFactory *wic_factory, +static HRESULT WINAPI d2d_device_CreatePrintControl(ID2D1Device1 *iface, IWICImagingFactory *wic_factory, IPrintDocumentPackageTarget *document_target, const D2D1_PRINT_CONTROL_PROPERTIES *desc, ID2D1PrintControl **print_control) { @@ -4570,26 +4571,46 @@ static HRESULT WINAPI d2d_device_CreatePrintControl(ID2D1Device *iface, IWICImag return E_NOTIMPL; } -static void WINAPI d2d_device_SetMaximumTextureMemory(ID2D1Device *iface, UINT64 max_texture_memory) +static void WINAPI d2d_device_SetMaximumTextureMemory(ID2D1Device1 *iface, UINT64 max_texture_memory) { FIXME("iface %p, max_texture_memory %s stub!\n", iface, wine_dbgstr_longlong(max_texture_memory)); } -static UINT64 WINAPI d2d_device_GetMaximumTextureMemory(ID2D1Device *iface) +static UINT64 WINAPI d2d_device_GetMaximumTextureMemory(ID2D1Device1 *iface) { FIXME("iface %p stub!\n", iface); return 0; } -static HRESULT WINAPI d2d_device_ClearResources(ID2D1Device *iface, UINT msec_since_use) +static HRESULT WINAPI d2d_device_ClearResources(ID2D1Device1 *iface, UINT msec_since_use) { FIXME("iface %p, msec_since_use %u stub!\n", iface, msec_since_use); return E_NOTIMPL; } -static const struct ID2D1DeviceVtbl d2d_device_vtbl = +static D2D1_RENDERING_PRIORITY WINAPI d2d_device_GetRenderingPriority(ID2D1Device1 *iface) +{ + FIXME("iface %p, stub, returning D2D1_RENDERING_PRIORITY_NORMAL!\n", iface); + + return D2D1_RENDERING_PRIORITY_NORMAL; +} + +static void WINAPI d2d_device_SetRenderingPriority(ID2D1Device1 *iface, D2D1_RENDERING_PRIORITY priority) +{ + FIXME("iface %p, priority %#x stub!\n", iface, priority); +} + +static HRESULT WINAPI d2d_device_CreateDeviceContext1(ID2D1Device1 *iface, D2D1_DEVICE_CONTEXT_OPTIONS options, + ID2D1DeviceContext1 **context) +{ + FIXME("iface %p, options %#x, context %p.\n", iface, options, context); + + return E_NOTIMPL; +} + +static const struct ID2D1Device1Vtbl d2d_device_vtbl = { d2d_device_QueryInterface, d2d_device_AddRef, @@ -4600,19 +4621,22 @@ static const struct ID2D1DeviceVtbl d2d_device_vtbl = d2d_device_SetMaximumTextureMemory, d2d_device_GetMaximumTextureMemory, d2d_device_ClearResources, + d2d_device_GetRenderingPriority, + d2d_device_SetRenderingPriority, + d2d_device_CreateDeviceContext1, }; -static struct d2d_device *unsafe_impl_from_ID2D1Device(ID2D1Device *iface) +static struct d2d_device *unsafe_impl_from_ID2D1Device(ID2D1Device1 *iface) { if (!iface) return NULL; assert(iface->lpVtbl == &d2d_device_vtbl); - return CONTAINING_RECORD(iface, struct d2d_device, ID2D1Device_iface); + return CONTAINING_RECORD(iface, struct d2d_device, ID2D1Device1_iface); } void d2d_device_init(struct d2d_device *device, ID2D1Factory1 *iface, IDXGIDevice *dxgi_device) { - device->ID2D1Device_iface.lpVtbl = &d2d_device_vtbl; + device->ID2D1Device1_iface.lpVtbl = &d2d_device_vtbl; device->refcount = 1; device->factory = iface; ID2D1Factory1_AddRef(device->factory); diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c index a160d7071c2..55130cc9b3f 100644 --- a/dlls/d2d1/factory.c +++ b/dlls/d2d1/factory.c @@ -529,20 +529,34 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDCRenderTarget(ID2D1Factory3 return S_OK; } -static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDevice(ID2D1Factory3 *iface, - IDXGIDevice *dxgi_device, ID2D1Device **device) -{ +static HRESULT d2d_factory_create_device(ID2D1Factory3 *iface, IDXGIDevice *dxgi_device, + ID2D1Device1 **device) { struct d2d_device *object; - TRACE("iface %p, dxgi_device %p, device %p.\n", iface, dxgi_device, device); - if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; d2d_device_init(object, (ID2D1Factory1 *)iface, dxgi_device); TRACE("Create device %p.\n", object); - *device = &object->ID2D1Device_iface; + *device = &object->ID2D1Device1_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDevice(ID2D1Factory3 *iface, + IDXGIDevice *dxgi_device, ID2D1Device **device) +{ + ID2D1Device1 *device1 = NULL; + HRESULT hr; + + TRACE("iface %p, dxgi_device %p, device %p.\n", iface, dxgi_device, device); + + if (FAILED(hr = d2d_factory_create_device(iface, dxgi_device, &device1))) { + return hr; + } + + *device = (ID2D1Device *)device1; return S_OK; } @@ -1080,9 +1094,18 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_GetEffectProperties(ID2D1Factory3 * static HRESULT STDMETHODCALLTYPE d2d_factory_ID2D1Factory2_CreateDevice(ID2D1Factory3 *iface, IDXGIDevice *dxgi_device, ID2D1Device1 **device) { - FIXME("iface %p, dxgi_device %p, device %p stub!\n", iface, dxgi_device, device); + ID2D1Device1 *device1 = NULL; + HRESULT hr; - return E_NOTIMPL; + TRACE("iface %p, dxgi_device %p, device %p.\n", iface, dxgi_device, device); + + if (FAILED(hr = d2d_factory_create_device(iface, dxgi_device, &device1))) { + return hr; + } + + *device = device1; + + return S_OK; } static HRESULT STDMETHODCALLTYPE d2d_factory_ID2D1Factory3_CreateDevice(ID2D1Factory3 *iface, IDXGIDevice *dxgi_device, diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 3bfc8973c31..172dd0e8140 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -9190,6 +9190,20 @@ static void test_device_context(BOOL d3d11) ID2D1DeviceContext_Release(device_context); + if (ctx.factory2) { + ID2D1Device1 *device1; + ID2D1DeviceContext1 *device_context1; + + hr = ID2D1Factory2_CreateDevice(ctx.factory2, ctx.device, &device1); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = ID2D1Device1_CreateDeviceContext(device1, D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &device_context1); + todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + if (hr == S_OK) ID2D1DeviceContext1_Release(device_context1); + ID2D1Device1_Release(device1); + } + /* DXGI target */ rt = ctx.rt; hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&device_context); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/1183
Thanks, this looks good now. I'll list a few minor things to tweak below. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/1183#note_12452
Nikolay Sivov (@nsivov) commented about dlls/d2d1/tests/d2d1.c:
ID2D1DeviceContext_Release(device_context);
+ if (ctx.factory2) { + ID2D1Device1 *device1;
To use existing style, please place opening braces on a new line. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/1183#note_12453
Nikolay Sivov (@nsivov) commented about dlls/d2d1/device.c:
TRACE("iface %p, device %p.\n", iface, device);
- *device = context->device; - ID2D1Device_AddRef(*device); + *device = (ID2D1Device *)context->device; + ID2D1Device1_AddRef((ID2D1Device1 *)*device);
You don't need to change AddRef() line. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/1183#note_12454
Nikolay Sivov (@nsivov) commented about dlls/d2d1/device.c:
return 0; }
-static HRESULT WINAPI d2d_device_ClearResources(ID2D1Device *iface, UINT msec_since_use) +static HRESULT WINAPI d2d_device_ClearResources(ID2D1Device1 *iface, UINT msec_since_use) { FIXME("iface %p, msec_since_use %u stub!\n", iface, msec_since_use);
return E_NOTIMPL; }
-static const struct ID2D1DeviceVtbl d2d_device_vtbl = +static D2D1_RENDERING_PRIORITY WINAPI d2d_device_GetRenderingPriority(ID2D1Device1 *iface) +{ + FIXME("iface %p, stub, returning D2D1_RENDERING_PRIORITY_NORMAL!\n", iface);
We usually just end the message on a "stub!". It's obvious what's returned once you look at the code. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/1183#note_12455
Nikolay Sivov (@nsivov) commented about dlls/d2d1/factory.c:
+ return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDevice(ID2D1Factory3 *iface, + IDXGIDevice *dxgi_device, ID2D1Device **device) +{ + ID2D1Device1 *device1 = NULL; + HRESULT hr; + + TRACE("iface %p, dxgi_device %p, device %p.\n", iface, dxgi_device, device); + + if (FAILED(hr = d2d_factory_create_device(iface, dxgi_device, &device1))) { + return hr; + } + + *device = (ID2D1Device *)device1; This does not have to be that verbose. You only need to "return d2d_factory_create_device()".
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/1183#note_12456
Nikolay Sivov (@nsivov) commented about dlls/d2d1/device.c:
+ return S_OK; +} + +static HRESULT WINAPI d2d_device_CreateDeviceContext(ID2D1Device1 *iface, D2D1_DEVICE_CONTEXT_OPTIONS options, + ID2D1DeviceContext **context) +{ + ID2D1DeviceContext1 *context1 = NULL; + HRESULT hr; + + TRACE("iface %p, options %#x, context %p.\n", iface, options, context); + + if (FAILED(hr = d2d_device_create_device_context(iface, options, &context1))) { + return hr; + } + + *context = (ID2D1DeviceContext *)context1; Same as with the first commit - just do a single call, and add a pointer cast, which is appropriate here because it's an out argument.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/1183#note_12457
participants (3)
-
Nikolay Sivov (@nsivov) -
Vladislav Timonin -
Vladislav Timonin (@vt)