jdk/src/windows/classes/sun/java2d/d3d/D3DRenderer.java
changeset 2 90ce3da70b43
child 887 0aab8d3fa11a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/windows/classes/sun/java2d/d3d/D3DRenderer.java	Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,365 @@
+/*
+ * Copyright 2002-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.java2d.d3d;
+
+import java.awt.Composite;
+import java.awt.Polygon;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Arc2D;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.IllegalPathStateException;
+import java.awt.geom.PathIterator;
+import java.awt.geom.RoundRectangle2D;
+import sun.java2d.SunGraphics2D;
+import sun.java2d.pipe.Region;
+import sun.java2d.SurfaceData;
+import sun.java2d.loops.GraphicsPrimitive;
+import sun.java2d.pipe.LoopPipe;
+import sun.java2d.pipe.ShapeSpanIterator;
+import sun.java2d.pipe.SpanIterator;
+
+import static sun.java2d.d3d.D3DContext.*;
+import sun.java2d.windows.DDRenderer;
+
+public class D3DRenderer extends DDRenderer {
+
+    native boolean doDrawLineD3D(long pData, long pCtx,
+                                 int x1, int y1, int x2, int y2);
+    native boolean doDrawRectD3D(long pData, long pCtx,
+                                 int x, int y, int w, int h);
+    native boolean doFillRectD3D(long pData, long pCtx, int x, int y,
+                                 int width, int height);
+    native void doDrawPoly(long pData, long pCtx, int transx, int transy,
+                           int[] xpoints, int[] ypoints,
+                           int npoints, boolean isclosed);
+    native void devFillSpans(long pData, long pCtx, SpanIterator si,
+                             long iterator, int transx, int transy);
+
+
+    private long getContext(SunGraphics2D sg2d) {
+        AffineTransform at =
+            sg2d.transformState < sg2d.TRANSFORM_TRANSLATESCALE ?
+            null : sg2d.transform;
+        int ctxflags = (sg2d.eargb >>> 24) == 0xff ?
+            SRC_IS_OPAQUE : NO_CONTEXT_FLAGS;
+        return D3DContext.getContext(null, sg2d.surfaceData,
+                                     sg2d.getCompClip(),
+                                     sg2d.getComposite(),
+                                     at,
+                                     sg2d.eargb,
+                                     ctxflags);
+    }
+
+    @Override
+    public void drawLine(SunGraphics2D sg2d,
+                         int x1, int y1, int x2, int y2)
+    {
+        synchronized (D3DContext.LOCK) {
+            doDrawLineD3D(sg2d.surfaceData.getNativeOps(),
+                          getContext(sg2d),
+                          x1 + sg2d.transX, y1 + sg2d.transY,
+                          x2 + sg2d.transX, y2 + sg2d.transY);
+        }
+    }
+
+    @Override
+    public void fillRect(SunGraphics2D sg2d,
+                         int x, int y, int width, int height)
+    {
+        synchronized (D3DContext.LOCK) {
+            doFillRectD3D(sg2d.surfaceData.getNativeOps(),
+                          getContext(sg2d),
+                          sg2d.transX + x, sg2d.transY + y, width, height);
+        }
+    }
+
+    @Override
+    public void drawRect(SunGraphics2D sg2d,
+                         int x, int y, int width, int height)
+    {
+        synchronized (D3DContext.LOCK) {
+            doDrawRectD3D(sg2d.surfaceData.getNativeOps(),
+                          getContext(sg2d),
+                          x + sg2d.transX, sg2d.transY + y, width, height);
+        }
+    }
+
+    @Override
+    public void drawPolyline(SunGraphics2D sg2d,
+                             int xpoints[], int ypoints[], int npoints)
+    {
+        synchronized (D3DContext.LOCK) {
+            doDrawPoly(sg2d.surfaceData.getNativeOps(),
+                       getContext(sg2d),
+                       sg2d.transX, sg2d.transY,
+                       xpoints, ypoints, npoints, false);
+        }
+    }
+
+    @Override
+    public void drawPolygon(SunGraphics2D sg2d,
+                            int xpoints[], int ypoints[], int npoints)
+    {
+        synchronized (D3DContext.LOCK) {
+            doDrawPoly(sg2d.surfaceData.getNativeOps(),
+                       getContext(sg2d),
+                       sg2d.transX, sg2d.transY,
+                       xpoints, ypoints, npoints, true);
+        }
+    }
+
+    @Override
+    public void drawRoundRect(SunGraphics2D sg2d,
+                              int x, int y, int width, int height,
+                              int arcWidth, int arcHeight)
+    {
+        draw(sg2d, new RoundRectangle2D.Float(x, y, width, height,
+                                              arcWidth, arcHeight));
+    }
+
+    @Override
+    public void drawOval(SunGraphics2D sg2d,
+                         int x, int y, int width, int height)
+    {
+        draw(sg2d, new Ellipse2D.Float(x, y, width, height));
+    }
+
+    @Override
+    public void drawArc(SunGraphics2D sg2d,
+                        int x, int y, int width, int height,
+                        int startAngle, int arcAngle)
+    {
+        draw(sg2d, new Arc2D.Float(x, y, width, height,
+                                   startAngle, arcAngle,
+                                   Arc2D.OPEN));
+    }
+
+    @Override
+    public void fillRoundRect(SunGraphics2D sg2d,
+                              int x, int y, int width, int height,
+                              int arcWidth, int arcHeight)
+    {
+        fill(sg2d, new RoundRectangle2D.Float(x, y, width, height,
+             arcWidth, arcHeight));
+    }
+
+    @Override
+    public void fillOval(SunGraphics2D sg2d,
+                         int x, int y, int width, int height)
+    {
+        fill(sg2d, new Ellipse2D.Float(x, y, width, height));
+    }
+
+    @Override
+    public void fillArc(SunGraphics2D sg2d,
+                        int x, int y, int width, int height,
+                        int startAngle, int arcAngle)
+    {
+        fill(sg2d, new Arc2D.Float(x, y, width, height,
+             startAngle, arcAngle, Arc2D.PIE));
+    }
+
+    @Override
+    public void fillPolygon(SunGraphics2D sg2d,
+                            int xpoints[], int ypoints[],
+                            int npoints)
+    {
+        fill(sg2d, new Polygon(xpoints, ypoints, npoints));
+    }
+
+    @Override
+    public void draw(SunGraphics2D sg2d, Shape s)
+    {
+        if (sg2d.strokeState == sg2d.STROKE_THIN) {
+            Polygon p;
+            if (s instanceof Polygon) {
+                p = (Polygon) s;
+                drawPolygon(sg2d, p.xpoints, p.ypoints, p.npoints);
+                return;
+            }
+            // we're letting d3d handle the transforms
+            PathIterator pi = s.getPathIterator(null, 0.5f);
+            p = new Polygon();
+            float coords[] = new float[2];
+            while (!pi.isDone()) {
+                switch (pi.currentSegment(coords)) {
+                    case PathIterator.SEG_MOVETO:
+                        if (p.npoints > 1) {
+                            drawPolyline(sg2d, p.xpoints, p.ypoints, p.npoints);
+                        }
+                        p.reset();
+                        p.addPoint((int) Math.floor(coords[0]),
+                            (int) Math.floor(coords[1]));
+                        break;
+                    case PathIterator.SEG_LINETO:
+                        if (p.npoints == 0) {
+                            throw new IllegalPathStateException
+                                ("missing initial moveto in path definition");
+                        }
+                        p.addPoint((int) Math.floor(coords[0]),
+                            (int) Math.floor(coords[1]));
+                        break;
+                    case PathIterator.SEG_CLOSE:
+                        if (p.npoints > 0) {
+                            p.addPoint(p.xpoints[0], p.ypoints[0]);
+                        }
+                        break;
+                    default:
+                        throw new
+                            IllegalPathStateException("path not flattened");
+                }
+                pi.next();
+            }
+            if (p.npoints > 1) {
+                drawPolyline(sg2d, p.xpoints, p.ypoints, p.npoints);
+            }
+        } else if (sg2d.strokeState < sg2d.STROKE_CUSTOM) {
+            ShapeSpanIterator si = LoopPipe.getStrokeSpans(sg2d, s);
+            try {
+                synchronized (D3DContext.LOCK) {
+                    int ctxflags = (sg2d.eargb >>> 24) == 0xff ?
+                        SRC_IS_OPAQUE : NO_CONTEXT_FLAGS;
+                    // in this case the spans will be pre-transformed, so we
+                    // pass null transform to getContext
+                    long pCtx = D3DContext.getContext(null, sg2d.surfaceData,
+                                                      sg2d.getCompClip(),
+                                                      sg2d.getComposite(),
+                                                      null /*transform*/,
+                                                      sg2d.eargb/*pixel*/,
+                                                      ctxflags);
+                    devFillSpans(sg2d.surfaceData.getNativeOps(), pCtx, si,
+                                 si.getNativeIterator(), 0, 0);
+                }
+            } finally {
+                si.dispose();
+            }
+        } else {
+            fill(sg2d, sg2d.stroke.createStrokedShape(s));
+        }
+    }
+
+    @Override
+    public void fill(SunGraphics2D sg2d, Shape s) {
+        AffineTransform at;
+        int transx, transy;
+
+        if ( sg2d.transformState < sg2d.TRANSFORM_TRANSLATESCALE) {
+            // Transform (translation) will be done by devFillSpans
+            at = null;
+            transx = sg2d.transX;
+            transy = sg2d.transY;
+        } else {
+            // Transform will be done by the PathIterator
+            at = sg2d.transform;
+            transx = transy = 0;
+        }
+
+        ShapeSpanIterator ssi = LoopPipe.getFillSSI(sg2d);
+        try {
+            // Subtract transx/y from the SSI clip to match the
+            // (potentially untranslated) geometry fed to it
+            Region clip = sg2d.getCompClip();
+            ssi.setOutputAreaXYXY(clip.getLoX() - transx,
+                                  clip.getLoY() - transy,
+                                  clip.getHiX() - transx,
+                                  clip.getHiY() - transy);
+            ssi.appendPath(s.getPathIterator(at));
+            synchronized (D3DContext.LOCK) {
+                int ctxflags = (sg2d.eargb >>> 24) == 0xff ?
+                    SRC_IS_OPAQUE : NO_CONTEXT_FLAGS;
+                long pCtx = D3DContext.getContext(null, sg2d.surfaceData,
+                                                  sg2d.getCompClip(),
+                                                  sg2d.getComposite(),
+                                                  null/*transform*/,
+                                                  sg2d.eargb/*pixel*/,
+                                                  ctxflags);
+                devFillSpans(sg2d.surfaceData.getNativeOps(), pCtx, ssi,
+                             ssi.getNativeIterator(),
+                             transx, transy);
+            }
+        } finally {
+            ssi.dispose();
+        }
+    }
+
+    D3DRenderer traceWrapD3D() {
+        return new Tracer();
+    }
+
+    private class Tracer extends D3DRenderer {
+        @Override
+        public void drawLine(SunGraphics2D sg2d,
+                             int x1, int y1, int x2, int y2)
+        {
+            GraphicsPrimitive.tracePrimitive("D3DDrawLine");
+            super.drawLine(sg2d, x1, y1, x2, y2);
+        }
+        @Override
+        public void drawRect(SunGraphics2D sg2d, int x, int y, int w, int h) {
+            GraphicsPrimitive.tracePrimitive("D3DDrawRect");
+            super.drawRect(sg2d, x, y, w, h);
+        }
+        @Override
+        public void drawPolyline(SunGraphics2D sg2d,
+                                 int[] xPoints, int[] yPoints,
+                                 int nPoints)
+        {
+            GraphicsPrimitive.tracePrimitive("D3DDrawPolyline");
+            super.drawPolyline(sg2d, xPoints, yPoints, nPoints);
+        }
+        @Override
+        public void drawPolygon(SunGraphics2D sg2d,
+                                int[] xPoints, int[] yPoints,
+                                int nPoints)
+        {
+            GraphicsPrimitive.tracePrimitive("D3DDrawPolygon");
+            super.drawPolygon(sg2d, xPoints, yPoints, nPoints);
+        }
+        @Override
+        public void fillRect(SunGraphics2D sg2d, int x, int y, int w, int h) {
+            GraphicsPrimitive.tracePrimitive("D3DFillRect");
+            super.fillRect(sg2d, x, y, w, h);
+        }
+        @Override
+        void devFillSpans(long pData, long pCtx, SpanIterator si, long iterator,
+                          int transx, int transy)
+        {
+            GraphicsPrimitive.tracePrimitive("D3DFillSpans");
+            super.devFillSpans(pData, pCtx, si, iterator, transx, transy);
+        }
+        @Override
+        public void devCopyArea(SurfaceData sData,
+                                int srcx, int srcy,
+                                int dx, int dy,
+                                int w, int h)
+        {
+            GraphicsPrimitive.tracePrimitive("DXCopyArea");
+            super.devCopyArea(sData, srcx, srcy, dx, dy, w, h);
+        }
+
+    }
+}