[PATCH v4] d2d1: Implement ID2D1DeviceContext::CreateImageBrush().

Dmitry Timoshkov dmitry at baikal.ru
Thu May 12 11:55:15 CDT 2022


Henri Verbeet <hverbeet at gmail.com> wrote:

> On Wed, 11 May 2022 at 16:22, Dmitry Timoshkov <dmitry at baikal.ru> wrote:
> > +HRESULT d2d_image_brush_create(ID2D1Factory *factory, ID2D1Image *image,
> > +        const D2D1_IMAGE_BRUSH_PROPERTIES *image_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc,
> > +        struct d2d_brush **brush)
> > +{
> > +    if (!(*brush = heap_alloc_zero(sizeof(**brush))))
> > +        return E_OUTOFMEMORY;
> > +
> > +    d2d_brush_init(*brush, factory, D2D_BRUSH_TYPE_BITMAP,
> > +            brush_desc, (ID2D1BrushVtbl *)&d2d_image_brush_vtbl);
> 
> I think you intended to use D2D_BRUSH_TYPE_IMAGE above.

Good catch, thanks!

> > +    if (((*brush)->u.image.image = image))
> > +        ID2D1Image_AddRef((*brush)->u.image.image);
> > +    if (image_brush_desc)
> > +    {
> > +        (*brush)->u.image.extend_mode_x = image_brush_desc->extendModeX;
> > +        (*brush)->u.image.extend_mode_y = image_brush_desc->extendModeY;
> > +        (*brush)->u.image.interpolation_mode = image_brush_desc->interpolationMode;
> > +    }
> 
> This ignores "image_brush_desc->sourceRectangle". That's fine to some
> extent, but might be easy to overlook when implementing
> d2d_image_brush_SetSourceRectangle()/d2d_image_brush_GetSourceRectangle()
> later.

Also good point, is that fine to just add a FIXME, or it makes sense to also
save it in the bitmap?

> > +static void d2d_brush_bind_image(struct d2d_brush *brush, struct d2d_device_context *context,
> > +        unsigned int brush_idx)
> > +{
> > +    ID3D11SamplerState **sampler_state;
> > +    ID3D11DeviceContext *d3d_context;
> > +    ID2D1Bitmap *bitmap;
> > +    struct d2d_bitmap *src_impl;
> > +    HRESULT hr;
> > +
> > +    hr = ID2D1Image_QueryInterface(brush->u.image.image, &IID_ID2D1Bitmap, (void **)&bitmap);
> > +    if (FAILED(hr))
> > +    {
> > +        FIXME("ID2D1Image doesn't support ID2D1Bitmap interface.\n");
> > +        return;
> > +    }
> > +
> > +    src_impl = unsafe_impl_from_ID2D1Bitmap(bitmap);
> > +
> > +    ID3D11Device1_GetImmediateContext(context->d3d_device, &d3d_context);
> > +    ID3D11DeviceContext_PSSetShaderResources(d3d_context, brush_idx, 1, &src_impl->srv);
> > +
> > +    sampler_state = &context->sampler_states
> > +            [brush->u.image.interpolation_mode % D2D_SAMPLER_INTERPOLATION_MODE_COUNT]
> > +            [brush->u.image.extend_mode_x % D2D_SAMPLER_EXTEND_MODE_COUNT]
> > +            [brush->u.image.extend_mode_y % D2D_SAMPLER_EXTEND_MODE_COUNT];
> > +
> > +    if (!*sampler_state)
> > +    {
> > +        D3D11_SAMPLER_DESC sampler_desc;
> > +
> > +        if (brush->u.image.interpolation_mode == D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR)
> > +            sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
> > +        else
> > +            sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
> > +        sampler_desc.AddressU = texture_address_mode_from_extend_mode(brush->u.image.extend_mode_x);
> > +        sampler_desc.AddressV = texture_address_mode_from_extend_mode(brush->u.image.extend_mode_y);
> > +        sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
> > +        sampler_desc.MipLODBias = 0.0f;
> > +        sampler_desc.MaxAnisotropy = 0;
> > +        sampler_desc.ComparisonFunc = D3D11_COMPARISON_NEVER;
> > +        sampler_desc.BorderColor[0] = 0.0f;
> > +        sampler_desc.BorderColor[1] = 0.0f;
> > +        sampler_desc.BorderColor[2] = 0.0f;
> > +        sampler_desc.BorderColor[3] = 0.0f;
> > +        sampler_desc.MinLOD = 0.0f;
> > +        sampler_desc.MaxLOD = 0.0f;
> > +
> > +        if (FAILED(hr = ID3D11Device1_CreateSamplerState(context->d3d_device, &sampler_desc, sampler_state)))
> > +            ERR("Failed to create sampler state, hr %#lx.\n", hr);
> > +    }
> > +
> > +    ID3D11DeviceContext_PSSetSamplers(d3d_context, brush_idx, 1, sampler_state);
> > +    ID3D11DeviceContext_Release(d3d_context);
> > +    ID2D1Bitmap_Release(bitmap);
> > +}
> 
> This doesn't seem wrong, although we could probably introduce a common
> helper for this and d2d_brush_bind_bitmap(). At the same time though,
> it's not going to do much as long as the pixel shader (i.e., ps_code[]
> in d2d_device_context_init()) doesn't handle image brushes. (And in
> it's current form, we never get here because we set the brush type to
> D2D_BRUSH_TYPE_BITMAP in d2d_image_brush_create().) It might be best
> to just go with the FIXME in d2d_brush_bind_resources(), unless we
> need the brush to actually work.

Thanks for the review and suggestions, I guess that adding a FIXME could be
a reasonable approach at this point.

-- 
Dmitry.



More information about the wine-devel mailing list