d2d1: Fix compatible target initialization.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2018-09-24 07:58:29 +03:00 committed by Alexandre Julliard
parent 23ad7f6a8b
commit dc67508338
3 changed files with 73 additions and 6 deletions

View file

@ -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);

View file

@ -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;

View file

@ -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)))
{
/* Compatible target follows its parent. */
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)
{
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);