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 #ifndef RENDERNODE_H 17 #define RENDERNODE_H 18 19 #ifndef LOG_TAG 20 #define LOG_TAG "OpenGLRenderer" 21 #endif 22 23 #include <SkCamera.h> 24 #include <SkMatrix.h> 25 26 #include <utils/LinearAllocator.h> 27 #include <utils/RefBase.h> 28 #include <utils/String8.h> 29 #include <utils/Vector.h> 30 31 #include <cutils/compiler.h> 32 33 #include <androidfw/ResourceTypes.h> 34 35 #include "AnimatorManager.h" 36 #include "DamageAccumulator.h" 37 #include "Debug.h" 38 #include "Matrix.h" 39 #include "DeferredDisplayList.h" 40 #include "DisplayList.h" 41 #include "RenderProperties.h" 42 #include "TreeInfo.h" 43 44 class SkBitmap; 45 class SkPaint; 46 class SkPath; 47 class SkRegion; 48 49 namespace android { 50 namespace uirenderer { 51 52 class DisplayListOp; 53 class DisplayListRenderer; 54 class OpenGLRenderer; 55 class Rect; 56 class Layer; 57 class SkiaShader; 58 59 class ClipRectOp; 60 class SaveLayerOp; 61 class SaveOp; 62 class RestoreToCountOp; 63 class DrawRenderNodeOp; 64 65 /** 66 * Primary class for storing recorded canvas commands, as well as per-View/ViewGroup display properties. 67 * 68 * Recording of canvas commands is somewhat similar to SkPicture, except the canvas-recording 69 * functionality is split between DisplayListRenderer (which manages the recording), DisplayListData 70 * (which holds the actual data), and DisplayList (which holds properties and performs playback onto 71 * a renderer). 72 * 73 * Note that DisplayListData is swapped out from beneath an individual DisplayList when a view's 74 * recorded stream of canvas operations is refreshed. The DisplayList (and its properties) stay 75 * attached. 76 */ 77 class RenderNode : public VirtualLightRefBase { 78 public: 79 enum DirtyPropertyMask { 80 GENERIC = 1 << 1, 81 TRANSLATION_X = 1 << 2, 82 TRANSLATION_Y = 1 << 3, 83 TRANSLATION_Z = 1 << 4, 84 SCALE_X = 1 << 5, 85 SCALE_Y = 1 << 6, 86 ROTATION = 1 << 7, 87 ROTATION_X = 1 << 8, 88 ROTATION_Y = 1 << 9, 89 X = 1 << 10, 90 Y = 1 << 11, 91 Z = 1 << 12, 92 ALPHA = 1 << 13, 93 DISPLAY_LIST = 1 << 14, 94 }; 95 96 ANDROID_API RenderNode(); 97 ANDROID_API virtual ~RenderNode(); 98 99 // See flags defined in DisplayList.java 100 enum ReplayFlag { 101 kReplayFlag_ClipChildren = 0x1 102 }; 103 104 static void outputLogBuffer(int fd); 105 void debugDumpLayers(const char* prefix); 106 107 ANDROID_API void setStagingDisplayList(DisplayListData* newData); 108 109 void computeOrdering(); 110 111 void defer(DeferStateStruct& deferStruct, const int level); 112 void replay(ReplayStateStruct& replayStruct, const int level); 113 114 ANDROID_API void output(uint32_t level = 1); 115 ANDROID_API int getDebugSize(); 116 117 bool isRenderable() const { 118 return mDisplayListData && !mDisplayListData->isEmpty(); 119 } 120 121 bool hasProjectionReceiver() const { 122 return mDisplayListData && mDisplayListData->projectionReceiveIndex >= 0; 123 } 124 125 const char* getName() const { 126 return mName.string(); 127 } 128 129 void setName(const char* name) { 130 if (name) { 131 char* lastPeriod = strrchr(name, '.'); 132 if (lastPeriod) { 133 mName.setTo(lastPeriod + 1); 134 } else { 135 mName.setTo(name); 136 } 137 } 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() { 165 return properties().getWidth(); 166 } 167 168 int getHeight() { 169 return properties().getHeight(); 170 } 171 172 ANDROID_API virtual void prepareTree(TreeInfo& info); 173 void destroyHardwareResources(); 174 175 // UI thread only! 176 ANDROID_API void addAnimator(const sp<BaseRenderNodeAnimator>& animator); 177 178 AnimatorManager& animators() { return mAnimatorManager; } 179 180 void applyViewPropertyTransforms(mat4& matrix, bool true3dTransform = false) const; 181 182 private: 183 typedef key_value_pair_t<float, DrawRenderNodeOp*> ZDrawRenderNodeOpPair; 184 185 static size_t findNonNegativeIndex(const Vector<ZDrawRenderNodeOpPair>& nodes) { 186 for (size_t i = 0; i < nodes.size(); i++) { 187 if (nodes[i].key >= 0.0f) return i; 188 } 189 return nodes.size(); 190 } 191 192 enum ChildrenSelectMode { 193 kNegativeZChildren, 194 kPositiveZChildren 195 }; 196 197 void computeOrderingImpl(DrawRenderNodeOp* opState, 198 const SkPath* outlineOfProjectionSurface, 199 Vector<DrawRenderNodeOp*>* compositedChildrenOfProjectionSurface, 200 const mat4* transformFromProjectionSurface); 201 202 template <class T> 203 inline void setViewProperties(OpenGLRenderer& renderer, T& handler); 204 205 void buildZSortedChildList(const DisplayListData::Chunk& chunk, 206 Vector<ZDrawRenderNodeOpPair>& zTranslatedNodes); 207 208 template<class T> 209 inline void issueDrawShadowOperation(const Matrix4& transformFromParent, T& handler); 210 211 template <class T> 212 inline void issueOperationsOf3dChildren(ChildrenSelectMode mode, 213 const Matrix4& initialTransform, const Vector<ZDrawRenderNodeOpPair>& zTranslatedNodes, 214 OpenGLRenderer& renderer, T& handler); 215 216 template <class T> 217 inline void issueOperationsOfProjectedChildren(OpenGLRenderer& renderer, T& handler); 218 219 /** 220 * Issue the RenderNode's operations into a handler, recursing for subtrees through 221 * DrawRenderNodeOp's defer() or replay() methods 222 */ 223 template <class T> 224 inline void issueOperations(OpenGLRenderer& renderer, T& handler); 225 226 class TextContainer { 227 public: 228 size_t length() const { 229 return mByteLength; 230 } 231 232 const char* text() const { 233 return (const char*) mText; 234 } 235 236 size_t mByteLength; 237 const char* mText; 238 }; 239 240 void prepareTreeImpl(TreeInfo& info); 241 void pushStagingPropertiesChanges(TreeInfo& info); 242 void pushStagingDisplayListChanges(TreeInfo& info); 243 void prepareSubTree(TreeInfo& info, DisplayListData* subtree); 244 void applyLayerPropertiesToLayer(TreeInfo& info); 245 void prepareLayer(TreeInfo& info, uint32_t dirtyMask); 246 void pushLayerUpdate(TreeInfo& info); 247 void deleteDisplayListData(); 248 void damageSelf(TreeInfo& info); 249 250 void incParentRefCount() { mParentCount++; } 251 void decParentRefCount(); 252 253 String8 mName; 254 255 uint32_t mDirtyPropertyFields; 256 RenderProperties mProperties; 257 RenderProperties mStagingProperties; 258 259 bool mNeedsDisplayListDataSync; 260 // WARNING: Do not delete this directly, you must go through deleteDisplayListData()! 261 DisplayListData* mDisplayListData; 262 DisplayListData* mStagingDisplayListData; 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 Layer* mLayer; 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 Vector<DrawRenderNodeOp*> 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 // mDisplayListData, not mStagingDisplayListData. 284 uint32_t mParentCount; 285 }; // class RenderNode 286 287 } /* namespace uirenderer */ 288 } /* namespace android */ 289 290 #endif /* RENDERNODE_H */ 291