001: /*
002: * $RCSfile: SunCachedTile.java,v $
003: *
004: * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
005: *
006: * Use is subject to license terms.
007: *
008: * $Revision: 1.1 $
009: * $Date: 2005/02/11 04:57:02 $
010: * $State: Exp $
011: */
012: package com.sun.media.jai.util;
013:
014: import java.awt.image.DataBuffer;
015: import java.awt.image.Raster;
016: import java.awt.image.RenderedImage;
017: import java.lang.ref.SoftReference;
018: import java.lang.ref.WeakReference;
019: import java.lang.reflect.Method;
020: import java.math.BigInteger;
021: import javax.media.jai.CachedTile;
022: import javax.media.jai.PlanarImage;
023: import javax.media.jai.remote.SerializableRenderedImage;
024:
025: /**
026: * Information associated with a cached tile.
027: *
028: * <p> This class is used by SunTileCache to create an object that
029: * includes all the information associated with a tile, and is put
030: * into the tile cache.
031: *
032: * <p> It also serves as a double linked list.
033: *
034: * @see SunTileCache
035: *
036: */
037: final class SunCachedTile implements CachedTile {
038:
039: // Soft or Weak references need to be used, or the objects
040: // never get garbage collected. The OpImage finalize
041: // method calls removeTiles(). It was suggested, that
042: // the owner be a weak reference.
043: Raster tile; // the tile to be cached
044: WeakReference owner; // the RenderedImage this tile belongs to
045:
046: int tileX; // tile X index
047: int tileY; // tile Y index
048:
049: Object tileCacheMetric; // Metric for weighting tile computation cost
050: long timeStamp; // the last time this tile is accessed
051:
052: Object key; // the key used to hash this tile
053: long memorySize; // the memory used by this tile in bytes
054:
055: SunCachedTile previous; // the SunCachedTile before this tile
056: SunCachedTile next; // the SunCachedTile after this tile
057:
058: int action = 0; // add, remove, update from tile cache
059:
060: /**
061: * Constructor that takes a tile cache metric
062: * @since 1.1
063: */
064: SunCachedTile(RenderedImage owner, int tileX, int tileY,
065: Raster tile, Object tileCacheMetric) {
066:
067: this .owner = new WeakReference(owner);
068: this .tile = tile;
069: this .tileX = tileX;
070: this .tileY = tileY;
071:
072: this .tileCacheMetric = tileCacheMetric; // may be null
073:
074: key = hashKey(owner, tileX, tileY);
075:
076: // tileMemorySize(Raster tile) inlined for performance
077: DataBuffer db = tile.getDataBuffer();
078: memorySize = db.getDataTypeSize(db.getDataType()) / 8L
079: * db.getSize() * db.getNumBanks();
080:
081: }
082:
083: /**
084: * Returns the hash table "key" as a <code>Object</code> for this
085: * tile. For <code>PlanarImage</code> and
086: * <code>SerializableRenderedImage</code>, the key is generated by
087: * the method <code>ImageUtilgenerateID(Object) </code>. For the
088: * other cases, a <code>Long</code> object is returned.
089: * The upper 32 bits for this <code>Long</code> is the tile owner's
090: * hash code, and the lower 32 bits is the tile's index.
091: */
092: static Object hashKey(RenderedImage owner, int tileX, int tileY) {
093: long idx = tileY * (long) owner.getNumXTiles() + tileX;
094:
095: BigInteger imageID = null;
096: if (owner instanceof PlanarImage)
097: imageID = (BigInteger) ((PlanarImage) owner).getImageID();
098: else if (owner instanceof SerializableRenderedImage)
099: imageID = (BigInteger) ((SerializableRenderedImage) owner)
100: .getImageID();
101:
102: if (imageID != null) {
103: byte[] buf = imageID.toByteArray();
104: int length = buf.length;
105: byte[] buf1 = new byte[length + 8];
106: System.arraycopy(buf, 0, buf1, 0, length);
107: for (int i = 7, j = 0; i >= 0; i--, j += 8)
108: buf1[length++] = (byte) (idx >> j);
109: return new BigInteger(buf1);
110: }
111:
112: idx = idx & 0x00000000ffffffffL;
113: return new Long(((long) owner.hashCode() << 32) | idx);
114: }
115:
116: /**
117: * Special version of hashKey for use in SunTileCache.removeTiles().
118: * Minimizes the overhead of repeated calls to
119: * hashCode and getNumTiles(). Note that this causes a
120: * linkage between the CachedTile and SunTileCache classes
121: * in that SunTileCache now has to understand how the
122: * tileIndex is calculated.
123: */
124: /*
125: static Long hashKey(int ownerHashCode,
126: int tileIndex) {
127: long idx = (long)tileIndex;
128: idx = idx & 0x00000000ffffffffL;
129: return new Long(((long)ownerHashCode << 32) | idx);
130: }
131: */
132: /** Returns the owner's hash code. */
133: /* static long getOwnerHashCode(Long key) {
134: return key.longValue() >>> 32;
135: }
136: */
137: /** Returns a string representation of the class object. */
138: public String toString() {
139: RenderedImage o = (RenderedImage) getOwner();
140: String ostring = o == null ? "null" : o.toString();
141:
142: Raster t = getTile();
143: String tstring = t == null ? "null" : t.toString();
144:
145: return getClass().getName()
146: + "@"
147: + Integer.toHexString(hashCode())
148: + ": owner = "
149: + ostring
150: + " tileX = "
151: + Integer.toString(tileX)
152: + " tileY = "
153: + Integer.toString(tileY)
154: + " tile = "
155: + tstring
156: + " key = "
157: + ((key instanceof Long) ? Long
158: .toHexString(((Long) key).longValue()) : key
159: .toString()) + " memorySize = "
160: + Long.toString(memorySize) + " timeStamp = "
161: + Long.toString(timeStamp);
162: }
163:
164: /** Returns the cached tile. */
165: public Raster getTile() {
166: return tile;
167: }
168:
169: /** Returns the owner of the cached tile. */
170: public RenderedImage getOwner() {
171: return (RenderedImage) owner.get();
172: }
173:
174: /** Returns the current time stamp */
175: public long getTileTimeStamp() {
176: return timeStamp;
177: }
178:
179: /** Returns the tileCacheMetric object */
180: public Object getTileCacheMetric() {
181: return tileCacheMetric;
182: }
183:
184: /** Returns the tile memory size */
185: public long getTileSize() {
186: return memorySize;
187: }
188:
189: /** Returns information about the method that
190: * triggered the notification event.
191: */
192: public int getAction() {
193: return action;
194: }
195: }
|