diff options
Diffstat (limited to 'src/windows/classes/sun/java2d/d3d/D3DVolatileSurfaceManager.java')
-rw-r--r-- | src/windows/classes/sun/java2d/d3d/D3DVolatileSurfaceManager.java | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/src/windows/classes/sun/java2d/d3d/D3DVolatileSurfaceManager.java b/src/windows/classes/sun/java2d/d3d/D3DVolatileSurfaceManager.java new file mode 100644 index 000000000..3dcf99b4c --- /dev/null +++ b/src/windows/classes/sun/java2d/d3d/D3DVolatileSurfaceManager.java @@ -0,0 +1,230 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.java2d.d3d; + +import java.awt.Component; +import java.awt.GraphicsConfiguration; +import java.awt.Image; +import java.awt.Transparency; +import java.awt.image.ColorModel; +import sun.awt.Win32GraphicsConfig; +import sun.awt.image.SunVolatileImage; +import sun.awt.image.SurfaceManager; +import sun.awt.image.VolatileSurfaceManager; +import sun.awt.windows.WComponentPeer; +import sun.java2d.InvalidPipeException; +import sun.java2d.SurfaceData; +import static sun.java2d.pipe.hw.AccelSurface.*; +import static sun.java2d.d3d.D3DContext.D3DContextCaps.*; +import sun.java2d.windows.GDIWindowSurfaceData; + +public class D3DVolatileSurfaceManager + extends VolatileSurfaceManager +{ + private boolean accelerationEnabled; + private int restoreCountdown; + + public D3DVolatileSurfaceManager(SunVolatileImage vImg, Object context) { + super(vImg, context); + + /* + * We will attempt to accelerate this image only under the + * following conditions: + * - the image is opaque OR + * - the image is translucent AND + * - the GraphicsConfig supports the FBO extension OR + * - the GraphicsConfig has a stored alpha channel + */ + int transparency = vImg.getTransparency(); + D3DGraphicsDevice gd = (D3DGraphicsDevice) + vImg.getGraphicsConfig().getDevice(); + accelerationEnabled = + (transparency == Transparency.OPAQUE) || + (transparency == Transparency.TRANSLUCENT && + (gd.isCapPresent(CAPS_RT_PLAIN_ALPHA) || + gd.isCapPresent(CAPS_RT_TEXTURE_ALPHA))); + } + + protected boolean isAccelerationEnabled() { + return accelerationEnabled; + } + public void setAccelerationEnabled(boolean accelerationEnabled) { + this.accelerationEnabled = accelerationEnabled; + } + + /** + * Create a pbuffer-based SurfaceData object (or init the backbuffer + * of an existing window if this is a double buffered GraphicsConfig). + */ + protected SurfaceData initAcceleratedSurface() { + SurfaceData sData; + Component comp = vImg.getComponent(); + WComponentPeer peer = + (comp != null) ? (WComponentPeer)comp.getPeer() : null; + + try { + boolean forceback = false; + if (context instanceof Boolean) { + forceback = ((Boolean)context).booleanValue(); + } + + if (forceback) { + // peer must be non-null in this case + sData = D3DSurfaceData.createData(peer, vImg); + } else { + D3DGraphicsConfig gc = + (D3DGraphicsConfig)vImg.getGraphicsConfig(); + ColorModel cm = gc.getColorModel(vImg.getTransparency()); + int type = vImg.getForcedAccelSurfaceType(); + // if acceleration type is forced (type != UNDEFINED) then + // use the forced type, otherwise use RT_TEXTURE + if (type == UNDEFINED) { + type = RT_TEXTURE; + } + sData = D3DSurfaceData.createData(gc, + vImg.getWidth(), + vImg.getHeight(), + cm, vImg, + type); + } + } catch (NullPointerException ex) { + sData = null; + } catch (OutOfMemoryError er) { + sData = null; + } catch (InvalidPipeException ipe) { + sData = null; + } + + return sData; + } + + protected boolean isConfigValid(GraphicsConfiguration gc) { + return ((gc == null) || (gc == vImg.getGraphicsConfig())); + } + + /** + * Set the number of iterations for restoreAcceleratedSurface to fail + * before attempting to restore the accelerated surface. + * + * @see #restoreAcceleratedSurface + * @see #handleVItoScreenOp + */ + private synchronized void setRestoreCountdown(int count) { + restoreCountdown = count; + } + + /** + * Note that we create a new surface instead of restoring + * an old one. This will help with D3DContext revalidation. + */ + @Override + protected void restoreAcceleratedSurface() { + synchronized (this) { + if (restoreCountdown > 0) { + restoreCountdown--; + throw new + InvalidPipeException("Will attempt to restore surface " + + " in " + restoreCountdown); + } + } + + SurfaceData sData = initAcceleratedSurface(); + if (sData != null) { + sdAccel = sData; + } else { + throw new InvalidPipeException("could not restore surface"); + // REMIND: alternatively, we could try this: +// ((D3DSurfaceData)sdAccel).restoreSurface(); + } + } + + /** + * We're asked to restore contents by the accelerated surface, which means + * that it had been lost. + */ + @Override + public SurfaceData restoreContents() { + acceleratedSurfaceLost(); + return super.restoreContents(); + } + + /** + * If the destination surface's peer can potentially handle accelerated + * on-screen rendering then it is likely that the condition which resulted + * in VI to Screen operation is temporary, so this method sets the + * restore countdown in hope that the on-screen accelerated rendering will + * resume. In the meantime the backup surface of the VISM will be used. + * + * The countdown is needed because otherwise we may never break out + * of "do { vi.validate()..} while(vi.lost)" loop since validate() could + * restore the source surface every time and it will get lost again on the + * next copy attempt, and we would never get a chance to use the backup + * surface. By using the countdown we allow the backup surface to be used + * while the screen surface gets sorted out, or if it for some reason can + * never be restored. + * + * If the destination surface's peer could never do accelerated onscreen + * rendering then the acceleration for the SurfaceManager associated with + * the source surface is disabled forever. + */ + static void handleVItoScreenOp(SurfaceData src, SurfaceData dst) { + if (src instanceof D3DSurfaceData && + dst instanceof GDIWindowSurfaceData) + { + D3DSurfaceData d3dsd = (D3DSurfaceData)src; + SurfaceManager mgr = + SurfaceManager.getManager((Image)d3dsd.getDestination()); + if (mgr instanceof D3DVolatileSurfaceManager) { + D3DVolatileSurfaceManager vsm = (D3DVolatileSurfaceManager)mgr; + if (vsm != null) { + d3dsd.setSurfaceLost(true); + + GDIWindowSurfaceData wsd = (GDIWindowSurfaceData)dst; + WComponentPeer p = wsd.getPeer(); + if (D3DScreenUpdateManager.canUseD3DOnScreen(p, + (Win32GraphicsConfig)p.getGraphicsConfiguration(), + p.getBackBuffersNum())) + { + // 10 is only chosen to be greater than the number of + // times a sane person would call validate() inside + // a validation loop, and to reduce thrashing between + // accelerated and backup surfaces + vsm.setRestoreCountdown(10); + } else { + vsm.setAccelerationEnabled(false); + } + } + } + } + } + + @Override + public void initContents() { + if (vImg.getForcedAccelSurfaceType() != TEXTURE) { + super.initContents(); + } + } +} |