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
>> > >> [email protected]
>> <mailto:[email protected]>
>> > >> 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
>> > [email protected]
>> <mailto:[email protected]>
>> > 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
>> [email protected]
>> 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
> [email protected]
> 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
[email protected]
https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel