mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-05 18:01:34 +00:00
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.
This commit is contained in:
parent
905bf79337
commit
52c412492f
3 changed files with 145 additions and 9 deletions
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue