Path: blob/master/src/java.desktop/windows/classes/sun/java2d/d3d/D3DVolatileSurfaceManager.java
41159 views
/*1* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.java2d.d3d;2627import java.awt.Component;28import java.awt.GraphicsConfiguration;29import java.awt.Image;30import java.awt.Transparency;31import java.awt.image.ColorModel;3233import sun.awt.AWTAccessor;34import sun.awt.AWTAccessor.ComponentAccessor;35import sun.awt.Win32GraphicsConfig;36import sun.awt.image.SunVolatileImage;37import sun.awt.image.SurfaceManager;38import sun.awt.image.VolatileSurfaceManager;39import sun.awt.windows.WComponentPeer;40import sun.java2d.InvalidPipeException;41import sun.java2d.SurfaceData;42import static sun.java2d.pipe.hw.AccelSurface.*;43import static sun.java2d.d3d.D3DContext.D3DContextCaps.*;44import sun.java2d.windows.GDIWindowSurfaceData;4546public class D3DVolatileSurfaceManager47extends VolatileSurfaceManager48{49private boolean accelerationEnabled;50private int restoreCountdown;5152public D3DVolatileSurfaceManager(SunVolatileImage vImg, Object context) {53super(vImg, context);5455/*56* We will attempt to accelerate this image only under the57* following conditions:58* - the image is opaque OR59* - the image is translucent AND60* - the GraphicsConfig supports the FBO extension OR61* - the GraphicsConfig has a stored alpha channel62*/63int transparency = vImg.getTransparency();64D3DGraphicsDevice gd = (D3DGraphicsDevice)65vImg.getGraphicsConfig().getDevice();66accelerationEnabled =67(transparency == Transparency.OPAQUE) ||68(transparency == Transparency.TRANSLUCENT &&69(gd.isCapPresent(CAPS_RT_PLAIN_ALPHA) ||70gd.isCapPresent(CAPS_RT_TEXTURE_ALPHA)));71}7273protected boolean isAccelerationEnabled() {74return accelerationEnabled;75}76public void setAccelerationEnabled(boolean accelerationEnabled) {77this.accelerationEnabled = accelerationEnabled;78}7980/**81* Create a pbuffer-based SurfaceData object (or init the backbuffer82* of an existing window if this is a double buffered GraphicsConfig).83*/84protected SurfaceData initAcceleratedSurface() {85SurfaceData sData;86Component comp = vImg.getComponent();87final ComponentAccessor acc = AWTAccessor.getComponentAccessor();88WComponentPeer peer = (comp != null) ? acc.getPeer(comp) : null;8990try {91boolean forceback = false;92if (context instanceof Boolean) {93forceback = ((Boolean)context).booleanValue();94}9596if (forceback) {97// peer must be non-null in this case98sData = D3DSurfaceData.createData(peer, vImg);99} else {100D3DGraphicsConfig gc =101(D3DGraphicsConfig)vImg.getGraphicsConfig();102ColorModel cm = gc.getColorModel(vImg.getTransparency());103int type = vImg.getForcedAccelSurfaceType();104// if acceleration type is forced (type != UNDEFINED) then105// use the forced type, otherwise use RT_TEXTURE106if (type == UNDEFINED) {107type = RT_TEXTURE;108}109sData = D3DSurfaceData.createData(gc,110vImg.getWidth(),111vImg.getHeight(),112cm, vImg,113type);114}115} catch (NullPointerException ex) {116sData = null;117} catch (OutOfMemoryError er) {118sData = null;119} catch (InvalidPipeException ipe) {120sData = null;121}122123return sData;124}125126protected boolean isConfigValid(GraphicsConfiguration gc) {127return ((gc == null) || (gc == vImg.getGraphicsConfig()));128}129130/**131* Set the number of iterations for restoreAcceleratedSurface to fail132* before attempting to restore the accelerated surface.133*134* @see #restoreAcceleratedSurface135* @see #handleVItoScreenOp136*/137private synchronized void setRestoreCountdown(int count) {138restoreCountdown = count;139}140141/**142* Note that we create a new surface instead of restoring143* an old one. This will help with D3DContext revalidation.144*/145@Override146protected void restoreAcceleratedSurface() {147synchronized (this) {148if (restoreCountdown > 0) {149restoreCountdown--;150throw new151InvalidPipeException("Will attempt to restore surface " +152" in " + restoreCountdown);153}154}155156SurfaceData sData = initAcceleratedSurface();157if (sData != null) {158sdAccel = sData;159} else {160throw new InvalidPipeException("could not restore surface");161// REMIND: alternatively, we could try this:162// ((D3DSurfaceData)sdAccel).restoreSurface();163}164}165166/**167* We're asked to restore contents by the accelerated surface, which means168* that it had been lost.169*/170@Override171public SurfaceData restoreContents() {172acceleratedSurfaceLost();173return super.restoreContents();174}175176/**177* If the destination surface's peer can potentially handle accelerated178* on-screen rendering then it is likely that the condition which resulted179* in VI to Screen operation is temporary, so this method sets the180* restore countdown in hope that the on-screen accelerated rendering will181* resume. In the meantime the backup surface of the VISM will be used.182*183* The countdown is needed because otherwise we may never break out184* of "do { vi.validate()..} while(vi.lost)" loop since validate() could185* restore the source surface every time and it will get lost again on the186* next copy attempt, and we would never get a chance to use the backup187* surface. By using the countdown we allow the backup surface to be used188* while the screen surface gets sorted out, or if it for some reason can189* never be restored.190*191* If the destination surface's peer could never do accelerated onscreen192* rendering then the acceleration for the SurfaceManager associated with193* the source surface is disabled forever.194*/195static void handleVItoScreenOp(SurfaceData src, SurfaceData dst) {196if (src instanceof D3DSurfaceData &&197dst instanceof GDIWindowSurfaceData)198{199D3DSurfaceData d3dsd = (D3DSurfaceData)src;200SurfaceManager mgr =201SurfaceManager.getManager((Image)d3dsd.getDestination());202if (mgr instanceof D3DVolatileSurfaceManager) {203D3DVolatileSurfaceManager vsm = (D3DVolatileSurfaceManager)mgr;204if (vsm != null) {205d3dsd.setSurfaceLost(true);206207GDIWindowSurfaceData wsd = (GDIWindowSurfaceData)dst;208WComponentPeer p = wsd.getPeer();209if (D3DScreenUpdateManager.canUseD3DOnScreen(p,210(Win32GraphicsConfig)p.getGraphicsConfiguration(),211p.getBackBuffersNum()))212{213// 10 is only chosen to be greater than the number of214// times a sane person would call validate() inside215// a validation loop, and to reduce thrashing between216// accelerated and backup surfaces217vsm.setRestoreCountdown(10);218} else {219vsm.setAccelerationEnabled(false);220}221}222}223}224}225226@Override227public void initContents() {228if (vImg.getForcedAccelSurfaceType() != TEXTURE) {229super.initContents();230}231}232}233234235