Commit ab70e9c4 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

d2d1: Validate bitmap options against surface description in CreateBitmapFromDxgiSurface().

parent a3273a58
......@@ -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;
}
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment