SkiaDisplayList.cpp revision b7d34b64dd32e3d84bd43344c9c3d9ad098129af
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 then we must force all 57 // mutable images to be pinned in the GPU cache until the next UI thread 58 // draw 59 if (info.mode == TreeInfo::MODE_FULL) { 60 info.prepareTextures = info.canvasContext.pinImages(mMutableImages); 61 } 62 63 for (auto& child : mChildNodes) { 64 RenderNode* childNode = child.getRenderNode(); 65 Matrix4 mat4(child.getRecordedMatrix()); 66 info.damageAccumulator->pushTransform(&mat4); 67 // TODO: a layer is needed if the canvas is rotated or has a non-rect clip 68 bool childFunctorsNeedLayer = functorsNeedLayer; 69 childFn(childNode, info, childFunctorsNeedLayer); 70 info.damageAccumulator->popTransform(); 71 } 72 73 bool isDirty = false; 74 for (auto& vectorDrawable : mVectorDrawables) { 75 // If any vector drawable in the display list needs update, damage the node. 76 if (vectorDrawable->isDirty()) { 77 isDirty = true; 78 } 79 vectorDrawable->setPropertyChangeWillBeConsumed(true); 80 } 81 return isDirty; 82} 83 84void SkiaDisplayList::reset(SkRect bounds) { 85 mIsProjectionReceiver = false; 86 87 mDrawable->reset(bounds); 88 89 mMutableImages.clear(); 90 mVectorDrawables.clear(); 91 mChildFunctors.clear(); 92 mChildNodes.clear(); 93 94 projectionReceiveIndex = -1; 95 allocator.~LinearAllocator(); 96 new (&allocator) LinearAllocator(); 97} 98 99}; // namespace skiapipeline 100}; // namespace uirenderer 101}; // namespace android 102