From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/tests/d2d1.c | 80 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 14a986b019c..1082d724534 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -15599,6 +15599,50 @@ static void test_compute_geometry_area(BOOL d3d11) release_test_context(&ctx); }
+static D2D1_PIXEL_FORMAT get_wic_target_format(const D2D1_PIXEL_FORMAT *target_format, + const GUID *bitmap_format) +{ + D2D1_PIXEL_FORMAT format; + + format = *target_format; + if (target_format->format == DXGI_FORMAT_UNKNOWN) + { + if (IsEqualGUID(bitmap_format, &GUID_WICPixelFormat32bppPBGRA) + || IsEqualGUID(bitmap_format, &GUID_WICPixelFormat32bppBGR)) + { + format.format = DXGI_FORMAT_B8G8R8A8_UNORM; + } + else if (IsEqualGUID(bitmap_format, &GUID_WICPixelFormat32bppPRGBA) + || IsEqualGUID(bitmap_format, &GUID_WICPixelFormat32bppRGB)) + { + format.format = DXGI_FORMAT_R8G8B8A8_UNORM; + } + else + { + ok(0, "Unexpected format %s.\n", debugstr_guid(bitmap_format)); + } + } + if (target_format->alphaMode == D2D1_ALPHA_MODE_UNKNOWN) + { + if (IsEqualGUID(bitmap_format, &GUID_WICPixelFormat32bppPBGRA) + || IsEqualGUID(bitmap_format, &GUID_WICPixelFormat32bppPRGBA)) + { + format.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + } + else if (IsEqualGUID(bitmap_format, &GUID_WICPixelFormat32bppBGR) + || IsEqualGUID(bitmap_format, &GUID_WICPixelFormat32bppRGB)) + { + format.alphaMode = D2D1_ALPHA_MODE_IGNORE; + } + else + { + ok(0, "Unexpected format %s.\n", debugstr_guid(bitmap_format)); + } + } + + return format; +} + static void test_wic_target_format(BOOL d3d11) { static const struct @@ -15659,11 +15703,16 @@ static void test_wic_target_format(BOOL d3d11) { { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE }, &GUID_WICPixelFormat32bppPBGRA, E_INVALIDARG }, }; + D2D1_PIXEL_FORMAT pixel_format, expected_pixel_format; D2D1_RENDER_TARGET_PROPERTIES rt_desc; + ID2D1DeviceContext *device_context; IWICImagingFactory *wic_factory; struct d2d1_test_context ctx; IWICBitmap *wic_bitmap; ID2D1RenderTarget *rt; + ID2D1Bitmap *bitmap; + ID2D1Image *image; + D2D1_SIZE_U size; unsigned int i; HRESULT hr;
@@ -15679,7 +15728,7 @@ static void test_wic_target_format(BOOL d3d11) { winetest_push_context("Test %u", i);
- hr = IWICImagingFactory_CreateBitmap(wic_factory, 16, 16, + hr = IWICImagingFactory_CreateBitmap(wic_factory, 24, 16, wic_target_formats[i].wic_format, WICBitmapCacheOnDemand, &wic_bitmap); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
@@ -15693,6 +15742,35 @@ static void test_wic_target_format(BOOL d3d11) todo_wine_if(FAILED(wic_target_formats[i].hr)) ok(hr == wic_target_formats[i].hr, "Got unexpected hr %#lx.\n", hr);
+ if (hr == S_OK && hr == wic_target_formats[i].hr && ctx.context) + { + hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&device_context); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + ID2D1DeviceContext_GetTarget(device_context, &image); + hr = ID2D1Image_QueryInterface(image, &IID_ID2D1Bitmap, (void **)&bitmap); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + size = ID2D1Bitmap_GetPixelSize(bitmap); + ok(size.width == 24 && size.height == 16, "Unexpected target size %ux%u.\n", + size.width, size.height); + + expected_pixel_format = get_wic_target_format(&wic_target_formats[i].pixel_format, + wic_target_formats[i].wic_format); + + pixel_format = ID2D1Bitmap_GetPixelFormat(bitmap); + ok(pixel_format.format == expected_pixel_format.format, "Unexpected pixel format %#x.\n", + pixel_format.format); + todo_wine_if(wic_target_formats[i].pixel_format.alphaMode == D2D1_ALPHA_MODE_UNKNOWN) + ok(pixel_format.alphaMode == expected_pixel_format.alphaMode, "Unexpected alpha mode %d.\n", + pixel_format.alphaMode); + + ID2D1Bitmap_Release(bitmap); + ID2D1Image_Release(image); + + ID2D1DeviceContext_Release(device_context); + } + IWICBitmap_Release(wic_bitmap);
if (SUCCEEDED(hr))
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/tests/d2d1.c | 1 - dlls/d2d1/wic_render_target.c | 80 ++++++++++++++++++++++------------- 2 files changed, 51 insertions(+), 30 deletions(-)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 1082d724534..7b897d1265b 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -15761,7 +15761,6 @@ static void test_wic_target_format(BOOL d3d11) pixel_format = ID2D1Bitmap_GetPixelFormat(bitmap); ok(pixel_format.format == expected_pixel_format.format, "Unexpected pixel format %#x.\n", pixel_format.format); - todo_wine_if(wic_target_formats[i].pixel_format.alphaMode == D2D1_ALPHA_MODE_UNKNOWN) ok(pixel_format.alphaMode == expected_pixel_format.alphaMode, "Unexpected alpha mode %d.\n", pixel_format.alphaMode);
diff --git a/dlls/d2d1/wic_render_target.c b/dlls/d2d1/wic_render_target.c index 970d4ceaec9..c0720e69a8a 100644 --- a/dlls/d2d1/wic_render_target.c +++ b/dlls/d2d1/wic_render_target.c @@ -149,10 +149,46 @@ static const struct d2d_device_context_ops d2d_wic_render_target_ops = d2d_wic_render_target_present, };
+static HRESULT d2d_wic_resolve_pixel_format(D2D1_PIXEL_FORMAT *pixel_format, + const WICPixelFormatGUID *wic_format) +{ + static const struct + { + const WICPixelFormatGUID *wic_format; + D2D1_PIXEL_FORMAT pixel_format; + } + formats[] = + { + { &GUID_WICPixelFormat32bppBGR, { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE } }, + { &GUID_WICPixelFormat32bppRGB, { DXGI_FORMAT_R8G8B8A8_UNORM, D2D1_ALPHA_MODE_IGNORE } }, + { &GUID_WICPixelFormat32bppPBGRA, { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED } }, + { &GUID_WICPixelFormat32bppPRGBA, { DXGI_FORMAT_R8G8B8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED } }, + }; + + if (pixel_format->format != DXGI_FORMAT_UNKNOWN && pixel_format->alphaMode != D2D1_ALPHA_MODE_UNKNOWN) + return S_OK; + + for (int i = 0; i < ARRAY_SIZE(formats); ++i) + { + if (IsEqualGUID(formats[i].wic_format, wic_format)) + { + if (pixel_format->format == DXGI_FORMAT_UNKNOWN) + pixel_format->format = formats[i].pixel_format.format; + if (pixel_format->alphaMode == D2D1_ALPHA_MODE_UNKNOWN) + pixel_format->alphaMode = formats[i].pixel_format.alphaMode; + return S_OK; + } + } + + return D2DERR_UNSUPPORTED_PIXEL_FORMAT; +} + HRESULT d2d_wic_render_target_init(struct d2d_wic_render_target *render_target, ID2D1Factory1 *factory, ID3D10Device1 *d3d_device, IWICBitmap *bitmap, const D2D1_RENDER_TARGET_PROPERTIES *desc) { + D2D1_RENDER_TARGET_PROPERTIES rt_desc; D3D10_TEXTURE2D_DESC texture_desc; + WICPixelFormatGUID bitmap_format; ID3D10Texture2D *texture; IDXGIDevice *dxgi_device; ID2D1Device *device; @@ -166,38 +202,24 @@ HRESULT d2d_wic_render_target_init(struct d2d_wic_render_target *render_target, return hr; }
+ if (FAILED(hr = IWICBitmap_GetPixelFormat(bitmap, &bitmap_format))) + { + WARN("Failed to get bitmap format, hr %#lx.\n", hr); + return hr; + } + + rt_desc = *desc; + if (FAILED(hr = d2d_wic_resolve_pixel_format(&rt_desc.pixelFormat, &bitmap_format))) + { + WARN("Unsupported WIC bitmap format %s.\n", debugstr_guid(&bitmap_format)); + return hr; + } + texture_desc.Width = render_target->width; texture_desc.Height = render_target->height; texture_desc.MipLevels = 1; texture_desc.ArraySize = 1; - - texture_desc.Format = desc->pixelFormat.format; - if (texture_desc.Format == DXGI_FORMAT_UNKNOWN) - { - WICPixelFormatGUID bitmap_format; - - if (FAILED(hr = IWICBitmap_GetPixelFormat(bitmap, &bitmap_format))) - { - WARN("Failed to get bitmap format, hr %#lx.\n", hr); - return hr; - } - - if (IsEqualGUID(&bitmap_format, &GUID_WICPixelFormat32bppPBGRA) - || IsEqualGUID(&bitmap_format, &GUID_WICPixelFormat32bppBGR)) - { - texture_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; - } - else if (IsEqualGUID(&bitmap_format, &GUID_WICPixelFormat32bppPRGBA) - || IsEqualGUID(&bitmap_format, &GUID_WICPixelFormat32bppRGB)) - { - texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - } - else - { - WARN("Unsupported WIC bitmap format %s.\n", debugstr_guid(&bitmap_format)); - return D2DERR_UNSUPPORTED_PIXEL_FORMAT; - } - } + texture_desc.Format = rt_desc.pixelFormat.format;
switch (texture_desc.Format) { @@ -263,7 +285,7 @@ HRESULT d2d_wic_render_target_init(struct d2d_wic_render_target *render_target,
hr = d2d_d3d_create_render_target(unsafe_impl_from_ID2D1Device((ID2D1Device1 *)device), render_target->dxgi_surface, &render_target->IUnknown_iface, - &d2d_wic_render_target_ops, desc, (void **)&render_target->dxgi_inner); + &d2d_wic_render_target_ops, &rt_desc, (void **)&render_target->dxgi_inner); ID2D1Device_Release(device); if (FAILED(hr)) {