blob: 4841714fd588cf2a486669699abd882554d81a90 [file] [log] [blame]
Florin Malita4aa44412017-12-19 12:21:02 -05001/*
2 * Copyright 2017 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SkSGGroup.h"
9
Florin Malitaca858b62018-09-02 13:44:13 -040010#include <algorithm>
11
Florin Malita4aa44412017-12-19 12:21:02 -050012namespace sksg {
13
Florin Malitacd9d0742018-09-10 09:57:15 -040014Group::Group(std::vector<sk_sp<RenderNode>> children)
15 : fChildren(std::move(children)) {
16 for (const auto& child : fChildren) {
17 this->observeInval(child);
18 }
19}
Florin Malita4aa44412017-12-19 12:21:02 -050020
21Group::~Group() {
22 for (const auto& child : fChildren) {
Florin Malita3ba3fa72018-01-22 10:19:28 -050023 this->unobserveInval(child);
Florin Malita4aa44412017-12-19 12:21:02 -050024 }
25}
26
27void Group::addChild(sk_sp<RenderNode> node) {
28 // should we allow duplicates?
29 for (const auto& child : fChildren) {
30 if (child == node) {
31 return;
32 }
33 }
34
Florin Malita3ba3fa72018-01-22 10:19:28 -050035 this->observeInval(node);
Florin Malita4aa44412017-12-19 12:21:02 -050036 fChildren.push_back(std::move(node));
Florin Malitac75e2402018-01-03 16:17:29 -050037
Florin Malitac14f1442018-01-05 11:32:31 -050038 this->invalidate();
Florin Malita4aa44412017-12-19 12:21:02 -050039}
40
41void Group::removeChild(const sk_sp<RenderNode>& node) {
Florin Malitaca858b62018-09-02 13:44:13 -040042 SkDEBUGCODE(const auto origSize = fChildren.size());
43 fChildren.erase(std::remove(fChildren.begin(), fChildren.end(), node), fChildren.end());
44 SkASSERT(fChildren.size() == origSize - 1);
Florin Malitac75e2402018-01-03 16:17:29 -050045
Florin Malitac14f1442018-01-05 11:32:31 -050046 this->invalidate();
Florin Malita4aa44412017-12-19 12:21:02 -050047}
48
Florin Malitac0132ff2018-08-09 07:40:01 -040049void Group::onRender(SkCanvas* canvas, const RenderContext* ctx) const {
50 // TODO: this heuristic works at the moment, but:
51 // a) it is fragile because it relies on all leaf render nodes being atomic draws
52 // b) could be improved by e.g. detecting all leaf render draws are non-overlapping
Florin Malitaca858b62018-09-02 13:44:13 -040053 const auto isolate = fChildren.size() > 1;
Florin Malitac0132ff2018-08-09 07:40:01 -040054 const auto local_ctx = ScopedRenderContext(canvas, ctx).setIsolation(this->bounds(), isolate);
55
Florin Malita4aa44412017-12-19 12:21:02 -050056 for (const auto& child : fChildren) {
Florin Malitac0132ff2018-08-09 07:40:01 -040057 child->render(canvas, local_ctx);
Florin Malita4aa44412017-12-19 12:21:02 -050058 }
59}
60
Florin Malitac14f1442018-01-05 11:32:31 -050061SkRect Group::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) {
Florin Malitac75e2402018-01-03 16:17:29 -050062 SkASSERT(this->hasInval());
63
Florin Malitac14f1442018-01-05 11:32:31 -050064 SkRect bounds = SkRect::MakeEmpty();
Florin Malitac75e2402018-01-03 16:17:29 -050065
Florin Malita4aa44412017-12-19 12:21:02 -050066 for (const auto& child : fChildren) {
Florin Malitac14f1442018-01-05 11:32:31 -050067 bounds.join(child->revalidate(ic, ctm));
Florin Malita4aa44412017-12-19 12:21:02 -050068 }
Florin Malitac75e2402018-01-03 16:17:29 -050069
Florin Malitac14f1442018-01-05 11:32:31 -050070 return bounds;
Florin Malita4aa44412017-12-19 12:21:02 -050071}
72
73} // namespace sksg