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