Benjamin K. Stuhl wrote:

> I've got a branch that I think implements this at
> https://github.com/bks/veusz/tree/layered-widgets The idea is that by
> improving the change-tracking of the document datasets and each widget's
> settings, it should now be possible to know when a cached layer is
> out-of-date. Take a look. I've opened all the example documents with the
> branch and I'm using it for real work, so it's not critically broken --
> but I did have to change most of the Operations to not directly write to
> document.data, so there's definitely room for breakage.

This looks interesing. Making the document changeset finer grained is 
definitely a good idea.

> The next step is to actually generate cached images and composite them
> together, but that needs some design thought: which component is
> responsible for maintaining the rendering hierarchy? Is it the PlotWindow,
> since that's the only component that actually wants cached images rather
> than a full redraw? Does each widget composite itself? Or does each parent
> widget composite its children? (And can we use the cached rendering tree
> to eliminate the special Painters that the PlotWindow currently uses?)

Maybe only some slower data plotting widgets need to be composited. It might 
be more effort (and take memory) to composite something like an axis or a 
key, which might occupy anywhere on the page. We could also have memory 
usage issues if someone wants to plot a hundred datasets on the same plot. 
There might need to be some intelligence where if there are over X MB of 
cached layers we switch to a direct rendering mode or do some basic 
compression (maybe storing layers as png or something).

It's an interesting problem as to how to process the rendering hierarchy. 
Maybe there should be some sort of RenderingVisitor which walks down the 
tree rendering each widget and layer, only updating those which have 
changed. It could keep track of cropping and so on and hold the images. In 
the widget class we could split up the drawing code and the code for 
calculating the dimensions of the widget in the plotted screen. It could 
also draw in a direct mode for plotting to a PDF or PS painter.

I think we could also drop the PlotWindow special painter, which would be 
nice.

>> I've thought about whether it is possible to offload rendering to a
>> non-UI thread. For the rendering thread to get a consistent view, we'd
>> need to either "snapshot" the document before rendering (maybe some sort
>> of clever copy on write scheme could be used for modifications), copy the
>> document before rendering (probably slow), or batch modifications until
>> rendering has finished (difficult to keep the UI showing the latest
>> version).
> 
> One other possibility is to have each widget render to a QPicture in the
> UI thread and then offload the QPicture-to-QImage rendering (which is
> probably the expensive part, especially if antialiasing is turned on) to a
> background thread. The PlotWindow would just recomposite whenever it got a
> new layer from the background thread; each rendering request should
> probably be tagged with the widget's changeset number so that the
> rendering thread can throw out already-out-of-date requests.

That could be a good idea. I think it might be fun to benchmark how much 
time would be spend in constructing the QPicture and how much to render it. 
We might have to modify the font metrics code for text and DPI, as I think 
QPicture doesn't propertly provide this.

Thanks for the discussion and code!

Jeremy



_______________________________________________
Veusz-discuss mailing list
[email protected]
https://mail.gna.org/listinfo/veusz-discuss

Répondre à