[PATCH 1/5] d2d1: Implement d2d_d3d_render_target_CreateSolidColorBrush().

Henri Verbeet hverbeet at gmail.com
Mon Jun 16 07:39:15 CDT 2014


On 16 June 2014 14:15, Jacek Caban <jacek at codeweavers.com> wrote:
> I don't know this how will this be used in the future, so my ideas may
> not be best fit. For the code that you sent so far, a separated struct
As far as the API is concerned, brushes are mostly used for drawing
commands like e.g. ID2D1RenderTarget::FillRectangle() and the like.
These all take ID2D1Brush pointers. The way the implementation is
likely to work in the future is that brush types will have an
associated fragment shader, and some constant buffer data. I.e., a
typical drawing function implementation would do something along the
lines of the following:

    struct d2d_brush *b = unsafe_impl_from_ID2DBrush(brush);
...
    ID3D10Device_PSSetShader(device, b->shader);
    ID3D10Device_PSSetConstantBuffers(device, 0, 1, &b->cb);
...
    ID3D10Device_DrawIndexed(device, ...);

> for all brush types would do the job. I guess that different brush types
> will store different data in the future, so separated structs will be
> needed anyway. If having some sort of shared struct is desired, this
> could be introduced as separated struct:
>
> struct d2d1_brash {
>   /* shared stuff, maybe even refcount */
> };
>
> struct d2d1_solid_brush {
>   ID2D1SolidColorBrush ID2D1SolidColorBrush_iface
>   LONG refcount;
>   struct brush base_brush;
>   /* Stuff specific to solid brush */
> };
>
> This has some drawbacks like the fact that d2d1_brush can't be easily
> casted to ID2D1Brush. This may be avoided by design or, with some
It's mostly the ID2D1Brush -> struct d2d_brush conversion that's the
issue. If you do the above, you either need to do multiple
QueryInterface() calls in each drawing function, or introduce a
private interface to get at the embedded d2d_brush structure, and then
implement that for every single brush. I think the two casts, while
not very pretty, are worth it in comparison.

> runtime overhead, d2d1_brush could store a pointer to ID2D1Brush (which
> would be initialized to solid_brush->ID2D1SoludBrush_iface in this case)
That would only help for getting an ID2D1Brush from struct d2d_brush,
but even then, you'd just reintroduce the casts you were trying to
avoid.



More information about the wine-devel mailing list