Commit 52c41249 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

d2d1: Bitmap values are always premultiplied in practice.

Since creating bitmaps with D2D1_ALPHA_MODE_UNKNOWN or D2D1_ALPHA_MODE_STRAIGHT is not possible, and D2D1_ALPHA_MODE_IGNORE behaves as if alpha == 1.0f.
parent 905bf793
......@@ -746,6 +746,9 @@ HRESULT d2d_brush_get_ps_cb(struct d2d_brush *brush, struct d2d_d3d_render_targe
{
color = brush->u.solid.color;
color.a *= brush->opacity;
color.r *= color.a;
color.g *= color.a;
color.b *= color.a;
buffer_desc.ByteWidth = sizeof(color);
buffer_data.pSysMem = &color;
......
......@@ -1580,16 +1580,14 @@ HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target,
texcoord.x = position.x * transform._11 + position.y * transform._21 + transform._31;
texcoord.y = position.x * transform._12 + position.y * transform._22 + transform._32;
ret = t.Sample(s, texcoord);
ret = t.Sample(s, texcoord) * opacity;
if (ignore_alpha)
ret.a = opacity;
else
ret.a *= opacity;
return ret;
}
#endif
0x43425844, 0xf2e9967c, 0xad1d1ac2, 0x865274b8, 0x6ab4c5ca, 0x00000001, 0x000001fc, 0x00000003,
0x43425844, 0xf5bb1e01, 0xe3386963, 0xcaa095bd, 0xea2887de, 0x00000001, 0x000001fc, 0x00000003,
0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49,
0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
......@@ -1601,10 +1599,10 @@ HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target,
0x0010000a, 0x00000000, 0x0020802a, 0x00000000, 0x00000000, 0x0800000f, 0x00100042, 0x00000000,
0x00101046, 0x00000000, 0x00208046, 0x00000000, 0x00000001, 0x08000000, 0x00100022, 0x00000000,
0x0010002a, 0x00000000, 0x0020802a, 0x00000000, 0x00000001, 0x09000045, 0x001000f2, 0x00000000,
0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, 0x00100082,
0x00000000, 0x0010003a, 0x00000000, 0x0020803a, 0x00000000, 0x00000001, 0x05000036, 0x00102072,
0x00000000, 0x00100246, 0x00000000, 0x0b000037, 0x00102082, 0x00000000, 0x0020800a, 0x00000000,
0x00000002, 0x0020803a, 0x00000000, 0x00000001, 0x0010003a, 0x00000000, 0x0100003e,
0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, 0x001000f2,
0x00000000, 0x00100e46, 0x00000000, 0x00208ff6, 0x00000000, 0x00000001, 0x0b000037, 0x00102082,
0x00000000, 0x0020800a, 0x00000000, 0x00000002, 0x0020803a, 0x00000000, 0x00000001, 0x0010003a,
0x00000000, 0x05000036, 0x00102072, 0x00000000, 0x00100246, 0x00000000, 0x0100003e,
};
/* The basic idea here is to evaluate the implicit form of the curve in
* texture space. "t.z" determines which side of the curve is shaded. */
......@@ -1793,7 +1791,7 @@ HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target,
memset(&blend_desc, 0, sizeof(blend_desc));
blend_desc.BlendEnable[0] = TRUE;
blend_desc.SrcBlend = D3D10_BLEND_SRC_ALPHA;
blend_desc.SrcBlend = D3D10_BLEND_ONE;
blend_desc.DestBlend = D3D10_BLEND_INV_SRC_ALPHA;
blend_desc.BlendOp = D3D10_BLEND_OP_ADD;
blend_desc.SrcBlendAlpha = D3D10_BLEND_ZERO;
......
......@@ -1609,6 +1609,140 @@ static void test_bitmap_formats(void)
DestroyWindow(window);
}
static void test_alpha_mode(void)
{
D2D1_BITMAP_PROPERTIES bitmap_desc;
ID2D1SolidColorBrush *color_brush;
ID2D1BitmapBrush *bitmap_brush;
IDXGISwapChain *swapchain;
ID2D1RenderTarget *rt;
ID3D10Device1 *device;
IDXGISurface *surface;
ID2D1Bitmap *bitmap;
D2D1_COLOR_F color;
D2D1_RECT_F rect;
D2D1_SIZE_U size;
ULONG refcount;
HWND window;
HRESULT hr;
BOOL match;
static const DWORD bitmap_data[] =
{
0x7f7f0000, 0x7f7f7f00, 0x7f007f00, 0x7f007f7f,
0x7f00007f, 0x7f7f007f, 0x7f000000, 0x7f404040,
0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f000000,
0x7f7f7f7f, 0x7f000000, 0x7f000000, 0x7f000000,
};
if (!(device = create_device()))
{
skip("Failed to create device, skipping tests.\n");
return;
}
window = CreateWindowA("static", "d2d1_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
0, 0, 640, 480, NULL, NULL, NULL, NULL);
swapchain = create_swapchain(device, window, TRUE);
hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
rt = create_render_target(surface);
ok(!!rt, "Failed to create render target.\n");
ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
set_size_u(&size, 4, 4);
bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
bitmap_desc.dpiX = 96.0f / 40.0f;
bitmap_desc.dpiY = 96.0f / 30.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);
hr = ID2D1RenderTarget_CreateBitmapBrush(rt, bitmap, NULL, NULL, &bitmap_brush);
ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
ID2D1BitmapBrush_SetInterpolationMode(bitmap_brush, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR);
ID2D1BitmapBrush_SetExtendModeX(bitmap_brush, D2D1_EXTEND_MODE_WRAP);
ID2D1BitmapBrush_SetExtendModeY(bitmap_brush, D2D1_EXTEND_MODE_WRAP);
set_color(&color, 0.0f, 1.0f, 0.0f, 0.75f);
hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &color_brush);
ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
ID2D1RenderTarget_BeginDraw(rt);
ID2D1RenderTarget_Clear(rt, NULL);
hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
match = compare_surface(surface, "b44510bf2d2e61a8d7c0ad862de49a471f1fd13f");
ok(match, "Surface does not match.\n");
ID2D1RenderTarget_BeginDraw(rt);
set_color(&color, 1.0f, 0.0f, 0.0f, 0.25f);
ID2D1RenderTarget_Clear(rt, &color);
hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
match = compare_surface(surface, "2184f4a9198fc1de09ac85301b7a03eebadd9b81");
ok(match, "Surface does not match.\n");
ID2D1RenderTarget_BeginDraw(rt);
set_color(&color, 0.0f, 0.0f, 1.0f, 0.75f);
ID2D1RenderTarget_Clear(rt, &color);
hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
match = compare_surface(surface, "6527ec83b4039c895b50f9b3e144fe0cf90d1889");
ok(match, "Surface does not match.\n");
ID2D1RenderTarget_BeginDraw(rt);
set_rect(&rect, 0.0f, 0.0f, 160.0f, 120.0f);
ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
set_rect(&rect, 160.0f, 0.0f, 320.0f, 120.0f);
ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.75f);
ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
set_rect(&rect, 320.0f, 0.0f, 480.0f, 120.0f);
ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.25f);
ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
ID2D1Bitmap_Release(bitmap);
bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
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);
ID2D1BitmapBrush_SetBitmap(bitmap_brush, bitmap);
set_rect(&rect, 0.0f, 120.0f, 160.0f, 240.0f);
ID2D1BitmapBrush_SetOpacity(bitmap_brush, 1.0f);
ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
set_rect(&rect, 160.0f, 120.0f, 320.0f, 240.0f);
ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.75f);
ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
set_rect(&rect, 320.0f, 120.0f, 480.0f, 240.0f);
ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.25f);
ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
set_rect(&rect, 0.0f, 240.0f, 160.0f, 360.0f);
ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)color_brush);
set_rect(&rect, 160.0f, 240.0f, 320.0f, 360.0f);
ID2D1SolidColorBrush_SetOpacity(color_brush, 0.75f);
ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)color_brush);
set_rect(&rect, 320.0f, 240.0f, 480.0f, 360.0f);
ID2D1SolidColorBrush_SetOpacity(color_brush, 0.25f);
ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)color_brush);
hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
match = compare_surface(surface, "465f5a3190d7bde408b3206b4be939fb22f8a3d6");
ok(match, "Surface does not match.\n");
refcount = ID2D1Bitmap_Release(bitmap);
ok(refcount == 1, "Bitmap has %u references left.\n", refcount);
ID2D1SolidColorBrush_Release(color_brush);
ID2D1BitmapBrush_Release(bitmap_brush);
ID2D1RenderTarget_Release(rt);
IDXGISurface_Release(surface);
IDXGISwapChain_Release(swapchain);
ID3D10Device1_Release(device);
DestroyWindow(window);
}
START_TEST(d2d1)
{
test_clip();
......@@ -1617,4 +1751,5 @@ START_TEST(d2d1)
test_bitmap_brush();
test_path_geometry();
test_bitmap_formats();
test_alpha_mode();
}
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