
/*
 * Copyright 2007 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#ifndef SkPicture_DEFINED
#define SkPicture_DEFINED

#include "SkBitmap.h"
#include "SkImageDecoder.h"
#include "SkRefCnt.h"

#if SK_SUPPORT_GPU
class GrContext;
#endif

class SkBBHFactory;
class SkBBoxHierarchy;
class SkCanvas;
class SkDrawPictureCallback;
class SkData;
class SkPathHeap;
class SkPicturePlayback;
class SkPictureRecord;
class SkStream;
class SkWStream;

struct SkPictInfo;

/** \class SkPicture

    The SkPicture class records the drawing commands made to a canvas, to
    be played back at a later time.
*/
class SK_API SkPicture : public SkRefCnt {
public:
    SK_DECLARE_INST_COUNT(SkPicture)

    // AccelData provides a base class for device-specific acceleration
    // data. It is added to the picture via a call to a device's optimize
    // method.
    class AccelData : public SkRefCnt {
    public:
        typedef uint8_t Domain;
        typedef uint32_t Key;

        AccelData(Key key) : fKey(key) { }

        const Key& getKey() const { return fKey; }

        // This entry point allows user's to get a unique domain prefix
        // for their keys
        static Domain GenerateDomain();
    private:
        Key fKey;

        typedef SkRefCnt INHERITED;
    };

    SkPicture();
    /** Make a copy of the contents of src. If src records more drawing after
        this call, those elements will not appear in this picture.
    */
    SkPicture(const SkPicture& src);

    /**  PRIVATE / EXPERIMENTAL -- do not call */
    void EXPERIMENTAL_addAccelData(const AccelData* data) {
        SkRefCnt_SafeAssign(fAccelData, data);
    }
    /**  PRIVATE / EXPERIMENTAL -- do not call */
    const AccelData* EXPERIMENTAL_getAccelData(AccelData::Key key) const {
        if (NULL != fAccelData && fAccelData->getKey() == key) {
            return fAccelData;
        }
        return NULL;
    }

    /**
     *  Function signature defining a function that sets up an SkBitmap from encoded data. On
     *  success, the SkBitmap should have its Config, width, height, rowBytes and pixelref set.
     *  If the installed pixelref has decoded the data into pixels, then the src buffer need not be
     *  copied. If the pixelref defers the actual decode until its lockPixels() is called, then it
     *  must make a copy of the src buffer.
     *  @param src Encoded data.
     *  @param length Size of the encoded data, in bytes.
     *  @param dst SkBitmap to install the pixel ref on.
     *  @param bool Whether or not a pixel ref was successfully installed.
     */
    typedef bool (*InstallPixelRefProc)(const void* src, size_t length, SkBitmap* dst);

    /**
     *  Recreate a picture that was serialized into a stream.
     *  @param SkStream Serialized picture data.
     *  @param proc Function pointer for installing pixelrefs on SkBitmaps representing the
     *              encoded bitmap data from the stream.
     *  @return A new SkPicture representing the serialized data, or NULL if the stream is
     *          invalid.
     */
    static SkPicture* CreateFromStream(SkStream*,
                                       InstallPixelRefProc proc = &SkImageDecoder::DecodeMemory);

    /**
     *  Recreate a picture that was serialized into a buffer. If the creation requires bitmap
     *  decoding, the decoder must be set on the SkReadBuffer parameter by calling
     *  SkReadBuffer::setBitmapDecoder() before calling SkPicture::CreateFromBuffer().
     *  @param SkReadBuffer Serialized picture data.
     *  @return A new SkPicture representing the serialized data, or NULL if the buffer is
     *          invalid.
     */
    static SkPicture* CreateFromBuffer(SkReadBuffer&);

    virtual ~SkPicture();

    /**
     *  Swap the contents of the two pictures. Guaranteed to succeed.
     */
    void swap(SkPicture& other);

    /**
     *  Creates a thread-safe clone of the picture that is ready for playback.
     */
    SkPicture* clone() const;

    /**
     * Creates multiple thread-safe clones of this picture that are ready for
     * playback. The resulting clones are stored in the provided array of
     * SkPictures.
     */
    void clone(SkPicture* pictures, int count) const;

    enum RecordingFlags {
        /*  This flag specifies that when clipPath() is called, the path will
            be faithfully recorded, but the recording canvas' current clip will
            only see the path's bounds. This speeds up the recording process
            without compromising the fidelity of the playback. The only side-
            effect for recording is that calling getTotalClip() or related
            clip-query calls will reflect the path's bounds, not the actual
            path.
         */
        kUsePathBoundsForClip_RecordingFlag = 0x01
    };

#ifndef SK_SUPPORT_DEPRECATED_RECORD_FLAGS
    // TODO: once kOptimizeForClippedPlayback_RecordingFlag is hidden from
    // all external consumers, SkPicture::createBBoxHierarchy can also be
    // cleaned up.
private:
#endif
    enum Deprecated_RecordingFlags {
        /*  This flag causes the picture to compute bounding boxes and build
            up a spatial hierarchy (currently an R-Tree), plus a tree of Canvas'
            usually stack-based clip/etc state. This requires an increase in
            recording time (often ~2x; likely more for very complex pictures),
            but allows us to perform much faster culling at playback time, and
            completely avoid some unnecessary clips and other operations. This
            is ideal for tiled rendering, or any other situation where you're
            drawing a fraction of a large scene into a smaller viewport.

            In most cases the record cost is offset by the playback improvement
            after a frame or two of tiled rendering (and complex pictures that
            induce the worst record times will generally get the largest
            speedups at playback time).

            Note: Currently this is not serializable, the bounding data will be
            discarded if you serialize into a stream and then deserialize.
        */
        kOptimizeForClippedPlayback_RecordingFlag = 0x02,
    };
#ifndef SK_SUPPORT_DEPRECATED_RECORD_FLAGS
public:
#endif

#ifndef SK_SUPPORT_LEGACY_PICTURE_CAN_RECORD
private:
#endif

#ifdef SK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES

    /** Returns the canvas that records the drawing commands.
        @param width the base width for the picture, as if the recording
                     canvas' bitmap had this width.
        @param height the base width for the picture, as if the recording
                     canvas' bitmap had this height.
        @param recordFlags optional flags that control recording.
        @return the picture canvas.
    */
    SkCanvas* beginRecording(int width, int height, uint32_t recordFlags = 0);
#endif

    /** Returns the recording canvas if one is active, or NULL if recording is
        not active. This does not alter the refcnt on the canvas (if present).
    */
    SkCanvas* getRecordingCanvas() const;
    /** Signal that the caller is done recording. This invalidates the canvas
        returned by beginRecording/getRecordingCanvas, and prepares the picture
        for drawing. Note: this happens implicitly the first time the picture
        is drawn.
    */
    void endRecording();

#ifndef SK_SUPPORT_LEGACY_PICTURE_CAN_RECORD
public:
#endif

    /** Replays the drawing commands on the specified canvas. This internally
        calls endRecording() if that has not already been called.
        @param canvas the canvas receiving the drawing commands.
    */
    void draw(SkCanvas* canvas, SkDrawPictureCallback* = NULL);

    /** Return the width of the picture's recording canvas. This
        value reflects what was passed to setSize(), and does not necessarily
        reflect the bounds of what has been recorded into the picture.
        @return the width of the picture's recording canvas
    */
    int width() const { return fWidth; }

    /** Return the height of the picture's recording canvas. This
        value reflects what was passed to setSize(), and does not necessarily
        reflect the bounds of what has been recorded into the picture.
        @return the height of the picture's recording canvas
    */
    int height() const { return fHeight; }

    /** Return a non-zero, unique value representing the picture. This call is
        only valid when not recording. Between a beginRecording/endRecording
        pair it will just return 0 (the invalid ID). Each beginRecording/
        endRecording pair will cause a different generation ID to be returned.
    */
    uint32_t uniqueID() const;

    /**
     *  Function to encode an SkBitmap to an SkData. A function with this
     *  signature can be passed to serialize() and SkWriteBuffer.
     *  Returning NULL will tell the SkWriteBuffer to use
     *  SkBitmap::flatten() to store the bitmap.
     *
     *  @param pixelRefOffset DEPRECATED -- caller assumes it will return 0.
     *  @return SkData If non-NULL, holds encoded data representing the passed
     *      in bitmap. The caller is responsible for calling unref().
     */
    typedef SkData* (*EncodeBitmap)(size_t* pixelRefOffset, const SkBitmap& bm);

    /**
     *  Serialize to a stream. If non NULL, encoder will be used to encode
     *  any bitmaps in the picture.
     *  encoder will never be called with a NULL pixelRefOffset.
     */
    void serialize(SkWStream*, EncodeBitmap encoder = NULL) const;

    /**
     *  Serialize to a buffer.
     */
    void flatten(SkWriteBuffer&) const;

    /**
     * Returns true if any bitmaps may be produced when this SkPicture
     * is replayed.
     * Returns false if called while still recording.
     */
    bool willPlayBackBitmaps() const;

#ifdef SK_BUILD_FOR_ANDROID
    /** Signals that the caller is prematurely done replaying the drawing
        commands. This can be called from a canvas virtual while the picture
        is drawing. Has no effect if the picture is not drawing.
        @deprecated preserving for legacy purposes
    */
    void abortPlayback();
#endif

    /** Return true if the SkStream/Buffer represents a serialized picture, and
        fills out SkPictInfo. After this function returns, the data source is not
        rewound so it will have to be manually reset before passing to
        CreateFromStream or CreateFromBuffer. Note, CreateFromStream and
        CreateFromBuffer perform this check internally so these entry points are
        intended for stand alone tools.
        If false is returned, SkPictInfo is unmodified.
    */
    static bool InternalOnly_StreamIsSKP(SkStream*, SkPictInfo*);
    static bool InternalOnly_BufferIsSKP(SkReadBuffer&, SkPictInfo*);

    /** Enable/disable all the picture recording optimizations (i.e.,
        those in SkPictureRecord). It is mainly intended for testing the
        existing optimizations (i.e., to actually have the pattern
        appear in an .skp we have to disable the optimization). Call right
        after 'beginRecording'.
    */
    void internalOnly_EnableOpts(bool enableOpts);

    /** Return true if the picture is suitable for rendering on the GPU.
     */

#if SK_SUPPORT_GPU
    bool suitableForGpuRasterization(GrContext*) const;
#endif

protected:
    // V2 : adds SkPixelRef's generation ID.
    // V3 : PictInfo tag at beginning, and EOF tag at the end
    // V4 : move SkPictInfo to be the header
    // V5 : don't read/write FunctionPtr on cross-process (we can detect that)
    // V6 : added serialization of SkPath's bounds (and packed its flags tighter)
    // V7 : changed drawBitmapRect(IRect) to drawBitmapRectToRect(Rect)
    // V8 : Add an option for encoding bitmaps
    // V9 : Allow the reader and writer of an SKP disagree on whether to support
    //      SK_SUPPORT_HINTING_SCALE_FACTOR
    // V10: add drawRRect, drawOval, clipRRect
    // V11: modify how readBitmap and writeBitmap store their info.
    // V12: add conics to SkPath, use new SkPathRef flattening
    // V13: add flag to drawBitmapRectToRect
    //      parameterize blurs by sigma rather than radius
    // V14: Add flags word to PathRef serialization
    // V15: Remove A1 bitmap config (and renumber remaining configs)
    // V16: Move SkPath's isOval flag to SkPathRef
    // V17: SkPixelRef now writes SkImageInfo
    // V18: SkBitmap now records x,y for its pixelref origin, instead of offset.
    // V19: encode matrices and regions into the ops stream
    // V20: added bool to SkPictureImageFilter's serialization (to allow SkPicture serialization)
    // V21: add pushCull, popCull
    // V22: SK_PICT_FACTORY_TAG's size is now the chunk size in bytes
    // V23: SkPaint::FilterLevel became a real enum
    // V24: SkTwoPointConicalGradient now has fFlipped flag for gradient flipping
    // V25: SkDashPathEffect now only writes phase and interval array when flattening
    // V26: Removed boolean from SkColorShader for inheriting color from SkPaint.
    // V27: Remove SkUnitMapper from gradients (and skia).
    // V28: No longer call bitmap::flatten inside SkWriteBuffer::writeBitmap.

    // Note: If the picture version needs to be increased then please follow the
    // steps to generate new SKPs in (only accessible to Googlers): http://goo.gl/qATVcw

    // Only SKPs within the min/current picture version range (inclusive) can be read.
    static const uint32_t MIN_PICTURE_VERSION = 19;
    static const uint32_t CURRENT_PICTURE_VERSION = 28;

    mutable uint32_t      fUniqueID;

    // fPlayback, fRecord, fWidth & fHeight are protected to allow derived classes to
    // install their own SkPicturePlayback-derived players,SkPictureRecord-derived
    // recorders and set the picture size
    SkPicturePlayback*    fPlayback;
    SkPictureRecord*      fRecord;
    int                   fWidth, fHeight;
    const AccelData*      fAccelData;

    void needsNewGenID() { fUniqueID = SK_InvalidGenID; }

    // Create a new SkPicture from an existing SkPicturePlayback. Ref count of
    // playback is unchanged.
    SkPicture(SkPicturePlayback*, int width, int height);

#ifdef SK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES
    // For testing. Derived classes may instantiate an alternate
    // SkBBoxHierarchy implementation
    virtual SkBBoxHierarchy* createBBoxHierarchy() const;
#endif

    SkCanvas* beginRecording(int width, int height, SkBBHFactory* factory, uint32_t recordFlags);

private:
    friend class SkPictureRecord;
    friend class SkPictureTester;   // for unit testing

    SkAutoTUnref<SkPathHeap> fPathHeap;  // reference counted

    // ContentInfo is not serialized! It is intended solely for use
    // with suitableForGpuRasterization.
    class ContentInfo {
    public:
        ContentInfo() { this->reset(); }

        ContentInfo(const ContentInfo& src) { this->set(src); }

        void set(const ContentInfo& src) {
            fNumPaintWithPathEffectUses = src.fNumPaintWithPathEffectUses;
            fNumAAConcavePaths = src.fNumAAConcavePaths;
            fNumAAHairlineConcavePaths = src.fNumAAHairlineConcavePaths;
        }

        void reset() {
            fNumPaintWithPathEffectUses = 0;
            fNumAAConcavePaths = 0;
            fNumAAHairlineConcavePaths = 0;
        }

        void swap(ContentInfo* other) {
            SkTSwap(fNumPaintWithPathEffectUses, other->fNumPaintWithPathEffectUses);
            SkTSwap(fNumAAConcavePaths, other->fNumAAConcavePaths);
            SkTSwap(fNumAAHairlineConcavePaths, other->fNumAAHairlineConcavePaths);
        }

        // This field is incremented every time a paint with a path effect is
        // used (i.e., it is not a de-duplicated count)
        int fNumPaintWithPathEffectUses;
        // This field is incremented every time an anti-aliased drawPath call is
        // issued with a concave path
        int fNumAAConcavePaths;
        // This field is incremented every time a drawPath call is
        // issued for a hairline stroked concave path.
        int fNumAAHairlineConcavePaths;
    };

    ContentInfo fContentInfo;

    void incPaintWithPathEffectUses() {
        ++fContentInfo.fNumPaintWithPathEffectUses;
    }
    int numPaintWithPathEffectUses() const {
        return fContentInfo.fNumPaintWithPathEffectUses;
    }

    void incAAConcavePaths() {
        ++fContentInfo.fNumAAConcavePaths;
    }
    int numAAConcavePaths() const {
        return fContentInfo.fNumAAConcavePaths;
    }

    void incAAHairlineConcavePaths() {
        ++fContentInfo.fNumAAHairlineConcavePaths;
        SkASSERT(fContentInfo.fNumAAHairlineConcavePaths <= fContentInfo.fNumAAConcavePaths);
    }
    int numAAHairlineConcavePaths() const {
        return fContentInfo.fNumAAHairlineConcavePaths;
    }

    const SkPath& getPath(int index) const;
    int addPathToHeap(const SkPath& path);

    void flattenToBuffer(SkWriteBuffer& buffer) const;
    bool parseBufferTag(SkReadBuffer& buffer, uint32_t tag, uint32_t size);

    static void WriteTagSize(SkWriteBuffer& buffer, uint32_t tag, size_t size);
    static void WriteTagSize(SkWStream* stream, uint32_t tag, size_t size);

    void initForPlayback() const;
    void dumpSize() const;

    // An OperationList encapsulates a set of operation offsets into the picture byte
    // stream along with the CTMs needed for those operation.
    class OperationList : ::SkNoncopyable {
    public:
        virtual ~OperationList() {}

        // If valid returns false then there is no optimization data
        // present. All the draw operations need to be issued.
        virtual bool valid() const { return false; }

        // The following three entry points should only be accessed if
        // 'valid' returns true.
        virtual int numOps() const { SkASSERT(false); return 0; };
        // The offset in the picture of the operation to execute.
        virtual uint32_t offset(int index) const { SkASSERT(false); return 0; };
        // The CTM that must be installed for the operation to behave correctly
        virtual const SkMatrix& matrix(int index) const { SkASSERT(false); return SkMatrix::I(); }

        static const OperationList& InvalidList();
    };

    /** PRIVATE / EXPERIMENTAL -- do not call
        Return the operations required to render the content inside 'queryRect'.
    */
    const OperationList& EXPERIMENTAL_getActiveOps(const SkIRect& queryRect);

    /** PRIVATE / EXPERIMENTAL -- do not call
        Return the ID of the operation currently being executed when playing
        back. 0 indicates no call is active.
    */
    size_t EXPERIMENTAL_curOpID() const;

    void createHeader(SkPictInfo* info) const;
    static bool IsValidPictInfo(const SkPictInfo& info);
    static SkPicturePlayback* FakeEndRecording(const SkPicture* resourceSrc,
                                               const SkPictureRecord& record,
                                               bool deepCopy);

    friend class SkFlatPicture;
    friend class SkPicturePlayback;
    friend class SkPictureRecorder;
    friend class SkGpuDevice;
    friend class GrGatherCanvas;
    friend class GrGatherDevice;
    friend class SkDebugCanvas;

    typedef SkRefCnt INHERITED;
};

/**
 *  Subclasses of this can be passed to canvas.drawPicture. During the drawing
 *  of the picture, this callback will periodically be invoked. If its
 *  abortDrawing() returns true, then picture playback will be interrupted.
 *
 *  The resulting drawing is undefined, as there is no guarantee how often the
 *  callback will be invoked. If the abort happens inside some level of nested
 *  calls to save(), restore will automatically be called to return the state
 *  to the same level it was before the drawPicture call was made.
 */
class SK_API SkDrawPictureCallback {
public:
    SkDrawPictureCallback() {}
    virtual ~SkDrawPictureCallback() {}

    virtual bool abortDrawing() = 0;
};

#ifdef SK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES

class SkPictureFactory : public SkRefCnt {
public:
    /**
     *  Allocate a new SkPicture. Return NULL on failure.
     */
    virtual SkPicture* create(int width, int height) = 0;

private:
    typedef SkRefCnt INHERITED;
};

#endif

#ifdef SK_SUPPORT_LEGACY_PICTURE_HEADERS
#include "SkPictureRecorder.h"
#endif

#endif
