jdk/src/share/classes/sun/java2d/loops/GraphicsPrimitive.java
changeset 2 90ce3da70b43
child 5275 fa9f5ce2006e
equal deleted inserted replaced
0:fd16c54261b3 2:90ce3da70b43
       
     1 /*
       
     2  * Copyright 1997-2005 Sun Microsystems, Inc.  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.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any questions.
       
    24  */
       
    25 
       
    26 /*
       
    27  * @author Charlton Innovations, Inc.
       
    28  */
       
    29 
       
    30 package sun.java2d.loops;
       
    31 
       
    32 import java.awt.image.BufferedImage;
       
    33 import java.awt.AlphaComposite;
       
    34 import java.awt.Rectangle;
       
    35 import sun.awt.image.BufImgSurfaceData;
       
    36 import sun.java2d.SurfaceData;
       
    37 import sun.java2d.pipe.Region;
       
    38 import java.lang.reflect.Field;
       
    39 import java.util.StringTokenizer;
       
    40 import java.util.Iterator;
       
    41 import java.util.HashMap;
       
    42 import java.util.Map;
       
    43 import java.io.PrintStream;
       
    44 import java.io.OutputStream;
       
    45 import java.io.FileOutputStream;
       
    46 import java.io.FileNotFoundException;
       
    47 import java.security.AccessController;
       
    48 import java.security.PrivilegedAction;
       
    49 import sun.security.action.GetPropertyAction;
       
    50 
       
    51 /**
       
    52  * defines interface for primitives which can be placed into
       
    53  * the graphic component manager framework
       
    54  */
       
    55 public abstract class GraphicsPrimitive {
       
    56 
       
    57     protected static interface GeneralBinaryOp {
       
    58         /**
       
    59          * This method allows the setupGeneralBinaryOp method to set
       
    60          * the converters into the General version of the Primitive.
       
    61          */
       
    62         public void setPrimitives(Blit srcconverter,
       
    63                                   Blit dstconverter,
       
    64                                   GraphicsPrimitive genericop,
       
    65                                   Blit resconverter);
       
    66 
       
    67         /**
       
    68          * These 4 methods are implemented automatically for any
       
    69          * GraphicsPrimitive.  They are used by setupGeneralBinaryOp
       
    70          * to retrieve the information needed to find the right
       
    71          * converter primitives.
       
    72          */
       
    73         public SurfaceType getSourceType();
       
    74         public CompositeType getCompositeType();
       
    75         public SurfaceType getDestType();
       
    76         public String getSignature();
       
    77         public int getPrimTypeID();
       
    78     }
       
    79 
       
    80     protected static interface GeneralUnaryOp {
       
    81         /**
       
    82          * This method allows the setupGeneralUnaryOp method to set
       
    83          * the converters into the General version of the Primitive.
       
    84          */
       
    85         public void setPrimitives(Blit dstconverter,
       
    86                                   GraphicsPrimitive genericop,
       
    87                                   Blit resconverter);
       
    88 
       
    89         /**
       
    90          * These 3 methods are implemented automatically for any
       
    91          * GraphicsPrimitive.  They are used by setupGeneralUnaryOp
       
    92          * to retrieve the information needed to find the right
       
    93          * converter primitives.
       
    94          */
       
    95         public CompositeType getCompositeType();
       
    96         public SurfaceType getDestType();
       
    97         public String getSignature();
       
    98         public int getPrimTypeID();
       
    99     }
       
   100 
       
   101     /**
       
   102     *  INSTANCE DATA MEMBERS DESCRIBING CHARACTERISTICS OF THIS PRIMITIVE
       
   103     **/
       
   104 
       
   105     // Making these be instance data members (instead of virtual methods
       
   106     // overridden by subclasses) is actually cheaper, since each class
       
   107     // is a singleton.  As instance data members with final accessors,
       
   108     // accesses can be inlined.
       
   109     private String methodSignature;
       
   110     private int uniqueID;
       
   111     private static int unusedPrimID = 1;
       
   112 
       
   113     private SurfaceType sourceType;
       
   114     private CompositeType compositeType;
       
   115     private SurfaceType destType;
       
   116 
       
   117     private long pNativePrim;   // Native blit loop info
       
   118 
       
   119     public synchronized static final int makePrimTypeID() {
       
   120         if (unusedPrimID > 255) {
       
   121             throw new InternalError("primitive id overflow");
       
   122         }
       
   123         return unusedPrimID++;
       
   124     }
       
   125 
       
   126     public synchronized static final int makeUniqueID(int primTypeID,
       
   127                                                       SurfaceType src,
       
   128                                                       CompositeType cmp,
       
   129                                                       SurfaceType dst)
       
   130     {
       
   131         return (primTypeID << 24) |
       
   132             (dst.getUniqueID() << 16) |
       
   133             (cmp.getUniqueID() << 8)  |
       
   134             (src.getUniqueID());
       
   135     }
       
   136 
       
   137     /**
       
   138      * Create a new GraphicsPrimitive with all of the required
       
   139      * descriptive information.
       
   140      */
       
   141     protected GraphicsPrimitive(String methodSignature,
       
   142                                 int primTypeID,
       
   143                                 SurfaceType sourceType,
       
   144                                 CompositeType compositeType,
       
   145                                 SurfaceType destType)
       
   146     {
       
   147         this.methodSignature = methodSignature;
       
   148         this.sourceType = sourceType;
       
   149         this.compositeType = compositeType;
       
   150         this.destType = destType;
       
   151 
       
   152         if(sourceType == null || compositeType == null || destType == null) {
       
   153             this.uniqueID = primTypeID << 24;
       
   154         } else {
       
   155             this.uniqueID = GraphicsPrimitive.makeUniqueID(primTypeID,
       
   156                                                            sourceType,
       
   157                                                            compositeType,
       
   158                                                            destType);
       
   159         }
       
   160     }
       
   161 
       
   162     /**
       
   163      * Create a new GraphicsPrimitive for native invocation
       
   164      * with all of the required descriptive information.
       
   165      */
       
   166     protected GraphicsPrimitive(long pNativePrim,
       
   167                                 String methodSignature,
       
   168                                 int primTypeID,
       
   169                                 SurfaceType sourceType,
       
   170                                 CompositeType compositeType,
       
   171                                 SurfaceType destType)
       
   172     {
       
   173         this.pNativePrim = pNativePrim;
       
   174         this.methodSignature = methodSignature;
       
   175         this.sourceType = sourceType;
       
   176         this.compositeType = compositeType;
       
   177         this.destType = destType;
       
   178 
       
   179         if(sourceType == null || compositeType == null || destType == null) {
       
   180             this.uniqueID = primTypeID << 24;
       
   181         } else {
       
   182             this.uniqueID = GraphicsPrimitive.makeUniqueID(primTypeID,
       
   183                                                            sourceType,
       
   184                                                            compositeType,
       
   185                                                            destType);
       
   186         }
       
   187     }
       
   188 
       
   189     /**
       
   190     *   METHODS TO DESCRIBE THE SURFACES PRIMITIVES
       
   191     *   CAN OPERATE ON AND THE FUNCTIONALITY THEY IMPLEMENT
       
   192     **/
       
   193 
       
   194     /**
       
   195      * Gets instance ID of this graphics primitive.
       
   196      *
       
   197      * Instance ID is comprised of four distinct ids (ORed together)
       
   198      * that uniquely identify each instance of a GraphicsPrimitive
       
   199      * object. The four ids making up instance ID are:
       
   200      * 1. primitive id - identifier shared by all primitives of the
       
   201      * same type (eg. all Blits have the same primitive id)
       
   202      * 2. sourcetype id - identifies source surface type
       
   203      * 3. desttype id - identifies destination surface type
       
   204      * 4. compositetype id - identifies composite used
       
   205      *
       
   206      * @return instance ID
       
   207      */
       
   208     public final int getUniqueID() {
       
   209         return uniqueID;
       
   210     }
       
   211 
       
   212     /**
       
   213      */
       
   214     public final String getSignature() {
       
   215         return methodSignature;
       
   216     }
       
   217 
       
   218     /**
       
   219      * Gets unique id for this GraphicsPrimitive type.
       
   220      *
       
   221      * This id is used to identify the TYPE of primitive (Blit vs. BlitBg)
       
   222      * as opposed to INSTANCE of primitive.
       
   223      *
       
   224      * @return primitive ID
       
   225      */
       
   226     public final int getPrimTypeID() {
       
   227         return uniqueID >>> 24;
       
   228     }
       
   229 
       
   230     /**
       
   231      */
       
   232     public final long getNativePrim() {
       
   233         return pNativePrim;
       
   234     }
       
   235 
       
   236     /**
       
   237      */
       
   238     public final SurfaceType getSourceType() {
       
   239         return sourceType;
       
   240     }
       
   241 
       
   242     /**
       
   243      */
       
   244     public final CompositeType getCompositeType() {
       
   245         return compositeType;
       
   246     }
       
   247 
       
   248     /**
       
   249      */
       
   250     public final SurfaceType getDestType() {
       
   251         return destType;
       
   252     }
       
   253 
       
   254     /**
       
   255      * Return true if this primitive can be used for the given signature
       
   256      * surfaces, and composite.
       
   257      *
       
   258      * @param signature The signature of the given operation.  Must be
       
   259      *          == (not just .equals) the signature string given by the
       
   260      *          abstract class that declares the operation.
       
   261      * @param srctype The surface type for the source of the operation
       
   262      * @param comptype The composite type for the operation
       
   263      * @param dsttype The surface type for the destination of the operation
       
   264      */
       
   265     public final boolean satisfies(String signature,
       
   266                                    SurfaceType srctype,
       
   267                                    CompositeType comptype,
       
   268                                    SurfaceType dsttype)
       
   269     {
       
   270         if (signature != methodSignature) {
       
   271             return false;
       
   272         }
       
   273         while (true) {
       
   274             if (srctype == null) {
       
   275                 return false;
       
   276             }
       
   277             if (srctype.equals(sourceType)) {
       
   278                 break;
       
   279             }
       
   280             srctype = srctype.getSuperType();
       
   281         }
       
   282         while (true) {
       
   283             if (comptype == null) {
       
   284                 return false;
       
   285             }
       
   286             if (comptype.equals(compositeType)) {
       
   287                 break;
       
   288             }
       
   289             comptype = comptype.getSuperType();
       
   290         }
       
   291         while (true) {
       
   292             if (dsttype == null) {
       
   293                 return false;
       
   294             }
       
   295             if (dsttype.equals(destType)) {
       
   296                 break;
       
   297             }
       
   298             dsttype = dsttype.getSuperType();
       
   299         }
       
   300         return true;
       
   301     }
       
   302 
       
   303     //
       
   304     // A version of satisfies used for regression testing
       
   305     //
       
   306     final boolean satisfiesSameAs(GraphicsPrimitive other) {
       
   307         return (methodSignature == other.methodSignature &&
       
   308                 sourceType.equals(other.sourceType) &&
       
   309                 compositeType.equals(other.compositeType) &&
       
   310                 destType.equals(other.destType));
       
   311     }
       
   312 
       
   313     public abstract GraphicsPrimitive makePrimitive(SurfaceType srctype,
       
   314                                                     CompositeType comptype,
       
   315                                                     SurfaceType dsttype);
       
   316 
       
   317     public abstract GraphicsPrimitive traceWrap();
       
   318 
       
   319     static HashMap traceMap;
       
   320 
       
   321     public static int traceflags;
       
   322     public static String tracefile;
       
   323     public static PrintStream traceout;
       
   324 
       
   325     public static final int TRACELOG = 1;
       
   326     public static final int TRACETIMESTAMP = 2;
       
   327     public static final int TRACECOUNTS = 4;
       
   328 
       
   329     static {
       
   330         GetPropertyAction gpa = new GetPropertyAction("sun.java2d.trace");
       
   331         String trace = (String)AccessController.doPrivileged(gpa);
       
   332         if (trace != null) {
       
   333             boolean verbose = false;
       
   334             int traceflags = 0;
       
   335             StringTokenizer st = new StringTokenizer(trace, ",");
       
   336             while (st.hasMoreTokens()) {
       
   337                 String tok = st.nextToken();
       
   338                 if (tok.equalsIgnoreCase("count")) {
       
   339                     traceflags |= GraphicsPrimitive.TRACECOUNTS;
       
   340                 } else if (tok.equalsIgnoreCase("log")) {
       
   341                     traceflags |= GraphicsPrimitive.TRACELOG;
       
   342                 } else if (tok.equalsIgnoreCase("timestamp")) {
       
   343                     traceflags |= GraphicsPrimitive.TRACETIMESTAMP;
       
   344                 } else if (tok.equalsIgnoreCase("verbose")) {
       
   345                     verbose = true;
       
   346                 } else if (tok.regionMatches(true, 0, "out:", 0, 4)) {
       
   347                     tracefile = tok.substring(4);
       
   348                 } else {
       
   349                     if (!tok.equalsIgnoreCase("help")) {
       
   350                         System.err.println("unrecognized token: "+tok);
       
   351                     }
       
   352                     System.err.println("usage: -Dsun.java2d.trace="+
       
   353                                        "[log[,timestamp]],[count],"+
       
   354                                        "[out:<filename>],[help],[verbose]");
       
   355                 }
       
   356             }
       
   357             if (verbose) {
       
   358                 System.err.print("GraphicsPrimitive logging ");
       
   359                 if ((traceflags & GraphicsPrimitive.TRACELOG) != 0) {
       
   360                     System.err.println("enabled");
       
   361                     System.err.print("GraphicsPrimitive timetamps ");
       
   362                     if ((traceflags & GraphicsPrimitive.TRACETIMESTAMP) != 0) {
       
   363                         System.err.println("enabled");
       
   364                     } else {
       
   365                         System.err.println("disabled");
       
   366                     }
       
   367                 } else {
       
   368                     System.err.println("[and timestamps] disabled");
       
   369                 }
       
   370                 System.err.print("GraphicsPrimitive invocation counts ");
       
   371                 if ((traceflags & GraphicsPrimitive.TRACECOUNTS) != 0) {
       
   372                     System.err.println("enabled");
       
   373                 } else {
       
   374                     System.err.println("disabled");
       
   375                 }
       
   376                 System.err.print("GraphicsPrimitive trace output to ");
       
   377                 if (tracefile == null) {
       
   378                     System.err.println("System.err");
       
   379                 } else {
       
   380                     System.err.println("file '"+tracefile+"'");
       
   381                 }
       
   382             }
       
   383             GraphicsPrimitive.traceflags = traceflags;
       
   384         }
       
   385     }
       
   386 
       
   387     public static boolean tracingEnabled() {
       
   388         return (traceflags != 0);
       
   389     }
       
   390 
       
   391     private static PrintStream getTraceOutputFile() {
       
   392         if (traceout == null) {
       
   393             if (tracefile != null) {
       
   394                 Object o =
       
   395                     AccessController.doPrivileged(new PrivilegedAction() {
       
   396                         public Object run() {
       
   397                             try {
       
   398                                 return new FileOutputStream(tracefile);
       
   399                             } catch (FileNotFoundException e) {
       
   400                                 return null;
       
   401                             }
       
   402                         }
       
   403                     });
       
   404                 if (o != null) {
       
   405                     traceout = new PrintStream((OutputStream) o);
       
   406                 } else {
       
   407                     traceout = System.err;
       
   408                 }
       
   409             } else {
       
   410                 traceout = System.err;
       
   411             }
       
   412         }
       
   413         return traceout;
       
   414     }
       
   415 
       
   416     public static class TraceReporter extends Thread {
       
   417         public static void setShutdownHook() {
       
   418             AccessController.doPrivileged(new PrivilegedAction() {
       
   419                 public Object run() {
       
   420                     Runtime.getRuntime().addShutdownHook(new TraceReporter());
       
   421                     return null;
       
   422                 }
       
   423             });
       
   424         }
       
   425 
       
   426         public void run() {
       
   427             PrintStream ps = getTraceOutputFile();
       
   428             Iterator iterator = traceMap.entrySet().iterator();
       
   429             long total = 0;
       
   430             int numprims = 0;
       
   431             while (iterator.hasNext()) {
       
   432                 Map.Entry me = (Map.Entry) iterator.next();
       
   433                 Object prim = me.getKey();
       
   434                 int[] count = (int[]) me.getValue();
       
   435                 if (count[0] == 1) {
       
   436                     ps.print("1 call to ");
       
   437                 } else {
       
   438                     ps.print(count[0]+" calls to ");
       
   439                 }
       
   440                 ps.println(prim);
       
   441                 numprims++;
       
   442                 total += count[0];
       
   443             }
       
   444             if (numprims == 0) {
       
   445                 ps.println("No graphics primitives executed");
       
   446             } else if (numprims > 1) {
       
   447                 ps.println(total+" total calls to "+
       
   448                            numprims+" different primitives");
       
   449             }
       
   450         }
       
   451     }
       
   452 
       
   453     public synchronized static void tracePrimitive(Object prim) {
       
   454         if ((traceflags & TRACECOUNTS) != 0) {
       
   455             if (traceMap == null) {
       
   456                 traceMap = new HashMap();
       
   457                 TraceReporter.setShutdownHook();
       
   458             }
       
   459             Object o = traceMap.get(prim);
       
   460             if (o == null) {
       
   461                 o = new int[1];
       
   462                 traceMap.put(prim, o);
       
   463             }
       
   464             ((int[]) o)[0]++;
       
   465         }
       
   466         if ((traceflags & TRACELOG) != 0) {
       
   467             PrintStream ps = getTraceOutputFile();
       
   468             if ((traceflags & TRACETIMESTAMP) != 0) {
       
   469                 ps.print(System.currentTimeMillis()+": ");
       
   470             }
       
   471             ps.println(prim);
       
   472         }
       
   473     }
       
   474 
       
   475     protected void setupGeneralBinaryOp(GeneralBinaryOp gbo) {
       
   476         int primID = gbo.getPrimTypeID();
       
   477         String methodSignature = gbo.getSignature();
       
   478         SurfaceType srctype = gbo.getSourceType();
       
   479         CompositeType comptype = gbo.getCompositeType();
       
   480         SurfaceType dsttype = gbo.getDestType();
       
   481         Blit convertsrc, convertdst, convertres;
       
   482         GraphicsPrimitive performop;
       
   483 
       
   484         convertsrc = createConverter(srctype, SurfaceType.IntArgb);
       
   485         performop = GraphicsPrimitiveMgr.locatePrim(primID,
       
   486                                                     SurfaceType.IntArgb,
       
   487                                                     comptype, dsttype);
       
   488         if (performop != null) {
       
   489             convertdst = null;
       
   490             convertres = null;
       
   491         } else {
       
   492             performop = getGeneralOp(primID, comptype);
       
   493             if (performop == null) {
       
   494                 throw new InternalError("Cannot construct general op for "+
       
   495                                         methodSignature+" "+comptype);
       
   496             }
       
   497             convertdst = createConverter(dsttype, SurfaceType.IntArgb);
       
   498             convertres = createConverter(SurfaceType.IntArgb, dsttype);
       
   499         }
       
   500 
       
   501         gbo.setPrimitives(convertsrc, convertdst, performop, convertres);
       
   502     }
       
   503 
       
   504     protected void setupGeneralUnaryOp(GeneralUnaryOp guo) {
       
   505         int primID = guo.getPrimTypeID();
       
   506         String methodSignature = guo.getSignature();
       
   507         CompositeType comptype = guo.getCompositeType();
       
   508         SurfaceType dsttype = guo.getDestType();
       
   509 
       
   510         Blit convertdst = createConverter(dsttype, SurfaceType.IntArgb);
       
   511         GraphicsPrimitive performop = getGeneralOp(primID, comptype);
       
   512         Blit convertres = createConverter(SurfaceType.IntArgb, dsttype);
       
   513         if (convertdst == null || performop == null || convertres == null) {
       
   514             throw new InternalError("Cannot construct binary op for "+
       
   515                                     comptype+" "+dsttype);
       
   516         }
       
   517 
       
   518         guo.setPrimitives(convertdst, performop, convertres);
       
   519     }
       
   520 
       
   521     protected static Blit createConverter(SurfaceType srctype,
       
   522                                           SurfaceType dsttype)
       
   523     {
       
   524         if (srctype.equals(dsttype)) {
       
   525             return null;
       
   526         }
       
   527         Blit cv = Blit.getFromCache(srctype, CompositeType.SrcNoEa, dsttype);
       
   528         if (cv == null) {
       
   529             throw new InternalError("Cannot construct converter for "+
       
   530                                     srctype+"=>"+dsttype);
       
   531         }
       
   532         return cv;
       
   533     }
       
   534 
       
   535     protected static SurfaceData convertFrom(Blit ob, SurfaceData srcData,
       
   536                                              int srcX, int srcY, int w, int h,
       
   537                                              SurfaceData dstData)
       
   538     {
       
   539         return convertFrom(ob, srcData,
       
   540                            srcX, srcY, w, h, dstData,
       
   541                            BufferedImage.TYPE_INT_ARGB);
       
   542     }
       
   543 
       
   544     protected static SurfaceData convertFrom(Blit ob, SurfaceData srcData,
       
   545                                              int srcX, int srcY, int w, int h,
       
   546                                              SurfaceData dstData, int type)
       
   547     {
       
   548         if (dstData != null) {
       
   549             Rectangle r = dstData.getBounds();
       
   550             if (w > r.width || h > r.height) {
       
   551                 dstData = null;
       
   552             }
       
   553         }
       
   554         if (dstData == null) {
       
   555             BufferedImage dstBI = new BufferedImage(w, h, type);
       
   556             dstData = BufImgSurfaceData.createData(dstBI);
       
   557         }
       
   558         ob.Blit(srcData, dstData, AlphaComposite.Src, null,
       
   559                 srcX, srcY, 0, 0, w, h);
       
   560         return dstData;
       
   561     }
       
   562 
       
   563     protected static void convertTo(Blit ob,
       
   564                                     SurfaceData srcImg, SurfaceData dstImg,
       
   565                                     Region clip,
       
   566                                     int dstX, int dstY, int w, int h)
       
   567     {
       
   568         if (ob != null) {
       
   569             ob.Blit(srcImg, dstImg, AlphaComposite.Src, clip,
       
   570                     0, 0, dstX, dstY, w, h);
       
   571         }
       
   572     }
       
   573 
       
   574     protected static GraphicsPrimitive getGeneralOp(int primID,
       
   575                                                     CompositeType comptype)
       
   576     {
       
   577         return GraphicsPrimitiveMgr.locatePrim(primID,
       
   578                                                SurfaceType.IntArgb,
       
   579                                                comptype,
       
   580                                                SurfaceType.IntArgb);
       
   581     }
       
   582 
       
   583     public static String simplename(Field[] fields, Object o) {
       
   584         for (int i = 0; i < fields.length; i++) {
       
   585             Field f = fields[i];
       
   586             try {
       
   587                 if (o == f.get(null)) {
       
   588                     return f.getName();
       
   589                 }
       
   590             } catch (Exception e) {
       
   591             }
       
   592         }
       
   593         return "\""+o.toString()+"\"";
       
   594     }
       
   595 
       
   596     public static String simplename(SurfaceType st) {
       
   597         return simplename(SurfaceType.class.getDeclaredFields(), st);
       
   598     }
       
   599 
       
   600     public static String simplename(CompositeType ct) {
       
   601         return simplename(CompositeType.class.getDeclaredFields(), ct);
       
   602     }
       
   603 
       
   604     private String cachedname;
       
   605 
       
   606     public String toString() {
       
   607         if (cachedname == null) {
       
   608             String sig = methodSignature;
       
   609             int index = sig.indexOf('(');
       
   610             if (index >= 0) {
       
   611                 sig = sig.substring(0, index);
       
   612             }
       
   613             cachedname = (getClass().getName()+"::"+
       
   614                           sig+"("+
       
   615                           simplename(sourceType)+", "+
       
   616                           simplename(compositeType)+", "+
       
   617                           simplename(destType)+")");
       
   618         }
       
   619         return cachedname;
       
   620     }
       
   621 }