From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/bitmap.c | 31 ++++++++- dlls/d2d1/d2d1_private.h | 7 ++ dlls/d2d1/tests/d2d1.c | 136 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+), 2 deletions(-)
diff --git a/dlls/d2d1/bitmap.c b/dlls/d2d1/bitmap.c index e5048611519..e07987ae5fa 100644 --- a/dlls/d2d1/bitmap.c +++ b/dlls/d2d1/bitmap.c @@ -184,9 +184,36 @@ static HRESULT STDMETHODCALLTYPE d2d_bitmap_CopyFromBitmap(ID2D1Bitmap1 *iface, static HRESULT STDMETHODCALLTYPE d2d_bitmap_CopyFromRenderTarget(ID2D1Bitmap1 *iface, const D2D1_POINT_2U *dst_point, ID2D1RenderTarget *render_target, const D2D1_RECT_U *src_rect) { - FIXME("iface %p, dst_point %p, render_target %p, src_rect %p stub!\n", iface, dst_point, render_target, src_rect); + ID2D1DeviceContext *device_context; + ID2D1Bitmap *target_bitmap = NULL; + ID2D1Image *target = NULL; + HRESULT hr; + + TRACE("iface %p, dst_point %p, render_target %p, src_rect %s.\n", iface, dst_point, + render_target, debug_d2d_rect_u(src_rect)); + + if (FAILED(hr = ID2D1RenderTarget_QueryInterface(render_target, &IID_ID2D1DeviceContext, + (void **)&device_context))) + { + return hr; + } + + ID2D1DeviceContext_GetTarget(device_context, &target); + ID2D1DeviceContext_Release(device_context);
- return E_NOTIMPL; + if (target) + { + ID2D1Image_QueryInterface(target, &IID_ID2D1Bitmap, (void **)&target_bitmap); + ID2D1Image_Release(target); + } + + if (!target_bitmap) + return D2DERR_RECREATE_TARGET; + + hr = ID2D1Bitmap1_CopyFromBitmap(iface, dst_point, target_bitmap, src_rect); + ID2D1Bitmap_Release(target_bitmap); + + return hr; }
static HRESULT STDMETHODCALLTYPE d2d_bitmap_CopyFromMemory(ID2D1Bitmap1 *iface, diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index e99dc165bac..473ca763374 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -1051,6 +1051,13 @@ static inline const char *debug_d2d_rect_l(const D2D1_RECT_L *rect) return wine_dbg_sprintf("(%ld, %ld)-(%ld, %ld)", rect->left, rect->top, rect->right, rect->bottom); }
+static inline const char *debug_d2d_rect_u(const D2D1_RECT_U *rect) +{ + if (!rect) + return "(null)"; + return wine_dbg_sprintf("(%u, %u)-(%u, %u)", rect->left, rect->top, rect->right, rect->bottom); +} + static inline const char *debug_d2d_rounded_rect(const D2D1_ROUNDED_RECT *rounded_rect) { if (!rounded_rect) diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 24829994e16..6c92fa1b81a 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -5521,6 +5521,141 @@ static void test_bitmap_updates(BOOL d3d11) ID2D1Bitmap_Release(dst_bitmap);
ID2D1Bitmap_Release(bitmap); + + release_test_context(&ctx); +} + +static void test_bitmap_copy_from_render_target(BOOL d3d11) +{ + D2D1_BITMAP_PROPERTIES bitmap_desc; + D2D1_PIXEL_FORMAT pixel_format; + struct d2d1_test_context ctx; + struct resource_readback rb; + ID2D1RenderTarget *rt; + ID2D1Bitmap *bitmap; + D2D1_COLOR_F color; + D2D1_RECT_F rect; + D2D1_SIZE_U size; + DWORD colour; + HRESULT hr; + + static const DWORD bitmap_data[] = + { + 0xffff0000, 0xffffff00, 0xff00ff00, 0xff00ffff, + 0xff0000ff, 0xffff00ff, 0xff000000, 0xff7f7f7f, + 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + }; + + if (!init_test_context(&ctx, d3d11)) + return; + + rt = ctx.rt; + pixel_format = ID2D1RenderTarget_GetPixelFormat(rt); + + set_size_u(&size, 4, 4); + bitmap_desc.pixelFormat = pixel_format; + bitmap_desc.dpiX = 96.0f; + bitmap_desc.dpiY = 96.0f; + hr = ID2D1RenderTarget_CreateBitmap(rt, size, NULL, 0, &bitmap_desc, &bitmap); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = ID2D1Bitmap_CopyFromMemory(bitmap, NULL, bitmap_data, 4 * sizeof(*bitmap_data)); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + ID2D1RenderTarget_BeginDraw(rt); + set_color(&color, 0.0f, 0.0f, 1.0f, 1.0f); + ID2D1RenderTarget_Clear(rt, &color); + set_rect(&rect, 0.0f, 0.0f, 4.0f, 4.0f); + ID2D1RenderTarget_DrawBitmap(rt, bitmap, &rect, 1.0f, + D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, NULL); + hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + get_surface_readback(&ctx, &rb); + colour = get_readback_colour(&rb, 0, 0); + ok(compare_colour(colour, 0xffff0000, 1), "Got unexpected colour 0x%08lx.\n", colour); + release_resource_readback(&rb); + + ID2D1RenderTarget_BeginDraw(rt); + set_color(&color, 1.0f, 0.0f, 1.0f, 1.0f); + ID2D1RenderTarget_Clear(rt, &color); + hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = ID2D1Bitmap_CopyFromRenderTarget(bitmap, NULL, rt, NULL); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + ID2D1RenderTarget_BeginDraw(rt); + set_color(&color, 0.0f, 0.0f, 1.0f, 1.0f); + ID2D1RenderTarget_Clear(rt, &color); + set_rect(&rect, 0.0f, 0.0f, 4.0f, 4.0f); + ID2D1RenderTarget_DrawBitmap(rt, bitmap, &rect, 1.0f, + D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, NULL); + hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + get_surface_readback(&ctx, &rb); + colour = get_readback_colour(&rb, 0, 0); + ok(compare_colour(colour, 0xffff00ff, 1), "Got unexpected colour 0x%08lx.\n", colour); + release_resource_readback(&rb); + + /* Render target without target bitmap. */ + if (ctx.factory1) + { + ID2D1Bitmap1 *bitmap_target, *bitmap2; + D2D1_BITMAP_PROPERTIES1 bitmap_desc1; + ID2D1DeviceContext *device_context; + ID2D1CommandList *command_list; + ID2D1Device *device; + D2D1_SIZE_U size; + + hr = ID2D1Factory1_CreateDevice(ctx.factory1, ctx.device, &device); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = ID2D1Device_CreateDeviceContext(device, D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &device_context); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = ID2D1Bitmap_CopyFromRenderTarget(bitmap, NULL, (ID2D1RenderTarget *)device_context, NULL); + ok(hr == D2DERR_RECREATE_TARGET, "Got unexpected hr %#lx.\n", hr); + + hr = ID2D1DeviceContext_CreateCommandList(device_context, &command_list); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)command_list); + ID2D1CommandList_Release(command_list); + + hr = ID2D1Bitmap_CopyFromRenderTarget(bitmap, NULL, (ID2D1RenderTarget *)device_context, NULL); + ok(hr == D2DERR_RECREATE_TARGET, "Got unexpected hr %#lx.\n", hr); + + memset(&bitmap_desc1, 0, sizeof(bitmap_desc1)); + memcpy(&bitmap_desc1, &bitmap_desc, sizeof(bitmap_desc)); + bitmap_desc1.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET; + set_size_u(&size, 16, 16); + hr = ID2D1DeviceContext_CreateBitmap(device_context, size, NULL, 0, &bitmap_desc1, &bitmap_target); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap_target); + ID2D1Bitmap1_Release(bitmap_target); + + hr = ID2D1Bitmap_CopyFromRenderTarget(bitmap, NULL, (ID2D1RenderTarget *)device_context, NULL); + todo_wine + ok(hr == D2DERR_WRONG_RESOURCE_DOMAIN, "Got unexpected hr %#lx.\n", hr); + + hr = ID2D1DeviceContext_CreateBitmap(device_context, size, NULL, 0, &bitmap_desc1, &bitmap2); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = ID2D1Bitmap1_CopyFromRenderTarget(bitmap2, NULL, (ID2D1RenderTarget *)device_context, NULL); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + ID2D1Bitmap1_Release(bitmap2); + + ID2D1DeviceContext_Release(device_context); + ID2D1Device_Release(device); + } + + ID2D1Bitmap_Release(bitmap); + release_test_context(&ctx); }
@@ -16085,6 +16220,7 @@ START_TEST(d2d1) queue_test(test_alpha_mode); queue_test(test_shared_bitmap); queue_test(test_bitmap_updates); + queue_test(test_bitmap_copy_from_render_target); queue_test(test_opacity_brush); queue_test(test_create_target); queue_test(test_dxgi_surface_target_gdi_interop);
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/bitmap.c | 10 ++++++---- dlls/d2d1/d2d1_private.h | 7 +++++++ 2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/dlls/d2d1/bitmap.c b/dlls/d2d1/bitmap.c index e07987ae5fa..c6ab60c1bc4 100644 --- a/dlls/d2d1/bitmap.c +++ b/dlls/d2d1/bitmap.c @@ -158,7 +158,8 @@ static HRESULT STDMETHODCALLTYPE d2d_bitmap_CopyFromBitmap(ID2D1Bitmap1 *iface, ID3D11Device *device; D3D11_BOX box;
- TRACE("iface %p, dst_point %p, bitmap %p, src_rect %p.\n", iface, dst_point, bitmap, src_rect); + TRACE("iface %p, dst_point %s, bitmap %p, src_rect %s.\n", iface, + debug_d2d_point_2u(dst_point), bitmap, debug_d2d_rect_u(src_rect));
if (src_rect) { @@ -189,8 +190,8 @@ static HRESULT STDMETHODCALLTYPE d2d_bitmap_CopyFromRenderTarget(ID2D1Bitmap1 *i ID2D1Image *target = NULL; HRESULT hr;
- TRACE("iface %p, dst_point %p, render_target %p, src_rect %s.\n", iface, dst_point, - render_target, debug_d2d_rect_u(src_rect)); + TRACE("iface %p, dst_point %s, render_target %p, src_rect %s.\n", iface, + debug_d2d_point_2u(dst_point), render_target, debug_d2d_rect_u(src_rect));
if (FAILED(hr = ID2D1RenderTarget_QueryInterface(render_target, &IID_ID2D1DeviceContext, (void **)&device_context))) @@ -224,7 +225,8 @@ static HRESULT STDMETHODCALLTYPE d2d_bitmap_CopyFromMemory(ID2D1Bitmap1 *iface, ID3D11Device *device; D3D11_BOX box;
- TRACE("iface %p, dst_rect %p, src_data %p, pitch %u.\n", iface, dst_rect, src_data, pitch); + TRACE("iface %p, dst_rect %s, src_data %p, pitch %u.\n", iface, debug_d2d_rect_u(dst_rect), + src_data, pitch);
if (dst_rect) { diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 473ca763374..24116bbe41a 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -1037,6 +1037,13 @@ static inline const char *debug_d2d_point_2l(const D2D1_POINT_2L *point) return wine_dbg_sprintf("{%ld, %ld}", point->x, point->y); }
+static inline const char *debug_d2d_point_2u(const D2D1_POINT_2U *point) +{ + if (!point) + return "(null)"; + return wine_dbg_sprintf("{%u, %u}", point->x, point->y); +} + static inline const char *debug_d2d_rect_f(const D2D1_RECT_F *rect) { if (!rect)