File: SkiaDisplayList.h

package info (click to toggle)
android-platform-frameworks-base 1%3A14~beta1-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 326,092 kB
  • sloc: java: 2,032,373; xml: 343,016; cpp: 304,181; python: 3,683; ansic: 2,090; sh: 1,871; makefile: 117; sed: 19
file content (213 lines) | stat: -rw-r--r-- 7,456 bytes parent folder | download | duplicates (2)
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <deque>

#include "RecordingCanvas.h"
#include "RenderNodeDrawable.h"
#include "TreeInfo.h"
#include "hwui/AnimatedImageDrawable.h"
#include "utils/LinearAllocator.h"
#include "utils/Pair.h"

namespace android {
namespace uirenderer {

namespace renderthread {
class CanvasContext;
}

class Outline;
struct WebViewSyncData;

namespace VectorDrawable {
class Tree;
}
typedef uirenderer::VectorDrawable::Tree VectorDrawableRoot;

namespace skiapipeline {

class FunctorDrawable;

class SkiaDisplayList {
public:
    size_t getUsedSize() const { return allocator.usedSize() + mDisplayList.usedSize(); }
    size_t getAllocatedSize() const {
        return allocator.allocatedSize() + mDisplayList.allocatedSize();
    }

    ~SkiaDisplayList() {
        /* Given that we are using a LinearStdAllocator to store some of the
         * SkDrawable contents we must ensure that any other object that is
         * holding a reference to those drawables is destroyed prior to their
         * deletion.
         */
        mDisplayList.reset();
    }

    /**
     * This resets the DisplayList so that it behaves as if the object were newly
     * constructed.  The reuse avoids any overhead associated with destroying
     * the SkLiteDL as well as the deques and vectors.
     */
    void reset();

    /**
     * Use the linear allocator to create any SkDrawables needed by the display
     * list. This could be dangerous as these objects are ref-counted, so we
     * need to monitor that they don't extend beyond the lifetime of the class
     * that creates them. Allocator dtor invokes all SkDrawable dtors.
     */
    template <class T, typename... Params>
    T* allocateDrawable(Params&&... params) {
        return allocator.create<T>(std::forward<Params>(params)...);
    }

    /**
     * Returns true if the DisplayList does not have any recorded content
     */
    bool isEmpty() const { return mDisplayList.empty(); }

    /**
     * Returns true if this list directly contains a GLFunctor drawing command.
     */
    bool hasFunctor() const { return !mChildFunctors.empty(); }

    /**
     * Returns true if this list directly contains a VectorDrawable drawing command.
     */
    bool hasVectorDrawables() const { return !mVectorDrawables.empty(); }

    bool hasText() const { return mDisplayList.hasText(); }

    /**
     * Attempts to reset and reuse this DisplayList.
     *
     * @return true if the displayList will be reused and therefore should not be deleted
     */
    bool reuseDisplayList(RenderNode* node);

    /**
     * ONLY to be called by RenderNode::syncDisplayList so that we can notify any
     * contained VectorDrawables or GLFunctors to sync their state.
     *
     * NOTE: This function can be folded into RenderNode when we no longer need
     *       to subclass from DisplayList
     */
    void syncContents(const WebViewSyncData& data);

    /**
     * ONLY to be called by RenderNode::onRemovedFromTree so that we can notify any
     * contained VectorDrawables or GLFunctors.
     *
     */
    void onRemovedFromTree();

    void applyColorTransform(ColorTransform transform) {
        mDisplayList.applyColorTransform(transform);
    }

    /**
     * ONLY to be called by RenderNode::prepareTree in order to prepare this
     * list while the UI thread is blocked.  Here we can upload mutable bitmaps
     * and notify our parent if any of our content has been invalidated and in
     * need of a redraw.  If the renderNode has any children then they are also
     * call in order to prepare them.
     *
     * @return true if any content change requires the node to be invalidated
     *
     * NOTE: This function can be folded into RenderNode when we no longer need
     *       to subclass from DisplayList
     */

    bool prepareListAndChildren(
            TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer,
            std::function<void(RenderNode*, TreeObserver&, TreeInfo&, bool)> childFn);

    /**
     *  Calls the provided function once for each child of this DisplayList
     */
    void updateChildren(std::function<void(RenderNode*)> updateFn);

    /**
     *  Returns true if there is a child render node that is a projection receiver.
     */
    inline bool containsProjectionReceiver() const { return mProjectionReceiver; }

    void attachRecorder(RecordingCanvas* recorder, const SkIRect& bounds) {
        recorder->reset(&mDisplayList, bounds);
    }

    void draw(SkCanvas* canvas) { mDisplayList.draw(canvas); }

    void output(std::ostream& output, uint32_t level) const;

    LinearAllocator allocator;

    /**
     * We use std::deque here because (1) we need to iterate through these
     * elements and (2) mDisplayList holds pointers to the elements, so they
     * cannot relocate.
     */
    std::deque<RenderNodeDrawable> mChildNodes;
    std::deque<FunctorDrawable*> mChildFunctors;
    std::vector<SkImage*> mMutableImages;

private:
    std::vector<Pair<VectorDrawableRoot*, SkMatrix>> mVectorDrawables;
    bool mHasHolePunches;
public:
    void appendVD(VectorDrawableRoot* r) { appendVD(r, SkMatrix::I()); }

    void appendVD(VectorDrawableRoot* r, const SkMatrix& mat) {
        mVectorDrawables.push_back(Pair<VectorDrawableRoot*, SkMatrix>(r, mat));
    }

    void setHasHolePunches(bool hasHolePunches) {
        mHasHolePunches = hasHolePunches;
    }

    bool hasHolePunches() {
        return mHasHolePunches;
    }

    std::vector<AnimatedImageDrawable*> mAnimatedImages;
    DisplayListData mDisplayList;

    // mProjectionReceiver points to a child node (stored in mChildNodes) that is as a projection
    // receiver. It is set at record time and used at both prepare and draw tree traversals to
    // make sure backward projected nodes are found and drawn immediately after mProjectionReceiver.
    RenderNodeDrawable* mProjectionReceiver = nullptr;

    // mProjectedOutline is valid only when render node tree is traversed during the draw pass.
    // Render nodes that have a child receiver node, will store a pointer to their outline in
    // mProjectedOutline. Child receiver node will apply the clip before any backward projected
    // node is drawn.
    const Outline* mProjectedOutline = nullptr;

    // mParentMatrix is set and valid when render node tree is traversed during the draw
    // pass. Render nodes, which draw in a order different than recording order (e.g. nodes with a
    // child receiver node or Z elevation), can use mParentMatrix to calculate the final transform
    // without replaying the matrix transform OPs from the display list.
    // Child receiver node will set the matrix and then clip with the outline of their parent.
    SkMatrix mParentMatrix;
};

}  // namespace skiapipeline
}  // namespace uirenderer
}  // namespace android