/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkClipStack_DEFINED
#define SkClipStack_DEFINED

#include "include/core/SkCanvas.h"
#include "include/core/SkPath.h"
#include "include/core/SkRRect.h"
#include "include/core/SkRect.h"
#include "include/core/SkRegion.h"
#include "include/core/SkShader.h"
#include "include/private/base/SkDeque.h"
#include "src/base/SkTLazy.h"
#include "src/core/SkMessageBus.h"

#if SK_SUPPORT_GPU
class GrProxyProvider;

#include "src/gpu/ResourceKey.h"
#endif

// Because a single save/restore state can have multiple clips, this class
// stores the stack depth (fSaveCount) and clips (fDeque) separately.
// Each clip in fDeque stores the stack state to which it belongs
// (i.e., the fSaveCount in force when it was added). Restores are thus
// implemented by removing clips from fDeque that have an fSaveCount larger
// then the freshly decremented count.
class SkClipStack {
public:
    enum BoundsType {
        // The bounding box contains all the pixels that can be written to
        kNormal_BoundsType,
        // The bounding box contains all the pixels that cannot be written to.
        // The real bound extends out to infinity and all the pixels outside
        // of the bound can be written to. Note that some of the pixels inside
        // the bound may also be writeable but all pixels that cannot be
        // written to are guaranteed to be inside.
        kInsideOut_BoundsType
    };

    /**
     * An element of the clip stack. It represents a shape combined with the prevoius clip using a
     * set operator. Each element can be antialiased or not.
     */
    class Element {
    public:
        /** This indicates the shape type of the clip element in device space. */
        enum class DeviceSpaceType {
            //!< This element makes the clip empty (regardless of previous elements).
            kEmpty,
            //!< This element combines a device space rect with the current clip.
            kRect,
            //!< This element combines a device space round-rect with the current clip.
            kRRect,
            //!< This element combines a device space path with the current clip.
            kPath,
            //!< This element does not have geometry, but applies a shader to the clip
            kShader,

            kLastType = kShader
        };
        static const int kTypeCnt = (int)DeviceSpaceType::kLastType + 1;

        Element() {
            this->initCommon(0, SkClipOp::kIntersect, false);
            this->setEmpty();
        }

        Element(const Element&);

        Element(const SkRect& rect, const SkMatrix& m, SkClipOp op, bool doAA) {
            this->initRect(0, rect, m, op, doAA);
        }

        Element(const SkRRect& rrect, const SkMatrix& m, SkClipOp op, bool doAA) {
            this->initRRect(0, rrect, m, op, doAA);
        }

        Element(const SkPath& path, const SkMatrix& m, SkClipOp op, bool doAA) {
            this->initPath(0, path, m, op, doAA);
        }

        Element(sk_sp<SkShader> shader) {
            this->initShader(0, std::move(shader));
        }

        Element(const SkRect& rect, bool doAA) {
            this->initReplaceRect(0, rect, doAA);
        }

        ~Element();

        bool operator== (const Element& element) const;
        bool operator!= (const Element& element) const { return !(*this == element); }

        //!< Call to get the type of the clip element.
        DeviceSpaceType getDeviceSpaceType() const { return fDeviceSpaceType; }

        //!< Call to get the save count associated with this clip element.
        int getSaveCount() const { return fSaveCount; }

        //!< Call if getDeviceSpaceType() is kPath to get the path.
        const SkPath& getDeviceSpacePath() const {
            SkASSERT(DeviceSpaceType::kPath == fDeviceSpaceType);
            return *fDeviceSpacePath;
        }

        //!< Call if getDeviceSpaceType() is kRRect to get the round-rect.
        const SkRRect& getDeviceSpaceRRect() const {
            SkASSERT(DeviceSpaceType::kRRect == fDeviceSpaceType);
            return fDeviceSpaceRRect;
        }

        //!< Call if getDeviceSpaceType() is kRect to get the rect.
        const SkRect& getDeviceSpaceRect() const {
            SkASSERT(DeviceSpaceType::kRect == fDeviceSpaceType &&
                     (fDeviceSpaceRRect.isRect() || fDeviceSpaceRRect.isEmpty()));
            return fDeviceSpaceRRect.getBounds();
        }

        //!<Call if getDeviceSpaceType() is kShader to get a reference to the clip shader.
        sk_sp<SkShader> refShader() const {
            return fShader;
        }
        const SkShader* getShader() const {
            return fShader.get();
        }

        //!< Call if getDeviceSpaceType() is not kEmpty to get the set operation used to combine
        //!< this element.
        SkClipOp getOp() const { return fOp; }
        // Augments getOps()'s behavior by requiring a clip reset before the op is applied.
        bool isReplaceOp() const { return fIsReplace; }

        //!< Call to get the element as a path, regardless of its type.
        void asDeviceSpacePath(SkPath* path) const;

        //!< Call if getType() is not kPath to get the element as a round rect.
        const SkRRect& asDeviceSpaceRRect() const {
            SkASSERT(DeviceSpaceType::kPath != fDeviceSpaceType);
            return fDeviceSpaceRRect;
        }

        /** If getType() is not kEmpty this indicates whether the clip shape should be anti-aliased
            when it is rasterized. */
        bool isAA() const { return fDoAA; }

        //!< Inverts the fill of the clip shape. Note that a kEmpty element remains kEmpty.
        void invertShapeFillType();

        /** The GenID can be used by clip stack clients to cache representations of the clip. The
            ID corresponds to the set of clip elements up to and including this element within the
            stack not to the element itself. That is the same clip path in different stacks will
            have a different ID since the elements produce different clip result in the context of
            their stacks. */
        uint32_t getGenID() const { SkASSERT(kInvalidGenID != fGenID); return fGenID; }

        /**
         * Gets the bounds of the clip element, either the rect or path bounds. (Whether the shape
         * is inverse filled is not considered.)
         */
        const SkRect& getBounds() const;

        /**
         * Conservatively checks whether the clip shape contains the rect/rrect. (Whether the shape
         * is inverse filled is not considered.)
         */
        bool contains(const SkRect& rect) const;
        bool contains(const SkRRect& rrect) const;

        /**
         * Is the clip shape inverse filled.
         */
        bool isInverseFilled() const {
            return DeviceSpaceType::kPath == fDeviceSpaceType &&
                   fDeviceSpacePath->isInverseFillType();
        }

#ifdef SK_DEBUG
        /**
         * Dumps the element to SkDebugf. This is intended for Skia development debugging
         * Don't rely on the existence of this function or the formatting of its output.
         */
        void dump() const;
#endif

#if SK_SUPPORT_GPU
        /**
         * This is used to purge any GPU resource cache items that become unreachable when
         * the element is destroyed because their key is based on this element's gen ID.
         */
        void addResourceInvalidationMessage(GrProxyProvider* proxyProvider,
                                            const skgpu::UniqueKey& key) const {
            SkASSERT(proxyProvider);

            if (!fProxyProvider) {
                fProxyProvider = proxyProvider;
            }
            SkASSERT(fProxyProvider == proxyProvider);

            fKeysToInvalidate.push_back(key);
        }
#endif

    private:
        friend class SkClipStack;

        SkTLazy<SkPath> fDeviceSpacePath;
        SkRRect fDeviceSpaceRRect;
        sk_sp<SkShader> fShader;
        int fSaveCount;  // save count of stack when this element was added.
        SkClipOp fOp;
        DeviceSpaceType fDeviceSpaceType;
        bool fDoAA;
        bool fIsReplace;

        /* fFiniteBoundType and fFiniteBound are used to incrementally update the clip stack's
           bound. When fFiniteBoundType is kNormal_BoundsType, fFiniteBound represents the
           conservative bounding box of the pixels that aren't clipped (i.e., any pixels that can be
           drawn to are inside the bound). When fFiniteBoundType is kInsideOut_BoundsType (which
           occurs when a clip is inverse filled), fFiniteBound represents the conservative bounding
           box of the pixels that _are_ clipped (i.e., any pixels that cannot be drawn to are inside
           the bound). When fFiniteBoundType is kInsideOut_BoundsType the actual bound is the
           infinite plane. This behavior of fFiniteBoundType and fFiniteBound is required so that we
           can capture the cancelling out of the extensions to infinity when two inverse filled
           clips are Booleaned together. */
        SkClipStack::BoundsType fFiniteBoundType;
        SkRect fFiniteBound;

        // When element is applied to the previous elements in the stack is the result known to be
        // equivalent to a single rect intersection? IIOW, is the clip effectively a rectangle.
        bool fIsIntersectionOfRects;

        uint32_t fGenID;
#if SK_SUPPORT_GPU
        mutable GrProxyProvider*           fProxyProvider = nullptr;
        mutable SkTArray<skgpu::UniqueKey> fKeysToInvalidate;
#endif
        Element(int saveCount) {
            this->initCommon(saveCount, SkClipOp::kIntersect, false);
            this->setEmpty();
        }

        Element(int saveCount, const SkRRect& rrect, const SkMatrix& m, SkClipOp op, bool doAA) {
            this->initRRect(saveCount, rrect, m, op, doAA);
        }

        Element(int saveCount, const SkRect& rect, const SkMatrix& m, SkClipOp op, bool doAA) {
            this->initRect(saveCount, rect, m, op, doAA);
        }

        Element(int saveCount, const SkPath& path, const SkMatrix& m, SkClipOp op, bool doAA) {
            this->initPath(saveCount, path, m, op, doAA);
        }

        Element(int saveCount, sk_sp<SkShader> shader) {
            this->initShader(saveCount, std::move(shader));
        }

        Element(int saveCount, const SkRect& rect, bool doAA) {
            this->initReplaceRect(saveCount, rect, doAA);
        }

        void initCommon(int saveCount, SkClipOp op, bool doAA);
        void initRect(int saveCount, const SkRect&, const SkMatrix&, SkClipOp, bool doAA);
        void initRRect(int saveCount, const SkRRect&, const SkMatrix&, SkClipOp, bool doAA);
        void initPath(int saveCount, const SkPath&, const SkMatrix&, SkClipOp, bool doAA);
        void initAsPath(int saveCount, const SkPath&, const SkMatrix&, SkClipOp, bool doAA);
        void initShader(int saveCount, sk_sp<SkShader>);
        void initReplaceRect(int saveCount, const SkRect&, bool doAA);

        void setEmpty();

        // All Element methods below are only used within SkClipStack.cpp
        inline void checkEmpty() const;
        inline bool canBeIntersectedInPlace(int saveCount, SkClipOp op) const;
        /* This method checks to see if two rect clips can be safely merged into one. The issue here
          is that to be strictly correct all the edges of the resulting rect must have the same
          anti-aliasing. */
        bool rectRectIntersectAllowed(const SkRect& newR, bool newAA) const;
        /** Determines possible finite bounds for the Element given the previous element of the
            stack */
        void updateBoundAndGenID(const Element* prior);
        // The different combination of fill & inverse fill when combining bounding boxes
        enum FillCombo {
            kPrev_Cur_FillCombo,
            kPrev_InvCur_FillCombo,
            kInvPrev_Cur_FillCombo,
            kInvPrev_InvCur_FillCombo
        };
        // per-set operation functions used by updateBoundAndGenID().
        inline void combineBoundsDiff(FillCombo combination, const SkRect& prevFinite);
        inline void combineBoundsIntersection(int combination, const SkRect& prevFinite);
    };

    SkClipStack();
    SkClipStack(void* storage, size_t size);
    SkClipStack(const SkClipStack& b);
    ~SkClipStack();

    SkClipStack& operator=(const SkClipStack& b);
    bool operator==(const SkClipStack& b) const;
    bool operator!=(const SkClipStack& b) const { return !(*this == b); }

    void reset();

    int getSaveCount() const { return fSaveCount; }
    void save();
    void restore();

    class AutoRestore {
    public:
        AutoRestore(SkClipStack* cs, bool doSave)
            : fCS(cs), fSaveCount(cs->getSaveCount())
        {
            if (doSave) {
                fCS->save();
            }
        }
        ~AutoRestore() {
            SkASSERT(fCS->getSaveCount() >= fSaveCount);  // no underflow
            while (fCS->getSaveCount() > fSaveCount) {
                fCS->restore();
            }
        }

    private:
        SkClipStack* fCS;
        const int    fSaveCount;
    };

    /**
     * getBounds places the current finite bound in its first parameter. In its
     * second, it indicates which kind of bound is being returned. If
     * 'canvFiniteBound' is a normal bounding box then it encloses all writeable
     * pixels. If 'canvFiniteBound' is an inside out bounding box then it
     * encloses all the un-writeable pixels and the true/normal bound is the
     * infinite plane. isIntersectionOfRects is an optional parameter
     * that is true if 'canvFiniteBound' resulted from an intersection of rects.
     */
    void getBounds(SkRect* canvFiniteBound,
                   BoundsType* boundType,
                   bool* isIntersectionOfRects = nullptr) const;

    SkRect bounds(const SkIRect& deviceBounds) const;
    bool isEmpty(const SkIRect& deviceBounds) const;

    /**
     * Returns true if the input (r)rect in device space is entirely contained
     * by the clip. A return value of false does not guarantee that the (r)rect
     * is not contained by the clip.
     */
    bool quickContains(const SkRect& devRect) const {
        return this->isWideOpen() || this->internalQuickContains(devRect);
    }

    bool quickContains(const SkRRect& devRRect) const {
        return this->isWideOpen() || this->internalQuickContains(devRRect);
    }

    void clipDevRect(const SkIRect& ir, SkClipOp op) {
        SkRect r;
        r.set(ir);
        this->clipRect(r, SkMatrix::I(), op, false);
    }
    void clipRect(const SkRect&, const SkMatrix& matrix, SkClipOp, bool doAA);
    void clipRRect(const SkRRect&, const SkMatrix& matrix, SkClipOp, bool doAA);
    void clipPath(const SkPath&, const SkMatrix& matrix, SkClipOp, bool doAA);
    void clipShader(sk_sp<SkShader>);
    // An optimized version of clipDevRect(emptyRect, kIntersect, ...)
    void clipEmpty();

    void replaceClip(const SkRect& devRect, bool doAA);

    /**
     * isWideOpen returns true if the clip state corresponds to the infinite
     * plane (i.e., draws are not limited at all)
     */
    bool isWideOpen() const { return this->getTopmostGenID() == kWideOpenGenID; }

    /**
     * This method quickly and conservatively determines whether the entire stack is equivalent to
     * intersection with a rrect given a bounds, where the rrect must not contain the entire bounds.
     *
     * @param bounds   A bounds on what will be drawn through the clip. The clip only need be
     *                 equivalent to a intersection with a rrect for draws within the bounds. The
     *                 returned rrect must intersect the bounds but need not be contained by the
     *                 bounds.
     * @param rrect    If return is true rrect will contain the rrect equivalent to the stack.
     * @param aa       If return is true aa will indicate whether the equivalent rrect clip is
     *                 antialiased.
     * @return true if the stack is equivalent to a single rrect intersect clip, false otherwise.
     */
    bool isRRect(const SkRect& bounds, SkRRect* rrect, bool* aa) const;

    /**
     * The generation ID has three reserved values to indicate special
     * (potentially ignorable) cases
     */
    static const uint32_t kInvalidGenID  = 0;    //!< Invalid id that is never returned by
                                                 //!< SkClipStack. Useful when caching clips
                                                 //!< based on GenID.
    static const uint32_t kEmptyGenID    = 1;    // no pixels writeable
    static const uint32_t kWideOpenGenID = 2;    // all pixels writeable

    uint32_t getTopmostGenID() const;

#ifdef SK_DEBUG
    /**
     * Dumps the contents of the clip stack to SkDebugf. This is intended for Skia development
     * debugging. Don't rely on the existence of this function or the formatting of its output.
     */
    void dump() const;
#endif

public:
    class Iter {
    public:
        enum IterStart {
            kBottom_IterStart = SkDeque::Iter::kFront_IterStart,
            kTop_IterStart = SkDeque::Iter::kBack_IterStart
        };

        /**
         * Creates an uninitialized iterator. Must be reset()
         */
        Iter();

        Iter(const SkClipStack& stack, IterStart startLoc);

        /**
         *  Return the clip element for this iterator. If next()/prev() returns NULL, then the
         *  iterator is done.
         */
        const Element* next();
        const Element* prev();

        /**
         * Moves the iterator to the topmost element with the specified RegionOp and returns that
         * element. If no clip element with that op is found, the first element is returned.
         */
        const Element* skipToTopmost(SkClipOp op);

        /**
         * Restarts the iterator on a clip stack.
         */
        void reset(const SkClipStack& stack, IterStart startLoc);

    private:
        const SkClipStack* fStack;
        SkDeque::Iter      fIter;
    };

    /**
     * The B2TIter iterates from the bottom of the stack to the top.
     * It inherits privately from Iter to prevent access to reverse iteration.
     */
    class B2TIter : private Iter {
    public:
        B2TIter() {}

        /**
         * Wrap Iter's 2 parameter ctor to force initialization to the
         * beginning of the deque/bottom of the stack
         */
        B2TIter(const SkClipStack& stack)
        : INHERITED(stack, kBottom_IterStart) {
        }

        using Iter::next;

        /**
         * Wrap Iter::reset to force initialization to the
         * beginning of the deque/bottom of the stack
         */
        void reset(const SkClipStack& stack) {
            this->INHERITED::reset(stack, kBottom_IterStart);
        }

    private:

        using INHERITED = Iter;
    };

    /**
     * GetConservativeBounds returns a conservative bound of the current clip.
     * Since this could be the infinite plane (if inverse fills were involved) the
     * maxWidth and maxHeight parameters can be used to limit the returned bound
     * to the expected drawing area. Similarly, the offsetX and offsetY parameters
     * allow the caller to offset the returned bound to account for translated
     * drawing areas (i.e., those resulting from a saveLayer). For finite bounds,
     * the translation (+offsetX, +offsetY) is applied before the clamp to the
     * maximum rectangle: [0,maxWidth) x [0,maxHeight).
     * isIntersectionOfRects is an optional parameter that is true when
     * 'devBounds' is the result of an intersection of rects. In this case
     * 'devBounds' is the exact answer/clip.
     */
    void getConservativeBounds(int offsetX,
                               int offsetY,
                               int maxWidth,
                               int maxHeight,
                               SkRect* devBounds,
                               bool* isIntersectionOfRects = nullptr) const;

private:
    friend class Iter;

    SkDeque fDeque;
    int     fSaveCount;

    bool internalQuickContains(const SkRect& devRect) const;
    bool internalQuickContains(const SkRRect& devRRect) const;

    /**
     * Helper for clipDevPath, etc.
     */
    void pushElement(const Element& element);

    /**
     * Restore the stack back to the specified save count.
     */
    void restoreTo(int saveCount);

    /**
     * Return the next unique generation ID.
     */
    static uint32_t GetNextGenID();
};

#endif
