d2d1: Properly handle D2D1_ALPHA_MODE_PREMULTIPLIED on render targets.

This commit is contained in:
Henri Verbeet 2015-07-30 11:10:56 +02:00 committed by Alexandre Julliard
parent 52c412492f
commit c2135dd498
2 changed files with 124 additions and 11 deletions

View File

@ -1165,7 +1165,11 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_Clear(ID2D1RenderTarget *ifa
if (color) if (color)
c = *color; c = *color;
c.a = 1.0f; if (render_target->format.alphaMode == D2D1_ALPHA_MODE_IGNORE)
c.a = 1.0f;
c.r *= c.a;
c.g *= c.a;
c.b *= c.a;
buffer_desc.ByteWidth = sizeof(c); buffer_desc.ByteWidth = sizeof(c);
buffer_data.pSysMem = &c; buffer_data.pSysMem = &c;
@ -1794,8 +1798,16 @@ HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target,
blend_desc.SrcBlend = D3D10_BLEND_ONE; blend_desc.SrcBlend = D3D10_BLEND_ONE;
blend_desc.DestBlend = D3D10_BLEND_INV_SRC_ALPHA; blend_desc.DestBlend = D3D10_BLEND_INV_SRC_ALPHA;
blend_desc.BlendOp = D3D10_BLEND_OP_ADD; blend_desc.BlendOp = D3D10_BLEND_OP_ADD;
blend_desc.SrcBlendAlpha = D3D10_BLEND_ZERO; if (desc->pixelFormat.alphaMode == D2D1_ALPHA_MODE_IGNORE)
blend_desc.DestBlendAlpha = D3D10_BLEND_ONE; {
blend_desc.SrcBlendAlpha = D3D10_BLEND_ZERO;
blend_desc.DestBlendAlpha = D3D10_BLEND_ONE;
}
else
{
blend_desc.SrcBlendAlpha = D3D10_BLEND_ONE;
blend_desc.DestBlendAlpha = D3D10_BLEND_INV_SRC_ALPHA;
}
blend_desc.BlendOpAlpha = D3D10_BLEND_OP_ADD; blend_desc.BlendOpAlpha = D3D10_BLEND_OP_ADD;
blend_desc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL; blend_desc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL;
if (FAILED(hr = ID3D10Device_CreateBlendState(render_target->device, &blend_desc, &render_target->bs))) if (FAILED(hr = ID3D10Device_CreateBlendState(render_target->device, &blend_desc, &render_target->bs)))

View File

@ -438,29 +438,34 @@ static IDXGISwapChain *create_swapchain(ID3D10Device1 *device, HWND window, BOOL
return swapchain; return swapchain;
} }
static ID2D1RenderTarget *create_render_target(IDXGISurface *surface) static ID2D1RenderTarget *create_render_target_desc(IDXGISurface *surface, const D2D1_RENDER_TARGET_PROPERTIES *desc)
{ {
D2D1_RENDER_TARGET_PROPERTIES desc;
ID2D1RenderTarget *render_target; ID2D1RenderTarget *render_target;
ID2D1Factory *factory; ID2D1Factory *factory;
HRESULT hr; HRESULT hr;
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory); hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr); ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory, surface, desc, &render_target);
ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
ID2D1Factory_Release(factory);
return render_target;
}
static ID2D1RenderTarget *create_render_target(IDXGISurface *surface)
{
D2D1_RENDER_TARGET_PROPERTIES desc;
desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN; desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE; desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
desc.dpiX = 0.0f; desc.dpiX = 0.0f;
desc.dpiY = 0.0f; desc.dpiY = 0.0f;
desc.usage = D2D1_RENDER_TARGET_USAGE_NONE; desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT; desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory, surface, &desc, &render_target);
ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
ID2D1Factory_Release(factory); return create_render_target_desc(surface, &desc);
return render_target;
} }
static void test_clip(void) static void test_clip(void)
@ -1611,6 +1616,7 @@ static void test_bitmap_formats(void)
static void test_alpha_mode(void) static void test_alpha_mode(void)
{ {
D2D1_RENDER_TARGET_PROPERTIES rt_desc;
D2D1_BITMAP_PROPERTIES bitmap_desc; D2D1_BITMAP_PROPERTIES bitmap_desc;
ID2D1SolidColorBrush *color_brush; ID2D1SolidColorBrush *color_brush;
ID2D1BitmapBrush *bitmap_brush; ID2D1BitmapBrush *bitmap_brush;
@ -1668,6 +1674,101 @@ static void test_alpha_mode(void)
hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &color_brush); hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &color_brush);
ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr); 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, "48c41aff3a130a17ee210866b2ab7d36763934d5");
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, "6487e683730fb5a77c1911388d00b04664c5c4e4");
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, "7a35ba09e43cbaf591388ff1ef8de56157630c98");
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, "14f8ac64b70966c7c3c6281c59aaecdb17c3b16a");
ok(match, "Surface does not match.\n");
ID2D1RenderTarget_Release(rt);
rt_desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
rt_desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
rt_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
rt_desc.dpiX = 0.0f;
rt_desc.dpiY = 0.0f;
rt_desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
rt_desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
rt = create_render_target_desc(surface, &rt_desc);
ok(!!rt, "Failed to create render target.\n");
ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
ID2D1Bitmap_Release(bitmap);
bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
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);
ID2D1BitmapBrush_Release(bitmap_brush);
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);
ID2D1SolidColorBrush_Release(color_brush);
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_BeginDraw(rt);
ID2D1RenderTarget_Clear(rt, NULL); ID2D1RenderTarget_Clear(rt, NULL);
hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL); hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);