2 * Copyright (C) 2014 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <utils/LinearAllocator.h>
23 #include <utils/RefBase.h>
24 #include <utils/String8.h>
26 #include <cutils/compiler.h>
28 #include <androidfw/ResourceTypes.h>
30 #include "AnimatorManager.h"
32 #include "DisplayList.h"
34 #include "RenderProperties.h"
44 namespace uirenderer {
47 class DisplayListCanvas;
55 class OffscreenBuffer;
57 typedef OffscreenBuffer layer_t;
58 typedef RenderNodeOp renderNodeOp_t;
61 typedef Layer layer_t;
62 typedef DrawRenderNodeOp renderNodeOp_t;
66 class DrawRenderNodeOp;
69 class RestoreToCountOp;
78 * Primary class for storing recorded canvas commands, as well as per-View/ViewGroup display properties.
80 * Recording of canvas commands is somewhat similar to SkPicture, except the canvas-recording
81 * functionality is split between DisplayListCanvas (which manages the recording), DisplayList
82 * (which holds the actual data), and DisplayList (which holds properties and performs playback onto
85 * Note that DisplayList is swapped out from beneath an individual RenderNode when a view's
86 * recorded stream of canvas operations is refreshed. The RenderNode (and its properties) stay
89 class RenderNode : public VirtualLightRefBase {
90 friend class TestUtils; // allow TestUtils to access syncDisplayList / syncProperties
91 friend class FrameBuilder;
93 enum DirtyPropertyMask {
95 TRANSLATION_X = 1 << 2,
96 TRANSLATION_Y = 1 << 3,
97 TRANSLATION_Z = 1 << 4,
107 DISPLAY_LIST = 1 << 14,
110 ANDROID_API RenderNode();
111 ANDROID_API virtual ~RenderNode();
113 // See flags defined in DisplayList.java
115 kReplayFlag_ClipChildren = 0x1
118 void debugDumpLayers(const char* prefix);
120 ANDROID_API void setStagingDisplayList(DisplayList* newData, TreeObserver* observer);
122 void computeOrdering();
124 void defer(DeferStateStruct& deferStruct, const int level);
125 void replay(ReplayStateStruct& replayStruct, const int level);
128 ANDROID_API void output(uint32_t level = 0, const char* label = "Root");
130 ANDROID_API void output(uint32_t level = 1);
132 ANDROID_API int getDebugSize();
133 void copyTo(proto::RenderNode* node);
135 bool isRenderable() const {
136 return mDisplayList && !mDisplayList->isEmpty();
139 bool hasProjectionReceiver() const {
140 return mDisplayList && mDisplayList->projectionReceiveIndex >= 0;
143 const char* getName() const {
144 return mName.string();
147 void setName(const char* name) {
149 char* lastPeriod = strrchr(name, '.');
151 mName.setTo(lastPeriod + 1);
158 VirtualLightRefBase* getUserContext() const {
159 return mUserContext.get();
162 void setUserContext(VirtualLightRefBase* context) {
163 mUserContext = context;
166 bool isPropertyFieldDirty(DirtyPropertyMask field) const {
167 return mDirtyPropertyFields & field;
170 void setPropertyFieldsDirty(uint32_t fields) {
171 mDirtyPropertyFields |= fields;
174 const RenderProperties& properties() const {
178 RenderProperties& animatorProperties() {
182 const RenderProperties& stagingProperties() {
183 return mStagingProperties;
186 RenderProperties& mutateStagingProperties() {
187 return mStagingProperties;
190 int getWidth() const {
191 return properties().getWidth();
194 int getHeight() const {
195 return properties().getHeight();
198 ANDROID_API virtual void prepareTree(TreeInfo& info);
199 void destroyHardwareResources(TreeObserver* observer, TreeInfo* info = nullptr);
202 ANDROID_API void addAnimator(const sp<BaseRenderNodeAnimator>& animator);
203 void removeAnimator(const sp<BaseRenderNodeAnimator>& animator);
205 // This can only happen during pushStaging()
206 void onAnimatorTargetChanged(BaseRenderNodeAnimator* animator) {
207 mAnimatorManager.onAnimatorTargetChanged(animator);
210 AnimatorManager& animators() { return mAnimatorManager; }
212 void applyViewPropertyTransforms(mat4& matrix, bool true3dTransform = false) const;
214 bool nothingToDraw() const {
215 const Outline& outline = properties().getOutline();
216 return mDisplayList == nullptr
217 || properties().getAlpha() <= 0
218 || (outline.getShouldClip() && outline.isEmpty())
219 || properties().getScaleX() == 0
220 || properties().getScaleY() == 0;
223 const DisplayList* getDisplayList() const {
227 OffscreenBuffer* getLayer() const { return mLayer; }
228 OffscreenBuffer** getLayerHandle() { return &mLayer; } // ugh...
231 // Note: The position callbacks are relying on the listener using
232 // the frameNumber to appropriately batch/synchronize these transactions.
233 // There is no other filtering/batching to ensure that only the "final"
234 // state called once per frame.
235 class ANDROID_API PositionListener : public VirtualLightRefBase {
237 virtual ~PositionListener() {}
238 // Called when the RenderNode's position changes
239 virtual void onPositionUpdated(RenderNode& node, const TreeInfo& info) = 0;
240 // Called when the RenderNode no longer has a position. As in, it's
241 // no longer being drawn.
242 // Note, tree info might be null
243 virtual void onPositionLost(RenderNode& node, const TreeInfo* info) = 0;
246 // Note this is not thread safe, this needs to be called
247 // before the RenderNode is used for drawing.
248 // RenderNode takes ownership of the pointer
249 ANDROID_API void setPositionListener(PositionListener* listener) {
250 mPositionListener = listener;
253 // This is only modified in MODE_FULL, so it can be safely accessed
255 ANDROID_API bool hasParents() {
260 typedef key_value_pair_t<float, DrawRenderNodeOp*> ZDrawRenderNodeOpPair;
262 static size_t findNonNegativeIndex(const std::vector<ZDrawRenderNodeOpPair>& nodes) {
263 for (size_t i = 0; i < nodes.size(); i++) {
264 if (nodes[i].key >= 0.0f) return i;
269 enum class ChildrenSelectMode {
274 void computeOrderingImpl(renderNodeOp_t* opState,
275 std::vector<renderNodeOp_t*>* compositedChildrenOfProjectionSurface,
276 const mat4* transformFromProjectionSurface);
279 inline void setViewProperties(OpenGLRenderer& renderer, T& handler);
281 void buildZSortedChildList(const DisplayList::Chunk& chunk,
282 std::vector<ZDrawRenderNodeOpPair>& zTranslatedNodes);
285 inline void issueDrawShadowOperation(const Matrix4& transformFromParent, T& handler);
288 inline void issueOperationsOf3dChildren(ChildrenSelectMode mode,
289 const Matrix4& initialTransform, const std::vector<ZDrawRenderNodeOpPair>& zTranslatedNodes,
290 OpenGLRenderer& renderer, T& handler);
293 inline void issueOperationsOfProjectedChildren(OpenGLRenderer& renderer, T& handler);
296 * Issue the RenderNode's operations into a handler, recursing for subtrees through
297 * DrawRenderNodeOp's defer() or replay() methods
300 inline void issueOperations(OpenGLRenderer& renderer, T& handler);
302 class TextContainer {
304 size_t length() const {
308 const char* text() const {
309 return (const char*) mText;
317 void syncProperties();
318 void syncDisplayList(TreeInfo* info);
320 void prepareTreeImpl(TreeInfo& info, bool functorsNeedLayer);
321 void pushStagingPropertiesChanges(TreeInfo& info);
322 void pushStagingDisplayListChanges(TreeInfo& info);
323 void prepareSubTree(TreeInfo& info, bool functorsNeedLayer, DisplayList* subtree);
325 void applyLayerPropertiesToLayer(TreeInfo& info);
327 void prepareLayer(TreeInfo& info, uint32_t dirtyMask);
328 void pushLayerUpdate(TreeInfo& info);
329 void deleteDisplayList(TreeObserver* observer, TreeInfo* info = nullptr);
330 void damageSelf(TreeInfo& info);
332 void incParentRefCount() { mParentCount++; }
333 void decParentRefCount(TreeObserver* observer, TreeInfo* info = nullptr);
336 sp<VirtualLightRefBase> mUserContext;
338 uint32_t mDirtyPropertyFields;
339 RenderProperties mProperties;
340 RenderProperties mStagingProperties;
342 bool mNeedsDisplayListSync;
343 // WARNING: Do not delete this directly, you must go through deleteDisplayList()!
344 DisplayList* mDisplayList;
345 DisplayList* mStagingDisplayList;
347 friend class AnimatorManager;
348 AnimatorManager mAnimatorManager;
350 // Owned by RT. Lifecycle is managed by prepareTree(), with the exception
351 // being in ~RenderNode() which may happen on any thread.
352 layer_t* mLayer = nullptr;
355 * Draw time state - these properties are only set and used during rendering
358 // for projection surfaces, contains a list of all children items
359 std::vector<renderNodeOp_t*> mProjectedNodes;
361 // How many references our parent(s) have to us. Typically this should alternate
362 // between 2 and 1 (when a staging push happens we inc first then dec)
363 // When this hits 0 we are no longer in the tree, so any hardware resources
364 // (specifically Layers) should be released.
365 // This is *NOT* thread-safe, and should therefore only be tracking
366 // mDisplayList, not mStagingDisplayList.
367 uint32_t mParentCount;
369 sp<PositionListener> mPositionListener;
370 }; // class RenderNode
372 } /* namespace uirenderer */
373 } /* namespace android */
375 #endif /* RENDERNODE_H */