1*d57664e9SAndroid Build Coastguard Worker /* 2*d57664e9SAndroid Build Coastguard Worker * Copyright (C) 2020 The Android Open Source Project 3*d57664e9SAndroid Build Coastguard Worker * 4*d57664e9SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*d57664e9SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*d57664e9SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*d57664e9SAndroid Build Coastguard Worker * 8*d57664e9SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*d57664e9SAndroid Build Coastguard Worker * 10*d57664e9SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*d57664e9SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*d57664e9SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*d57664e9SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*d57664e9SAndroid Build Coastguard Worker * limitations under the License. 15*d57664e9SAndroid Build Coastguard Worker */ 16*d57664e9SAndroid Build Coastguard Worker 17*d57664e9SAndroid Build Coastguard Worker #pragma once 18*d57664e9SAndroid Build Coastguard Worker 19*d57664e9SAndroid Build Coastguard Worker #include <SkMatrix.h> 20*d57664e9SAndroid Build Coastguard Worker 21*d57664e9SAndroid Build Coastguard Worker #include "CanvasOpTypes.h" 22*d57664e9SAndroid Build Coastguard Worker #include "CanvasTransform.h" 23*d57664e9SAndroid Build Coastguard Worker #include "OpBuffer.h" 24*d57664e9SAndroid Build Coastguard Worker #include "TreeInfo.h" 25*d57664e9SAndroid Build Coastguard Worker #include "private/hwui/WebViewFunctor.h" 26*d57664e9SAndroid Build Coastguard Worker 27*d57664e9SAndroid Build Coastguard Worker #include <functional> 28*d57664e9SAndroid Build Coastguard Worker 29*d57664e9SAndroid Build Coastguard Worker namespace android::uirenderer { 30*d57664e9SAndroid Build Coastguard Worker 31*d57664e9SAndroid Build Coastguard Worker class RenderNode; 32*d57664e9SAndroid Build Coastguard Worker 33*d57664e9SAndroid Build Coastguard Worker template <CanvasOpType T> 34*d57664e9SAndroid Build Coastguard Worker struct CanvasOp; 35*d57664e9SAndroid Build Coastguard Worker 36*d57664e9SAndroid Build Coastguard Worker template <CanvasOpType T> 37*d57664e9SAndroid Build Coastguard Worker class CanvasOpContainer { 38*d57664e9SAndroid Build Coastguard Worker private: 39*d57664e9SAndroid Build Coastguard Worker BE_OPBUFFERS_FRIEND(); 40*d57664e9SAndroid Build Coastguard Worker 41*d57664e9SAndroid Build Coastguard Worker OpBufferItemHeader<CanvasOpType> header; 42*d57664e9SAndroid Build Coastguard Worker // TODO: Figure out some magic to make this not be here when it's identity (or not used) 43*d57664e9SAndroid Build Coastguard Worker SkMatrix mTransform; 44*d57664e9SAndroid Build Coastguard Worker CanvasOp<T> mImpl; 45*d57664e9SAndroid Build Coastguard Worker 46*d57664e9SAndroid Build Coastguard Worker public: 47*d57664e9SAndroid Build Coastguard Worker CanvasOpContainer(CanvasOp<T>&& impl, const SkMatrix& transform = SkMatrix::I()) mTransform(transform)48*d57664e9SAndroid Build Coastguard Worker : mTransform(transform), mImpl(std::move(impl)) {} 49*d57664e9SAndroid Build Coastguard Worker size()50*d57664e9SAndroid Build Coastguard Worker uint32_t size() const { return header.size; } type()51*d57664e9SAndroid Build Coastguard Worker CanvasOpType type() const { return header.type; } 52*d57664e9SAndroid Build Coastguard Worker transform()53*d57664e9SAndroid Build Coastguard Worker const SkMatrix& transform() const { return mTransform; } 54*d57664e9SAndroid Build Coastguard Worker 55*d57664e9SAndroid Build Coastguard Worker CanvasOp<T>* operator->() noexcept { return &mImpl; } 56*d57664e9SAndroid Build Coastguard Worker const CanvasOp<T>* operator->() const noexcept { return &mImpl; } 57*d57664e9SAndroid Build Coastguard Worker op()58*d57664e9SAndroid Build Coastguard Worker CanvasOp<T>& op() noexcept { return mImpl; } op()59*d57664e9SAndroid Build Coastguard Worker const CanvasOp<T>& op() const noexcept { return mImpl; } 60*d57664e9SAndroid Build Coastguard Worker }; 61*d57664e9SAndroid Build Coastguard Worker 62*d57664e9SAndroid Build Coastguard Worker extern template class OpBuffer<CanvasOpType, CanvasOpContainer>; 63*d57664e9SAndroid Build Coastguard Worker class CanvasOpBuffer final : private OpBuffer<CanvasOpType, CanvasOpContainer> { 64*d57664e9SAndroid Build Coastguard Worker private: 65*d57664e9SAndroid Build Coastguard Worker using SUPER = OpBuffer<CanvasOpType, CanvasOpContainer>; 66*d57664e9SAndroid Build Coastguard Worker 67*d57664e9SAndroid Build Coastguard Worker public: 68*d57664e9SAndroid Build Coastguard Worker // Expose select superclass methods publicly 69*d57664e9SAndroid Build Coastguard Worker using SUPER::for_each; 70*d57664e9SAndroid Build Coastguard Worker using SUPER::size; 71*d57664e9SAndroid Build Coastguard Worker using SUPER::resize; 72*d57664e9SAndroid Build Coastguard Worker 73*d57664e9SAndroid Build Coastguard Worker template <CanvasOpType T> push(CanvasOp<T> && op)74*d57664e9SAndroid Build Coastguard Worker void push(CanvasOp<T>&& op) { 75*d57664e9SAndroid Build Coastguard Worker push_container(CanvasOpContainer<T>(std::move(op))); 76*d57664e9SAndroid Build Coastguard Worker } 77*d57664e9SAndroid Build Coastguard Worker 78*d57664e9SAndroid Build Coastguard Worker template <CanvasOpType T> push_container(CanvasOpContainer<T> && op)79*d57664e9SAndroid Build Coastguard Worker void push_container(CanvasOpContainer<T>&& op) { 80*d57664e9SAndroid Build Coastguard Worker if constexpr (IsDrawOp(T)) { 81*d57664e9SAndroid Build Coastguard Worker mHas.content = true; 82*d57664e9SAndroid Build Coastguard Worker } 83*d57664e9SAndroid Build Coastguard Worker if constexpr (T == CanvasOpType::DrawRenderNode) { 84*d57664e9SAndroid Build Coastguard Worker mHas.children = true; 85*d57664e9SAndroid Build Coastguard Worker // use staging property, since recording on UI thread 86*d57664e9SAndroid Build Coastguard Worker if (op->renderNode->stagingProperties().isProjectionReceiver()) { 87*d57664e9SAndroid Build Coastguard Worker mHas.projectionReceiver = true; 88*d57664e9SAndroid Build Coastguard Worker } 89*d57664e9SAndroid Build Coastguard Worker } 90*d57664e9SAndroid Build Coastguard Worker SUPER::push_container(std::move(op)); 91*d57664e9SAndroid Build Coastguard Worker } 92*d57664e9SAndroid Build Coastguard Worker clear()93*d57664e9SAndroid Build Coastguard Worker void clear() { 94*d57664e9SAndroid Build Coastguard Worker mHas = Contains{}; 95*d57664e9SAndroid Build Coastguard Worker SUPER::clear(); 96*d57664e9SAndroid Build Coastguard Worker } 97*d57664e9SAndroid Build Coastguard Worker 98*d57664e9SAndroid Build Coastguard Worker void updateChildren(std::function<void(RenderNode*)> updateFn); 99*d57664e9SAndroid Build Coastguard Worker bool prepareListAndChildren( 100*d57664e9SAndroid Build Coastguard Worker TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer, 101*d57664e9SAndroid Build Coastguard Worker std::function<void(RenderNode*, TreeObserver&, TreeInfo&, bool)> childFn); 102*d57664e9SAndroid Build Coastguard Worker void syncContents(const WebViewSyncData& data); 103*d57664e9SAndroid Build Coastguard Worker void onRemovedFromTree(); 104*d57664e9SAndroid Build Coastguard Worker void applyColorTransform(ColorTransform transform); 105*d57664e9SAndroid Build Coastguard Worker isEmpty()106*d57664e9SAndroid Build Coastguard Worker [[nodiscard]] bool isEmpty() const { return !mHas.content; } hasText()107*d57664e9SAndroid Build Coastguard Worker [[nodiscard]] bool hasText() const { return mHas.text; } hasVectorDrawables()108*d57664e9SAndroid Build Coastguard Worker [[nodiscard]] bool hasVectorDrawables() const { return mHas.vectorDrawable; } containsProjectionReceiver()109*d57664e9SAndroid Build Coastguard Worker [[nodiscard]] bool containsProjectionReceiver() const { return mHas.projectionReceiver; } hasFunctor()110*d57664e9SAndroid Build Coastguard Worker [[nodiscard]] bool hasFunctor() const { return mHas.functor; } 111*d57664e9SAndroid Build Coastguard Worker getUsedSize()112*d57664e9SAndroid Build Coastguard Worker [[nodiscard]] size_t getUsedSize() const { 113*d57664e9SAndroid Build Coastguard Worker return size(); 114*d57664e9SAndroid Build Coastguard Worker } 115*d57664e9SAndroid Build Coastguard Worker getAllocatedSize()116*d57664e9SAndroid Build Coastguard Worker [[nodiscard]] size_t getAllocatedSize() const { 117*d57664e9SAndroid Build Coastguard Worker return capacity(); 118*d57664e9SAndroid Build Coastguard Worker } 119*d57664e9SAndroid Build Coastguard Worker 120*d57664e9SAndroid Build Coastguard Worker void output(std::ostream& output, uint32_t level) const; 121*d57664e9SAndroid Build Coastguard Worker 122*d57664e9SAndroid Build Coastguard Worker private: 123*d57664e9SAndroid Build Coastguard Worker struct Contains { 124*d57664e9SAndroid Build Coastguard Worker bool content : 1 = false; 125*d57664e9SAndroid Build Coastguard Worker bool children : 1 = false; 126*d57664e9SAndroid Build Coastguard Worker bool projectionReceiver : 1 = false; 127*d57664e9SAndroid Build Coastguard Worker bool text : 1 = false; 128*d57664e9SAndroid Build Coastguard Worker bool vectorDrawable : 1 = false; 129*d57664e9SAndroid Build Coastguard Worker bool functor : 1 = false; 130*d57664e9SAndroid Build Coastguard Worker }; 131*d57664e9SAndroid Build Coastguard Worker Contains mHas; 132*d57664e9SAndroid Build Coastguard Worker }; 133*d57664e9SAndroid Build Coastguard Worker 134*d57664e9SAndroid Build Coastguard Worker } // namespace android::uirenderer 135