Re: more visiting and less buffering in drawinglayer/
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 by
Re: more visiting and less buffering in drawinglayer/
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/
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&friends, 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/
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/
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&friends, 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/
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/
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/
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
more visiting and less buffering in drawinglayer/
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) 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. Regards, Noel Grandin