blob: eb5878d95561ae816980c489899ede0d108aab86 [file] [log] [blame]
Chris Craik0776a602013-02-14 15:36:01 -08001/*
2 * Copyright (C) 2013 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
Chris Craik5e00c7c2016-07-06 16:10:09 -070017#pragma once
Chris Craik0776a602013-02-14 15:36:01 -080018
John Reck844516c2021-01-13 10:59:10 -050019#include "pipeline/skia/SkiaDisplayList.h"
John Reck064650b2021-01-19 21:29:24 -050020#include "canvas/CanvasOpBuffer.h"
John Reck844516c2021-01-13 10:59:10 -050021
John Reckbe671952021-01-13 22:39:32 -050022#include <memory>
John Reck064650b2021-01-19 21:29:24 -050023#include <variant>
John Reckbe671952021-01-13 22:39:32 -050024
Chris Craik0776a602013-02-14 15:36:01 -080025namespace android {
26namespace uirenderer {
27
Doris Liu67ce99b2016-05-17 16:50:31 -070028namespace VectorDrawable {
29class Tree;
30};
31typedef uirenderer::VectorDrawable::Tree VectorDrawableRoot;
32
John Reck064650b2021-01-19 21:29:24 -050033class SkiaDisplayListWrapper {
John Reckbe671952021-01-13 22:39:32 -050034public:
35 // Constructs an empty (invalid) DisplayList
John Reck064650b2021-01-19 21:29:24 -050036 explicit SkiaDisplayListWrapper() {}
John Reckbe671952021-01-13 22:39:32 -050037
38 // Constructs a DisplayList from a SkiaDisplayList
John Reck064650b2021-01-19 21:29:24 -050039 explicit SkiaDisplayListWrapper(std::unique_ptr<skiapipeline::SkiaDisplayList> impl)
John Reckbe671952021-01-13 22:39:32 -050040 : mImpl(std::move(impl)) {}
41
42 // Move support
John Reck064650b2021-01-19 21:29:24 -050043 SkiaDisplayListWrapper(SkiaDisplayListWrapper&& other) : mImpl(std::move(other.mImpl)) {}
44 SkiaDisplayListWrapper& operator=(SkiaDisplayListWrapper&& other) {
John Reckbe671952021-01-13 22:39:32 -050045 mImpl = std::move(other.mImpl);
46 return *this;
47 }
48
49 // No copy support
John Reck064650b2021-01-19 21:29:24 -050050 SkiaDisplayListWrapper(const SkiaDisplayListWrapper& other) = delete;
51 SkiaDisplayListWrapper& operator=(const SkiaDisplayListWrapper&) = delete;
John Reckbe671952021-01-13 22:39:32 -050052
53 void updateChildren(std::function<void(RenderNode*)> updateFn) {
54 mImpl->updateChildren(std::move(updateFn));
55 }
56
57 [[nodiscard]] explicit operator bool() const {
58 return mImpl.get() != nullptr;
59 }
60
61 // If true this DisplayList contains a backing content, even if that content is empty
62 // If false, there this DisplayList is in an "empty" state
63 [[nodiscard]] bool isValid() const {
64 return mImpl.get() != nullptr;
65 }
66
67 [[nodiscard]] bool isEmpty() const {
68 return !hasContent();
69 }
70
71 [[nodiscard]] bool hasContent() const {
72 return mImpl && !(mImpl->isEmpty());
73 }
74
Nader Jawad2dc632a2021-03-29 18:51:29 -070075 [[nodiscard]] bool hasHolePunches() const {
76 return mImpl && mImpl->hasHolePunches();
77 }
78
John Reckbe671952021-01-13 22:39:32 -050079 [[nodiscard]] bool containsProjectionReceiver() const {
80 return mImpl && mImpl->containsProjectionReceiver();
81 }
82
83 [[nodiscard]] skiapipeline::SkiaDisplayList* asSkiaDl() {
84 return mImpl.get();
85 }
86
87 [[nodiscard]] const skiapipeline::SkiaDisplayList* asSkiaDl() const {
88 return mImpl.get();
89 }
90
91 [[nodiscard]] bool hasVectorDrawables() const {
92 return mImpl && mImpl->hasVectorDrawables();
93 }
94
95 void clear(RenderNode* owningNode = nullptr) {
96 if (mImpl && owningNode && mImpl->reuseDisplayList(owningNode)) {
97 // TODO: This is a bit sketchy to have a unique_ptr temporarily owned twice
98 // Do something to cleanup reuseDisplayList passing itself to the RenderNode
99 mImpl.release();
100 } else {
101 mImpl = nullptr;
102 }
103 }
104
105 [[nodiscard]] size_t getUsedSize() const {
106 return mImpl ? mImpl->getUsedSize() : 0;
107 }
108
109 [[nodiscard]] size_t getAllocatedSize() const {
110 return mImpl ? mImpl->getAllocatedSize() : 0;
111 }
112
113 void output(std::ostream& output, uint32_t level) const {
114 if (mImpl) {
115 mImpl->output(output, level);
116 }
117 }
118
119 [[nodiscard]] bool hasFunctor() const {
120 return mImpl && mImpl->hasFunctor();
121 }
122
123 bool prepareListAndChildren(
124 TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer,
125 std::function<void(RenderNode*, TreeObserver&, TreeInfo&, bool)> childFn) {
126 return mImpl && mImpl->prepareListAndChildren(
127 observer, info, functorsNeedLayer, std::move(childFn));
128 }
129
130 void syncContents(const WebViewSyncData& data) {
131 if (mImpl) {
132 mImpl->syncContents(data);
133 }
134 }
135
Huihong Luoec68b7c2021-06-25 21:54:16 -0700136 void onRemovedFromTree() {
137 if (mImpl) {
138 mImpl->onRemovedFromTree();
139 }
140 }
141
John Reckbe671952021-01-13 22:39:32 -0500142 [[nodiscard]] bool hasText() const {
143 return mImpl && mImpl->hasText();
144 }
145
146 void applyColorTransform(ColorTransform transform) {
147 if (mImpl) {
John Reck064650b2021-01-19 21:29:24 -0500148 mImpl->applyColorTransform(transform);
John Reckbe671952021-01-13 22:39:32 -0500149 }
150 }
151
152private:
153 std::unique_ptr<skiapipeline::SkiaDisplayList> mImpl;
154};
Chris Craik0776a602013-02-14 15:36:01 -0800155
John Reck064650b2021-01-19 21:29:24 -0500156
157/**
158 * Data structure that holds the list of commands used in display list stream
159 */
160//using DisplayList = skiapipeline::SkiaDisplayList;
161class MultiDisplayList {
162private:
163 using SkiaDisplayList = skiapipeline::SkiaDisplayList;
164
165 struct EmptyList {
166 bool hasText() const { return false; }
167 void updateChildren(std::function<void(RenderNode*)> updateFn) {}
168 bool isEmpty() const { return true; }
169 bool containsProjectionReceiver() const { return false; }
170 bool hasVectorDrawables() const { return false; }
171 size_t getUsedSize() const { return 0; }
172 size_t getAllocatedSize() const { return 0; }
173 void output(std::ostream& output, uint32_t level) const { }
174 bool hasFunctor() const { return false; }
175 bool prepareListAndChildren(
176 TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer,
177 std::function<void(RenderNode*, TreeObserver&, TreeInfo&, bool)> childFn) {
178 return false;
179 }
180 void syncContents(const WebViewSyncData& data) { }
Huihong Luoec68b7c2021-06-25 21:54:16 -0700181 void onRemovedFromTree() { }
John Reck064650b2021-01-19 21:29:24 -0500182 void applyColorTransform(ColorTransform transform) { }
183 };
184
185 std::variant<EmptyList, std::unique_ptr<SkiaDisplayList>, CanvasOpBuffer> mImpls;
186
187 template <typename T>
188 static constexpr T& get(T& t) { return t; }
189 template <typename T>
190 static constexpr const T& get(const T& t) { return t; }
191
192 template <typename T>
193 static constexpr T& get(std::unique_ptr<T>& t) { return *t; }
194 template <typename T>
195 static constexpr const T& get(const std::unique_ptr<T>& t) { return *t; }
196
197 template <typename T>
198 auto apply(T&& t) {
199 return std::visit([&t](auto& it) -> auto {
200 return t(get(it));
201 }, mImpls);
202 }
203
204 template <typename T>
205 auto apply(T&& t) const {
206 return std::visit([&t](const auto& it) -> auto {
207 return t(get(it));
208 }, mImpls);
209 }
210
211public:
212 // Constructs an empty (invalid) DisplayList
213 explicit MultiDisplayList() {}
214
215 // Constructs a DisplayList from a SkiaDisplayList
216 explicit MultiDisplayList(std::unique_ptr<SkiaDisplayList> impl)
217 : mImpls(std::move(impl)) {}
218
219 explicit MultiDisplayList(CanvasOpBuffer&& opBuffer) : mImpls(std::move(opBuffer)) {}
220
221 // Move support
222 MultiDisplayList(MultiDisplayList&& other) : mImpls(std::move(other.mImpls)) {}
223 MultiDisplayList& operator=(MultiDisplayList&& other) {
224 mImpls = std::move(other.mImpls);
225 return *this;
226 }
227
228 // No copy support
229 MultiDisplayList(const MultiDisplayList& other) = delete;
230 MultiDisplayList& operator=(const MultiDisplayList&) = delete;
231
232 void updateChildren(std::function<void(RenderNode*)> updateFn) {
233 apply([&](auto& it) { it.updateChildren(std::move(updateFn)); });
234 }
235
236 [[nodiscard]] explicit operator bool() const {
237 return isValid();
238 }
239
240 // If true this DisplayList contains a backing content, even if that content is empty
241 // If false, there this DisplayList is in an "empty" state
242 [[nodiscard]] bool isValid() const {
243 return mImpls.index() != 0;
244 }
245
246 [[nodiscard]] bool isEmpty() const {
247 return apply([](const auto& it) -> auto { return it.isEmpty(); });
248 }
249
250 [[nodiscard]] bool hasContent() const {
251 return !isEmpty();
252 }
253
254 [[nodiscard]] bool containsProjectionReceiver() const {
255 return apply([](const auto& it) -> auto { return it.containsProjectionReceiver(); });
256 }
257
258 [[nodiscard]] SkiaDisplayList* asSkiaDl() {
259 return std::get<1>(mImpls).get();
260 }
261
262 [[nodiscard]] const SkiaDisplayList* asSkiaDl() const {
263 return std::get<1>(mImpls).get();
264 }
265
266 [[nodiscard]] bool hasVectorDrawables() const {
267 return apply([](const auto& it) -> auto { return it.hasVectorDrawables(); });
268 }
269
270 void clear(RenderNode* owningNode = nullptr) {
271 if (owningNode && mImpls.index() == 1) {
272 auto& skiaDl = std::get<1>(mImpls);
273 if (skiaDl->reuseDisplayList(owningNode)) {
274 skiaDl.release();
275 }
276 }
277 mImpls = EmptyList{};
278 }
279
280 [[nodiscard]] size_t getUsedSize() const {
281 return apply([](const auto& it) -> auto { return it.getUsedSize(); });
282 }
283
284 [[nodiscard]] size_t getAllocatedSize() const {
285 return apply([](const auto& it) -> auto { return it.getAllocatedSize(); });
286 }
287
288 void output(std::ostream& output, uint32_t level) const {
289 apply([&](const auto& it) { it.output(output, level); });
290 }
291
292 [[nodiscard]] bool hasFunctor() const {
293 return apply([](const auto& it) -> auto { return it.hasFunctor(); });
294 }
295
296 bool prepareListAndChildren(
297 TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer,
298 std::function<void(RenderNode*, TreeObserver&, TreeInfo&, bool)> childFn) {
299 return apply([&](auto& it) -> auto {
300 return it.prepareListAndChildren(observer, info, functorsNeedLayer, std::move(childFn));
301 });
302 }
303
304 void syncContents(const WebViewSyncData& data) {
305 apply([&](auto& it) { it.syncContents(data); });
306 }
307
Huihong Luoec68b7c2021-06-25 21:54:16 -0700308 void onRemovedFromTree() {
309 apply([&](auto& it) { it.onRemovedFromTree(); });
310 }
311
John Reck064650b2021-01-19 21:29:24 -0500312 [[nodiscard]] bool hasText() const {
313 return apply([](const auto& it) -> auto { return it.hasText(); });
314 }
315
316 void applyColorTransform(ColorTransform transform) {
317 apply([=](auto& it) { it.applyColorTransform(transform); });
318 }
319
320 [[nodiscard]] CanvasOpBuffer& asOpBuffer() {
321 return std::get<CanvasOpBuffer>(mImpls);
322 }
323};
324
325// For now stick to the original single-type container to avoid any regressions
326using DisplayList = SkiaDisplayListWrapper;
327
Chris Blume7b8a8082018-11-30 15:51:58 -0800328} // namespace uirenderer
329} // namespace android