1 /* 2 * Copyright (C) 2020 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 #pragma once 18 19 #include <SkMatrix.h> 20 21 #include "CanvasOpTypes.h" 22 #include "CanvasTransform.h" 23 #include "OpBuffer.h" 24 #include "TreeInfo.h" 25 #include "private/hwui/WebViewFunctor.h" 26 27 #include <functional> 28 29 namespace android::uirenderer { 30 31 class RenderNode; 32 33 template <CanvasOpType T> 34 struct CanvasOp; 35 36 template <CanvasOpType T> 37 class CanvasOpContainer { 38 private: 39 BE_OPBUFFERS_FRIEND(); 40 41 OpBufferItemHeader<CanvasOpType> header; 42 // TODO: Figure out some magic to make this not be here when it's identity (or not used) 43 SkMatrix mTransform; 44 CanvasOp<T> mImpl; 45 46 public: 47 CanvasOpContainer(CanvasOp<T>&& impl, const SkMatrix& transform = SkMatrix::I()) mTransform(transform)48 : mTransform(transform), mImpl(std::move(impl)) {} 49 size()50 uint32_t size() const { return header.size; } type()51 CanvasOpType type() const { return header.type; } 52 transform()53 const SkMatrix& transform() const { return mTransform; } 54 55 CanvasOp<T>* operator->() noexcept { return &mImpl; } 56 const CanvasOp<T>* operator->() const noexcept { return &mImpl; } 57 op()58 CanvasOp<T>& op() noexcept { return mImpl; } op()59 const CanvasOp<T>& op() const noexcept { return mImpl; } 60 }; 61 62 extern template class OpBuffer<CanvasOpType, CanvasOpContainer>; 63 class CanvasOpBuffer final : private OpBuffer<CanvasOpType, CanvasOpContainer> { 64 private: 65 using SUPER = OpBuffer<CanvasOpType, CanvasOpContainer>; 66 67 public: 68 // Expose select superclass methods publicly 69 using SUPER::for_each; 70 using SUPER::size; 71 using SUPER::resize; 72 73 template <CanvasOpType T> push(CanvasOp<T> && op)74 void push(CanvasOp<T>&& op) { 75 push_container(CanvasOpContainer<T>(std::move(op))); 76 } 77 78 template <CanvasOpType T> push_container(CanvasOpContainer<T> && op)79 void push_container(CanvasOpContainer<T>&& op) { 80 if constexpr (IsDrawOp(T)) { 81 mHas.content = true; 82 } 83 if constexpr (T == CanvasOpType::DrawRenderNode) { 84 mHas.children = true; 85 // use staging property, since recording on UI thread 86 if (op->renderNode->stagingProperties().isProjectionReceiver()) { 87 mHas.projectionReceiver = true; 88 } 89 } 90 SUPER::push_container(std::move(op)); 91 } 92 clear()93 void clear() { 94 mHas = Contains{}; 95 SUPER::clear(); 96 } 97 98 void updateChildren(std::function<void(RenderNode*)> updateFn); 99 bool prepareListAndChildren( 100 TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer, 101 std::function<void(RenderNode*, TreeObserver&, TreeInfo&, bool)> childFn); 102 void syncContents(const WebViewSyncData& data); 103 void onRemovedFromTree(); 104 void applyColorTransform(ColorTransform transform); 105 isEmpty()106 [[nodiscard]] bool isEmpty() const { return !mHas.content; } hasText()107 [[nodiscard]] bool hasText() const { return mHas.text; } hasVectorDrawables()108 [[nodiscard]] bool hasVectorDrawables() const { return mHas.vectorDrawable; } containsProjectionReceiver()109 [[nodiscard]] bool containsProjectionReceiver() const { return mHas.projectionReceiver; } hasFunctor()110 [[nodiscard]] bool hasFunctor() const { return mHas.functor; } 111 getUsedSize()112 [[nodiscard]] size_t getUsedSize() const { 113 return size(); 114 } 115 getAllocatedSize()116 [[nodiscard]] size_t getAllocatedSize() const { 117 return capacity(); 118 } 119 120 void output(std::ostream& output, uint32_t level) const; 121 122 private: 123 struct Contains { 124 bool content : 1 = false; 125 bool children : 1 = false; 126 bool projectionReceiver : 1 = false; 127 bool text : 1 = false; 128 bool vectorDrawable : 1 = false; 129 bool functor : 1 = false; 130 }; 131 Contains mHas; 132 }; 133 134 } // namespace android::uirenderer 135