Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/brush.c | 49 ++++++++++++++-------------------------- dlls/d2d1/d2d1_private.h | 14 ++++++++++-- dlls/d2d1/device.c | 17 +++++++++++--- 3 files changed, 43 insertions(+), 37 deletions(-)
diff --git a/dlls/d2d1/brush.c b/dlls/d2d1/brush.c index 07d2e26a143..e3aff19bdf0 100644 --- a/dlls/d2d1/brush.c +++ b/dlls/d2d1/brush.c @@ -859,8 +859,6 @@ static ULONG STDMETHODCALLTYPE d2d_bitmap_brush_Release(ID2D1BitmapBrush1 *iface
if (!refcount) { - if (brush->u.bitmap.sampler_state) - ID3D10SamplerState_Release(brush->u.bitmap.sampler_state); if (brush->u.bitmap.bitmap) ID2D1Bitmap1_Release(&brush->u.bitmap.bitmap->ID2D1Bitmap1_iface); d2d_brush_destroy(brush); @@ -924,11 +922,6 @@ static void STDMETHODCALLTYPE d2d_bitmap_brush_SetExtendModeX(ID2D1BitmapBrush1 TRACE("iface %p, mode %#x.\n", iface, mode);
brush->u.bitmap.extend_mode_x = mode; - if (brush->u.bitmap.sampler_state) - { - ID3D10SamplerState_Release(brush->u.bitmap.sampler_state); - brush->u.bitmap.sampler_state = NULL; - } }
static void STDMETHODCALLTYPE d2d_bitmap_brush_SetExtendModeY(ID2D1BitmapBrush1 *iface, D2D1_EXTEND_MODE mode) @@ -938,11 +931,6 @@ static void STDMETHODCALLTYPE d2d_bitmap_brush_SetExtendModeY(ID2D1BitmapBrush1 TRACE("iface %p, mode %#x.\n", iface, mode);
brush->u.bitmap.extend_mode_y = mode; - if (brush->u.bitmap.sampler_state) - { - ID3D10SamplerState_Release(brush->u.bitmap.sampler_state); - brush->u.bitmap.sampler_state = NULL; - } }
static void STDMETHODCALLTYPE d2d_bitmap_brush_SetInterpolationMode(ID2D1BitmapBrush1 *iface, @@ -963,11 +951,6 @@ static void STDMETHODCALLTYPE d2d_bitmap_brush_SetInterpolationMode(ID2D1BitmapB }
brush->u.bitmap.interpolation_mode = d2d1_1_interp_mode_from_d2d1(mode); - if (brush->u.bitmap.sampler_state) - { - ID3D10SamplerState_Release(brush->u.bitmap.sampler_state); - brush->u.bitmap.sampler_state = NULL; - } }
static void STDMETHODCALLTYPE d2d_bitmap_brush_SetBitmap(ID2D1BitmapBrush1 *iface, ID2D1Bitmap *bitmap) @@ -1051,11 +1034,6 @@ static void STDMETHODCALLTYPE d2d_bitmap_brush_SetInterpolationMode1(ID2D1Bitmap }
brush->u.bitmap.interpolation_mode = mode; - if (brush->u.bitmap.sampler_state) - { - ID3D10SamplerState_Release(brush->u.bitmap.sampler_state); - brush->u.bitmap.sampler_state = NULL; - } }
static D2D1_INTERPOLATION_MODE STDMETHODCALLTYPE d2d_bitmap_brush_GetInterpolationMode1(ID2D1BitmapBrush1 *iface) @@ -1292,12 +1270,20 @@ HRESULT d2d_brush_get_ps_cb(struct d2d_brush *brush, struct d2d_brush *opacity_b return hr; }
-static void d2d_brush_bind_bitmap(struct d2d_brush *brush, ID3D10Device *device, unsigned int brush_idx) +static void d2d_brush_bind_bitmap(struct d2d_brush *brush, struct d2d_device_context *context, + unsigned int brush_idx) { + ID3D10SamplerState **sampler_state; HRESULT hr;
- ID3D10Device_PSSetShaderResources(device, brush_idx, 1, &brush->u.bitmap.bitmap->srv); - if (!brush->u.bitmap.sampler_state) + ID3D10Device_PSSetShaderResources(context->d3d_device, brush_idx, 1, &brush->u.bitmap.bitmap->srv); + + sampler_state = &context->sampler_states + [brush->u.bitmap.interpolation_mode % D2D_MAX_SAMPLER_INTERPOLATION_MODE] + [brush->u.bitmap.extend_mode_x % D2D_MAX_SAMPLER_EXTEND_MODE] + [brush->u.bitmap.extend_mode_y % D2D_MAX_SAMPLER_EXTEND_MODE]; + + if (!*sampler_state) { D3D10_SAMPLER_DESC sampler_desc;
@@ -1318,14 +1304,13 @@ static void d2d_brush_bind_bitmap(struct d2d_brush *brush, ID3D10Device *device, sampler_desc.MinLOD = 0.0f; sampler_desc.MaxLOD = 0.0f;
- if (FAILED(hr = ID3D10Device_CreateSamplerState(device, - &sampler_desc, &brush->u.bitmap.sampler_state))) + if (FAILED(hr = ID3D10Device_CreateSamplerState(context->d3d_device, &sampler_desc, sampler_state))) ERR("Failed to create sampler state, hr %#x.\n", hr); } - ID3D10Device_PSSetSamplers(device, brush_idx, 1, &brush->u.bitmap.sampler_state); + ID3D10Device_PSSetSamplers(context->d3d_device, brush_idx, 1, sampler_state); }
-void d2d_brush_bind_resources(struct d2d_brush *brush, ID3D10Device *device, unsigned int brush_idx) +void d2d_brush_bind_resources(struct d2d_brush *brush, struct d2d_device_context *context, unsigned int brush_idx) { switch (brush->type) { @@ -1333,15 +1318,15 @@ void d2d_brush_bind_resources(struct d2d_brush *brush, ID3D10Device *device, uns break;
case D2D_BRUSH_TYPE_LINEAR: - d2d_gradient_bind(brush->u.linear.gradient, device, brush_idx); + d2d_gradient_bind(brush->u.linear.gradient, context->d3d_device, brush_idx); break;
case D2D_BRUSH_TYPE_RADIAL: - d2d_gradient_bind(brush->u.radial.gradient, device, brush_idx); + d2d_gradient_bind(brush->u.radial.gradient, context->d3d_device, brush_idx); break;
case D2D_BRUSH_TYPE_BITMAP: - d2d_brush_bind_bitmap(brush, device, brush_idx); + d2d_brush_bind_bitmap(brush, context, brush_idx); break;
default: diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 199439b4616..4be52b2fd10 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -126,6 +126,12 @@ struct d2d_device_context_ops HRESULT (*device_context_present)(IUnknown *outer_unknown); };
+enum d2d_device_context_sampler_limits +{ + D2D_MAX_SAMPLER_INTERPOLATION_MODE = 2, + D2D_MAX_SAMPLER_EXTEND_MODE = 3, +}; + struct d2d_device_context { ID2D1DeviceContext ID2D1DeviceContext_iface; @@ -149,6 +155,10 @@ struct d2d_device_context ID3D10Buffer *vb; ID3D10RasterizerState *rs; ID3D10BlendState *bs; + ID3D10SamplerState *sampler_states + [D2D_MAX_SAMPLER_INTERPOLATION_MODE] + [D2D_MAX_SAMPLER_EXTEND_MODE] + [D2D_MAX_SAMPLER_EXTEND_MODE];
struct d2d_error_state error; D2D1_DRAWING_STATE_DESCRIPTION1 drawing_state; @@ -287,7 +297,6 @@ struct d2d_brush D2D1_EXTEND_MODE extend_mode_x; D2D1_EXTEND_MODE extend_mode_y; D2D1_INTERPOLATION_MODE interpolation_mode; - ID3D10SamplerState *sampler_state; } bitmap; } u; }; @@ -303,7 +312,8 @@ HRESULT d2d_radial_gradient_brush_create(ID2D1Factory *factory, HRESULT d2d_bitmap_brush_create(ID2D1Factory *factory, ID2D1Bitmap *bitmap, const D2D1_BITMAP_BRUSH_PROPERTIES1 *bitmap_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc, struct d2d_brush **brush) DECLSPEC_HIDDEN; -void d2d_brush_bind_resources(struct d2d_brush *brush, ID3D10Device *device, unsigned int brush_idx) DECLSPEC_HIDDEN; +void d2d_brush_bind_resources(struct d2d_brush *brush, struct d2d_device_context *context, + unsigned int brush_idx) DECLSPEC_HIDDEN; HRESULT d2d_brush_get_ps_cb(struct d2d_brush *brush, struct d2d_brush *opacity_brush, BOOL outline, BOOL is_arc, struct d2d_device_context *render_target, ID3D10Buffer **ps_cb) DECLSPEC_HIDDEN; struct d2d_brush *unsafe_impl_from_ID2D1Brush(ID2D1Brush *iface) DECLSPEC_HIDDEN; diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c index 23ce03dce5e..b078d927858 100644 --- a/dlls/d2d1/device.c +++ b/dlls/d2d1/device.c @@ -176,10 +176,10 @@ static void d2d_device_context_draw(struct d2d_device_context *render_target, en if (brush) { ID3D10Device_OMSetBlendState(device, render_target->bs, NULL, D3D10_DEFAULT_SAMPLE_MASK); - d2d_brush_bind_resources(brush, device, 0); + d2d_brush_bind_resources(brush, render_target, 0); } if (opacity_brush) - d2d_brush_bind_resources(opacity_brush, device, 1); + d2d_brush_bind_resources(opacity_brush, render_target, 1);
if (ib) ID3D10Device_DrawIndexed(device, index_count, 0, 0); @@ -254,7 +254,7 @@ static ULONG STDMETHODCALLTYPE d2d_device_context_inner_Release(IUnknown *iface)
if (!refcount) { - unsigned int i; + unsigned int i, j, k;
d2d_clip_stack_cleanup(&context->clip_stack); IDWriteRenderingParams_Release(context->default_text_rendering_params); @@ -271,6 +271,17 @@ static ULONG STDMETHODCALLTYPE d2d_device_context_inner_Release(IUnknown *iface) ID3D10VertexShader_Release(context->shape_resources[i].vs); ID3D10InputLayout_Release(context->shape_resources[i].il); } + for (i = 0; i < D2D_MAX_SAMPLER_INTERPOLATION_MODE; ++i) + { + for (j = 0; j < D2D_MAX_SAMPLER_EXTEND_MODE; ++j) + { + for (k = 0; k < D2D_MAX_SAMPLER_EXTEND_MODE; ++k) + { + if (context->sampler_states[i][j][k]) + ID3D10SamplerState_Release(context->sampler_states[i][j][k]); + } + } + } context->stateblock->lpVtbl->Release(context->stateblock); if (context->target) ID2D1Bitmap1_Release(&context->target->ID2D1Bitmap1_iface);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/brush.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/dlls/d2d1/brush.c b/dlls/d2d1/brush.c index e3aff19bdf0..70d0c77466d 100644 --- a/dlls/d2d1/brush.c +++ b/dlls/d2d1/brush.c @@ -1122,8 +1122,7 @@ static D3D10_TEXTURE_ADDRESS_MODE texture_address_mode_from_extend_mode(D2D1_EXT } }
-static BOOL d2d_brush_fill_cb(const struct d2d_brush *brush, - const struct d2d_device_context *render_target, struct d2d_brush_cb *cb) +static BOOL d2d_brush_fill_cb(const struct d2d_brush *brush, struct d2d_brush_cb *cb) { float theta, sin_theta, cos_theta; float dpi_scale, d, s1, s2, t, u; @@ -1249,9 +1248,9 @@ HRESULT d2d_brush_get_ps_cb(struct d2d_brush *brush, struct d2d_brush *opacity_b
cb_data.outline = outline; cb_data.is_arc = is_arc; - if (!d2d_brush_fill_cb(brush, render_target, &cb_data.colour_brush)) + if (!d2d_brush_fill_cb(brush, &cb_data.colour_brush)) return E_NOTIMPL; - if (!d2d_brush_fill_cb(opacity_brush, render_target, &cb_data.opacity_brush)) + if (!d2d_brush_fill_cb(opacity_brush, &cb_data.opacity_brush)) return E_NOTIMPL;
buffer_desc.ByteWidth = sizeof(cb_data);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/brush.c | 32 ++------- dlls/d2d1/d2d1_private.h | 5 +- dlls/d2d1/device.c | 136 ++++++++++++++++++++++----------------- 3 files changed, 86 insertions(+), 87 deletions(-)
diff --git a/dlls/d2d1/brush.c b/dlls/d2d1/brush.c index 70d0c77466d..786fbc7f887 100644 --- a/dlls/d2d1/brush.c +++ b/dlls/d2d1/brush.c @@ -1238,35 +1238,17 @@ static BOOL d2d_brush_fill_cb(const struct d2d_brush *brush, struct d2d_brush_cb } }
-HRESULT d2d_brush_get_ps_cb(struct d2d_brush *brush, struct d2d_brush *opacity_brush, - BOOL outline, BOOL is_arc, struct d2d_device_context *render_target, ID3D10Buffer **ps_cb) +HRESULT d2d_brush_init_ps_cb_data(struct d2d_brush *brush, struct d2d_brush *opacity_brush, + BOOL outline, BOOL is_arc, struct d2d_ps_cb *cb_data) { - D3D10_SUBRESOURCE_DATA buffer_data; - struct d2d_ps_cb cb_data = {0}; - D3D10_BUFFER_DESC buffer_desc; - HRESULT hr; - - cb_data.outline = outline; - cb_data.is_arc = is_arc; - if (!d2d_brush_fill_cb(brush, &cb_data.colour_brush)) + cb_data->outline = outline; + cb_data->is_arc = is_arc; + if (!d2d_brush_fill_cb(brush, &cb_data->colour_brush)) return E_NOTIMPL; - if (!d2d_brush_fill_cb(opacity_brush, &cb_data.opacity_brush)) + if (!d2d_brush_fill_cb(opacity_brush, &cb_data->opacity_brush)) return E_NOTIMPL;
- buffer_desc.ByteWidth = sizeof(cb_data); - buffer_desc.Usage = D3D10_USAGE_DEFAULT; - buffer_desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER; - buffer_desc.CPUAccessFlags = 0; - buffer_desc.MiscFlags = 0; - - buffer_data.pSysMem = &cb_data; - buffer_data.SysMemPitch = 0; - buffer_data.SysMemSlicePitch = 0; - - if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, ps_cb))) - ERR("Failed to create constant buffer, hr %#x.\n", hr); - - return hr; + return S_OK; }
static void d2d_brush_bind_bitmap(struct d2d_brush *brush, struct d2d_device_context *context, diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 4be52b2fd10..be0ee8a49e7 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -150,6 +150,7 @@ struct d2d_device_context ID3D10StateBlock *stateblock; struct d2d_shape_resources shape_resources[D2D_SHAPE_TYPE_COUNT]; ID3D10PixelShader *ps; + ID3D10Buffer *ps_cb; ID3D10Buffer *ib; unsigned int vb_stride; ID3D10Buffer *vb; @@ -314,8 +315,8 @@ HRESULT d2d_bitmap_brush_create(ID2D1Factory *factory, ID2D1Bitmap *bitmap, struct d2d_brush **brush) DECLSPEC_HIDDEN; void d2d_brush_bind_resources(struct d2d_brush *brush, struct d2d_device_context *context, unsigned int brush_idx) DECLSPEC_HIDDEN; -HRESULT d2d_brush_get_ps_cb(struct d2d_brush *brush, struct d2d_brush *opacity_brush, BOOL outline, BOOL is_arc, - struct d2d_device_context *render_target, ID3D10Buffer **ps_cb) DECLSPEC_HIDDEN; +HRESULT d2d_brush_init_ps_cb_data(struct d2d_brush *brush, struct d2d_brush *opacity_brush, BOOL outline, BOOL is_arc, + struct d2d_ps_cb *cb_data) DECLSPEC_HIDDEN; struct d2d_brush *unsafe_impl_from_ID2D1Brush(ID2D1Brush *iface) DECLSPEC_HIDDEN;
struct d2d_stroke_style diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c index b078d927858..240bf835ca2 100644 --- a/dlls/d2d1/device.c +++ b/dlls/d2d1/device.c @@ -119,7 +119,7 @@ static void d2d_clip_stack_pop(struct d2d_clip_stack *stack)
static void d2d_device_context_draw(struct d2d_device_context *render_target, enum d2d_shape_type shape_type, ID3D10Buffer *ib, unsigned int index_count, ID3D10Buffer *vb, unsigned int vb_stride, - ID3D10Buffer *vs_cb, ID3D10Buffer *ps_cb, struct d2d_brush *brush, struct d2d_brush *opacity_brush) + ID3D10Buffer *vs_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; @@ -150,7 +150,7 @@ static void d2d_device_context_draw(struct d2d_device_context *render_target, en ID3D10Device_IASetVertexBuffers(device, 0, 1, &vb, &vb_stride, &offset); ID3D10Device_VSSetConstantBuffers(device, 0, 1, &vs_cb); ID3D10Device_VSSetShader(device, shape_resources->vs); - ID3D10Device_PSSetConstantBuffers(device, 0, 1, &ps_cb); + ID3D10Device_PSSetConstantBuffers(device, 0, 1, &render_target->ps_cb); ID3D10Device_PSSetShader(device, render_target->ps); ID3D10Device_RSSetViewports(device, 1, &vp); if (render_target->clip_stack.count) @@ -266,6 +266,8 @@ static ULONG STDMETHODCALLTYPE d2d_device_context_inner_Release(IUnknown *iface) ID3D10Buffer_Release(context->vb); ID3D10Buffer_Release(context->ib); ID3D10PixelShader_Release(context->ps); + if (context->ps_cb) + ID3D10Buffer_Release(context->ps_cb); for (i = 0; i < D2D_SHAPE_TYPE_COUNT; ++i) { ID3D10VertexShader_Release(context->shape_resources[i].vs); @@ -706,12 +708,59 @@ static void STDMETHODCALLTYPE d2d_device_context_FillEllipse(ID2D1DeviceContext ID2D1EllipseGeometry_Release(geometry); }
+static HRESULT d2d_device_context_update_ps_cb(struct d2d_device_context *context, + struct d2d_brush *brush, struct d2d_brush *opacity_brush, BOOL outline, BOOL is_arc) +{ + D3D10_SUBRESOURCE_DATA buffer_data; + struct d2d_ps_cb cb_data = {0}; + D3D10_BUFFER_DESC buffer_desc; + void *data; + HRESULT hr; + + if (FAILED(hr = d2d_brush_init_ps_cb_data(brush, opacity_brush, outline, is_arc, &cb_data))) + { + WARN("Failed to initialize brush constant buffer data, hr %#x.\n", hr); + return hr; + } + + if (context->ps_cb) + { + if (SUCCEEDED(hr = ID3D10Buffer_Map(context->ps_cb, D3D10_MAP_WRITE_DISCARD, 0, &data))) + { + memcpy(data, &cb_data, sizeof(cb_data)); + ID3D10Buffer_Unmap(context->ps_cb); + } + else + ERR("Failed to map constant buffer, hr %#x.\n", hr); + } + else + { + buffer_desc.ByteWidth = sizeof(cb_data); + buffer_desc.Usage = D3D10_USAGE_DYNAMIC; + buffer_desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER; + buffer_desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; + buffer_desc.MiscFlags = 0; + + buffer_data.pSysMem = &cb_data; + buffer_data.SysMemPitch = 0; + buffer_data.SysMemSlicePitch = 0; + + if (FAILED(hr = ID3D10Device_CreateBuffer(context->d3d_device, &buffer_desc, &buffer_data, + &context->ps_cb))) + { + ERR("Failed to create constant buffer, hr %#x.\n", hr); + } + } + + return hr; +} + static void d2d_device_context_draw_geometry(struct d2d_device_context *render_target, const struct d2d_geometry *geometry, struct d2d_brush *brush, float stroke_width) { - ID3D10Buffer *ib, *vb, *vs_cb, *ps_cb_bezier, *ps_cb_arc; D3D10_SUBRESOURCE_DATA buffer_data; D3D10_BUFFER_DESC buffer_desc; + ID3D10Buffer *ib, *vb, *vs_cb; const D2D1_MATRIX_3X2_F *w; float tmp_x, tmp_y; HRESULT hr; @@ -765,18 +814,10 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t return; }
- if (FAILED(hr = d2d_brush_get_ps_cb(brush, NULL, TRUE, FALSE, render_target, &ps_cb_bezier))) - { - WARN("Failed to get ps constant buffer, hr %#x.\n", hr); - ID3D10Buffer_Release(vs_cb); - return; - } - - if (FAILED(hr = d2d_brush_get_ps_cb(brush, NULL, TRUE, TRUE, render_target, &ps_cb_arc))) + if (FAILED(hr = d2d_device_context_update_ps_cb(render_target, brush, NULL, TRUE, FALSE))) { - WARN("Failed to get ps constant buffer, hr %#x.\n", hr); + WARN("Failed to update constant buffer, hr %#x.\n", hr); ID3D10Buffer_Release(vs_cb); - ID3D10Buffer_Release(ps_cb_bezier); return; }
@@ -804,7 +845,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t }
d2d_device_context_draw(render_target, D2D_SHAPE_TYPE_OUTLINE, ib, 3 * geometry->outline.face_count, vb, - sizeof(*geometry->outline.vertices), vs_cb, ps_cb_bezier, brush, NULL); + sizeof(*geometry->outline.vertices), vs_cb, brush, NULL);
ID3D10Buffer_Release(vb); ID3D10Buffer_Release(ib); @@ -835,7 +876,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t
d2d_device_context_draw(render_target, D2D_SHAPE_TYPE_BEZIER_OUTLINE, ib, 3 * geometry->outline.bezier_face_count, vb, - sizeof(*geometry->outline.beziers), vs_cb, ps_cb_bezier, brush, NULL); + sizeof(*geometry->outline.beziers), vs_cb, brush, NULL);
ID3D10Buffer_Release(vb); ID3D10Buffer_Release(ib); @@ -864,17 +905,16 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t goto done; }
- d2d_device_context_draw(render_target, D2D_SHAPE_TYPE_ARC_OUTLINE, ib, - 3 * geometry->outline.arc_face_count, vb, - sizeof(*geometry->outline.arcs), vs_cb, ps_cb_arc, brush, NULL); + if (SUCCEEDED(d2d_device_context_update_ps_cb(render_target, brush, NULL, TRUE, TRUE))) + d2d_device_context_draw(render_target, D2D_SHAPE_TYPE_ARC_OUTLINE, ib, + 3 * geometry->outline.arc_face_count, vb, + sizeof(*geometry->outline.arcs), vs_cb, brush, NULL);
ID3D10Buffer_Release(vb); ID3D10Buffer_Release(ib); }
done: - ID3D10Buffer_Release(ps_cb_arc); - ID3D10Buffer_Release(ps_cb_bezier); ID3D10Buffer_Release(vs_cb); }
@@ -897,9 +937,9 @@ static void STDMETHODCALLTYPE d2d_device_context_DrawGeometry(ID2D1DeviceContext static void d2d_device_context_fill_geometry(struct d2d_device_context *render_target, const struct d2d_geometry *geometry, struct d2d_brush *brush, struct d2d_brush *opacity_brush) { - ID3D10Buffer *ib, *vb, *vs_cb, *ps_cb_bezier, *ps_cb_arc; D3D10_SUBRESOURCE_DATA buffer_data; D3D10_BUFFER_DESC buffer_desc; + ID3D10Buffer *ib, *vb, *vs_cb; D2D1_MATRIX_3X2_F *w; float tmp_x, tmp_y; HRESULT hr; @@ -953,18 +993,10 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t return; }
- if (FAILED(hr = d2d_brush_get_ps_cb(brush, opacity_brush, FALSE, FALSE, render_target, &ps_cb_bezier))) - { - WARN("Failed to get ps constant buffer, hr %#x.\n", hr); - ID3D10Buffer_Release(vs_cb); - return; - } - - if (FAILED(hr = d2d_brush_get_ps_cb(brush, opacity_brush, FALSE, TRUE, render_target, &ps_cb_arc))) + if (FAILED(hr = d2d_device_context_update_ps_cb(render_target, brush, opacity_brush, FALSE, FALSE))) { - WARN("Failed to get ps constant buffer, hr %#x.\n", hr); + WARN("Failed to update ps constant buffer, hr %#x.\n", hr); ID3D10Buffer_Release(vs_cb); - ID3D10Buffer_Release(ps_cb_bezier); return; }
@@ -992,7 +1024,7 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t }
d2d_device_context_draw(render_target, D2D_SHAPE_TYPE_TRIANGLE, ib, 3 * geometry->fill.face_count, vb, - sizeof(*geometry->fill.vertices), vs_cb, ps_cb_bezier, brush, opacity_brush); + sizeof(*geometry->fill.vertices), vs_cb, brush, opacity_brush);
ID3D10Buffer_Release(vb); ID3D10Buffer_Release(ib); @@ -1011,7 +1043,7 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t }
d2d_device_context_draw(render_target, D2D_SHAPE_TYPE_CURVE, NULL, geometry->fill.bezier_vertex_count, vb, - sizeof(*geometry->fill.bezier_vertices), vs_cb, ps_cb_bezier, brush, opacity_brush); + sizeof(*geometry->fill.bezier_vertices), vs_cb, brush, opacity_brush);
ID3D10Buffer_Release(vb); } @@ -1028,15 +1060,14 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t goto done; }
- d2d_device_context_draw(render_target, D2D_SHAPE_TYPE_CURVE, NULL, geometry->fill.arc_vertex_count, vb, - sizeof(*geometry->fill.arc_vertices), vs_cb, ps_cb_arc, brush, opacity_brush); + if (SUCCEEDED(d2d_device_context_update_ps_cb(render_target, brush, opacity_brush, FALSE, TRUE))) + d2d_device_context_draw(render_target, D2D_SHAPE_TYPE_CURVE, NULL, geometry->fill.arc_vertex_count, vb, + sizeof(*geometry->fill.arc_vertices), vs_cb, brush, opacity_brush);
ID3D10Buffer_Release(vb); }
done: - ID3D10Buffer_Release(ps_cb_arc); - ID3D10Buffer_Release(ps_cb_bezier); ID3D10Buffer_Release(vs_cb); }
@@ -1634,9 +1665,9 @@ static void STDMETHODCALLTYPE d2d_device_context_Clear(ID2D1DeviceContext *iface { struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); D3D10_SUBRESOURCE_DATA buffer_data; - struct d2d_ps_cb ps_cb_data = {0}; D3D10_BUFFER_DESC buffer_desc; - ID3D10Buffer *vs_cb, *ps_cb; + struct d2d_brush brush; + ID3D10Buffer *vs_cb; D2D1_COLOR_F *c; HRESULT hr;
@@ -1676,34 +1707,19 @@ static void STDMETHODCALLTYPE d2d_device_context_Clear(ID2D1DeviceContext *iface return; }
- ps_cb_data.outline = FALSE; - ps_cb_data.colour_brush.type = D2D_BRUSH_TYPE_SOLID; - ps_cb_data.colour_brush.opacity = 1.0f; - c = &ps_cb_data.colour_brush.u.solid.colour; + memset(&brush, 0, sizeof(brush)); + brush.type = D2D_BRUSH_TYPE_SOLID; + brush.opacity = 1.0f; + c = &brush.u.solid.color; if (colour) *c = *colour; if (render_target->desc.pixelFormat.alphaMode == D2D1_ALPHA_MODE_IGNORE) c->a = 1.0f; - c->r *= c->a; - c->g *= c->a; - c->b *= c->a; - - ps_cb_data.opacity_brush.type = D2D_BRUSH_TYPE_COUNT; - - 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))) - { - WARN("Failed to create constant buffer, hr %#x.\n", hr); - ID3D10Buffer_Release(vs_cb); - return; - }
+ d2d_device_context_update_ps_cb(render_target, &brush, NULL, FALSE, FALSE); d2d_device_context_draw(render_target, D2D_SHAPE_TYPE_TRIANGLE, render_target->ib, 6, - render_target->vb, render_target->vb_stride, vs_cb, ps_cb, NULL, NULL); + render_target->vb, render_target->vb_stride, vs_cb, NULL, NULL);
- ID3D10Buffer_Release(ps_cb); ID3D10Buffer_Release(vs_cb); }
On Tue, 8 Jun 2021 at 10:57, Nikolay Sivov nsivov@codeweavers.com wrote:
-HRESULT d2d_brush_get_ps_cb(struct d2d_brush *brush, struct d2d_brush *opacity_brush,
BOOL outline, BOOL is_arc, struct d2d_device_context *render_target, ID3D10Buffer **ps_cb)
+HRESULT d2d_brush_init_ps_cb_data(struct d2d_brush *brush, struct d2d_brush *opacity_brush,
BOOL outline, BOOL is_arc, struct d2d_ps_cb *cb_data)
{
- D3D10_SUBRESOURCE_DATA buffer_data;
- struct d2d_ps_cb cb_data = {0};
- D3D10_BUFFER_DESC buffer_desc;
- HRESULT hr;
- cb_data.outline = outline;
- cb_data.is_arc = is_arc;
- if (!d2d_brush_fill_cb(brush, &cb_data.colour_brush))
- cb_data->outline = outline;
- cb_data->is_arc = is_arc;
- if (!d2d_brush_fill_cb(brush, &cb_data->colour_brush)) return E_NOTIMPL;
- if (!d2d_brush_fill_cb(opacity_brush, &cb_data.opacity_brush))
- if (!d2d_brush_fill_cb(opacity_brush, &cb_data->opacity_brush)) return E_NOTIMPL;
- buffer_desc.ByteWidth = sizeof(cb_data);
- buffer_desc.Usage = D3D10_USAGE_DEFAULT;
- buffer_desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER;
- buffer_desc.CPUAccessFlags = 0;
- buffer_desc.MiscFlags = 0;
- buffer_data.pSysMem = &cb_data;
- buffer_data.SysMemPitch = 0;
- buffer_data.SysMemSlicePitch = 0;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, ps_cb)))
ERR("Failed to create constant buffer, hr %#x.\n", hr);
- return hr;
- return S_OK;
}
Arguably, what's left of the function could just be inlined in d2d_device_context_update_ps_cb() now.
@@ -266,6 +266,8 @@ static ULONG STDMETHODCALLTYPE d2d_device_context_inner_Release(IUnknown *iface) ID3D10Buffer_Release(context->vb); ID3D10Buffer_Release(context->ib); ID3D10PixelShader_Release(context->ps);
if (context->ps_cb)
ID3D10Buffer_Release(context->ps_cb); for (i = 0; i < D2D_SHAPE_TYPE_COUNT; ++i) { ID3D10VertexShader_Release(context->shape_resources[i].vs);
If we created "context->ps_cb" in d2d_device_context_init(), this would become an unconditional release.
+static HRESULT d2d_device_context_update_ps_cb(struct d2d_device_context *context,
struct d2d_brush *brush, struct d2d_brush *opacity_brush, BOOL outline, BOOL is_arc)
+{
- D3D10_SUBRESOURCE_DATA buffer_data;
- struct d2d_ps_cb cb_data = {0};
- D3D10_BUFFER_DESC buffer_desc;
- void *data;
- HRESULT hr;
- if (FAILED(hr = d2d_brush_init_ps_cb_data(brush, opacity_brush, outline, is_arc, &cb_data)))
- {
WARN("Failed to initialize brush constant buffer data, hr %#x.\n", hr);
return hr;
- }
- if (context->ps_cb)
- {
if (SUCCEEDED(hr = ID3D10Buffer_Map(context->ps_cb, D3D10_MAP_WRITE_DISCARD, 0, &data)))
{
memcpy(data, &cb_data, sizeof(cb_data));
ID3D10Buffer_Unmap(context->ps_cb);
}
else
ERR("Failed to map constant buffer, hr %#x.\n", hr);
- }
We don't need the memcpy(). I.e., we can just do the following:
struct d2d_ps_cb *cb_data; [...] ID3D10Buffer_Map(..., &cb_data); d2d_brush_init_ps_cb_data(..., cb_data); ID3D10Buffer_Unmap(...);
- else
- {
buffer_desc.ByteWidth = sizeof(cb_data);
buffer_desc.Usage = D3D10_USAGE_DYNAMIC;
buffer_desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER;
buffer_desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
buffer_desc.MiscFlags = 0;
buffer_data.pSysMem = &cb_data;
buffer_data.SysMemPitch = 0;
buffer_data.SysMemSlicePitch = 0;
if (FAILED(hr = ID3D10Device_CreateBuffer(context->d3d_device, &buffer_desc, &buffer_data,
&context->ps_cb)))
{
ERR("Failed to create constant buffer, hr %#x.\n", hr);
}
- }
- return hr;
+}
And this could just happen during d2d_device_context_init(). (The "buffer_data" argument is optional; it can be convenient for initialising resources without explicitly mapping them, but I don't think it provides much of an advantage here.)
@@ -1676,34 +1707,19 @@ static void STDMETHODCALLTYPE d2d_device_context_Clear(ID2D1DeviceContext *iface return; }
- ps_cb_data.outline = FALSE;
- ps_cb_data.colour_brush.type = D2D_BRUSH_TYPE_SOLID;
- ps_cb_data.colour_brush.opacity = 1.0f;
- c = &ps_cb_data.colour_brush.u.solid.colour;
- memset(&brush, 0, sizeof(brush));
- brush.type = D2D_BRUSH_TYPE_SOLID;
- brush.opacity = 1.0f;
- c = &brush.u.solid.color; if (colour) *c = *colour; if (render_target->desc.pixelFormat.alphaMode == D2D1_ALPHA_MODE_IGNORE) c->a = 1.0f;
- c->r *= c->a;
- c->g *= c->a;
- c->b *= c->a;
Constructing a brush like that is a little awkward, I think. To some extent that's also true of constructing the d2d_ps_cb structure in the original code, but brush objects are a bit more complex than the d2d_ps_cb structure. It would seem preferable to either directly map "ps_cb" here, and generate its contents in the existing way, or to create a proper brush object using d2d_solid_color_brush_create().
On Tue, 8 Jun 2021 at 10:57, Nikolay Sivov nsivov@codeweavers.com wrote:
+enum d2d_device_context_sampler_limits +{
- D2D_MAX_SAMPLER_INTERPOLATION_MODE = 2,
- D2D_MAX_SAMPLER_EXTEND_MODE = 3,
+};
I could live with it, but the naming is perhaps a little unfortunate here. I.e., these are counts, not maximum values.