Jim,

thanks for your interesting feedback.

2013/3/30 Jim Graham <james.gra...@oracle.com>

> J2DBench does not have a regression test mode unfortunately.
>
> Clipping in the stroker and dasher is doable, but it is complicated by the
> fact that stroking adds decorations that are not always easy to account
> for.  Round joins and end caps are easy - they "grow" the path by exactly
> half the line width.  Square and Butt caps and Bevel joins are equally
> predictable, you can do some trig or come up with an upper bound on how
> much they may "grow" the path in any given direction.  Miter joins are the
> hardest as it depends on the miter limit and the angle between the line
> segments.  Also, curves could be rejected based on conservative trivial
> estimates of the worst case of the path and the worst case of the stroke
> "grow" factor by using their 4 control points, but if you want something
> more exact then you have to subdivide them anyway.
>
> And when you cull, you have to remember to update all of the state so that
> you know the "previous slope and join info" so that the next segment, which
> might not be culled, can interpolate the correct joins.
>
> As with any culling, you have to measure the likelihood of success against
> the cost of the computations.  As such, it is probably best to perform the
> most conservative estimates before culling the paths so that you don't slow
> down some common cases of the path being fully visible.
>

I would like first try / do simple things: skip segments totally out of the
clipping + margin (10%) to avoid the dasher create millions of invisible
segments.
it seams simple but check each segment could become a performance
bottleneck too !

I advocate it is a complex issue but I think it can be done first by
analyzing each line given to the Renderer (lineTo) ...

For complex shapes (curves), it could be interesting to take into account
the spatial resolution: for example a curve that represents less than 1
(AA) pixel should be skipped ... it can apply to caps (mitter, bevel,
rounded) too!

Do you look at the java2D Pisces code, Jim ?
I think it quite difficult to understand (only few comments / explanations
...). Does somebody know if there is some docs on this implementation /
algorithms ?


>
> I forget how the Renderer piece is written, but hopefully it culls
> segments that are outside the clip so that while we may waste time
> generating the dashes and widened paths for parts that are outside the
> clip, at least we don't spend time rasterizing them?
>

I should check if the Renderer really skips (edges / tiles) that are out of
the clipping area. (ScanLineIterator ...)

Thanks again,
Happy easter,

Laurent


On 3/28/2013 8:40 AM, Laurent Bourgès wrote:

> Dear java2d members,
>
> FYI: I now have a working patched java2d pisces that performs better: no
> memory waste (99%) and performance increased on complex operations (dashed
> ...); patch / benchmark in progress ...
>
> Does J2DBench have a regression test mode ?
> i.e. capture screenshots (with few shapes) to compare them between
> different runs (image comparison pixel by pixel)
>
> Besides, I found an important bug in pisces Stroker / Dasher: it does not
> use the clip region given to PiscesRenderingEngine.**
> getAATileGenerator(clip).
>
> In Aspro2, I can zoom on jFreeChart plots a lot and it draws shapes
> (rectangle or lines with dashed lines) then the dasher emits segments out
> of the visible area (millions in case of a important zoom) and the
> application hangs a for while (5s to minutes).
>
> I would like to determine the shape part (line or any complex shape) that
> is inside the clip and avoid useless segments (Stroker / Dasher).
>
> Does somebody have any idea ?
> or know java2d.pisces code enough to help me ?
>
> Laurent
>
>
> 2013/3/26 Laurent Bourgčs <bourges.laur...@gmail.com <mailto:
> bourges.laurent@gmail.**com <bourges.laur...@gmail.com>>>
>
>
>     Dear all,
>
>     First I joined recently the openJDK contributors, and I plan to fix
> java2D pisces code in my spare time.
>
>     I have a full time job on Aspro2: http://www.jmmc.fr/aspro; it is an
> application to prepare astronomical observations at VLTI / CHARA and is
> very used in our community (200 users): it provides scientific computations
> (observability, model images using complex numbers ...) and zoomable plots
> thanks to jFreeChart.
>
>     Aspro2 is known to be very efficient (computation parallelization) and
> I am often doing profiling using netbeans profiler or visualVM.
>
>     To fix huge memory usages by java2d.pisces, I started implementing an
> efficient ArrayCache (int[] and float[]) (in thread local to concurrency
> problems):
>     - arrays in sizes between 10 and 10000 (more small arrays used than
> big ones)
>     - resizing support (Arrays.copyOf) without wasting arrays
>     - reentrance i.e. many arrays are used at the same time (java2D Pisces
> stroke / dash creates many segments to render)
>     - GC / Heap friendly ie support cache eviction and avoid consuming too
> much memory
>
>     I know object pooling is known to be not efficient with recent VM (GC
> is better) but I think it is counter productive to create so many int[]
> arrays in java2d.pisces and let the GC remove such wasted memory.
>
>     Does someone have implemented such (open source) array cache
> (core-libs) ?
>     Opinions are welcome (but avoid "trolls").
>
>     Moreover, sun.java2d.pisces.Helpers.**widenArray() performs a lot of
> array resizing / copy (Arrays.copyOf) that I want to avoid mostly:
>          // These use a hardcoded factor of 2 for increasing sizes.
> Perhaps this
>          // should be provided as an argument.
>          static float[] widenArray(float[] in, final int cursize, final
> int numToAdd) {
>              if (in.length >= cursize + numToAdd) {
>                  return in;
>              }
>              return Arrays.copyOf(in, 2 * (cursize + numToAdd));
>          }
>
>          static int[] widenArray(int[] in, final int cursize, final int
> numToAdd) {
>              if (in.length >= cursize + numToAdd) {
>                  return in;
>              }
>              return Arrays.copyOf(in, 2 * (cursize + numToAdd));
>          }
>
>     Thanks to Peter Levart, I use its microbench tool (
> https://github.com/plevart/**micro-bench/tree/v2<https://github.com/plevart/micro-bench/tree/v2>)
> to benchmark ArrayCache operations... and J2DBench to test java2d
> performances
>
> ...
>
>
>     PS: java.awt.geom.Path2D has also memory allocation issues:
>              void needRoom(boolean needMove, int newCoords) {
>                  if (needMove && numTypes == 0) {
>                      throw new IllegalPathStateException("**missing
> initial moveto "+
>                                                          "in path
> definition");
>                  }
>                  int size = pointTypes.length;
>                  if (numTypes >= size) {
>                      int grow = size;
>                      if (grow > EXPAND_MAX) {
>                          grow = EXPAND_MAX;
>                      }
>                      pointTypes = Arrays.copyOf(pointTypes, size+grow);
>                  }
>                  size = floatCoords.length;
>                  if (numCoords + newCoords > size) {
>                      int grow = size;
>                      if (grow > EXPAND_MAX * 2) {
>                          grow = EXPAND_MAX * 2;
>                      }
>                      if (grow < newCoords) {
>                          grow = newCoords;
>                      }
>                      floatCoords = Arrays.copyOf(floatCoords, size+grow);
>                  }
>              }
>
>     Best regards,
>     Laurent
>
>
>

Reply via email to