-- v2: d2d1: Implement ID2D1Device1::CreateDeviceContext. d2d1: Update to ID2D1Device1.
From: Vladislav Timonin timoninvlad@yandex.ru
--- dlls/d2d1/d2d1_private.h | 2 +- dlls/d2d1/device.c | 68 +++++++++++++++++++++++++++------------- dlls/d2d1/factory.c | 39 ++++++++++++++++++----- dlls/d2d1/tests/d2d1.c | 11 +++++++ 4 files changed, 89 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..a281d26cb82 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..280fcf6fa38 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -9144,8 +9144,10 @@ static void test_device_context(BOOL d3d11) D2D1_HWND_RENDER_TARGET_PROPERTIES hwnd_rt_desc; D2D1_RENDER_TARGET_PROPERTIES rt_desc; ID2D1DeviceContext *device_context; + ID2D1DeviceContext1 *device_context1; IDXGISurface *surface, *surface2; ID2D1Device *device, *device2; + ID2D1Device1 *device1; struct d2d1_test_context ctx; D2D1_BITMAP_OPTIONS options; ID2D1DCRenderTarget *dc_rt; @@ -9190,6 +9192,15 @@ static void test_device_context(BOOL d3d11)
ID2D1DeviceContext_Release(device_context);
+ 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); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + ID2D1DeviceContext1_Release(device_context1); + ID2D1Device1_Release(device1); + /* DXGI target */ rt = ctx.rt; hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&device_context);
From: Vladislav Timonin timoninvlad@yandex.ru
--- dlls/d2d1/device.c | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 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 =
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=125537
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
d2d1: 0498:d2d1: unhandled exception c0000005 at 0041E58A
=== w7u_adm (32 bit report) ===
d2d1: 0858:d2d1: unhandled exception c0000005 at 0041E58A
=== w7u_el (32 bit report) ===
d2d1: 0508:d2d1: unhandled exception c0000005 at 0041E58A
On Sat Oct 29 12:44:59 2022 +0000, Vladislav Timonin wrote:
changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/1183/diffs?diff_id=15957&start_sha=f9f6041fea3e86a79721019ec42331b67eb51009#78507d505947ac14f51de00766df6ad4893c1c07_211_211)
Was a result of playing whack-a-warning, tried again, much cleaner this time, but with a slightly dodgy upcast (`unsafe_impl_from_ID2D1Device` call in `d2d_device_context_init`).
On Sat Oct 29 07:33:03 2022 +0000, Nikolay Sivov wrote:
Let's not rearrange function order, I would add a new function d2d_device_create() that takes dxgi device and returns "struct d2d_device *", you can use that function in all CreateDevice methods, keeping their own trace messages without duplicating them in debug output.
Moved functions back, `d2d_device_init` in `device.c` is basically that, but without allocation part, moved the common device creation into it's own function.