You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-dev@xmlgraphics.apache.org by Cameron McCormack <ca...@mcc.id.au> on 2008/11/12 05:38:28 UTC

Renderer bug

Hi Thomas.

I’m trying to track down a bug with the renderer.  Basically, in a
JSVGCanvas, the renderer stops painting updates after the canvas resized
in some circurmstances.  On my machine I can reproduce this (if I’m
lucky) with this document:

  http://mcc.id.au/temp/2008/resize-renderer-bug.svg

It has animation that continually changes the position of the <rect>,
back and forth.  It prints to the console the current animated position
of the <rect> every so often.  If I load that document in Squiggle, and
resize the window quickly, it will sometimes get into a state where the
rendering is not updated, but the document is otherwise still running OK
(which can be seen by the changing values being printed to the console).

I’ve found that the rendering stops because a call to
WritableRaster.createWritableChild() inside DynamicRenderer.repaint()
throws an exception (which is swallowed up) because its arguments
indicate an area that lies outside the raster:

  http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/gvt/renderer/DynamicRenderer.java?annotate=489226#l220

I have a feeling it has to do with the change that inflated dirty
rectangles by 1px to avoid rendering problems with anti-aliasing.  If I
change this line:

  http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/RepaintManager.java?view=annotate#l79

to remove that extra pixel inflation, then I can’t reproduce the bug.  I
don’t know enough about the renderer to know what to change though.  Are
you able to give me a brief rundown on how the renderer works, including
what all the various raster objects are for?

Thanks,

Cameron

-- 
Cameron McCormack ≝ http://mcc.id.au/

---------------------------------------------------------------------
To unsubscribe, e-mail: batik-dev-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: batik-dev-help@xmlgraphics.apache.org


Re: Renderer bug

Posted by Cameron McCormack <ca...@mcc.id.au>.
Hi Thomas.

Thomas DeWeese:
> How are things going?

Not bad.  Forever a uni student, but what can you do? :)

> I probably can't give you a brief run down but here we go anyway...
> …

Thanks, that was useful.

>    The Renderer just swaps back and forth between the two rasters most of
> the time.  However if the window size _grows_ then it will allocate at
> least one new raster.  This I think is where we get into trouble.  If we
> have just grown the Raster then the working/copyRaster will have larger 
> bounds than the currentRaster.  This is critical because when we go
> to copy the previous dirty regions we only intersect the copying rect
> against the working/copyRaster (r = dr.intersection(r) line 218).  I 
> didn't think of intersecting with the currentRaster since that dirty
> rectangle came from the update of that Raster. 

Ah, understood.

>    I'm having a little trouble associating the anti-alias outset with 
> the problem. However I'm fairly certain that if we clip the copy rects
> against the currentRasters bounds it will fix the problem.
> 
>         Rectangle dr = copyRaster.getBounds();
> +       Rectangle sr = null;
> +       if (currentRaster != null) 
> +           sr = currentRaster.getBounds();
> 
> ----
> 
>                         Rectangle r = (Rectangle)iter.next();
>                         if (!dr.intersects(r)) continue;
>                         r = dr.intersection(r);
> +                       if (!sr.intersects(r)) continue;
> +                       r = sr.intersection(r);

That does seem to fix the problem (adding an extra null check for sr in
there), so I’ve just committed it.

Thanks!

Cameron

-- 
Cameron McCormack ≝ http://mcc.id.au/

---------------------------------------------------------------------
To unsubscribe, e-mail: batik-dev-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: batik-dev-help@xmlgraphics.apache.org


Re: Renderer bug

Posted by th...@kodak.com.
Hi Camron,

    How are things going?

Cameron McCormack <ca...@mcc.id.au> wrote on 11/11/2008 11:38:28 PM:

> I?m trying to track down a bug with the renderer.  Basically, in a
> JSVGCanvas, the renderer stops painting updates after the canvas resized
> in some circurmstances.
>   http://mcc.id.au/temp/2008/resize-renderer-bug.svg

> I?ve found that the rendering stops because a call to
> WritableRaster.createWritableChild() inside DynamicRenderer.repaint()
> throws an exception (which is swallowed up) because its arguments
> indicate an area that lies outside the raster:
> 
>   http://svn.apache.
> 
org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/gvt/renderer/DynamicRenderer.
> java?annotate=489226#l220
> 
> I have a feeling it has to do with the change that inflated dirty
> rectangles by 1px to avoid rendering problems with anti-aliasing.  If I
> change this line:
> 
>   http://svn.apache.
> 
org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/RepaintManager.
> java?view=annotate#l79
> 
> to remove that extra pixel inflation, then I can?t reproduce the bug.

   Ok, I think I know what is happening...
 
> I don?t know enough about the renderer to know what to change though. 
Are
> you able to give me a brief rundown on how the renderer works, including
> what all the various raster objects are for?

   I probably can't give you a brief run down but here we go anyway...

   Assuming you are in the double buffered case the Renderer maintains two 

Rasters/BufferedImages; 'current' and 'working'.  The 'current' set is 
associated
with the BufferedImage most recently returned from the Renderer.  The 
'working'
set is the image/raster that we are preparing to display.  We reference 
the
workingRaster as 'copyRaster' I think this is to avoid any issues when we
swap them.

   When we get a repaint request the first thing we do is take the set of 
rectangles we last updated (damagedAreas) and subtract the set of 
rectangles
that were just changed (devRLM).  This gives us a list of areas that we 
need
to copy from the current raster to the working raster (this is where the
problem is) - these are the area that changed in the last frame but aren't
changed in the current frame.

   Once we have copied those regions we then go and render the devRLM 
list.
into the working raster.  When that is done we then swap the current and
working sets.

   The Renderer just swaps back and forth between the two rasters most of
the time.  However if the window size _grows_ then it will allocate at
least one new raster.  This I think is where we get into trouble.  If we
have just grown the Raster then the working/copyRaster will have larger 
bounds than the currentRaster.  This is critical because when we go
to copy the previous dirty regions we only intersect the copying rect
against the working/copyRaster (r = dr.intersection(r) line 218).  I 
didn't think of intersecting with the currentRaster since that dirty
rectangle came from the update of that Raster. 

   I'm having a little trouble associating the anti-alias outset with 
the problem. However I'm fairly certain that if we clip the copy rects
against the currentRasters bounds it will fix the problem.

        Rectangle dr = copyRaster.getBounds();
+       Rectangle sr = null;
+       if (currentRaster != null) 
+           sr = currentRaster.getBounds();

----

                        Rectangle r = (Rectangle)iter.next();
                        if (!dr.intersects(r)) continue;
                        r = dr.intersection(r);
+                       if (!sr.intersects(r)) continue;
+                       r = sr.intersection(r);