Reinstate the mask cache. We were spending about half our scene time making masks
git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@672 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
@@ -21,14 +21,6 @@
|
|||||||
|
|
||||||
package com.threerings.miso.client;
|
package com.threerings.miso.client;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.WeakHashMap;
|
|
||||||
|
|
||||||
import java.awt.AlphaComposite;
|
import java.awt.AlphaComposite;
|
||||||
import java.awt.BasicStroke;
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
@@ -48,6 +40,13 @@ import java.awt.event.ActionListener;
|
|||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.awt.event.MouseListener;
|
import java.awt.event.MouseListener;
|
||||||
import java.awt.event.MouseMotionListener;
|
import java.awt.event.MouseMotionListener;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
@@ -150,6 +149,7 @@ public class MisoScenePanel extends VirtualMediaPanel
|
|||||||
_blocks.clear();
|
_blocks.clear();
|
||||||
_vizobjs.clear();
|
_vizobjs.clear();
|
||||||
_fringes.clear();
|
_fringes.clear();
|
||||||
|
_masks.clear();
|
||||||
if (_dpanel != null) {
|
if (_dpanel != null) {
|
||||||
_dpanel.newScene();
|
_dpanel.newScene();
|
||||||
}
|
}
|
||||||
@@ -370,9 +370,9 @@ public class MisoScenePanel extends VirtualMediaPanel
|
|||||||
for (SceneBlock block : _blocks.values()) {
|
for (SceneBlock block : _blocks.values()) {
|
||||||
block.computeMemoryUsage(base, fringe, object, usage);
|
block.computeMemoryUsage(base, fringe, object, usage);
|
||||||
}
|
}
|
||||||
log.info("Scene tile memory usage",
|
log.info("Scene tile memory usage",
|
||||||
"scene", StringUtil.shortClassName(this),
|
"scene", StringUtil.shortClassName(this),
|
||||||
"base", base.size() + "->" + (usage[0] / 1024) + "k",
|
"base", base.size() + "->" + (usage[0] / 1024) + "k",
|
||||||
"fringe", fringe.size() + "->" + (usage[1] / 1024) + "k",
|
"fringe", fringe.size() + "->" + (usage[1] / 1024) + "k",
|
||||||
"obj", object.size() + "->" + (usage[2] / 1024) + "k");
|
"obj", object.size() + "->" + (usage[2] / 1024) + "k");
|
||||||
}
|
}
|
||||||
@@ -479,7 +479,7 @@ public class MisoScenePanel extends VirtualMediaPanel
|
|||||||
|
|
||||||
// make the menu surround the clicked object, but with consistent size
|
// make the menu surround the clicked object, but with consistent size
|
||||||
Rectangle mbounds = getRadialMenuBounds(scobj);
|
Rectangle mbounds = getRadialMenuBounds(scobj);
|
||||||
|
|
||||||
_activeMenu = menu;
|
_activeMenu = menu;
|
||||||
_activeMenu.addActionListener(new ActionListener() {
|
_activeMenu.addActionListener(new ActionListener() {
|
||||||
public void actionPerformed (ActionEvent e) {
|
public void actionPerformed (ActionEvent e) {
|
||||||
@@ -515,7 +515,7 @@ public class MisoScenePanel extends VirtualMediaPanel
|
|||||||
}
|
}
|
||||||
return mbounds;
|
return mbounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the size of the rectangle around which we create an
|
* Returns the size of the rectangle around which we create an
|
||||||
* object's radial menu. The default is a sensible size, but derived
|
* object's radial menu. The default is a sensible size, but derived
|
||||||
@@ -874,7 +874,7 @@ public class MisoScenePanel extends VirtualMediaPanel
|
|||||||
* Configures <code>influentialBounds</code> to contain the bounds of the potentially
|
* Configures <code>influentialBounds</code> to contain the bounds of the potentially
|
||||||
* "influential" world and <code>visibleBlockBounds</code> to contain bounds that are used to
|
* "influential" world and <code>visibleBlockBounds</code> to contain bounds that are used to
|
||||||
* determine which blocks should be resolved before making the view visible.
|
* determine which blocks should be resolved before making the view visible.
|
||||||
*
|
*
|
||||||
* <p> Everything that intersects the influential area will be resolved on the expectation
|
* <p> Everything that intersects the influential area will be resolved on the expectation
|
||||||
* that it could be scrolled into view at any time. The influential bounds should be large
|
* that it could be scrolled into view at any time. The influential bounds should be large
|
||||||
* enough that the time between a block becoming influential and the time at which it is
|
* enough that the time between a block becoming influential and the time at which it is
|
||||||
@@ -890,7 +890,7 @@ public class MisoScenePanel extends VirtualMediaPanel
|
|||||||
influentualBounds.setBounds(visibleBounds.x - infborx, visibleBounds.y - infbory,
|
influentualBounds.setBounds(visibleBounds.x - infborx, visibleBounds.y - infbory,
|
||||||
visibleBounds.width + 2 * infborx, visibleBounds.height + 3 * infbory);
|
visibleBounds.width + 2 * infborx, visibleBounds.height + 3 * infbory);
|
||||||
visibleBlockBounds.setBounds(visibleBounds.x - visibleBounds.width / 4,
|
visibleBlockBounds.setBounds(visibleBounds.x - visibleBounds.width / 4,
|
||||||
visibleBounds.y, visibleBounds.width + visibleBounds.width / 2,
|
visibleBounds.y, visibleBounds.width + visibleBounds.width / 2,
|
||||||
visibleBounds.height + infbory);
|
visibleBounds.height + infbory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -922,7 +922,7 @@ public class MisoScenePanel extends VirtualMediaPanel
|
|||||||
if (_dpanel != null) {
|
if (_dpanel != null) {
|
||||||
_dpanel.blockCleared(block);
|
_dpanel.blockCleared(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
blockFinished(block);
|
blockFinished(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -947,7 +947,7 @@ public class MisoScenePanel extends VirtualMediaPanel
|
|||||||
_remgr.invalidateRegion(sbounds);
|
_remgr.invalidateRegion(sbounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
blockFinished(block);
|
blockFinished(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1007,10 +1007,10 @@ public class MisoScenePanel extends VirtualMediaPanel
|
|||||||
|
|
||||||
// see which of this block's objects are visible
|
// see which of this block's objects are visible
|
||||||
SceneObject[] objs = block.getObjects();
|
SceneObject[] objs = block.getObjects();
|
||||||
for (int ii = 0; ii < objs.length; ii++) {
|
for (SceneObject obj : objs) {
|
||||||
if (objs[ii].bounds != null &&
|
if (obj.bounds != null &&
|
||||||
vbounds.intersects(objs[ii].bounds)) {
|
vbounds.intersects(obj.bounds)) {
|
||||||
_vizobjs.add(objs[ii]);
|
_vizobjs.add(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1228,7 +1228,7 @@ public class MisoScenePanel extends VirtualMediaPanel
|
|||||||
}
|
}
|
||||||
super.paint(g);
|
super.paint(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintInFront (Graphics2D gfx, Rectangle dirty)
|
protected void paintInFront (Graphics2D gfx, Rectangle dirty)
|
||||||
{
|
{
|
||||||
@@ -1337,7 +1337,7 @@ public class MisoScenePanel extends VirtualMediaPanel
|
|||||||
{
|
{
|
||||||
// make sure the indicators are ready
|
// make sure the indicators are ready
|
||||||
if (!_indicatorsLaidOut) {
|
if (!_indicatorsLaidOut) {
|
||||||
List<Rectangle> boundaries = Lists.newArrayList();
|
List<Rectangle> boundaries = Lists.newArrayList();
|
||||||
for (Map.Entry<SceneObject, SceneObjectIndicator> entry : _indicators.entrySet()) {
|
for (Map.Entry<SceneObject, SceneObjectIndicator> entry : _indicators.entrySet()) {
|
||||||
entry.getValue().layout(gfx, entry.getKey(), _vbounds, boundaries);
|
entry.getValue().layout(gfx, entry.getKey(), _vbounds, boundaries);
|
||||||
dirtyIndicator(entry.getValue());
|
dirtyIndicator(entry.getValue());
|
||||||
@@ -1415,7 +1415,8 @@ public class MisoScenePanel extends VirtualMediaPanel
|
|||||||
/** Computes the fringe tile for the specified coordinate. */
|
/** Computes the fringe tile for the specified coordinate. */
|
||||||
protected BaseTile computeFringeTile (int tx, int ty)
|
protected BaseTile computeFringeTile (int tx, int ty)
|
||||||
{
|
{
|
||||||
return _ctx.getTileManager().getAutoFringer().getFringeTile(_model, tx, ty, _fringes);
|
return _ctx.getTileManager().getAutoFringer().getFringeTile(_model, tx, ty, _fringes,
|
||||||
|
_masks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1563,6 +1564,11 @@ public class MisoScenePanel extends VirtualMediaPanel
|
|||||||
/** A list of the potentially visible objects in the scene. */
|
/** A list of the potentially visible objects in the scene. */
|
||||||
protected List<SceneObject> _vizobjs = Lists.newArrayList();
|
protected List<SceneObject> _vizobjs = Lists.newArrayList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map of the masks used to calculate fringes in this scene.
|
||||||
|
*/
|
||||||
|
protected Map<Long, BufferedImage> _masks = Maps.newHashMap();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map of active fringe tiles. Scene blocks have hard references to fringe tiles in this map
|
* Map of active fringe tiles. Scene blocks have hard references to fringe tiles in this map
|
||||||
* for the tiles they're using, so the blocks coming in and out of the influential bounds
|
* for the tiles they're using, so the blocks coming in and out of the influential bounds
|
||||||
@@ -1616,7 +1622,7 @@ public class MisoScenePanel extends VirtualMediaPanel
|
|||||||
|
|
||||||
/** The scene block resolver for this scene panel's context. */
|
/** The scene block resolver for this scene panel's context. */
|
||||||
protected SceneBlockResolver _resolver;
|
protected SceneBlockResolver _resolver;
|
||||||
|
|
||||||
/** Scene block resolvers shared by all scene panels in a context. */
|
/** Scene block resolvers shared by all scene panels in a context. */
|
||||||
protected static Map<MisoContext, SceneBlockResolver> _resolvers =
|
protected static Map<MisoContext, SceneBlockResolver> _resolvers =
|
||||||
new WeakHashMap<MisoContext, SceneBlockResolver>();
|
new WeakHashMap<MisoContext, SceneBlockResolver>();
|
||||||
@@ -1624,7 +1630,7 @@ public class MisoScenePanel extends VirtualMediaPanel
|
|||||||
// used to display debugging information on scene block resolution
|
// used to display debugging information on scene block resolution
|
||||||
protected JFrame _dframe;
|
protected JFrame _dframe;
|
||||||
protected ResolutionView _dpanel;
|
protected ResolutionView _dpanel;
|
||||||
|
|
||||||
protected TileOpApplicator _applicator;
|
protected TileOpApplicator _applicator;
|
||||||
|
|
||||||
/** A debug hook that toggles debug rendering of traversable tiles. */
|
/** A debug hook that toggles debug rendering of traversable tiles. */
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ public class AutoFringer
|
|||||||
* Compute and return the fringe tile to be inserted at the specified location.
|
* Compute and return the fringe tile to be inserted at the specified location.
|
||||||
*/
|
*/
|
||||||
public BaseTile getFringeTile (MisoSceneModel scene, int col, int row,
|
public BaseTile getFringeTile (MisoSceneModel scene, int col, int row,
|
||||||
Map<FringeTile, WeakReference<FringeTile>> fringes)
|
Map<FringeTile, WeakReference<FringeTile>> fringes, Map<Long, BufferedImage> masks)
|
||||||
{
|
{
|
||||||
// get the tileset id of the base tile we are considering
|
// get the tileset id of the base tile we are considering
|
||||||
int underset = adjustTileSetId(scene.getBaseTileId(col, row) >> 16);
|
int underset = adjustTileSetId(scene.getBaseTileId(col, row) >> 16);
|
||||||
@@ -180,14 +180,15 @@ public class AutoFringer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return composeFringeTile(frecs, fringes, TileUtil.getTileHash(col, row), passable);
|
return composeFringeTile(frecs, fringes, TileUtil.getTileHash(col, row), passable, masks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compose a FringeTile out of the various fringe images needed.
|
* Compose a FringeTile out of the various fringe images needed.
|
||||||
*/
|
*/
|
||||||
protected FringeTile composeFringeTile (FringerRec[] fringers,
|
protected FringeTile composeFringeTile (FringerRec[] fringers,
|
||||||
Map<FringeTile, WeakReference<FringeTile>> fringes, int hashValue, boolean passable)
|
Map<FringeTile, WeakReference<FringeTile>> fringes, int hashValue, boolean passable,
|
||||||
|
Map<Long, BufferedImage> masks)
|
||||||
{
|
{
|
||||||
// sort the array so that higher priority fringers get drawn first
|
// sort the array so that higher priority fringers get drawn first
|
||||||
QuickSort.sort(fringers);
|
QuickSort.sort(fringers);
|
||||||
@@ -195,15 +196,15 @@ public class AutoFringer
|
|||||||
// Generate an identifier for the fringe tile being created as an array of the keys of its
|
// Generate an identifier for the fringe tile being created as an array of the keys of its
|
||||||
// component tiles in the order they'll be drawn in the fringe tile.
|
// component tiles in the order they'll be drawn in the fringe tile.
|
||||||
List<Long> keys = Lists.newArrayList();
|
List<Long> keys = Lists.newArrayList();
|
||||||
for (int ii = 0; ii < fringers.length; ii++) {
|
for (FringerRec fringer : fringers) {
|
||||||
int[] indexes = getFringeIndexes(fringers[ii].bits);
|
int[] indexes = getFringeIndexes(fringer.bits);
|
||||||
FringeConfiguration.FringeTileSetRecord tsr = _fringeconf.getFringe(
|
FringeConfiguration.FringeTileSetRecord tsr = _fringeconf.getFringe(
|
||||||
fringers[ii].baseset, hashValue);
|
fringer.baseset, hashValue);
|
||||||
int fringeset = tsr.fringe_tsid;
|
int fringeset = tsr.fringe_tsid;
|
||||||
for (int jj = 0; jj < indexes.length; jj++) {
|
for (int index : indexes) {
|
||||||
// Add a key for this tile as a long containing its base tile, the fringe set it's
|
// Add a key for this tile as a long containing its base tile, the fringe set it's
|
||||||
// working with and the index used in that set.
|
// working with and the index used in that set.
|
||||||
keys.add((((long)fringers[ii].baseset) << 32) + (fringeset << 16) + indexes[jj]);
|
keys.add((((long)fringer.baseset) << 32) + (fringeset << 16) + index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
long[] fringeId = new long[keys.size()];
|
long[] fringeId = new long[keys.size()];
|
||||||
@@ -224,13 +225,13 @@ public class AutoFringer
|
|||||||
|
|
||||||
// There's no fringe with he same identifier, so we need to create the tile.
|
// There's no fringe with he same identifier, so we need to create the tile.
|
||||||
BufferedImage img = null;
|
BufferedImage img = null;
|
||||||
for (int ii = 0; ii < fringers.length; ii++) {
|
for (FringerRec fringer : fringers) {
|
||||||
int[] indexes = getFringeIndexes(fringers[ii].bits);
|
int[] indexes = getFringeIndexes(fringer.bits);
|
||||||
FringeConfiguration.FringeTileSetRecord tsr = _fringeconf.getFringe(
|
FringeConfiguration.FringeTileSetRecord tsr = _fringeconf.getFringe(
|
||||||
fringers[ii].baseset, hashValue);
|
fringer.baseset, hashValue);
|
||||||
for (int jj = 0; jj < indexes.length; jj++) {
|
for (int index : indexes) {
|
||||||
try {
|
try {
|
||||||
img = getTileImage(img, tsr, fringers[ii].baseset, indexes[jj], hashValue);
|
img = getTileImage(img, tsr, fringer.baseset, index, hashValue, masks);
|
||||||
} catch (NoSuchTileSetException nstse) {
|
} catch (NoSuchTileSetException nstse) {
|
||||||
log.warning("Autofringer couldn't find a needed tileset", nstse);
|
log.warning("Autofringer couldn't find a needed tileset", nstse);
|
||||||
}
|
}
|
||||||
@@ -245,7 +246,8 @@ public class AutoFringer
|
|||||||
* Retrieve or compose an image for the specified fringe.
|
* Retrieve or compose an image for the specified fringe.
|
||||||
*/
|
*/
|
||||||
protected BufferedImage getTileImage (BufferedImage img,
|
protected BufferedImage getTileImage (BufferedImage img,
|
||||||
FringeConfiguration.FringeTileSetRecord tsr, int baseset, int index, int hashValue)
|
FringeConfiguration.FringeTileSetRecord tsr, int baseset, int index, int hashValue,
|
||||||
|
Map<Long, BufferedImage> masks)
|
||||||
throws NoSuchTileSetException
|
throws NoSuchTileSetException
|
||||||
{
|
{
|
||||||
int fringeset = tsr.fringe_tsid;
|
int fringeset = tsr.fringe_tsid;
|
||||||
@@ -257,9 +259,14 @@ public class AutoFringer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, it's a mask..
|
// otherwise, it's a mask..
|
||||||
BufferedImage fsrc = _tmgr.getTileSet(fringeset).getRawTileImage(index);
|
Long maskkey = Long.valueOf((((long)baseset) << 32) + (fringeset << 16) + index);
|
||||||
BufferedImage bsrc = _tmgr.getTileSet(baseset).getRawTileImage(0);
|
BufferedImage mask = masks.get(maskkey);
|
||||||
BufferedImage mask = ImageUtil.composeMaskedImage(_imgr, fsrc, bsrc);
|
if (mask == null) {
|
||||||
|
BufferedImage fsrc = _tmgr.getTileSet(fringeset).getRawTileImage(index);
|
||||||
|
BufferedImage bsrc = _tmgr.getTileSet(baseset).getRawTileImage(0);
|
||||||
|
mask = ImageUtil.composeMaskedImage(_imgr, fsrc, bsrc);
|
||||||
|
masks.put(maskkey, mask);
|
||||||
|
}
|
||||||
|
|
||||||
return stampTileImage(mask, img, mask.getWidth(null), mask.getHeight(null));
|
return stampTileImage(mask, img, mask.getWidth(null), mask.getHeight(null));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user