File: SkiaDisplayList.h

package info (click to toggle)
android-platform-frameworks-base 1%3A8.1.0%2Br23-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 179,108 kB
  • sloc: java: 783,264; cpp: 234,851; xml: 204,638; python: 2,837; ansic: 366; sh: 274; makefile: 43; sed: 19
file content (168 lines) | stat: -rw-r--r-- 6,488 bytes parent folder | download
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
/*
 * 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 "DisplayList.h"
#include "GLFunctorDrawable.h"
#include "RenderNodeDrawable.h"

#include <deque>
#include <SkLiteDL.h>
#include <SkLiteRecorder.h>

namespace android {
namespace uirenderer {

class Outline;

namespace skiapipeline {

/**
 * This class is intended to be self contained, but still subclasses from
 * DisplayList to make it easier to support switching between the two at
 * runtime.  The downside of this inheritance is that we pay for the overhead
 * of the parent class construction/destruction without any real benefit.
 */
class SkiaDisplayList : public DisplayList {
public:
    SkiaDisplayList() { SkASSERT(projectionReceiveIndex == -1); }
    virtual ~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>
    SkDrawable* allocateDrawable(Params&&... params) {
        return allocator.create<T>(std::forward<Params>(params)...);
    }

    bool isSkiaDL() const override { return true; }

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

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

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

    /**
     * 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, renderthread::CanvasContext* context) override;

    /**
     * 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() override;

    /**
     * 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) override;

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

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

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

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

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

    /**
     * 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<GLFunctorDrawable> mChildFunctors;
    std::vector<SkImage*> mMutableImages;
    std::vector<VectorDrawableRoot*> mVectorDrawables;
    SkLiteDL 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;

    //mProjectedReceiverParentMatrix is valid when render node tree is traversed during the draw
    //pass. Render nodes that have a child receiver node, will store their matrix in
    //mProjectedReceiverParentMatrix. Child receiver node will set the matrix and then clip with the
    //outline of their parent.
    SkMatrix mProjectedReceiverParentMatrix;
};

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