1 /* 2 * Copyright (c) 1997, 2018, 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 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); 53 private static native void registerNativeLoops(); 54 static native void setTraceFlags(int traceflags); 55 56 static { 57 initIDs(GraphicsPrimitive.class, 58 SurfaceType.class, 59 CompositeType.class, 60 SunGraphics2D.class, 61 java.awt.Color.class, 62 java.awt.geom.AffineTransform.class, 63 XORComposite.class, 64 java.awt.AlphaComposite.class, 65 java.awt.geom.Path2D.class, 66 java.awt.geom.Path2D.Float.class, 67 sun.awt.SunHints.class); 68 CustomComponent.register(); 69 GeneralRenderer.register(); 70 registerNativeLoops(); 71 } 72 73 private static class PrimitiveSpec { 74 public int uniqueID; 75 } 76 77 private static Comparator<GraphicsPrimitive> primSorter = 78 new Comparator<GraphicsPrimitive>() { 79 public int compare(GraphicsPrimitive o1, GraphicsPrimitive o2) { 80 int id1 = o1.getUniqueID(); 81 int id2 = o2.getUniqueID(); 82 83 return (id1 == id2 ? 0 : (id1 < id2 ? -1 : 1)); 84 } 85 }; 86 87 private static Comparator<Object> primFinder = new Comparator<Object>() { 88 public int compare(Object o1, Object o2) { 89 int id1 = ((GraphicsPrimitive) o1).getUniqueID(); 90 int id2 = ((PrimitiveSpec) o2).uniqueID; 91 92 return (id1 == id2 ? 0 : (id1 < id2 ? -1 : 1)); 93 } 94 }; 95 96 /** 97 * Ensure that noone can instantiate this class. 98 */ 99 private GraphicsPrimitiveMgr() { 100 } 101 102 public static synchronized void register(GraphicsPrimitive[] newPrimitives) 103 { 104 GraphicsPrimitive[] devCollection = primitives; 105 int oldSize = 0; 106 int newSize = newPrimitives.length; 107 if (debugTrace) { 108 writeLog("Registering " + newSize + " primitives"); 109 for (int i = 0; i < newSize; i++) { 110 writeLog(newPrimitives[i].toString()); 111 } 112 } 113 if (devCollection != null) { 114 oldSize = devCollection.length; 115 } 116 GraphicsPrimitive[] temp = new GraphicsPrimitive[oldSize + newSize]; 117 if (devCollection != null) { 118 System.arraycopy(devCollection, 0, temp, 0, oldSize); 119 } 120 System.arraycopy(newPrimitives, 0, temp, oldSize, newSize); 121 needssort = true; 122 primitives = temp; 123 } 124 125 public static synchronized void registerGeneral(GraphicsPrimitive gen) { 126 if (generalPrimitives == null) { 127 generalPrimitives = new GraphicsPrimitive[] {gen}; 128 return; 129 } 130 int len = generalPrimitives.length; 131 GraphicsPrimitive[] newGen = new GraphicsPrimitive[len + 1]; 132 System.arraycopy(generalPrimitives, 0, newGen, 0, len); 133 newGen[len] = gen; 134 generalPrimitives = newGen; 135 } 136 137 public static synchronized GraphicsPrimitive locate(int primTypeID, 138 SurfaceType dsttype) 139 { 140 return locate(primTypeID, 141 SurfaceType.OpaqueColor, 142 CompositeType.Src, 143 dsttype); 144 } 145 146 public static synchronized GraphicsPrimitive locate(int primTypeID, 147 SurfaceType srctype, 148 CompositeType comptype, 149 SurfaceType dsttype) 150 { 151 /* 152 System.out.println("Looking for:"); 153 System.out.println(" method: "+signature); 154 System.out.println(" from: "+srctype); 155 System.out.println(" by: "+comptype); 156 System.out.println(" to: "+dsttype); 157 */ 158 GraphicsPrimitive prim = locatePrim(primTypeID, 159 srctype, comptype, dsttype); 160 161 if (prim == null) { 162 //System.out.println("Trying general loop"); 163 prim = locateGeneral(primTypeID); 164 if (prim != null) { 165 prim = prim.makePrimitive(srctype, comptype, dsttype); 166 if (prim != null && GraphicsPrimitive.traceflags != 0) { 167 prim = prim.traceWrap(); 168 } 169 } 170 } 171 return prim; 172 } 173 174 public static synchronized GraphicsPrimitive 175 locatePrim(int primTypeID, 176 SurfaceType srctype, 177 CompositeType comptype, 178 SurfaceType dsttype) 179 { 180 /* 181 System.out.println("Looking for:"); 182 System.out.println(" method: "+signature); 183 System.out.println(" from: "+srctype); 184 System.out.println(" by: "+comptype); 185 System.out.println(" to: "+dsttype); 186 */ 187 SurfaceType src, dst; 188 CompositeType cmp; 189 GraphicsPrimitive prim; 190 PrimitiveSpec spec = new PrimitiveSpec(); 191 192 for (dst = dsttype; dst != null; dst = dst.getSuperType()) { 193 for (src = srctype; src != null; src = src.getSuperType()) { 194 for (cmp = comptype; cmp != null; cmp = cmp.getSuperType()) { 195 /* 196 System.out.println("Trying:"); 197 System.out.println(" method: "+spec.methodSignature); 198 System.out.println(" from: "+spec.sourceType); 199 System.out.println(" by: "+spec.compType); 200 System.out.println(" to: "+spec.destType); 201 */ 202 203 spec.uniqueID = 204 GraphicsPrimitive.makeUniqueID(primTypeID, src, cmp, dst); 205 prim = locate(spec); 206 if (prim != null) { 207 //System.out.println("<GPMgr> Found: " + prim + " in " + i + " steps"); 208 return prim; 209 } 210 } 211 } 212 } 213 return null; 214 } 215 216 private static GraphicsPrimitive locateGeneral(int primTypeID) { 217 if (generalPrimitives == null) { 218 return null; 219 } 220 for (int i = 0; i < generalPrimitives.length; i++) { 221 GraphicsPrimitive prim = generalPrimitives[i]; 222 if (prim.getPrimTypeID() == primTypeID) { 223 return prim; 224 } 225 } 226 return null; 227 //throw new InternalError("No general handler registered for"+signature); 228 } 229 230 private static GraphicsPrimitive locate(PrimitiveSpec spec) { 231 if (needssort) { 232 if (GraphicsPrimitive.traceflags != 0) { 233 for (int i = 0; i < primitives.length; i++) { 234 primitives[i] = primitives[i].traceWrap(); 235 } 236 } 237 Arrays.sort(primitives, primSorter); 238 needssort = false; 239 } 240 GraphicsPrimitive[] devCollection = primitives; 241 if (devCollection == null) { 242 return null; 243 } 244 int index = Arrays.binarySearch(devCollection, spec, primFinder); 245 if (index >= 0) { 246 GraphicsPrimitive prim = devCollection[index]; 247 if (prim instanceof GraphicsPrimitiveProxy) { 248 prim = ((GraphicsPrimitiveProxy) prim).instantiate(); 249 devCollection[index] = prim; 250 if (debugTrace) { 251 writeLog("Instantiated graphics primitive " + prim); 252 } 253 } 254 if (debugTrace) { 255 writeLog("Lookup found[" + index + "]["+ prim + "]"); 256 } 257 return prim; 258 } 259 if (debugTrace) { 260 writeLog("Lookup found nothing for:"); 261 writeLog(" " + spec.uniqueID); 262 } 263 return null; 264 } 265 266 private static void writeLog(String str) { 267 if (debugTrace) { 268 System.err.println(str); 269 } 270 } 271 272 /** 273 * Test that all of the GraphicsPrimitiveProxy objects actually 274 * resolve to something. Throws a RuntimeException if anything 275 * is wrong, an has no effect if all is well. 276 */ 277 // This is only really meant to be called from GraphicsPrimitiveProxyTest 278 // in the regression tests directory, but it has to be here because 279 // it needs access to a private data structure. It is not very 280 // big, though. 281 public static void testPrimitiveInstantiation() { 282 testPrimitiveInstantiation(false); 283 } 284 285 public static void testPrimitiveInstantiation(boolean verbose) { 286 int resolved = 0; 287 int unresolved = 0; 288 GraphicsPrimitive[] prims = primitives; 289 for (int j = 0; j < prims.length; j++) { 290 GraphicsPrimitive p = prims[j]; 291 if (p instanceof GraphicsPrimitiveProxy) { 292 GraphicsPrimitive r = ((GraphicsPrimitiveProxy) p).instantiate(); 293 if (!r.getSignature().equals(p.getSignature()) || 294 r.getUniqueID() != p.getUniqueID()) { 295 System.out.println("r.getSignature == "+r.getSignature()); 296 System.out.println("r.getUniqueID == " + r.getUniqueID()); 297 System.out.println("p.getSignature == "+p.getSignature()); 298 System.out.println("p.getUniqueID == " + p.getUniqueID()); 299 throw new RuntimeException("Primitive " + p 300 + " returns wrong signature for " 301 + r.getClass()); 302 } 303 // instantiate checks that p.satisfiesSameAs(r) 304 unresolved++; 305 p = r; 306 if (verbose) { 307 System.out.println(p); 308 } 309 } else { 310 if (verbose) { 311 System.out.println(p + " (not proxied)."); 312 } 313 resolved++; 314 } 315 } 316 System.out.println(resolved+ 317 " graphics primitives were not proxied."); 318 System.out.println(unresolved+ 319 " proxied graphics primitives resolved correctly."); 320 System.out.println(resolved+unresolved+ 321 " total graphics primitives"); 322 } 323 324 public static void main(String[] argv) { 325 // REMIND: Should trigger loading of platform primitives somehow... 326 if (needssort) { 327 Arrays.sort(primitives, primSorter); 328 needssort = false; 329 } 330 testPrimitiveInstantiation(argv.length > 0); 331 } 332 }