Signed-off-by: Nikolay Sivov nsivov@codeweavers.com ---
v3: changed object release order in patch 3.
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..76276bafc7a 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_SAMPLER_INTERPOLATION_MODE_COUNT] + [brush->u.bitmap.extend_mode_x % D2D_SAMPLER_EXTEND_MODE_COUNT] + [brush->u.bitmap.extend_mode_y % D2D_SAMPLER_EXTEND_MODE_COUNT]; + + 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..64bc10a4895 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_SAMPLER_INTERPOLATION_MODE_COUNT = 2, + D2D_SAMPLER_EXTEND_MODE_COUNT = 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_SAMPLER_INTERPOLATION_MODE_COUNT] + [D2D_SAMPLER_EXTEND_MODE_COUNT] + [D2D_SAMPLER_EXTEND_MODE_COUNT];
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..0c89e802510 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_SAMPLER_INTERPOLATION_MODE_COUNT; ++i) + { + for (j = 0; j < D2D_SAMPLER_EXTEND_MODE_COUNT; ++j) + { + for (k = 0; k < D2D_SAMPLER_EXTEND_MODE_COUNT; ++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);