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

/**
 * 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 = System.getProperty("sun.java2d.managedimages");
        if ("false".equals(manimg)) {
            cachingAllowed = false;
            System.out.println("Disabling managed images");
        }

        defaultThreshold = 1;
        String num = System.getProperty("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-existent 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();
    }
}
