1 /* 2 * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* 27 * @author Charlton Innovations, Inc. 28 */ 29 30 package sun.java2d.loops; 31 32 import java.util.Comparator; 33 import java.util.Arrays; 34 import sun.java2d.SunGraphics2D; 35 36 /** 37 * GraphicsComponentMgr provides services to 38 * 1. register primitives for later use 39 * 2. locate an instance of a primitve based on characteristics 40 */ 41 public final class GraphicsPrimitiveMgr { 42 43 private static final boolean debugTrace = false; 44 private static GraphicsPrimitive primitives[]; 45 private static GraphicsPrimitive generalPrimitives[]; 46 private static boolean needssort = true; 47 initIDs(Class GP, Class ST, Class CT, Class SG2D, Class Color, Class AT, Class XORComp, Class AlphaComp, Class Path2D, Class Path2DFloat, Class SHints)48 private static native void initIDs(Class GP, Class ST, Class CT, 49 Class SG2D, Class Color, Class AT, 50 Class XORComp, Class AlphaComp, 51 Class Path2D, Class Path2DFloat, 52 Class SHints); registerNativeLoops()53 private static native void registerNativeLoops(); 54 55 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)56 initIDs(GraphicsPrimitive.class, 57 SurfaceType.class, 58 CompositeType.class, 59 SunGraphics2D.class, 60 java.awt.Color.class, 61 java.awt.geom.AffineTransform.class, 62 XORComposite.class, 63 java.awt.AlphaComposite.class, 64 java.awt.geom.Path2D.class, 65 java.awt.geom.Path2D.Float.class, 66 sun.awt.SunHints.class); CustomComponent.register()67 CustomComponent.register(); GeneralRenderer.register()68 GeneralRenderer.register(); registerNativeLoops()69 registerNativeLoops(); 70 } 71 72 private static class PrimitiveSpec { 73 public int uniqueID; 74 } 75 76 private static Comparator primSorter = new Comparator() { 77 public int compare(Object o1, Object o2) { 78 int id1 = ((GraphicsPrimitive) o1).getUniqueID(); 79 int id2 = ((GraphicsPrimitive) o2).getUniqueID(); 80 81 return (id1 == id2 ? 0 : (id1 < id2 ? -1 : 1)); 82 } 83 }; 84 85 private static Comparator primFinder = new Comparator() { 86 public int compare(Object o1, Object o2) { 87 int id1 = ((GraphicsPrimitive) o1).getUniqueID(); 88 int id2 = ((PrimitiveSpec) o2).uniqueID; 89 90 return (id1 == id2 ? 0 : (id1 < id2 ? -1 : 1)); 91 } 92 }; 93 94 /** 95 * Ensure that noone can instantiate this class. 96 */ GraphicsPrimitiveMgr()97 private GraphicsPrimitiveMgr() { 98 } 99 register(GraphicsPrimitive[] newPrimitives)100 public synchronized static void register(GraphicsPrimitive[] newPrimitives) 101 { 102 GraphicsPrimitive[] devCollection = primitives; 103 int oldSize = 0; 104 int newSize = newPrimitives.length; 105 if (debugTrace) { 106 writeLog("Registering " + newSize + " primitives"); 107 for (int i = 0; i < newSize; i++) { 108 writeLog(newPrimitives[i].toString()); 109 } 110 } 111 if (devCollection != null) { 112 oldSize = devCollection.length; 113 } 114 GraphicsPrimitive[] temp = new GraphicsPrimitive[oldSize + newSize]; 115 if (devCollection != null) { 116 System.arraycopy(devCollection, 0, temp, 0, oldSize); 117 } 118 System.arraycopy(newPrimitives, 0, temp, oldSize, newSize); 119 needssort = true; 120 primitives = temp; 121 } 122 registerGeneral(GraphicsPrimitive gen)123 public synchronized static void registerGeneral(GraphicsPrimitive gen) { 124 if (generalPrimitives == null) { 125 generalPrimitives = new GraphicsPrimitive[] {gen}; 126 return; 127 } 128 int len = generalPrimitives.length; 129 GraphicsPrimitive[] newGen = new GraphicsPrimitive[len + 1]; 130 System.arraycopy(generalPrimitives, 0, newGen, 0, len); 131 newGen[len] = gen; 132 generalPrimitives = newGen; 133 } 134 locate(int primTypeID, SurfaceType dsttype)135 public synchronized static GraphicsPrimitive locate(int primTypeID, 136 SurfaceType dsttype) 137 { 138 return locate(primTypeID, 139 SurfaceType.OpaqueColor, 140 CompositeType.Src, 141 dsttype); 142 } 143 locate(int primTypeID, SurfaceType srctype, CompositeType comptype, SurfaceType dsttype)144 public synchronized static GraphicsPrimitive locate(int primTypeID, 145 SurfaceType srctype, 146 CompositeType comptype, 147 SurfaceType dsttype) 148 { 149 /* 150 System.out.println("Looking for:"); 151 System.out.println(" method: "+signature); 152 System.out.println(" from: "+srctype); 153 System.out.println(" by: "+comptype); 154 System.out.println(" to: "+dsttype); 155 */ 156 GraphicsPrimitive prim = locatePrim(primTypeID, 157 srctype, comptype, dsttype); 158 159 if (prim == null) { 160 //System.out.println("Trying general loop"); 161 prim = locateGeneral(primTypeID); 162 if (prim != null) { 163 prim = prim.makePrimitive(srctype, comptype, dsttype); 164 if (prim != null && GraphicsPrimitive.traceflags != 0) { 165 prim = prim.traceWrap(); 166 } 167 } 168 } 169 return prim; 170 } 171 172 public synchronized static GraphicsPrimitive locatePrim(int primTypeID, SurfaceType srctype, CompositeType comptype, SurfaceType dsttype)173 locatePrim(int primTypeID, 174 SurfaceType srctype, 175 CompositeType comptype, 176 SurfaceType dsttype) 177 { 178 /* 179 System.out.println("Looking for:"); 180 System.out.println(" method: "+signature); 181 System.out.println(" from: "+srctype); 182 System.out.println(" by: "+comptype); 183 System.out.println(" to: "+dsttype); 184 */ 185 SurfaceType src, dst; 186 CompositeType cmp; 187 GraphicsPrimitive prim; 188 PrimitiveSpec spec = new PrimitiveSpec(); 189 190 for (dst = dsttype; dst != null; dst = dst.getSuperType()) { 191 for (src = srctype; src != null; src = src.getSuperType()) { 192 for (cmp = comptype; cmp != null; cmp = cmp.getSuperType()) { 193 /* 194 System.out.println("Trying:"); 195 System.out.println(" method: "+spec.methodSignature); 196 System.out.println(" from: "+spec.sourceType); 197 System.out.println(" by: "+spec.compType); 198 System.out.println(" to: "+spec.destType); 199 */ 200 201 spec.uniqueID = 202 GraphicsPrimitive.makeUniqueID(primTypeID, src, cmp, dst); 203 prim = locate(spec); 204 if (prim != null) { 205 //System.out.println("<GPMgr> Found: " + prim + " in " + i + " steps"); 206 return prim; 207 } 208 } 209 } 210 } 211 return null; 212 } 213 locateGeneral(int primTypeID)214 private static GraphicsPrimitive locateGeneral(int primTypeID) { 215 if (generalPrimitives == null) { 216 return null; 217 } 218 for (int i = 0; i < generalPrimitives.length; i++) { 219 GraphicsPrimitive prim = generalPrimitives[i]; 220 if (prim.getPrimTypeID() == primTypeID) { 221 return prim; 222 } 223 } 224 return null; 225 //throw new InternalError("No general handler registered for"+signature); 226 } 227 locate(PrimitiveSpec spec)228 private static GraphicsPrimitive locate(PrimitiveSpec spec) { 229 if (needssort) { 230 if (GraphicsPrimitive.traceflags != 0) { 231 for (int i = 0; i < primitives.length; i++) { 232 primitives[i] = primitives[i].traceWrap(); 233 } 234 } 235 Arrays.sort(primitives, primSorter); 236 needssort = false; 237 } 238 GraphicsPrimitive[] devCollection = primitives; 239 if (devCollection == null) { 240 return null; 241 } 242 int index = Arrays.binarySearch(devCollection, spec, primFinder); 243 if (index >= 0) { 244 GraphicsPrimitive prim = devCollection[index]; 245 if (prim instanceof GraphicsPrimitiveProxy) { 246 prim = ((GraphicsPrimitiveProxy) prim).instantiate(); 247 devCollection[index] = prim; 248 if (debugTrace) { 249 writeLog("Instantiated graphics primitive " + prim); 250 } 251 } 252 if (debugTrace) { 253 writeLog("Lookup found[" + index + "]["+ prim + "]"); 254 } 255 return prim; 256 } 257 if (debugTrace) { 258 writeLog("Lookup found nothing for:"); 259 writeLog(" " + spec.uniqueID); 260 } 261 return null; 262 } 263 writeLog(String str)264 private static void writeLog(String str) { 265 if (debugTrace) { 266 System.err.println(str); 267 } 268 } 269 270 /** 271 * Test that all of the GraphicsPrimitiveProxy objects actually 272 * resolve to something. Throws a RuntimeException if anything 273 * is wrong, an has no effect if all is well. 274 */ 275 // This is only really meant to be called from GraphicsPrimitiveProxyTest 276 // in the regression tests directory, but it has to be here because 277 // it needs access to a private data structure. It is not very 278 // big, though. testPrimitiveInstantiation()279 public static void testPrimitiveInstantiation() { 280 testPrimitiveInstantiation(false); 281 } 282 testPrimitiveInstantiation(boolean verbose)283 public static void testPrimitiveInstantiation(boolean verbose) { 284 int resolved = 0; 285 int unresolved = 0; 286 GraphicsPrimitive[] prims = primitives; 287 for (int j = 0; j < prims.length; j++) { 288 GraphicsPrimitive p = prims[j]; 289 if (p instanceof GraphicsPrimitiveProxy) { 290 GraphicsPrimitive r = ((GraphicsPrimitiveProxy) p).instantiate(); 291 if (!r.getSignature().equals(p.getSignature()) || 292 r.getUniqueID() != p.getUniqueID()) { 293 System.out.println("r.getSignature == "+r.getSignature()); 294 System.out.println("r.getUniqueID == " + r.getUniqueID()); 295 System.out.println("p.getSignature == "+p.getSignature()); 296 System.out.println("p.getUniqueID == " + p.getUniqueID()); 297 throw new RuntimeException("Primitive " + p 298 + " returns wrong signature for " 299 + r.getClass()); 300 } 301 // instantiate checks that p.satisfiesSameAs(r) 302 unresolved++; 303 p = r; 304 if (verbose) { 305 System.out.println(p); 306 } 307 } else { 308 if (verbose) { 309 System.out.println(p + " (not proxied)."); 310 } 311 resolved++; 312 } 313 } 314 System.out.println(resolved+ 315 " graphics primitives were not proxied."); 316 System.out.println(unresolved+ 317 " proxied graphics primitives resolved correctly."); 318 System.out.println(resolved+unresolved+ 319 " total graphics primitives"); 320 } 321 main(String argv[])322 public static void main(String argv[]) { 323 // REMIND: Should trigger loading of platform primitives somehow... 324 if (needssort) { 325 Arrays.sort(primitives, primSorter); 326 needssort = false; 327 } 328 testPrimitiveInstantiation(argv.length > 0); 329 } 330 } 331