| /* |
| * Copyright (c) 1997, 2006, Oracle and/or its affiliates. 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. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| /* |
| * @author Charlton Innovations, Inc. |
| */ |
| |
| package sun.java2d.loops; |
| |
| import java.util.Comparator; |
| import java.util.Arrays; |
| import sun.java2d.SunGraphics2D; |
| |
| /** |
| * GraphicsComponentMgr provides services to |
| * 1. register primitives for later use |
| * 2. locate an instance of a primitve based on characteristics |
| */ |
| public final class GraphicsPrimitiveMgr { |
| |
| private static final boolean debugTrace = false; |
| private static GraphicsPrimitive primitives[]; |
| private static GraphicsPrimitive generalPrimitives[]; |
| private static boolean needssort = true; |
| |
| private static native void initIDs(Class GP, Class ST, Class CT, |
| Class SG2D, Class Color, Class AT, |
| Class XORComp, Class AlphaComp, |
| Class Path2D, Class Path2DFloat, |
| Class SHints); |
| private static native void registerNativeLoops(); |
| |
| static { |
| initIDs(GraphicsPrimitive.class, |
| SurfaceType.class, |
| CompositeType.class, |
| SunGraphics2D.class, |
| java.awt.Color.class, |
| java.awt.geom.AffineTransform.class, |
| XORComposite.class, |
| java.awt.AlphaComposite.class, |
| java.awt.geom.Path2D.class, |
| java.awt.geom.Path2D.Float.class, |
| sun.awt.SunHints.class); |
| CustomComponent.register(); |
| GeneralRenderer.register(); |
| registerNativeLoops(); |
| } |
| |
| private static class PrimitiveSpec { |
| public int uniqueID; |
| } |
| |
| private static Comparator primSorter = new Comparator() { |
| public int compare(Object o1, Object o2) { |
| int id1 = ((GraphicsPrimitive) o1).getUniqueID(); |
| int id2 = ((GraphicsPrimitive) o2).getUniqueID(); |
| |
| return (id1 == id2 ? 0 : (id1 < id2 ? -1 : 1)); |
| } |
| }; |
| |
| private static Comparator primFinder = new Comparator() { |
| public int compare(Object o1, Object o2) { |
| int id1 = ((GraphicsPrimitive) o1).getUniqueID(); |
| int id2 = ((PrimitiveSpec) o2).uniqueID; |
| |
| return (id1 == id2 ? 0 : (id1 < id2 ? -1 : 1)); |
| } |
| }; |
| |
| /** |
| * Ensure that noone can instantiate this class. |
| */ |
| private GraphicsPrimitiveMgr() { |
| } |
| |
| public synchronized static void register(GraphicsPrimitive[] newPrimitives) |
| { |
| GraphicsPrimitive[] devCollection = primitives; |
| int oldSize = 0; |
| int newSize = newPrimitives.length; |
| if (debugTrace) { |
| writeLog("Registering " + newSize + " primitives"); |
| for (int i = 0; i < newSize; i++) { |
| writeLog(newPrimitives[i].toString()); |
| } |
| } |
| if (devCollection != null) { |
| oldSize = devCollection.length; |
| } |
| GraphicsPrimitive[] temp = new GraphicsPrimitive[oldSize + newSize]; |
| if (devCollection != null) { |
| System.arraycopy(devCollection, 0, temp, 0, oldSize); |
| } |
| System.arraycopy(newPrimitives, 0, temp, oldSize, newSize); |
| needssort = true; |
| primitives = temp; |
| } |
| |
| public synchronized static void registerGeneral(GraphicsPrimitive gen) { |
| if (generalPrimitives == null) { |
| generalPrimitives = new GraphicsPrimitive[] {gen}; |
| return; |
| } |
| int len = generalPrimitives.length; |
| GraphicsPrimitive[] newGen = new GraphicsPrimitive[len + 1]; |
| System.arraycopy(generalPrimitives, 0, newGen, 0, len); |
| newGen[len] = gen; |
| generalPrimitives = newGen; |
| } |
| |
| public synchronized static GraphicsPrimitive locate(int primTypeID, |
| SurfaceType dsttype) |
| { |
| return locate(primTypeID, |
| SurfaceType.OpaqueColor, |
| CompositeType.Src, |
| dsttype); |
| } |
| |
| public synchronized static GraphicsPrimitive locate(int primTypeID, |
| SurfaceType srctype, |
| CompositeType comptype, |
| SurfaceType dsttype) |
| { |
| /* |
| System.out.println("Looking for:"); |
| System.out.println(" method: "+signature); |
| System.out.println(" from: "+srctype); |
| System.out.println(" by: "+comptype); |
| System.out.println(" to: "+dsttype); |
| */ |
| GraphicsPrimitive prim = locatePrim(primTypeID, |
| srctype, comptype, dsttype); |
| |
| if (prim == null) { |
| //System.out.println("Trying general loop"); |
| prim = locateGeneral(primTypeID); |
| if (prim != null) { |
| prim = prim.makePrimitive(srctype, comptype, dsttype); |
| if (prim != null && GraphicsPrimitive.traceflags != 0) { |
| prim = prim.traceWrap(); |
| } |
| } |
| } |
| return prim; |
| } |
| |
| public synchronized static GraphicsPrimitive |
| locatePrim(int primTypeID, |
| SurfaceType srctype, |
| CompositeType comptype, |
| SurfaceType dsttype) |
| { |
| /* |
| System.out.println("Looking for:"); |
| System.out.println(" method: "+signature); |
| System.out.println(" from: "+srctype); |
| System.out.println(" by: "+comptype); |
| System.out.println(" to: "+dsttype); |
| */ |
| SurfaceType src, dst; |
| CompositeType cmp; |
| GraphicsPrimitive prim; |
| PrimitiveSpec spec = new PrimitiveSpec(); |
| |
| for (dst = dsttype; dst != null; dst = dst.getSuperType()) { |
| for (src = srctype; src != null; src = src.getSuperType()) { |
| for (cmp = comptype; cmp != null; cmp = cmp.getSuperType()) { |
| /* |
| System.out.println("Trying:"); |
| System.out.println(" method: "+spec.methodSignature); |
| System.out.println(" from: "+spec.sourceType); |
| System.out.println(" by: "+spec.compType); |
| System.out.println(" to: "+spec.destType); |
| */ |
| |
| spec.uniqueID = |
| GraphicsPrimitive.makeUniqueID(primTypeID, src, cmp, dst); |
| prim = locate(spec); |
| if (prim != null) { |
| //System.out.println("<GPMgr> Found: " + prim + " in " + i + " steps"); |
| return prim; |
| } |
| } |
| } |
| } |
| return null; |
| } |
| |
| private static GraphicsPrimitive locateGeneral(int primTypeID) { |
| if (generalPrimitives == null) { |
| return null; |
| } |
| for (int i = 0; i < generalPrimitives.length; i++) { |
| GraphicsPrimitive prim = generalPrimitives[i]; |
| if (prim.getPrimTypeID() == primTypeID) { |
| return prim; |
| } |
| } |
| return null; |
| //throw new InternalError("No general handler registered for"+signature); |
| } |
| |
| private static GraphicsPrimitive locate(PrimitiveSpec spec) { |
| if (needssort) { |
| if (GraphicsPrimitive.traceflags != 0) { |
| for (int i = 0; i < primitives.length; i++) { |
| primitives[i] = primitives[i].traceWrap(); |
| } |
| } |
| Arrays.sort(primitives, primSorter); |
| needssort = false; |
| } |
| GraphicsPrimitive[] devCollection = primitives; |
| if (devCollection == null) { |
| return null; |
| } |
| int index = Arrays.binarySearch(devCollection, spec, primFinder); |
| if (index >= 0) { |
| GraphicsPrimitive prim = devCollection[index]; |
| if (prim instanceof GraphicsPrimitiveProxy) { |
| prim = ((GraphicsPrimitiveProxy) prim).instantiate(); |
| devCollection[index] = prim; |
| if (debugTrace) { |
| writeLog("Instantiated graphics primitive " + prim); |
| } |
| } |
| if (debugTrace) { |
| writeLog("Lookup found[" + index + "]["+ prim + "]"); |
| } |
| return prim; |
| } |
| if (debugTrace) { |
| writeLog("Lookup found nothing for:"); |
| writeLog(" " + spec.uniqueID); |
| } |
| return null; |
| } |
| |
| private static void writeLog(String str) { |
| if (debugTrace) { |
| System.err.println(str); |
| } |
| } |
| |
| /** |
| * Test that all of the GraphicsPrimitiveProxy objects actually |
| * resolve to something. Throws a RuntimeException if anything |
| * is wrong, an has no effect if all is well. |
| */ |
| // This is only really meant to be called from GraphicsPrimitiveProxyTest |
| // in the regression tests directory, but it has to be here because |
| // it needs access to a private data structure. It is not very |
| // big, though. |
| public static void testPrimitiveInstantiation() { |
| testPrimitiveInstantiation(false); |
| } |
| |
| public static void testPrimitiveInstantiation(boolean verbose) { |
| int resolved = 0; |
| int unresolved = 0; |
| GraphicsPrimitive[] prims = primitives; |
| for (int j = 0; j < prims.length; j++) { |
| GraphicsPrimitive p = prims[j]; |
| if (p instanceof GraphicsPrimitiveProxy) { |
| GraphicsPrimitive r = ((GraphicsPrimitiveProxy) p).instantiate(); |
| if (!r.getSignature().equals(p.getSignature()) || |
| r.getUniqueID() != p.getUniqueID()) { |
| System.out.println("r.getSignature == "+r.getSignature()); |
| System.out.println("r.getUniqueID == " + r.getUniqueID()); |
| System.out.println("p.getSignature == "+p.getSignature()); |
| System.out.println("p.getUniqueID == " + p.getUniqueID()); |
| throw new RuntimeException("Primitive " + p |
| + " returns wrong signature for " |
| + r.getClass()); |
| } |
| // instantiate checks that p.satisfiesSameAs(r) |
| unresolved++; |
| p = r; |
| if (verbose) { |
| System.out.println(p); |
| } |
| } else { |
| if (verbose) { |
| System.out.println(p + " (not proxied)."); |
| } |
| resolved++; |
| } |
| } |
| System.out.println(resolved+ |
| " graphics primitives were not proxied."); |
| System.out.println(unresolved+ |
| " proxied graphics primitives resolved correctly."); |
| System.out.println(resolved+unresolved+ |
| " total graphics primitives"); |
| } |
| |
| public static void main(String argv[]) { |
| // REMIND: Should trigger loading of platform primitives somehow... |
| if (needssort) { |
| Arrays.sort(primitives, primSorter); |
| needssort = false; |
| } |
| testPrimitiveInstantiation(argv.length > 0); |
| } |
| } |