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

Reply via email to