SkiaDisplayList.cpp revision 189e87498f666e94dc8c8201e7bac56bb09b9251
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#include "SkiaDisplayList.h" 18 19#include "renderthread/CanvasContext.h" 20#include "VectorDrawable.h" 21 22#include <SkImagePriv.h> 23 24 25namespace android { 26namespace uirenderer { 27namespace skiapipeline { 28 29SkiaDisplayList::SkiaDisplayList(SkRect bounds) : mDrawable(SkLiteDL::New(bounds)) { 30 SkASSERT(projectionReceiveIndex == -1); 31} 32 33void SkiaDisplayList::syncContents() { 34 for (auto& functor : mChildFunctors) { 35 functor.syncFunctor(); 36 } 37 for (auto& vectorDrawable : mVectorDrawables) { 38 vectorDrawable->syncProperties(); 39 } 40} 41 42bool SkiaDisplayList::reuseDisplayList(RenderNode* node, renderthread::CanvasContext* context) { 43 reset(SkRect::MakeEmpty()); 44 node->attachAvailableList(this); 45 return true; 46} 47 48void SkiaDisplayList::updateChildren(std::function<void(RenderNode*)> updateFn) { 49 for (auto& child : mChildNodes) { 50 updateFn(child.getRenderNode()); 51 } 52} 53 54bool SkiaDisplayList::prepareListAndChildren(TreeInfo& info, bool functorsNeedLayer, 55 std::function<void(RenderNode*, TreeInfo&, bool)> childFn) { 56 // If the prepare tree is triggered by the UI thread and no previous call to 57 // pinImages has failed then we must pin all mutable images in the GPU cache 58 // until the next UI thread draw. 59 if (info.prepareTextures && !info.canvasContext.pinImages(mMutableImages)) { 60 // In the event that pinning failed we prevent future pinImage calls for the 61 // remainder of this tree traversal and also unpin any currently pinned images 62 // to free up GPU resources. 63 info.prepareTextures = false; 64 info.canvasContext.unpinImages(); 65 } 66 67 for (auto& child : mChildNodes) { 68 RenderNode* childNode = child.getRenderNode(); 69 Matrix4 mat4(child.getRecordedMatrix()); 70 info.damageAccumulator->pushTransform(&mat4); 71 // TODO: a layer is needed if the canvas is rotated or has a non-rect clip 72 bool childFunctorsNeedLayer = functorsNeedLayer; 73 childFn(childNode, info, childFunctorsNeedLayer); 74 info.damageAccumulator->popTransform(); 75 } 76 77 bool isDirty = false; 78 for (auto& vectorDrawable : mVectorDrawables) { 79 // If any vector drawable in the display list needs update, damage the node. 80 if (vectorDrawable->isDirty()) { 81 isDirty = true; 82 } 83 vectorDrawable->setPropertyChangeWillBeConsumed(true); 84 } 85 return isDirty; 86} 87 88void SkiaDisplayList::reset(SkRect bounds) { 89 mIsProjectionReceiver = false; 90 91 mDrawable->reset(bounds); 92 93 mMutableImages.clear(); 94 mVectorDrawables.clear(); 95 mChildFunctors.clear(); 96 mChildNodes.clear(); 97 98 projectionReceiveIndex = -1; 99 allocator.~LinearAllocator(); 100 new (&allocator) LinearAllocator(); 101} 102 103}; // namespace skiapipeline 104}; // namespace uirenderer 105}; // namespace android 106