Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/d2d1/tests/d2d1.c | 274 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 274 insertions(+)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c
index 3b824709f2..b7d3bfa09c 100644
--- a/dlls/d2d1/tests/d2d1.c
+++ b/dlls/d2d1/tests/d2d1.c
@@ -7652,6 +7652,279 @@ static void test_skew_matrix(void)
}
}
+static ID2D1DeviceContext *create_device_context(ID2D1Factory1 *factory, ID3D10Device1 *d3d_device)
+{
+ ID2D1DeviceContext *device_context;
+ IDXGIDevice *dxgi_device;
+ ID2D1Device *device;
+ HRESULT hr;
+
+ hr = ID3D10Device1_QueryInterface(d3d_device, &IID_IDXGIDevice, (void **)&dxgi_device);
+ ok(SUCCEEDED(hr), "Failed to get IDXGIDevice interface, hr %#x.\n", hr);
+
+ hr = ID2D1Factory1_CreateDevice(factory, dxgi_device, &device);
+ ok(SUCCEEDED(hr), "Failed to get ID2D1Device, hr %#x.\n", hr);
+ IDXGIDevice_Release(dxgi_device);
+
+ hr = ID2D1Device_CreateDeviceContext(device, D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &device_context);
+ ok(SUCCEEDED(hr), "Failed to create device context, hr %#x.\n", hr);
+ ID2D1Device_Release(device);
+
+ return device_context;
+}
+
+static void test_command_list(void)
+{
+ static const DWORD bitmap_data[] =
+ {
+ 0xffff0000, 0xffffff00, 0xff00ff00, 0xff00ffff,
+ };
+ static const D2D1_GRADIENT_STOP stops[] =
+ {
+ {0.0f, {1.0f, 0.0f, 0.0f, 1.0f}},
+ {0.5f, {0.0f, 1.0f, 0.0f, 1.0f}},
+ {1.0f, {0.0f, 0.0f, 1.0f, 1.0f}},
+ };
+ D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES radial_gradient_properties;
+ D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES linear_gradient_properties;
+ ID2D1DeviceContext *device_context, *device_context2;
+ D2D1_STROKE_STYLE_PROPERTIES stroke_desc;
+ ID2D1GradientStopCollection *gradient;
+ D2D1_BITMAP_PROPERTIES bitmap_desc;
+ ID2D1StrokeStyle *stroke_style;
+ ID2D1CommandList *command_list;
+ ID3D10Device1 *d3d_device;
+ ID2D1Geometry *geometry;
+ ID2D1Factory1 *factory;
+ ID2D1RenderTarget *rt;
+ D2D1_POINT_2F p0, p1;
+ ID2D1Bitmap *bitmap;
+ ID2D1Image *target;
+ D2D1_COLOR_F color;
+ ID2D1Brush *brush;
+ D2D1_RECT_F rect;
+ D2D_SIZE_U size;
+ ULONG refcount;
+ HRESULT hr;
+
+ if (!(d3d_device = create_device()))
+ {
+ skip("Failed to create device, skipping tests.\n");
+ return;
+ }
+
+ if (FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory1, NULL, (void **)&factory)))
+ {
+ win_skip("ID2D1Factory1 is not supported.\n");
+ ID3D10Device1_Release(d3d_device);
+ return;
+ }
+
+ device_context = create_device_context(factory, d3d_device);
+ ok(device_context != NULL, "Failed to create device context.\n");
+
+ hr = ID2D1DeviceContext_CreateCommandList(device_context, &command_list);
+todo_wine
+ ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr);
+
+ if (FAILED(hr))
+ {
+ ID2D1DeviceContext_Release(device_context);
+ ID2D1Factory1_Release(factory);
+ return;
+ }
+
+ ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)command_list);
+ ID2D1DeviceContext_BeginDraw(device_context);
+
+ hr = ID2D1DeviceContext_QueryInterface(device_context, &IID_ID2D1RenderTarget, (void **)&rt);
+ ok(SUCCEEDED(hr), "Failed to get rt interface, hr %#x.\n", hr);
+
+ /* Test how resources are referenced by the list. */
+
+ /* Bitmap. */
+ set_size_u(&size, 4, 1);
+ bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
+ bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
+ bitmap_desc.dpiX = 96.0f;
+ bitmap_desc.dpiY = 96.0f;
+ hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
+ ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
+
+ ID2D1RenderTarget_DrawBitmap(rt, bitmap, NULL, 0.25f, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, NULL);
+
+ refcount = ID2D1Bitmap_Release(bitmap);
+ ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
+
+ /* Solid color brush. */
+ set_color(&color, 0.0f, 0.0f, 0.0f, 0.0f);
+ hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, (ID2D1SolidColorBrush **)&brush);
+ ok(SUCCEEDED(hr), "Failed to create a brush, hr %#x.\n", hr);
+
+ set_rect(&rect, 0.0f, 0.0f, 16.0f, 16.0f);
+ ID2D1RenderTarget_FillRectangle(rt, &rect, brush);
+
+ refcount = ID2D1Brush_Release(brush);
+ ok(refcount == 0, "Got unexpected refcount %u.\n", refcount);
+
+ /* Bitmap brush. */
+ hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
+ ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
+
+ hr = ID2D1RenderTarget_CreateBitmapBrush(rt, bitmap, NULL, NULL, (ID2D1BitmapBrush **)&brush);
+ ok(SUCCEEDED(hr), "Failed to create bitmap brush, hr %#x.\n", hr);
+
+ set_rect(&rect, 0.0f, 0.0f, 16.0f, 16.0f);
+ ID2D1RenderTarget_FillRectangle(rt, &rect, brush);
+
+ refcount = ID2D1Brush_Release(brush);
+ ok(refcount == 0, "Got unexpected refcount %u.\n", refcount);
+
+ refcount = ID2D1Bitmap_Release(bitmap);
+ ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
+
+ /* Linear gradient brush. */
+ hr = ID2D1RenderTarget_CreateGradientStopCollection(rt, stops, ARRAY_SIZE(stops),
+ D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP, &gradient);
+ ok(SUCCEEDED(hr), "Failed to create stop collection, hr %#x.\n", hr);
+
+ set_point(&linear_gradient_properties.startPoint, 320.0f, 0.0f);
+ set_point(&linear_gradient_properties.endPoint, 0.0f, 960.0f);
+ hr = ID2D1RenderTarget_CreateLinearGradientBrush(rt, &linear_gradient_properties, NULL, gradient,
+ (ID2D1LinearGradientBrush **)&brush);
+ ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
+
+ set_rect(&rect, -1.0f, -1.0f, 1.0f, 1.0f);
+ hr = ID2D1Factory1_CreateRectangleGeometry(factory, &rect, (ID2D1RectangleGeometry **)&geometry);
+ ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
+
+ ID2D1RenderTarget_FillGeometry(rt, geometry, brush, NULL);
+
+ refcount = ID2D1Brush_Release(brush);
+ ok(refcount == 0, "Got unexpected refcount %u.\n", refcount);
+
+ refcount = ID2D1Geometry_Release(geometry);
+ ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
+
+ refcount = ID2D1GradientStopCollection_Release(gradient);
+ ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
+
+ /* Radial gradient brush. */
+ hr = ID2D1RenderTarget_CreateGradientStopCollection(rt, stops, ARRAY_SIZE(stops),
+ D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP, &gradient);
+ ok(SUCCEEDED(hr), "Failed to create stop collection, hr %#x.\n", hr);
+
+ set_point(&radial_gradient_properties.center, 160.0f, 480.0f);
+ set_point(&radial_gradient_properties.gradientOriginOffset, 40.0f, -120.0f);
+ radial_gradient_properties.radiusX = 160.0f;
+ radial_gradient_properties.radiusY = 480.0f;
+ hr = ID2D1RenderTarget_CreateRadialGradientBrush(rt, &radial_gradient_properties, NULL, gradient,
+ (ID2D1RadialGradientBrush **)&brush);
+ ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
+
+ set_rect(&rect, -1.0f, -1.0f, 1.0f, 1.0f);
+ hr = ID2D1Factory1_CreateRectangleGeometry(factory, &rect, (ID2D1RectangleGeometry **)&geometry);
+ ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
+
+ ID2D1RenderTarget_FillGeometry(rt, geometry, brush, NULL);
+
+ refcount = ID2D1Brush_Release(brush);
+ ok(refcount == 0, "Got unexpected refcount %u.\n", refcount);
+
+ refcount = ID2D1Geometry_Release(geometry);
+ ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
+
+ refcount = ID2D1GradientStopCollection_Release(gradient);
+ ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
+
+ /* Geometry. */
+ set_rect(&rect, -1.0f, -1.0f, 1.0f, 1.0f);
+ hr = ID2D1Factory1_CreateRectangleGeometry(factory, &rect, (ID2D1RectangleGeometry **)&geometry);
+ ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
+
+ set_color(&color, 0.0f, 0.0f, 0.0f, 0.0f);
+ hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, (ID2D1SolidColorBrush **)&brush);
+ ok(SUCCEEDED(hr), "Failed to create a brush, hr %#x.\n", hr);
+
+ ID2D1RenderTarget_FillGeometry(rt, geometry, brush, NULL);
+
+ refcount = ID2D1Brush_Release(brush);
+ ok(refcount == 0, "Got unexpected refcount %u.\n", refcount);
+
+ refcount = ID2D1Geometry_Release(geometry);
+ ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
+
+ /* Stroke style. */
+ stroke_desc.startCap = D2D1_CAP_STYLE_SQUARE;
+ stroke_desc.endCap = D2D1_CAP_STYLE_ROUND;
+ stroke_desc.dashCap = D2D1_CAP_STYLE_TRIANGLE;
+ stroke_desc.lineJoin = D2D1_LINE_JOIN_BEVEL;
+ stroke_desc.miterLimit = 1.5f;
+ stroke_desc.dashStyle = D2D1_DASH_STYLE_DOT;
+ stroke_desc.dashOffset = -1.0f;
+
+ hr = ID2D1Factory_CreateStrokeStyle((ID2D1Factory *)factory, &stroke_desc, NULL, 0, &stroke_style);
+ ok(SUCCEEDED(hr), "Failed to create stroke style, %#x.\n", hr);
+
+ set_color(&color, 0.0f, 0.0f, 0.0f, 0.0f);
+ hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, (ID2D1SolidColorBrush **)&brush);
+ ok(SUCCEEDED(hr), "Failed to create a brush, hr %#x.\n", hr);
+
+ set_point(&p0, 100.0f, 160.0f);
+ set_point(&p1, 140.0f, 160.0f);
+ ID2D1RenderTarget_DrawLine(rt, p0, p1, brush, 1.0f, stroke_style);
+
+ refcount = ID2D1Brush_Release(brush);
+ ok(refcount == 0, "Got unexpected refcount %u.\n", refcount);
+
+ refcount = ID2D1StrokeStyle_Release(stroke_style);
+ ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
+
+ /* Close on attached list. */
+ ID2D1DeviceContext_GetTarget(device_context, &target);
+ ok(target == (ID2D1Image *)command_list, "Unexpected context target.\n");
+ ID2D1Image_Release(target);
+
+ hr = ID2D1CommandList_Close(command_list);
+ ok(SUCCEEDED(hr), "Failed to close a list, hr %#x.\n", hr);
+
+ ID2D1DeviceContext_GetTarget(device_context, &target);
+ ok(target == NULL, "Unexpected context target.\n");
+
+ hr = ID2D1CommandList_Close(command_list);
+ ok(hr == D2DERR_WRONG_STATE, "Unexpected hr %#x.\n", hr);
+
+ ID2D1CommandList_Release(command_list);
+
+ /* Close empty list. */
+ hr = ID2D1DeviceContext_CreateCommandList(device_context, &command_list);
+ ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr);
+
+ hr = ID2D1CommandList_Close(command_list);
+ ok(SUCCEEDED(hr), "Failed to close a list, hr %#x.\n", hr);
+
+ ID2D1CommandList_Release(command_list);
+
+ /* List created with different context. */
+ device_context2 = create_device_context(factory, d3d_device);
+ ok(device_context2 != NULL, "Failed to create device context.\n");
+
+ hr = ID2D1DeviceContext_CreateCommandList(device_context, &command_list);
+ ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr);
+
+ ID2D1DeviceContext_SetTarget(device_context2, (ID2D1Image *)command_list);
+ ID2D1DeviceContext_GetTarget(device_context2, &target);
+ ok(target == NULL, "Unexpected target.\n");
+
+ ID2D1CommandList_Release(command_list);
+ ID2D1DeviceContext_Release(device_context2);
+
+ ID2D1RenderTarget_Release(rt);
+ ID2D1DeviceContext_Release(device_context);
+ refcount = ID2D1Factory1_Release(factory);
+ ok(!refcount, "Factory has %u references left.\n", refcount);
+}
+
START_TEST(d2d1)
{
unsigned int argc, i;
@@ -7695,6 +7968,7 @@ START_TEST(d2d1)
queue_test(test_device_context);
queue_test(test_invert_matrix);
queue_test(test_skew_matrix);
+ queue_test(test_command_list);
run_queued_tests();
}
--
2.19.1