If we're creating a CompositedMultiFrameImage with only a single source image and it's a TileSetFrameImage, just use the Mirages in that TileSet rather than creating a whole new set of BufferedImages to composite them into. This halves the image memory used by anything that's just colorizing and transforming its images and doesn't really need composition.

git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@295 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
Charlie Groves
2007-09-26 21:49:11 +00:00
parent 8d5fc6c6ea
commit c45878681f
4 changed files with 131 additions and 29 deletions
@@ -90,7 +90,7 @@ public class CompositedMaskedImage extends CompositedMultiFrameImage
/**
* Combines the image in the first source with the masks in the rest. */
protected class MaskedMirage extends CompositedMirage
protected class MaskedMirage extends CompositedVolatileMirage
{
public MaskedMirage (int index)
{
@@ -0,0 +1,21 @@
package com.threerings.cast;
import java.util.Comparator;
import com.threerings.cast.CompositedActionFrames.ComponentFrames;
import com.threerings.media.image.Mirage;
public interface CompositedMirage
extends Mirage, Comparator<ComponentFrames>
{
/**
* Returns the x offset into our image.
*/
public int getX ();
/**
* Returns the y offset into our image.
*/
public int getY ();
}
@@ -25,17 +25,15 @@ import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.util.Arrays;
import java.util.Comparator;
import com.threerings.cast.CompositedActionFrames.ComponentFrames;
import com.threerings.cast.bundle.BundledComponentRepository.TileSetFrameImage;
import com.threerings.media.image.ImageManager;
import com.threerings.media.image.Mirage;
import com.threerings.media.image.VolatileMirage;
import com.threerings.cast.CompositedActionFrames.ComponentFrames;
import com.threerings.cast.TrimmedMultiFrameImage;
/**
* Used to composite the action frames for a particular orientation of a
* {@link CompositedActionFrames}.
@@ -75,12 +73,14 @@ public class CompositedMultiFrameImage
return _images[index].getHeight();
}
public int getXOrigin (int index) {
return _images[index].getXOrigin();
public int getXOrigin (int index)
{
return _images[index].getX();
}
public int getYOrigin (int index) {
return _images[index].getYOrigin();
public int getYOrigin (int index)
{
return _images[index].getY();
}
// documentation inherited from interface
@@ -115,7 +115,78 @@ public class CompositedMultiFrameImage
*/
protected CompositedMirage createCompositedMirage (int index)
{
return new CompositedMirage(index);
if (_sources.length == 1 && _sources[0].frames instanceof TileSetFrameImage) {
TileSetFrameImage frames = (TileSetFrameImage)_sources[0].frames;
Rectangle tbounds = new Rectangle();
frames.getTrimmedBounds(_orient, index, tbounds);
int x = frames.getXOrigin(_orient, index) - tbounds.x;
int y = frames.getYOrigin(_orient, index) - tbounds.y;
return new SubmirageForwarder(frames.getTileMirage(_orient, index), x, y);
}
return new CompositedVolatileMirage(index);
}
/**
* A CompositedMirage that forwards all of its Mirage calls to a delegate Mirage.
*/
protected class SubmirageForwarder implements CompositedMirage {
public SubmirageForwarder(Mirage m, int x, int y) {
delegate = m;
this.x = x;
this.y = y;
}
public int getX ()
{
return x;
}
public int getY ()
{
return y;
}
// documentation inherited from interface
public int compare (ComponentFrames cf1, ComponentFrames cf2)
{
return (cf1.ccomp.componentClass.getRenderPriority(_action, _orient) -
cf2.ccomp.componentClass.getRenderPriority(_action, _orient));
}
public long getEstimatedMemoryUsage ()
{
return delegate.getEstimatedMemoryUsage();
}
public int getHeight ()
{
return delegate.getHeight();
}
public BufferedImage getSnapshot ()
{
return delegate.getSnapshot();
}
public int getWidth ()
{
return delegate.getWidth();
}
public boolean hitTest (int x, int y)
{
return delegate.hitTest(x, y);
}
public void paint (Graphics2D gfx, int x, int y)
{
delegate.paint(gfx, x, y);
}
protected int x, y;
protected Mirage delegate;
}
// documentation inherited
@@ -142,10 +213,10 @@ public class CompositedMultiFrameImage
/**
* Used to create our mirage using the source action frame images.
*/
protected class CompositedMirage extends VolatileMirage
implements Comparator
protected class CompositedVolatileMirage extends VolatileMirage
implements CompositedMirage
{
public CompositedMirage (int index)
public CompositedVolatileMirage (int index)
{
super(CompositedMultiFrameImage.this._imgr,
new Rectangle(0, 0, 0, 0));
@@ -192,14 +263,10 @@ public class CompositedMultiFrameImage
}
// documentation inherited from interface
public int compare (Object o1, Object o2)
public int compare (ComponentFrames cf1, ComponentFrames cf2)
{
ComponentFrames cf1 = (ComponentFrames)o1,
cf2 = (ComponentFrames)o2;
return (cf1.ccomp.componentClass.getRenderPriority(
_action, _orient) -
cf2.ccomp.componentClass.getRenderPriority(
_action, _orient));
return (cf1.ccomp.componentClass.getRenderPriority(_action, _orient) -
cf2.ccomp.componentClass.getRenderPriority(_action, _orient));
}
/**
@@ -374,7 +374,7 @@ public class BundledComponentRepository
/**
* Used to provide multiframe images using data obtained from a tileset.
*/
protected static class TileSetFrameImage implements ActionFrames
public static class TileSetFrameImage implements ActionFrames
{
/**
* Constructs a tileset frame image with the specified tileset and for the specified
@@ -437,17 +437,21 @@ public class BundledComponentRepository
}
public void getTrimmedBounds (int index, Rectangle bounds) {
Tile tile = _set.getTile(getTileIndex(orient, index));
if (tile instanceof TrimmedTile) {
((TrimmedTile)tile).getTrimmedBounds(bounds);
} else {
bounds.setBounds(0, 0, tile.getWidth(), tile.getHeight());
}
bounds.translate(_dx, _dy);
TileSetFrameImage.this.getTrimmedBounds(orient, index, bounds);
}
};
}
public void getTrimmedBounds (int orient, int index, Rectangle bounds) {
Tile tile = getTile(orient, index);
if (tile instanceof TrimmedTile) {
((TrimmedTile)tile).getTrimmedBounds(bounds);
} else {
bounds.setBounds(0, 0, tile.getWidth(), tile.getHeight());
}
bounds.translate(_dx, _dy);
}
// documentation inherited from interface
public int getXOrigin (int orient, int index)
{
@@ -477,6 +481,15 @@ public class BundledComponentRepository
return _orients.get(orient) * _fcount + index;
}
public Tile getTile (int orient, int index)
{
return _set.getTile(getTileIndex(orient, index));
}
public Mirage getTileMirage(int orient, int index) {
return _set.getTileMirage(getTileIndex(orient, index));
}
/** The tileset from which we obtain our frame images. */
protected TileSet _set;
@@ -491,6 +504,7 @@ public class BundledComponentRepository
/** A mapping from orientation code to animation sequence index. */
protected IntIntMap _orients = new IntIntMap();
}
/** We use the image manager to decode and cache images. */