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 "RecordingCanvas.h" 20 #include "RenderNodeDrawable.h" 21 #include "TreeInfo.h" 22 #include "hwui/AnimatedImageDrawable.h" 23 #include "utils/LinearAllocator.h" 24 #include "utils/Pair.h" 25 26 #include <deque> 27 28 namespace android { 29 namespace uirenderer { 30 31 namespace renderthread { 32 class CanvasContext; 33 } 34 35 class Outline; 36 struct WebViewSyncData; 37 38 namespace VectorDrawable { 39 class Tree; 40 } 41 typedef uirenderer::VectorDrawable::Tree VectorDrawableRoot; 42 43 namespace skiapipeline { 44 45 class FunctorDrawable; 46 47 class SkiaDisplayList { 48 public: getUsedSize()49 size_t getUsedSize() { return allocator.usedSize() + mDisplayList.usedSize(); } getAllocatedSize()50 size_t getAllocatedSize() { return allocator.allocatedSize() + mDisplayList.allocatedSize(); } 51 ~SkiaDisplayList()52 ~SkiaDisplayList() { 53 /* Given that we are using a LinearStdAllocator to store some of the 54 * SkDrawable contents we must ensure that any other object that is 55 * holding a reference to those drawables is destroyed prior to their 56 * deletion. 57 */ 58 mDisplayList.reset(); 59 } 60 61 /** 62 * This resets the DisplayList so that it behaves as if the object were newly 63 * constructed. The reuse avoids any overhead associated with destroying 64 * the SkLiteDL as well as the deques and vectors. 65 */ 66 void reset(); 67 68 /** 69 * Use the linear allocator to create any SkDrawables needed by the display 70 * list. This could be dangerous as these objects are ref-counted, so we 71 * need to monitor that they don't extend beyond the lifetime of the class 72 * that creates them. Allocator dtor invokes all SkDrawable dtors. 73 */ 74 template <class T, typename... Params> allocateDrawable(Params &&...params)75 T* allocateDrawable(Params&&... params) { 76 return allocator.create<T>(std::forward<Params>(params)...); 77 } 78 79 /** 80 * Returns true if the DisplayList does not have any recorded content 81 */ isEmpty()82 bool isEmpty() const { return mDisplayList.empty(); } 83 84 /** 85 * Returns true if this list directly contains a GLFunctor drawing command. 86 */ hasFunctor()87 bool hasFunctor() const { return !mChildFunctors.empty(); } 88 89 /** 90 * Returns true if this list directly contains a VectorDrawable drawing command. 91 */ hasVectorDrawables()92 bool hasVectorDrawables() const { return !mVectorDrawables.empty(); } 93 hasText()94 bool hasText() const { return mDisplayList.hasText(); } 95 96 /** 97 * Attempts to reset and reuse this DisplayList. 98 * 99 * @return true if the displayList will be reused and therefore should not be deleted 100 */ 101 bool reuseDisplayList(RenderNode* node, renderthread::CanvasContext* context); 102 103 /** 104 * ONLY to be called by RenderNode::syncDisplayList so that we can notify any 105 * contained VectorDrawables or GLFunctors to sync their state. 106 * 107 * NOTE: This function can be folded into RenderNode when we no longer need 108 * to subclass from DisplayList 109 */ 110 void syncContents(const WebViewSyncData& data); 111 112 /** 113 * ONLY to be called by RenderNode::prepareTree in order to prepare this 114 * list while the UI thread is blocked. Here we can upload mutable bitmaps 115 * and notify our parent if any of our content has been invalidated and in 116 * need of a redraw. If the renderNode has any children then they are also 117 * call in order to prepare them. 118 * 119 * @return true if any content change requires the node to be invalidated 120 * 121 * NOTE: This function can be folded into RenderNode when we no longer need 122 * to subclass from DisplayList 123 */ 124 125 bool prepareListAndChildren( 126 TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer, 127 std::function<void(RenderNode*, TreeObserver&, TreeInfo&, bool)> childFn); 128 129 /** 130 * Calls the provided function once for each child of this DisplayList 131 */ 132 void updateChildren(std::function<void(RenderNode*)> updateFn); 133 134 /** 135 * Returns true if there is a child render node that is a projection receiver. 136 */ containsProjectionReceiver()137 inline bool containsProjectionReceiver() const { return mProjectionReceiver; } 138 attachRecorder(RecordingCanvas * recorder,const SkIRect & bounds)139 void attachRecorder(RecordingCanvas* recorder, const SkIRect& bounds) { 140 recorder->reset(&mDisplayList, bounds); 141 } 142 draw(SkCanvas * canvas)143 void draw(SkCanvas* canvas) { mDisplayList.draw(canvas); } 144 145 void output(std::ostream& output, uint32_t level); 146 147 LinearAllocator allocator; 148 149 /** 150 * We use std::deque here because (1) we need to iterate through these 151 * elements and (2) mDisplayList holds pointers to the elements, so they 152 * cannot relocate. 153 */ 154 std::deque<RenderNodeDrawable> mChildNodes; 155 std::deque<FunctorDrawable*> mChildFunctors; 156 std::vector<SkImage*> mMutableImages; 157 private: 158 std::vector<Pair<VectorDrawableRoot*, SkMatrix>> mVectorDrawables; 159 public: appendVD(VectorDrawableRoot * r)160 void appendVD(VectorDrawableRoot* r) { 161 appendVD(r, SkMatrix::I()); 162 } 163 appendVD(VectorDrawableRoot * r,const SkMatrix & mat)164 void appendVD(VectorDrawableRoot* r, const SkMatrix& mat) { 165 mVectorDrawables.push_back(Pair<VectorDrawableRoot*, SkMatrix>(r, mat)); 166 } 167 168 std::vector<AnimatedImageDrawable*> mAnimatedImages; 169 DisplayListData mDisplayList; 170 171 // mProjectionReceiver points to a child node (stored in mChildNodes) that is as a projection 172 // receiver. It is set at record time and used at both prepare and draw tree traversals to 173 // make sure backward projected nodes are found and drawn immediately after mProjectionReceiver. 174 RenderNodeDrawable* mProjectionReceiver = nullptr; 175 176 // mProjectedOutline is valid only when render node tree is traversed during the draw pass. 177 // Render nodes that have a child receiver node, will store a pointer to their outline in 178 // mProjectedOutline. Child receiver node will apply the clip before any backward projected 179 // node is drawn. 180 const Outline* mProjectedOutline = nullptr; 181 182 // mParentMatrix is set and valid when render node tree is traversed during the draw 183 // pass. Render nodes, which draw in a order different than recording order (e.g. nodes with a 184 // child receiver node or Z elevation), can use mParentMatrix to calculate the final transform 185 // without replaying the matrix transform OPs from the display list. 186 // Child receiver node will set the matrix and then clip with the outline of their parent. 187 SkMatrix mParentMatrix; 188 }; 189 190 } // namespace skiapipeline 191 } // namespace uirenderer 192 } // namespace android 193