001: /*
002: * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: /*
027: * @author Charlton Innovations, Inc.
028: */
029:
030: package sun.java2d.loops;
031:
032: import java.util.Comparator;
033: import java.util.Arrays;
034: import sun.java2d.SunGraphics2D;
035:
036: /**
037: * GraphicsComponentMgr provides services to
038: * 1. register primitives for later use
039: * 2. locate an instance of a primitve based on characteristics
040: */
041: public final class GraphicsPrimitiveMgr {
042:
043: private static final boolean debugTrace = false;
044: private static GraphicsPrimitive primitives[];
045: private static GraphicsPrimitive generalPrimitives[];
046: private static boolean needssort = true;
047:
048: private static native void initIDs(Class GP, Class ST, Class CT,
049: Class SG2D, Class Color, Class AT, Class XORComp,
050: Class AlphaComp, Class Path2D, Class Path2DFloat,
051: Class SHints);
052:
053: private static native void registerNativeLoops();
054:
055: static {
056: initIDs(GraphicsPrimitive.class, SurfaceType.class,
057: CompositeType.class, SunGraphics2D.class,
058: java.awt.Color.class,
059: java.awt.geom.AffineTransform.class,
060: XORComposite.class, java.awt.AlphaComposite.class,
061: java.awt.geom.Path2D.class,
062: java.awt.geom.Path2D.Float.class,
063: sun.awt.SunHints.class);
064: CustomComponent.register();
065: GeneralRenderer.register();
066: registerNativeLoops();
067: }
068:
069: private static class PrimitiveSpec {
070: public int uniqueID;
071: }
072:
073: private static Comparator primSorter = new Comparator() {
074: public int compare(Object o1, Object o2) {
075: int id1 = ((GraphicsPrimitive) o1).getUniqueID();
076: int id2 = ((GraphicsPrimitive) o2).getUniqueID();
077:
078: return (id1 == id2 ? 0 : (id1 < id2 ? -1 : 1));
079: }
080: };
081:
082: private static Comparator primFinder = new Comparator() {
083: public int compare(Object o1, Object o2) {
084: int id1 = ((GraphicsPrimitive) o1).getUniqueID();
085: int id2 = ((PrimitiveSpec) o2).uniqueID;
086:
087: return (id1 == id2 ? 0 : (id1 < id2 ? -1 : 1));
088: }
089: };
090:
091: /**
092: * Ensure that noone can instantiate this class.
093: */
094: private GraphicsPrimitiveMgr() {
095: }
096:
097: public synchronized static void register(
098: GraphicsPrimitive[] newPrimitives) {
099: GraphicsPrimitive[] devCollection = primitives;
100: int oldSize = 0;
101: int newSize = newPrimitives.length;
102: if (debugTrace) {
103: writeLog("Registering " + newSize + " primitives");
104: for (int i = 0; i < newSize; i++) {
105: writeLog(newPrimitives[i].toString());
106: }
107: }
108: if (devCollection != null) {
109: oldSize = devCollection.length;
110: }
111: GraphicsPrimitive[] temp = new GraphicsPrimitive[oldSize
112: + newSize];
113: if (devCollection != null) {
114: System.arraycopy(devCollection, 0, temp, 0, oldSize);
115: }
116: System.arraycopy(newPrimitives, 0, temp, oldSize, newSize);
117: needssort = true;
118: primitives = temp;
119: }
120:
121: public synchronized static void registerGeneral(
122: GraphicsPrimitive gen) {
123: if (generalPrimitives == null) {
124: generalPrimitives = new GraphicsPrimitive[] { gen };
125: return;
126: }
127: int len = generalPrimitives.length;
128: GraphicsPrimitive[] newGen = new GraphicsPrimitive[len + 1];
129: System.arraycopy(generalPrimitives, 0, newGen, 0, len);
130: newGen[len] = gen;
131: generalPrimitives = newGen;
132: }
133:
134: public synchronized static GraphicsPrimitive locate(int primTypeID,
135: SurfaceType dsttype) {
136: return locate(primTypeID, SurfaceType.OpaqueColor,
137: CompositeType.Src, dsttype);
138: }
139:
140: public synchronized static GraphicsPrimitive locate(int primTypeID,
141: SurfaceType srctype, CompositeType comptype,
142: SurfaceType dsttype) {
143: /*
144: System.out.println("Looking for:");
145: System.out.println(" method: "+signature);
146: System.out.println(" from: "+srctype);
147: System.out.println(" by: "+comptype);
148: System.out.println(" to: "+dsttype);
149: */
150: GraphicsPrimitive prim = locatePrim(primTypeID, srctype,
151: comptype, dsttype);
152:
153: if (prim == null) {
154: //System.out.println("Trying general loop");
155: prim = locateGeneral(primTypeID);
156: if (prim != null) {
157: prim = prim.makePrimitive(srctype, comptype, dsttype);
158: if (prim != null && GraphicsPrimitive.traceflags != 0) {
159: prim = prim.traceWrap();
160: }
161: }
162: }
163: return prim;
164: }
165:
166: public synchronized static GraphicsPrimitive locatePrim(
167: int primTypeID, SurfaceType srctype,
168: CompositeType comptype, SurfaceType dsttype) {
169: /*
170: System.out.println("Looking for:");
171: System.out.println(" method: "+signature);
172: System.out.println(" from: "+srctype);
173: System.out.println(" by: "+comptype);
174: System.out.println(" to: "+dsttype);
175: */
176: SurfaceType src, dst;
177: CompositeType cmp;
178: GraphicsPrimitive prim;
179: PrimitiveSpec spec = new PrimitiveSpec();
180:
181: for (dst = dsttype; dst != null; dst = dst.getSuperType()) {
182: for (src = srctype; src != null; src = src.getSuperType()) {
183: for (cmp = comptype; cmp != null; cmp = cmp
184: .getSuperType()) {
185: /*
186: System.out.println("Trying:");
187: System.out.println(" method: "+spec.methodSignature);
188: System.out.println(" from: "+spec.sourceType);
189: System.out.println(" by: "+spec.compType);
190: System.out.println(" to: "+spec.destType);
191: */
192:
193: spec.uniqueID = GraphicsPrimitive.makeUniqueID(
194: primTypeID, src, cmp, dst);
195: prim = locate(spec);
196: if (prim != null) {
197: //System.out.println("<GPMgr> Found: " + prim + " in " + i + " steps");
198: return prim;
199: }
200: }
201: }
202: }
203: return null;
204: }
205:
206: private static GraphicsPrimitive locateGeneral(int primTypeID) {
207: if (generalPrimitives == null) {
208: return null;
209: }
210: for (int i = 0; i < generalPrimitives.length; i++) {
211: GraphicsPrimitive prim = generalPrimitives[i];
212: if (prim.getPrimTypeID() == primTypeID) {
213: return prim;
214: }
215: }
216: return null;
217: //throw new InternalError("No general handler registered for"+signature);
218: }
219:
220: private static GraphicsPrimitive locate(PrimitiveSpec spec) {
221: if (needssort) {
222: if (GraphicsPrimitive.traceflags != 0) {
223: for (int i = 0; i < primitives.length; i++) {
224: primitives[i] = primitives[i].traceWrap();
225: }
226: }
227: Arrays.sort(primitives, primSorter);
228: needssort = false;
229: }
230: GraphicsPrimitive[] devCollection = primitives;
231: if (devCollection == null) {
232: return null;
233: }
234: int index = Arrays
235: .binarySearch(devCollection, spec, primFinder);
236: if (index >= 0) {
237: GraphicsPrimitive prim = devCollection[index];
238: if (prim instanceof GraphicsPrimitiveProxy) {
239: prim = ((GraphicsPrimitiveProxy) prim).instantiate();
240: devCollection[index] = prim;
241: if (debugTrace) {
242: writeLog("Instantiated graphics primitive " + prim);
243: }
244: }
245: if (debugTrace) {
246: writeLog("Lookup found[" + index + "][" + prim + "]");
247: }
248: return prim;
249: }
250: if (debugTrace) {
251: writeLog("Lookup found nothing for:");
252: writeLog(" " + spec.uniqueID);
253: }
254: return null;
255: }
256:
257: private static void writeLog(String str) {
258: if (debugTrace) {
259: System.err.println(str);
260: }
261: }
262:
263: /**
264: * Test that all of the GraphicsPrimitiveProxy objects actually
265: * resolve to something. Throws a RuntimeException if anything
266: * is wrong, an has no effect if all is well.
267: */
268: // This is only really meant to be called from GraphicsPrimitiveProxyTest
269: // in the regression tests directory, but it has to be here because
270: // it needs access to a private data structure. It is not very
271: // big, though.
272: public static void testPrimitiveInstantiation() {
273: testPrimitiveInstantiation(false);
274: }
275:
276: public static void testPrimitiveInstantiation(boolean verbose) {
277: int resolved = 0;
278: int unresolved = 0;
279: GraphicsPrimitive[] prims = primitives;
280: for (int j = 0; j < prims.length; j++) {
281: GraphicsPrimitive p = prims[j];
282: if (p instanceof GraphicsPrimitiveProxy) {
283: GraphicsPrimitive r = ((GraphicsPrimitiveProxy) p)
284: .instantiate();
285: if (!r.getSignature().equals(p.getSignature())
286: || r.getUniqueID() != p.getUniqueID()) {
287: System.out.println("r.getSignature == "
288: + r.getSignature());
289: System.out.println("r.getUniqueID == "
290: + r.getUniqueID());
291: System.out.println("p.getSignature == "
292: + p.getSignature());
293: System.out.println("p.getUniqueID == "
294: + p.getUniqueID());
295: throw new RuntimeException("Primitive " + p
296: + " returns wrong signature for "
297: + r.getClass());
298: }
299: // instantiate checks that p.satisfiesSameAs(r)
300: unresolved++;
301: p = r;
302: if (verbose) {
303: System.out.println(p);
304: }
305: } else {
306: if (verbose) {
307: System.out.println(p + " (not proxied).");
308: }
309: resolved++;
310: }
311: }
312: System.out.println(resolved
313: + " graphics primitives were not proxied.");
314: System.out.println(unresolved
315: + " proxied graphics primitives resolved correctly.");
316: System.out.println(resolved + unresolved
317: + " total graphics primitives");
318: }
319:
320: public static void main(String argv[]) {
321: // REMIND: Should trigger loading of platform primitives somehow...
322: if (needssort) {
323: Arrays.sort(primitives, primSorter);
324: needssort = false;
325: }
326: testPrimitiveInstantiation(argv.length > 0);
327: }
328: }
|