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