[PATCH 8/9] d2d1: Partially implement ID2D1DeviceContext

Lucian Poston lucian.poston at gmail.com
Tue Nov 21 02:41:12 CST 2017


https://bugs.winehq.org/show_bug.cgi?id=44052

Signed-off-by: Lucian Poston <lucian.poston at gmail.com>
---
 dlls/d2d1/d2d1_private.h   |  16 +++
 dlls/d2d1/device.c         |  36 ++++-
 dlls/d2d1/device_context.c | 318 ++++++++++++++++++++++++++++++++-------------
 dlls/d2d1/render_target.c  |  82 ++++++++----
 4 files changed, 336 insertions(+), 116 deletions(-)

diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h
index edeed5106b..90ccc66a7d 100644
--- a/dlls/d2d1/d2d1_private.h
+++ b/dlls/d2d1/d2d1_private.h
@@ -147,6 +147,10 @@ struct d2d_d3d_render_target
 
 HRESULT d2d_d3d_create_render_target(ID2D1Factory *factory, IDXGISurface *surface, IUnknown *outer_unknown,
         const D2D1_RENDER_TARGET_PROPERTIES *desc, ID2D1RenderTarget **render_target) DECLSPEC_HIDDEN;
+HRESULT d2d_d3d_create_render_target_with_device(ID2D1Factory *factory,
+        ID3D10Device *device, IUnknown *outer_unknown,
+        const D2D1_RENDER_TARGET_PROPERTIES *desc,
+        ID2D1RenderTarget **render_target) DECLSPEC_HIDDEN;
 HRESULT d2d_d3d_render_target_create_rtv(ID2D1RenderTarget *render_target, IDXGISurface1 *surface) DECLSPEC_HIDDEN;
 
 struct d2d_wic_render_target
@@ -545,4 +549,16 @@ struct d2d_device
 
 void d2d_device_init(struct d2d_device *This, ID2D1Factory1 *iface, IDXGIDevice *dxgiDevice) DECLSPEC_HIDDEN;
 
+struct d2d_device_context
+{
+    ID2D1DeviceContext ID2D1DeviceContext_iface;
+    LONG refcount;
+    ID2D1Device *device;
+    ID2D1RenderTarget *dxgi_target;
+};
+
+HRESULT d2d_device_context_init(struct d2d_device_context *This,
+        ID2D1Device *device_iface, D2D1_DEVICE_CONTEXT_OPTIONS options,
+        ID3D10Device *d3d_device) DECLSPEC_HIDDEN;
+
 #endif /* __WINE_D2D1_PRIVATE_H */
diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c
index b5007a9dd5..d730aaea53 100644
--- a/dlls/d2d1/device.c
+++ b/dlls/d2d1/device.c
@@ -97,8 +97,40 @@ static HRESULT WINAPI d2d_device_CreateDeviceContext(
         ID2D1DeviceContext **deviceContext)
 {
     struct d2d_device *This = impl_from_ID2D1Device(iface);
-    FIXME("%p stub!\n", This);
-    return E_NOTIMPL;
+    struct d2d_device_context *object;
+    ID3D10Device *d3d_device;
+    HRESULT hr;
+
+    TRACE("This %p, options %#x\n", This, options);
+    if (deviceContext == NULL)
+        return E_POINTER;
+
+    if (FAILED(hr = IDXGIDevice_QueryInterface(This->dxgi_device,
+                    &IID_ID3D10Device, (void **)&d3d_device)))
+    {
+        WARN("Failed to query d3d device, hr %#x.\n", hr);
+        return hr;
+    }
+
+    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+    {
+        ID3D10Device_Release(d3d_device);
+        return E_OUTOFMEMORY;
+    }
+
+    hr = d2d_device_context_init(object, iface, options, d3d_device);
+    ID3D10Device_Release(d3d_device);
+    if (FAILED(hr))
+    {
+        HeapFree(GetProcessHeap(), 0, object);
+        WARN("Failed to create device context, hr %#x.\n", hr);
+        return hr;
+    }
+
+    *deviceContext = &object->ID2D1DeviceContext_iface;
+    TRACE("Created device context %p.\n", object);
+
+    return S_OK;
 }
 
 static HRESULT WINAPI d2d_device_CreatePrintControl(
diff --git a/dlls/d2d1/device_context.c b/dlls/d2d1/device_context.c
index 5b679c2af8..ef0fb88cba 100644
--- a/dlls/d2d1/device_context.c
+++ b/dlls/d2d1/device_context.c
@@ -23,12 +23,6 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(d2d);
 
-struct d2d_device_context
-{
-    ID2D1DeviceContext ID2D1DeviceContext_iface;
-    LONG refcount;
-};
-
 static inline struct d2d_device_context *impl_from_ID2D1DeviceContext(ID2D1DeviceContext *iface)
 {
     return CONTAINING_RECORD(iface, struct d2d_device_context, ID2D1DeviceContext_iface);
@@ -39,25 +33,49 @@ static HRESULT WINAPI d2d_device_context_QueryInterface(
         REFIID riid,
         void **ppvObject)
 {
-    struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
-    return E_NOTIMPL;
+    TRACE("iface %p, riid %s, ppvObject %p.\n", iface, debugstr_guid(riid), ppvObject);
+    if (ppvObject == NULL)
+        return E_POINTER;
+
+    if (IsEqualGUID(riid, &IID_ID2D1DeviceContext)
+            || IsEqualGUID(riid, &IID_ID2D1RenderTarget)
+            || IsEqualGUID(riid, &IID_ID2D1Resource)
+            || IsEqualGUID(riid, &IID_IUnknown))
+    {
+        ID2D1DeviceContext_AddRef(iface);
+        *ppvObject = iface;
+        return S_OK;
+    }
+
+    WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+    *ppvObject = NULL;
+    return E_NOINTERFACE;
 }
 
 static ULONG WINAPI d2d_device_context_AddRef(
         ID2D1DeviceContext *iface)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
-    return 0;
+    ULONG refcount = InterlockedIncrement(&This->refcount);
+    TRACE("%p increasing refcount to %u.\n", iface, refcount);
+    return refcount;
 }
 
 static ULONG WINAPI d2d_device_context_Release(
         ID2D1DeviceContext *iface)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
-    return 0;
+    ULONG refcount = InterlockedDecrement(&This->refcount);
+    TRACE("%p decreasing refcount to %u.\n", iface, refcount);
+
+    if (refcount == 0)
+    {
+        ID2D1RenderTarget_Release(This->dxgi_target);
+        ID2D1Device_Release(This->device);
+        HeapFree(GetProcessHeap(), 0, This);
+    }
+
+    return refcount;
 }
 
 static void WINAPI d2d_device_context_GetFactory(
@@ -65,7 +83,8 @@ static void WINAPI d2d_device_context_GetFactory(
         ID2D1Factory **factory)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p, factory %p.\n", This, factory);
+    ID2D1Device_GetFactory(This->device, factory);
 }
 
 static HRESULT WINAPI d2d_device_context_CreateBitmap(
@@ -77,8 +96,8 @@ static HRESULT WINAPI d2d_device_context_CreateBitmap(
         ID2D1Bitmap **bitmap)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
-    return E_NOTIMPL;
+    TRACE("This %p, src_data %p, desc %p, bitmap %p.\n", This, src_data, desc, bitmap);
+    return ID2D1RenderTarget_CreateBitmap(This->dxgi_target, size, src_data, pitch, desc, bitmap);
 }
 
 static HRESULT WINAPI d2d_device_context_CreateBitmapFromWicBitmap(
@@ -88,8 +107,9 @@ static HRESULT WINAPI d2d_device_context_CreateBitmapFromWicBitmap(
         ID2D1Bitmap **bitmap)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
-    return E_NOTIMPL;
+    TRACE("This %p, bitmap_source %p, desc %p, bitmap %p.\n",
+            This, bitmap_source, desc, bitmap);
+    return ID2D1RenderTarget_CreateBitmapFromWicBitmap(This->dxgi_target, bitmap_source, desc, bitmap);
 }
 
 static HRESULT WINAPI d2d_device_context_CreateSharedBitmap(
@@ -100,8 +120,9 @@ static HRESULT WINAPI d2d_device_context_CreateSharedBitmap(
         ID2D1Bitmap **bitmap)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
-    return E_NOTIMPL;
+    TRACE("This %p, iid %s, data %p, desc %p, bitmap %p.\n",
+            This, debugstr_guid(iid), data, desc, bitmap);
+    return ID2D1RenderTarget_CreateSharedBitmap(This->dxgi_target, iid, data, desc, bitmap);
 }
 
 static HRESULT WINAPI d2d_device_context_CreateBitmapBrush(
@@ -112,8 +133,10 @@ static HRESULT WINAPI d2d_device_context_CreateBitmapBrush(
         ID2D1BitmapBrush **brush)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
-    return E_NOTIMPL;
+    TRACE("This %p, bitmap %p, bitmap_brush_desc %p, brush_desc %p, brush %p.\n",
+            This, bitmap, bitmap_brush_desc, brush_desc, brush);
+    return ID2D1RenderTarget_CreateBitmapBrush(This->dxgi_target,
+            bitmap, bitmap_brush_desc, brush_desc, brush);
 }
 
 static HRESULT WINAPI d2d_device_context_CreateSolidColorBrush(
@@ -123,8 +146,8 @@ static HRESULT WINAPI d2d_device_context_CreateSolidColorBrush(
         ID2D1SolidColorBrush **brush)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
-    return E_NOTIMPL;
+    TRACE("This %p, color %p, desc %p, brush %p.\n", This, color, desc, brush);
+    return ID2D1RenderTarget_CreateSolidColorBrush(This->dxgi_target, color, desc, brush);
 }
 
 static HRESULT WINAPI d2d_device_context_CreateGradientStopCollection(
@@ -136,8 +159,9 @@ static HRESULT WINAPI d2d_device_context_CreateGradientStopCollection(
         ID2D1GradientStopCollection **gradient)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
-    return E_NOTIMPL;
+    TRACE("This %p, stops %p, gradient %p.\n", This, stops, gradient);
+    return ID2D1RenderTarget_CreateGradientStopCollection(This->dxgi_target,
+            stops, stop_count, gamma, extend_mode, gradient);
 }
 
 static HRESULT WINAPI d2d_device_context_CreateLinearGradientBrush(
@@ -148,8 +172,10 @@ static HRESULT WINAPI d2d_device_context_CreateLinearGradientBrush(
         ID2D1LinearGradientBrush **brush)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
-    return E_NOTIMPL;
+    TRACE("This %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p.\n",
+            This, gradient_brush_desc, brush_desc, gradient, brush);
+    return ID2D1RenderTarget_CreateLinearGradientBrush(This->dxgi_target,
+            gradient_brush_desc, brush_desc, gradient, brush);
 }
 
 static HRESULT WINAPI d2d_device_context_CreateRadialGradientBrush(
@@ -160,8 +186,10 @@ static HRESULT WINAPI d2d_device_context_CreateRadialGradientBrush(
         ID2D1RadialGradientBrush **brush)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
-    return E_NOTIMPL;
+    TRACE("This %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p.\n",
+            This, gradient_brush_desc, brush_desc, gradient, brush);
+    return ID2D1RenderTarget_CreateRadialGradientBrush(This->dxgi_target,
+            gradient_brush_desc, brush_desc, gradient, brush);
 }
 
 static HRESULT WINAPI d2d_device_context_CreateCompatibleRenderTarget(
@@ -173,8 +201,10 @@ static HRESULT WINAPI d2d_device_context_CreateCompatibleRenderTarget(
         ID2D1BitmapRenderTarget **render_target)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
-    return E_NOTIMPL;
+    TRACE("This %p, size %p, pixel_size %p, format %p, render_target %p.\n",
+            This, size, pixel_size, format, render_target);
+    return ID2D1RenderTarget_CreateCompatibleRenderTarget(This->dxgi_target,
+            size, pixel_size, format, options, render_target);
 }
 
 static HRESULT WINAPI d2d_device_context_CreateLayer(
@@ -183,8 +213,8 @@ static HRESULT WINAPI d2d_device_context_CreateLayer(
         ID2D1Layer **layer)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
-    return E_NOTIMPL;
+    TRACE("This %p, size %p, layer %p.\n", This, size, layer);
+    return ID2D1RenderTarget_CreateLayer(This->dxgi_target, size, layer);
 }
 
 static HRESULT WINAPI d2d_device_context_CreateMesh(
@@ -192,8 +222,8 @@ static HRESULT WINAPI d2d_device_context_CreateMesh(
         ID2D1Mesh **mesh)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
-    return E_NOTIMPL;
+    TRACE("This %p, mesh %p.\n", This, mesh);
+    return ID2D1RenderTarget_CreateMesh(This->dxgi_target, mesh);
 }
 
 static void WINAPI d2d_device_context_DrawLine(
@@ -205,7 +235,8 @@ static void WINAPI d2d_device_context_DrawLine(
         ID2D1StrokeStyle *stroke_style)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p, brush %p, stroke_style %p.\n", This, brush, stroke_style);
+    ID2D1RenderTarget_DrawLine(This->dxgi_target, p0, p1, brush, stroke_width, stroke_style);
 }
 
 static void WINAPI d2d_device_context_DrawRectangle(
@@ -216,7 +247,8 @@ static void WINAPI d2d_device_context_DrawRectangle(
         ID2D1StrokeStyle *stroke_style)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p, rect %p, brush %p, stroke_style %p.\n", This, rect, brush, stroke_style);
+    ID2D1RenderTarget_DrawRectangle(This->dxgi_target, rect, brush, stroke_width, stroke_style);
 }
 
 static void WINAPI d2d_device_context_FillRectangle(
@@ -225,7 +257,8 @@ static void WINAPI d2d_device_context_FillRectangle(
         ID2D1Brush *brush)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p, rect %p, brush %p.\n", This, rect, brush);
+    ID2D1RenderTarget_FillRectangle(This->dxgi_target, rect, brush);
 }
 
 static void WINAPI d2d_device_context_DrawRoundedRectangle(
@@ -236,7 +269,8 @@ static void WINAPI d2d_device_context_DrawRoundedRectangle(
         ID2D1StrokeStyle *stroke_style)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p, rect %p, brush %p, stroke_style %p.\n", This, rect, brush, stroke_style);
+    ID2D1RenderTarget_DrawRoundedRectangle(This->dxgi_target, rect, brush, stroke_width, stroke_style);
 }
 
 static void WINAPI d2d_device_context_FillRoundedRectangle(
@@ -245,7 +279,8 @@ static void WINAPI d2d_device_context_FillRoundedRectangle(
         ID2D1Brush *brush)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p, rect %p, brush %p.\n", This, rect, brush);
+    ID2D1RenderTarget_FillRoundedRectangle(This->dxgi_target, rect, brush);
 }
 
 static void WINAPI d2d_device_context_DrawEllipse(
@@ -256,7 +291,8 @@ static void WINAPI d2d_device_context_DrawEllipse(
         ID2D1StrokeStyle *stroke_style)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p, ellipse %p, brush %p, stroke_style %p.\n", This, ellipse, brush, stroke_style);
+    ID2D1RenderTarget_DrawEllipse(This->dxgi_target, ellipse, brush, stroke_width, stroke_style);
 }
 
 static void WINAPI d2d_device_context_FillEllipse(
@@ -265,7 +301,8 @@ static void WINAPI d2d_device_context_FillEllipse(
         ID2D1Brush *brush)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p, ellipse %p, brush %p.\n", This, ellipse, brush);
+    ID2D1RenderTarget_FillEllipse(This->dxgi_target, ellipse, brush);
 }
 
 static void WINAPI d2d_device_context_DrawGeometry(
@@ -276,7 +313,8 @@ static void WINAPI d2d_device_context_DrawGeometry(
         ID2D1StrokeStyle *stroke_style)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p, geometry %p, brush %p, stroke_style %p.\n", This, geometry, brush, stroke_style);
+    ID2D1RenderTarget_DrawGeometry(This->dxgi_target, geometry, brush, stroke_width, stroke_style);
 }
 
 static void WINAPI d2d_device_context_FillGeometry(
@@ -286,7 +324,8 @@ static void WINAPI d2d_device_context_FillGeometry(
         ID2D1Brush *opacity_brush)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p, geometry %p, brush %p, opacity_brush %p.\n", This, geometry, brush, opacity_brush);
+    ID2D1RenderTarget_FillGeometry(This->dxgi_target, geometry, brush, opacity_brush);
 }
 
 static void WINAPI d2d_device_context_FillMesh(
@@ -295,7 +334,8 @@ static void WINAPI d2d_device_context_FillMesh(
         ID2D1Brush *brush)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p, mesh %p, brush %p.\n", This, mesh, brush);
+    ID2D1RenderTarget_FillMesh(This->dxgi_target, mesh, brush);
 }
 
 static void WINAPI d2d_device_context_FillOpacityMask(
@@ -307,7 +347,9 @@ static void WINAPI d2d_device_context_FillOpacityMask(
         const D2D1_RECT_F *src_rect)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p, mask %p, brush %p.\n", This, mask, brush);
+    ID2D1RenderTarget_FillOpacityMask(This->dxgi_target,
+            mask, brush, content, dst_rect, src_rect);
 }
 
 static void WINAPI d2d_device_context_DrawBitmap(
@@ -319,7 +361,9 @@ static void WINAPI d2d_device_context_DrawBitmap(
         const D2D1_RECT_F *src_rect)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p, bitmap %p.\n", This, bitmap);
+    ID2D1RenderTarget_DrawBitmap(This->dxgi_target,
+            bitmap, dst_rect, opacity, interpolation_mode, src_rect);
 }
 
 static void WINAPI d2d_device_context_DrawText(
@@ -333,7 +377,9 @@ static void WINAPI d2d_device_context_DrawText(
         DWRITE_MEASURING_MODE measuring_mode)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p, string %s.\n", This, debugstr_w(string));
+    ID2D1RenderTarget_DrawText(This->dxgi_target, string, string_len,
+            text_format, layout_rect, brush, options, measuring_mode);
 }
 
 static void WINAPI d2d_device_context_DrawTextLayout(
@@ -344,7 +390,8 @@ static void WINAPI d2d_device_context_DrawTextLayout(
         D2D1_DRAW_TEXT_OPTIONS options)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p, layout %p, brush %p.\n", This, layout, brush);
+    ID2D1RenderTarget_DrawTextLayout(This->dxgi_target, origin, layout, brush, options);
 }
 
 static void WINAPI d2d_device_context_DrawGlyphRun(
@@ -355,7 +402,9 @@ static void WINAPI d2d_device_context_DrawGlyphRun(
         DWRITE_MEASURING_MODE measuring_mode)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p, glyph_run %p, brush %p.\n", This, glyph_run, brush);
+    ID2D1RenderTarget_DrawGlyphRun(This->dxgi_target,
+            baseline_origin, glyph_run, brush, measuring_mode);
 }
 
 static void WINAPI d2d_device_context_SetTransform(
@@ -363,7 +412,8 @@ static void WINAPI d2d_device_context_SetTransform(
         const D2D1_MATRIX_3X2_F *transform)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p, transform %p.\n", This, transform);
+    ID2D1RenderTarget_SetTransform(This->dxgi_target, transform);
 }
 
 static void WINAPI d2d_device_context_GetTransform(
@@ -371,7 +421,8 @@ static void WINAPI d2d_device_context_GetTransform(
         D2D1_MATRIX_3X2_F *transform)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p, transform %p.\n", This, transform);
+    ID2D1RenderTarget_GetTransform(This->dxgi_target, transform);
 }
 
 static void WINAPI d2d_device_context_SetAntialiasMode(
@@ -379,15 +430,16 @@ static void WINAPI d2d_device_context_SetAntialiasMode(
         D2D1_ANTIALIAS_MODE antialias_mode)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p.\n", This);
+    ID2D1RenderTarget_SetAntialiasMode(This->dxgi_target, antialias_mode);
 }
 
 static D2D1_ANTIALIAS_MODE WINAPI d2d_device_context_GetAntialiasMode(
         ID2D1DeviceContext *iface)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
-    return D2D1_ANTIALIAS_MODE_PER_PRIMITIVE;
+    TRACE("This %p.\n", This);
+    return ID2D1RenderTarget_GetAntialiasMode(This->dxgi_target);
 }
 
 static void WINAPI d2d_device_context_SetTextAntialiasMode(
@@ -395,15 +447,16 @@ static void WINAPI d2d_device_context_SetTextAntialiasMode(
         D2D1_TEXT_ANTIALIAS_MODE antialias_mode)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p.\n", This);
+    ID2D1RenderTarget_SetTextAntialiasMode(This->dxgi_target, antialias_mode);
 }
 
 static D2D1_TEXT_ANTIALIAS_MODE WINAPI d2d_device_context_GetTextAntialiasMode(
         ID2D1DeviceContext *iface)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
-    return D2D1_TEXT_ANTIALIAS_MODE_DEFAULT;
+    TRACE("This %p.\n", This);
+    return ID2D1RenderTarget_GetTextAntialiasMode(This->dxgi_target);
 }
 
 static void WINAPI d2d_device_context_SetTextRenderingParams(
@@ -411,7 +464,8 @@ static void WINAPI d2d_device_context_SetTextRenderingParams(
         IDWriteRenderingParams *text_rendering_params)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p.\n", This);
+    ID2D1RenderTarget_SetTextRenderingParams(This->dxgi_target, text_rendering_params);
 }
 
 static void WINAPI d2d_device_context_GetTextRenderingParams(
@@ -419,7 +473,8 @@ static void WINAPI d2d_device_context_GetTextRenderingParams(
         IDWriteRenderingParams **text_rendering_params)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p.\n", This);
+    ID2D1RenderTarget_GetTextRenderingParams(This->dxgi_target, text_rendering_params);
 }
 
 static void WINAPI d2d_device_context_SetTags(
@@ -428,7 +483,8 @@ static void WINAPI d2d_device_context_SetTags(
         D2D1_TAG tag2)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p.\n", This);
+    ID2D1RenderTarget_SetTags(This->dxgi_target, tag1, tag2);
 }
 
 static void WINAPI d2d_device_context_GetTags(
@@ -437,7 +493,8 @@ static void WINAPI d2d_device_context_GetTags(
         D2D1_TAG *tag2)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p.\n", This);
+    ID2D1RenderTarget_GetTags(This->dxgi_target, tag1, tag2);
 }
 
 static void WINAPI d2d_device_context_PushLayer(
@@ -446,14 +503,16 @@ static void WINAPI d2d_device_context_PushLayer(
         ID2D1Layer *layer)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p.\n", This);
+    ID2D1RenderTarget_PushLayer(This->dxgi_target, layer_parameters, layer);
 }
 
 static void WINAPI d2d_device_context_PopLayer(
         ID2D1DeviceContext *iface)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p.\n", This);
+    ID2D1RenderTarget_PopLayer(This->dxgi_target);
 }
 
 static HRESULT WINAPI d2d_device_context_Flush(
@@ -462,8 +521,8 @@ static HRESULT WINAPI d2d_device_context_Flush(
         D2D1_TAG *tag2)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
-    return E_NOTIMPL;
+    TRACE("This %p.\n", This);
+    return ID2D1RenderTarget_Flush(This->dxgi_target, tag1, tag2);
 }
 
 static void WINAPI d2d_device_context_SaveDrawingState(
@@ -471,7 +530,8 @@ static void WINAPI d2d_device_context_SaveDrawingState(
         ID2D1DrawingStateBlock *state_block)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p, state_block %p.\n", This, state_block);
+    ID2D1RenderTarget_SaveDrawingState(This->dxgi_target, state_block);
 }
 
 static void WINAPI d2d_device_context_RestoreDrawingState(
@@ -479,7 +539,8 @@ static void WINAPI d2d_device_context_RestoreDrawingState(
         ID2D1DrawingStateBlock *state_block)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p, state_block %p.\n", This, state_block);
+    ID2D1RenderTarget_RestoreDrawingState(This->dxgi_target, state_block);
 }
 
 static void WINAPI d2d_device_context_PushAxisAlignedClip(
@@ -488,14 +549,16 @@ static void WINAPI d2d_device_context_PushAxisAlignedClip(
         D2D1_ANTIALIAS_MODE antialias_mode)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p.\n", This);
+    ID2D1RenderTarget_PushAxisAlignedClip(This->dxgi_target, clip_rect, antialias_mode);
 }
 
 static void WINAPI d2d_device_context_PopAxisAlignedClip(
         ID2D1DeviceContext *iface)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p.\n", This);
+    ID2D1RenderTarget_PopAxisAlignedClip(This->dxgi_target);
 }
 
 static void WINAPI d2d_device_context_Clear(
@@ -503,14 +566,16 @@ static void WINAPI d2d_device_context_Clear(
         const D2D1_COLOR_F *color)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p.\n", This);
+    ID2D1RenderTarget_Clear(This->dxgi_target, color);
 }
 
 static void WINAPI d2d_device_context_BeginDraw(
         ID2D1DeviceContext *iface)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p.\n", This);
+    ID2D1RenderTarget_BeginDraw(This->dxgi_target);
 }
 
 static HRESULT WINAPI d2d_device_context_EndDraw(
@@ -519,8 +584,8 @@ static HRESULT WINAPI d2d_device_context_EndDraw(
         D2D1_TAG *tag2)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
-    return E_NOTIMPL;
+    TRACE("This %p.\n", This);
+    return ID2D1RenderTarget_EndDraw(This->dxgi_target, tag1, tag2);
 }
 
 static D2D1_PIXEL_FORMAT * WINAPI d2d_device_context_GetPixelFormat(
@@ -528,8 +593,9 @@ static D2D1_PIXEL_FORMAT * WINAPI d2d_device_context_GetPixelFormat(
         D2D1_PIXEL_FORMAT *__ret)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
-    return NULL;
+    TRACE("This %p, __ret %p.\n", This, __ret);
+    *__ret = ID2D1RenderTarget_GetPixelFormat(This->dxgi_target);
+    return __ret;
 }
 
 static void WINAPI d2d_device_context_SetDpi(
@@ -538,7 +604,8 @@ static void WINAPI d2d_device_context_SetDpi(
         float dpi_y)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p.\n", This);
+    ID2D1RenderTarget_SetDpi(This->dxgi_target, dpi_x, dpi_y);
 }
 
 static void WINAPI d2d_device_context_GetDpi(
@@ -547,7 +614,8 @@ static void WINAPI d2d_device_context_GetDpi(
         float *dpi_y)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p.\n", This);
+    ID2D1RenderTarget_GetDpi(This->dxgi_target, dpi_x, dpi_y);
 }
 
 static D2D1_SIZE_F * WINAPI d2d_device_context_GetSize(
@@ -555,8 +623,9 @@ static D2D1_SIZE_F * WINAPI d2d_device_context_GetSize(
         D2D1_SIZE_F *__ret)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
-    return NULL;
+    TRACE("This %p, __ret %p.\n", This, __ret);
+    *__ret = ID2D1RenderTarget_GetSize(This->dxgi_target);
+    return __ret;
 }
 
 static D2D1_SIZE_U * WINAPI d2d_device_context_GetPixelSize(
@@ -564,16 +633,17 @@ static D2D1_SIZE_U * WINAPI d2d_device_context_GetPixelSize(
         D2D1_SIZE_U *__ret)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
-    return NULL;
+    TRACE("This %p, __ret %p.\n", This, __ret);
+    *__ret = ID2D1RenderTarget_GetPixelSize(This->dxgi_target);
+    return __ret;
 }
 
 static UINT32 WINAPI d2d_device_context_GetMaximumBitmapSize(
         ID2D1DeviceContext *iface)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
-    return 0;
+    TRACE("This %p.\n", This);
+    return ID2D1RenderTarget_GetMaximumBitmapSize(This->dxgi_target);
 }
 
 static BOOL WINAPI d2d_device_context_IsSupported(
@@ -581,8 +651,8 @@ static BOOL WINAPI d2d_device_context_IsSupported(
         const D2D1_RENDER_TARGET_PROPERTIES *desc)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
-    return FALSE;
+    TRACE("This %p.\n", This);
+    return ID2D1RenderTarget_IsSupported(This->dxgi_target, desc);
 }
 
 static HRESULT WINAPI d2d_device_context_ID2D1DeviceContext_CreateBitmap(
@@ -765,7 +835,12 @@ static void WINAPI d2d_device_context_GetDevice(
         ID2D1Device **device)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    TRACE("This %p, device %p.\n", This, device);
+    if (device == NULL)
+        return;
+
+    ID2D1Device_AddRef(This->device);
+    *device = This->device;
 }
 
 static void WINAPI d2d_device_context_SetTarget(
@@ -773,7 +848,34 @@ static void WINAPI d2d_device_context_SetTarget(
         ID2D1Image *target)
 {
     struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface);
-    FIXME("%p stub!\n", This);
+    IDXGISurface *surface;
+    IDXGISurface1 *surface1;
+    ID2D1Bitmap1 *bitmap;
+    HRESULT hr;
+
+    TRACE("This %p, target %p.\n", This, target);
+    if (FAILED(hr = ID2D1Image_QueryInterface(target, &IID_ID2D1Bitmap1, (void **)&bitmap)))
+    {
+        FIXME("Provided ID2D1Image type not yet supported, hr %#x.\n", hr);
+        return;
+    }
+
+    ID2D1Bitmap1_GetSurface(bitmap, &surface);
+    ID2D1Bitmap1_Release(bitmap);
+    hr = IDXGISurface_QueryInterface(surface, &IID_IDXGISurface1, (void **)&surface1);
+    IDXGISurface_Release(surface);
+    if (FAILED(hr))
+    {
+        WARN("Failed to query IDXGISurface1, hr %#x.\n", hr);
+        return;
+    }
+
+    if (FAILED(d2d_d3d_render_target_create_rtv(This->dxgi_target, surface1)))
+    {
+        WARN("Failed to set renderviewtarget, hr %#x.\n", hr);
+    }
+
+    IDXGISurface1_Release(surface1);
 }
 
 static void WINAPI d2d_device_context_GetTarget(
@@ -1038,3 +1140,41 @@ static const struct ID2D1DeviceContextVtbl d2d_device_context_vtbl =
     d2d_device_context_GetEffectRequiredInputRectangles,
     d2d_device_context_ID2D1DeviceContext_FillOpacityMask,
 };
+
+HRESULT d2d_device_context_init(struct d2d_device_context *This,
+        ID2D1Device *device_iface, D2D1_DEVICE_CONTEXT_OPTIONS options,
+        ID3D10Device *d3d_device)
+{
+    HRESULT hr;
+    ID2D1Factory *factory;
+    D2D1_RENDER_TARGET_PROPERTIES desc;
+    desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
+    desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
+    desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_UNKNOWN;
+    desc.dpiX = 96.0f;
+    desc.dpiY = 96.0f;
+    desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
+    desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
+
+    if (options == D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS)
+        FIXME("D2D1_DEVICE_CONTEXT_OPTIONS ignored.");
+
+    This->ID2D1DeviceContext_iface.lpVtbl = &d2d_device_context_vtbl;
+    This->refcount = 1;
+    This->device = device_iface;
+
+    ID2D1Device_GetFactory(This->device, &factory);
+    hr = d2d_d3d_create_render_target_with_device(factory, d3d_device,
+            (IUnknown *)&This->ID2D1DeviceContext_iface,
+            &desc, &This->dxgi_target);
+    ID2D1Factory_Release(factory);
+    if (FAILED(hr))
+    {
+        WARN("Failed to create base render target, hr %#x.\n", hr);
+        return hr;
+    }
+
+    ID2D1Device_AddRef(This->device);
+
+    return S_OK;
+}
diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c
index 1299c849ac..afab3910f7 100644
--- a/dlls/d2d1/render_target.c
+++ b/dlls/d2d1/render_target.c
@@ -2152,7 +2152,7 @@ static const struct ID2D1GdiInteropRenderTargetVtbl d2d_gdi_interop_render_targe
 };
 
 static HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target, ID2D1Factory *factory,
-        IDXGISurface *surface, IUnknown *outer_unknown, const D2D1_RENDER_TARGET_PROPERTIES *desc)
+        IDXGISurface *surface, ID3D10Device *device, IUnknown *outer_unknown, const D2D1_RENDER_TARGET_PROPERTIES *desc)
 {
     D3D10_SUBRESOURCE_DATA buffer_data;
     D3D10_STATE_BLOCK_MASK state_mask;
@@ -3041,25 +3041,41 @@ static HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_t
     render_target->outer_unknown = outer_unknown ? outer_unknown :
             (IUnknown *)&render_target->ID2D1RenderTarget_iface;
 
-    if (FAILED(hr = IDXGISurface_GetDevice(surface, &IID_ID3D10Device, (void **)&render_target->device)))
+    if (surface == NULL)
     {
-        WARN("Failed to get device interface, hr %#x.\n", hr);
-        ID2D1Factory_Release(render_target->factory);
-        return hr;
+        ID3D10Device_AddRef(render_target->device = device);
     }
-
-    if (FAILED(hr = IDXGISurface_QueryInterface(surface, &IID_ID3D10Resource, (void **)&resource)))
+    else
     {
-        WARN("Failed to get ID3D10Resource interface, hr %#x.\n", hr);
-        goto err;
-    }
+        if (FAILED(hr = IDXGISurface_GetDevice(surface, &IID_ID3D10Device, (void **)&render_target->device)))
+        {
+            WARN("Failed to get device interface, hr %#x.\n", hr);
+            ID2D1Factory_Release(render_target->factory);
+            return hr;
+        }
 
-    hr = ID3D10Device_CreateRenderTargetView(render_target->device, resource, NULL, &render_target->view);
-    ID3D10Resource_Release(resource);
-    if (FAILED(hr))
-    {
-        WARN("Failed to create rendertarget view, hr %#x.\n", hr);
-        goto err;
+        if (FAILED(hr = IDXGISurface_QueryInterface(surface, &IID_ID3D10Resource, (void **)&resource)))
+        {
+            WARN("Failed to get ID3D10Resource interface, hr %#x.\n", hr);
+            goto err;
+        }
+
+        hr = ID3D10Device_CreateRenderTargetView(render_target->device, resource, NULL, &render_target->view);
+        ID3D10Resource_Release(resource);
+        if (FAILED(hr))
+        {
+            WARN("Failed to create rendertarget view, hr %#x.\n", hr);
+            goto err;
+        }
+
+        if (FAILED(hr = IDXGISurface_GetDesc(surface, &surface_desc)))
+        {
+            WARN("Failed to get surface desc, hr %#x.\n", hr);
+            goto err;
+        }
+
+        render_target->pixel_size.width = surface_desc.Width;
+        render_target->pixel_size.height = surface_desc.Height;
     }
 
     if (FAILED(hr = D3D10StateBlockMaskEnableAll(&state_mask)))
@@ -3184,15 +3200,7 @@ static HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_t
         goto err;
     }
 
-    if (FAILED(hr = IDXGISurface_GetDesc(surface, &surface_desc)))
-    {
-        WARN("Failed to get surface desc, hr %#x.\n", hr);
-        goto err;
-    }
-
     render_target->desc.pixelFormat = desc->pixelFormat;
-    render_target->pixel_size.width = surface_desc.Width;
-    render_target->pixel_size.height = surface_desc.Height;
     render_target->drawing_state.transform = identity;
 
     if (!d2d_clip_stack_init(&render_target->clip_stack))
@@ -3246,7 +3254,31 @@ HRESULT d2d_d3d_create_render_target(ID2D1Factory *factory, IDXGISurface *surfac
     if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
         return E_OUTOFMEMORY;
 
-    if (FAILED(hr = d2d_d3d_render_target_init(object, factory, surface, outer_unknown, desc)))
+    if (FAILED(hr = d2d_d3d_render_target_init(object, factory, surface, NULL, outer_unknown, 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->ID2D1RenderTarget_iface;
+
+    return S_OK;
+}
+
+HRESULT d2d_d3d_create_render_target_with_device(ID2D1Factory *factory,
+        ID3D10Device *device, IUnknown *outer_unknown,
+        const D2D1_RENDER_TARGET_PROPERTIES *desc,
+        ID2D1RenderTarget **render_target)
+{
+    struct d2d_d3d_render_target *object;
+    HRESULT hr;
+
+    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+        return E_OUTOFMEMORY;
+
+    if (FAILED(hr = d2d_d3d_render_target_init(object, factory, NULL, device, outer_unknown, desc)))
     {
         WARN("Failed to initialize render target, hr %#x.\n", hr);
         HeapFree(GetProcessHeap(), 0, object);
-- 
2.13.6




More information about the wine-devel mailing list