1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2011 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#ifndef SkPictureRecord_DEFINED
9cb93a386Sopenharmony_ci#define SkPictureRecord_DEFINED
10cb93a386Sopenharmony_ci
11cb93a386Sopenharmony_ci#include "include/core/SkCanvas.h"
12cb93a386Sopenharmony_ci#include "include/core/SkCanvasVirtualEnforcer.h"
13cb93a386Sopenharmony_ci#include "include/core/SkFlattenable.h"
14cb93a386Sopenharmony_ci#include "include/core/SkPicture.h"
15cb93a386Sopenharmony_ci#include "include/core/SkVertices.h"
16cb93a386Sopenharmony_ci#include "include/private/SkTArray.h"
17cb93a386Sopenharmony_ci#include "include/private/SkTDArray.h"
18cb93a386Sopenharmony_ci#include "include/private/SkTHash.h"
19cb93a386Sopenharmony_ci#include "include/private/SkTo.h"
20cb93a386Sopenharmony_ci#include "src/core/SkPictureData.h"
21cb93a386Sopenharmony_ci#include "src/core/SkWriter32.h"
22cb93a386Sopenharmony_ci
23cb93a386Sopenharmony_ci// These macros help with packing and unpacking a single byte value and
24cb93a386Sopenharmony_ci// a 3 byte value into/out of a uint32_t
25cb93a386Sopenharmony_ci#define MASK_24 0x00FFFFFF
26cb93a386Sopenharmony_ci#define UNPACK_8_24(combined, small, large) \
27cb93a386Sopenharmony_ci    small = (combined >> 24) & 0xFF;        \
28cb93a386Sopenharmony_ci    large = combined & MASK_24
29cb93a386Sopenharmony_ci#define PACK_8_24(small, large) ((small << 24) | large)
30cb93a386Sopenharmony_ci
31cb93a386Sopenharmony_ci
32cb93a386Sopenharmony_ciclass SkPictureRecord : public SkCanvasVirtualEnforcer<SkCanvas> {
33cb93a386Sopenharmony_cipublic:
34cb93a386Sopenharmony_ci    SkPictureRecord(const SkISize& dimensions, uint32_t recordFlags);
35cb93a386Sopenharmony_ci
36cb93a386Sopenharmony_ci    SkPictureRecord(const SkIRect& dimensions, uint32_t recordFlags);
37cb93a386Sopenharmony_ci
38cb93a386Sopenharmony_ci    const SkTArray<sk_sp<const SkPicture>>& getPictures() const {
39cb93a386Sopenharmony_ci        return fPictures;
40cb93a386Sopenharmony_ci    }
41cb93a386Sopenharmony_ci
42cb93a386Sopenharmony_ci    const SkTArray<sk_sp<SkDrawable>>& getDrawables() const {
43cb93a386Sopenharmony_ci        return fDrawables;
44cb93a386Sopenharmony_ci    }
45cb93a386Sopenharmony_ci
46cb93a386Sopenharmony_ci    const SkTArray<sk_sp<const SkTextBlob>>& getTextBlobs() const {
47cb93a386Sopenharmony_ci        return fTextBlobs;
48cb93a386Sopenharmony_ci    }
49cb93a386Sopenharmony_ci
50cb93a386Sopenharmony_ci    const SkTArray<sk_sp<const SkVertices>>& getVertices() const {
51cb93a386Sopenharmony_ci        return fVertices;
52cb93a386Sopenharmony_ci    }
53cb93a386Sopenharmony_ci
54cb93a386Sopenharmony_ci    const SkTArray<sk_sp<const SkImage>>& getImages() const {
55cb93a386Sopenharmony_ci        return fImages;
56cb93a386Sopenharmony_ci    }
57cb93a386Sopenharmony_ci
58cb93a386Sopenharmony_ci    sk_sp<SkData> opData() const {
59cb93a386Sopenharmony_ci        this->validate(fWriter.bytesWritten(), 0);
60cb93a386Sopenharmony_ci
61cb93a386Sopenharmony_ci        if (fWriter.bytesWritten() == 0) {
62cb93a386Sopenharmony_ci            return SkData::MakeEmpty();
63cb93a386Sopenharmony_ci        }
64cb93a386Sopenharmony_ci        return fWriter.snapshotAsData();
65cb93a386Sopenharmony_ci    }
66cb93a386Sopenharmony_ci
67cb93a386Sopenharmony_ci    void setFlags(uint32_t recordFlags) {
68cb93a386Sopenharmony_ci        fRecordFlags = recordFlags;
69cb93a386Sopenharmony_ci    }
70cb93a386Sopenharmony_ci
71cb93a386Sopenharmony_ci    const SkWriter32& writeStream() const {
72cb93a386Sopenharmony_ci        return fWriter;
73cb93a386Sopenharmony_ci    }
74cb93a386Sopenharmony_ci
75cb93a386Sopenharmony_ci    void beginRecording();
76cb93a386Sopenharmony_ci    void endRecording();
77cb93a386Sopenharmony_ci
78cb93a386Sopenharmony_ciprotected:
79cb93a386Sopenharmony_ci    void addNoOp();
80cb93a386Sopenharmony_ci
81cb93a386Sopenharmony_ciprivate:
82cb93a386Sopenharmony_ci    void handleOptimization(int opt);
83cb93a386Sopenharmony_ci    size_t recordRestoreOffsetPlaceholder();
84cb93a386Sopenharmony_ci    void fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t restoreOffset);
85cb93a386Sopenharmony_ci
86cb93a386Sopenharmony_ci    SkTDArray<int32_t> fRestoreOffsetStack;
87cb93a386Sopenharmony_ci
88cb93a386Sopenharmony_ci    SkTDArray<uint32_t> fCullOffsetStack;
89cb93a386Sopenharmony_ci
90cb93a386Sopenharmony_ci    /*
91cb93a386Sopenharmony_ci     * Write the 'drawType' operation and chunk size to the skp. 'size'
92cb93a386Sopenharmony_ci     * can potentially be increased if the chunk size needs its own storage
93cb93a386Sopenharmony_ci     * location (i.e., it overflows 24 bits).
94cb93a386Sopenharmony_ci     * Returns the start offset of the chunk. This is the location at which
95cb93a386Sopenharmony_ci     * the opcode & size are stored.
96cb93a386Sopenharmony_ci     * TODO: since we are handing the size into here we could call reserve
97cb93a386Sopenharmony_ci     * and then return a pointer to the memory storage. This could decrease
98cb93a386Sopenharmony_ci     * allocation overhead but could lead to more wasted space (the tail
99cb93a386Sopenharmony_ci     * end of blocks could go unused). Possibly add a second addDraw that
100cb93a386Sopenharmony_ci     * operates in this manner.
101cb93a386Sopenharmony_ci     */
102cb93a386Sopenharmony_ci    size_t addDraw(DrawType drawType, size_t* size) {
103cb93a386Sopenharmony_ci        size_t offset = fWriter.bytesWritten();
104cb93a386Sopenharmony_ci
105cb93a386Sopenharmony_ci        SkASSERT_RELEASE(this->predrawNotify());
106cb93a386Sopenharmony_ci
107cb93a386Sopenharmony_ci        SkASSERT(0 != *size);
108cb93a386Sopenharmony_ci        SkASSERT(((uint8_t) drawType) == drawType);
109cb93a386Sopenharmony_ci
110cb93a386Sopenharmony_ci        if (0 != (*size & ~MASK_24) || *size == MASK_24) {
111cb93a386Sopenharmony_ci            fWriter.writeInt(PACK_8_24(drawType, MASK_24));
112cb93a386Sopenharmony_ci            *size += 1;
113cb93a386Sopenharmony_ci            fWriter.writeInt(SkToU32(*size));
114cb93a386Sopenharmony_ci        } else {
115cb93a386Sopenharmony_ci            fWriter.writeInt(PACK_8_24(drawType, SkToU32(*size)));
116cb93a386Sopenharmony_ci        }
117cb93a386Sopenharmony_ci
118cb93a386Sopenharmony_ci        return offset;
119cb93a386Sopenharmony_ci    }
120cb93a386Sopenharmony_ci
121cb93a386Sopenharmony_ci    void addInt(int value) {
122cb93a386Sopenharmony_ci        fWriter.writeInt(value);
123cb93a386Sopenharmony_ci    }
124cb93a386Sopenharmony_ci    void addScalar(SkScalar scalar) {
125cb93a386Sopenharmony_ci        fWriter.writeScalar(scalar);
126cb93a386Sopenharmony_ci    }
127cb93a386Sopenharmony_ci
128cb93a386Sopenharmony_ci    void addImage(const SkImage*);
129cb93a386Sopenharmony_ci    void addMatrix(const SkMatrix& matrix);
130cb93a386Sopenharmony_ci    void addPaint(const SkPaint& paint) { this->addPaintPtr(&paint); }
131cb93a386Sopenharmony_ci    void addPaintPtr(const SkPaint* paint);
132cb93a386Sopenharmony_ci    void addPatch(const SkPoint cubics[12]);
133cb93a386Sopenharmony_ci    void addPath(const SkPath& path);
134cb93a386Sopenharmony_ci    void addPicture(const SkPicture* picture);
135cb93a386Sopenharmony_ci    void addDrawable(SkDrawable* picture);
136cb93a386Sopenharmony_ci    void addPoint(const SkPoint& point);
137cb93a386Sopenharmony_ci    void addPoints(const SkPoint pts[], int count);
138cb93a386Sopenharmony_ci    void addRect(const SkRect& rect);
139cb93a386Sopenharmony_ci    void addRectPtr(const SkRect* rect);
140cb93a386Sopenharmony_ci    void addIRect(const SkIRect& rect);
141cb93a386Sopenharmony_ci    void addIRectPtr(const SkIRect* rect);
142cb93a386Sopenharmony_ci    void addRRect(const SkRRect&);
143cb93a386Sopenharmony_ci    void addRegion(const SkRegion& region);
144cb93a386Sopenharmony_ci    void addSampling(const SkSamplingOptions&);
145cb93a386Sopenharmony_ci    void addText(const void* text, size_t byteLength);
146cb93a386Sopenharmony_ci    void addTextBlob(const SkTextBlob* blob);
147cb93a386Sopenharmony_ci    void addVertices(const SkVertices*);
148cb93a386Sopenharmony_ci
149cb93a386Sopenharmony_ci    int find(const SkBitmap& bitmap);
150cb93a386Sopenharmony_ci
151cb93a386Sopenharmony_ciprotected:
152cb93a386Sopenharmony_ci    void validate(size_t initialOffset, size_t size) const {
153cb93a386Sopenharmony_ci        SkASSERT(fWriter.bytesWritten() == initialOffset + size);
154cb93a386Sopenharmony_ci    }
155cb93a386Sopenharmony_ci
156cb93a386Sopenharmony_ci    sk_sp<SkSurface> onNewSurface(const SkImageInfo&, const SkSurfaceProps&) override;
157cb93a386Sopenharmony_ci    bool onPeekPixels(SkPixmap*) override { return false; }
158cb93a386Sopenharmony_ci
159cb93a386Sopenharmony_ci    void onFlush() override;
160cb93a386Sopenharmony_ci
161cb93a386Sopenharmony_ci    void willSave() override;
162cb93a386Sopenharmony_ci    SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override;
163cb93a386Sopenharmony_ci    bool onDoSaveBehind(const SkRect*) override;
164cb93a386Sopenharmony_ci    void willRestore() override;
165cb93a386Sopenharmony_ci
166cb93a386Sopenharmony_ci    void onMarkCTM(const char*) override;
167cb93a386Sopenharmony_ci    void didConcat44(const SkM44&) override;
168cb93a386Sopenharmony_ci    void didSetM44(const SkM44&) override;
169cb93a386Sopenharmony_ci    void didScale(SkScalar, SkScalar) override;
170cb93a386Sopenharmony_ci    void didTranslate(SkScalar, SkScalar) override;
171cb93a386Sopenharmony_ci
172cb93a386Sopenharmony_ci    void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override;
173cb93a386Sopenharmony_ci
174cb93a386Sopenharmony_ci    void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
175cb93a386Sopenharmony_ci                                const SkPaint& paint) override;
176cb93a386Sopenharmony_ci
177cb93a386Sopenharmony_ci    void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
178cb93a386Sopenharmony_ci                     const SkPoint texCoords[4], SkBlendMode, const SkPaint& paint) override;
179cb93a386Sopenharmony_ci
180cb93a386Sopenharmony_ci    void onDrawPaint(const SkPaint&) override;
181cb93a386Sopenharmony_ci    void onDrawBehind(const SkPaint&) override;
182cb93a386Sopenharmony_ci    void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override;
183cb93a386Sopenharmony_ci    void onDrawRect(const SkRect&, const SkPaint&) override;
184cb93a386Sopenharmony_ci    void onDrawRegion(const SkRegion&, const SkPaint&) override;
185cb93a386Sopenharmony_ci    void onDrawOval(const SkRect&, const SkPaint&) override;
186cb93a386Sopenharmony_ci    void onDrawArc(const SkRect&, SkScalar, SkScalar, bool, const SkPaint&) override;
187cb93a386Sopenharmony_ci    void onDrawRRect(const SkRRect&, const SkPaint&) override;
188cb93a386Sopenharmony_ci    void onDrawPath(const SkPath&, const SkPaint&) override;
189cb93a386Sopenharmony_ci
190cb93a386Sopenharmony_ci    void onDrawImage2(const SkImage*, SkScalar, SkScalar, const SkSamplingOptions&,
191cb93a386Sopenharmony_ci                      const SkPaint*) override;
192cb93a386Sopenharmony_ci    void onDrawImageRect2(const SkImage*, const SkRect&, const SkRect&, const SkSamplingOptions&,
193cb93a386Sopenharmony_ci                          const SkPaint*, SrcRectConstraint) override;
194cb93a386Sopenharmony_ci    void onDrawImageLattice2(const SkImage*, const Lattice&, const SkRect&, SkFilterMode,
195cb93a386Sopenharmony_ci                             const SkPaint*) override;
196cb93a386Sopenharmony_ci    void onDrawAtlas2(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int,
197cb93a386Sopenharmony_ci                     SkBlendMode, const SkSamplingOptions&, const SkRect*, const SkPaint*) override;
198cb93a386Sopenharmony_ci
199cb93a386Sopenharmony_ci    void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override;
200cb93a386Sopenharmony_ci    void onDrawVerticesObject(const SkVertices*, SkBlendMode, const SkPaint&) override;
201cb93a386Sopenharmony_ci
202cb93a386Sopenharmony_ci    void onClipRect(const SkRect&, SkClipOp, ClipEdgeStyle) override;
203cb93a386Sopenharmony_ci    void onClipRRect(const SkRRect&, SkClipOp, ClipEdgeStyle) override;
204cb93a386Sopenharmony_ci    void onClipPath(const SkPath&, SkClipOp, ClipEdgeStyle) override;
205cb93a386Sopenharmony_ci    void onClipShader(sk_sp<SkShader>, SkClipOp) override;
206cb93a386Sopenharmony_ci    void onClipRegion(const SkRegion&, SkClipOp) override;
207cb93a386Sopenharmony_ci    void onResetClip() override;
208cb93a386Sopenharmony_ci
209cb93a386Sopenharmony_ci    void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override;
210cb93a386Sopenharmony_ci
211cb93a386Sopenharmony_ci    void onDrawDrawable(SkDrawable*, const SkMatrix*) override;
212cb93a386Sopenharmony_ci    void onDrawAnnotation(const SkRect&, const char[], SkData*) override;
213cb93a386Sopenharmony_ci
214cb93a386Sopenharmony_ci    void onDrawEdgeAAQuad(const SkRect&, const SkPoint[4], QuadAAFlags, const SkColor4f&,
215cb93a386Sopenharmony_ci                          SkBlendMode) override;
216cb93a386Sopenharmony_ci    void onDrawEdgeAAImageSet2(const ImageSetEntry[], int count, const SkPoint[], const SkMatrix[],
217cb93a386Sopenharmony_ci                               const SkSamplingOptions&,const SkPaint*, SrcRectConstraint) override;
218cb93a386Sopenharmony_ci
219cb93a386Sopenharmony_ci    int addPathToHeap(const SkPath& path);  // does not write to ops stream
220cb93a386Sopenharmony_ci
221cb93a386Sopenharmony_ci    // These entry points allow the writing of matrices, clips, saves &
222cb93a386Sopenharmony_ci    // restores to be deferred (e.g., if the MC state is being collapsed and
223cb93a386Sopenharmony_ci    // only written out as needed).
224cb93a386Sopenharmony_ci    void recordConcat(const SkMatrix& matrix);
225cb93a386Sopenharmony_ci    void recordTranslate(const SkMatrix& matrix);
226cb93a386Sopenharmony_ci    void recordScale(const SkMatrix& matrix);
227cb93a386Sopenharmony_ci    size_t recordClipRect(const SkRect& rect, SkClipOp op, bool doAA);
228cb93a386Sopenharmony_ci    size_t recordClipRRect(const SkRRect& rrect, SkClipOp op, bool doAA);
229cb93a386Sopenharmony_ci    size_t recordClipPath(int pathID, SkClipOp op, bool doAA);
230cb93a386Sopenharmony_ci    size_t recordClipRegion(const SkRegion& region, SkClipOp op);
231cb93a386Sopenharmony_ci    void recordSave();
232cb93a386Sopenharmony_ci    void recordSaveLayer(const SaveLayerRec&);
233cb93a386Sopenharmony_ci    void recordRestore(bool fillInSkips = true);
234cb93a386Sopenharmony_ci
235cb93a386Sopenharmony_ciprivate:
236cb93a386Sopenharmony_ci    SkTArray<SkPaint>  fPaints;
237cb93a386Sopenharmony_ci
238cb93a386Sopenharmony_ci    struct PathHash {
239cb93a386Sopenharmony_ci        uint32_t operator()(const SkPath& p) { return p.getGenerationID(); }
240cb93a386Sopenharmony_ci    };
241cb93a386Sopenharmony_ci    SkTHashMap<SkPath, int, PathHash> fPaths;
242cb93a386Sopenharmony_ci
243cb93a386Sopenharmony_ci    SkWriter32 fWriter;
244cb93a386Sopenharmony_ci
245cb93a386Sopenharmony_ci    SkTArray<sk_sp<const SkImage>>    fImages;
246cb93a386Sopenharmony_ci    SkTArray<sk_sp<const SkPicture>>  fPictures;
247cb93a386Sopenharmony_ci    SkTArray<sk_sp<SkDrawable>>       fDrawables;
248cb93a386Sopenharmony_ci    SkTArray<sk_sp<const SkTextBlob>> fTextBlobs;
249cb93a386Sopenharmony_ci    SkTArray<sk_sp<const SkVertices>> fVertices;
250cb93a386Sopenharmony_ci
251cb93a386Sopenharmony_ci    uint32_t fRecordFlags;
252cb93a386Sopenharmony_ci    int      fInitialSaveCount;
253cb93a386Sopenharmony_ci
254cb93a386Sopenharmony_ci    friend class SkPictureData;   // for SkPictureData's SkPictureRecord-based constructor
255cb93a386Sopenharmony_ci
256cb93a386Sopenharmony_ci    using INHERITED = SkCanvasVirtualEnforcer<SkCanvas>;
257cb93a386Sopenharmony_ci};
258cb93a386Sopenharmony_ci
259cb93a386Sopenharmony_ci#endif
260