[PATCH 5/6] d2d1: Introduce new ID3D10Device access wrappers.
Rémi Bernon
rbernon at codeweavers.com
Mon Jan 18 06:57:45 CST 2021
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
dlls/d2d1/bitmap.c | 47 +++++++++--
dlls/d2d1/brush.c | 10 ++-
dlls/d2d1/d2d1_private.h | 4 +-
dlls/d2d1/device.c | 147 ++++++++++++++++++++++++++--------
dlls/d2d1/wic_render_target.c | 24 +++++-
5 files changed, 188 insertions(+), 44 deletions(-)
diff --git a/dlls/d2d1/bitmap.c b/dlls/d2d1/bitmap.c
index bc58d7d92d5..51fefe535fa 100644
--- a/dlls/d2d1/bitmap.c
+++ b/dlls/d2d1/bitmap.c
@@ -152,6 +152,7 @@ static HRESULT STDMETHODCALLTYPE d2d_bitmap_CopyFromMemory(ID2D1Bitmap1 *iface,
struct d2d_bitmap *bitmap = impl_from_ID2D1Bitmap1(iface);
ID3D10Device *device;
D3D10_BOX box;
+ HRESULT hr;
TRACE("iface %p, dst_rect %p, src_data %p, pitch %u.\n", iface, dst_rect, src_data, pitch);
@@ -165,10 +166,15 @@ static HRESULT STDMETHODCALLTYPE d2d_bitmap_CopyFromMemory(ID2D1Bitmap1 *iface,
box.back = 1;
}
- ID3D10Resource_GetDevice(bitmap->resource, &device);
+ if (FAILED(hr = d2d_device_get_d3d10_device(bitmap->device, &device)))
+ {
+ ERR("Failed to get ID3D10Device interface, hr %#x.\n", hr);
+ return hr;
+ }
+
ID3D10Device_UpdateSubresource(device, bitmap->resource, 0, dst_rect ? &box : NULL, src_data, pitch, 0);
- ID3D10Device_Release(device);
+ d2d_device_release_d3d10_device(bitmap->device, device);
return S_OK;
}
@@ -316,6 +322,7 @@ HRESULT d2d_bitmap_create(struct d2d_device_context *context, D2D1_SIZE_U size,
D2D1_BITMAP_PROPERTIES1 bitmap_desc;
D3D10_TEXTURE2D_DESC texture_desc;
ID3D10Texture2D *texture;
+ ID3D10Device *d3d10_device;
HRESULT hr;
if (!format_supported(&desc->pixelFormat))
@@ -360,10 +367,17 @@ HRESULT d2d_bitmap_create(struct d2d_device_context *context, D2D1_SIZE_U size,
resource_data.pSysMem = src_data;
resource_data.SysMemPitch = pitch;
- if (FAILED(hr = ID3D10Device_CreateTexture2D(context->d3d_device, &texture_desc,
+ if (FAILED(hr = d2d_device_get_d3d10_device(context->device, &d3d10_device)))
+ {
+ ERR("Failed to get ID3D10Device interface, hr %#x.\n", hr);
+ return hr;
+ }
+
+ if (FAILED(hr = ID3D10Device_CreateTexture2D(d3d10_device, &texture_desc,
src_data ? &resource_data : NULL, &texture)))
{
ERR("Failed to create texture, hr %#x.\n", hr);
+ d2d_device_release_d3d10_device(context->device, d3d10_device);
return hr;
}
@@ -374,6 +388,7 @@ HRESULT d2d_bitmap_create(struct d2d_device_context *context, D2D1_SIZE_U size,
}
ID3D10Texture2D_Release(texture);
+ d2d_device_release_d3d10_device(context->device, d3d10_device);
return *bitmap ? S_OK : E_OUTOFMEMORY;
}
@@ -386,9 +401,15 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid,
{
struct d2d_bitmap *src_impl = unsafe_impl_from_ID2D1Bitmap(data);
ID2D1Factory *factory;
- ID3D10Device *device;
+ ID3D10Device *device, *context_device;
HRESULT hr = S_OK;
+ if (FAILED(hr = d2d_device_get_d3d10_device(context->device, &context_device)))
+ {
+ ERR("Failed to get ID3D10Device interface, hr %#x.\n", hr);
+ goto failed;
+ }
+
ID2D1Device_GetFactory(src_impl->device, &factory);
if (factory != context->factory)
{
@@ -400,7 +421,7 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid,
ID3D10Resource_GetDevice(src_impl->resource, &device);
ID3D10Device_Release(device);
- if (device != context->d3d_device)
+ if (device != context_device)
{
hr = D2DERR_UNSUPPORTED_OPERATION;
goto failed;
@@ -434,6 +455,7 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid,
TRACE("Created bitmap %p.\n", *bitmap);
failed:
+ d2d_device_release_d3d10_device(context->device, context_device);
return hr;
}
@@ -443,26 +465,35 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid,
IDXGISurface *surface = data;
ID3D10Resource *resource;
D2D1_SIZE_U pixel_size;
- ID3D10Device *device;
+ ID3D10Device *device, *context_device;
HRESULT hr;
+ if (FAILED(hr = d2d_device_get_d3d10_device(context->device, &context_device)))
+ {
+ ERR("Failed to get ID3D10Device interface, hr %#x.\n", hr);
+ return hr;
+ }
+
if (FAILED(IDXGISurface_QueryInterface(surface, &IID_ID3D10Resource, (void **)&resource)))
{
WARN("Failed to get d3d resource from dxgi surface.\n");
+ d2d_device_release_d3d10_device(context->device, context_device);
return E_FAIL;
}
ID3D10Resource_GetDevice(resource, &device);
ID3D10Device_Release(device);
- if (device != context->d3d_device)
+ if (device != context_device)
{
ID3D10Resource_Release(resource);
+ d2d_device_release_d3d10_device(context->device, context_device);
return D2DERR_UNSUPPORTED_OPERATION;
}
if (!(*bitmap = heap_alloc_zero(sizeof(**bitmap))))
{
ID3D10Resource_Release(resource);
+ d2d_device_release_d3d10_device(context->device, context_device);
return E_OUTOFMEMORY;
}
@@ -471,6 +502,7 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid,
{
WARN("Failed to get surface desc, hr %#x.\n", hr);
ID3D10Resource_Release(resource);
+ d2d_device_release_d3d10_device(context->device, context_device);
return hr;
}
@@ -501,6 +533,7 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid,
ID3D10Resource_Release(resource);
TRACE("Created bitmap %p.\n", *bitmap);
+ d2d_device_release_d3d10_device(context->device, context_device);
return S_OK;
}
diff --git a/dlls/d2d1/brush.c b/dlls/d2d1/brush.c
index 07d2e26a143..cc02495a116 100644
--- a/dlls/d2d1/brush.c
+++ b/dlls/d2d1/brush.c
@@ -1267,6 +1267,7 @@ HRESULT d2d_brush_get_ps_cb(struct d2d_brush *brush, struct d2d_brush *opacity_b
D3D10_SUBRESOURCE_DATA buffer_data;
struct d2d_ps_cb cb_data = {0};
D3D10_BUFFER_DESC buffer_desc;
+ ID3D10Device *d3d10_device;
HRESULT hr;
cb_data.outline = outline;
@@ -1286,9 +1287,16 @@ HRESULT d2d_brush_get_ps_cb(struct d2d_brush *brush, struct d2d_brush *opacity_b
buffer_data.SysMemPitch = 0;
buffer_data.SysMemSlicePitch = 0;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, ps_cb)))
+ if (FAILED(hr = d2d_device_get_d3d10_device(render_target->device, &d3d10_device)))
+ {
+ ERR("Failed to acquire D3D10 device, hr %#x.\n", hr);
+ return hr;
+ }
+
+ if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, ps_cb)))
ERR("Failed to create constant buffer, hr %#x.\n", hr);
+ d2d_device_release_d3d10_device(render_target->device, d3d10_device);
return hr;
}
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h
index 153113cafa9..cb3421478f0 100644
--- a/dlls/d2d1/d2d1_private.h
+++ b/dlls/d2d1/d2d1_private.h
@@ -139,7 +139,6 @@ struct d2d_device_context
ID2D1Factory *factory;
ID2D1Device *device;
- ID3D10Device *d3d_device;
struct d2d_bitmap *target;
ID3D10StateBlock *stateblock;
struct d2d_shape_resources shape_resources[D2D_SHAPE_TYPE_COUNT];
@@ -543,6 +542,9 @@ struct d2d_device
ID3D10Multithread *d3d10_mt;
};
+HRESULT d2d_device_get_d3d10_device(ID2D1Device *iface, ID3D10Device **d3d10_device) DECLSPEC_HIDDEN;
+void d2d_device_release_d3d10_device(ID2D1Device *iface, ID3D10Device *d3d10_device) DECLSPEC_HIDDEN;
+
void d2d_device_init(struct d2d_device *device, ID2D1Factory1 *factory, IDXGIDevice *dxgi_device) DECLSPEC_HIDDEN;
struct d2d_effect
diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c
index acbcab5caeb..cfa28e984f9 100644
--- a/dlls/d2d1/device.c
+++ b/dlls/d2d1/device.c
@@ -122,7 +122,7 @@ static void d2d_device_context_draw(struct d2d_device_context *render_target, en
ID3D10Buffer *vs_cb, ID3D10Buffer *ps_cb, struct d2d_brush *brush, struct d2d_brush *opacity_brush)
{
struct d2d_shape_resources *shape_resources = &render_target->shape_resources[shape_type];
- ID3D10Device *device = render_target->d3d_device;
+ ID3D10Device *device = NULL;
D3D10_RECT scissor_rect;
unsigned int offset;
D3D10_VIEWPORT vp;
@@ -135,9 +135,16 @@ static void d2d_device_context_draw(struct d2d_device_context *render_target, en
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
+ if (FAILED(hr = d2d_device_get_d3d10_device(render_target->device, &device)))
+ {
+ ERR("Failed to get ID3D10Device interface, hr %#x.\n", hr);
+ return;
+ }
+
if (FAILED(hr = render_target->stateblock->lpVtbl->Capture(render_target->stateblock)))
{
WARN("Failed to capture stateblock, hr %#x.\n", hr);
+ d2d_device_release_d3d10_device(render_target->device, device);
return;
}
@@ -188,6 +195,8 @@ static void d2d_device_context_draw(struct d2d_device_context *render_target, en
if (FAILED(hr = render_target->stateblock->lpVtbl->Apply(render_target->stateblock)))
WARN("Failed to apply stateblock, hr %#x.\n", hr);
+
+ d2d_device_release_d3d10_device(render_target->device, device);
}
static void d2d_device_context_set_error(struct d2d_device_context *context, HRESULT code)
@@ -274,7 +283,6 @@ static ULONG STDMETHODCALLTYPE d2d_device_context_inner_Release(IUnknown *iface)
context->stateblock->lpVtbl->Release(context->stateblock);
if (context->target)
ID2D1Bitmap1_Release(&context->target->ID2D1Bitmap1_iface);
- ID3D10Device_Release(context->d3d_device);
ID2D1Factory_Release(context->factory);
ID2D1Device_Release(context->device);
heap_free(context);
@@ -438,15 +446,23 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateGradientStopCollection
{
struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
struct d2d_gradient *object;
+ ID3D10Device *d3d10_device;
HRESULT hr;
TRACE("iface %p, stops %p, stop_count %u, gamma %#x, extend_mode %#x, gradient %p.\n",
iface, stops, stop_count, gamma, extend_mode, gradient);
- if (SUCCEEDED(hr = d2d_gradient_create(render_target->factory, render_target->d3d_device,
+ if (FAILED(hr = d2d_device_get_d3d10_device(render_target->device, &d3d10_device)))
+ {
+ ERR("Failed to get ID3D10Device1 interface, hr %#x.\n", hr);
+ return hr;
+ }
+
+ if (SUCCEEDED(hr = d2d_gradient_create(render_target->factory, d3d10_device,
stops, stop_count, gamma, extend_mode, &object)))
*gradient = &object->ID2D1GradientStopCollection_iface;
+ d2d_device_release_d3d10_device(render_target->device, d3d10_device);
return hr;
}
@@ -702,6 +718,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t
D3D10_SUBRESOURCE_DATA buffer_data;
D3D10_BUFFER_DESC buffer_desc;
const D2D1_MATRIX_3X2_F *w;
+ ID3D10Device *d3d10_device;
float tmp_x, tmp_y;
HRESULT hr;
struct
@@ -748,9 +765,16 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t
buffer_data.SysMemPitch = 0;
buffer_data.SysMemSlicePitch = 0;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vs_cb)))
+ if (FAILED(hr = d2d_device_get_d3d10_device(render_target->device, &d3d10_device)))
+ {
+ ERR("Failed to get ID3D10Device1 interface, hr %#x.\n", hr);
+ return;
+ }
+
+ if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &vs_cb)))
{
WARN("Failed to create constant buffer, hr %#x.\n", hr);
+ d2d_device_release_d3d10_device(render_target->device, d3d10_device);
return;
}
@@ -758,6 +782,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t
{
WARN("Failed to get ps constant buffer, hr %#x.\n", hr);
ID3D10Buffer_Release(vs_cb);
+ d2d_device_release_d3d10_device(render_target->device, d3d10_device);
return;
}
@@ -766,6 +791,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t
WARN("Failed to get ps constant buffer, hr %#x.\n", hr);
ID3D10Buffer_Release(vs_cb);
ID3D10Buffer_Release(ps_cb_bezier);
+ d2d_device_release_d3d10_device(render_target->device, d3d10_device);
return;
}
@@ -775,7 +801,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t
buffer_desc.BindFlags = D3D10_BIND_INDEX_BUFFER;
buffer_data.pSysMem = geometry->outline.faces;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ib)))
+ if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &ib)))
{
WARN("Failed to create index buffer, hr %#x.\n", hr);
goto done;
@@ -785,7 +811,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t
buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
buffer_data.pSysMem = geometry->outline.vertices;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb)))
+ if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &vb)))
{
ERR("Failed to create vertex buffer, hr %#x.\n", hr);
ID3D10Buffer_Release(ib);
@@ -805,7 +831,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t
buffer_desc.BindFlags = D3D10_BIND_INDEX_BUFFER;
buffer_data.pSysMem = geometry->outline.bezier_faces;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ib)))
+ if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &ib)))
{
WARN("Failed to create beziers index buffer, hr %#x.\n", hr);
goto done;
@@ -815,7 +841,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t
buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
buffer_data.pSysMem = geometry->outline.beziers;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb)))
+ if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &vb)))
{
ERR("Failed to create beziers vertex buffer, hr %#x.\n", hr);
ID3D10Buffer_Release(ib);
@@ -836,7 +862,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t
buffer_desc.BindFlags = D3D10_BIND_INDEX_BUFFER;
buffer_data.pSysMem = geometry->outline.arc_faces;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ib)))
+ if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &ib)))
{
WARN("Failed to create arcs index buffer, hr %#x.\n", hr);
goto done;
@@ -846,7 +872,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t
buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
buffer_data.pSysMem = geometry->outline.arcs;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb)))
+ if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &vb)))
{
ERR("Failed to create arcs vertex buffer, hr %#x.\n", hr);
ID3D10Buffer_Release(ib);
@@ -865,6 +891,7 @@ done:
ID3D10Buffer_Release(ps_cb_arc);
ID3D10Buffer_Release(ps_cb_bezier);
ID3D10Buffer_Release(vs_cb);
+ d2d_device_release_d3d10_device(render_target->device, d3d10_device);
}
static void STDMETHODCALLTYPE d2d_device_context_DrawGeometry(ID2D1DeviceContext *iface,
@@ -890,6 +917,7 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t
D3D10_SUBRESOURCE_DATA buffer_data;
D3D10_BUFFER_DESC buffer_desc;
D2D1_MATRIX_3X2_F *w;
+ ID3D10Device *d3d10_device;
float tmp_x, tmp_y;
HRESULT hr;
struct
@@ -936,9 +964,16 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t
buffer_data.SysMemPitch = 0;
buffer_data.SysMemSlicePitch = 0;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vs_cb)))
+ if (FAILED(hr = d2d_device_get_d3d10_device(render_target->device, &d3d10_device)))
+ {
+ ERR("Failed to get ID3D10Device1 interface, hr %#x.\n", hr);
+ return;
+ }
+
+ if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &vs_cb)))
{
WARN("Failed to create constant buffer, hr %#x.\n", hr);
+ d2d_device_release_d3d10_device(render_target->device, d3d10_device);
return;
}
@@ -946,6 +981,7 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t
{
WARN("Failed to get ps constant buffer, hr %#x.\n", hr);
ID3D10Buffer_Release(vs_cb);
+ d2d_device_release_d3d10_device(render_target->device, d3d10_device);
return;
}
@@ -954,6 +990,7 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t
WARN("Failed to get ps constant buffer, hr %#x.\n", hr);
ID3D10Buffer_Release(vs_cb);
ID3D10Buffer_Release(ps_cb_bezier);
+ d2d_device_release_d3d10_device(render_target->device, d3d10_device);
return;
}
@@ -963,7 +1000,7 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t
buffer_desc.BindFlags = D3D10_BIND_INDEX_BUFFER;
buffer_data.pSysMem = geometry->fill.faces;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ib)))
+ if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &ib)))
{
WARN("Failed to create index buffer, hr %#x.\n", hr);
goto done;
@@ -973,7 +1010,7 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t
buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
buffer_data.pSysMem = geometry->fill.vertices;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb)))
+ if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &vb)))
{
ERR("Failed to create vertex buffer, hr %#x.\n", hr);
ID3D10Buffer_Release(ib);
@@ -993,7 +1030,7 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t
buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
buffer_data.pSysMem = geometry->fill.bezier_vertices;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb)))
+ if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &vb)))
{
ERR("Failed to create beziers vertex buffer, hr %#x.\n", hr);
goto done;
@@ -1011,7 +1048,7 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t
buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
buffer_data.pSysMem = geometry->fill.arc_vertices;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb)))
+ if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &vb)))
{
ERR("Failed to create arc vertex buffer, hr %#x.\n", hr);
goto done;
@@ -1027,6 +1064,7 @@ done:
ID3D10Buffer_Release(ps_cb_arc);
ID3D10Buffer_Release(ps_cb_bezier);
ID3D10Buffer_Release(vs_cb);
+ d2d_device_release_d3d10_device(render_target->device, d3d10_device);
}
static void STDMETHODCALLTYPE d2d_device_context_FillGeometry(ID2D1DeviceContext *iface,
@@ -1622,6 +1660,7 @@ static void STDMETHODCALLTYPE d2d_device_context_Clear(ID2D1DeviceContext *iface
D3D10_SUBRESOURCE_DATA buffer_data;
struct d2d_ps_cb ps_cb_data = {0};
D3D10_BUFFER_DESC buffer_desc;
+ ID3D10Device *d3d10_device;
ID3D10Buffer *vs_cb, *ps_cb;
D2D1_COLOR_F *c;
HRESULT hr;
@@ -1656,9 +1695,16 @@ static void STDMETHODCALLTYPE d2d_device_context_Clear(ID2D1DeviceContext *iface
buffer_data.SysMemPitch = 0;
buffer_data.SysMemSlicePitch = 0;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vs_cb)))
+ if (FAILED(hr = d2d_device_get_d3d10_device(render_target->device, &d3d10_device)))
+ {
+ ERR("Failed to get ID3D10Device1 interface, hr %#x.\n", hr);
+ return;
+ }
+
+ if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &vs_cb)))
{
WARN("Failed to create constant buffer, hr %#x.\n", hr);
+ d2d_device_release_d3d10_device(render_target->device, d3d10_device);
return;
}
@@ -1679,10 +1725,11 @@ static void STDMETHODCALLTYPE d2d_device_context_Clear(ID2D1DeviceContext *iface
buffer_desc.ByteWidth = sizeof(ps_cb_data);
buffer_data.pSysMem = &ps_cb_data;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ps_cb)))
+ if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &ps_cb)))
{
WARN("Failed to create constant buffer, hr %#x.\n", hr);
ID3D10Buffer_Release(vs_cb);
+ d2d_device_release_d3d10_device(render_target->device, d3d10_device);
return;
}
@@ -1691,6 +1738,7 @@ static void STDMETHODCALLTYPE d2d_device_context_Clear(ID2D1DeviceContext *iface
ID3D10Buffer_Release(ps_cb);
ID3D10Buffer_Release(vs_cb);
+ d2d_device_release_d3d10_device(render_target->device, d3d10_device);
}
static void STDMETHODCALLTYPE d2d_device_context_BeginDraw(ID2D1DeviceContext *iface)
@@ -2028,6 +2076,7 @@ static void STDMETHODCALLTYPE d2d_device_context_SetTarget(ID2D1DeviceContext *i
struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface);
struct d2d_bitmap *bitmap_impl;
D3D10_BLEND_DESC blend_desc;
+ ID3D10Device *d3d10_device;
ID2D1Bitmap *bitmap;
HRESULT hr;
@@ -2077,8 +2126,17 @@ static void STDMETHODCALLTYPE d2d_device_context_SetTarget(ID2D1DeviceContext *i
}
blend_desc.BlendOpAlpha = D3D10_BLEND_OP_ADD;
blend_desc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL;
- if (FAILED(hr = ID3D10Device_CreateBlendState(context->d3d_device, &blend_desc, &context->bs)))
+
+ if (FAILED(hr = d2d_device_get_d3d10_device(context->device, &d3d10_device)))
+ {
+ ERR("Failed to get ID3D10Device1 interface, hr %#x.\n", hr);
+ return;
+ }
+
+ if (FAILED(hr = ID3D10Device_CreateBlendState(d3d10_device, &blend_desc, &context->bs)))
WARN("Failed to create blend state, hr %#x.\n", hr);
+
+ d2d_device_release_d3d10_device(context->device, d3d10_device);
}
static void STDMETHODCALLTYPE d2d_device_context_GetTarget(ID2D1DeviceContext *iface, ID2D1Image **target)
@@ -2803,17 +2861,42 @@ static const struct ID2D1GdiInteropRenderTargetVtbl d2d_gdi_interop_render_targe
d2d_gdi_interop_render_target_ReleaseDC,
};
+HRESULT d2d_device_get_d3d10_device(ID2D1Device *iface, ID3D10Device **d3d10_device)
+{
+ struct d2d_device *device = unsafe_impl_from_ID2D1Device(iface);
+
+ if (!device->d3d10_device)
+ {
+ WARN("Failed to get device interface.\n");
+ return E_NOINTERFACE;
+ }
+
+ if (device->d3d10_mt) ID3D10Multithread_Enter(device->d3d10_mt);
+
+ ID3D10Device_AddRef(*d3d10_device = device->d3d10_device);
+ return S_OK;
+}
+
+void d2d_device_release_d3d10_device(ID2D1Device *iface, ID3D10Device *d3d10_device)
+{
+ struct d2d_device *device = unsafe_impl_from_ID2D1Device(iface);
+
+ ID3D10Device_Release(d3d10_device);
+
+ if (device->d3d10_mt) ID3D10Multithread_Leave(device->d3d10_mt);
+}
+
static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, ID2D1Device *device,
IUnknown *outer_unknown, const struct d2d_device_context_ops *ops)
{
D3D10_SUBRESOURCE_DATA buffer_data;
D3D10_STATE_BLOCK_MASK state_mask;
- struct d2d_device *device_impl;
IDWriteFactory *dwrite_factory;
D3D10_RASTERIZER_DESC rs_desc;
D3D10_BUFFER_DESC buffer_desc;
unsigned int i;
HRESULT hr;
+ ID3D10Device *d3d10_device = NULL;
static const D3D10_INPUT_ELEMENT_DESC il_desc_outline[] =
{
@@ -3874,14 +3957,12 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target,
render_target->outer_unknown = outer_unknown ? outer_unknown : &render_target->IUnknown_iface;
render_target->ops = ops;
- device_impl = unsafe_impl_from_ID2D1Device(device);
- if (!device_impl->d3d10_device)
+ if (FAILED(hr = d2d_device_get_d3d10_device(device, &d3d10_device)))
{
- WARN("Failed to get device interface.\n");
+ ERR("Failed to get ID3D10Device interface, hr %#x.\n", hr);
ID2D1Factory_Release(render_target->factory);
- return E_NOINTERFACE;
+ return hr;
}
- ID3D10Device_AddRef(render_target->d3d_device = device_impl->d3d10_device);
if (FAILED(hr = D3D10StateBlockMaskEnableAll(&state_mask)))
{
@@ -3889,7 +3970,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target,
goto err;
}
- if (FAILED(hr = D3D10CreateStateBlock(render_target->d3d_device, &state_mask, &render_target->stateblock)))
+ if (FAILED(hr = D3D10CreateStateBlock(d3d10_device, &state_mask, &render_target->stateblock)))
{
WARN("Failed to create stateblock, hr %#x.\n", hr);
goto err;
@@ -3899,14 +3980,14 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target,
{
const struct shape_info *si = &shape_info[i];
- if (FAILED(hr = ID3D10Device_CreateInputLayout(render_target->d3d_device, si->il_desc, si->il_element_count,
+ if (FAILED(hr = ID3D10Device_CreateInputLayout(d3d10_device, si->il_desc, si->il_element_count,
si->vs_code, si->vs_code_size, &render_target->shape_resources[si->shape_type].il)))
{
WARN("Failed to create input layout for shape type %#x, hr %#x.\n", si->shape_type, hr);
goto err;
}
- if (FAILED(hr = ID3D10Device_CreateVertexShader(render_target->d3d_device, si->vs_code,
+ if (FAILED(hr = ID3D10Device_CreateVertexShader(d3d10_device, si->vs_code,
si->vs_code_size, &render_target->shape_resources[si->shape_type].vs)))
{
WARN("Failed to create vertex shader for shape type %#x, hr %#x.\n", si->shape_type, hr);
@@ -3915,7 +3996,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target,
}
- if (FAILED(hr = ID3D10Device_CreatePixelShader(render_target->d3d_device,
+ if (FAILED(hr = ID3D10Device_CreatePixelShader(d3d10_device,
ps_code, sizeof(ps_code), &render_target->ps)))
{
WARN("Failed to create pixel shader, hr %#x.\n", hr);
@@ -3932,7 +4013,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target,
buffer_data.SysMemPitch = 0;
buffer_data.SysMemSlicePitch = 0;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device,
+ if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device,
&buffer_desc, &buffer_data, &render_target->ib)))
{
WARN("Failed to create clear index buffer, hr %#x.\n", hr);
@@ -3944,7 +4025,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target,
buffer_data.pSysMem = quad;
render_target->vb_stride = sizeof(*quad);
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device,
+ if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device,
&buffer_desc, &buffer_data, &render_target->vb)))
{
WARN("Failed to create clear vertex buffer, hr %#x.\n", hr);
@@ -3961,7 +4042,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target,
rs_desc.ScissorEnable = TRUE;
rs_desc.MultisampleEnable = FALSE;
rs_desc.AntialiasedLineEnable = FALSE;
- if (FAILED(hr = ID3D10Device_CreateRasterizerState(render_target->d3d_device, &rs_desc, &render_target->rs)))
+ if (FAILED(hr = ID3D10Device_CreateRasterizerState(d3d10_device, &rs_desc, &render_target->rs)))
{
WARN("Failed to create clear rasterizer state, hr %#x.\n", hr);
goto err;
@@ -3994,6 +4075,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target,
render_target->desc.dpiX = 96.0f;
render_target->desc.dpiY = 96.0f;
+ d2d_device_release_d3d10_device(render_target->device, d3d10_device);
return S_OK;
err:
@@ -4016,8 +4098,7 @@ err:
}
if (render_target->stateblock)
render_target->stateblock->lpVtbl->Release(render_target->stateblock);
- if (render_target->d3d_device)
- ID3D10Device_Release(render_target->d3d_device);
+ d2d_device_release_d3d10_device(render_target->device, d3d10_device);
ID2D1Device_Release(render_target->device);
ID2D1Factory_Release(render_target->factory);
return hr;
diff --git a/dlls/d2d1/wic_render_target.c b/dlls/d2d1/wic_render_target.c
index 9b57a5d2c34..2d8d7edcd9b 100644
--- a/dlls/d2d1/wic_render_target.c
+++ b/dlls/d2d1/wic_render_target.c
@@ -31,15 +31,34 @@ static HRESULT d2d_wic_render_target_present(IUnknown *outer_unknown)
{
struct d2d_wic_render_target *render_target = impl_from_IUnknown(outer_unknown);
D3D10_MAPPED_TEXTURE2D mapped_texture;
+ ID2D1DeviceContext *d2d1_context;
ID3D10Resource *src_resource;
IWICBitmapLock *bitmap_lock;
UINT dst_size, dst_pitch;
ID3D10Device *device;
+ ID2D1Device *d2d1_device;
WICRect dst_rect;
BYTE *src, *dst;
unsigned int i;
HRESULT hr;
+ if (FAILED(hr = ID2D1RenderTarget_QueryInterface(render_target->dxgi_target,
+ &IID_ID2D1DeviceContext, (void **)&d2d1_context)))
+ {
+ WARN("Failed to retrieve ID2D1DeviceContext interface, hr %#x.\n", hr);
+ return hr;
+ }
+
+ ID2D1DeviceContext_GetDevice(d2d1_context, &d2d1_device);
+
+ if (FAILED(hr = d2d_device_get_d3d10_device(d2d1_device, &device)))
+ {
+ ERR("Failed to get ID3D10Device interface, hr %#x.\n", hr);
+ ID2D1DeviceContext_Release(d2d1_context);
+ ID2D1Device_Release(d2d1_device);
+ return hr;
+ }
+
if (FAILED(hr = IDXGISurface_QueryInterface(render_target->dxgi_surface,
&IID_ID3D10Resource, (void **)&src_resource)))
{
@@ -47,9 +66,7 @@ static HRESULT d2d_wic_render_target_present(IUnknown *outer_unknown)
goto end;
}
- ID3D10Texture2D_GetDevice(render_target->readback_texture, &device);
ID3D10Device_CopyResource(device, (ID3D10Resource *)render_target->readback_texture, src_resource);
- ID3D10Device_Release(device);
ID3D10Resource_Release(src_resource);
dst_rect.X = 0;
@@ -96,6 +113,9 @@ static HRESULT d2d_wic_render_target_present(IUnknown *outer_unknown)
IWICBitmapLock_Release(bitmap_lock);
end:
+ d2d_device_release_d3d10_device(d2d1_device, device);
+ ID2D1DeviceContext_Release(d2d1_context);
+ ID2D1Device_Release(d2d1_device);
return S_OK;
}
--
2.30.0
More information about the wine-devel
mailing list