Commit 03d301cc authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

d2d1: Initial implementation of DC render target.

parent c7a9ab82
MODULE = d2d1.dll
IMPORTLIB = d2d1
IMPORTS = d3d10_1 dxguid uuid
IMPORTS = d3d10_1 dxguid uuid gdi32
DELAYIMPORTS = dwrite
C_SRCS = \
bitmap.c \
brush.c \
dc_render_target.c \
factory.c \
geometry.c \
mesh.c \
......
......@@ -96,6 +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;
struct d2d_wic_render_target
{
......@@ -115,6 +116,21 @@ struct d2d_wic_render_target
HRESULT d2d_wic_render_target_init(struct d2d_wic_render_target *render_target, ID2D1Factory *factory,
ID3D10Device1 *device, IWICBitmap *bitmap, const D2D1_RENDER_TARGET_PROPERTIES *desc) DECLSPEC_HIDDEN;
struct d2d_dc_render_target
{
ID2D1DCRenderTarget ID2D1DCRenderTarget_iface;
LONG refcount;
IDXGISurface1 *dxgi_surface;
ID2D1RenderTarget *dxgi_target;
RECT dst_rect;
HDC hdc;
};
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_gradient
{
ID2D1GradientStopCollection ID2D1GradientStopCollection_iface;
......
......@@ -29,7 +29,7 @@ struct d2d_factory
ID2D1Factory ID2D1Factory_iface;
LONG refcount;
ID3D10Device1 *wic_device;
ID3D10Device1 *device;
};
static inline struct d2d_factory *impl_from_ID2D1Factory(ID2D1Factory *iface)
......@@ -74,8 +74,8 @@ static ULONG STDMETHODCALLTYPE d2d_factory_Release(ID2D1Factory *iface)
if (!refcount)
{
if (factory->wic_device)
ID3D10Device1_Release(factory->wic_device);
if (factory->device)
ID3D10Device1_Release(factory->device);
HeapFree(GetProcessHeap(), 0, factory);
}
......@@ -223,11 +223,24 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDrawingStateBlock(ID2D1Factor
return S_OK;
}
static HRESULT d2d_factory_get_device(struct d2d_factory *factory, ID3D10Device1 **device)
{
HRESULT hr = S_OK;
if (!factory->device && FAILED(hr = D3D10CreateDevice1(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, D3D10_CREATE_DEVICE_BGRA_SUPPORT,
D3D10_FEATURE_LEVEL_10_0, D3D10_1_SDK_VERSION, &factory->device)))
WARN("Failed to create device, hr %#x.\n", hr);
*device = factory->device;
return hr;
}
static HRESULT STDMETHODCALLTYPE d2d_factory_CreateWicBitmapRenderTarget(ID2D1Factory *iface,
IWICBitmap *target, const D2D1_RENDER_TARGET_PROPERTIES *desc, ID2D1RenderTarget **render_target)
{
struct d2d_factory *factory = impl_from_ID2D1Factory(iface);
struct d2d_wic_render_target *object;
ID3D10Device1 *device;
HRESULT hr;
TRACE("iface %p, target %p, desc %p, render_target %p.\n", iface, target, desc, render_target);
......@@ -235,15 +248,13 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateWicBitmapRenderTarget(ID2D1Fa
if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
return E_OUTOFMEMORY;
if (!factory->wic_device && FAILED(hr = D3D10CreateDevice1(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL,
D3D10_CREATE_DEVICE_BGRA_SUPPORT, D3D10_FEATURE_LEVEL_10_0, D3D10_1_SDK_VERSION, &factory->wic_device)))
if (FAILED(hr = d2d_factory_get_device(factory, &device)))
{
WARN("Failed to create device, hr %#x.\n", hr);
HeapFree(GetProcessHeap(), 0, object);
return hr;
}
if (FAILED(hr = d2d_wic_render_target_init(object, iface, factory->wic_device, target, desc)))
if (FAILED(hr = d2d_wic_render_target_init(object, iface, device, target, desc)))
{
WARN("Failed to initialize render target, hr %#x.\n", hr);
HeapFree(GetProcessHeap(), 0, object);
......@@ -292,9 +303,30 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDxgiSurfaceRenderTarget(ID2D1
static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDCRenderTarget(ID2D1Factory *iface,
const D2D1_RENDER_TARGET_PROPERTIES *desc, ID2D1DCRenderTarget **render_target)
{
FIXME("iface %p, desc %p, render_target %p stub!\n", iface, desc, render_target);
struct d2d_factory *factory = impl_from_ID2D1Factory(iface);
struct d2d_dc_render_target *object;
ID3D10Device1 *device;
HRESULT hr;
return E_NOTIMPL;
TRACE("iface %p, desc %p, render_target %p.\n", iface, 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_dc_render_target_init(object, iface, device, 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->ID2D1DCRenderTarget_iface;
return S_OK;
}
static const struct ID2D1FactoryVtbl d2d_factory_vtbl =
......
......@@ -2180,3 +2180,39 @@ err:
ID2D1Factory_Release(render_target->factory);
return hr;
}
HRESULT d2d_d3d_render_target_update_surface(ID2D1RenderTarget *iface, IDXGISurface1 *surface)
{
struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
DXGI_SURFACE_DESC surface_desc;
ID3D10RenderTargetView *view;
ID3D10Resource *resource;
HRESULT hr;
if (FAILED(hr = IDXGISurface1_GetDesc(surface, &surface_desc)))
{
WARN("Failed to get surface desc, hr %#x.\n", hr);
return hr;
}
if (FAILED(hr = IDXGISurface1_QueryInterface(surface, &IID_ID3D10Resource, (void **)&resource)))
{
WARN("Failed to get ID3D10Resource interface, hr %#x.\n", hr);
return hr;
}
hr = ID3D10Device_CreateRenderTargetView(render_target->device, resource, NULL, &view);
ID3D10Resource_Release(resource);
if (FAILED(hr))
{
WARN("Failed to create rendertarget view, hr %#x.\n", hr);
return hr;
}
render_target->pixel_size.width = surface_desc.Width;
render_target->pixel_size.height = surface_desc.Height;
ID3D10RenderTargetView_Release(render_target->view);
render_target->view = view;
return S_OK;
}
......@@ -2661,8 +2661,10 @@ static void test_dc_target(void)
ID2D1SolidColorBrush *brush;
ID2D1DCRenderTarget *rt;
ID2D1Factory *factory;
ID3D10Device1 *device;
FLOAT dpi_x, dpi_y;
D2D1_COLOR_F color;
D2D1_SIZE_U sizeu;
D2D1_SIZE_F size;
D2D1_TAG t1, t2;
unsigned int i;
......@@ -2672,6 +2674,13 @@ static void test_dc_target(void)
HRESULT hr;
RECT rect;
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);
......@@ -2685,7 +2694,6 @@ static void test_dc_target(void)
desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
hr = ID2D1Factory_CreateDCRenderTarget(factory, &desc, &rt);
todo_wine
ok(hr == D2DERR_UNSUPPORTED_PIXEL_FORMAT, "Got unexpected hr %#x.\n", hr);
}
......@@ -2697,14 +2705,16 @@ static void test_dc_target(void)
desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
hr = ID2D1Factory_CreateDCRenderTarget(factory, &desc, &rt);
todo_wine
ok(SUCCEEDED(hr), "Failed to create target, hr %#x.\n", hr);
if (SUCCEEDED(hr))
{
size = ID2D1DCRenderTarget_GetSize(rt);
ok(size.width == 0.0f, "got width %.08e.\n", size.width);
ok(size.height == 0.0f, "got height %.08e.\n", size.height);
sizeu = ID2D1DCRenderTarget_GetPixelSize(rt);
ok(sizeu.width == 0, "got width %u.\n", sizeu.width);
ok(sizeu.height == 0, "got height %u.\n", sizeu.height);
/* object creation methods work without BindDC() */
set_color(&color, 0.0f, 0.0f, 0.0f, 0.0f);
hr = ID2D1DCRenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush);
......@@ -2818,7 +2828,6 @@ if (SUCCEEDED(hr))
DeleteDC(hdc);
DeleteDC(hdc2);
ID2D1DCRenderTarget_Release(rt);
}
ID2D1Factory_Release(factory);
}
......
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