Re: more visiting and less buffering in drawinglayer/

2021-12-06 Thread Armin Le Grand
Hi Lubos,

On 12/4/21 2:15 PM, Luboš Luňák wrote:
> On Friday 03 of December 2021, Armin Le Grand wrote:
>> In this case it's - as you say - broken and thus an error. So please
>> talk about it, report it
>  How likely would that achieve anything though? It's not like reporting a 
> problem somehow magically fixes it. Even high-priority bugreports with a 
> simple solution like tdf#138068 can apparently linger for quite while, so 
> what's the chance a non-critical problem with a complex fix would do anything 
> else than sit in bugzilla and do nothing?
Yepp, I know that problem, too :-( I would love to be (or have someone)
in a role sponsored (by sth like TDF?) what would allow me/us to do
maintenance :-) Besides filing Tenders (which never get elected, so no
way to continue that DL changes, sigh) I see a missing mechanism for
just doing maintenance in important core regions - optimally by people
which are familiar with it...
>
>> and fix it when it's an error - or motivate others to fix it.
>  Given the above, that's what I normally try to do, but that's not always 
> possible. In the case of the canvas caching, after several attempts at it I 
> managed to fix like 3(?) places that were breaking it, and after I ran into 
> yet another reason why it was irrelevant I just gave up. As for motivating 
> others, I don't see how that'd happen given 'git log canvas cppcanvas' - 
> ironically the largest recent contributor of commits specific to that code is 
> probably me, and the only thing I feel like motivating people to do is to 
> rewrite code using it away from it.

I am still not sure what part of LO you are talking about - if it's
slideshow (replay?), that's mainly THB's original work. There is also a
Tender for this - never got voted, would be also important - to change
that to primitive usage. That would be a precondition to get that
buffering I was talking about into that part - sigh. In the rest of he
office all BM stuff should use BitmapPrimitive by now and should buffer.

Anyways, with the current backends there should be no place (well, never
say never) that does sw-based scaling - we have that DrawTransformed
which can/is pretty much implemented on every backend (?) Maybe hat
broke/is broken somehow? That should be used pretty everywhere and leave
the transformation/scale to the graphic system below - whatever it is.

>
>> I think it's not the most effective way if everyone 
>> implements it's own buffers. This is possible (as we see), but I doubt
>> that it's effective - except that you do not need to cope too much with
>> the existing stuff ;-) It will even eventually conflict potentially in
>> the long run and wastes lots of energy :-( The ype of energy that is the
>> most valuable for the project - developer ressources.
>>
>> Please note that there is nowadays type-template-based buffering of
>> system-dependent data - of *any* kind. That works for win/cairo/X11
>> specific bitmap representations. It also is used for buffering
>> system-dependent PolyPolygon path representations (cairo & win) which
>> are also expensive to re-create at each repaint. I see no hindrance to
>> use the same system for Skia. This is not complicated, just needs a
>> little research/looking (or asking & help) how it is used. It even can
>> have it's own 'decider' if it should be buffered longer or can be
>> dismissed.
>>
>> If there are cases for (software-)scaled/changed bitmaps for paint which
>> are not yet handled - and there are always such, of course - please
>> report them. This system can be used to do this, dependent of
>> attributes/necessities of your choice.
>  Actually that's how I saw it in theory too, and that's where I started,
I did not want to question that, but just ensure it. That's the point
that was important to me! Good to know :-)
>  but 
> then practice went rather differently. As I recall it, it could be summed 
> roughly as:
> - it's not documented (can't help notice the irony of you talking about not 
> wasting developer time when you didn't find 5 minutes to do something about 
> it)

I just did not hear about it until this thread :-( No idea why that
happened...

For documented: I agree we are weak here, but I usually add quite some
comments, and there are examples in he code. But I happily agree that it
would have been better to communicate about it - there should be always
some minutes to be found to answer questions.

> - the usage didn't seem clear from looking at the 3 classes
> - the usage didn't seem clear from looking at how VCL cairo/headless backend 
> uses it (IIRC the main thought I had was that it seemed rather complicated 
> for something as simple as caching)
> - after deciphering some of it the assumptions seemed wrong (only one item of 
> the same type for an object, so no caching of scaling to different sizes; 
> binding the data to the one object, so problematic when copying bitmaps or 
> involving more than one of them)
> - it seemed that trying to save time/code 

Re: more visiting and less buffering in drawinglayer/

2021-12-06 Thread Luboš Luňák
On Friday 03 of December 2021, Armin Le Grand wrote:
> In this case it's - as you say - broken and thus an error. So please
> talk about it, report it

 How likely would that achieve anything though? It's not like reporting a 
problem somehow magically fixes it. Even high-priority bugreports with a 
simple solution like tdf#138068 can apparently linger for quite while, so 
what's the chance a non-critical problem with a complex fix would do anything 
else than sit in bugzilla and do nothing?

> and fix it when it's an error - or motivate others to fix it.

 Given the above, that's what I normally try to do, but that's not always 
possible. In the case of the canvas caching, after several attempts at it I 
managed to fix like 3(?) places that were breaking it, and after I ran into 
yet another reason why it was irrelevant I just gave up. As for motivating 
others, I don't see how that'd happen given 'git log canvas cppcanvas' - 
ironically the largest recent contributor of commits specific to that code is 
probably me, and the only thing I feel like motivating people to do is to 
rewrite code using it away from it.

> I think it's not the most effective way if everyone 
> implements it's own buffers. This is possible (as we see), but I doubt
> that it's effective - except that you do not need to cope too much with
> the existing stuff ;-) It will even eventually conflict potentially in
> the long run and wastes lots of energy :-( The ype of energy that is the
> most valuable for the project - developer ressources.
>
> Please note that there is nowadays type-template-based buffering of
> system-dependent data - of *any* kind. That works for win/cairo/X11
> specific bitmap representations. It also is used for buffering
> system-dependent PolyPolygon path representations (cairo & win) which
> are also expensive to re-create at each repaint. I see no hindrance to
> use the same system for Skia. This is not complicated, just needs a
> little research/looking (or asking & help) how it is used. It even can
> have it's own 'decider' if it should be buffered longer or can be
> dismissed.
>
> If there are cases for (software-)scaled/changed bitmaps for paint which
> are not yet handled - and there are always such, of course - please
> report them. This system can be used to do this, dependent of
> attributes/necessities of your choice.

 Actually that's how I saw it in theory too, and that's where I started, but 
then practice went rather differently. As I recall it, it could be summed 
roughly as:
- it's not documented (can't help notice the irony of you talking about not 
wasting developer time when you didn't find 5 minutes to do something about 
it)
- the usage didn't seem clear from looking at the 3 classes
- the usage didn't seem clear from looking at how VCL cairo/headless backend 
uses it (IIRC the main thought I had was that it seemed rather complicated 
for something as simple as caching)
- after deciphering some of it the assumptions seemed wrong (only one item of 
the same type for an object, so no caching of scaling to different sizes; 
binding the data to the one object, so problematic when copying bitmaps or 
involving more than one of them)
- it seemed that trying to save time/code by reusing the code would result in 
writing more code than would be saved
- when I tried the cairo backend with whichever bugreport I needed the caching 
for, it performed poorly
- so when faced with the decision whether to write a simple cache myself or 
try to fit a complex undocumented design that probably would work poorly, I 
indeed decided not to waste developer time

 Even going over this again in hindsight I still think that was the correct 
and effective decision - AFAICT the Skia backend generally outperforms the 
Cairo one, and it's not just because of Skia itself. As far as I'm concerned, 
this is the common OOo problem of something looking nice in theory but 
struggling with the reality check.

-- 
 Luboš Luňák
 l.lu...@collabora.com


Re: more visiting and less buffering in drawinglayer/

2021-12-03 Thread Armin Le Grand
Hi,

On 12/3/21 3:35 PM, Luboš Luňák wrote:
> On Friday 03 of December 2021, Thorsten Behrens wrote:
>> Luboš Luňák wrote:
>>> I've implemented a cache in the Skia backend to handle cases of
>>> drawinglayer being dumb and repeatedly asking to do expensive
>>> redraws of the same stuff over and over again, which requires that
>>> the underlying bitmap is the same object and not something created
>>> from scratch every time.
>> You meant to say application code being dumb & dropping their
>> ViewObjectContact instead of keeping it for the next paint? ;)
>  I don't understand in enough detail how all that stuff works, but I'd say 
> that the answer is that not always.
>From my POV it may then be feasible to get more knowledge of the
concepts behind that things, either by asking people who are still
available and did some of that stuff, or by reading more code, or by
checking the presentations held at various conferences which are
available and contain a lot of infos about the concepts. There is also a
lot of comments in the headers/sources explaining stuff e.g. for
Primitives and ViewObjectContact(s). This can of course always be
improved - there is no developer documentation (docu is the *cxx/*hxx
files we said with a blinking eye those days :-) - , but there are also
people here - a community.
>  I think application code is not involved 
> in tdf#104878, and even if, it's Impress, the app that AFAIK should be the 
> most adapted to drawinglayer, so there is probably something wrong if 
> even that one can't get it right. And I definitely remember dumb things in 
> graphics stack code, a random example that comes to mind is Impress/canvas 
> having 0% hit rate for cached scaled bitmaps (with at leats two different 
> reasons for the caching being broken).

In this case it's - as you say - broken and thus an error. So please
talk about it, report it and fix it when it's an error - or motivate
others to fix it. I think it's not the most effective way if everyone
implements it's own buffers. This is possible (as we see), but I doubt
that it's effective - except that you do not need to cope too much with
the existing stuff ;-) It will even eventually conflict potentially in
the long run and wastes lots of energy :-( The ype of energy that is the
most valuable for the project - developer ressources.

Please note that there is nowadays type-template-based buffering of
system-dependent data - of *any* kind. That works for win/cairo/X11
specific bitmap representations. It also is used for buffering
system-dependent PolyPolygon path representations (cairo & win) which
are also expensive to re-create at each repaint. I see no hindrance to
use the same system for Skia. This is not complicated, just needs a
little research/looking (or asking & help) how it is used. It even can
have it's own 'decider' if it should be buffered longer or can be dismissed.

If there are cases for (software-)scaled/changed bitmaps for paint which
are not yet handled - and there are always such, of course - please
report them. This system can be used to do this, dependent of
attributes/necessities of your choice.

All the best,

Armin

--

ALG (PGP: EE1C 4B3F E751 D8BC C485 DEC1 3C59 F953 D81C F4A2)



Re: more visiting and less buffering in drawinglayer/

2021-12-03 Thread Armin Le Grand
Hi Noel,

On 12/3/21 12:21 PM, Noel Grandin wrote:
> Hi
>
> 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
to stay.

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,

Armin


-- 
--
ALG (PGP: EE1C 4B3F E751 D8BC C485 DEC1 3C59 F953 D81C F4A2)



Re: more visiting and less buffering in drawinglayer/

2021-12-03 Thread Luboš Luňák
On Friday 03 of December 2021, Thorsten Behrens wrote:
> Luboš Luňák wrote:
> > I've implemented a cache in the Skia backend to handle cases of
> > drawinglayer being dumb and repeatedly asking to do expensive
> > redraws of the same stuff over and over again, which requires that
> > the underlying bitmap is the same object and not something created
> > from scratch every time.
>
> You meant to say application code being dumb & dropping their
> ViewObjectContact instead of keeping it for the next paint? ;)

 I don't understand in enough detail how all that stuff works, but I'd say 
that the answer is that not always. I think application code is not involved 
in tdf#104878, and even if, it's Impress, the app that AFAIK should be the 
most adapted to drawinglayer, so there is probably something wrong if 
even that one can't get it right. And I definitely remember dumb things in 
graphics stack code, a random example that comes to mind is Impress/canvas 
having 0% hit rate for cached scaled bitmaps (with at leats two different 
reasons for the caching being broken).

-- 
 Luboš Luňák
 l.lu...@collabora.com


Re: more visiting and less buffering in drawinglayer/

2021-12-03 Thread Thorsten Behrens
Luboš Luňák wrote:
> I've implemented a cache in the Skia backend to handle cases of
> drawinglayer being dumb and repeatedly asking to do expensive
> redraws of the same stuff over and over again, which requires that
> the underlying bitmap is the same object and not something created
> from scratch every time.
>
You meant to say application code being dumb & dropping their
ViewObjectContact instead of keeping it for the next paint? ;)

Cheers,

-- Thorsten


signature.asc
Description: PGP signature


Re: more visiting and less buffering in drawinglayer/

2021-12-03 Thread Noel Grandin
On Fri, 3 Dec 2021 at 15:06, Luboš Luňák  wrote:

>
>  In case that would involve removing buffering of bitmaps, please check
> things


No problem, not touching bitmaps at all, only the buffering of objects in
the Primitive2D hierarchy.


Re: more visiting and less buffering in drawinglayer/

2021-12-03 Thread Luboš Luňák
On Friday 03 of December 2021, Noel Grandin wrote:
> 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)

 +1

> 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.

 In case that would involve removing buffering of bitmaps, please check things 
like https://bugs.documentfoundation.org/show_bug.cgi?id=104878 still work 
well with Skia in software mode. I've implemented a cache in the Skia backend 
to handle cases of drawinglayer being dumb and repeatedly asking to do 
expensive redraws of the same stuff over and over again, which requires that 
the underlying bitmap is the same object and not something created from 
scratch every time.

-- 
 Luboš Luňák
 l.lu...@collabora.com