SkPicture.h revision f799706656f2581c5bf5510d94df3fa17cce1607
1/*
2 * Copyright 2007 The Android Open Source Project
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SkPicture_DEFINED
9#define SkPicture_DEFINED
10
11#include "SkRefCnt.h"
12#include "SkTypes.h"
13
14class GrContext;
15class SkBigPicture;
16class SkBitmap;
17class SkCanvas;
18class SkPath;
19class SkPictureData;
20class SkPixelSerializer;
21class SkReadBuffer;
22class SkRefCntSet;
23class SkStream;
24class SkTypefacePlayback;
25class SkWStream;
26class SkWriteBuffer;
27struct SkPictInfo;
28struct SkRect;
29
30#define SK_SUPPORT_LEGACY_PICTURE_PTR
31
32/** \class SkPicture
33
34    An SkPicture records drawing commands made to a canvas to be played back at a later time.
35    This base class handles serialization and a few other miscellany.
36*/
37class SK_API SkPicture : public SkRefCnt {
38public:
39    virtual ~SkPicture();
40
41    /**
42     *  Function signature defining a function that sets up an SkBitmap from encoded data. On
43     *  success, the SkBitmap should have its Config, width, height, rowBytes and pixelref set.
44     *  If the installed pixelref has decoded the data into pixels, then the src buffer need not be
45     *  copied. If the pixelref defers the actual decode until its lockPixels() is called, then it
46     *  must make a copy of the src buffer.
47     *  @param src Encoded data.
48     *  @param length Size of the encoded data, in bytes.
49     *  @param dst SkBitmap to install the pixel ref on.
50     *  @param bool Whether or not a pixel ref was successfully installed.
51     */
52    typedef bool (*InstallPixelRefProc)(const void* src, size_t length, SkBitmap* dst);
53
54    /**
55     *  Recreate a picture that was serialized into a stream.
56     *  @param SkStream Serialized picture data. Ownership is unchanged by this call.
57     *  @param proc Function pointer for installing pixelrefs on SkBitmaps representing the
58     *              encoded bitmap data from the stream.
59     *  @return A new SkPicture representing the serialized data, or NULL if the stream is
60     *          invalid.
61     */
62    static sk_sp<SkPicture> MakeFromStream(SkStream*, InstallPixelRefProc proc);
63
64    /**
65     *  Recreate a picture that was serialized into a stream.
66     *
67     *  Any serialized images in the stream will be passed to
68     *  SkImageGenerator::NewFromEncoded.
69     *
70     *  @param SkStream Serialized picture data. Ownership is unchanged by this call.
71     *  @return A new SkPicture representing the serialized data, or NULL if the stream is
72     *          invalid.
73     */
74    static sk_sp<SkPicture> MakeFromStream(SkStream*);
75
76    /**
77     *  Recreate a picture that was serialized into a buffer. If the creation requires bitmap
78     *  decoding, the decoder must be set on the SkReadBuffer parameter by calling
79     *  SkReadBuffer::setBitmapDecoder() before calling SkPicture::CreateFromBuffer().
80     *  @param SkReadBuffer Serialized picture data.
81     *  @return A new SkPicture representing the serialized data, or NULL if the buffer is
82     *          invalid.
83     */
84    static sk_sp<SkPicture> MakeFromBuffer(SkReadBuffer&);
85
86    /**
87    *  Subclasses of this can be passed to playback(). During the playback
88    *  of the picture, this callback will periodically be invoked. If its
89    *  abort() returns true, then picture playback will be interrupted.
90    *
91    *  The resulting drawing is undefined, as there is no guarantee how often the
92    *  callback will be invoked. If the abort happens inside some level of nested
93    *  calls to save(), restore will automatically be called to return the state
94    *  to the same level it was before the playback call was made.
95    */
96    class SK_API AbortCallback {
97    public:
98        AbortCallback() {}
99        virtual ~AbortCallback() {}
100        virtual bool abort() = 0;
101    };
102
103    /** Replays the drawing commands on the specified canvas. Note that
104        this has the effect of unfurling this picture into the destination
105        canvas. Using the SkCanvas::drawPicture entry point gives the destination
106        canvas the option of just taking a ref.
107        @param canvas the canvas receiving the drawing commands.
108        @param callback a callback that allows interruption of playback
109    */
110    virtual void playback(SkCanvas*, AbortCallback* = NULL) const = 0;
111
112    /** Return a cull rect for this picture.
113        Ops recorded into this picture that attempt to draw outside the cull might not be drawn.
114     */
115    virtual SkRect cullRect() const = 0;
116
117    /** Returns a non-zero value unique among all pictures. */
118    uint32_t uniqueID() const;
119
120    /**
121     *  Serialize to a stream. If non NULL, serializer will be used to serialize
122     *  bitmaps and images in the picture.
123     */
124    void serialize(SkWStream*, SkPixelSerializer* = NULL) const;
125
126    /**
127     *  Serialize to a buffer.
128     */
129    void flatten(SkWriteBuffer&) const;
130
131    /**
132     * Returns true if any bitmaps may be produced when this SkPicture
133     * is replayed.
134     */
135    virtual bool willPlayBackBitmaps() const = 0;
136
137    /** Return the approximate number of operations in this picture.  This
138     *  number may be greater or less than the number of SkCanvas calls
139     *  recorded: some calls may be recorded as more than one operation, or some
140     *  calls may be optimized away.
141     */
142    virtual int approximateOpCount() const = 0;
143
144    /** Return true if this picture contains text.
145     */
146    virtual bool hasText() const = 0;
147
148    /** Returns the approximate byte size of this picture, not including large ref'd objects. */
149    virtual size_t approximateBytesUsed() const = 0;
150
151    /** Return true if the SkStream/Buffer represents a serialized picture, and
152        fills out SkPictInfo. After this function returns, the data source is not
153        rewound so it will have to be manually reset before passing to
154        CreateFromStream or CreateFromBuffer. Note, CreateFromStream and
155        CreateFromBuffer perform this check internally so these entry points are
156        intended for stand alone tools.
157        If false is returned, SkPictInfo is unmodified.
158    */
159    static bool InternalOnly_StreamIsSKP(SkStream*, SkPictInfo*);
160    static bool InternalOnly_BufferIsSKP(SkReadBuffer*, SkPictInfo*);
161
162    /** Return true if the picture is suitable for rendering on the GPU.  */
163    bool suitableForGpuRasterization(GrContext*, const char** whyNot = NULL) const;
164
165    // Sent via SkMessageBus from destructor.
166    struct DeletionMessage { int32_t fUniqueID; };  // TODO: -> uint32_t?
167
168    // Returns NULL if this is not an SkBigPicture.
169    virtual const SkBigPicture* asSkBigPicture() const { return NULL; }
170
171    // Global setting to enable or disable security precautions for serialization.
172    static void SetPictureIOSecurityPrecautionsEnabled_Dangerous(bool set);
173    static bool PictureIOSecurityPrecautionsEnabled();
174
175#ifdef SK_SUPPORT_LEGACY_PICTURE_PTR
176    static SkPicture* CreateFromStream(SkStream* stream, InstallPixelRefProc proc) {
177        return MakeFromStream(stream, proc).release();
178    }
179    static SkPicture* CreateFromStream(SkStream* stream) {
180        return MakeFromStream(stream).release();
181    }
182    static SkPicture* CreateFromBuffer(SkReadBuffer& rbuf) {
183        return MakeFromBuffer(rbuf).release();
184    }
185#endif
186
187private:
188    // Subclass whitelist.
189    SkPicture();
190    friend class SkBigPicture;
191    friend class SkEmptyPicture;
192    template <typename> friend class SkMiniPicture;
193
194    void serialize(SkWStream*, SkPixelSerializer*, SkRefCntSet* typefaces) const;
195    static sk_sp<SkPicture> MakeFromStream(SkStream*, InstallPixelRefProc, SkTypefacePlayback*);
196    friend class SkPictureData;
197
198    virtual int numSlowPaths() const = 0;
199    friend struct SkPathCounter;
200
201    // V35: Store SkRect (rather then width & height) in header
202    // V36: Remove (obsolete) alphatype from SkColorTable
203    // V37: Added shadow only option to SkDropShadowImageFilter (last version to record CLEAR)
204    // V38: Added PictureResolution option to SkPictureImageFilter
205    // V39: Added FilterLevel option to SkPictureImageFilter
206    // V40: Remove UniqueID serialization from SkImageFilter.
207    // V41: Added serialization of SkBitmapSource's filterQuality parameter
208    // V42: Added a bool to SkPictureShader serialization to indicate did-we-serialize-a-picture?
209    // V43: Added DRAW_IMAGE and DRAW_IMAGE_RECT opt codes to serialized data
210    // V44: Move annotations from paint to drawAnnotation
211
212    // Only SKPs within the min/current picture version range (inclusive) can be read.
213    static const uint32_t     MIN_PICTURE_VERSION = 35;     // Produced by Chrome M39.
214    static const uint32_t CURRENT_PICTURE_VERSION = 44;
215
216    static_assert(MIN_PICTURE_VERSION <= 41,
217                  "Remove kFontFileName and related code from SkFontDescriptor.cpp.");
218
219    static_assert(MIN_PICTURE_VERSION <= 42,
220                  "Remove COMMENT API handlers from SkPicturePlayback.cpp");
221
222    static_assert(MIN_PICTURE_VERSION <= 43,
223                  "Remove SkBitmapSourceDeserializer.");
224
225    static bool IsValidPictInfo(const SkPictInfo& info);
226    static sk_sp<SkPicture> Forwardport(const SkPictInfo&, const SkPictureData*);
227
228    SkPictInfo createHeader() const;
229    SkPictureData* backport() const;
230
231    mutable uint32_t fUniqueID;
232};
233
234#endif
235