SkiaDisplayList.cpp revision 021693b967a2c5556dddd183eb0247df4079e1ad
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#include <SkMutex.h> 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(context ? context->getGrContext() : nullptr, 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 // force all mutable images to be pinned in the GPU cache for the duration 57 // of this frame 58 pinImages(info.canvasContext.getGrContext()); 59 60 for (auto& child : mChildNodes) { 61 RenderNode* childNode = child.getRenderNode(); 62 Matrix4 mat4(child.getRecordedMatrix()); 63 info.damageAccumulator->pushTransform(&mat4); 64 // TODO: a layer is needed if the canvas is rotated or has a non-rect clip 65 bool childFunctorsNeedLayer = functorsNeedLayer; 66 childFn(childNode, info, childFunctorsNeedLayer); 67 info.damageAccumulator->popTransform(); 68 } 69 70 bool isDirty = false; 71 for (auto& vectorDrawable : mVectorDrawables) { 72 // If any vector drawable in the display list needs update, damage the node. 73 if (vectorDrawable->isDirty()) { 74 isDirty = true; 75 } 76 vectorDrawable->setPropertyChangeWillBeConsumed(true); 77 } 78 return isDirty; 79} 80 81static std::vector<sk_sp<SkImage>> gPinnedImages; 82static SkBaseMutex gLock; 83 84void SkiaDisplayList::pinImages(GrContext* context) { 85 if (mPinnedImages) return; 86 for (SkImage* image : mMutableImages) { 87 SkImage_pinAsTexture(image, context); 88 } 89 mPinnedImages = true; 90} 91 92void SkiaDisplayList::unpinImages(GrContext* context) { 93 if (!mPinnedImages) return; 94 if (context) { 95 for (SkImage* image : mMutableImages) { 96 SkImage_unpinAsTexture(image, context); 97 } 98 } else { 99 gLock.acquire(); 100 for (SkImage* image : mMutableImages) { 101 gPinnedImages.emplace_back(sk_ref_sp(image)); 102 } 103 gLock.release(); 104 } 105 mPinnedImages = false; 106} 107 108void SkiaDisplayList::cleanupImages(GrContext* context) { 109 gLock.acquire(); 110 for (auto& image : gPinnedImages) { 111 SkImage_unpinAsTexture(image.get(), context); 112 } 113 gPinnedImages.clear(); 114 gLock.release(); 115} 116 117void SkiaDisplayList::reset(GrContext* context, SkRect bounds) { 118 unpinImages(context); 119 SkASSERT(!mPinnedImages); 120 mIsProjectionReceiver = false; 121 122 mDrawable->reset(bounds); 123 124 mMutableImages.clear(); 125 mVectorDrawables.clear(); 126 mChildFunctors.clear(); 127 mChildNodes.clear(); 128 129 projectionReceiveIndex = -1; 130 allocator.~LinearAllocator(); 131 new (&allocator) LinearAllocator(); 132} 133 134}; // namespace skiapipeline 135}; // namespace uirenderer 136}; // namespace android 137