6635462: D3D: REGRESSION: XOR rendering is extremly slow

Reviewed-by: igor, prr
This commit is contained in:
Jennifer Godinez 2010-12-17 09:39:54 -08:00
parent dbef654a2c
commit 33b174749a
3 changed files with 89 additions and 3 deletions

View File

@ -359,7 +359,22 @@ public class DefaultDesktopManager implements DesktopManager, java.io.Serializab
f.getWidth()-1, f.getHeight()-1); f.getWidth()-1, f.getHeight()-1);
} }
g.drawRect( newX, newY, f.getWidth()-1, f.getHeight()-1); g.drawRect( newX, newY, f.getWidth()-1, f.getHeight()-1);
currentLoc = new Point (newX, newY); /* Work around for 6635462: XOR mode may cause a SurfaceLost on first use.
* Swing doesn't expect that its XOR drawRect did
* not complete, so believes that on re-entering at
* the next update location, that there is an XOR rect
* to draw out at "currentLoc". But in fact
* its now got a new clean surface without that rect,
* so drawing it "out" in fact draws it on, leaving garbage.
* So only update/set currentLoc if the draw completed.
*/
sun.java2d.SurfaceData sData =
((sun.java2d.SunGraphics2D)g).getSurfaceData();
if (!sData.isSurfaceLost()) {
currentLoc = new Point (newX, newY);
}
;
g.dispose(); g.dispose();
} }
} else if (dragMode == FASTER_DRAG_MODE) { } else if (dragMode == FASTER_DRAG_MODE) {
@ -412,7 +427,14 @@ public class DefaultDesktopManager implements DesktopManager, java.io.Serializab
g.drawRect( currentBounds.x, currentBounds.y, currentBounds.width-1, currentBounds.height-1); g.drawRect( currentBounds.x, currentBounds.y, currentBounds.width-1, currentBounds.height-1);
} }
g.drawRect( newX, newY, newWidth-1, newHeight-1); g.drawRect( newX, newY, newWidth-1, newHeight-1);
currentBounds = new Rectangle (newX, newY, newWidth, newHeight);
// Work around for 6635462, see comment in dragFrame()
sun.java2d.SurfaceData sData =
((sun.java2d.SunGraphics2D)g).getSurfaceData();
if (!sData.isSurfaceLost()) {
currentBounds = new Rectangle (newX, newY, newWidth, newHeight);
}
g.setPaintMode(); g.setPaintMode();
g.dispose(); g.dispose();
} }

View File

@ -999,6 +999,8 @@ public abstract class WComponentPeer extends WObjectPeer
public void setBoundsOperation(int operation) { public void setBoundsOperation(int operation) {
} }
private volatile boolean isAccelCapable = true;
/** /**
* Returns whether this component is capable of being hw accelerated. * Returns whether this component is capable of being hw accelerated.
* More specifically, whether rendering to this component or a * More specifically, whether rendering to this component or a
@ -1009,11 +1011,22 @@ public abstract class WComponentPeer extends WObjectPeer
* {@link GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT * {@link GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT
* PERPIXEL_TRANSLUCENT}. * PERPIXEL_TRANSLUCENT}.
* *
* Another condition is if Xor paint mode was detected when rendering
* to an on-screen accelerated surface associated with this peer.
* in this case both on- and off-screen acceleration for this peer is
* disabled.
*
* @return {@code true} if this component is capable of being hw * @return {@code true} if this component is capable of being hw
* accelerated, {@code false} otherwise * accelerated, {@code false} otherwise
* @see GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT * @see GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT
*/ */
public boolean isAccelCapable() { public boolean isAccelCapable() {
if (!isAccelCapable ||
!isContainingTopLevelAccelCapable((Component)target))
{
return false;
}
boolean isTranslucent = boolean isTranslucent =
SunToolkit.isContainingTopLevelTranslucent((Component)target); SunToolkit.isContainingTopLevelTranslucent((Component)target);
// D3D/OGL and translucent windows interacted poorly in Windows XP; // D3D/OGL and translucent windows interacted poorly in Windows XP;
@ -1021,6 +1034,14 @@ public abstract class WComponentPeer extends WObjectPeer
return !isTranslucent || Win32GraphicsEnvironment.isVistaOS(); return !isTranslucent || Win32GraphicsEnvironment.isVistaOS();
} }
/**
* Disables acceleration for this peer.
*/
public void disableAcceleration() {
isAccelCapable = false;
}
native void setRectangularShape(int lox, int loy, int hix, int hiy, native void setRectangularShape(int lox, int loy, int hix, int hiy,
Region region); Region region);

View File

@ -437,6 +437,10 @@ public class D3DSurfaceData extends SurfaceData implements AccelSurface {
protected int getElem(final int x, final int y, protected int getElem(final int x, final int y,
final SurfaceData sData) final SurfaceData sData)
{ {
if (sData.isSurfaceLost()) {
return 0;
}
int retPixel; int retPixel;
D3DRenderQueue rq = D3DRenderQueue.getInstance(); D3DRenderQueue rq = D3DRenderQueue.getInstance();
rq.lock(); rq.lock();
@ -456,6 +460,10 @@ public class D3DSurfaceData extends SurfaceData implements AccelSurface {
protected void setElem(final int x, final int y, final int pixel, protected void setElem(final int x, final int y, final int pixel,
final SurfaceData sData) final SurfaceData sData)
{ {
if (sData.isSurfaceLost()) {
return;
}
D3DRenderQueue rq = D3DRenderQueue.getInstance(); D3DRenderQueue rq = D3DRenderQueue.getInstance();
rq.lock(); rq.lock();
try { try {
@ -512,15 +520,32 @@ public class D3DSurfaceData extends SurfaceData implements AccelSurface {
sg2d.surfaceData.getTransparency() == Transparency.OPAQUE; sg2d.surfaceData.getTransparency() == Transparency.OPAQUE;
} }
/**
* If acceleration should no longer be used for this surface.
* This implementation flags to the manager that it should no
* longer attempt to re-create a D3DSurface.
*/
void disableAccelerationForSurface() {
if (offscreenImage != null) {
SurfaceManager sm = SurfaceManager.getManager(offscreenImage);
if (sm instanceof D3DVolatileSurfaceManager) {
setSurfaceLost(true);
((D3DVolatileSurfaceManager)sm).setAccelerationEnabled(false);
}
}
}
public void validatePipe(SunGraphics2D sg2d) { public void validatePipe(SunGraphics2D sg2d) {
TextPipe textpipe; TextPipe textpipe;
boolean validated = false; boolean validated = false;
// REMIND: the D3D pipeline doesn't support XOR!, more // REMIND: the D3D pipeline doesn't support XOR!, more
// fixes will be needed below // fixes will be needed below. For now we disable D3D rendering
// for the surface which had any XOR rendering done to.
if (sg2d.compositeState >= sg2d.COMP_XOR) { if (sg2d.compositeState >= sg2d.COMP_XOR) {
super.validatePipe(sg2d); super.validatePipe(sg2d);
sg2d.imagepipe = d3dImagePipe; sg2d.imagepipe = d3dImagePipe;
disableAccelerationForSurface();
return; return;
} }
@ -894,8 +919,26 @@ public class D3DSurfaceData extends SurfaceData implements AccelSurface {
return peer.getTarget(); return peer.getTarget();
} }
@Override
void disableAccelerationForSurface() {
// for on-screen surfaces we need to make sure a backup GDI surface is
// is used until a new one is set (which may happen during a resize). We
// don't want the screen update maanger to replace the surface right way
// because it causes repainting issues in Swing, so we invalidate it,
// this will prevent SUM from issuing a replaceSurfaceData call.
setSurfaceLost(true);
invalidate();
flush();
peer.disableAcceleration();
ScreenUpdateManager.getInstance().dropScreenSurface(this);
}
@Override @Override
void restoreSurface() { void restoreSurface() {
if (!peer.isAccelCapable()) {
throw new InvalidPipeException("Onscreen acceleration " +
"disabled for this surface");
}
Window fsw = graphicsDevice.getFullScreenWindow(); Window fsw = graphicsDevice.getFullScreenWindow();
if (fsw != null && fsw != peer.getTarget()) { if (fsw != null && fsw != peer.getTarget()) {
throw new InvalidPipeException("Can't restore onscreen surface"+ throw new InvalidPipeException("Can't restore onscreen surface"+