Thanks Stefan.  We appreciate other voices in what was becoming a dialog.

Hi Sascha,

I agree with your two problems as stated.
        1 - We cannot determine exactly when a rendering
             has ended (successfully or not).
        2 - We have a javax,swing.Timer in RenderingManager
             that triggers a repaint any x ms.

I'm not sure that changing the repaint timer setting from 1000 to 400
affects performance significantly.  My benchmarks show a 3% increase in
render time for burlulc.  I'm not sure if that will be true for all
platforms and CPUs.  There could be some advantage from my Dell's P4
hyper-threading here.  I'll have to do more tests on a single CPU to be
sure.  I did drop the time to 40 ms and got a 22% increase.  At that level,
Jon's comment about too little happening each repaint rang true.

A 400 ms repaint timer doesn't solve the problem, but it makes it bearable
for zoom to selected.  I can't speak to how this affects the printing
plugins.  For databases and WMSLayers, it isn't the solution.  Are the
printing plugins working around this problem now by long delays or what?

I'm trying to assess the impact of not fixing this issue right now.  I don't
want to minimize the problem, but I see other more pressing issues of speed
and usability that need my attention right now.  I need to work on the speed
of Task Loading, and I found a new issue today working with very large
datasets.  It takes a _very_ long time to delete 50,000 objects.  I see big
gains with minimal effort expended in these areas.

So Sascha, what is your other suggestion for a less radical solution?

regards,
Larry


On 6/20/07, Stefan Steiniger <[EMAIL PROTECTED]> wrote:

except the ones from pirol I am not really aware of other renderers...
but compatibility is (sometimes unfortunately) one of our goals

stefan

Sascha L. Teichmann schrieb:
> Hi Larry,
>
> this all fits together very well and I have
> a couple of comments/ideas. This is most radical one:
>
> Let me switch to "software designer mode" for a moment.
> (This is what my company is paying me for besides working
> with legacy code... ;-)
>
> We have actually two problems:
>
> 1 - We cannot determine exactly when a rendering
>     has ended (successfully or not).
>
>     This is important for e.g. printing and zooming+flashing.
>
>     The 'wakeup' Runnable trick only works if all jobs are
>     processed in a serial manner. It fails when DB or WMS layers
>     are involved because these are processed truly parallel.
>
>     What we really want is some kind of a reliable barrier
>     mechanism that triggers certain things after a rendering.
>     (unlocking a wait in the printing case and flashing in case of
>      zoom to selection)
>
> 2 - We have a javax,swing.Timer in RenderingManager
>     that triggers a repaint any x ms.
>
>     To what value we should set x?
>
>     A x too large makes the the GUI feels sluggish. x choosen too
>     small costs a lot of performance. I've got interesting profiling
>     numbers from JProbe that told me that the copyTo() stuff can
>     take up to 25% of the rendering time when you set x too low.
>
>     If we ask how we have to set x, we're asking the wrong question.
>     The question should state:
>
>     Has a renderer made enough progress to do a repaint?
>
>     If the on screen differences between two repaints would be too
>     small, why should we waste time to do a redraw? Only a significant
>     change (say a quarter of features drawn more) is worth this expense.
>     With a fixed scheduled timer you cannot test this efficiently.
>
>     This has to be done in cooperation with the particular renderer.
>
> How to address these issues?
>
> In my "software designer" dreamland i would propose the following:
>
> 1 - Remove the fixed scheduled timer
>
> 2 - Change the Renderer interface (Gulp!)
>
>     I would introduce an inner interface 'RenderingMaster':
>
>       interface RenderingMaster {
>          void doRepaint(Renderer thisRenderer);
>          void renderingDone(Renderer thisRenderer, boolean success);
>       }
>
>     and change the signature of createRunnable() to:
>
>       Runnable createRunnable(RenderingMaster master);
>
>    The idea of this extra callback should be pretty obvious.
>    Each time a renderer has produced a significant part of
>    output it calls master.doRepaint(this). On the implementors
>    side of RenderingMaster we can do a repaint.
>    If a renderer finished its job it calls
>    master.renderingDone(this, true). (false after canceling)
>    On the implementors side of RenderingMaster we can do some
>    reference counting and kick some listeners when all jobs are
>    done.
>
>>From designer dreamland back to the reality of legacy code:
>
> I would estimate about 1-2 days of work to refactor the core code
> to use this new pattern + some testing.
>
> The real problem arises from the fact that there is a sky
> full of JUMPs and a lot of non-core Renderers out there.
> This modification would be a heavy one and I
> don't really dare to think about the consequences ...
>
> Things like mouse wheel zooming may profit from this change too.
> So I don't want to wipe off this idea.
>
> Any comments?
>
> Regards,
> Sascha
>
> PS: If you don't like it all I have some 'workaround' ideas too ...
>
> Larry Becker schrieb:
>> Hi Sascha,
>>
>>    I have figured out what is different about rendering timing in
>> SkyJUMP and OpenJump.  The randomly delayed drawing in OpenJump is
>> caused by the repaintTimer in RenderingManager.  In OpenJump and JUMP
it
>> is set to 1 second, and in SkyJUMP it is set to 400 ms.  This makes
>> SkyJUMP rendering more responsive to support Mouse Wheel zooming,
>> although still somewhat random.
>>
>>   When the number of items withing the current window for a given layer
>> falls below the maxFeatures threshold, the
>> simpleFeatureCollectionRenderer is used, otherwise
>> imageCachingFeatureCollectionRenderer is used.  Image Caching implies
>> that we have to wait for the repaintTimer to expire before all of the
>> results of render operations are guaranteed to be copied on screen.
>> When image Caching is disabled, drawing is synchronized but
unresponsive
>> because nothing appears on the screen until the end of the process.
>>
>>   I'm not sure we can do anything about the repaintTimer's apparent
>> randomness.  The whole point of having a repaint timer is to be
>> unsynchronized with the layer rendering process.  Setting the timer
>> value to 400 ms seems to make it responsive enough for the
>> ZoomToSelectedItemsPlugIn.  We'll need to do that anyway when mouse
>> wheel zooming in ported over.
>>
>> regards,
>> Larry
>>
>> On 6/18/07, *Larry Becker* <[EMAIL PROTECTED]
>> <mailto:[EMAIL PROTECTED]>> wrote:
>>
>>     Sascha,
>>
>>        I replaced the ThreadQueue.Listener with the following code:
>>
>>             panel.getRenderingManager
().getDefaultRendererThreadQueue().add(
>>                     new Runnable() {
>>                         public void run() {
>>                             try {
>>                                 flash(geometries, panel);
>>                             } catch (NoninvertibleTransformException e)
{};
>>                             }
>>                     });
>>
>>     This works great in SkyJUMP where I also used it to fix my refresh
>>     timer and ZoomRealtime, however although it is better than the
>>     Listener in OpenJump, it still occasionally flashes first and then
>>     zooms.  Clearly there is something wrong, but it is not in your
>>     ThreadQueue code.  I'll look some more tomorrow.
>>
>>     regards,
>>     Larry
>>
>>
>>     On 6/18/07, *Larry Becker* < [EMAIL PROTECTED]
>>     <mailto:[EMAIL PROTECTED]>> wrote:
>>
>>         Sascha,
>>
>>         > Don't you have the same effects with the original one?
>>
>>            I begin to see...   I can reproduce flash problems easily in
JUMP
>>         and OpenJump, but not in SkyJUMP.  That explains why we are
both
>>         surprised.  I have no idea why there is a difference, but I
will
>>         investigate further.
>>
>>         regards,
>>         Larry
>>
>>         On 6/18/07, Sascha L. Teichmann < [EMAIL PROTECTED]
>>         <mailto:[EMAIL PROTECTED]>> wrote:
>>         > Larry,
>>         >
>>         > _exactly_ this the thread lottery we are playing with the
>>         > assumption that no running threads means there no more
>>         rendering jobs!
>>         >
>>         > I get the same irritating behavior with the original
ThreadQueue.
>>         > I put an System.err.println("flash!") into the listener of
>>         > the zoom plug-in. Sometimes it gets printed before the
display
>>         > is in the right 'mood' to display a flash. Result: no visible
>>         > flash or only a shortened variant.
>>         >
>>         > Don't you have the same effects with the original one?
>>         > I have!
>>         >
>>         > Register a println Listener yourself to the ThreadQueue
>>         > and be surprised how often it is called.
>>         >
>>         > The zoom plug-in builds on this assumption the even more
venturous
>>         > assumption that the zoom is done when there no more running
>>         threads.
>>         > It does not take into account that the hole
>>         repaint()/erase()/copyTo()
>>         > stuff also takes some time. The invokeLater() call does not
make it
>>         > more predictable.
>>         >
>>         > Let us compare the TQs:
>>         >
>>         > 1) Original TQ:
>>         >
>>         >   public void add(final Runnable runnable) {
>>         >      queuedRunnables.add(new Runnable() {
>>         >         public void run() {
>>         >            try {
>>         >              runnable.run();
>>         >            } finally {
>>         >               setRunningThreads(getRunningThreads() - 1);
>>         >               processQueue();
>>         >            }
>>         >         }
>>         >      });
>>         >      processQueue();
>>         >   }
>>         >
>>         >   private void setRunningThreads(int runningThreads) {
>>         >       this.runningThreads = runningThreads;
>>         >      if (runningThreads == 0) {
fireAllRunningThreadsFinished(); }
>>         >   }
>>         >
>>         >   The defaultRenderingThread has only one Thread running.
>>         >   -> runningThreads == 1 during try block of new Runnable.run
().
>>         >
>>         >   setRunningThread() in the finally sets it to zero
>>         >   -> listeners get there kick.
>>         >
>>         >   This means that after each and every job the listeners get
>>         kicked.
>>         >
>>         > 2) New TQ: (in worker thread's run())
>>         >
>>         >   for (;;) {
>>         >      // unimportant part
>>         >      try {
>>         >        runnable.run();
>>         >      }
>>         >      catch (Exception e) {
>>         >         e.printStackTrace();
>>         >      }
>>         >
>>         >      boolean lastRunningThread;
>>         >      synchronized (runningThreads) {
>>         >        lastRunningThread = runningThreads[0] == 1;
>>         >      }
>>         >      if (lastRunningThread) {
>>         >        fireAllRunningThreadsFinished();
>>         >      }
>>         >   }
>>         >
>>         >   The defaultRenderingThread has only one Thread running.
>>         >   -> runningThreads[0] == 1
>>         >
>>         >   after the try block lastRunningThread is set to true
>>         >   if runningThreads[0] == 1. This is always fulfilled for
>>         >   the defaultRenderingThread.
>>         >   -> listeners get there kick.
>>         >
>>         >   This means that after each and every job the listeners get
>>         kicked.
>>         >
>>         > => Same behavior for 1) and 2)
>>         >
>>         > Maybe I bore you a bit by repeating it.
>>         >
>>         > Regards,
>>         > Sascha
>>         >
>>         >
>>         > Larry Becker schrieb:
>>         > > Sascha,
>>         > >
>>         > >    Thanks for your patience.  I like the idea of preserving
the
>>         > > original behavior, however this version doesn't seem to
flash
>>         > > consistently.  Sometimes it doesn't flash, sometimes it
does.
>>         > >
>>         > > regards,
>>         > > Larry
>>         > >
>>         > > On 6/18/07, Sascha L. Teichmann < [EMAIL PROTECTED]
>>         <mailto:[EMAIL PROTECTED]>> wrote:
>>         > >> Larry,
>>         > >>
>>         > >> there is probably somebody out there (younger than us)
>>         > >> how says that 400ms feels slow too.
>>         > >>
>>         > >> I've thought a bit about the compromise and came to the
>>         > >> conclusion that we don't need a make a compromise here.
>>         > >>
>>         > >> We have simply to restore the behavior of the
>>         > >> original TheadQueue. The original one fires the
>>         > >> Listeners when the running threads went down to zero.
>>         > >> We can do the same when we're in the situation that we
>>         > >> are the last remaining thread with our job done.
>>         > >>
>>         > >> In this case the number of running threads is
>>         > >> one but this measure wasn't reliable in the old
>>         > >> ThreadQueue too. So it doesn't matter.
>>         > >> But in difference to the original we keep the
>>         > >> worker thread alive afterwards instead of killing it.
>>         > >>
>>         > >> Find attached a new version of the ThreadQueue that
>>         > >> implements this behavior.
>>         > >>
>>         > >> regards,
>>         > >> Sascha
>>         > >>
>>         > >> Larry Becker schrieb:
>>         > >>> Sascha,
>>         > >>>
>>         > >>>   I tried one second, and it feels slow.  When I am
>>         arrowing through a
>>         > >>> selection of records in View/Edit Attributes it makes me
>>         wait for the
>>         > >>> flash before I move on.  Really, this is becoming  an
issue of
>>         > >>> compromising the interactivity of the application to
>>         achieve some
>>         > >>> theoretical benefit that can't be seen or measured.
>>         > >>>
>>         > >>> How about 400 ms?  That is about the average reaction
time.
>>         > >>>
>>         > >>> regards,
>>         > >>> Larry Becker
>>         > >>
>>
-------------------------------------------------------------------------
>>         > >> This SF.net email is sponsored by DB2 Express
>>         > >> Download DB2 Express C - the FREE version of DB2 express
and
>>         take
>>         > >> control of your XML. No limits. Just data. Click to get it
now.
>>         > >> http://sourceforge.net/powerbar/db2/
>>         <http://sourceforge.net/powerbar/db2/>
>>         > >> _______________________________________________
>>         > >> Jump-pilot-devel mailing list
>>         > >> Jump-pilot-devel@lists.sourceforge.net
>>         <mailto:Jump-pilot-devel@lists.sourceforge.net>
>>         > >>
https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel
>>         > >>
>>         > >>
>>         > >>
>>         > >
>>         > >
>>         >
>>         >
-------------------------------------------------------------------------
>>
>>         > This SF.net email is sponsored by DB2 Express
>>         > Download DB2 Express C - the FREE version of DB2 express and
take
>>         > control of your XML. No limits. Just data. Click to get it
now.
>>         > http://sourceforge.net/powerbar/db2/
>>         > _______________________________________________
>>         > Jump-pilot-devel mailing list
>>         > Jump-pilot-devel@lists.sourceforge.net
>>         <mailto:Jump-pilot-devel@lists.sourceforge.net>
>>         > https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel
>>         >
>>
>>
>>         --
>>         http://amusingprogrammer.blogspot.com/
>>
>>
>>
>>
>>     --
>>     http://amusingprogrammer.blogspot.com/
>>
>>
>>
>>
>> --
>> http://amusingprogrammer.blogspot.com/
>>
>>
>>
------------------------------------------------------------------------
>>
>>
-------------------------------------------------------------------------
>> This SF.net email is sponsored by DB2 Express
>> Download DB2 Express C - the FREE version of DB2 express and take
>> control of your XML. No limits. Just data. Click to get it now.
>> http://sourceforge.net/powerbar/db2/
>>
>>
>>
------------------------------------------------------------------------
>>
>> _______________________________________________
>> Jump-pilot-devel mailing list
>> Jump-pilot-devel@lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel
>
>
-------------------------------------------------------------------------
> This SF.net email is sponsored by DB2 Express
> Download DB2 Express C - the FREE version of DB2 express and take
> control of your XML. No limits. Just data. Click to get it now.
> http://sourceforge.net/powerbar/db2/
> _______________________________________________
> Jump-pilot-devel mailing list
> Jump-pilot-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel
>
>

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Jump-pilot-devel mailing list
Jump-pilot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel




--
http://amusingprogrammer.blogspot.com/
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Jump-pilot-devel mailing list
Jump-pilot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel

Reply via email to