Optimized the fringe tile creation process (we only create the graphics

context once and use it to stamp all fringe fragments).


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3633 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2005-06-28 21:19:38 +00:00
parent 6474d7de7e
commit ced6c5b826
@@ -50,11 +50,12 @@ public class TileFringer
public String getDefaultType ();
}
public static interface ImageSource
public static interface ImageSource extends ImageUtil.ImageCreator
{
/** Creates a blank image into which various fringe images will be
* composited. */
public BufferedImage createImage (int width, int height);
public BufferedImage createImage (
int width, int height, int transparency);
/** Returns the source image for a tile of the specified type.
* This can be randomly selected and change from call to call. */
@@ -143,25 +144,34 @@ public class TileFringer
QuickSort.sort(fringers);
BufferedImage source = _isrc.getTileSource(baseType);
int width = source.getWidth(), height = source.getHeight();
BufferedImage ftimg = _isrc.createImage(width, height);
stampTileImage(source, ftimg, width, height);
for (int ii = 0; ii < fringers.length; ii++) {
int[] indexes = getFringeIndexes(fringers[ii].bits);
for (int jj = 0; jj < indexes.length; jj++) {
ftimg = getTileImage(ftimg, fringers[ii].fringerType,
indexes[jj], masks, hashValue);
}
}
BufferedImage ftimg = _isrc.createImage(
source.getWidth(), source.getHeight(), Transparency.OPAQUE);
Graphics2D gfx = (Graphics2D)ftimg.getGraphics();
try {
// start with the base tile image
gfx.drawImage(source, 0, 0, null);
// and stamp the fringers on top of it
for (int ii = 0; ii < fringers.length; ii++) {
int[] indexes = getFringeIndexes(fringers[ii].bits);
for (int jj = 0; jj < indexes.length; jj++) {
stampTileImage(gfx, fringers[ii].fringerType,
indexes[jj], masks, hashValue);
}
}
} finally {
gfx.dispose();
}
return ftimg;
}
/**
* Retrieve or compose an image for the specified fringe.
* Looks up or creates the appropriate fringe mask and draws it into
* the supplied graphics context.
*/
protected BufferedImage getTileImage (
BufferedImage ftimg, String fringerType, int index,
protected void stampTileImage (
Graphics2D gfx, String fringerType, int index,
HashMap masks, int hashValue)
{
FringeConfiguration.FringeRecord frec =
@@ -171,28 +181,26 @@ public class TileFringer
if (fsimg == null) {
Log.warning("Missing fringe source image [type=" + fringerType +
", hash=" + hashValue + ", frec=" + frec + "].");
return ftimg;
return;
}
if (!frec.mask) {
if (frec.mask) {
// it's a mask; look for it in the cache
String maskkey = fringerType + ":" + frec.name + ":" + index;
BufferedImage mimg = (BufferedImage)masks.get(maskkey);
if (mimg == null) {
BufferedImage fsrc = getSubimage(fsimg, index);
BufferedImage bsrc = _isrc.getTileSource(fringerType);
mimg = ImageUtil.composeMaskedImage(_isrc, fsrc, bsrc);
masks.put(maskkey, mimg);
}
gfx.drawImage(mimg, 0, 0, null);
} else {
// this is a non-mask image so just use the data from the
// fringe source image directly
BufferedImage stamp = getSubimage(fsimg, index);
return stampTileImage(stamp, ftimg, stamp.getWidth(),
stamp.getHeight());
gfx.drawImage(getSubimage(fsimg, index), 0, 0, null);
}
// otherwise, it's a mask; look for it in the cache
String maskkey = fringerType + ":" + frec.name + ":" + index;
BufferedImage mimg = (BufferedImage)masks.get(maskkey);
if (mimg == null) {
BufferedImage fsrc = getSubimage(fsimg, index);
BufferedImage bsrc = _isrc.getTileSource(fringerType);
mimg = ImageUtil.composeMaskedImage(null, fsrc, bsrc); // TODO
masks.put(maskkey, mimg);
}
return stampTileImage(mimg, ftimg, mimg.getWidth(null),
mimg.getHeight(null));
}
/**
@@ -206,23 +214,6 @@ public class TileFringer
return source.getSubimage(x, 0, size, size);
}
/** Helper function for {@link #getTileImage}. */
protected BufferedImage stampTileImage (
BufferedImage stamp, BufferedImage ftimg, int width, int height)
{
// create the target image if necessary
if (ftimg == null) {
ftimg = _isrc.createImage(width, height);
}
Graphics2D gfx = (Graphics2D)ftimg.getGraphics();
try {
gfx.drawImage(stamp, 0, 0, null);
} finally {
gfx.dispose();
}
return ftimg;
}
/**
* Get the fringe index specified by the fringebits. If no index
* is available, try breaking down the bits into contiguous regions of