Mercurial > hg > release > icedtea7-forest-2.3 > jdk
changeset 3420:33a0f66771d5
6635462: D3D: REGRESSION: XOR rendering is extremly slow
Reviewed-by: igor, prr
author | jgodinez |
---|---|
date | Fri, 17 Dec 2010 09:39:54 -0800 |
parents | 6a219e5ccfd7 |
children | 0125062d65b6 |
files | src/share/classes/javax/swing/DefaultDesktopManager.java src/windows/classes/sun/awt/windows/WComponentPeer.java src/windows/classes/sun/java2d/d3d/D3DSurfaceData.java |
diffstat | 3 files changed, 89 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/javax/swing/DefaultDesktopManager.java Fri Dec 17 13:18:08 2010 +0300 +++ b/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/src/windows/classes/sun/awt/windows/WComponentPeer.java Fri Dec 17 13:18:08 2010 +0300 +++ b/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/src/windows/classes/sun/java2d/d3d/D3DSurfaceData.java Fri Dec 17 13:18:08 2010 +0300 +++ b/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"+