[v2 PATCH] d2d1: Initial implementation of DC render target
Nikolay Sivov
nsivov at codeweavers.com
Sun Sep 11 15:24:36 CDT 2016
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
v2: skip test if device creation fails
dlls/d2d1/Makefile.in | 3 ++-
dlls/d2d1/d2d1_private.h | 16 +++++++++++++++
dlls/d2d1/factory.c | 50 ++++++++++++++++++++++++++++++++++++++---------
dlls/d2d1/render_target.c | 36 ++++++++++++++++++++++++++++++++++
dlls/d2d1/tests/d2d1.c | 18 ++++++++++++-----
5 files changed, 108 insertions(+), 15 deletions(-)
diff --git a/dlls/d2d1/Makefile.in b/dlls/d2d1/Makefile.in
index 8a6618d..06f7bde 100644
--- a/dlls/d2d1/Makefile.in
+++ b/dlls/d2d1/Makefile.in
@@ -1,11 +1,12 @@
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 \
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h
index f0577ed..fa7e464 100644
--- a/dlls/d2d1/d2d1_private.h
+++ b/dlls/d2d1/d2d1_private.h
@@ -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;
diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c
index d63add5..66ed25b 100644
--- a/dlls/d2d1/factory.c
+++ b/dlls/d2d1/factory.c
@@ -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 =
diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c
index 5005840..6824e9f 100644
--- a/dlls/d2d1/render_target.c
+++ b/dlls/d2d1/render_target.c
@@ -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;
+}
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c
index 0a81013..a4b123d 100644
--- a/dlls/d2d1/tests/d2d1.c
+++ b/dlls/d2d1/tests/d2d1.c
@@ -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,12 @@ static void test_dc_target(void)
HRESULT hr;
RECT rect;
+ if (!(device = create_device()))
+ {
+ skip("Failed to create device, skipping tests.\n");
+ return;
+ }
+
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 +2693,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 +2704,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.0f, "got width %u.\n", sizeu.width);
+ ok(sizeu.height == 0.0f, "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 +2827,6 @@ if (SUCCEEDED(hr))
DeleteDC(hdc);
DeleteDC(hdc2);
ID2D1DCRenderTarget_Release(rt);
-}
ID2D1Factory_Release(factory);
}
--
2.9.3
More information about the wine-patches
mailing list