• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include "DisplayList.h"
20 #include "hwui/AnimatedImageDrawable.h"
21 #include "GLFunctorDrawable.h"
22 #include "RenderNodeDrawable.h"
23 
24 #include <SkLiteDL.h>
25 #include <SkLiteRecorder.h>
26 #include <deque>
27 
28 namespace android {
29 namespace uirenderer {
30 
31 class Outline;
32 
33 namespace skiapipeline {
34 
35 /**
36  * This class is intended to be self contained, but still subclasses from
37  * DisplayList to make it easier to support switching between the two at
38  * runtime.  The downside of this inheritance is that we pay for the overhead
39  * of the parent class construction/destruction without any real benefit.
40  */
41 class SkiaDisplayList : public DisplayList {
42 public:
SkiaDisplayList()43     SkiaDisplayList() { SkASSERT(projectionReceiveIndex == -1); }
~SkiaDisplayList()44     virtual ~SkiaDisplayList() {
45         /* Given that we are using a LinearStdAllocator to store some of the
46          * SkDrawable contents we must ensure that any other object that is
47          * holding a reference to those drawables is destroyed prior to their
48          * deletion.
49          */
50         mDisplayList.reset();
51     }
52 
53     /**
54      * This resets the DisplayList so that it behaves as if the object were newly
55      * constructed.  The reuse avoids any overhead associated with destroying
56      * the SkLiteDL as well as the deques and vectors.
57      */
58     void reset();
59 
60     /**
61      * Use the linear allocator to create any SkDrawables needed by the display
62      * list. This could be dangerous as these objects are ref-counted, so we
63      * need to monitor that they don't extend beyond the lifetime of the class
64      * that creates them. Allocator dtor invokes all SkDrawable dtors.
65      */
66     template <class T, typename... Params>
allocateDrawable(Params &&...params)67     SkDrawable* allocateDrawable(Params&&... params) {
68         return allocator.create<T>(std::forward<Params>(params)...);
69     }
70 
isSkiaDL()71     bool isSkiaDL() const override { return true; }
72 
73     /**
74      * Returns true if the DisplayList does not have any recorded content
75      */
isEmpty()76     bool isEmpty() const override { return mDisplayList.empty(); }
77 
78     /**
79      * Returns true if this list directly contains a GLFunctor drawing command.
80      */
hasFunctor()81     bool hasFunctor() const override { return !mChildFunctors.empty(); }
82 
83     /**
84      * Returns true if this list directly contains a VectorDrawable drawing command.
85      */
hasVectorDrawables()86     bool hasVectorDrawables() const override { return !mVectorDrawables.empty(); }
87 
88     /**
89      * Attempts to reset and reuse this DisplayList.
90      *
91      * @return true if the displayList will be reused and therefore should not be deleted
92      */
93     bool reuseDisplayList(RenderNode* node, renderthread::CanvasContext* context) override;
94 
95     /**
96      * ONLY to be called by RenderNode::syncDisplayList so that we can notify any
97      * contained VectorDrawables or GLFunctors to sync their state.
98      *
99      * NOTE: This function can be folded into RenderNode when we no longer need
100      *       to subclass from DisplayList
101      */
102     void syncContents() override;
103 
104     /**
105      * ONLY to be called by RenderNode::prepareTree in order to prepare this
106      * list while the UI thread is blocked.  Here we can upload mutable bitmaps
107      * and notify our parent if any of our content has been invalidated and in
108      * need of a redraw.  If the renderNode has any children then they are also
109      * call in order to prepare them.
110      *
111      * @return true if any content change requires the node to be invalidated
112      *
113      * NOTE: This function can be folded into RenderNode when we no longer need
114      *       to subclass from DisplayList
115      */
116 
117     bool prepareListAndChildren(
118             TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer,
119             std::function<void(RenderNode*, TreeObserver&, TreeInfo&, bool)> childFn) override;
120 
121     /**
122      *  Calls the provided function once for each child of this DisplayList
123      */
124     void updateChildren(std::function<void(RenderNode*)> updateFn) override;
125 
126     /**
127      *  Returns true if there is a child render node that is a projection receiver.
128      */
containsProjectionReceiver()129     inline bool containsProjectionReceiver() const { return mProjectionReceiver; }
130 
attachRecorder(SkLiteRecorder * recorder,const SkIRect & bounds)131     void attachRecorder(SkLiteRecorder* recorder, const SkIRect& bounds) {
132         recorder->reset(&mDisplayList, bounds);
133     }
134 
draw(SkCanvas * canvas)135     void draw(SkCanvas* canvas) { mDisplayList.draw(canvas); }
136 
137     void output(std::ostream& output, uint32_t level) override;
138 
139     /**
140      * We use std::deque here because (1) we need to iterate through these
141      * elements and (2) mDisplayList holds pointers to the elements, so they
142      * cannot relocate.
143      */
144     std::deque<RenderNodeDrawable> mChildNodes;
145     std::deque<GLFunctorDrawable> mChildFunctors;
146     std::vector<SkImage*> mMutableImages;
147     std::vector<VectorDrawableRoot*> mVectorDrawables;
148     std::vector<AnimatedImageDrawable*> mAnimatedImages;
149     SkLiteDL mDisplayList;
150 
151     // mProjectionReceiver points to a child node (stored in mChildNodes) that is as a projection
152     // receiver. It is set at record time and used at both prepare and draw tree traversals to
153     // make sure backward projected nodes are found and drawn immediately after mProjectionReceiver.
154     RenderNodeDrawable* mProjectionReceiver = nullptr;
155 
156     // mProjectedOutline is valid only when render node tree is traversed during the draw pass.
157     // Render nodes that have a child receiver node, will store a pointer to their outline in
158     // mProjectedOutline. Child receiver node will apply the clip before any backward projected
159     // node is drawn.
160     const Outline* mProjectedOutline = nullptr;
161 
162     // mProjectedReceiverParentMatrix is valid when render node tree is traversed during the draw
163     // pass. Render nodes that have a child receiver node, will store their matrix in
164     // mProjectedReceiverParentMatrix. Child receiver node will set the matrix and then clip with
165     // the
166     // outline of their parent.
167     SkMatrix mProjectedReceiverParentMatrix;
168 };
169 
170 };  // namespace skiapipeline
171 };  // namespace uirenderer
172 };  // namespace android
173