aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkPicturePlayback.h
blob: 6c32b152396eea9da8577141e7dfda035f0f8e0f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkPicturePlayback_DEFINED
#define SkPicturePlayback_DEFINED

#include "SkPictureFlat.h"  // for DrawType
#include "SkPictureStateTree.h"

class SkBitmap;
class SkCanvas;
class SkDrawPictureCallback;
class SkPaint;
class SkPictureData;

class SkPicturePlayback : SkNoncopyable {
public:
    SkPicturePlayback(const SkPicture* picture)
        : fPictureData(picture->fData.get())
        , fCurOffset(0)
        , fUseBBH(true)
        , fReplacements(NULL) {
    }
    virtual ~SkPicturePlayback() { }

    virtual void draw(SkCanvas* canvas, SkDrawPictureCallback*);

    // Return the ID of the operation currently being executed when playing
    // back. 0 indicates no call is active.
    size_t curOpID() const { return fCurOffset; }
    void resetOpID() { fCurOffset = 0; }

    void setUseBBH(bool useBBH) { fUseBBH = useBBH; }

    // PlaybackReplacements collects op ranges that can be replaced with
    // a single drawBitmap call (using a precomputed bitmap).
    class PlaybackReplacements {
    public:
        // All the operations between fStart and fStop (inclusive) will be replaced with
        // a single drawBitmap call using fPos, fBM and fPaint.
        // fPaint will be NULL if the picture's paint wasn't copyable
        struct ReplacementInfo {
            size_t          fStart;
            size_t          fStop;
            SkIPoint        fPos;
            SkBitmap*       fBM;     // fBM is allocated so ReplacementInfo can remain POD
            const SkPaint*  fPaint;  // Note: this object doesn't own the paint

            SkIRect         fSrcRect;
        };

        ~PlaybackReplacements() { this->freeAll(); }

        // Add a new replacement range. The replacement ranges should be
        // sorted in increasing order and non-overlapping (esp. no nested
        // saveLayers).
        ReplacementInfo* push();

    private:
        friend class SkPicturePlayback; // for access to lookupByStart

        // look up a replacement range by its start offset
        ReplacementInfo* lookupByStart(size_t start);

        void freeAll();

#ifdef SK_DEBUG
        void validate() const;
#endif

        SkTDArray<ReplacementInfo> fReplacements;
    };

    // Replace all the draw ops in the replacement ranges in 'replacements' with
    // the associated drawBitmap call
    // Draw replacing cannot be enabled at the same time as draw limiting
    void setReplacements(PlaybackReplacements* replacements) {
        fReplacements = replacements;
    }

protected:
    const SkPictureData* fPictureData;

    // The offset of the current operation when within the draw method
    size_t fCurOffset;

    bool   fUseBBH;
    PlaybackReplacements* fReplacements;

    void handleOp(SkReader32* reader, 
                  DrawType op, 
                  uint32_t size, 
                  SkCanvas* canvas,
                  const SkMatrix& initialMatrix);

    const SkPicture::OperationList* getActiveOps(const SkCanvas* canvas);
    bool initIterator(SkPictureStateTree::Iterator* iter, 
                      SkCanvas* canvas,
                      const SkPicture::OperationList *activeOpsList);
    static void StepIterator(SkPictureStateTree::Iterator* iter, SkReader32* reader);
    static void SkipIterTo(SkPictureStateTree::Iterator* iter, 
                           SkReader32* reader, uint32_t skipTo);
    bool replaceOps(SkPictureStateTree::Iterator* iter, 
                    SkReader32* reader, 
                    SkCanvas* canvas,
                    const SkMatrix& initialMatrix);

    static DrawType ReadOpAndSize(SkReader32* reader, uint32_t* size);

    class AutoResetOpID {
    public:
        AutoResetOpID(SkPicturePlayback* playback) : fPlayback(playback) { }
        ~AutoResetOpID() {
            if (NULL != fPlayback) {
                fPlayback->resetOpID();
            }
        }

    private:
        SkPicturePlayback* fPlayback;
    };

private:
    typedef SkNoncopyable INHERITED;
};

#endif