DisplayList.cpp revision 0df6209a02d0ea99d2dff3a46ed9febd5925df4b
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#include <SkCanvas.h> 18#include <algorithm> 19 20#include <utils/Trace.h> 21 22#include "DamageAccumulator.h" 23#include "Debug.h" 24#include "DisplayList.h" 25#include "RecordedOp.h" 26#include "RenderNode.h" 27#include "VectorDrawable.h" 28 29namespace android { 30namespace uirenderer { 31 32DisplayList::DisplayList() 33 : projectionReceiveIndex(-1) 34 , stdAllocator(allocator) 35 , chunks(stdAllocator) 36 , ops(stdAllocator) 37 , children(stdAllocator) 38 , bitmapResources(stdAllocator) 39 , pathResources(stdAllocator) 40 , patchResources(stdAllocator) 41 , paints(stdAllocator) 42 , regions(stdAllocator) 43 , referenceHolders(stdAllocator) 44 , functors(stdAllocator) 45 , vectorDrawables(stdAllocator) { 46} 47 48DisplayList::~DisplayList() { 49 cleanupResources(); 50} 51 52void DisplayList::cleanupResources() { 53 if (CC_UNLIKELY(patchResources.size())) { 54 ResourceCache& resourceCache = ResourceCache::getInstance(); 55 resourceCache.lock(); 56 57 for (size_t i = 0; i < patchResources.size(); i++) { 58 resourceCache.decrementRefcountLocked(patchResources[i]); 59 } 60 61 resourceCache.unlock(); 62 } 63 64 for (size_t i = 0; i < pathResources.size(); i++) { 65 const SkPath* path = pathResources[i]; 66 if (path->unique() && Caches::hasInstance()) { 67 Caches::getInstance().pathCache.removeDeferred(path); 68 } 69 delete path; 70 } 71 72 for (auto& iter : functors) { 73 if (iter.listener) { 74 iter.listener->onGlFunctorReleased(iter.functor); 75 } 76 } 77 78 patchResources.clear(); 79 pathResources.clear(); 80 paints.clear(); 81 regions.clear(); 82} 83 84size_t DisplayList::addChild(NodeOpType* op) { 85 referenceHolders.push_back(op->renderNode); 86 size_t index = children.size(); 87 children.push_back(op); 88 return index; 89} 90 91void DisplayList::syncContents() { 92 for (auto& iter : functors) { 93 (*iter.functor)(DrawGlInfo::kModeSync, nullptr); 94 } 95 for (auto& vectorDrawable : vectorDrawables) { 96 vectorDrawable->syncProperties(); 97 } 98} 99 100void DisplayList::updateChildren(std::function<void(RenderNode*)> updateFn) { 101 for (auto&& child : children) { 102 updateFn(child->renderNode); 103 } 104} 105 106bool DisplayList::prepareListAndChildren(TreeInfo& info, bool functorsNeedLayer, 107 std::function<void(RenderNode*, TreeInfo&, bool)> childFn) { 108 TextureCache& cache = Caches::getInstance().textureCache; 109 for (auto&& bitmapResource : bitmapResources) { 110 void* ownerToken = &info.canvasContext; 111 info.prepareTextures = cache.prefetchAndMarkInUse(ownerToken, bitmapResource); 112 } 113 for (auto&& op : children) { 114 RenderNode* childNode = op->renderNode; 115 info.damageAccumulator->pushTransform(&op->localMatrix); 116 bool childFunctorsNeedLayer = functorsNeedLayer; // TODO! || op->mRecordedWithPotentialStencilClip; 117 childFn(childNode, info, childFunctorsNeedLayer); 118 info.damageAccumulator->popTransform(); 119 } 120 121 bool isDirty = false; 122 for (auto& vectorDrawable : vectorDrawables) { 123 // If any vector drawable in the display list needs update, damage the node. 124 if (vectorDrawable->isDirty()) { 125 isDirty = true; 126 } 127 vectorDrawable->setPropertyChangeWillBeConsumed(true); 128 } 129 return isDirty; 130} 131 132}; // namespace uirenderer 133}; // namespace android 134