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

#ifndef SkPictureStateTree_DEFINED
#define SkPictureStateTree_DEFINED

#include "SkTDArray.h"
#include "SkChunkAlloc.h"
#include "SkDeque.h"
#include "SkMatrix.h"
#include "SkRefCnt.h"

class SkCanvas;

/**
 * Provides an interface that, given a sequence of draws into an SkPicture with corresponding
 * offsets, allows for playback of an arbitrary subset of the draws (note that Z-order is only
 * guaranteed if the draws are explicitly sorted).
 */
class SkPictureStateTree : public SkRefCnt {
private:
    struct Node;
public:
    SK_DECLARE_INST_COUNT(SkPictureStateTree)

    /**
     * A draw call, stores offset into command buffer, a pointer to the matrix, and a pointer to
     * the node in the tree that corresponds to its clip/layer state
     */
    struct Draw {
        SkMatrix* fMatrix;
        Node* fNode;
        uint32_t fOffset;
        bool operator<(const Draw& other) const { return fOffset < other.fOffset; }
    };

    class Iterator;

    SkPictureStateTree();
    ~SkPictureStateTree();

    /**
     * Creates and returns a struct representing a draw at the given offset.
     */
    Draw* appendDraw(size_t offset);

    /**
     * Given a list of draws, and a canvas, returns an iterator that produces the correct sequence
     * of offsets into the command buffer to carry out those calls with correct matrix/clip state.
     * This handles saves/restores, and does all necessary matrix setup.
     */
    Iterator getIterator(const SkTDArray<void*>& draws, SkCanvas* canvas);

    void appendSave();
    void appendSaveLayer(size_t offset);
    void appendRestore();
    void appendTransform(const SkMatrix& trans);
    void appendClip(size_t offset);

    /**
     * Call this immediately after an appendRestore call that is associated
     * a save or saveLayer that was removed from the command stream
     * due to a command pattern optimization in SkPicture.
     */
    void saveCollapsed();

    /**
     * Playback helper
     */
    class Iterator {
    public:
        /** Returns the next offset into the picture stream, or kDrawComplete if complete. */
        uint32_t nextDraw();
        static const uint32_t kDrawComplete = SK_MaxU32;
        Iterator() : fPlaybackMatrix(), fValid(false) { }
        bool isValid() const { return fValid; }

    private:
        Iterator(const SkTDArray<void*>& draws, SkCanvas* canvas, Node* root);

        void setCurrentMatrix(const SkMatrix*);

        // The draws this iterator is associated with
        const SkTDArray<void*>* fDraws;

        // canvas this is playing into (so we can insert saves/restores as necessary)
        SkCanvas* fCanvas;

        // current state node
        Node* fCurrentNode;

        // List of nodes whose state we need to apply to reach TargetNode
        SkTDArray<Node*> fNodes;

        // The matrix of the canvas we're playing back into
        const SkMatrix fPlaybackMatrix;

        // Cache of current matrix, so we can avoid redundantly setting it
        const SkMatrix* fCurrentMatrix;

        // current position in the array of draws
        int fPlaybackIndex;
        // Whether or not we need to do a save next iteration
        bool fSave;

        // Whether or not this is a valid iterator (the default public constructor sets this false)
        bool fValid;

        friend class SkPictureStateTree;
    };

private:

    void appendNode(size_t offset);

    SkChunkAlloc fAlloc;
    // Needed by saveCollapsed() because nodes do not currently store
    // references to their children.  If they did, we could just retrieve the
    // last added child.
    Node* fLastRestoredNode;

    // The currently active state
    Draw fCurrentState;
    // A stack of states for tracking save/restores
    SkDeque fStateStack;

    // Represents a notable piece of state that requires an offset into the command buffer,
    // corresponding to a clip/saveLayer/etc call, to apply.
    struct Node {
        Node* fParent;
        uint32_t fOffset;
        uint16_t fLevel;
        uint16_t fFlags;
        SkMatrix* fMatrix;
        enum Flags {
            kSave_Flag      = 0x1,
            kSaveLayer_Flag = 0x2
        };
    };

    Node fRoot;
    SkMatrix fRootMatrix;

    typedef SkRefCnt INHERITED;
};

#endif
