1 /* Copyright (C) 2005-2011 Fabio Riccardi */ 2 3 /* 4 * $RCSfile: SunCachedTile.java,v $ 5 * 6 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 7 * 8 * Use is subject to license terms. 9 * 10 * $Revision: 1.1 $ 11 * $Date: 2005/02/11 04:57:02 $ 12 * $State: Exp $ 13 */ 14 package com.lightcrafts.jai.utils; 15 16 import java.awt.image.DataBuffer; 17 import java.awt.image.Raster; 18 import java.awt.image.RenderedImage; 19 import java.lang.ref.WeakReference; 20 import java.math.BigInteger; 21 import com.lightcrafts.mediax.jai.CachedTile; 22 import com.lightcrafts.mediax.jai.PlanarImage; 23 import com.lightcrafts.mediax.jai.remote.SerializableRenderedImage; 24 25 /** 26 * Information associated with a cached tile. 27 * 28 * <p> This class is used by SunTileCache to create an object that 29 * includes all the information associated with a tile, and is put 30 * into the tile cache. 31 * 32 * <p> It also serves as a double linked list. 33 * 34 * @see LCTileCache 35 * 36 */ 37 final class LCCachedTile implements CachedTile { 38 39 // Soft or Weak references need to be used, or the objects 40 // never get garbage collected. The OpImage finalize 41 // method calls removeTiles(). It was suggested, that 42 // the owner be a weak reference. 43 Raster tile; // the tile to be cached 44 WeakReference owner; // the RenderedImage this tile belongs to 45 46 int tileX; // tile X index 47 int tileY; // tile Y index 48 49 Object tileCacheMetric; // Metric for weighting tile computation cost 50 long timeStamp; // the last time this tile is accessed 51 52 Object key; // the key used to hash this tile 53 long memorySize; // the memory used by this tile in bytes 54 55 LCCachedTile previous; // the SunCachedTile before this tile 56 LCCachedTile next; // the SunCachedTile after this tile 57 58 int action = 0; // add, remove, update from tile cache 59 60 61 /** 62 * Constructor that takes a tile cache metric 63 * @since 1.1 64 */ LCCachedTile(RenderedImage owner, int tileX, int tileY, Raster tile, Object tileCacheMetric)65 LCCachedTile(RenderedImage owner, 66 int tileX, 67 int tileY, 68 Raster tile, 69 Object tileCacheMetric) { 70 71 this.owner = new WeakReference(owner); 72 this.tile = tile; 73 this.tileX = tileX; 74 this.tileY = tileY; 75 76 this.tileCacheMetric = tileCacheMetric; // may be null 77 78 key = hashKey(owner, tileX, tileY); 79 80 // tileMemorySize(Raster tile) inlined for performance 81 DataBuffer db = tile.getDataBuffer(); 82 memorySize = db.getDataTypeSize(db.getDataType()) / 8L * 83 db.getSize() * db.getNumBanks(); 84 85 } 86 fastHashKey(RenderedImage owner, int tileX, int tileY)87 static Object fastHashKey(RenderedImage owner, 88 int tileX, 89 int tileY) { 90 return new Integer(((Object) owner).hashCode() + tileY * owner.getNumXTiles() + tileX); 91 } 92 93 /** 94 * Returns the hash table "key" as a <code>Object</code> for this 95 * tile. For <code>PlanarImage</code> and 96 * <code>SerializableRenderedImage</code>, the key is generated by 97 * the method <code>ImageUtilgenerateID(Object) </code>. For the 98 * other cases, a <code>Long</code> object is returned. 99 * The upper 32 bits for this <code>Long</code> is the tile owner's 100 * hash code, and the lower 32 bits is the tile's index. 101 */ hashKey(RenderedImage owner, int tileX, int tileY)102 static Object hashKey(RenderedImage owner, 103 int tileX, 104 int tileY) { 105 long idx = tileY * (long)owner.getNumXTiles() + tileX; 106 107 BigInteger imageID = null; 108 if (owner instanceof PlanarImage) 109 imageID = (BigInteger)((PlanarImage)owner).getImageID(); 110 else if (owner instanceof SerializableRenderedImage) 111 imageID = (BigInteger)((SerializableRenderedImage)owner).getImageID(); 112 113 if (imageID != null) { 114 byte[] buf = imageID.toByteArray(); 115 int length = buf.length; 116 byte[] buf1 = new byte[length + 8]; 117 System.arraycopy(buf, 0, buf1, 0, length); 118 for (int i = 7, j = 0; i >= 0; i--, j += 8) 119 buf1[length++] = (byte)(idx >> j); 120 return new BigInteger(buf1); 121 } 122 123 idx = idx & 0x00000000ffffffffL; 124 return new Long(((long)owner.hashCode() << 32) | idx); 125 } 126 127 /** 128 * Special version of hashKey for use in SunTileCache.removeTiles(). 129 * Minimizes the overhead of repeated calls to 130 * hashCode and getNumTiles(). Note that this causes a 131 * linkage between the CachedTile and SunTileCache classes 132 * in that SunTileCache now has to understand how the 133 * tileIndex is calculated. 134 */ 135 /* 136 static Long hashKey(int ownerHashCode, 137 int tileIndex) { 138 long idx = (long)tileIndex; 139 idx = idx & 0x00000000ffffffffL; 140 return new Long(((long)ownerHashCode << 32) | idx); 141 } 142 */ 143 /** Returns the owner's hash code. */ 144 /* static long getOwnerHashCode(Long key) { 145 return key.longValue() >>> 32; 146 } 147 */ 148 /** Returns a string representation of the class object. */ toString()149 public String toString() { 150 RenderedImage o = (RenderedImage) getOwner(); 151 String ostring = o == null ? "null" : o.toString(); 152 153 Raster t = getTile(); 154 String tstring = t == null ? "null" : t.toString(); 155 156 return getClass().getName() + "@" + Integer.toHexString(hashCode()) + 157 ": owner = " + ostring + 158 " tileX = " + Integer.toString(tileX) + 159 " tileY = " + Integer.toString(tileY) + 160 " tile = " + tstring + 161 " key = " + ((key instanceof Long)? Long.toHexString(((Long)key).longValue()) : key.toString()) + 162 " memorySize = " + Long.toString(memorySize) + 163 " timeStamp = " + Long.toString(timeStamp); 164 } 165 166 /** Returns the cached tile. */ getTile()167 public Raster getTile() { 168 return tile; 169 } 170 171 /** Returns the owner of the cached tile. */ getOwner()172 public RenderedImage getOwner() { 173 return (RenderedImage)owner.get(); 174 } 175 176 /** Returns the current time stamp */ getTileTimeStamp()177 public long getTileTimeStamp() { 178 return timeStamp; 179 } 180 181 /** Returns the tileCacheMetric object */ getTileCacheMetric()182 public Object getTileCacheMetric() { 183 return tileCacheMetric; 184 } 185 186 /** Returns the tile memory size */ getTileSize()187 public long getTileSize() { 188 return memorySize; 189 } 190 191 /** Returns information about the method that 192 * triggered the notification event. 193 */ getAction()194 public int getAction() { 195 return action; 196 } 197 } 198