aboutsummaryrefslogtreecommitdiff
path: root/src/windows/classes/sun/java2d/d3d/D3DVolatileSurfaceManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/windows/classes/sun/java2d/d3d/D3DVolatileSurfaceManager.java')
-rw-r--r--src/windows/classes/sun/java2d/d3d/D3DVolatileSurfaceManager.java230
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();
+ }
+ }
+}