/* * This file is modified by Ivan Maidanski <ivmai@ivmaisoft.com> * Project name: JCGO-SUNAWT (http://www.ivmaisoft.com/jcgo/) */ /* * @(#)WVolatileImage.java 1.14 03/01/23 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package sun.awt.windows; import java.awt.*; import java.awt.image.BufferedImage; import sun.java2d.SunGraphics2D; import sun.java2d.SurfaceData; import sun.awt.image.BufImgSurfaceData; import sun.awt.image.SunVolatileImage; import sun.awt.Win32GraphicsEnvironment; import java.awt.image.ColorModel; import java.awt.image.IndexColorModel; import sun.awt.Win32GraphicsConfig; import sun.awt.DisplayChangedListener; /** * Windows platform implementation of the VolatileImage class. * This implementation has to handle the case of surfaceLoss due * to displayChange or other events. The class attempts to create * and use a hardware-based surfaceData object (Win32OffScreenSurfaceData). * If this object cannot be created or re-created as necessary, the * class falls back to a software-based SurfaceData object * (BufImgSurfaceData) that will be used until the hardware-based * surfaceData can be restored. */ public class WVolatileImage extends SunVolatileImage implements DisplayChangedListener { static { // Default value of accelerationEnabled set in SunVolatileImage // Override here based on system properties String noddraw = (String) java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("sun.java2d.noddraw")); String ddoffscreenProp = (String) java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("sun.java2d.ddoffscreen")); boolean ddoffscreenDisable = (ddoffscreenProp != null && (ddoffscreenProp.equals("false") || ddoffscreenProp.equals("f"))); if ((noddraw != null) || ddoffscreenDisable || (ddoffscreenProp == null && getOsMajorVer() >= 6)) { accelerationEnabled = false; } } private static int getOsMajorVer() { try { String ver = System.getProperty("os.version"); int pos; if (ver != null && (pos = ver.indexOf('.')) > 0) return Integer.parseInt(ver.substring(0, pos)); } catch (SecurityException e) { } catch (NumberFormatException e) { } return -1; } /** * Called by constuctors to initialize common functionality */ private void initialize() { ((Win32GraphicsEnvironment)GraphicsEnvironment.getLocalGraphicsEnvironment()).addDisplayChangedListener(this); } /** * Constructor for win32-based VolatileImage using Component */ public WVolatileImage(Component c, int width, int height) { super(c, width, height); initialize(); } /** * Constructor for win32-based VolatileImage using Component */ public WVolatileImage(Component c, int width, int height, Object context) { super(c, width, height, context); initialize(); } /** * Constructor for win32-based VolatileImage using GraphicsConfiguration */ public WVolatileImage(GraphicsConfiguration graphicsConfig, int width, int height) { super(graphicsConfig, width, height); initialize(); } protected Win32OffScreenSurfaceData createHWData() { ColorModel cm = getDeviceColorModel(); return (Win32OffScreenSurfaceData) Win32OffScreenSurfaceData.createData(getWidth(), getHeight(), cm, graphicsConfig, this, Transparency.OPAQUE); } /** * Create a vram-based surfaceData object */ public void initAcceleratedBackground() { try { surfaceDataHw = createHWData(); if (surfaceDataHw != null) { surfaceData = surfaceDataHw; initContents(); return; } } catch (sun.java2d.InvalidPipeException e) { // Problems during creation. Don't propagate the exception, just // set the hardware surface data to null; the software surface // data will be used in the meantime surfaceDataHw = null; } surfaceData = getSurfaceDataSw(); } /** * Called from Win32OffScreenSurfaceData to notify us that our * accelerated surface has been lost. */ public SurfaceData restoreContents() { if (accelerationEnabled) { surfaceLossHw = true; surfaceLoss = true; } return super.restoreContents(); } protected ColorModel getDeviceColorModel() { if (comp != null) { Win32GraphicsConfig gc = (Win32GraphicsConfig)comp.getGraphicsConfiguration(); return gc.getDeviceColorModel(); } else { return ((Win32GraphicsConfig)graphicsConfig).getDeviceColorModel(); } } /** * Called from superclass to force restoration of this surface * during the validation process. The method calls into the * hardware surfaceData object to force the restore. */ protected void restoreSurfaceDataHw() { ((Win32OffScreenSurfaceData)surfaceDataHw).restoreSurface(); } /** * Called from Win32GraphicsEnv when there has been a display mode change. * Note that we simply invalidate hardware surfaces here; we do not * attempt to recreate or re-render them. This is to avoid doing * rendering operations on the AWT-Windows thread, which tends to * get into deadlock states with the rendering thread. Instead, * we just nullify the old surface data object and wait for a future * method in the rendering process to recreate the surface. */ public void displayChanged() { if (!accelerationEnabled) { return; } surfaceLoss = true; surfaceLossHw = true; if (surfaceDataHw != null) { // First, nullify the software surface. This guards against // using a surfaceData that was created in a different // display mode. surfaceDataSw = null; surfaceData = getSurfaceDataSw(); // Now, invalidate the old hardware-based surfaceData SurfaceData oldData = surfaceDataHw; surfaceDataHw = null; oldData.invalidate(); } // If we were created by a Component, get the new GC // associated with that object. Then we won't return // IMAGE_INCOMPATIBLE from our next validate() call. // 4636548: We need to reset graphicsConfig every time // through here, not just when surfaceDataHw is not null. if (comp != null) { graphicsConfig = comp.getGraphicsConfiguration(); } } /** * When device palette changes, need to force a new copy * of the image into our hardware cache to update the * color indices of the pixels (indexed mode only). */ public void paletteChanged() { surfaceLoss = true; } private class DDImageCaps extends DefaultImageCapabilities { private DDImageCaps() { } public boolean isTrueVolatile() { return isAccelerated(); } } /** * Returns an ImageCapabilities object which can be * inquired as to the specific capabilities of this * VolatileImage. This would allow programmers to find * out more runtime information on the specific VolatileImage * object that they have created. For example, the user * might create a VolatileImage but the system may have * no video memory left for creating an image of that * size, so although the object is a VolatileImage, it is * not as accelerated as other VolatileImage objects on * this platform might be. The user might want that * information to find other solutions to their problem. * @since 1.4 */ public ImageCapabilities getCapabilities() { if (accelerationEnabled) { if (!(imageCaps instanceof DDImageCaps)) { imageCaps = new DDImageCaps(); } } return super.getCapabilities(); } /** * Releases any associated hardware memory for this image by * calling flush on surfaceDataHw. This method forces a surfaceLoss * situation so any future operations on the image will need to * revalidate the image first. */ public void flush() { surfaceLoss = true; Win32OffScreenSurfaceData oldSD = (Win32OffScreenSurfaceData)surfaceDataHw; surfaceDataHw = null; if (oldSD != null) { oldSD.flush(); } } }