/*
 * Copyright (c) 2007, 2013, 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.java2d;

import java.awt.Color;
import java.awt.Rectangle;
import java.awt.AlphaComposite;
import java.awt.GraphicsEnvironment;

import sun.awt.DisplayChangedListener;
import sun.java2d.StateTrackable.State;
import sun.java2d.loops.CompositeType;
import sun.java2d.loops.SurfaceType;
import sun.java2d.loops.Blit;
import sun.java2d.loops.BlitBg;
import sun.awt.image.SurfaceManager;
import sun.awt.image.SurfaceManager.FlushableCacheData;

import java.security.AccessController;
import sun.security.action.GetPropertyAction;

/**
 * The proxy class encapsulates the logic for managing alternate
 * SurfaceData representations of a primary SurfaceData.
 * The main class will handle tracking the state changes of the
 * primary SurfaceData and updating the associated SurfaceData
 * proxy variants.
 * <p>
 * Subclasses have 2 main responsibilities:
 * <ul>
 * <li> Override the isSupportedOperation() method to determine if
 *      a given operation can be accelerated with a given source
 *      SurfaceData
 * <li> Override the validateSurfaceData() method to create or update
 *      a given accelerated surface to hold the pixels for the indicated
 *      source SurfaceData
 * </ul>
 * If necessary, a subclass may also override the updateSurfaceData
 * method to transfer the pixels to the accelerated surface.
 * By default the parent class will transfer the pixels using a
 * standard Blit operation between the two SurfaceData objects.
 */
public abstract class SurfaceDataProxy
    implements DisplayChangedListener, SurfaceManager.FlushableCacheData
{
    private static boolean cachingAllowed;
    private static int defaultThreshold;

    static {
        cachingAllowed = true;
        String manimg = AccessController.doPrivileged(
            new GetPropertyAction("sun.java2d.managedimages"));
        if (manimg != null && manimg.equals("false")) {
            cachingAllowed = false;
            System.out.println("Disabling managed images");
        }

        defaultThreshold = 1;
        String num = AccessController.doPrivileged(
            new GetPropertyAction("sun.java2d.accthreshold"));
        if (num != null) {
            try {
                int parsed = Integer.parseInt(num);
                if (parsed >= 0) {
                    defaultThreshold = parsed;
                    System.out.println("New Default Acceleration Threshold: " +
                                       defaultThreshold);
                }
            } catch (NumberFormatException e) {
                System.err.println("Error setting new threshold:" + e);
            }
        }
    }

    public static boolean isCachingAllowed() {
        return cachingAllowed;
    }

    /**
     * Determine if an alternate form for the srcData is needed
     * and appropriate from the given operational parameters.
     */
    public abstract boolean isSupportedOperation(SurfaceData srcData,
                                                 int txtype,
                                                 CompositeType comp,
                                                 Color bgColor);

    /**
     * Construct an alternate form of the given SurfaceData.
     * The contents of the returned SurfaceData may be undefined
     * since the calling code will take care of updating the
     * contents with a subsequent call to updateSurfaceData.
     * <p>
     * If the method returns null then there was a problem with
     * allocating the accelerated surface.  The getRetryTracker()
     * method will be called to track when to attempt another
     * revalidation.
     */
    public abstract SurfaceData validateSurfaceData(SurfaceData srcData,
                                                    SurfaceData cachedData,
                                                    int w, int h);

    /**
     * If the subclass is unable to validate or create a cached
     * SurfaceData then this method will be used to get a
     * StateTracker object that will indicate when to attempt
     * to validate the surface again.  Subclasses may return
     * trackers which count down an ever increasing threshold
     * to provide hysteresis on creating surfaces during low
     * memory conditions.  The default implementation just waits
     * another "threshold" number of accesses before trying again.
     */
    public StateTracker getRetryTracker(SurfaceData srcData) {
        return new CountdownTracker(threshold);
    }

    public static class CountdownTracker implements StateTracker {
        private int countdown;

        public CountdownTracker(int threshold) {
            this.countdown = threshold;
        }

        public synchronized boolean isCurrent() {
            return (--countdown >= 0);
        }
    }

    /**
     * This instance is for cases where a caching implementation
     * determines that a particular source image will never need
     * to be cached - either the source SurfaceData was of an
     * incompatible type, or it was in an UNTRACKABLE state or
     * some other factor is discovered that permanently prevents
     * acceleration or caching.
     * This class optimally implements NOP variants of all necessary
     * methods to avoid caching with a minimum of fuss.
     */
    public static SurfaceDataProxy UNCACHED = new SurfaceDataProxy(0) {
        @Override
        public boolean isAccelerated() {
            return false;
        }

        @Override
        public boolean isSupportedOperation(SurfaceData srcData,
                                            int txtype,
                                            CompositeType comp,
                                            Color bgColor)
        {
            return false;
        }

        @Override
        public SurfaceData validateSurfaceData(SurfaceData srcData,
                                               SurfaceData cachedData,
                                               int w, int h)
        {
            throw new InternalError("UNCACHED should never validate SDs");
        }

        @Override
        public SurfaceData replaceData(SurfaceData srcData,
                                       int txtype,
                                       CompositeType comp,
                                       Color bgColor)
        {
            // Not necessary to override this, but doing so is faster
            return srcData;
        }
    };

    // The number of attempts to copy from a STABLE source before
    // a cached copy is created or updated.
    private int threshold;

    /*
     * Source tracking data
     *
     * Every time that srcTracker is out of date we will reset numtries
     * to threshold and set the cacheTracker to one that is non-current.
     * numtries will then count down to 0 at which point the cacheTracker
     * will remind us that we need to update the cachedSD before we can
     * use it.
     *
     * Note that since these fields interrelate we should synchronize
     * whenever we update them, but it should be OK to read them
     * without synchronization.
     */
    private StateTracker srcTracker;
    private int numtries;

    /*
     * Cached data
     *
     * We cache a SurfaceData created by the subclass in cachedSD and
     * track its state (isValid and !surfaceLost) in cacheTracker.
     *
     * Also, when we want to note that cachedSD needs to be updated
     * we replace the cacheTracker with a NEVER_CURRENT tracker which
     * will cause us to try to revalidate and update the surface on
     * next use.
     */
    private SurfaceData cachedSD;
    private StateTracker cacheTracker;

    /*
     * Are we still the best object to control caching of data
     * for the source image?
     */
    private boolean valid;

    /**
     * Create a SurfaceData proxy manager that attempts to create
     * and cache a variant copy of the source SurfaceData after
     * the default threshold number of attempts to copy from the
     * STABLE source.
     */
    public SurfaceDataProxy() {
        this(defaultThreshold);
    }

    /**
     * Create a SurfaceData proxy manager that attempts to create
     * and cache a variant copy of the source SurfaceData after
     * the specified threshold number of attempts to copy from
     * the STABLE source.
     */
    public SurfaceDataProxy(int threshold) {
        this.threshold = threshold;

        this.srcTracker = StateTracker.NEVER_CURRENT;
        // numtries will be reset on first use
        this.cacheTracker = StateTracker.NEVER_CURRENT;

        this.valid = true;
    }

    /**
     * Returns true iff this SurfaceData proxy is still the best
     * way to control caching of the given source on the given
     * destination.
     */
    public boolean isValid() {
        return valid;
    }

    /**
     * Sets the valid state to false so that the next time this
     * proxy is fetched to generate a replacement SurfaceData,
     * the code in SurfaceData knows to replace the proxy first.
     */
    public void invalidate() {
        this.valid = false;
    }

    /**
     * Flush all cached resources as per the FlushableCacheData interface.
     * 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) {
        if (deaccelerated) {
            invalidate();
        }
        flush();
        return !isValid();
    }

    /**
     * Actively flushes (drops and invalidates) the cached surface
     * so that it can be reclaimed quickly.
     */
    public synchronized void flush() {
        SurfaceData csd = this.cachedSD;
        this.cachedSD = null;
        this.cacheTracker = StateTracker.NEVER_CURRENT;
        if (csd != null) {
            csd.flush();
        }
    }

    /**
     * Returns true iff this SurfaceData proxy is still valid
     * and if it has a currently cached replacement that is also
     * valid and current.
     */
    public boolean isAccelerated() {
        return (isValid() &&
                srcTracker.isCurrent() &&
                cacheTracker.isCurrent());
    }

    /**
     * This method should be called from subclasses which create
     * cached SurfaceData objects that depend on the current
     * properties of the display.
     */
    protected void activateDisplayListener() {
        GraphicsEnvironment ge =
            GraphicsEnvironment.getLocalGraphicsEnvironment();
        // We could have a HeadlessGE at this point, so double-check before
        // assuming anything.
        // Also, no point in listening to display change events if
        // the image is never going to be accelerated.
        if (ge instanceof SunGraphicsEnvironment) {
            ((SunGraphicsEnvironment)ge).addDisplayChangedListener(this);
        }
    }

    /**
     * Invoked when the display mode has changed.
     * This method will invalidate and drop the internal cachedSD object.
     */
    public void displayChanged() {
        flush();
    }

    /**
     * Invoked when the palette has changed.
     */
    public void paletteChanged() {
        // We could potentially get away with just resetting cacheTracker
        // here but there is a small window of vulnerability in the
        // replaceData method where we could be just finished with
        // updating the cachedSD when this method is called and even
        // though we set a non-current cacheTracker here it will then
        // immediately get set to a current one by the thread that is
        // updating the cachedSD.  It is safer to just replace the
        // srcTracker with a non-current version that will trigger a
        // full update cycle the next time this proxy is used.
        // The downside is having to go through a full threshold count
        // before we can update and use our cache again, but palette
        // changes should be relatively rare...
        this.srcTracker = StateTracker.NEVER_CURRENT;
    }

    /**
     * This method attempts to replace the srcData with a cached version.
     * It relies on the subclass to determine if the cached version will
     * be useful given the operational parameters.
     * This method checks any preexisting cached copy for being "up to date"
     * and tries to update it if it is stale or non-existant and the
     * appropriate number of accesses have occurred since it last was stale.
     * <p>
     * An outline of the process is as follows:
     * <ol>
     * <li> Check the operational parameters (txtype, comp, bgColor)
     *      to make sure that the operation is supported.  Return the
     *      original SurfaceData if the operation cannot be accelerated.
     * <li> Check the tracker for the source surface to see if it has
     *      remained stable since it was last cached.  Update the state
     *      variables to cause both a threshold countdown and an update
     *      of the cached copy if it is not.  (Setting cacheTracker to
     *      NEVER_CURRENT effectively marks it as "needing to be updated".)
     * <li> Check the tracker for the cached copy to see if is still
     *      valid and up to date.  Note that the cacheTracker may be
     *      non-current if either something happened to the cached copy
     *      (eg. surfaceLost) or if the source was out of date and the
     *      cacheTracker was set to NEVER_CURRENT to force an update.
     *      Decrement the countdown and copy the source to the cache
     *      as necessary and then update the variables to show that
     *      the cached copy is stable.
     * </ol>
     */
    public SurfaceData replaceData(SurfaceData srcData,
                                   int txtype,
                                   CompositeType comp,
                                   Color bgColor)
    {
        if (isSupportedOperation(srcData, txtype, comp, bgColor)) {
            // First deal with tracking the source.
            if (!srcTracker.isCurrent()) {
                synchronized (this) {
                    this.numtries = threshold;
                    this.srcTracker = srcData.getStateTracker();
                    this.cacheTracker = StateTracker.NEVER_CURRENT;
                }

                if (!srcTracker.isCurrent()) {
                    // Dynamic or Untrackable (or a very recent modification)
                    if (srcData.getState() == State.UNTRACKABLE) {
                        // UNTRACKABLE means we can never cache again.

                        // Invalidate so we get replaced next time we are used
                        // (presumably with an UNCACHED proxy).
                        invalidate();

                        // Aggressively drop our reference to the cachedSD
                        // in case this proxy is not consulted again (and
                        // thus replaced) for a long time.
                        flush();
                    }
                    return srcData;
                }
            }

            // Then deal with checking the validity of the cached SurfaceData
            SurfaceData csd = this.cachedSD;
            if (!cacheTracker.isCurrent()) {
                // Next make sure the dust has settled
                synchronized (this) {
                    if (numtries > 0) {
                        --numtries;
                        return srcData;
                    }
                }

                Rectangle r = srcData.getBounds();
                int w = r.width;
                int h = r.height;

                // Snapshot the tracker in case it changes while
                // we are updating the cached SD...
                StateTracker curTracker = srcTracker;

                csd = validateSurfaceData(srcData, csd, w, h);
                if (csd == null) {
                    synchronized (this) {
                        if (curTracker == srcTracker) {
                            this.cacheTracker = getRetryTracker(srcData);
                            this.cachedSD = null;
                        }
                    }
                    return srcData;
                }

                updateSurfaceData(srcData, csd, w, h);
                if (!csd.isValid()) {
                    return srcData;
                }

                synchronized (this) {
                    // We only reset these variables if the tracker from
                    // before the surface update is still in use and current
                    // Note that we must use a srcTracker that was fetched
                    // from before the update process to make sure that we
                    // do not lose some pixel changes in the shuffle.
                    if (curTracker == srcTracker && curTracker.isCurrent()) {
                        this.cacheTracker = csd.getStateTracker();
                        this.cachedSD = csd;
                    }
                }
            }

            if (csd != null) {
                return csd;
            }
        }

        return srcData;
    }

    /**
     * This is the default implementation for updating the cached
     * SurfaceData from the source (primary) SurfaceData.
     * A simple Blit is used to copy the pixels from the source to
     * the destination SurfaceData.
     * A subclass can override this implementation if a more complex
     * operation is required to update its cached copies.
     */
    public void updateSurfaceData(SurfaceData srcData,
                                  SurfaceData dstData,
                                  int w, int h)
    {
        SurfaceType srcType = srcData.getSurfaceType();
        SurfaceType dstType = dstData.getSurfaceType();
        Blit blit = Blit.getFromCache(srcType,
                                      CompositeType.SrcNoEa,
                                      dstType);
        blit.Blit(srcData, dstData,
                  AlphaComposite.Src, null,
                  0, 0, 0, 0, w, h);
        dstData.markDirty();
    }

    /**
     * This is an alternate implementation for updating the cached
     * SurfaceData from the source (primary) SurfaceData using a
     * background color for transparent pixels.
     * A simple BlitBg is used to copy the pixels from the source to
     * the destination SurfaceData with the specified bgColor.
     * A subclass can override the normal updateSurfaceData method
     * and call this implementation instead if it wants to use color
     * keying for bitmask images.
     */
    public void updateSurfaceDataBg(SurfaceData srcData,
                                    SurfaceData dstData,
                                    int w, int h, Color bgColor)
    {
        SurfaceType srcType = srcData.getSurfaceType();
        SurfaceType dstType = dstData.getSurfaceType();
        BlitBg blitbg = BlitBg.getFromCache(srcType,
                                            CompositeType.SrcNoEa,
                                            dstType);
        blitbg.BlitBg(srcData, dstData,
                      AlphaComposite.Src, null, bgColor.getRGB(),
                      0, 0, 0, 0, w, h);
        dstData.markDirty();
    }
}
