1 /*
2  * Copyright (C) 2013 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 #ifndef ANDROID_HWUI_DISPLAY_LIST_H
18 #define ANDROID_HWUI_DISPLAY_LIST_H
19 
20 #include <SkCamera.h>
21 #include <SkMatrix.h>
22 
23 #include <private/hwui/DrawGlInfo.h>
24 
25 #include <utils/KeyedVector.h>
26 #include <utils/LinearAllocator.h>
27 #include <utils/RefBase.h>
28 #include <utils/SortedVector.h>
29 #include <utils/String8.h>
30 
31 #include <cutils/compiler.h>
32 
33 #include <androidfw/ResourceTypes.h>
34 
35 #include "Debug.h"
36 #include "CanvasProperty.h"
37 #include "DeferredDisplayList.h"
38 #include "GlFunctorLifecycleListener.h"
39 #include "Matrix.h"
40 #include "RenderProperties.h"
41 
42 #include <vector>
43 
44 class SkBitmap;
45 class SkPaint;
46 class SkPath;
47 class SkRegion;
48 
49 namespace android {
50 namespace uirenderer {
51 
52 class DeferredDisplayList;
53 class DisplayListOp;
54 class DisplayListCanvas;
55 class OpenGLRenderer;
56 class Rect;
57 class Layer;
58 
59 #if HWUI_NEW_OPS
60 struct RecordedOp;
61 struct RenderNodeOp;
62 
63 typedef RecordedOp BaseOpType;
64 typedef RenderNodeOp NodeOpType;
65 #else
66 class DrawRenderNodeOp;
67 
68 typedef DisplayListOp BaseOpType;
69 typedef DrawRenderNodeOp NodeOpType;
70 #endif
71 
72 /**
73  * Holds data used in the playback a tree of DisplayLists.
74  */
75 struct PlaybackStateStruct {
76 protected:
PlaybackStateStructPlaybackStateStruct77     PlaybackStateStruct(OpenGLRenderer& renderer, int replayFlags, LinearAllocator* allocator)
78             : mRenderer(renderer)
79             , mReplayFlags(replayFlags)
80             , mAllocator(allocator) {}
81 
82 public:
83     OpenGLRenderer& mRenderer;
84     const int mReplayFlags;
85 
86     // Allocator with the lifetime of a single frame. replay uses an Allocator owned by the struct,
87     // while defer shares the DeferredDisplayList's Allocator
88     // TODO: move this allocator to be owned by object with clear frame lifecycle
89     LinearAllocator * const mAllocator;
90 
allocPathForFramePlaybackStateStruct91     SkPath* allocPathForFrame() {
92         return mRenderer.allocPathForFrame();
93     }
94 };
95 
96 struct DeferStateStruct : public PlaybackStateStruct {
DeferStateStructDeferStateStruct97     DeferStateStruct(DeferredDisplayList& deferredList, OpenGLRenderer& renderer, int replayFlags)
98             : PlaybackStateStruct(renderer, replayFlags, &(deferredList.mAllocator)),
99             mDeferredList(deferredList) {}
100 
101     DeferredDisplayList& mDeferredList;
102 };
103 
104 struct ReplayStateStruct : public PlaybackStateStruct {
ReplayStateStructReplayStateStruct105     ReplayStateStruct(OpenGLRenderer& renderer, Rect& dirty, int replayFlags)
106             : PlaybackStateStruct(renderer, replayFlags, &mReplayAllocator),
107             mDirty(dirty) {}
108 
109     Rect& mDirty;
110     LinearAllocator mReplayAllocator;
111 };
112 
113 /**
114  * Functor that can be used for objects with data in both UI thread and RT to keep the data
115  * in sync. This functor, when added to DisplayList, will be call during DisplayList sync.
116  */
117 struct PushStagingFunctor {
PushStagingFunctorPushStagingFunctor118     PushStagingFunctor() {}
~PushStagingFunctorPushStagingFunctor119     virtual ~PushStagingFunctor() {}
operatorPushStagingFunctor120     virtual void operator ()() {}
121 };
122 
123 struct FunctorContainer {
124     Functor* functor;
125     GlFunctorLifecycleListener* listener;
126 };
127 
128 /**
129  * Data structure that holds the list of commands used in display list stream
130  */
131 class DisplayList {
132     friend class DisplayListCanvas;
133     friend class RecordingCanvas;
134 public:
135     struct Chunk {
136         // range of included ops in DisplayList::ops()
137         size_t beginOpIndex;
138         size_t endOpIndex;
139 
140         // range of included children in DisplayList::children()
141         size_t beginChildIndex;
142         size_t endChildIndex;
143 
144         // whether children with non-zero Z in the chunk should be reordered
145         bool reorderChildren;
146 #if HWUI_NEW_OPS
147         const ClipBase* reorderClip;
148 #endif
149     };
150 
151     DisplayList();
152     ~DisplayList();
153 
154     // index of DisplayListOp restore, after which projected descendants should be drawn
155     int projectionReceiveIndex;
156 
getChunks()157     const LsaVector<Chunk>& getChunks() const { return chunks; }
getOps()158     const LsaVector<BaseOpType*>& getOps() const { return ops; }
159 
getChildren()160     const LsaVector<NodeOpType*>& getChildren() const { return children; }
161 
getBitmapResources()162     const LsaVector<const SkBitmap*>& getBitmapResources() const { return bitmapResources; }
getFunctors()163     const LsaVector<FunctorContainer>& getFunctors() const { return functors; }
getPushStagingFunctors()164     const LsaVector<PushStagingFunctor*>& getPushStagingFunctors() { return pushStagingFunctors; }
165 
166     size_t addChild(NodeOpType* childOp);
167 
168 
ref(VirtualLightRefBase * prop)169     void ref(VirtualLightRefBase* prop) {
170         referenceHolders.push_back(prop);
171     }
172 
getUsedSize()173     size_t getUsedSize() {
174         return allocator.usedSize();
175     }
isEmpty()176     bool isEmpty() {
177 #if HWUI_NEW_OPS
178         return ops.empty();
179 #else
180         return !hasDrawOps;
181 #endif
182     }
183 
184 private:
185     // allocator into which all ops and LsaVector arrays allocated
186     LinearAllocator allocator;
187     LinearStdAllocator<void*> stdAllocator;
188 
189     LsaVector<Chunk> chunks;
190     LsaVector<BaseOpType*> ops;
191 
192     // list of Ops referring to RenderNode children for quick, non-drawing traversal
193     LsaVector<NodeOpType*> children;
194 
195     // Resources - Skia objects + 9 patches referred to by this DisplayList
196     LsaVector<const SkBitmap*> bitmapResources;
197     LsaVector<const SkPath*> pathResources;
198     LsaVector<const Res_png_9patch*> patchResources;
199     LsaVector<std::unique_ptr<const SkPaint>> paints;
200     LsaVector<std::unique_ptr<const SkRegion>> regions;
201     LsaVector< sp<VirtualLightRefBase> > referenceHolders;
202 
203     // List of functors
204     LsaVector<FunctorContainer> functors;
205 
206     // List of functors that need to be notified of pushStaging. Note that this list gets nothing
207     // but a callback during sync DisplayList, unlike the list of functors defined above, which
208     // gets special treatment exclusive for webview.
209     LsaVector<PushStagingFunctor*> pushStagingFunctors;
210 
211     bool hasDrawOps; // only used if !HWUI_NEW_OPS
212 
213     void cleanupResources();
214 };
215 
216 }; // namespace uirenderer
217 }; // namespace android
218 
219 #endif // ANDROID_HWUI_OPENGL_RENDERER_H
220