0N/A/*
3261N/A * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/A/*
0N/A * @author Charlton Innovations, Inc.
0N/A */
0N/A
0N/Apackage sun.java2d.loops;
0N/A
0N/Aimport java.awt.image.BufferedImage;
0N/Aimport java.awt.AlphaComposite;
0N/Aimport java.awt.Rectangle;
0N/Aimport sun.awt.image.BufImgSurfaceData;
0N/Aimport sun.java2d.SurfaceData;
0N/Aimport sun.java2d.pipe.Region;
0N/Aimport java.lang.reflect.Field;
0N/Aimport java.util.StringTokenizer;
0N/Aimport java.util.Iterator;
0N/Aimport java.util.HashMap;
0N/Aimport java.util.Map;
0N/Aimport java.io.PrintStream;
0N/Aimport java.io.OutputStream;
0N/Aimport java.io.FileOutputStream;
0N/Aimport java.io.FileNotFoundException;
0N/Aimport java.security.AccessController;
0N/Aimport java.security.PrivilegedAction;
0N/Aimport sun.security.action.GetPropertyAction;
0N/A
0N/A/**
0N/A * defines interface for primitives which can be placed into
0N/A * the graphic component manager framework
0N/A */
0N/Apublic abstract class GraphicsPrimitive {
0N/A
0N/A protected static interface GeneralBinaryOp {
0N/A /**
0N/A * This method allows the setupGeneralBinaryOp method to set
0N/A * the converters into the General version of the Primitive.
0N/A */
0N/A public void setPrimitives(Blit srcconverter,
0N/A Blit dstconverter,
0N/A GraphicsPrimitive genericop,
0N/A Blit resconverter);
0N/A
0N/A /**
0N/A * These 4 methods are implemented automatically for any
0N/A * GraphicsPrimitive. They are used by setupGeneralBinaryOp
0N/A * to retrieve the information needed to find the right
0N/A * converter primitives.
0N/A */
0N/A public SurfaceType getSourceType();
0N/A public CompositeType getCompositeType();
0N/A public SurfaceType getDestType();
0N/A public String getSignature();
0N/A public int getPrimTypeID();
0N/A }
0N/A
0N/A protected static interface GeneralUnaryOp {
0N/A /**
0N/A * This method allows the setupGeneralUnaryOp method to set
0N/A * the converters into the General version of the Primitive.
0N/A */
0N/A public void setPrimitives(Blit dstconverter,
0N/A GraphicsPrimitive genericop,
0N/A Blit resconverter);
0N/A
0N/A /**
0N/A * These 3 methods are implemented automatically for any
0N/A * GraphicsPrimitive. They are used by setupGeneralUnaryOp
0N/A * to retrieve the information needed to find the right
0N/A * converter primitives.
0N/A */
0N/A public CompositeType getCompositeType();
0N/A public SurfaceType getDestType();
0N/A public String getSignature();
0N/A public int getPrimTypeID();
0N/A }
0N/A
0N/A /**
0N/A * INSTANCE DATA MEMBERS DESCRIBING CHARACTERISTICS OF THIS PRIMITIVE
0N/A **/
0N/A
0N/A // Making these be instance data members (instead of virtual methods
0N/A // overridden by subclasses) is actually cheaper, since each class
0N/A // is a singleton. As instance data members with final accessors,
0N/A // accesses can be inlined.
0N/A private String methodSignature;
0N/A private int uniqueID;
0N/A private static int unusedPrimID = 1;
0N/A
0N/A private SurfaceType sourceType;
0N/A private CompositeType compositeType;
0N/A private SurfaceType destType;
0N/A
0N/A private long pNativePrim; // Native blit loop info
0N/A
0N/A public synchronized static final int makePrimTypeID() {
0N/A if (unusedPrimID > 255) {
0N/A throw new InternalError("primitive id overflow");
0N/A }
0N/A return unusedPrimID++;
0N/A }
0N/A
0N/A public synchronized static final int makeUniqueID(int primTypeID,
0N/A SurfaceType src,
0N/A CompositeType cmp,
0N/A SurfaceType dst)
0N/A {
0N/A return (primTypeID << 24) |
0N/A (dst.getUniqueID() << 16) |
0N/A (cmp.getUniqueID() << 8) |
0N/A (src.getUniqueID());
0N/A }
0N/A
0N/A /**
0N/A * Create a new GraphicsPrimitive with all of the required
0N/A * descriptive information.
0N/A */
0N/A protected GraphicsPrimitive(String methodSignature,
0N/A int primTypeID,
0N/A SurfaceType sourceType,
0N/A CompositeType compositeType,
0N/A SurfaceType destType)
0N/A {
0N/A this.methodSignature = methodSignature;
0N/A this.sourceType = sourceType;
0N/A this.compositeType = compositeType;
0N/A this.destType = destType;
0N/A
0N/A if(sourceType == null || compositeType == null || destType == null) {
0N/A this.uniqueID = primTypeID << 24;
0N/A } else {
0N/A this.uniqueID = GraphicsPrimitive.makeUniqueID(primTypeID,
0N/A sourceType,
0N/A compositeType,
0N/A destType);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Create a new GraphicsPrimitive for native invocation
0N/A * with all of the required descriptive information.
0N/A */
0N/A protected GraphicsPrimitive(long pNativePrim,
0N/A String methodSignature,
0N/A int primTypeID,
0N/A SurfaceType sourceType,
0N/A CompositeType compositeType,
0N/A SurfaceType destType)
0N/A {
0N/A this.pNativePrim = pNativePrim;
0N/A this.methodSignature = methodSignature;
0N/A this.sourceType = sourceType;
0N/A this.compositeType = compositeType;
0N/A this.destType = destType;
0N/A
0N/A if(sourceType == null || compositeType == null || destType == null) {
0N/A this.uniqueID = primTypeID << 24;
0N/A } else {
0N/A this.uniqueID = GraphicsPrimitive.makeUniqueID(primTypeID,
0N/A sourceType,
0N/A compositeType,
0N/A destType);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * METHODS TO DESCRIBE THE SURFACES PRIMITIVES
0N/A * CAN OPERATE ON AND THE FUNCTIONALITY THEY IMPLEMENT
0N/A **/
0N/A
0N/A /**
0N/A * Gets instance ID of this graphics primitive.
0N/A *
0N/A * Instance ID is comprised of four distinct ids (ORed together)
0N/A * that uniquely identify each instance of a GraphicsPrimitive
0N/A * object. The four ids making up instance ID are:
0N/A * 1. primitive id - identifier shared by all primitives of the
0N/A * same type (eg. all Blits have the same primitive id)
0N/A * 2. sourcetype id - identifies source surface type
0N/A * 3. desttype id - identifies destination surface type
0N/A * 4. compositetype id - identifies composite used
0N/A *
0N/A * @return instance ID
0N/A */
0N/A public final int getUniqueID() {
0N/A return uniqueID;
0N/A }
0N/A
0N/A /**
0N/A */
0N/A public final String getSignature() {
0N/A return methodSignature;
0N/A }
0N/A
0N/A /**
0N/A * Gets unique id for this GraphicsPrimitive type.
0N/A *
0N/A * This id is used to identify the TYPE of primitive (Blit vs. BlitBg)
0N/A * as opposed to INSTANCE of primitive.
0N/A *
0N/A * @return primitive ID
0N/A */
0N/A public final int getPrimTypeID() {
0N/A return uniqueID >>> 24;
0N/A }
0N/A
0N/A /**
0N/A */
0N/A public final long getNativePrim() {
0N/A return pNativePrim;
0N/A }
0N/A
0N/A /**
0N/A */
0N/A public final SurfaceType getSourceType() {
0N/A return sourceType;
0N/A }
0N/A
0N/A /**
0N/A */
0N/A public final CompositeType getCompositeType() {
0N/A return compositeType;
0N/A }
0N/A
0N/A /**
0N/A */
0N/A public final SurfaceType getDestType() {
0N/A return destType;
0N/A }
0N/A
0N/A /**
0N/A * Return true if this primitive can be used for the given signature
0N/A * surfaces, and composite.
0N/A *
0N/A * @param signature The signature of the given operation. Must be
0N/A * == (not just .equals) the signature string given by the
0N/A * abstract class that declares the operation.
0N/A * @param srctype The surface type for the source of the operation
0N/A * @param comptype The composite type for the operation
0N/A * @param dsttype The surface type for the destination of the operation
0N/A */
0N/A public final boolean satisfies(String signature,
0N/A SurfaceType srctype,
0N/A CompositeType comptype,
0N/A SurfaceType dsttype)
0N/A {
0N/A if (signature != methodSignature) {
0N/A return false;
0N/A }
0N/A while (true) {
0N/A if (srctype == null) {
0N/A return false;
0N/A }
0N/A if (srctype.equals(sourceType)) {
0N/A break;
0N/A }
0N/A srctype = srctype.getSuperType();
0N/A }
0N/A while (true) {
0N/A if (comptype == null) {
0N/A return false;
0N/A }
0N/A if (comptype.equals(compositeType)) {
0N/A break;
0N/A }
0N/A comptype = comptype.getSuperType();
0N/A }
0N/A while (true) {
0N/A if (dsttype == null) {
0N/A return false;
0N/A }
0N/A if (dsttype.equals(destType)) {
0N/A break;
0N/A }
0N/A dsttype = dsttype.getSuperType();
0N/A }
0N/A return true;
0N/A }
0N/A
0N/A //
0N/A // A version of satisfies used for regression testing
0N/A //
0N/A final boolean satisfiesSameAs(GraphicsPrimitive other) {
0N/A return (methodSignature == other.methodSignature &&
0N/A sourceType.equals(other.sourceType) &&
0N/A compositeType.equals(other.compositeType) &&
0N/A destType.equals(other.destType));
0N/A }
0N/A
0N/A public abstract GraphicsPrimitive makePrimitive(SurfaceType srctype,
0N/A CompositeType comptype,
0N/A SurfaceType dsttype);
0N/A
0N/A public abstract GraphicsPrimitive traceWrap();
0N/A
0N/A static HashMap traceMap;
0N/A
0N/A public static int traceflags;
0N/A public static String tracefile;
0N/A public static PrintStream traceout;
0N/A
0N/A public static final int TRACELOG = 1;
0N/A public static final int TRACETIMESTAMP = 2;
0N/A public static final int TRACECOUNTS = 4;
0N/A
0N/A static {
0N/A GetPropertyAction gpa = new GetPropertyAction("sun.java2d.trace");
0N/A String trace = (String)AccessController.doPrivileged(gpa);
0N/A if (trace != null) {
0N/A boolean verbose = false;
0N/A int traceflags = 0;
0N/A StringTokenizer st = new StringTokenizer(trace, ",");
0N/A while (st.hasMoreTokens()) {
0N/A String tok = st.nextToken();
0N/A if (tok.equalsIgnoreCase("count")) {
0N/A traceflags |= GraphicsPrimitive.TRACECOUNTS;
0N/A } else if (tok.equalsIgnoreCase("log")) {
0N/A traceflags |= GraphicsPrimitive.TRACELOG;
0N/A } else if (tok.equalsIgnoreCase("timestamp")) {
0N/A traceflags |= GraphicsPrimitive.TRACETIMESTAMP;
0N/A } else if (tok.equalsIgnoreCase("verbose")) {
0N/A verbose = true;
0N/A } else if (tok.regionMatches(true, 0, "out:", 0, 4)) {
0N/A tracefile = tok.substring(4);
0N/A } else {
0N/A if (!tok.equalsIgnoreCase("help")) {
0N/A System.err.println("unrecognized token: "+tok);
0N/A }
0N/A System.err.println("usage: -Dsun.java2d.trace="+
0N/A "[log[,timestamp]],[count],"+
0N/A "[out:<filename>],[help],[verbose]");
0N/A }
0N/A }
0N/A if (verbose) {
0N/A System.err.print("GraphicsPrimitive logging ");
0N/A if ((traceflags & GraphicsPrimitive.TRACELOG) != 0) {
0N/A System.err.println("enabled");
0N/A System.err.print("GraphicsPrimitive timetamps ");
0N/A if ((traceflags & GraphicsPrimitive.TRACETIMESTAMP) != 0) {
0N/A System.err.println("enabled");
0N/A } else {
0N/A System.err.println("disabled");
0N/A }
0N/A } else {
0N/A System.err.println("[and timestamps] disabled");
0N/A }
0N/A System.err.print("GraphicsPrimitive invocation counts ");
0N/A if ((traceflags & GraphicsPrimitive.TRACECOUNTS) != 0) {
0N/A System.err.println("enabled");
0N/A } else {
0N/A System.err.println("disabled");
0N/A }
0N/A System.err.print("GraphicsPrimitive trace output to ");
0N/A if (tracefile == null) {
0N/A System.err.println("System.err");
0N/A } else {
0N/A System.err.println("file '"+tracefile+"'");
0N/A }
0N/A }
0N/A GraphicsPrimitive.traceflags = traceflags;
0N/A }
0N/A }
0N/A
0N/A public static boolean tracingEnabled() {
0N/A return (traceflags != 0);
0N/A }
0N/A
0N/A private static PrintStream getTraceOutputFile() {
0N/A if (traceout == null) {
0N/A if (tracefile != null) {
0N/A Object o =
0N/A AccessController.doPrivileged(new PrivilegedAction() {
0N/A public Object run() {
0N/A try {
0N/A return new FileOutputStream(tracefile);
0N/A } catch (FileNotFoundException e) {
0N/A return null;
0N/A }
0N/A }
0N/A });
0N/A if (o != null) {
0N/A traceout = new PrintStream((OutputStream) o);
0N/A } else {
0N/A traceout = System.err;
0N/A }
0N/A } else {
0N/A traceout = System.err;
0N/A }
0N/A }
0N/A return traceout;
0N/A }
0N/A
0N/A public static class TraceReporter extends Thread {
0N/A public static void setShutdownHook() {
0N/A AccessController.doPrivileged(new PrivilegedAction() {
0N/A public Object run() {
2285N/A TraceReporter t = new TraceReporter();
2285N/A t.setContextClassLoader(null);
2285N/A Runtime.getRuntime().addShutdownHook(t);
0N/A return null;
0N/A }
0N/A });
0N/A }
0N/A
0N/A public void run() {
0N/A PrintStream ps = getTraceOutputFile();
0N/A Iterator iterator = traceMap.entrySet().iterator();
0N/A long total = 0;
0N/A int numprims = 0;
0N/A while (iterator.hasNext()) {
0N/A Map.Entry me = (Map.Entry) iterator.next();
0N/A Object prim = me.getKey();
0N/A int[] count = (int[]) me.getValue();
0N/A if (count[0] == 1) {
0N/A ps.print("1 call to ");
0N/A } else {
0N/A ps.print(count[0]+" calls to ");
0N/A }
0N/A ps.println(prim);
0N/A numprims++;
0N/A total += count[0];
0N/A }
0N/A if (numprims == 0) {
0N/A ps.println("No graphics primitives executed");
0N/A } else if (numprims > 1) {
0N/A ps.println(total+" total calls to "+
0N/A numprims+" different primitives");
0N/A }
0N/A }
0N/A }
0N/A
0N/A public synchronized static void tracePrimitive(Object prim) {
0N/A if ((traceflags & TRACECOUNTS) != 0) {
0N/A if (traceMap == null) {
0N/A traceMap = new HashMap();
0N/A TraceReporter.setShutdownHook();
0N/A }
0N/A Object o = traceMap.get(prim);
0N/A if (o == null) {
0N/A o = new int[1];
0N/A traceMap.put(prim, o);
0N/A }
0N/A ((int[]) o)[0]++;
0N/A }
0N/A if ((traceflags & TRACELOG) != 0) {
0N/A PrintStream ps = getTraceOutputFile();
0N/A if ((traceflags & TRACETIMESTAMP) != 0) {
0N/A ps.print(System.currentTimeMillis()+": ");
0N/A }
0N/A ps.println(prim);
0N/A }
0N/A }
0N/A
0N/A protected void setupGeneralBinaryOp(GeneralBinaryOp gbo) {
0N/A int primID = gbo.getPrimTypeID();
0N/A String methodSignature = gbo.getSignature();
0N/A SurfaceType srctype = gbo.getSourceType();
0N/A CompositeType comptype = gbo.getCompositeType();
0N/A SurfaceType dsttype = gbo.getDestType();
0N/A Blit convertsrc, convertdst, convertres;
0N/A GraphicsPrimitive performop;
0N/A
0N/A convertsrc = createConverter(srctype, SurfaceType.IntArgb);
0N/A performop = GraphicsPrimitiveMgr.locatePrim(primID,
0N/A SurfaceType.IntArgb,
0N/A comptype, dsttype);
0N/A if (performop != null) {
0N/A convertdst = null;
0N/A convertres = null;
0N/A } else {
0N/A performop = getGeneralOp(primID, comptype);
0N/A if (performop == null) {
0N/A throw new InternalError("Cannot construct general op for "+
0N/A methodSignature+" "+comptype);
0N/A }
0N/A convertdst = createConverter(dsttype, SurfaceType.IntArgb);
0N/A convertres = createConverter(SurfaceType.IntArgb, dsttype);
0N/A }
0N/A
0N/A gbo.setPrimitives(convertsrc, convertdst, performop, convertres);
0N/A }
0N/A
0N/A protected void setupGeneralUnaryOp(GeneralUnaryOp guo) {
0N/A int primID = guo.getPrimTypeID();
0N/A String methodSignature = guo.getSignature();
0N/A CompositeType comptype = guo.getCompositeType();
0N/A SurfaceType dsttype = guo.getDestType();
0N/A
0N/A Blit convertdst = createConverter(dsttype, SurfaceType.IntArgb);
0N/A GraphicsPrimitive performop = getGeneralOp(primID, comptype);
0N/A Blit convertres = createConverter(SurfaceType.IntArgb, dsttype);
0N/A if (convertdst == null || performop == null || convertres == null) {
0N/A throw new InternalError("Cannot construct binary op for "+
0N/A comptype+" "+dsttype);
0N/A }
0N/A
0N/A guo.setPrimitives(convertdst, performop, convertres);
0N/A }
0N/A
0N/A protected static Blit createConverter(SurfaceType srctype,
0N/A SurfaceType dsttype)
0N/A {
0N/A if (srctype.equals(dsttype)) {
0N/A return null;
0N/A }
0N/A Blit cv = Blit.getFromCache(srctype, CompositeType.SrcNoEa, dsttype);
0N/A if (cv == null) {
0N/A throw new InternalError("Cannot construct converter for "+
0N/A srctype+"=>"+dsttype);
0N/A }
0N/A return cv;
0N/A }
0N/A
0N/A protected static SurfaceData convertFrom(Blit ob, SurfaceData srcData,
0N/A int srcX, int srcY, int w, int h,
0N/A SurfaceData dstData)
0N/A {
0N/A return convertFrom(ob, srcData,
0N/A srcX, srcY, w, h, dstData,
0N/A BufferedImage.TYPE_INT_ARGB);
0N/A }
0N/A
0N/A protected static SurfaceData convertFrom(Blit ob, SurfaceData srcData,
0N/A int srcX, int srcY, int w, int h,
0N/A SurfaceData dstData, int type)
0N/A {
0N/A if (dstData != null) {
0N/A Rectangle r = dstData.getBounds();
0N/A if (w > r.width || h > r.height) {
0N/A dstData = null;
0N/A }
0N/A }
0N/A if (dstData == null) {
0N/A BufferedImage dstBI = new BufferedImage(w, h, type);
0N/A dstData = BufImgSurfaceData.createData(dstBI);
0N/A }
0N/A ob.Blit(srcData, dstData, AlphaComposite.Src, null,
0N/A srcX, srcY, 0, 0, w, h);
0N/A return dstData;
0N/A }
0N/A
0N/A protected static void convertTo(Blit ob,
0N/A SurfaceData srcImg, SurfaceData dstImg,
0N/A Region clip,
0N/A int dstX, int dstY, int w, int h)
0N/A {
0N/A if (ob != null) {
0N/A ob.Blit(srcImg, dstImg, AlphaComposite.Src, clip,
0N/A 0, 0, dstX, dstY, w, h);
0N/A }
0N/A }
0N/A
0N/A protected static GraphicsPrimitive getGeneralOp(int primID,
0N/A CompositeType comptype)
0N/A {
0N/A return GraphicsPrimitiveMgr.locatePrim(primID,
0N/A SurfaceType.IntArgb,
0N/A comptype,
0N/A SurfaceType.IntArgb);
0N/A }
0N/A
0N/A public static String simplename(Field[] fields, Object o) {
0N/A for (int i = 0; i < fields.length; i++) {
0N/A Field f = fields[i];
0N/A try {
0N/A if (o == f.get(null)) {
0N/A return f.getName();
0N/A }
0N/A } catch (Exception e) {
0N/A }
0N/A }
0N/A return "\""+o.toString()+"\"";
0N/A }
0N/A
0N/A public static String simplename(SurfaceType st) {
0N/A return simplename(SurfaceType.class.getDeclaredFields(), st);
0N/A }
0N/A
0N/A public static String simplename(CompositeType ct) {
0N/A return simplename(CompositeType.class.getDeclaredFields(), ct);
0N/A }
0N/A
0N/A private String cachedname;
0N/A
0N/A public String toString() {
0N/A if (cachedname == null) {
0N/A String sig = methodSignature;
0N/A int index = sig.indexOf('(');
0N/A if (index >= 0) {
0N/A sig = sig.substring(0, index);
0N/A }
0N/A cachedname = (getClass().getName()+"::"+
0N/A sig+"("+
0N/A simplename(sourceType)+", "+
0N/A simplename(compositeType)+", "+
0N/A simplename(destType)+")");
0N/A }
0N/A return cachedname;
0N/A }
0N/A}