Setting -Dsun.java2d.d3d=true is also slightly slower than the default. Larry
On 6/5/07, Sascha L. Teichmann <[EMAIL PROTECTED]> wrote: > Have you also tried the Direct3D path (-Dsun.java2d.d3d=true)? > > I think the results depend on the graphics hardware and driver quality. > > Sascha > > > Larry Becker schrieb: > > I did try the -Dsun.java2d.opengl=true on Windows XP and it rendered > > just a little slower than the default method. > > > > Larry > > > > On 6/5/07, Larry Becker <[EMAIL PROTECTED]> wrote: > >> Hi Sascha, > >> > >> I've done experiments with doing inline transformations (no > >> AffineTransform), and found that it was no faster either. One theory > >> to explain this is that the bottleneck is in the graphics system > >> itself. However, that is contradicted by other experiments that I > >> have done which show that if you have all of the shape objects > >> already, the time to plot them is not significant on modern > >> accelerated graphics cards (less than a second). It might be > >> different on X11 under Linux though. > >> > >> What we need is a better understanding of where the time is being > >> spent, but this is difficult to achieve. So far I have not been > >> successful at getting the profile information needed. > >> > >> I do know that the redraw process is responsible for most of the > >> cyclic (new generation) memory consumption in JUMP. This doesn't seem > >> to slow down the program much until the percent of free memory drops > >> to below 5 %. > >> > >> regards, > >> Larry > >> > >> On 6/5/07, Sascha L. Teichmann <[EMAIL PROTECTED]> wrote: > >>> Hi! > >>> > >>> It's only that temp array, there are actually two. In case > >>> of decimation the first allocated is copied over to a second > >>> to archive tight fitting. > >>> Not to forget the Coordinate->Point2D->Coordinate > >>> transformations with the PointConverter, which also > >>> introduces a lot of temporal object allocation. The > >>> new created GeneralPaths stores another internal copy > >>> of the data too if the moveTo()/lineTo() calls are done > >>> to fill it. > >>> > >>> I experimented with caching the result of the > >>> on-the-fly DirectPolygon in case of filled polygons > >>> where the geometry is rendered twice (border + fill). > >>> In this case the inline decimation is run twice per > >>> polygon. You can log the transformation result from > >>> the first rendering and associate it with last transform. > >>> If the second path iterator call is coming you can > >>> compare the last transform and new one and in case > >>> of equality you can run a simple and fast replay PathIterator > >>> for the last result. But this does _not_ lead to > >>> speed improvements. The extra book keeping seems to be more > >>> expensive than the simply run the decimation twice. > >>> I've code for this, but I think we do better without this. > >>> > >>> The streamlining is a good idea! I will do the same > >>> optimization to LineStrings too, if you approve. > >>> > >>> BTW: If I turn on the OpenGL backend (-Dsun.java2d.opengl=true) > >>> the burlulc layer renders a second faster when compared to > >>> the plain X11 backend. As soon as I've access to a 3D accelerated > >>> MS Windows I will have a look if this holds for Direct3D too. > >>> > >>> regards, Sascha > >>> > >>> > >>> > >>> Larry Becker schrieb: > >>>> I don't have time to look at it closely right now, but it sounds like > >>>> a logical simplification. I hate that temp array too. > >>>> > >>>> regards, > >>>> Larry > >>>> > >>>> On 6/4/07, Michaël Michaud <[EMAIL PROTECTED]> wrote: > >>>>> Hi Sascha; > >>>>> > >>>>> Sounds interesting. > >>>>> Please, let me some more time to have a closer look and see how your > >>>>> code compare to the one in CVS. > >>>>> Note : I made a recent change in CVS to have the resolution as a > >>>>> property and modify it as needed (default=1/2 pixel) for special > >>>>> renderers. > >>>>> > >>>>> Michael > >>>>> > >>>>> Sascha L. Teichmann a écrit : > >>>>> > >>>>>> Hi Larry, hi Michaël, > >>>>>> > >>>>>> I had a look at the decimation code in Java2DConverter. > >>>>>> This is awesome! Congratulations! :-) > >>>>>> > >>>>>> But way not go step further and streamline the model to view > >>>>>> coordination transform. Why to create all this temporary > >>>>>> Coordinate[] stuff? In the end all what matters is a PathIterator > >>>>>> that can handle an AffineTransform coming from Java2D. > >>>>>> Instead of transform the data to a temporary Coordinate array > >>>>>> and used this to construct GeneralPaths we can write a PathIterator > >>>>>> that transforms and decimates the data on-the-fly. > >>>>>> All we have to do is to concatenate the model to view transform to the > >>>>>> incoming matrix. > >>>>>> > >>>>>> To archive this we must add a > >>>>>> > >>>>>> AffineTransform getModelToViewTransform(); > >>>>>> > >>>>>> method to the Java2DConverter.PointConverter interface. This > >>>>>> does not hurt because Viewport already implements it. > >>>>>> > >>>>>> To see what I mean, look at the DirectPolygonShape that I've > >>>>>> attached. It handles the Polygon case of Java2DConverter. > >>>>>> Add this class to the sources and change the toShape(Polygon) > >>>>>> method to look as follow: > >>>>>> > >>>>>> private Shape toShape(Polygon polygon) throws > >>>>>> NoninvertibleTransformException > >>>>>> { > >>>>>> return new DirectPolygonShape( > >>>>>> polygon, > >>>>>> pointConverter.getModelToViewTransform(), > >>>>>> 1d / (2d*pointConverter.getScale())); > >>>>>> } > >>>>>> > >>>>>> Speaking of performance. On my computer > >>>>>> (very old 1.2 GHz AMD/Athlon-T-Bird running GNU/Linux, Java 6) > >>>>>> the burluc layer is rendered in full extend without the streamling > >>>>>> in about 9.x seconds, with the streamling in about 8.x secs, with > >>>>>> x varying a bit. It's just a second, but it's a second! ;-) > >>>>>> > >>>>>> What do you think? > >>>>>> > >>>>>> Regards, Sascha > >>>>>> > >>>>>> > >>>>>> ------------------------------------------------------------------------ > >>>>>> > >>>>>> > >>>>>> /* > >>>>>> * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI > >>>>>> * for visualizing and manipulating spatial features with geometry and > >>>>>> attributes. > >>>>>> * > >>>>>> * Copyright (C) 2003 Vivid Solutions > >>>>>> * > >>>>>> * This program is free software; you can redistribute it and/or > >>>>>> * modify it under the terms of the GNU General Public License > >>>>>> * as published by the Free Software Foundation; either version 2 > >>>>>> * of the License, or (at your option) any later version. > >>>>>> * > >>>>>> * This program is distributed in the hope that it will be useful, > >>>>>> * but WITHOUT ANY WARRANTY; without even the implied warranty of > >>>>>> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > >>>>>> * GNU General Public License for more details. > >>>>>> * > >>>>>> * You should have received a copy of the GNU General Public License > >>>>>> * along with this program; if not, write to the Free Software > >>>>>> * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA > >>>>>> 02111-1307, USA. > >>>>>> * > >>>>>> * For more information, contact: > >>>>>> * > >>>>>> * Vivid Solutions > >>>>>> * Suite #1A > >>>>>> * 2328 Government Street > >>>>>> * Victoria BC V8T 5G5 > >>>>>> * Canada > >>>>>> * > >>>>>> * (250)385-6040 > >>>>>> * www.vividsolutions.com > >>>>>> */ > >>>>>> > >>>>>> package com.vividsolutions.jump.workbench.ui.renderer.java2D; > >>>>>> > >>>>>> import com.vividsolutions.jts.geom.Coordinate; > >>>>>> import com.vividsolutions.jts.geom.Polygon; > >>>>>> > >>>>>> import java.awt.Rectangle; > >>>>>> import java.awt.Shape; > >>>>>> import java.awt.geom.AffineTransform; > >>>>>> import java.awt.geom.GeneralPath; > >>>>>> import java.awt.geom.PathIterator; > >>>>>> import java.awt.geom.Point2D; > >>>>>> import java.awt.geom.Rectangle2D; > >>>>>> > >>>>>> import java.util.Iterator; > >>>>>> import java.util.NoSuchElementException; > >>>>>> > >>>>>> // for more accurate (float instead of int) rendering. > >>>>>> // From larry becker's SkyJUMP code to OpenJUMP [mmichaud] > >>>>>> // Streamlined [s-l-teichmann] > >>>>>> public class DirectPolygonShape > >>>>>> implements Shape > >>>>>> { > >>>>>> private Polygon polygon; > >>>>>> private AffineTransform model2view; > >>>>>> private double halfPixel; > >>>>>> > >>>>>> protected DirectPolygonShape(){ > >>>>>> } > >>>>>> > >>>>>> /** > >>>>>> * @param polygon the JTS polygon > >>>>>> * @param model2view the affine transform from model to view > >>>>>> * @param halfPixel line segments shorter than halfPixel are > >>>>>> ignored. > >>>>>> */ > >>>>>> public DirectPolygonShape( > >>>>>> Polygon polygon, > >>>>>> AffineTransform model2view, > >>>>>> double halfPixel > >>>>>> ) { > >>>>>> this.polygon = polygon; > >>>>>> this.model2view = model2view; > >>>>>> this.halfPixel = halfPixel; > >>>>>> } > >>>>>> > >>>>>> /** > >>>>>> * helper PathIterator that iterates over PathIterators > >>>>>> */ > >>>>>> public final class PathIteratorsIterator > >>>>>> implements PathIterator > >>>>>> { > >>>>>> private Iterator iterators; > >>>>>> private boolean done; > >>>>>> private PathIterator current; > >>>>>> > >>>>>> public PathIteratorsIterator(Iterator iterators) { > >>>>>> this.iterators = iterators; > >>>>>> > >>>>>> if (!iterators.hasNext()) > >>>>>> done = true; > >>>>>> else > >>>>>> current = (PathIterator)iterators.next(); > >>>>>> } > >>>>>> > >>>>>> public int getWindingRule() { > >>>>>> return WIND_EVEN_ODD; > >>>>>> } > >>>>>> > >>>>>> public boolean isDone() { > >>>>>> return done; > >>>>>> } > >>>>>> > >>>>>> public void next() { > >>>>>> if (done) > >>>>>> return; > >>>>>> > >>>>>> if (current.isDone()) { > >>>>>> if (iterators.hasNext()) > >>>>>> current = > >>>>>> (PathIterator)iterators.next(); > >>>>>> else > >>>>>> done = true; > >>>>>> } > >>>>>> else > >>>>>> current.next(); > >>>>>> } > >>>>>> > >>>>>> public int currentSegment(float [] coords) { > >>>>>> return current.currentSegment(coords); > >>>>>> } > >>>>>> > >>>>>> public int currentSegment(double [] coords) { > >>>>>> return current.currentSegment(coords); > >>>>>> } > >>>>>> } // class PathIteratorsIterator > >>>>>> > >>>>>> /** > >>>>>> * Implements a PathIterator and Larry's decimator on-the-fly > >>>>>> */ > >>>>>> public static final class AffinePolygonPath > >>>>>> implements PathIterator > >>>>>> { > >>>>>> private int iterate; > >>>>>> private Coordinate [] points; > >>>>>> private Point2D.Double tmp; > >>>>>> private AffineTransform xform; > >>>>>> private double halfPixel; > >>>>>> private Coordinate p0; > >>>>>> private int segmentType; > >>>>>> > >>>>>> public AffinePolygonPath( > >>>>>> Coordinate [] points, > >>>>>> AffineTransform xform, > >>>>>> double halfPixel > >>>>>> ){ > >>>>>> this.xform = xform; > >>>>>> this.points = points; > >>>>>> this.halfPixel = halfPixel; > >>>>>> tmp = new Point2D.Double(); > >>>>>> internalNext(); > >>>>>> } > >>>>>> > >>>>>> /** Math.abs() is a known for being slow ... */ > >>>>>> private static final double abs(double x) { > >>>>>> return x < 0d ? -x : x; > >>>>>> } > >>>>>> > >>>>>> private final void internalNext() { > >>>>>> for (;;) { > >>>>>> // issue SEG_CLOSE at end > >>>>>> if (iterate >= points.length) { > >>>>>> segmentType = SEG_CLOSE; > >>>>>> break; > >>>>>> } > >>>>>> > >>>>>> // issue first two and last > >>>>>> if (iterate < 2 || iterate == > >>>>>> points.length-1) { > >>>>>> Coordinate pi = points[iterate]; > >>>>>> tmp.x = pi.x; > >>>>>> tmp.y = pi.y; > >>>>>> xform.transform(tmp, tmp); > >>>>>> p0 = pi; > >>>>>> } > >>>>>> else { // distance lesser than halfPixel? > >>>>>> Coordinate pi = points[iterate]; > >>>>>> if (abs(p0.x-pi.x) > halfPixel > >>>>>> || abs(p0.y-pi.y) > halfPixel) { > >>>>>> tmp.x = pi.x; > >>>>>> tmp.y = pi.y; > >>>>>> xform.transform(tmp, > >>>>>> tmp); > >>>>>> p0 = pi; > >>>>>> } > >>>>>> else { // yes: try next > >>>>>> ++iterate; > >>>>>> continue; > >>>>>> } > >>>>>> } > >>>>>> > >>>>>> segmentType = iterate == 0 > >>>>>> ? SEG_MOVETO > >>>>>> : SEG_LINETO; > >>>>>> break; > >>>>>> } // for (;;) > >>>>>> } > >>>>>> > >>>>>> public int currentSegment(double[] coords) { > >>>>>> coords[0] = tmp.x; > >>>>>> coords[1] = tmp.y; > >>>>>> return segmentType; > >>>>>> } > >>>>>> > >>>>>> > >>>>>> public int currentSegment(float[] coords) { > >>>>>> coords[0] = (float)tmp.x; > >>>>>> coords[1] = (float)tmp.y; > >>>>>> return segmentType; > >>>>>> } > >>>>>> > >>>>>> public int getWindingRule() { > >>>>>> return GeneralPath.WIND_EVEN_ODD; > >>>>>> } > >>>>>> > >>>>>> public boolean isDone() { > >>>>>> return segmentType == SEG_CLOSE; > >>>>>> } > >>>>>> > >>>>>> public void next() { > >>>>>> ++iterate; > >>>>>> internalNext(); > >>>>>> } > >>>>>> } // class AffinePolygonPath > >>>>>> > >>>>>> public Rectangle getBounds() { > >>>>>> /[EMAIL PROTECTED] Implement this java.awt.Shape > >>>>>> method*/ > >>>>>> throw new > >>>>>> java.lang.UnsupportedOperationException( > >>>>>> "Method getBounds() not yet > >>>>>> implemented."); > >>>>>> } > >>>>>> > >>>>>> public Rectangle2D getBounds2D() { > >>>>>> /[EMAIL PROTECTED] Implement this java.awt.Shape > >>>>>> method*/ > >>>>>> throw new > >>>>>> java.lang.UnsupportedOperationException( > >>>>>> "Method getBounds() not yet > >>>>>> implemented."); > >>>>>> } > >>>>>> > >>>>>> public boolean contains(double x, double y) { > >>>>>> /[EMAIL PROTECTED] Implement this java.awt.Shape > >>>>>> method*/ > >>>>>> throw new > >>>>>> java.lang.UnsupportedOperationException( > >>>>>> "Method contains() not yet > >>>>>> implemented."); > >>>>>> } > >>>>>> > >>>>>> public boolean contains(Point2D p) { > >>>>>> /[EMAIL PROTECTED] Implement this java.awt.Shape > >>>>>> method*/ > >>>>>> throw new > >>>>>> java.lang.UnsupportedOperationException( > >>>>>> "Method contains() not yet > >>>>>> implemented."); > >>>>>> } > >>>>>> > >>>>>> public boolean intersects(double x, double y, double w, double > >>>>>> h) { > >>>>>> /[EMAIL PROTECTED] Implement this java.awt.Shape > >>>>>> method*/ > >>>>>> throw new > >>>>>> java.lang.UnsupportedOperationException( > >>>>>> "Method intersects() not yet > >>>>>> implemented."); > >>>>>> } > >>>>>> > >>>>>> public boolean intersects(Rectangle2D r) { > >>>>>> /[EMAIL PROTECTED] Implement this java.awt.Shape > >>>>>> method*/ > >>>>>> throw new > >>>>>> java.lang.UnsupportedOperationException( > >>>>>> "Method intersects() not yet > >>>>>> implemented."); > >>>>>> } > >>>>>> > >>>>>> public boolean contains(double x, double y, double w, double h) { > >>>>>> /[EMAIL PROTECTED] Implement this java.awt.Shape > >>>>>> method*/ > >>>>>> throw new > >>>>>> java.lang.UnsupportedOperationException( > >>>>>> "Method contains() not yet > >>>>>> implemented."); > >>>>>> } > >>>>>> > >>>>>> public boolean contains(Rectangle2D r) { > >>>>>> /[EMAIL PROTECTED] Implement this java.awt.Shape > >>>>>> method*/ > >>>>>> throw new > >>>>>> java.lang.UnsupportedOperationException( > >>>>>> "Method contains() not yet > >>>>>> implemented."); > >>>>>> } > >>>>>> > >>>>>> public PathIterator getPathIterator(AffineTransform xform) { > >>>>>> > >>>>>> if (xform == null) > >>>>>> xform = model2view; > >>>>>> else { > >>>>>> xform = new AffineTransform(xform); > >>>>>> xform.concatenate(model2view); > >>>>>> } > >>>>>> > >>>>>> final AffineTransform at = xform; > >>>>>> > >>>>>> return new PathIteratorsIterator(new Iterator() { > >>>>>> > >>>>>> int ring; > >>>>>> > >>>>>> public boolean hasNext() { > >>>>>> return ring < > >>>>>> polygon.getNumInteriorRing() + 1; > >>>>>> } > >>>>>> > >>>>>> public Object next() { > >>>>>> if (!hasNext()) > >>>>>> throw new > >>>>>> NoSuchElementException(); > >>>>>> Object x = ring == 0 > >>>>>> ? new > >>>>>> AffinePolygonPath(polygon.getExteriorRing().getCoordinates(), > >>>>>> at, halfPixel) > >>>>>> : new > >>>>>> AffinePolygonPath(polygon.getInteriorRingN(ring-1).getCoordinates(), > >>>>>> at, halfPixel); > >>>>>> ++ring; > >>>>>> return x; > >>>>>> } > >>>>>> > >>>>>> public void remove() { > >>>>>> throw new > >>>>>> UnsupportedOperationException(); > >>>>>> } > >>>>>> }); > >>>>>> > >>>>>> } > >>>>>> > >>>>>> public PathIterator getPathIterator(AffineTransform at, double > >>>>>> flatness) { > >>>>>> // since we don't support curved geometries, can simply > >>>>>> delegate to the simple method > >>>>>> return getPathIterator(at); > >>>>>> } > >>>>>> } > >>>>>> // end of file > >>>>>> > >>>>>> > >>>>>> ------------------------------------------------------------------------ > >>>>>> > >>>>>> ------------------------------------------------------------------------- > >>>>>> 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 > >>> > >> > >> -- > >> 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 > -- 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