The plot, she is thick. The Nenya framework supports a MediaOverlay that can
render sprites and animations over the top of everything in the frame: JComponents, MediaPanels anything we like. To support this, we have the MediaOverlay tell the ActiveRepaintManager when it has dirtied an area of the screen and it will mark that component as needing repainting. Peachy. However, if a component decides on its own that it needs repainting, we need to propagate that now dirty region up to the MediaOverlay so that it can repaint anything that's above the just-repainted component on the same frame tick. This also fixes a potential problem if a changed sprite dirties a component which then repaints itself but the bounds of that component overlapped some other sprite which was not going to be repainted on this tick. There were also potential problems if components were put in the JLayeredPane layers (which are "above" the normal components and MediaPanels but "below" the MediaOverlay). They too should now properly dirty regions in the overlay. It occurs to me though that if a MediaOverlay sprite is on top of a MediaPanel, the MediaPanel will probably not properly propagate its dirty region to the overlay because the MediaPanel is a frame participant, not a JComponent and its repainting is handled by the FrameManager not the ActiveRepaintManager. I may just use the sledgehammer approach and dirty in the media overlay the entire bounds of a frame participant if it paints anything on a frame rather than try to translated and propagate its underlying dirty regions up to the overlay. Oh the twisty maze of passages we've created in trying to create an active rendering system that works magically with Swing. git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@566 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
@@ -524,8 +524,8 @@ public abstract class FrameManager
|
||||
}
|
||||
}
|
||||
|
||||
// if we have a media overlay, give that a chance to propagate dirty regions to the active
|
||||
// repaint manager for areas it dirtied during this tick
|
||||
// if we have a media overlay, give that a chance to propagate its dirty regions to the
|
||||
// active repaint manager for areas it dirtied during this tick
|
||||
if (_overlay != null) {
|
||||
_overlay.propagateDirtyRegions(_repainter, _root.getRootPane());
|
||||
}
|
||||
@@ -561,6 +561,12 @@ public abstract class FrameManager
|
||||
renderLayer(g, bounds, lpane, clipped, JLayeredPane.POPUP_LAYER);
|
||||
renderLayer(g, bounds, lpane, clipped, JLayeredPane.DRAG_LAYER);
|
||||
}
|
||||
|
||||
// if we have a MediaOverlay, let it know that any sprites in this region need to be
|
||||
// repainted as the components beneath them have just been redrawn
|
||||
if (_overlay != null) {
|
||||
_overlay.addDirtyRegion(new Rectangle(bounds));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,6 +24,7 @@ package com.threerings.media;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.List;
|
||||
import javax.swing.JRootPane;
|
||||
|
||||
import com.threerings.media.animation.Animation;
|
||||
@@ -121,6 +122,15 @@ public class MediaOverlay
|
||||
_metamgr.clearAnimations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a dirty region to this overlay. Note: control of the rectangle is granted to our
|
||||
* underlying {@link RegionManager} which may bend, fold or mutilate it.
|
||||
*/
|
||||
public void addDirtyRegion (Rectangle rect)
|
||||
{
|
||||
_metamgr.getRegionManager().addDirtyRegion(rect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the {@link FrameManager} to propagate our dirty regions to the active repaint
|
||||
* manager so that it can repaint the underlying components just prior to our painting our
|
||||
@@ -130,13 +140,13 @@ public class MediaOverlay
|
||||
public void propagateDirtyRegions (ActiveRepaintManager repmgr, JRootPane root)
|
||||
{
|
||||
if (_metamgr.needsPaint()) {
|
||||
// this will clear out our dirty regions, so we need to keep these around for our
|
||||
// subsequent call to paint
|
||||
_dirty = _metamgr.getRegionManager().getDirtyRegions();
|
||||
for (int ii = 0; ii < _dirty.length; ii++) {
|
||||
Rectangle dirty = _dirty[ii];
|
||||
// tell the repaint manager about our raw (unmerged) dirty regions so that it can dirty
|
||||
// only components that are actually impacted
|
||||
List<Rectangle> dlist = _metamgr.getRegionManager().peekDirtyRegions();
|
||||
for (int ii = 0, ll = dlist.size(); ii < ll; ii++) {
|
||||
Rectangle dirty = dlist.get(ii);
|
||||
repmgr.addDirtyRegion(root, dirty.x - root.getX(), dirty.y - root.getY(),
|
||||
dirty.width, dirty.height);
|
||||
dirty.width, dirty.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -149,16 +159,17 @@ public class MediaOverlay
|
||||
*/
|
||||
public boolean paint (Graphics2D gfx)
|
||||
{
|
||||
if (_dirty != null) {
|
||||
for (int ii = 0; ii < _dirty.length; ii++) {
|
||||
gfx.setClip(_dirty[ii]);
|
||||
_metamgr.paintMedia(gfx, MediaConstants.BACK, _dirty[ii]);
|
||||
_metamgr.paintMedia(gfx, MediaConstants.FRONT, _dirty[ii]);
|
||||
}
|
||||
_dirty = null;
|
||||
return true;
|
||||
if (!_metamgr.getRegionManager().haveDirtyRegions()) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
Rectangle[] dirty = _metamgr.getRegionManager().getDirtyRegions();
|
||||
for (int ii = 0; ii < dirty.length; ii++) {
|
||||
gfx.setClip(dirty[ii]);
|
||||
_metamgr.paintMedia(gfx, MediaConstants.BACK, dirty[ii]);
|
||||
_metamgr.paintMedia(gfx, MediaConstants.FRONT, dirty[ii]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// from interface MediaHost
|
||||
|
||||
@@ -118,6 +118,16 @@ public class RegionManager
|
||||
return (_dirty.size() > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns our unmerged list of dirty regions. <em>Do not</em> modify the returned list. It's
|
||||
* just for peeking. Unlike {@link #getDirtyRegions}, this does not clear out the list of dirty
|
||||
* regions and prepare for the next frame.
|
||||
*/
|
||||
public List<Rectangle> peekDirtyRegions ()
|
||||
{
|
||||
return _dirty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges all outstanding dirty regions into a single list of rectangles and returns that to
|
||||
* the caller. Interally, the list of accumulated dirty regions is cleared out and prepared for
|
||||
|
||||
Reference in New Issue
Block a user