Render DNC to offscreen canvas

30 views
Skip to first unread message

Christopher Dillard

unread,
Feb 26, 2020, 4:57:11 PM2/26/20
to Glimpse
What would be the best way to use the DncPainter to render to an offscreen canvas?

You might think you could just start with OffscreenRenderingExample and change it to use a layout that includes the DNC painter.  But this always produces a completely blank, black image.  Some debugging shows that the DNC painter fires up a number of background threads (managed by the asyncExec, iconsExec, and labelsExec members, plus the render cache has others).  So naively just building the layout and immediately calling canvas.toBufferedImage() doesn't give those threads enough time to do their work. See attached file NaiveAttempt.java.

So I tried subclassing DncPainter to override paintTo so that it would wait until the background threads are done and call the superclass paintTo again.  But this is unreliable.  Sometimes everything draws, sometimes not.  See attached file WaitForAsyncAndRepaint.java.  If you were to run it a few times, it'll produce slightly different images each time.

Is there some easy way to un-thread DncPainter and its moving parts?  Or to force it to pre-load everything in the view so that the paintTo method can render everything immediately?

Thanks for any input or ideas!
NaiveAttempt.java
WaitForAsyncAndRepaint.java

Mike Hogye

unread,
Feb 27, 2020, 7:58:46 AM2/27/20
to metsci-...@googlegroups.com
Glimpse doesn't provide a good way to do this. We needed something similar several years ago, so we started sticking semaphores into all of DncPainter's async jobs ... and it was so complicated that we gave up on that approach. I'm sure it could be made to work, but debuggability would be very poor.

In the end we made a copy of DncPainter, called it DncPainterSync, and chopped out all the async code. That resulted in a few hundred lines of duplicated code ... but it was dramatically cleaner than our semaphore-based attempt.

Let me dig up that old DncPainterSync code. It's not going to be exactly what you want -- it's based on an old version of DncPainter -- but it might help point the way for you if you want to de-asynchronize the current DncPainter.

Mike Hogye

unread,
Feb 27, 2020, 10:33:04 AM2/27/20
to Glimpse
Here's the old DncPainterSync code. Let me know if you have any questions.
DncPainterSync.java

Christopher Dillard

unread,
Feb 27, 2020, 5:39:42 PM2/27/20
to Glimpse
It appears that the DNC code has changed quite a bit between then and now.  If I don't care about having the latest and greatest Glimpse, could I check out some old version from github and use your file verbatim?

Mike Hogye

unread,
Mar 2, 2020, 10:22:41 AM3/2/20
to Glimpse
Try this. It's ugly, but it should work reliably. Let me know how it goes!
DncPainterSync.java
DncPainterSyncExample.java

Christopher Dillard

unread,
Mar 2, 2020, 6:04:59 PM3/2/20
to Glimpse
That works great, thank you very much!

We want to reuse the canvas and painter objects (for performance).  So I re-added some of the chunk disposal logic.  Is there anything else I need to do to make sure it doesn't leak memory if we keep using the same painter object over and over?

Mike Hogye

unread,
Mar 3, 2020, 1:37:20 PM3/3/20
to Glimpse
Good call on chunk disposal! You may already have gotten these, but the other things to dispose of are: dIconAtlasesToDispose, dLabelAtlasesToDispose, highlightSetsToDispose.

Updated version attached. It disposes of all that stuff, and also simplifies the synchronization in the paint method (... which worked fine before, but was unnecessarily complicated).
DncPainterSync.java
Reply all
Reply to author
Forward
0 new messages