290 lines · 10.9 KB · Java
RawDownload
/* * Copyright (c) 2003, 2007, Oracle and/or its affiliates. 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.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.awt.image; import java.awt.Color;import java.awt.GraphicsEnvironment;import java.awt.GraphicsConfiguration;import java.awt.Image;import java.awt.ImageCapabilities;import java.awt.image.BufferedImage;import java.util.concurrent.ConcurrentHashMap;import java.util.Iterator;import sun.java2d.SurfaceData;import sun.java2d.SurfaceDataProxy;import sun.java2d.loops.CompositeType; /** * The abstract base class that manages the various SurfaceData objects that * represent an Image's contents.  Subclasses can customize how the surfaces * are organized, whether to cache the original contents in an accelerated * surface, and so on. * <p> * The SurfaceManager also maintains an arbitrary "cache" mechanism which * allows other agents to store data in it specific to their use of this * image.  The most common use of the caching mechanism is for destination * SurfaceData objects to store cached copies of the source image. */public abstract class SurfaceManager {     public static abstract class ImageAccessor {        public abstract SurfaceManager getSurfaceManager(Image img);        public abstract void setSurfaceManager(Image img, SurfaceManager mgr);    }     private static ImageAccessor imgaccessor;     public static void setImageAccessor(ImageAccessor ia) {        if (imgaccessor != null) {            throw new InternalError("Attempt to set ImageAccessor twice");        }        imgaccessor = ia;    }     /**     * Returns the SurfaceManager object contained within the given Image.     */    public static SurfaceManager getManager(Image img) {        SurfaceManager sMgr = imgaccessor.getSurfaceManager(img);        if (sMgr == null) {            /*             * In practice only a BufferedImage will get here.             */            try {                BufferedImage bi = (BufferedImage) img;                sMgr = new BufImgSurfaceManager(bi);                setManager(bi, sMgr);            } catch (ClassCastException e) {                throw new IllegalArgumentException("Invalid Image variant");            }        }        return sMgr;    }     public static void setManager(Image img, SurfaceManager mgr) {        imgaccessor.setSurfaceManager(img, mgr);    }     private ConcurrentHashMap cacheMap;     /**     * Return an arbitrary cached object for an arbitrary cache key.     * Other objects can use this mechanism to store cached data about     * the source image that will let them save time when using or     * manipulating the image in the future.     * <p>     * Note that the cache is maintained as a simple Map with no     * attempts to keep it up to date or invalidate it so any data     * stored here must either not be dependent on the state of the     * image or it must be individually tracked to see if it is     * outdated or obsolete.     * <p>     * The SurfaceData object of the primary (destination) surface     * has a StateTracker mechanism which can help track the validity     * and "currentness" of any data stored here.     * For convenience and expediency an object stored as cached     * data may implement the FlushableCacheData interface specified     * below so that it may be notified immediately if the flush()     * method is ever called.     */    public Object getCacheData(Object key) {        return (cacheMap == null) ? null : cacheMap.get(key);    }     /**     * Store an arbitrary cached object for an arbitrary cache key.     * See the getCacheData() method for notes on tracking the     * validity of data stored using this mechanism.     */    public void setCacheData(Object key, Object value) {        if (cacheMap == null) {            synchronized (this) {                if (cacheMap == null) {                    cacheMap = new ConcurrentHashMap(2);                }            }        }        cacheMap.put(key, value);    }     /**     * Returns the main SurfaceData object that "owns" the pixels for     * this SurfaceManager.  This SurfaceData is used as the destination     * surface in a rendering operation and is the most authoritative     * storage for the current state of the pixels, though other     * versions might be cached in other locations for efficiency.     */    public abstract SurfaceData getPrimarySurfaceData();     /**     * Restores the primary surface being managed, and then returns the     * replacement surface.  This is called when an accelerated surface has     * been "lost", in an attempt to auto-restore its contents.     */    public abstract SurfaceData restoreContents();     /**     * Notification that any accelerated surfaces associated with this manager     * have been "lost", which might mean that they need to be manually     * restored or recreated.     *     * The default implementation does nothing, but platform-specific     * variants which have accelerated surfaces should perform any necessary     * actions.     */    public void acceleratedSurfaceLost() {}     /**     * Returns an ImageCapabilities object which can be     * inquired as to the specific capabilities of this     * Image.  The capabilities object will return true for     * isAccelerated() if the image has a current and valid     * SurfaceDataProxy object cached for the specified     * GraphicsConfiguration parameter.     * <p>     * This class provides a default implementation of the     * ImageCapabilities that will try to determine if there     * is an associated SurfaceDataProxy object and if it is     * up to date, but only works for GraphicsConfiguration     * objects which implement the ProxiedGraphicsConfig     * interface defined below.  In practice, all configs     * which can be accelerated are currently implementing     * that interface.     * <p>     * A null GraphicsConfiguration returns a value based on whether the     * image is currently accelerated on its default GraphicsConfiguration.     *     * @see java.awt.Image#getCapabilities     * @since 1.5     */    public ImageCapabilities getCapabilities(GraphicsConfiguration gc) {        return new ImageCapabilitiesGc(gc);    }     class ImageCapabilitiesGc extends ImageCapabilities {        GraphicsConfiguration gc;         public ImageCapabilitiesGc(GraphicsConfiguration gc) {            super(false);            this.gc = gc;        }         public boolean isAccelerated() {            // Note that when img.getAccelerationPriority() gets set to 0            // we remove SurfaceDataProxy objects from the cache and the            // answer will be false.            GraphicsConfiguration tmpGc = gc;            if (tmpGc == null) {                tmpGc = GraphicsEnvironment.getLocalGraphicsEnvironment().                    getDefaultScreenDevice().getDefaultConfiguration();            }            if (tmpGc instanceof ProxiedGraphicsConfig) {                Object proxyKey =                    ((ProxiedGraphicsConfig) tmpGc).getProxyKey();                if (proxyKey != null) {                    SurfaceDataProxy sdp =                        (SurfaceDataProxy) getCacheData(proxyKey);                    return (sdp != null && sdp.isAccelerated());                }            }            return false;        }    }     /**     * An interface for GraphicsConfiguration objects to implement if     * their surfaces accelerate images using SurfaceDataProxy objects.     *     * Implementing this interface facilitates the default     * implementation of getImageCapabilities() above.     */    public static interface ProxiedGraphicsConfig {        /**         * Return the key that destination surfaces created on the         * given GraphicsConfiguration use to store SurfaceDataProxy         * objects for their cached copies.         */        public Object getProxyKey();    }     /**     * Releases system resources in use by ancillary SurfaceData objects,     * such as surfaces cached in accelerated memory.  Subclasses should     * override to release any of their flushable data.     * <p>     * The default implementation will visit all of the value objects     * in the cacheMap and flush them if they implement the     * FlushableCacheData interface.     */    public synchronized void flush() {        flush(false);    }     synchronized void flush(boolean deaccelerate) {        if (cacheMap != null) {            Iterator i = cacheMap.values().iterator();            while (i.hasNext()) {                Object o = i.next();                if (o instanceof FlushableCacheData) {                    if (((FlushableCacheData) o).flush(deaccelerate)) {                        i.remove();                    }                }            }        }    }     /**     * An interface for Objects used in the SurfaceManager cache     * to implement if they have data that should be flushed when     * the Image is flushed.     */    public static interface FlushableCacheData {        /**         * Flush all cached resources.         * The deaccelerated parameter indicates if the flush is         * happening because the associated surface is no longer         * being accelerated (for instance the acceleration priority         * is set below the threshold needed for acceleration).         * Returns a boolean that indicates if the cached object is         * no longer needed and should be removed from the cache.         */        public boolean flush(boolean deaccelerated);    }     /**     * Called when image's acceleration priority is changed.     * <p>     * The default implementation will visit all of the value objects     * in the cacheMap when the priority gets set to 0.0 and flush them     * if they implement the FlushableCacheData interface.     */    public void setAccelerationPriority(float priority) {        if (priority == 0.0f) {            flush(true);        }    }}