--- a/jdk/src/share/classes/javax/swing/DefaultDesktopManager.java Fri Dec 17 13:18:08 2010 +0300
+++ b/jdk/src/share/classes/javax/swing/DefaultDesktopManager.java Fri Dec 17 09:39:54 2010 -0800
@@ -359,7 +359,22 @@
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();
}
} else if (dragMode == FASTER_DRAG_MODE) {
@@ -412,7 +427,14 @@
g.drawRect( currentBounds.x, currentBounds.y, currentBounds.width-1, currentBounds.height-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.dispose();
}
--- a/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java Fri Dec 17 13:18:08 2010 +0300
+++ b/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java Fri Dec 17 09:39:54 2010 -0800
@@ -999,6 +999,8 @@
public void setBoundsOperation(int operation) {
}
+ private volatile boolean isAccelCapable = true;
+
/**
* Returns whether this component is capable of being hw accelerated.
* More specifically, whether rendering to this component or a
@@ -1009,11 +1011,22 @@
* {@link GraphicsDevice.WindowTranslucency#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
* accelerated, {@code false} otherwise
* @see GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT
*/
public boolean isAccelCapable() {
+ if (!isAccelCapable ||
+ !isContainingTopLevelAccelCapable((Component)target))
+ {
+ return false;
+ }
+
boolean isTranslucent =
SunToolkit.isContainingTopLevelTranslucent((Component)target);
// D3D/OGL and translucent windows interacted poorly in Windows XP;
@@ -1021,6 +1034,14 @@
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,
Region region);
--- a/jdk/src/windows/classes/sun/java2d/d3d/D3DSurfaceData.java Fri Dec 17 13:18:08 2010 +0300
+++ b/jdk/src/windows/classes/sun/java2d/d3d/D3DSurfaceData.java Fri Dec 17 09:39:54 2010 -0800
@@ -437,6 +437,10 @@
protected int getElem(final int x, final int y,
final SurfaceData sData)
{
+ if (sData.isSurfaceLost()) {
+ return 0;
+ }
+
int retPixel;
D3DRenderQueue rq = D3DRenderQueue.getInstance();
rq.lock();
@@ -456,6 +460,10 @@
protected void setElem(final int x, final int y, final int pixel,
final SurfaceData sData)
{
+ if (sData.isSurfaceLost()) {
+ return;
+ }
+
D3DRenderQueue rq = D3DRenderQueue.getInstance();
rq.lock();
try {
@@ -512,15 +520,32 @@
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) {
TextPipe textpipe;
boolean validated = false;
// 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) {
super.validatePipe(sg2d);
sg2d.imagepipe = d3dImagePipe;
+ disableAccelerationForSurface();
return;
}
@@ -895,7 +920,25 @@
}
@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
void restoreSurface() {
+ if (!peer.isAccelCapable()) {
+ throw new InvalidPipeException("Onscreen acceleration " +
+ "disabled for this surface");
+ }
Window fsw = graphicsDevice.getFullScreenWindow();
if (fsw != null && fsw != peer.getTarget()) {
throw new InvalidPipeException("Can't restore onscreen surface"+