Nikolay Sivov : d2d1: Validate bitmap options against surface description in CreateBitmapFromDxgiSurface().
Alexandre Julliard
julliard at winehq.org
Tue May 31 15:58:00 CDT 2022
Module: wine
Branch: master
Commit: ab70e9c4f4f43e4af5728286aa72ae88f539f57e
URL: https://source.winehq.org/git/wine.git/?a=commit;h=ab70e9c4f4f43e4af5728286aa72ae88f539f57e
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Mon May 30 12:52:17 2022 +0300
d2d1: Validate bitmap options against surface description in CreateBitmapFromDxgiSurface().
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/d2d1/device.c | 56 +++++++++++++++++++++++++++++++++++++++++--
dlls/d2d1/tests/d2d1.c | 65 ++++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 109 insertions(+), 12 deletions(-)
diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c
index b7faf33e266..12aa2acc331 100644
--- a/dlls/d2d1/device.c
+++ b/dlls/d2d1/device.c
@@ -1856,17 +1856,69 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateColorContextFromWicCol
return E_NOTIMPL;
}
+static BOOL d2d_bitmap_check_options_with_surface(unsigned int options, unsigned int surface_options)
+{
+ switch (options)
+ {
+ case D2D1_BITMAP_OPTIONS_NONE:
+ case D2D1_BITMAP_OPTIONS_TARGET:
+ case D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW:
+ case D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW | D2D1_BITMAP_OPTIONS_GDI_COMPATIBLE:
+ case D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_GDI_COMPATIBLE:
+ case D2D1_BITMAP_OPTIONS_CANNOT_DRAW | D2D1_BITMAP_OPTIONS_CPU_READ:
+ case D2D1_BITMAP_OPTIONS_CANNOT_DRAW:
+ break;
+ default:
+ WARN("Invalid bitmap options %#x.\n", options);
+ return FALSE;
+ }
+
+ if (options && (options & D2D1_BITMAP_OPTIONS_TARGET) != (surface_options & D2D1_BITMAP_OPTIONS_TARGET))
+ return FALSE;
+ if (options & D2D1_BITMAP_OPTIONS_TARGET)
+ {
+ if (!(options & D2D1_BITMAP_OPTIONS_CANNOT_DRAW) && (surface_options & D2D1_BITMAP_OPTIONS_CANNOT_DRAW))
+ return FALSE;
+ if (options & D2D1_BITMAP_OPTIONS_GDI_COMPATIBLE && !(surface_options & D2D1_BITMAP_OPTIONS_GDI_COMPATIBLE))
+ return FALSE;
+ return TRUE;
+ }
+
+ if (options & D2D1_BITMAP_OPTIONS_CANNOT_DRAW)
+ {
+ if (!(surface_options & D2D1_BITMAP_OPTIONS_CANNOT_DRAW))
+ return FALSE;
+
+ if (options & D2D1_BITMAP_OPTIONS_CPU_READ && !(surface_options & D2D1_BITMAP_OPTIONS_CPU_READ))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateBitmapFromDxgiSurface(ID2D1DeviceContext *iface,
IDXGISurface *surface, const D2D1_BITMAP_PROPERTIES1 *desc, ID2D1Bitmap1 **bitmap)
{
struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface);
D2D1_BITMAP_PROPERTIES1 bitmap_desc;
+ unsigned int surface_options;
struct d2d_bitmap *object;
HRESULT hr;
TRACE("iface %p, surface %p, desc %p, bitmap %p.\n", iface, surface, desc, bitmap);
- if (!desc)
+ surface_options = d2d_get_bitmap_options_for_surface(surface);
+
+ if (desc)
+ {
+ if (!d2d_bitmap_check_options_with_surface(desc->bitmapOptions, surface_options))
+ {
+ WARN("Incompatible bitmap options %#x, surface options %#x.\n",
+ desc->bitmapOptions, surface_options);
+ return E_INVALIDARG;
+ }
+ }
+ else
{
DXGI_SURFACE_DESC surface_desc;
@@ -1879,7 +1931,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateBitmapFromDxgiSurface(
memset(&bitmap_desc, 0, sizeof(bitmap_desc));
bitmap_desc.pixelFormat.format = surface_desc.Format;
bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
- bitmap_desc.bitmapOptions = d2d_get_bitmap_options_for_surface(surface);
+ bitmap_desc.bitmapOptions = surface_options;
desc = &bitmap_desc;
}
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c
index 5185c07c29b..c73039504d3 100644
--- a/dlls/d2d1/tests/d2d1.c
+++ b/dlls/d2d1/tests/d2d1.c
@@ -1213,6 +1213,24 @@ static BOOL init_test_context_(unsigned int line, struct d2d1_test_context *ctx,
return TRUE;
}
+#define check_bitmap_options(b, o) check_bitmap_options_(__LINE__, b, o)
+static void check_bitmap_options_(unsigned int line, ID2D1Bitmap *bitmap, DWORD expected_options)
+{
+ D2D1_BITMAP_OPTIONS options;
+ ID2D1Bitmap1 *bitmap1;
+ HRESULT hr;
+
+ hr = ID2D1Bitmap_QueryInterface(bitmap, &IID_ID2D1Bitmap1, (void **)&bitmap1);
+ if (FAILED(hr))
+ return;
+
+ options = ID2D1Bitmap1_GetOptions(bitmap1);
+ ok_(__FILE__, line)(options == expected_options, "Got unexpected bitmap options %#x, expected %#lx.\n",
+ options, expected_options);
+
+ ID2D1Bitmap1_Release(bitmap1);
+}
+
#define check_bitmap_surface(b, s, o) check_bitmap_surface_(__LINE__, b, s, o)
static void check_bitmap_surface_(unsigned int line, ID2D1Bitmap *bitmap, BOOL has_surface, DWORD expected_options)
{
@@ -11605,6 +11623,7 @@ static void test_bitmap_map(BOOL d3d11)
};
D2D1_BITMAP_PROPERTIES1 bitmap_desc;
D3D11_TEXTURE2D_DESC texture_desc;
+ ID2D1Bitmap *bitmap2, *bitmap3;
struct d2d1_test_context ctx;
D2D1_MAPPED_RECT mapped_rect;
ID3D11Device *d3d_device;
@@ -11612,7 +11631,6 @@ static void test_bitmap_map(BOOL d3d11)
unsigned int i, options;
IDXGISurface *surface;
ID2D1Bitmap1 *bitmap;
- ID2D1Bitmap *bitmap2;
D2D1_SIZE_U size;
HRESULT hr;
@@ -11768,14 +11786,13 @@ static void test_bitmap_map(BOOL d3d11)
hr = ID2D1DeviceContext_CreateSharedBitmap(ctx.context, &IID_IDXGISurface, surface,
(const D2D1_BITMAP_PROPERTIES *)&bitmap_desc, &bitmap2);
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ check_bitmap_options(bitmap2, D2D1_BITMAP_OPTIONS_CANNOT_DRAW | D2D1_BITMAP_OPTIONS_CPU_READ);
- hr = ID2D1Bitmap_QueryInterface(bitmap2, &IID_ID2D1Bitmap1, (void **)&bitmap);
+ hr = ID2D1DeviceContext_CreateSharedBitmap(ctx.context, &IID_ID2D1Bitmap, bitmap2, NULL, &bitmap3);
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
- options = ID2D1Bitmap1_GetOptions(bitmap);
- ok(options == (D2D1_BITMAP_OPTIONS_CANNOT_DRAW | D2D1_BITMAP_OPTIONS_CPU_READ),
- "Unexpected options %#x.\n", options);
+ check_bitmap_options(bitmap3, D2D1_BITMAP_OPTIONS_CANNOT_DRAW | D2D1_BITMAP_OPTIONS_CPU_READ);
+ ID2D1Bitmap_Release(bitmap3);
- ID2D1Bitmap1_Release(bitmap);
ID2D1Bitmap_Release(bitmap2);
hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(ctx.context, surface, NULL, &bitmap);
@@ -11788,9 +11805,7 @@ static void test_bitmap_map(BOOL d3d11)
/* Options incompatible with the surface. */
bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET;
hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(ctx.context, surface, &bitmap_desc, &bitmap);
- todo_wine
ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
- if (SUCCEEDED(hr)) ID2D1Bitmap1_Release(bitmap);
bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_NONE;
hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(ctx.context, surface, &bitmap_desc, &bitmap);
todo_wine
@@ -11798,9 +11813,7 @@ static void test_bitmap_map(BOOL d3d11)
if (SUCCEEDED(hr)) ID2D1Bitmap1_Release(bitmap);
bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW;
hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(ctx.context, surface, &bitmap_desc, &bitmap);
- todo_wine
ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
- if (SUCCEEDED(hr)) ID2D1Bitmap1_Release(bitmap);
/* Create without D2D1_BITMAP_OPTIONS_CPU_READ, surface supports CPU reads. */
bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_CANNOT_DRAW;
@@ -11813,6 +11826,38 @@ static void test_bitmap_map(BOOL d3d11)
ID3D11Texture2D_Release(texture);
IDXGISurface_Release(surface);
+ /* Surface D2D1_BITMAP_OPTIONS_TARGET */
+ texture_desc.Width = 4;
+ texture_desc.Height = 4;
+ texture_desc.MipLevels = 1;
+ texture_desc.ArraySize = 1;
+ texture_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+ texture_desc.SampleDesc.Count = 1;
+ texture_desc.SampleDesc.Quality = 0;
+ texture_desc.Usage = D3D11_USAGE_DEFAULT;
+ texture_desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
+ texture_desc.CPUAccessFlags = 0;
+ texture_desc.MiscFlags = 0;
+
+ hr = ID3D11Device_CreateTexture2D(d3d_device, &texture_desc, NULL, &texture);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ hr = ID3D11Texture2D_QueryInterface(texture, &IID_IDXGISurface, (void **)&surface);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+
+ bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_CANNOT_DRAW | D2D1_BITMAP_OPTIONS_TARGET;
+ hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(ctx.context, surface, &bitmap_desc, &bitmap);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ ID2D1Bitmap1_Release(bitmap);
+
+ bitmap_desc.bitmapOptions = 0;
+ hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(ctx.context, surface, &bitmap_desc, &bitmap);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ check_bitmap_options((ID2D1Bitmap *)bitmap, 0);
+ ID2D1Bitmap1_Release(bitmap);
+
+ ID3D11Texture2D_Release(texture);
+ IDXGISurface_Release(surface);
+
ID3D11Device_Release(d3d_device);
release_test_context(&ctx);
More information about the wine-cvs
mailing list