Hi Camron,
How are things going?
Cameron McCormack <[EMAIL PROTECTED]> 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);