• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
10 #include <algorithm>
11 
12 namespace sksg {
13 
Group(std::vector<sk_sp<RenderNode>> children)14 Group::Group(std::vector<sk_sp<RenderNode>> children)
15     : fChildren(std::move(children)) {
16     for (const auto& child : fChildren) {
17         this->observeInval(child);
18     }
19 }
20 
~Group()21 Group::~Group() {
22     for (const auto& child : fChildren) {
23         this->unobserveInval(child);
24     }
25 }
26 
clear()27 void Group::clear() {
28     for (const auto& child : fChildren) {
29         this->unobserveInval(child);
30     }
31     fChildren.clear();
32 }
33 
addChild(sk_sp<RenderNode> node)34 void Group::addChild(sk_sp<RenderNode> node) {
35     // should we allow duplicates?
36     for (const auto& child : fChildren) {
37         if (child == node) {
38             return;
39         }
40     }
41 
42     this->observeInval(node);
43     fChildren.push_back(std::move(node));
44 
45     this->invalidate();
46 }
47 
removeChild(const sk_sp<RenderNode> & node)48 void Group::removeChild(const sk_sp<RenderNode>& node) {
49     SkDEBUGCODE(const auto origSize = fChildren.size());
50     fChildren.erase(std::remove(fChildren.begin(), fChildren.end(), node), fChildren.end());
51     SkASSERT(fChildren.size() == origSize - 1);
52 
53     this->unobserveInval(node);
54     this->invalidate();
55 }
56 
onRender(SkCanvas * canvas,const RenderContext * ctx) const57 void Group::onRender(SkCanvas* canvas, const RenderContext* ctx) const {
58     // TODO: this heuristic works at the moment, but:
59     //   a) it is fragile because it relies on all leaf render nodes being atomic draws
60     //   b) could be improved by e.g. detecting all leaf render draws are non-overlapping
61     const auto isolate = fChildren.size() > 1;
62     const auto local_ctx = ScopedRenderContext(canvas, ctx).setIsolation(this->bounds(), isolate);
63 
64     for (const auto& child : fChildren) {
65         child->render(canvas, local_ctx);
66     }
67 }
68 
onNodeAt(const SkPoint & p) const69 const RenderNode* Group::onNodeAt(const SkPoint& p) const {
70     for (auto it = fChildren.crbegin(); it != fChildren.crend(); ++it) {
71         if (const auto* node = (*it)->nodeAt(p)) {
72             return node;
73         }
74     }
75 
76     return nullptr;
77 }
78 
onRevalidate(InvalidationController * ic,const SkMatrix & ctm)79 SkRect Group::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) {
80     SkASSERT(this->hasInval());
81 
82     SkRect bounds = SkRect::MakeEmpty();
83 
84     for (const auto& child : fChildren) {
85         bounds.join(child->revalidate(ic, ctm));
86     }
87 
88     return bounds;
89 }
90 
91 } // namespace sksg
92