blob: 2c0a9d7b814f039acefbaab5221fcc57296cfa9b [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
14Group::Group() {}
15
16Group::~Group() {
17 for (const auto& child : fChildren) {
Florin Malita3ba3fa72018-01-22 10:19:28 -050018 this->unobserveInval(child);
Florin Malita4aa44412017-12-19 12:21:02 -050019 }
20}
21
22void Group::addChild(sk_sp<RenderNode> node) {
23 // should we allow duplicates?
24 for (const auto& child : fChildren) {
25 if (child == node) {
26 return;
27 }
28 }
29
Florin Malita3ba3fa72018-01-22 10:19:28 -050030 this->observeInval(node);
Florin Malita4aa44412017-12-19 12:21:02 -050031 fChildren.push_back(std::move(node));
Florin Malitac75e2402018-01-03 16:17:29 -050032
Florin Malitac14f1442018-01-05 11:32:31 -050033 this->invalidate();
Florin Malita4aa44412017-12-19 12:21:02 -050034}
35
36void Group::removeChild(const sk_sp<RenderNode>& node) {
Florin Malitaca858b62018-09-02 13:44:13 -040037 SkDEBUGCODE(const auto origSize = fChildren.size());
38 fChildren.erase(std::remove(fChildren.begin(), fChildren.end(), node), fChildren.end());
39 SkASSERT(fChildren.size() == origSize - 1);
Florin Malitac75e2402018-01-03 16:17:29 -050040
Florin Malitac14f1442018-01-05 11:32:31 -050041 this->invalidate();
Florin Malita4aa44412017-12-19 12:21:02 -050042}
43
Florin Malitaca858b62018-09-02 13:44:13 -040044void Group::shrink_to_fit() {
45 fChildren.shrink_to_fit();
46}
47
Florin Malitac0132ff2018-08-09 07:40:01 -040048void Group::onRender(SkCanvas* canvas, const RenderContext* ctx) const {
49 // TODO: this heuristic works at the moment, but:
50 // a) it is fragile because it relies on all leaf render nodes being atomic draws
51 // b) could be improved by e.g. detecting all leaf render draws are non-overlapping
Florin Malitaca858b62018-09-02 13:44:13 -040052 const auto isolate = fChildren.size() > 1;
Florin Malitac0132ff2018-08-09 07:40:01 -040053 const auto local_ctx = ScopedRenderContext(canvas, ctx).setIsolation(this->bounds(), isolate);
54
Florin Malita4aa44412017-12-19 12:21:02 -050055 for (const auto& child : fChildren) {
Florin Malitac0132ff2018-08-09 07:40:01 -040056 child->render(canvas, local_ctx);
Florin Malita4aa44412017-12-19 12:21:02 -050057 }
58}
59
Florin Malitac14f1442018-01-05 11:32:31 -050060SkRect Group::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) {
Florin Malitac75e2402018-01-03 16:17:29 -050061 SkASSERT(this->hasInval());
62
Florin Malitac14f1442018-01-05 11:32:31 -050063 SkRect bounds = SkRect::MakeEmpty();
Florin Malitac75e2402018-01-03 16:17:29 -050064
Florin Malita4aa44412017-12-19 12:21:02 -050065 for (const auto& child : fChildren) {
Florin Malitac14f1442018-01-05 11:32:31 -050066 bounds.join(child->revalidate(ic, ctm));
Florin Malita4aa44412017-12-19 12:21:02 -050067 }
Florin Malitac75e2402018-01-03 16:17:29 -050068
Florin Malitac14f1442018-01-05 11:32:31 -050069 return bounds;
Florin Malita4aa44412017-12-19 12:21:02 -050070}
71
72} // namespace sksg