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

d2d1: Initial implementation of HWND render target.

parent 6372cd8e
MODULE = d2d1.dll
IMPORTLIB = d2d1
IMPORTS = d3d10_1 dxguid uuid gdi32
IMPORTS = d3d10_1 dxguid uuid gdi32 user32
DELAYIMPORTS = dwrite
C_SRCS = \
......@@ -9,6 +9,7 @@ C_SRCS = \
dc_render_target.c \
factory.c \
geometry.c \
hwnd_render_target.c \
mesh.c \
render_target.c \
state_block.c \
......
......@@ -96,7 +96,7 @@ struct d2d_d3d_render_target
HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target, ID2D1Factory *factory,
IDXGISurface *surface, const D2D1_RENDER_TARGET_PROPERTIES *desc) DECLSPEC_HIDDEN;
HRESULT d2d_d3d_render_target_update_surface(ID2D1RenderTarget *render_target, IDXGISurface1 *surface) DECLSPEC_HIDDEN;
HRESULT d2d_d3d_render_target_create_rtv(ID2D1RenderTarget *render_target, IDXGISurface1 *surface) DECLSPEC_HIDDEN;
struct d2d_wic_render_target
{
......@@ -131,6 +131,21 @@ struct d2d_dc_render_target
HRESULT d2d_dc_render_target_init(struct d2d_dc_render_target *render_target, ID2D1Factory *factory,
ID3D10Device1 *device, const D2D1_RENDER_TARGET_PROPERTIES *desc) DECLSPEC_HIDDEN;
struct d2d_hwnd_render_target
{
ID2D1HwndRenderTarget ID2D1HwndRenderTarget_iface;
LONG refcount;
ID2D1RenderTarget *dxgi_target;
IDXGISwapChain *swapchain;
UINT sync_interval;
HWND hwnd;
};
HRESULT d2d_hwnd_render_target_init(struct d2d_hwnd_render_target *render_target, ID2D1Factory *factory,
ID3D10Device1 *device, const D2D1_RENDER_TARGET_PROPERTIES *desc,
const D2D1_HWND_RENDER_TARGET_PROPERTIES *hwnd_desc) DECLSPEC_HIDDEN;
struct d2d_gradient
{
ID2D1GradientStopCollection ID2D1GradientStopCollection_iface;
......
......@@ -731,7 +731,7 @@ static HRESULT STDMETHODCALLTYPE d2d_dc_render_target_BindDC(ID2D1DCRenderTarget
}
/* Switch dxgi target to new surface. */
if (FAILED(hr = d2d_d3d_render_target_update_surface(render_target->dxgi_target, dxgi_surface)))
if (FAILED(hr = d2d_d3d_render_target_create_rtv(render_target->dxgi_target, dxgi_surface)))
{
WARN("Failed to set new surface, hr %#x.\n", hr);
IDXGISurface1_Release(dxgi_surface);
......
......@@ -271,9 +271,30 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateHwndRenderTarget(ID2D1Factory
const D2D1_RENDER_TARGET_PROPERTIES *desc, const D2D1_HWND_RENDER_TARGET_PROPERTIES *hwnd_rt_desc,
ID2D1HwndRenderTarget **render_target)
{
FIXME("iface %p, desc %p, hwnd_rt_desc %p, render_target %p stub!\n", iface, desc, hwnd_rt_desc, render_target);
struct d2d_factory *factory = impl_from_ID2D1Factory(iface);
struct d2d_hwnd_render_target *object;
ID3D10Device1 *device;
HRESULT hr;
return E_NOTIMPL;
TRACE("iface %p, desc %p, hwnd_rt_desc %p, render_target %p.\n", iface, desc, hwnd_rt_desc, render_target);
if (FAILED(hr = d2d_factory_get_device(factory, &device)))
return hr;
if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
return E_OUTOFMEMORY;
if (FAILED(hr = d2d_hwnd_render_target_init(object, iface, device, desc, hwnd_rt_desc)))
{
WARN("Failed to initialize render target, hr %#x.\n", hr);
HeapFree(GetProcessHeap(), 0, object);
return hr;
}
TRACE("Created render target %p.\n", object);
*render_target = &object->ID2D1HwndRenderTarget_iface;
return S_OK;
}
static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDxgiSurfaceRenderTarget(ID2D1Factory *iface,
......
......@@ -2181,7 +2181,7 @@ err:
return hr;
}
HRESULT d2d_d3d_render_target_update_surface(ID2D1RenderTarget *iface, IDXGISurface1 *surface)
HRESULT d2d_d3d_render_target_create_rtv(ID2D1RenderTarget *iface, IDXGISurface1 *surface)
{
struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
DXGI_SURFACE_DESC surface_desc;
......@@ -2189,6 +2189,13 @@ HRESULT d2d_d3d_render_target_update_surface(ID2D1RenderTarget *iface, IDXGISurf
ID3D10Resource *resource;
HRESULT hr;
if (!surface)
{
ID3D10RenderTargetView_Release(render_target->view);
render_target->view = NULL;
return S_OK;
}
if (FAILED(hr = IDXGISurface1_GetDesc(surface, &surface_desc)))
{
WARN("Failed to get surface desc, hr %#x.\n", hr);
......
......@@ -2831,6 +2831,56 @@ static void test_dc_target(void)
ID2D1Factory_Release(factory);
}
static void test_hwnd_target(void)
{
D2D1_HWND_RENDER_TARGET_PROPERTIES hwnd_rt_desc;
D2D1_RENDER_TARGET_PROPERTIES desc;
ID2D1HwndRenderTarget *rt;
ID2D1Factory *factory;
ID3D10Device1 *device;
HRESULT hr;
if (!(device = create_device()))
{
skip("Failed to create device, skipping tests.\n");
return;
}
ID3D10Device1_Release(device);
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
desc.dpiX = 0.0f;
desc.dpiY = 0.0f;
desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
hwnd_rt_desc.hwnd = NULL;
hwnd_rt_desc.pixelSize.width = 64;
hwnd_rt_desc.pixelSize.height = 64;
hwnd_rt_desc.presentOptions = D2D1_PRESENT_OPTIONS_NONE;
hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt);
ok(FAILED(hr), "Target creation should fail, hr %#x.\n", hr);
hwnd_rt_desc.hwnd = (HWND)0xdeadbeef;
hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt);
ok(FAILED(hr), "Target creation should fail, hr %#x.\n", hr);
hwnd_rt_desc.hwnd = CreateWindowA("static", "d2d_test", 0, 0, 0, 0, 0, 0, 0, 0, 0);
ok(!!hwnd_rt_desc.hwnd, "Failed to create target window.\n");
hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt);
ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
ID2D1HwndRenderTarget_Release(rt);
DestroyWindow(hwnd_rt_desc.hwnd);
ID2D1Factory_Release(factory);
}
START_TEST(d2d1)
{
test_clip();
......@@ -2846,4 +2896,5 @@ START_TEST(d2d1)
test_create_target();
test_draw_text_layout();
test_dc_target();
test_hwnd_target();
}
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