RenderNode.h revision c3849aa786db65dbda254b90b7db3b13efd98e65
1/* 2 * Copyright (C) 2014 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 <SkCamera.h> 20#include <SkMatrix.h> 21 22#include <utils/LinearAllocator.h> 23#include <utils/RefBase.h> 24#include <utils/String8.h> 25 26#include <cutils/compiler.h> 27 28#include <androidfw/ResourceTypes.h> 29 30#include "AnimatorManager.h" 31#include "Debug.h" 32#include "DisplayList.h" 33#include "Matrix.h" 34#include "RenderProperties.h" 35 36#include <vector> 37 38class SkBitmap; 39class SkPaint; 40class SkPath; 41class SkRegion; 42 43namespace android { 44namespace uirenderer { 45 46class CanvasState; 47class DisplayListOp; 48class FrameBuilder; 49class OffscreenBuffer; 50class Rect; 51class SkiaShader; 52struct RenderNodeOp; 53 54class TreeInfo; 55class TreeObserver; 56 57namespace proto { 58class RenderNode; 59} 60 61/** 62 * Primary class for storing recorded canvas commands, as well as per-View/ViewGroup display properties. 63 * 64 * Recording of canvas commands is somewhat similar to SkPicture, except the canvas-recording 65 * functionality is split between RecordingCanvas (which manages the recording), DisplayList 66 * (which holds the actual data), and RenderNode (which holds properties used for render playback). 67 * 68 * Note that DisplayList is swapped out from beneath an individual RenderNode when a view's 69 * recorded stream of canvas operations is refreshed. The RenderNode (and its properties) stay 70 * attached. 71 */ 72class RenderNode : public VirtualLightRefBase { 73friend class TestUtils; // allow TestUtils to access syncDisplayList / syncProperties 74friend class FrameBuilder; 75public: 76 enum DirtyPropertyMask { 77 GENERIC = 1 << 1, 78 TRANSLATION_X = 1 << 2, 79 TRANSLATION_Y = 1 << 3, 80 TRANSLATION_Z = 1 << 4, 81 SCALE_X = 1 << 5, 82 SCALE_Y = 1 << 6, 83 ROTATION = 1 << 7, 84 ROTATION_X = 1 << 8, 85 ROTATION_Y = 1 << 9, 86 X = 1 << 10, 87 Y = 1 << 11, 88 Z = 1 << 12, 89 ALPHA = 1 << 13, 90 DISPLAY_LIST = 1 << 14, 91 }; 92 93 ANDROID_API RenderNode(); 94 ANDROID_API virtual ~RenderNode(); 95 96 // See flags defined in DisplayList.java 97 enum ReplayFlag { 98 kReplayFlag_ClipChildren = 0x1 99 }; 100 101 ANDROID_API void setStagingDisplayList(DisplayList* newData, TreeObserver* observer); 102 103 void computeOrdering(); 104 105 ANDROID_API void output(); 106 ANDROID_API int getDebugSize(); 107 void copyTo(proto::RenderNode* node); 108 109 bool isRenderable() const { 110 return mDisplayList && !mDisplayList->isEmpty(); 111 } 112 113 bool hasProjectionReceiver() const { 114 return mDisplayList && mDisplayList->projectionReceiveIndex >= 0; 115 } 116 117 const char* getName() const { 118 return mName.string(); 119 } 120 121 void setName(const char* name) { 122 if (name) { 123 const char* lastPeriod = strrchr(name, '.'); 124 if (lastPeriod) { 125 mName.setTo(lastPeriod + 1); 126 } else { 127 mName.setTo(name); 128 } 129 } 130 } 131 132 VirtualLightRefBase* getUserContext() const { 133 return mUserContext.get(); 134 } 135 136 void setUserContext(VirtualLightRefBase* context) { 137 mUserContext = context; 138 } 139 140 bool isPropertyFieldDirty(DirtyPropertyMask field) const { 141 return mDirtyPropertyFields & field; 142 } 143 144 void setPropertyFieldsDirty(uint32_t fields) { 145 mDirtyPropertyFields |= fields; 146 } 147 148 const RenderProperties& properties() const { 149 return mProperties; 150 } 151 152 RenderProperties& animatorProperties() { 153 return mProperties; 154 } 155 156 const RenderProperties& stagingProperties() { 157 return mStagingProperties; 158 } 159 160 RenderProperties& mutateStagingProperties() { 161 return mStagingProperties; 162 } 163 164 int getWidth() const { 165 return properties().getWidth(); 166 } 167 168 int getHeight() const { 169 return properties().getHeight(); 170 } 171 172 ANDROID_API virtual void prepareTree(TreeInfo& info); 173 void destroyHardwareResources(TreeObserver* observer, TreeInfo* info = nullptr); 174 175 // UI thread only! 176 ANDROID_API void addAnimator(const sp<BaseRenderNodeAnimator>& animator); 177 void removeAnimator(const sp<BaseRenderNodeAnimator>& animator); 178 179 // This can only happen during pushStaging() 180 void onAnimatorTargetChanged(BaseRenderNodeAnimator* animator) { 181 mAnimatorManager.onAnimatorTargetChanged(animator); 182 } 183 184 AnimatorManager& animators() { return mAnimatorManager; } 185 186 void applyViewPropertyTransforms(mat4& matrix, bool true3dTransform = false) const; 187 188 bool nothingToDraw() const { 189 const Outline& outline = properties().getOutline(); 190 return mDisplayList == nullptr 191 || properties().getAlpha() <= 0 192 || (outline.getShouldClip() && outline.isEmpty()) 193 || properties().getScaleX() == 0 194 || properties().getScaleY() == 0; 195 } 196 197 const DisplayList* getDisplayList() const { 198 return mDisplayList; 199 } 200 OffscreenBuffer* getLayer() const { return mLayer; } 201 OffscreenBuffer** getLayerHandle() { return &mLayer; } // ugh... 202 203 // Note: The position callbacks are relying on the listener using 204 // the frameNumber to appropriately batch/synchronize these transactions. 205 // There is no other filtering/batching to ensure that only the "final" 206 // state called once per frame. 207 class ANDROID_API PositionListener : public VirtualLightRefBase { 208 public: 209 virtual ~PositionListener() {} 210 // Called when the RenderNode's position changes 211 virtual void onPositionUpdated(RenderNode& node, const TreeInfo& info) = 0; 212 // Called when the RenderNode no longer has a position. As in, it's 213 // no longer being drawn. 214 // Note, tree info might be null 215 virtual void onPositionLost(RenderNode& node, const TreeInfo* info) = 0; 216 }; 217 218 // Note this is not thread safe, this needs to be called 219 // before the RenderNode is used for drawing. 220 // RenderNode takes ownership of the pointer 221 ANDROID_API void setPositionListener(PositionListener* listener) { 222 mPositionListener = listener; 223 } 224 225 // This is only modified in MODE_FULL, so it can be safely accessed 226 // on the UI thread. 227 ANDROID_API bool hasParents() { 228 return mParentCount; 229 } 230 231private: 232 void computeOrderingImpl(RenderNodeOp* opState, 233 std::vector<RenderNodeOp*>* compositedChildrenOfProjectionSurface, 234 const mat4* transformFromProjectionSurface); 235 236 void syncProperties(); 237 void syncDisplayList(TreeInfo* info); 238 239 void prepareTreeImpl(TreeInfo& info, bool functorsNeedLayer); 240 void pushStagingPropertiesChanges(TreeInfo& info); 241 void pushStagingDisplayListChanges(TreeInfo& info); 242 void prepareSubTree(TreeInfo& info, bool functorsNeedLayer, DisplayList* subtree); 243 void prepareLayer(TreeInfo& info, uint32_t dirtyMask); 244 void pushLayerUpdate(TreeInfo& info); 245 void deleteDisplayList(TreeObserver* observer, TreeInfo* info = nullptr); 246 void damageSelf(TreeInfo& info); 247 248 void incParentRefCount() { mParentCount++; } 249 void decParentRefCount(TreeObserver* observer, TreeInfo* info = nullptr); 250 void output(std::ostream& output, uint32_t level); 251 252 String8 mName; 253 sp<VirtualLightRefBase> mUserContext; 254 255 uint32_t mDirtyPropertyFields; 256 RenderProperties mProperties; 257 RenderProperties mStagingProperties; 258 259 bool mNeedsDisplayListSync; 260 // WARNING: Do not delete this directly, you must go through deleteDisplayList()! 261 DisplayList* mDisplayList; 262 DisplayList* mStagingDisplayList; 263 264 friend class AnimatorManager; 265 AnimatorManager mAnimatorManager; 266 267 // Owned by RT. Lifecycle is managed by prepareTree(), with the exception 268 // being in ~RenderNode() which may happen on any thread. 269 OffscreenBuffer* mLayer = nullptr; 270 271 /** 272 * Draw time state - these properties are only set and used during rendering 273 */ 274 275 // for projection surfaces, contains a list of all children items 276 std::vector<RenderNodeOp*> mProjectedNodes; 277 278 // How many references our parent(s) have to us. Typically this should alternate 279 // between 2 and 1 (when a staging push happens we inc first then dec) 280 // When this hits 0 we are no longer in the tree, so any hardware resources 281 // (specifically Layers) should be released. 282 // This is *NOT* thread-safe, and should therefore only be tracking 283 // mDisplayList, not mStagingDisplayList. 284 uint32_t mParentCount; 285 286 sp<PositionListener> mPositionListener; 287}; // class RenderNode 288 289} /* namespace uirenderer */ 290} /* namespace android */ 291