more visiting and less buffering in drawinglayer/
Armin Le Grand
armin_le_grand at me.com
Fri Dec 3 17:11:38 UTC 2021
On 12/3/21 12:21 PM, Noel Grandin wrote:
> There will be a variety of drawinglayer related patches going through
> as I work though some performance issues.
> So for drawinglayer code, we generally start with a hierarchy of
> drawinglayer objects.
> Then we call that hierarchy recursively, and it produces as output a
> list of more primitive drawinglayer objects.
> Then we iterate over that list of "primitive" objects and do something
> - usually rendering, sometimes hit-testing, sometimes something else.
> What I am doing is attempting to remove the intermediate creation of
> drawinglayer objects (which is fairly expensive), and instead use a
> visitor pattern (represented by the Primitive2DDecompositionVisitor
> abstract class)
The best way to avoid decomposition is not to call getDecomposition().
The concept is that a Processor (e.g. renderer or HitTest) *has* to
implement that 7 minimal Primitives to do everything. It *can* implement
higher-level ones to not need to let decompose run.
Example: HitTest for FatLines. A HitTest Processor which does not know
FatLines Primitives will trigger getDecomposition() and that will create
the filled PolyPolygon geometry for the FatLine. That Processor would
then HitTest by checking the to-be-tested point position against
PolyPolygons. If it implements FatLine, it will have to do a geometrical
test against the hairline PolyPolygon using the known LineWidth.
The advantage is that Processors can be easily written, with e.g. not
knowing about FatLines or Text at all.
The disadvantage is that a decomposition has to be done.
The best way to avoid decomposition is to implement handling of more
complex primitives in Processors.
To allow for simple impl of Processors, keeping the getDecomposition()
is necessary. Be wawre that UNO API has getDecomposition and that needs
A visitor concept would be fine and interesting - I already did
something similar whit LinePatters which when handled in the renderers
use a lambda now to no longer create the line pattern line snippets in
memory - but I would be interested how this will look like. Especially
since we need to keep UNO API - do you plan to extend hat visitor
concept over the UNO API?
For the buffering: Every impl of a getDecomposition *can* decide if it
implements to buffer the created decomposition primitive representation
or not. Maybe using this more is feasible to fix performance stuff -
plus more direct handling of higher-level primitives in Processors.
I think there are existing possibilities to fix performance problems,
but I am open to new concepts - if they fit into the existing concepts :-)
> Along the way I also intend to remove some buffering of these
> intermediate objects, since it is generally less expensive to just
> visit the higher-level tree.
As explained, this may just be added to the impls of
::getDecomposition() of the Primitives in question.
I see the advantage of *not* creating all sub-primitives, but I see no
UNO API compatible way to add a visitor concept here. Of course it would
be interesing, maybe even a reason to extend UNO API.
Be aware that this is not always usable: With the example of FatLines
broken down to PolyPolygon representation it is *not* the same
(unfortunately) to paint each single one of the decomposed geometry -
these do overlap and the gaps do not add correctly on AAed modes, so
these *need* to be painted in a single run to be represented correctly
when the line has a transparency.
Those cases are not obvious (you find them when you do that stuff and it
looks weird/is wrong, then *have* to think about it - sigh). Be aware
that there are more such not obvious cases where handling all single
decomposed parts *is* graphically different from handling as a whole.
> Regards, Noel Grandin#
All the best,
ALG (PGP: EE1C 4B3F E751 D8BC C485 DEC1 3C59 F953 D81C F4A2)
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the LibreOffice