Factor in the percentage of the databuffer a BufferedMirage is using to

estimate its memory if its BufferedImage is a subimage of another
BufferedImage.

Include the amount of memory used by colorizations in ImageManager's cache
usage calculations.

Crank ImageManager's cache size up to 32 megs since a) it's actually seeing the
memory used by colorizations and b) the new seamonsters are pretty sizable.



git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@291 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
Charlie Groves
2007-08-30 22:50:24 +00:00
parent 37b5e58961
commit 65b8cdbc3a
3 changed files with 43 additions and 17 deletions
@@ -355,10 +355,13 @@ public class BundledComponentRepository
{ {
// we don't need our images prepared for screen rendering // we don't need our images prepared for screen rendering
BufferedImage src = _imgr.getImage(getImageKey(path), zations); BufferedImage src = _imgr.getImage(getImageKey(path), zations);
float percentageOfDataBuffer = 1;
if (bounds != null) { if (bounds != null) {
percentageOfDataBuffer =
(bounds.height * bounds.width) / (float)(src.getHeight() * src.getWidth());
src = src.getSubimage(bounds.x, bounds.y, bounds.width, bounds.height); src = src.getSubimage(bounds.x, bounds.y, bounds.width, bounds.height);
} }
return new BufferedMirage(src); return new BufferedMirage(src, percentageOfDataBuffer);
} }
/** The resource bundle from which we obtain image data. */ /** The resource bundle from which we obtain image data. */
@@ -30,8 +30,19 @@ import java.awt.image.BufferedImage;
public class BufferedMirage implements Mirage public class BufferedMirage implements Mirage
{ {
public BufferedMirage (BufferedImage image) public BufferedMirage (BufferedImage image)
{
this(image, 1);
}
/**
* @param percentageOfDataBuffer - the percentage of image's data buffer used by image for use
* in getEstimatedMemory. ie if this image is a subimage of another image, and they share a
* data buffer, this is the percentage of the size of this image compared to the source.
*/
public BufferedMirage (BufferedImage image, float percentageOfDataBuffer)
{ {
_image = image; _image = image;
_percentageOfDataBuffer = percentageOfDataBuffer;
} }
// documentation inherited from interface // documentation inherited from interface
@@ -61,7 +72,8 @@ public class BufferedMirage implements Mirage
// documentation inherited from interface // documentation inherited from interface
public long getEstimatedMemoryUsage () public long getEstimatedMemoryUsage ()
{ {
return ImageUtil.getEstimatedMemoryUsage(_image.getRaster()); return (long)(ImageUtil.getEstimatedMemoryUsage(_image.getRaster()) *
_percentageOfDataBuffer);
} }
// documentation inherited from interface // documentation inherited from interface
@@ -69,6 +81,8 @@ public class BufferedMirage implements Mirage
{ {
return _image; return _image;
} }
protected float _percentageOfDataBuffer;
protected BufferedImage _image; protected BufferedImage _image;
} }
@@ -273,7 +273,7 @@ public class ImageManager
} }
if (crec != null) { if (crec != null) {
// Log.info("Cache hit [key=" + key + ", crec=" + crec + "]."); // Log.info("Cache hit [key=" + key + ", crec=" + crec + "].");
return crec.getImage(zations); return crec.getImage(zations, _ccache);
} }
// Log.info("Cache miss [key=" + key + ", crec=" + crec + "]."); // Log.info("Cache miss [key=" + key + ", crec=" + crec + "].");
@@ -298,7 +298,7 @@ public class ImageManager
// periodically report our image cache performance // periodically report our image cache performance
reportCachePerformance(); reportCachePerformance();
return crec.getImage(zations); return crec.getImage(zations, _ccache);
} }
/** /**
@@ -345,6 +345,7 @@ public class ImageManager
{ {
BufferedImage src = null; BufferedImage src = null;
float percentageOfDataBuffer = 1;
if (bounds == null) { if (bounds == null) {
// if they specified no bounds, we need to load up the raw image and determine its // if they specified no bounds, we need to load up the raw image and determine its
// bounds so that we can pass those along to the created mirage // bounds so that we can pass those along to the created mirage
@@ -353,6 +354,8 @@ public class ImageManager
} else if (!_prepareImages.getValue()) { } else if (!_prepareImages.getValue()) {
src = getImage(key, zations); src = getImage(key, zations);
percentageOfDataBuffer =
(bounds.width * bounds.height)/(float)(src.getHeight() * src.getWidth());
src = src.getSubimage(bounds.x, bounds.y, bounds.width, bounds.height); src = src.getSubimage(bounds.x, bounds.y, bounds.width, bounds.height);
} }
@@ -361,7 +364,7 @@ public class ImageManager
} else if (_prepareImages.getValue()) { } else if (_prepareImages.getValue()) {
return new CachedVolatileMirage(this, key, bounds, zations); return new CachedVolatileMirage(this, key, bounds, zations);
} else { } else {
return new BufferedMirage(src); return new BufferedMirage(src, percentageOfDataBuffer);
} }
} }
@@ -493,9 +496,8 @@ public class ImageManager
} }
eff = _ccache.getTrackedEffectiveness(); eff = _ccache.getTrackedEffectiveness();
} }
Log.info("ImageManager LRU [mem=" + (size / 1024) + "k" + ", size=" + _ccache.size() + Log.info("ImageManager LRU [mem=" + (size / 1024) + "k, size=" + _ccache.size() +
", hits=" + eff[0] + ", misses=" + eff[1] + ", hits=" + eff[0] + ", misses=" + eff[1] + ", totalKeys=" + _keySet.size() + "].");
", totalKeys=" + _keySet.size() + "].");
} }
/** Maintains a source image and a set of colorized versions in the image cache. */ /** Maintains a source image and a set of colorized versions in the image cache. */
@@ -507,30 +509,31 @@ public class ImageManager
_source = source; _source = source;
} }
public BufferedImage getImage (Colorization[] zations) public BufferedImage getImage (Colorization[] zations, LRUHashMap cache)
{ {
if (zations == null) { if (zations == null) {
return _source; return _source;
} }
if (_colorized == null) { if (_colorized == null) {
_colorized = new ArrayList(); _colorized = new ArrayList<Tuple<Colorization[], BufferedImage>>();
} }
// we search linearly through our list of colorized copies because it is not likely to // we search linearly through our list of colorized copies because it is not likely to
// be very long // be very long
int csize = _colorized.size(); int csize = _colorized.size();
for (int ii = 0; ii < csize; ii++) { for (int ii = 0; ii < csize; ii++) {
Tuple tup = (Tuple)_colorized.get(ii); Tuple<Colorization[], BufferedImage> tup = _colorized.get(ii);
Colorization[] tzations = (Colorization[])tup.left; Colorization[] tzations = tup.left;
if (Arrays.equals(zations, tzations)) { if (Arrays.equals(zations, tzations)) {
return (BufferedImage)tup.right; return tup.right;
} }
} }
try { try {
BufferedImage cimage = ImageUtil.recolorImage(_source, zations); BufferedImage cimage = ImageUtil.recolorImage(_source, zations);
_colorized.add(new Tuple(zations, cimage)); _colorized.add(new Tuple<Colorization[], BufferedImage>(zations, cimage));
cache.adjustSize((int)ImageUtil.getEstimatedMemoryUsage(cimage));
return cimage; return cimage;
} catch (Exception re) { } catch (Exception re) {
@@ -543,7 +546,13 @@ public class ImageManager
public long getEstimatedMemoryUsage () public long getEstimatedMemoryUsage ()
{ {
return ImageUtil.getEstimatedMemoryUsage(_source); long usage = ImageUtil.getEstimatedMemoryUsage(_source);
if (_colorized != null) {
for (Tuple<Colorization[], BufferedImage> tup : _colorized) {
usage += ImageUtil.getEstimatedMemoryUsage(tup.right);
}
}
return usage;
} }
public String toString () public String toString ()
@@ -554,7 +563,7 @@ public class ImageManager
protected ImageKey _key; protected ImageKey _key;
protected BufferedImage _source; protected BufferedImage _source;
protected ArrayList _colorized; protected ArrayList<Tuple<Colorization[], BufferedImage>> _colorized;
} }
/** A reference to the resource manager via which we load image data by default. */ /** A reference to the resource manager via which we load image data by default. */
@@ -588,7 +597,7 @@ public class ImageManager
/** Register our image cache size with the runtime adjustments framework. */ /** Register our image cache size with the runtime adjustments framework. */
protected static RuntimeAdjust.IntAdjust _cacheSize = new RuntimeAdjust.IntAdjust( protected static RuntimeAdjust.IntAdjust _cacheSize = new RuntimeAdjust.IntAdjust(
"Size (in kb of memory used) of the image manager LRU cache [requires restart]", "Size (in kb of memory used) of the image manager LRU cache [requires restart]",
"narya.media.image.cache_size", MediaPrefs.config, 2048); "narya.media.image.cache_size", MediaPrefs.config, 32768);
/** Controls whether or not we prepare images or use raw versions. */ /** Controls whether or not we prepare images or use raw versions. */
protected static RuntimeAdjust.BooleanAdjust _prepareImages = new RuntimeAdjust.BooleanAdjust( protected static RuntimeAdjust.BooleanAdjust _prepareImages = new RuntimeAdjust.BooleanAdjust(