-- v4: d2d1: Implement ID2D1Device1::CreateDeviceContext. d2d1: Update to ID2D1Device1.
From: Vladislav Timonin timoninvlad@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); }
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 | 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);
Thanks, this looks good now. I'll list a few minor things to tweak below.
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.
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.
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.
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()".
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.