10776a6069365bdea83855db154fa2d37f9d1d808Chris Craik/*
20776a6069365bdea83855db154fa2d37f9d1d808Chris Craik * Copyright (C) 2013 The Android Open Source Project
30776a6069365bdea83855db154fa2d37f9d1d808Chris Craik *
40776a6069365bdea83855db154fa2d37f9d1d808Chris Craik * Licensed under the Apache License, Version 2.0 (the "License");
50776a6069365bdea83855db154fa2d37f9d1d808Chris Craik * you may not use this file except in compliance with the License.
60776a6069365bdea83855db154fa2d37f9d1d808Chris Craik * You may obtain a copy of the License at
70776a6069365bdea83855db154fa2d37f9d1d808Chris Craik *
80776a6069365bdea83855db154fa2d37f9d1d808Chris Craik *      http://www.apache.org/licenses/LICENSE-2.0
90776a6069365bdea83855db154fa2d37f9d1d808Chris Craik *
100776a6069365bdea83855db154fa2d37f9d1d808Chris Craik * Unless required by applicable law or agreed to in writing, software
110776a6069365bdea83855db154fa2d37f9d1d808Chris Craik * distributed under the License is distributed on an "AS IS" BASIS,
120776a6069365bdea83855db154fa2d37f9d1d808Chris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130776a6069365bdea83855db154fa2d37f9d1d808Chris Craik * See the License for the specific language governing permissions and
140776a6069365bdea83855db154fa2d37f9d1d808Chris Craik * limitations under the License.
150776a6069365bdea83855db154fa2d37f9d1d808Chris Craik */
160776a6069365bdea83855db154fa2d37f9d1d808Chris Craik
17c46d07a29e94807e768f8b162ce9f77a88ba6f46Romain Guy#include <SkCanvas.h>
189f68c096263b36f59c383435e587bd8bd279af34Chris Craik#include <algorithm>
19c46d07a29e94807e768f8b162ce9f77a88ba6f46Romain Guy
20f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik#include <utils/Trace.h>
21f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik
220df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger#include "DamageAccumulator.h"
23c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik#include "Debug.h"
240776a6069365bdea83855db154fa2d37f9d1d808Chris Craik#include "DisplayList.h"
25d21723704571dba7e69947d92856f22989d53dbfStan Iliev#include "OpDumper.h"
26b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include "RecordedOp.h"
275e00c7ce063116c11315639f0035aca8ad73e8ccChris Craik#include "RenderNode.h"
280df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger#include "VectorDrawable.h"
29b7d34b64dd32e3d84bd43344c9c3d9ad098129afDerek Sollenberger#include "renderthread/CanvasContext.h"
300776a6069365bdea83855db154fa2d37f9d1d808Chris Craik
310776a6069365bdea83855db154fa2d37f9d1d808Chris Craiknamespace android {
320776a6069365bdea83855db154fa2d37f9d1d808Chris Craiknamespace uirenderer {
330776a6069365bdea83855db154fa2d37f9d1d808Chris Craik
34003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris CraikDisplayList::DisplayList()
353f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik        : projectionReceiveIndex(-1)
36b36af87f8275f4b982906f88193ec27600f2746aChris Craik        , stdAllocator(allocator)
37b36af87f8275f4b982906f88193ec27600f2746aChris Craik        , chunks(stdAllocator)
38b36af87f8275f4b982906f88193ec27600f2746aChris Craik        , ops(stdAllocator)
39b36af87f8275f4b982906f88193ec27600f2746aChris Craik        , children(stdAllocator)
40b36af87f8275f4b982906f88193ec27600f2746aChris Craik        , bitmapResources(stdAllocator)
41b36af87f8275f4b982906f88193ec27600f2746aChris Craik        , pathResources(stdAllocator)
42b36af87f8275f4b982906f88193ec27600f2746aChris Craik        , patchResources(stdAllocator)
43b36af87f8275f4b982906f88193ec27600f2746aChris Craik        , paints(stdAllocator)
44b36af87f8275f4b982906f88193ec27600f2746aChris Craik        , regions(stdAllocator)
45b36af87f8275f4b982906f88193ec27600f2746aChris Craik        , referenceHolders(stdAllocator)
46b36af87f8275f4b982906f88193ec27600f2746aChris Craik        , functors(stdAllocator)
475e00c7ce063116c11315639f0035aca8ad73e8ccChris Craik        , vectorDrawables(stdAllocator) {
48087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck}
49087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck
50003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris CraikDisplayList::~DisplayList() {
51087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck    cleanupResources();
52087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck}
53087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck
54003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craikvoid DisplayList::cleanupResources() {
554a4bc892e826849bd58606d99408f1bfbceddc3bJohn Reck    if (CC_UNLIKELY(patchResources.size())) {
564a4bc892e826849bd58606d99408f1bfbceddc3bJohn Reck        ResourceCache& resourceCache = ResourceCache::getInstance();
574a4bc892e826849bd58606d99408f1bfbceddc3bJohn Reck        resourceCache.lock();
5844fd8d24f761f82d21e9b00932648a1b6bf91449John Reck
594a4bc892e826849bd58606d99408f1bfbceddc3bJohn Reck        for (size_t i = 0; i < patchResources.size(); i++) {
604a4bc892e826849bd58606d99408f1bfbceddc3bJohn Reck            resourceCache.decrementRefcountLocked(patchResources[i]);
614a4bc892e826849bd58606d99408f1bfbceddc3bJohn Reck        }
6244fd8d24f761f82d21e9b00932648a1b6bf91449John Reck
634a4bc892e826849bd58606d99408f1bfbceddc3bJohn Reck        resourceCache.unlock();
644a4bc892e826849bd58606d99408f1bfbceddc3bJohn Reck    }
6544fd8d24f761f82d21e9b00932648a1b6bf91449John Reck
66ee248599d49a15fc207c5aeb0b90ec263cc1d600Derek Sollenberger    for (size_t i = 0; i < pathResources.size(); i++) {
67272a685f17cc4828257e521a6f62b7b17870f75eJohn Reck        const SkPath* path = pathResources[i];
68ee248599d49a15fc207c5aeb0b90ec263cc1d600Derek Sollenberger        if (path->unique() && Caches::hasInstance()) {
69ee248599d49a15fc207c5aeb0b90ec263cc1d600Derek Sollenberger            Caches::getInstance().pathCache.removeDeferred(path);
70ee248599d49a15fc207c5aeb0b90ec263cc1d600Derek Sollenberger        }
71ee248599d49a15fc207c5aeb0b90ec263cc1d600Derek Sollenberger        delete path;
72ee248599d49a15fc207c5aeb0b90ec263cc1d600Derek Sollenberger    }
73ee248599d49a15fc207c5aeb0b90ec263cc1d600Derek Sollenberger
74cd1c3eba69d044b551cededad75474038f919890John Reck    for (auto& iter : functors) {
75cd1c3eba69d044b551cededad75474038f919890John Reck        if (iter.listener) {
76cd1c3eba69d044b551cededad75474038f919890John Reck            iter.listener->onGlFunctorReleased(iter.functor);
77cd1c3eba69d044b551cededad75474038f919890John Reck        }
78cd1c3eba69d044b551cededad75474038f919890John Reck    }
79cd1c3eba69d044b551cededad75474038f919890John Reck
8044fd8d24f761f82d21e9b00932648a1b6bf91449John Reck    patchResources.clear();
81ee248599d49a15fc207c5aeb0b90ec263cc1d600Derek Sollenberger    pathResources.clear();
8244fd8d24f761f82d21e9b00932648a1b6bf91449John Reck    paints.clear();
8344fd8d24f761f82d21e9b00932648a1b6bf91449John Reck    regions.clear();
8444fd8d24f761f82d21e9b00932648a1b6bf91449John Reck}
8544fd8d24f761f82d21e9b00932648a1b6bf91449John Reck
86003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craiksize_t DisplayList::addChild(NodeOpType* op) {
87b36af87f8275f4b982906f88193ec27600f2746aChris Craik    referenceHolders.push_back(op->renderNode);
88b36af87f8275f4b982906f88193ec27600f2746aChris Craik    size_t index = children.size();
89b36af87f8275f4b982906f88193ec27600f2746aChris Craik    children.push_back(op);
90272a685f17cc4828257e521a6f62b7b17870f75eJohn Reck    return index;
91087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck}
92087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck
930df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenbergervoid DisplayList::syncContents() {
940df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    for (auto& iter : functors) {
950df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger        (*iter.functor)(DrawGlInfo::kModeSync, nullptr);
960df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    }
970df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    for (auto& vectorDrawable : vectorDrawables) {
980df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger        vectorDrawable->syncProperties();
990df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    }
1000df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger}
1010df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger
1020df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenbergervoid DisplayList::updateChildren(std::function<void(RenderNode*)> updateFn) {
1030df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    for (auto&& child : children) {
1040df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger        updateFn(child->renderNode);
1050df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    }
1060df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger}
1070df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger
1082de950d5a8b47c7b4648ada1b1260ce4b7342798John Reckbool DisplayList::prepareListAndChildren(TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer,
1092de950d5a8b47c7b4648ada1b1260ce4b7342798John Reck        std::function<void(RenderNode*, TreeObserver&, TreeInfo&, bool)> childFn) {
110b7d34b64dd32e3d84bd43344c9c3d9ad098129afDerek Sollenberger    info.prepareTextures = info.canvasContext.pinImages(bitmapResources);
111b7d34b64dd32e3d84bd43344c9c3d9ad098129afDerek Sollenberger
1120df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    for (auto&& op : children) {
1130df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger        RenderNode* childNode = op->renderNode;
1140df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger        info.damageAccumulator->pushTransform(&op->localMatrix);
1150df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger        bool childFunctorsNeedLayer = functorsNeedLayer; // TODO! || op->mRecordedWithPotentialStencilClip;
1162de950d5a8b47c7b4648ada1b1260ce4b7342798John Reck        childFn(childNode, observer, info, childFunctorsNeedLayer);
1170df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger        info.damageAccumulator->popTransform();
1180df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    }
1190df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger
1200df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    bool isDirty = false;
1210df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    for (auto& vectorDrawable : vectorDrawables) {
1220df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger        // If any vector drawable in the display list needs update, damage the node.
1230df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger        if (vectorDrawable->isDirty()) {
1240df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger            isDirty = true;
1250df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger        }
1260df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger        vectorDrawable->setPropertyChangeWillBeConsumed(true);
1270df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    }
1280df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    return isDirty;
1290df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger}
1300df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger
131d21723704571dba7e69947d92856f22989d53dbfStan Ilievvoid DisplayList::output(std::ostream& output, uint32_t level) {
132d21723704571dba7e69947d92856f22989d53dbfStan Iliev    for (auto&& op : getOps()) {
133d21723704571dba7e69947d92856f22989d53dbfStan Iliev        OpDumper::dump(*op, output, level + 1);
134d21723704571dba7e69947d92856f22989d53dbfStan Iliev        if (op->opId == RecordedOpId::RenderNodeOp) {
135d21723704571dba7e69947d92856f22989d53dbfStan Iliev            auto rnOp = reinterpret_cast<const RenderNodeOp*>(op);
136d21723704571dba7e69947d92856f22989d53dbfStan Iliev            rnOp->renderNode->output(output, level + 1);
137d21723704571dba7e69947d92856f22989d53dbfStan Iliev        } else {
138d21723704571dba7e69947d92856f22989d53dbfStan Iliev            output << std::endl;
139d21723704571dba7e69947d92856f22989d53dbfStan Iliev        }
140d21723704571dba7e69947d92856f22989d53dbfStan Iliev    }
141d21723704571dba7e69947d92856f22989d53dbfStan Iliev}
142d21723704571dba7e69947d92856f22989d53dbfStan Iliev
1430776a6069365bdea83855db154fa2d37f9d1d808Chris Craik}; // namespace uirenderer
1440776a6069365bdea83855db154fa2d37f9d1d808Chris Craik}; // namespace android
145