From: Nikolay Sivov Subject: [PATCH 1/3] d2d1: Fix compatible target initialization. Message-Id: <20180924045831.32271-1-nsivov@codeweavers.com> Date: Mon, 24 Sep 2018 07:58:29 +0300 Signed-off-by: Nikolay Sivov --- dlls/d2d1/bitmap_render_target.c | 8 +++- dlls/d2d1/device.c | 4 +- dlls/d2d1/tests/d2d1.c | 67 ++++++++++++++++++++++++++++++-- 3 files changed, 73 insertions(+), 6 deletions(-) diff --git a/dlls/d2d1/bitmap_render_target.c b/dlls/d2d1/bitmap_render_target.c index 57f5b23b51..6cea50972f 100644 --- a/dlls/d2d1/bitmap_render_target.c +++ b/dlls/d2d1/bitmap_render_target.c @@ -722,6 +722,11 @@ static const struct ID2D1BitmapRenderTargetVtbl d2d_bitmap_render_target_vtbl = d2d_bitmap_render_target_GetBitmap }; +static const struct d2d_device_context_ops d2d_bitmap_render_target_ops = +{ + NULL, +}; + HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_target, const struct d2d_device_context *parent_target, const D2D1_SIZE_F *size, const D2D1_SIZE_U *pixel_size, const D2D1_PIXEL_FORMAT *pixel_format, @@ -805,7 +810,8 @@ HRESULT d2d_bitmap_render_target_init(struct d2d_bitmap_render_target *render_ta } if (FAILED(hr = d2d_d3d_create_render_target(parent_target->factory, dxgi_surface, - (IUnknown *)&render_target->ID2D1BitmapRenderTarget_iface, NULL, + (IUnknown *)&render_target->ID2D1BitmapRenderTarget_iface, + parent_target->ops ? &d2d_bitmap_render_target_ops : NULL, &dxgi_rt_desc, (void **)&render_target->dxgi_inner))) { WARN("Failed to create DXGI surface render target, hr %#x.\n", hr); diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c index d20377b5c2..f1d0dad45e 100644 --- a/dlls/d2d1/device.c +++ b/dlls/d2d1/device.c @@ -1515,7 +1515,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_Flush(ID2D1DeviceContext *if FIXME("iface %p, tag1 %p, tag2 %p stub!\n", iface, tag1, tag2); - if (context->ops) + if (context->ops && context->ops->device_context_present) context->ops->device_context_present(context->outer_unknown); return E_NOTIMPL; @@ -1693,7 +1693,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_EndDraw(ID2D1DeviceContext * if (tag2) *tag2 = context->error.tag2; - if (context->ops) + if (context->ops && context->ops->device_context_present) { if (FAILED(hr = context->ops->device_context_present(context->outer_unknown))) context->error.code = hr; diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 4136b69885..9e6ce06543 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -6705,8 +6705,10 @@ static void check_rt_bitmap_surface_(unsigned int line, ID2D1RenderTarget *rt, B ID2D1RenderTarget *compatible_rt; IWICImagingFactory *wic_factory; ID2D1DeviceContext *context; + ID2D1DCRenderTarget *dc_rt; IWICBitmap *wic_bitmap; ID2D1Bitmap *bitmap; + ID2D1Image *target; D2D1_SIZE_U size; HRESULT hr; @@ -6749,13 +6751,37 @@ static void check_rt_bitmap_surface_(unsigned int line, ID2D1RenderTarget *rt, B CoUninitialize(); - if (FAILED(ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&context))) + /* Compatible target follows its parent. */ + hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&context); + ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get device context, hr %#x.\n", hr); + + dc_rt = NULL; + ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DCRenderTarget, (void **)&dc_rt); + + bitmap = NULL; + target = NULL; + ID2D1DeviceContext_GetTarget(context, &target); + if (target && FAILED(ID2D1Image_QueryInterface(target, &IID_ID2D1Bitmap, (void **)&bitmap))) + { + ID2D1Image_Release(target); + target = NULL; + } + if (bitmap) + ID2D1Bitmap_Release(bitmap); + + /* Pixel format is not defined until target is set, for DC target it's specified on creation. */ + if (target || dc_rt) { - /* Compatible target follows its parent. */ + ID2D1DeviceContext *context2; + hr = ID2D1RenderTarget_CreateCompatibleRenderTarget(rt, NULL, NULL, NULL, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, (ID2D1BitmapRenderTarget **)&compatible_rt); ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create compatible render target, hr %#x.\n", hr); + hr = ID2D1RenderTarget_QueryInterface(compatible_rt, &IID_ID2D1DeviceContext, (void **)&context2); + ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get device context, hr %#x.\n", hr); + ID2D1DeviceContext_Release(context2); + hr = ID2D1RenderTarget_CreateBitmap(compatible_rt, size, bitmap_data, sizeof(*bitmap_data), &bitmap_desc, &bitmap); ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr); @@ -6765,7 +6791,18 @@ static void check_rt_bitmap_surface_(unsigned int line, ID2D1RenderTarget *rt, B ID2D1Bitmap_Release(bitmap); } else - ID2D1DeviceContext_Release(context); + { + 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); + } + + ID2D1DeviceContext_Release(context); + if (target) + ID2D1Image_Release(target); + if (dc_rt) + ID2D1DCRenderTarget_Release(dc_rt); } static void test_bitmap_surface(void) @@ -6782,6 +6819,7 @@ static void test_bitmap_surface(void) IDXGISurface *surface; ID2D1Bitmap1 *bitmap; ID2D1Device *device; + ID2D1Image *target; HWND window; HRESULT hr; @@ -6809,7 +6847,23 @@ static void test_bitmap_surface(void) rt = create_render_target(surface); ok(!!rt, "Failed to create render target.\n"); + hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&device_context); + ok(SUCCEEDED(hr), "Failed to get device context, hr %#x.\n", hr); + + 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); + ID2D1RenderTarget_Release(rt); /* Bitmap created from DXGI surface. */ @@ -6836,7 +6890,14 @@ if (SUCCEEDED(hr)) check_bitmap_surface((ID2D1Bitmap *)bitmap, TRUE, D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW); check_rt_bitmap_surface((ID2D1RenderTarget *)device_context, TRUE, D2D1_BITMAP_OPTIONS_NONE); + ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap); + ID2D1DeviceContext_GetTarget(device_context, &target); + ok(target == (ID2D1Image *)bitmap, "Unexpected target.\n"); + + check_rt_bitmap_surface((ID2D1RenderTarget *)device_context, TRUE, D2D1_BITMAP_OPTIONS_NONE); + ID2D1DeviceContext_Release(device_context); + ID2D1Bitmap1_Release(bitmap); } ID2D1Device_Release(device); IDXGIDevice_Release(dxgi_device); -- 2.19.0