Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/Makefile.in | 1 + dlls/d2d1/d2d1_private.h | 8 ++ dlls/d2d1/device.c | 12 ++- dlls/d2d1/effect.c | 215 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 235 insertions(+), 1 deletion(-) create mode 100644 dlls/d2d1/effect.c
diff --git a/dlls/d2d1/Makefile.in b/dlls/d2d1/Makefile.in index 4bfe3b5953..413571338b 100644 --- a/dlls/d2d1/Makefile.in +++ b/dlls/d2d1/Makefile.in @@ -9,6 +9,7 @@ C_SRCS = \ brush.c \ dc_render_target.c \ device.c \ + effect.c \ factory.c \ geometry.c \ hwnd_render_target.c \ diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 9bfbbf2a6c..726d143d86 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -503,6 +503,14 @@ struct d2d_device
void d2d_device_init(struct d2d_device *device, ID2D1Factory1 *factory, IDXGIDevice *dxgi_device) DECLSPEC_HIDDEN;
+struct d2d_effect +{ + ID2D1Effect ID2D1Effect_iface; + LONG refcount; +}; + +void d2d_effect_init(struct d2d_effect *effect) DECLSPEC_HIDDEN; + static inline BOOL d2d_array_reserve(void **elements, size_t *capacity, size_t count, size_t size) { size_t new_capacity, max_capacity; diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c index 5e6655feba..be31ecafc8 100644 --- a/dlls/d2d1/device.c +++ b/dlls/d2d1/device.c @@ -1858,9 +1858,19 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateBitmapFromDxgiSurface( static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateEffect(ID2D1DeviceContext *iface, REFCLSID effect_id, ID2D1Effect **effect) { + struct d2d_effect *object; + FIXME("iface %p, effect_id %s, effect %p stub!\n", iface, debugstr_guid(effect_id), effect);
- return E_NOTIMPL; + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + d2d_effect_init(object); + + TRACE("Created effect %p.\n", object); + *effect = &object->ID2D1Effect_iface; + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_CreateGradientStopCollection( diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c new file mode 100644 index 0000000000..48e2912ab8 --- /dev/null +++ b/dlls/d2d1/effect.c @@ -0,0 +1,215 @@ +/* + * Copyright 2018 Nikolay Sivov for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" + +#include "d2d1_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d2d); + +static inline struct d2d_effect *impl_from_ID2D1Effect(ID2D1Effect *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_effect, ID2D1Effect_iface); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_QueryInterface(ID2D1Effect *iface, REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_ID2D1Effect) + || IsEqualGUID(iid, &IID_ID2D1Properties) + || IsEqualGUID(iid, &IID_IUnknown)) + { + ID2D1Effect_AddRef(iface); + *out = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d2d_effect_AddRef(ID2D1Effect *iface) +{ + struct d2d_effect *effect = impl_from_ID2D1Effect(iface); + ULONG refcount = InterlockedIncrement(&effect->refcount); + + TRACE("%p increasing refcount to %u.\n", iface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d2d_effect_Release(ID2D1Effect *iface) +{ + struct d2d_effect *effect = impl_from_ID2D1Effect(iface); + ULONG refcount = InterlockedDecrement(&effect->refcount); + + TRACE("%p decreasing refcount to %u.\n", iface, refcount); + + if (!refcount) + heap_free(effect); + + return refcount; +} + +static UINT32 STDMETHODCALLTYPE d2d_effect_GetPropertyCount(ID2D1Effect *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_GetPropertyName(ID2D1Effect *iface, UINT32 index, + WCHAR *name, UINT32 name_count) +{ + FIXME("iface %p, index %u, name %p, name_count %u stub!\n", iface, index, name, name_count); + + return E_NOTIMPL; +} + +static UINT32 STDMETHODCALLTYPE d2d_effect_GetPropertyNameLength(ID2D1Effect *iface, UINT32 index) +{ + FIXME("iface %p, index %u stub!\n", iface, index); + + return 0; +} + +static D2D1_PROPERTY_TYPE STDMETHODCALLTYPE d2d_effect_GetType(ID2D1Effect *iface, UINT32 index) +{ + FIXME("iface %p, index %u stub!\n", iface, index); + + return 0; +} + +static UINT32 STDMETHODCALLTYPE d2d_effect_GetPropertyIndex(ID2D1Effect *iface, const WCHAR *name) +{ + FIXME("iface %p, name %s stub!\n", iface, debugstr_w(name)); + + return 0; +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_SetValueByName(ID2D1Effect *iface, const WCHAR *name, + D2D1_PROPERTY_TYPE type, const BYTE *value, UINT32 value_size) +{ + FIXME("iface %p, name %s, type %#x, value %p, value_size %u stub!\n", iface, debugstr_w(name), + type, value, value_size); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_SetValue(ID2D1Effect *iface, UINT32 index, D2D1_PROPERTY_TYPE type, + const BYTE *value, UINT32 value_size) +{ + FIXME("iface %p, index %u, type %#x, value %p, value_size %u stub!\n", iface, index, type, value, value_size); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_GetValueByName(ID2D1Effect *iface, const WCHAR *name, + D2D1_PROPERTY_TYPE type, BYTE *value, UINT32 value_size) +{ + FIXME("iface %p, name %s, type %#x, value %p, value_size %u stub!\n", iface, debugstr_w(name), type, + value, value_size); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_GetValue(ID2D1Effect *iface, UINT32 index, D2D1_PROPERTY_TYPE type, + BYTE *value, UINT32 value_size) +{ + FIXME("iface %p, index %u, type %#x, value %p, value_size %u stub!\n", iface, index, type, + value, value_size); + + return E_NOTIMPL; +} + +static UINT32 STDMETHODCALLTYPE d2d_effect_GetValueSize(ID2D1Effect *iface, UINT32 index) +{ + FIXME("iface %p, index %u stub!\n", iface, index); + + return 0; +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_GetSubProperties(ID2D1Effect *iface, UINT32 index, ID2D1Properties **props) +{ + FIXME("iface %p, index %u, props %p stub!\n", iface, index, props); + + return E_NOTIMPL; +} + +static void STDMETHODCALLTYPE d2d_effect_SetInput(ID2D1Effect *iface, UINT32 index, ID2D1Image *input, BOOL invalidate) +{ + FIXME("iface %p, index %u, input %p, invalidate %d stub!\n", iface, index, input, invalidate); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_SetInputCount(ID2D1Effect *iface, UINT32 count) +{ + FIXME("iface %p, count %u stub!\n", iface, count); + + return E_NOTIMPL; +} + +static void STDMETHODCALLTYPE d2d_effect_GetInput(ID2D1Effect *iface, UINT32 index, ID2D1Image **input) +{ + FIXME("iface %p, index %u, input %p stub!\n", iface, index, input); +} + +static UINT32 STDMETHODCALLTYPE d2d_effect_GetInputCount(ID2D1Effect *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static void STDMETHODCALLTYPE d2d_effect_GetOutput(ID2D1Effect *iface, ID2D1Image **output) +{ + FIXME("iface %p, output %p stub!\n", iface, output); +} + +static const ID2D1EffectVtbl d2d_effect_vtbl = +{ + d2d_effect_QueryInterface, + d2d_effect_AddRef, + d2d_effect_Release, + d2d_effect_GetPropertyCount, + d2d_effect_GetPropertyName, + d2d_effect_GetPropertyNameLength, + d2d_effect_GetType, + d2d_effect_GetPropertyIndex, + d2d_effect_SetValueByName, + d2d_effect_SetValue, + d2d_effect_GetValueByName, + d2d_effect_GetValue, + d2d_effect_GetValueSize, + d2d_effect_GetSubProperties, + d2d_effect_SetInput, + d2d_effect_SetInputCount, + d2d_effect_GetInput, + d2d_effect_GetInputCount, + d2d_effect_GetOutput, +}; + +void d2d_effect_init(struct d2d_effect *effect) +{ + effect->ID2D1Effect_iface.lpVtbl = &d2d_effect_vtbl; + effect->refcount = 1; +} +
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/bitmap.c | 4 ++ dlls/d2d1/tests/d2d1.c | 112 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 110 insertions(+), 6 deletions(-)
diff --git a/dlls/d2d1/bitmap.c b/dlls/d2d1/bitmap.c index c8d099c7df..85514627ca 100644 --- a/dlls/d2d1/bitmap.c +++ b/dlls/d2d1/bitmap.c @@ -464,7 +464,11 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid, d.pixelFormat.format = surface_desc.Format; } else + { d = *desc; + if (d.pixelFormat.format == DXGI_FORMAT_UNKNOWN) + d.pixelFormat.format = surface_desc.Format; + }
if (d.dpiX == 0.0f || d.dpiY == 0.0f) { diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index eaa0b64a3d..3005b43e44 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -4123,6 +4123,7 @@ static void test_shared_bitmap(void) IWICImagingFactory *wic_factory; ID2D1Bitmap *bitmap1, *bitmap2; DXGI_SURFACE_DESC surface_desc; + D2D1_PIXEL_FORMAT pixel_format; D2D1_SIZE_U size = {4, 4}; IDXGISurface1 *surface3; HWND window1, window2; @@ -4279,6 +4280,32 @@ static void test_shared_bitmap(void)
if (SUCCEEDED(hr)) { + static const struct bitmap_format_test + { + D2D1_PIXEL_FORMAT original; + D2D1_PIXEL_FORMAT result; + HRESULT hr; + } + bitmap_format_tests[] = + { + { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED }, + { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED } }, + + { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_IGNORE }, + { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE } }, + + { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_UNKNOWN }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT }, + + { { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_UNKNOWN }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT }, + + { { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE }, + { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE } }, + + { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_STRAIGHT }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT }, + { { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_STRAIGHT }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT }, + }; + unsigned int i; + size = ID2D1Bitmap_GetPixelSize(bitmap2); hr = IDXGISurface_GetDesc(surface2, &surface_desc); ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr); @@ -4297,6 +4324,26 @@ static void test_shared_bitmap(void) ID2D1Bitmap_Release(bitmap2); IDXGISurface1_Release(surface3); } + + for (i = 0; i < ARRAY_SIZE(bitmap_format_tests); ++i) + { + bitmap_desc.pixelFormat = bitmap_format_tests[i].original; + + hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_IDXGISurface, surface2, &bitmap_desc, &bitmap2); + todo_wine_if(i == 2 || i == 3 || i == 5 || i == 6) + ok(hr == bitmap_format_tests[i].hr, "%u: unexpected hr %#x.\n", i, hr); + + if (SUCCEEDED(bitmap_format_tests[i].hr)) + { + pixel_format = ID2D1Bitmap_GetPixelFormat(bitmap2); + ok(pixel_format.format == bitmap_format_tests[i].result.format, "%u: unexpected pixel format %#x.\n", + i, pixel_format.format); + ok(pixel_format.alphaMode == bitmap_format_tests[i].result.alphaMode, "%u: unexpected alpha mode %d.\n", + i, pixel_format.alphaMode); + + ID2D1Bitmap_Release(bitmap2); + } + } }
ID2D1RenderTarget_Release(rt2); @@ -6767,7 +6814,15 @@ static void check_rt_bitmap_surface_(unsigned int line, ID2D1RenderTarget *rt, B target = NULL; } if (bitmap) + { + D2D1_PIXEL_FORMAT rt_format, bitmap_format; + + rt_format = ID2D1RenderTarget_GetPixelFormat(rt); + bitmap_format = ID2D1Bitmap_GetPixelFormat(bitmap); + ok_(__FILE__, line)(!memcmp(&rt_format, &bitmap_format, sizeof(rt_format)), "Unexpected bitmap format.\n"); + ID2D1Bitmap_Release(bitmap); + }
/* Pixel format is not defined until target is set, for DC target it's specified on creation. */ if (target || dc_rt) @@ -6805,7 +6860,7 @@ static void check_rt_bitmap_surface_(unsigned int line, ID2D1RenderTarget *rt, B hr = ID2D1RenderTarget_CreateCompatibleRenderTarget(rt, NULL, NULL, NULL, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, (ID2D1BitmapRenderTarget **)&compatible_rt); todo_wine - ok_(__FILE__, line)(hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT, " --- Unexpected hr %#x.\n", hr); + ok_(__FILE__, line)(hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT, "Unexpected hr %#x.\n", hr); }
ID2D1DeviceContext_Release(context); @@ -6817,6 +6872,31 @@ static void check_rt_bitmap_surface_(unsigned int line, ID2D1RenderTarget *rt, B
static void test_bitmap_surface(void) { + static const struct bitmap_format_test + { + D2D1_PIXEL_FORMAT original; + D2D1_PIXEL_FORMAT result; + HRESULT hr; + } + bitmap_format_tests[] = + { + { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED }, + { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED } }, + + { { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_STRAIGHT }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT }, + + { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_IGNORE }, + { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE } }, + + { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_UNKNOWN }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT }, + + { { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_UNKNOWN }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT }, + + { { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE }, + { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE } }, + + { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_STRAIGHT }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT }, + }; D2D1_HWND_RENDER_TARGET_PROPERTIES hwnd_rt_desc; D2D1_RENDER_TARGET_PROPERTIES rt_desc; D2D1_BITMAP_PROPERTIES1 bitmap_desc; @@ -6830,6 +6910,7 @@ static void test_bitmap_surface(void) ID2D1Bitmap1 *bitmap; ID2D1Device *device; ID2D1Image *target; + unsigned int i; HWND window; HRESULT hr;
@@ -6889,11 +6970,30 @@ todo_wine
if (SUCCEEDED(hr)) { - memset(&bitmap_desc, 0, sizeof(bitmap_desc)); - bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; - bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE; - bitmap_desc.dpiX = 96.0f; - bitmap_desc.dpiY = 96.0f; + for (i = 0; i < ARRAY_SIZE(bitmap_format_tests); ++i) + { + D2D1_PIXEL_FORMAT pixel_format; + + memset(&bitmap_desc, 0, sizeof(bitmap_desc)); + bitmap_desc.pixelFormat = bitmap_format_tests[i].original; + bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW; + + hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(device_context, surface, &bitmap_desc, &bitmap); + ok(hr == bitmap_format_tests[i].hr, "%u: unexpected hr %#x.\n", i, hr); + + if (SUCCEEDED(hr)) + { + pixel_format = ID2D1Bitmap1_GetPixelFormat(bitmap); + + ok(pixel_format.format == bitmap_format_tests[i].result.format, "%u: unexpected pixel format %#x.\n", + i, pixel_format.format); + ok(pixel_format.alphaMode == bitmap_format_tests[i].result.alphaMode, "%u: unexpected alpha mode %d.\n", + i, pixel_format.alphaMode); + + ID2D1Bitmap1_Release(bitmap); + } + } + hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(device_context, surface, NULL, &bitmap); ok(SUCCEEDED(hr), "Failed to create a bitmap, hr %#x.\n", hr);
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/d2d1_private.h | 14 ++- dlls/d2d1/device.c | 245 +++++++++++++++++++++++++-------------- dlls/d2d1/tests/d2d1.c | 5 +- 3 files changed, 170 insertions(+), 94 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 726d143d86..ac42f7cf25 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -136,7 +136,6 @@ struct d2d_device_context ID2D1Factory *factory; ID2D1Device *device; ID3D10Device *d3d_device; - ID3D10RenderTargetView *view; ID3D10StateBlock *stateblock; struct d2d_shape_resources shape_resources[D2D_SHAPE_TYPE_COUNT]; ID3D10PixelShader *ps; @@ -146,6 +145,19 @@ struct d2d_device_context ID3D10RasterizerState *rs; ID3D10BlendState *bs;
+ struct + { + union + { + ID2D1Image *image; + struct + { + ID2D1Bitmap *bitmap; + ID3D10RenderTargetView *view; + } bitmap; + } u; + } target; + struct d2d_error_state error; D2D1_DRAWING_STATE_DESCRIPTION1 drawing_state; IDWriteRenderingParams *text_rendering_params; diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c index be31ecafc8..212e9c0df9 100644 --- a/dlls/d2d1/device.c +++ b/dlls/d2d1/device.c @@ -43,6 +43,8 @@ static inline struct d2d_device *impl_from_ID2D1Device(ID2D1Device *iface) return CONTAINING_RECORD(iface, struct d2d_device, ID2D1Device_iface); }
+static struct d2d_device *unsafe_impl_from_ID2D1Device(ID2D1Device *iface); + static ID2D1Brush *d2d_draw_get_text_brush(struct d2d_draw_text_layout_ctx *context, IUnknown *effect) { ID2D1Brush *brush = NULL; @@ -175,7 +177,7 @@ static void d2d_device_context_draw(struct d2d_device_context *render_target, en } ID3D10Device_RSSetScissorRects(device, 1, &scissor_rect); ID3D10Device_RSSetState(device, render_target->rs); - ID3D10Device_OMSetRenderTargets(device, 1, &render_target->view, NULL); + ID3D10Device_OMSetRenderTargets(device, 1, &render_target->target.u.bitmap.view, NULL); if (brush) { ID3D10Device_OMSetBlendState(device, render_target->bs, blend_factor, D3D10_DEFAULT_SAMPLE_MASK); @@ -261,7 +263,8 @@ static ULONG STDMETHODCALLTYPE d2d_device_context_inner_Release(IUnknown *iface) IDWriteRenderingParams_Release(context->default_text_rendering_params); if (context->text_rendering_params) IDWriteRenderingParams_Release(context->text_rendering_params); - ID3D10BlendState_Release(context->bs); + if (context->bs) + ID3D10BlendState_Release(context->bs); ID3D10RasterizerState_Release(context->rs); ID3D10Buffer_Release(context->vb); ID3D10Buffer_Release(context->ib); @@ -272,8 +275,11 @@ static ULONG STDMETHODCALLTYPE d2d_device_context_inner_Release(IUnknown *iface) ID3D10InputLayout_Release(context->shape_resources[i].il); } context->stateblock->lpVtbl->Release(context->stateblock); - ID3D10RenderTargetView_Release(context->view); ID3D10Device_Release(context->d3d_device); + if (context->target.u.bitmap.view) + ID3D10RenderTargetView_Release(context->target.u.bitmap.view); + if (context->target.u.image) + ID2D1Image_Release(context->target.u.image); ID2D1Factory_Release(context->factory); ID2D1Device_Release(context->device); heap_free(context); @@ -1971,14 +1977,100 @@ static void STDMETHODCALLTYPE d2d_device_context_GetDevice(ID2D1DeviceContext *i ID2D1Device_AddRef(*device); }
+static void d2d_device_context_reset_target(struct d2d_device_context *context) +{ + if (!context->target.u.image) + return; + + ID2D1Image_Release(context->target.u.image); + context->target.u.image = NULL; + + context->desc.dpiX = 96.0f; + context->desc.dpiY = 96.0f; + + memset(&context->desc.pixelFormat, 0, sizeof(context->desc.pixelFormat)); + memset(&context->pixel_size, 0, sizeof(context->pixel_size)); + + ID3D10BlendState_Release(context->bs); + context->bs = NULL; + + ID3D10RenderTargetView_Release(context->target.u.bitmap.view); + context->target.u.bitmap.view = NULL; +} + static void STDMETHODCALLTYPE d2d_device_context_SetTarget(ID2D1DeviceContext *iface, ID2D1Image *target) { - FIXME("iface %p, target %p stub!\n", iface, target); + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); + struct d2d_bitmap *bitmap_impl; + D3D10_BLEND_DESC blend_desc; + ID3D10Resource *resource; + ID2D1Bitmap *bitmap; + HRESULT hr; + + TRACE("iface %p, target %p.\n", iface, target); + + if (!target) + { + d2d_device_context_reset_target(context); + return; + } + + if (FAILED(ID2D1Image_QueryInterface(target, &IID_ID2D1Bitmap1, (void **)&bitmap))) + { + FIXME("Only bitmap targets are supported.\n"); + return; + } + + d2d_device_context_reset_target(context); + + context->target.u.bitmap.bitmap = bitmap; + + /* Set sizes and pixel format. */ + ID2D1Bitmap_GetDpi(bitmap, &context->desc.dpiX, &context->desc.dpiY); + context->pixel_size = ID2D1Bitmap_GetPixelSize(bitmap); + context->desc.pixelFormat = ID2D1Bitmap_GetPixelFormat(bitmap); + + memset(&blend_desc, 0, sizeof(blend_desc)); + blend_desc.BlendEnable[0] = TRUE; + blend_desc.SrcBlend = D3D10_BLEND_ONE; + blend_desc.DestBlend = D3D10_BLEND_INV_SRC_ALPHA; + blend_desc.BlendOp = D3D10_BLEND_OP_ADD; + if (context->desc.pixelFormat.alphaMode == D2D1_ALPHA_MODE_IGNORE) + { + blend_desc.SrcBlendAlpha = D3D10_BLEND_ZERO; + blend_desc.DestBlendAlpha = D3D10_BLEND_ONE; + } + else + { + blend_desc.SrcBlendAlpha = D3D10_BLEND_ONE; + blend_desc.DestBlendAlpha = D3D10_BLEND_INV_SRC_ALPHA; + } + blend_desc.BlendOpAlpha = D3D10_BLEND_OP_ADD; + blend_desc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL; + if (FAILED(hr = ID3D10Device_CreateBlendState(context->d3d_device, &blend_desc, &context->bs))) + { + WARN("Failed to create blend state, hr %#x.\n", hr); + return; + } + + bitmap_impl = unsafe_impl_from_ID2D1Bitmap(bitmap); + ID3D10ShaderResourceView_GetResource(bitmap_impl->view, &resource); + + hr = ID3D10Device_CreateRenderTargetView(context->d3d_device, resource, NULL, &context->target.u.bitmap.view); + ID3D10Resource_Release(resource); + if (FAILED(hr)) + WARN("Failed to create rendertarget view, hr %#x.\n", hr); }
static void STDMETHODCALLTYPE d2d_device_context_GetTarget(ID2D1DeviceContext *iface, ID2D1Image **target) { - FIXME("iface %p, target %p stub!\n", iface, target); + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); + + TRACE("iface %p, target %p.\n", iface, target); + + *target = context->target.u.image; + if (*target) + ID2D1Image_AddRef(*target); }
static void STDMETHODCALLTYPE d2d_device_context_SetRenderingControls(ID2D1DeviceContext *iface, @@ -2530,7 +2622,7 @@ static HRESULT d2d_device_context_get_surface(struct d2d_device_context *render_ ID3D10Resource *resource; HRESULT hr;
- ID3D10RenderTargetView_GetResource(render_target->view, &resource); + ID3D10RenderTargetView_GetResource(render_target->target.u.bitmap.view, &resource); hr = ID3D10Resource_QueryInterface(resource, &IID_IDXGISurface1, (void **)surface); ID3D10Resource_Release(resource); if (FAILED(hr)) @@ -2592,17 +2684,14 @@ static const struct ID2D1GdiInteropRenderTargetVtbl d2d_gdi_interop_render_targe };
static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, ID2D1Device *device, - IDXGISurface *surface, IUnknown *outer_unknown, const struct d2d_device_context_ops *ops, - const D2D1_RENDER_TARGET_PROPERTIES *desc) + IUnknown *outer_unknown, const struct d2d_device_context_ops *ops) { D3D10_SUBRESOURCE_DATA buffer_data; D3D10_STATE_BLOCK_MASK state_mask; - DXGI_SURFACE_DESC surface_desc; + struct d2d_device *device_impl; IDWriteFactory *dwrite_factory; D3D10_RASTERIZER_DESC rs_desc; D3D10_BUFFER_DESC buffer_desc; - D3D10_BLEND_DESC blend_desc; - ID3D10Resource *resource; unsigned int i; HRESULT hr;
@@ -3452,25 +3541,6 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, { 1.0f, -1.0f}, }; static const UINT16 indices[] = {0, 1, 2, 2, 1, 3}; - float dpi_x, dpi_y; - - dpi_x = desc->dpiX; - dpi_y = desc->dpiY; - - if (dpi_x == 0.0f && dpi_y == 0.0f) - { - dpi_x = 96.0f; - dpi_y = 96.0f; - } - else if (dpi_x <= 0.0f || dpi_y <= 0.0f) - return E_INVALIDARG; - - if (desc->type != D2D1_RENDER_TARGET_TYPE_DEFAULT && desc->type != D2D1_RENDER_TARGET_TYPE_HARDWARE) - WARN("Ignoring render target type %#x.\n", desc->type); - if (desc->usage != D2D1_RENDER_TARGET_USAGE_NONE) - FIXME("Ignoring render target usage %#x.\n", desc->usage); - if (desc->minLevel != D2D1_FEATURE_LEVEL_DEFAULT) - WARN("Ignoring feature level %#x.\n", desc->minLevel);
render_target->ID2D1DeviceContext_iface.lpVtbl = &d2d_device_context_vtbl; render_target->ID2D1GdiInteropRenderTarget_iface.lpVtbl = &d2d_gdi_interop_render_target_vtbl; @@ -3484,27 +3554,15 @@ 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;
- if (FAILED(hr = IDXGISurface_GetDevice(surface, &IID_ID3D10Device, (void **)&render_target->d3d_device))) + device_impl = unsafe_impl_from_ID2D1Device(device); + if (FAILED(hr = IDXGIDevice_QueryInterface(device_impl->dxgi_device, &IID_ID3D10Device, + (void **)&render_target->d3d_device))) { WARN("Failed to get device interface, hr %#x.\n", hr); ID2D1Factory_Release(render_target->factory); return hr; }
- if (FAILED(hr = IDXGISurface_QueryInterface(surface, &IID_ID3D10Resource, (void **)&resource))) - { - WARN("Failed to get ID3D10Resource interface, hr %#x.\n", hr); - goto err; - } - - hr = ID3D10Device_CreateRenderTargetView(render_target->d3d_device, resource, NULL, &render_target->view); - ID3D10Resource_Release(resource); - if (FAILED(hr)) - { - WARN("Failed to create rendertarget view, hr %#x.\n", hr); - goto err; - } - if (FAILED(hr = D3D10StateBlockMaskEnableAll(&state_mask))) { WARN("Failed to create stateblock mask, hr %#x.\n", hr); @@ -3589,29 +3647,6 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, goto err; }
- memset(&blend_desc, 0, sizeof(blend_desc)); - blend_desc.BlendEnable[0] = TRUE; - blend_desc.SrcBlend = D3D10_BLEND_ONE; - blend_desc.DestBlend = D3D10_BLEND_INV_SRC_ALPHA; - blend_desc.BlendOp = D3D10_BLEND_OP_ADD; - if (desc->pixelFormat.alphaMode == D2D1_ALPHA_MODE_IGNORE) - { - blend_desc.SrcBlendAlpha = D3D10_BLEND_ZERO; - blend_desc.DestBlendAlpha = D3D10_BLEND_ONE; - } - else - { - blend_desc.SrcBlendAlpha = D3D10_BLEND_ONE; - blend_desc.DestBlendAlpha = D3D10_BLEND_INV_SRC_ALPHA; - } - blend_desc.BlendOpAlpha = D3D10_BLEND_OP_ADD; - blend_desc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL; - if (FAILED(hr = ID3D10Device_CreateBlendState(render_target->d3d_device, &blend_desc, &render_target->bs))) - { - WARN("Failed to create blend state, hr %#x.\n", hr); - goto err; - } - if (FAILED(hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, &IID_IDWriteFactory, (IUnknown **)&dwrite_factory))) { @@ -3627,15 +3662,6 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, goto err; }
- if (FAILED(hr = IDXGISurface_GetDesc(surface, &surface_desc))) - { - WARN("Failed to get surface desc, hr %#x.\n", hr); - goto err; - } - - render_target->desc.pixelFormat = desc->pixelFormat; - render_target->pixel_size.width = surface_desc.Width; - render_target->pixel_size.height = surface_desc.Height; render_target->drawing_state.transform = identity;
if (!d2d_clip_stack_init(&render_target->clip_stack)) @@ -3645,16 +3671,14 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, goto err; }
- render_target->desc.dpiX = dpi_x; - render_target->desc.dpiY = dpi_y; + render_target->desc.dpiX = 96.0f; + render_target->desc.dpiY = 96.0f;
return S_OK;
err: if (render_target->default_text_rendering_params) IDWriteRenderingParams_Release(render_target->default_text_rendering_params); - if (render_target->bs) - ID3D10BlendState_Release(render_target->bs); if (render_target->rs) ID3D10RasterizerState_Release(render_target->rs); if (render_target->vb) @@ -3672,8 +3696,6 @@ err: } if (render_target->stateblock) render_target->stateblock->lpVtbl->Release(render_target->stateblock); - if (render_target->view) - ID3D10RenderTargetView_Release(render_target->view); if (render_target->d3d_device) ID3D10Device_Release(render_target->d3d_device); ID2D1Device_Release(render_target->device); @@ -3684,19 +3706,55 @@ err: HRESULT d2d_d3d_create_render_target(ID2D1Device *device, IDXGISurface *surface, IUnknown *outer_unknown, const struct d2d_device_context_ops *ops, const D2D1_RENDER_TARGET_PROPERTIES *desc, void **render_target) { + D2D1_BITMAP_PROPERTIES1 bitmap_desc; struct d2d_device_context *object; + ID2D1Bitmap1 *bitmap; HRESULT hr;
+ if (desc->type != D2D1_RENDER_TARGET_TYPE_DEFAULT && desc->type != D2D1_RENDER_TARGET_TYPE_HARDWARE) + WARN("Ignoring render target type %#x.\n", desc->type); + if (desc->usage != D2D1_RENDER_TARGET_USAGE_NONE) + FIXME("Ignoring render target usage %#x.\n", desc->usage); + if (desc->minLevel != D2D1_FEATURE_LEVEL_DEFAULT) + WARN("Ignoring feature level %#x.\n", desc->minLevel); + + bitmap_desc.dpiX = desc->dpiX; + bitmap_desc.dpiY = desc->dpiY; + + if (bitmap_desc.dpiX == 0.0f && bitmap_desc.dpiY == 0.0f) + { + bitmap_desc.dpiX = 96.0f; + bitmap_desc.dpiY = 96.0f; + } + else if (bitmap_desc.dpiX <= 0.0f || bitmap_desc.dpiY <= 0.0f) + return E_INVALIDARG; + if (!(object = heap_alloc_zero(sizeof(*object)))) return E_OUTOFMEMORY;
- if (FAILED(hr = d2d_device_context_init(object, device, surface, outer_unknown, ops, desc))) + if (FAILED(hr = d2d_device_context_init(object, device, outer_unknown, ops))) { WARN("Failed to initialize render target, hr %#x.\n", hr); heap_free(object); return hr; }
+ bitmap_desc.pixelFormat = desc->pixelFormat; + bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW; + bitmap_desc.colorContext = NULL; + + if (FAILED(hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(&object->ID2D1DeviceContext_iface, surface, + &bitmap_desc, &bitmap))) + { + WARN("Failed to create target bitmap, hr %#x.\n", hr); + ID2D1DeviceContext_Release(&object->ID2D1DeviceContext_iface); + heap_free(object); + return hr; + } + + ID2D1DeviceContext_SetTarget(&object->ID2D1DeviceContext_iface, (ID2D1Image *)bitmap); + ID2D1Bitmap1_Release(bitmap); + TRACE("Created render target %p.\n", object); *render_target = outer_unknown ? &object->IUnknown_iface : (IUnknown *)&object->ID2D1DeviceContext_iface;
@@ -3713,8 +3771,9 @@ HRESULT d2d_d3d_render_target_create_rtv(ID2D1RenderTarget *iface, IDXGISurface1
if (!surface) { - ID3D10RenderTargetView_Release(render_target->view); - render_target->view = NULL; + if (render_target->target.u.bitmap.view) + ID3D10RenderTargetView_Release(render_target->target.u.bitmap.view); + render_target->target.u.bitmap.view = NULL; return S_OK; }
@@ -3740,9 +3799,9 @@ HRESULT d2d_d3d_render_target_create_rtv(ID2D1RenderTarget *iface, IDXGISurface1
render_target->pixel_size.width = surface_desc.Width; render_target->pixel_size.height = surface_desc.Height; - if (render_target->view) - ID3D10RenderTargetView_Release(render_target->view); - render_target->view = view; + if (render_target->target.u.bitmap.view) + ID3D10RenderTargetView_Release(render_target->target.u.bitmap.view); + render_target->target.u.bitmap.view = view;
return S_OK; } @@ -3853,6 +3912,14 @@ static const struct ID2D1DeviceVtbl d2d_device_vtbl = d2d_device_ClearResources, };
+static struct d2d_device *unsafe_impl_from_ID2D1Device(ID2D1Device *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d2d_device_vtbl); + return CONTAINING_RECORD(iface, struct d2d_device, ID2D1Device_iface); +} + void d2d_device_init(struct d2d_device *device, ID2D1Factory1 *iface, IDXGIDevice *dxgi_device) { device->ID2D1Device_iface.lpVtbl = &d2d_device_vtbl; diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 3005b43e44..c2e0ab2a08 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -6943,14 +6943,11 @@ static void test_bitmap_surface(void)
bitmap = NULL; ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap); -todo_wine ok(!!bitmap, "Unexpected target.\n");
-if (bitmap) -{ check_bitmap_surface((ID2D1Bitmap *)bitmap, TRUE, D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW); ID2D1Bitmap1_Release(bitmap); -} + check_rt_bitmap_surface(rt, TRUE, D2D1_BITMAP_OPTIONS_NONE);
ID2D1DeviceContext_Release(device_context);
On 26 September 2018 at 04:04, Nikolay Sivov nsivov@codeweavers.com wrote:
@@ -136,7 +136,6 @@ struct d2d_device_context ID2D1Factory *factory; ID2D1Device *device; ID3D10Device *d3d_device;
- ID3D10RenderTargetView *view; ID3D10StateBlock *stateblock; struct d2d_shape_resources shape_resources[D2D_SHAPE_TYPE_COUNT]; ID3D10PixelShader *ps;
@@ -146,6 +145,19 @@ struct d2d_device_context ID3D10RasterizerState *rs; ID3D10BlendState *bs;
- struct
- {
union
{
ID2D1Image *image;
struct
{
ID2D1Bitmap *bitmap;
ID3D10RenderTargetView *view;
} bitmap;
} u;
- } target;
I don't think you need a separate view field if you have a bitmap. I think the rendertarget view should be stored in the d2d_bitmap structure. I.e., the same way the shader resource view is part of that structure.
I also don't think you need that union in this patch. Depending on where we go with this in the future we may want it at some later point, but I think that's a separate change from implementing SetTarget() for bitmap targets.
I.e., for this patch, I think just replacing "ID3D10RenderTargetView *view;" with "struct d2d_bitmap *target;" should be enough.
On 26 September 2018 at 21:18, Henri Verbeet hverbeet@gmail.com wrote:
I don't think you need a separate view field if you have a bitmap. I think the rendertarget view should be stored in the d2d_bitmap structure. I.e., the same way the shader resource view is part of that structure.
Actually, related to that, I imagine SetTarget() should check that the bitmap has D2D1_BITMAP_OPTIONS_TARGET.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/device.c | 23 +++++++++++++++++++++-- dlls/d2d1/tests/d2d1.c | 16 +++++++--------- 2 files changed, 28 insertions(+), 11 deletions(-)
diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c index 212e9c0df9..b1b719e2eb 100644 --- a/dlls/d2d1/device.c +++ b/dlls/d2d1/device.c @@ -3865,9 +3865,28 @@ static void WINAPI d2d_device_GetFactory(ID2D1Device *iface, ID2D1Factory **fact static HRESULT WINAPI d2d_device_CreateDeviceContext(ID2D1Device *iface, D2D1_DEVICE_CONTEXT_OPTIONS options, ID2D1DeviceContext **context) { - FIXME("iface %p, options %#x, context %p stub!\n", iface, options, context); + struct d2d_device_context *object; + HRESULT hr;
- return E_NOTIMPL; + TRACE("iface %p, options %#x, context %p.\n", iface, options, context); + + if (options) + FIXME("Options are ignored %#x.\n", options); + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = d2d_device_context_init(object, iface, NULL, NULL))) + { + WARN("Failed to initialize device context, hr %#x.\n", hr); + heap_free(object); + return hr; + } + + TRACE("Created device context %p.\n", object); + *context = &object->ID2D1DeviceContext_iface; + + return S_OK; }
static HRESULT WINAPI d2d_device_CreatePrintControl(ID2D1Device *iface, IWICImagingFactory *wic_factory, diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index c2e0ab2a08..e6320e51b0 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -6962,11 +6962,8 @@ static void test_bitmap_surface(void) ok(SUCCEEDED(hr), "Failed to get ID2D1Device, hr %#x.\n", hr);
hr = ID2D1Device_CreateDeviceContext(device, D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &device_context); -todo_wine ok(SUCCEEDED(hr), "Failed to create device context, hr %#x.\n", hr);
-if (SUCCEEDED(hr)) -{ for (i = 0; i < ARRAY_SIZE(bitmap_format_tests); ++i) { D2D1_PIXEL_FORMAT pixel_format; @@ -6976,9 +6973,10 @@ if (SUCCEEDED(hr)) bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW;
hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(device_context, surface, &bitmap_desc, &bitmap); + todo_wine_if(FAILED(bitmap_format_tests[i].hr)) ok(hr == bitmap_format_tests[i].hr, "%u: unexpected hr %#x.\n", i, hr);
- if (SUCCEEDED(hr)) + if (SUCCEEDED(bitmap_format_tests[i].hr)) { pixel_format = ID2D1Bitmap1_GetPixelFormat(bitmap);
@@ -7005,7 +7003,7 @@ if (SUCCEEDED(hr))
ID2D1DeviceContext_Release(device_context); ID2D1Bitmap1_Release(bitmap); -} + ID2D1Device_Release(device); IDXGIDevice_Release(dxgi_device); IDXGISurface_Release(surface); @@ -7108,11 +7106,8 @@ static void test_device_context(void) IDXGIDevice_Release(dxgi_device);
hr = ID2D1Device_CreateDeviceContext(device, D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &device_context); -todo_wine ok(SUCCEEDED(hr), "Failed to create device context, hr %#x.\n", hr);
-if (SUCCEEDED(hr)) -{ ID2D1DeviceContext_GetDevice(device_context, &device2); ok(device2 == device, "Unexpected device instance.\n"); ID2D1Device_Release(device2); @@ -7190,6 +7185,7 @@ if (SUCCEEDED(hr)) ok(options == (D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW), "Unexpected bitmap options %#x.\n", options); hr = ID2D1Bitmap1_GetSurface(bitmap, &surface); +todo_wine ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr); ID2D1Bitmap1_Release(bitmap);
@@ -7238,6 +7234,7 @@ if (SUCCEEDED(hr)) hr = ID2D1DCRenderTarget_QueryInterface(dc_rt, &IID_ID2D1DeviceContext, (void **)&device_context); ok(SUCCEEDED(hr), "Failed to get device context interface, hr %#x.\n", hr); ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap); +todo_wine ok(bitmap == NULL, "Unexpected bitmap instance.\n");
hdc = CreateCompatibleDC(NULL); @@ -7251,6 +7248,7 @@ if (SUCCEEDED(hr))
ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap); options = ID2D1Bitmap1_GetOptions(bitmap); +todo_wine ok(options == (D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW | D2D1_BITMAP_OPTIONS_GDI_COMPATIBLE), "Unexpected bitmap options %#x.\n", options); hr = ID2D1Bitmap1_GetSurface(bitmap, &surface); @@ -7264,7 +7262,7 @@ if (SUCCEEDED(hr)) ID2D1DeviceContext_Release(device_context); ID2D1DCRenderTarget_Release(dc_rt); DeleteDC(hdc); -} + ID2D1Device_Release(device); ID2D1Factory1_Release(factory); ID3D10Device1_Release(d3d_device);
On 26 September 2018 at 04:04, Nikolay Sivov nsivov@codeweavers.com wrote:
+void d2d_effect_init(struct d2d_effect *effect) +{
- effect->ID2D1Effect_iface.lpVtbl = &d2d_effect_vtbl;
- effect->refcount = 1;
+}
--
That's a whitespace error, but I think Alexandre's scripts will fix that up automatically.