Signed-off-by: Rémi Bernon rbernon@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; }