1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2017 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #ifndef SkSGNode_DEFINED 9*c8dee2aaSAndroid Build Coastguard Worker #define SkSGNode_DEFINED 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAssert.h" 14*c8dee2aaSAndroid Build Coastguard Worker 15*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint> 16*c8dee2aaSAndroid Build Coastguard Worker #include <vector> 17*c8dee2aaSAndroid Build Coastguard Worker 18*c8dee2aaSAndroid Build Coastguard Worker class SkMatrix; 19*c8dee2aaSAndroid Build Coastguard Worker 20*c8dee2aaSAndroid Build Coastguard Worker namespace sksg { 21*c8dee2aaSAndroid Build Coastguard Worker 22*c8dee2aaSAndroid Build Coastguard Worker class InvalidationController; 23*c8dee2aaSAndroid Build Coastguard Worker 24*c8dee2aaSAndroid Build Coastguard Worker /** 25*c8dee2aaSAndroid Build Coastguard Worker * Base class for all scene graph nodes. 26*c8dee2aaSAndroid Build Coastguard Worker * 27*c8dee2aaSAndroid Build Coastguard Worker * Handles ingress edge management for the DAG (i.e. node -> "parent" node mapping), 28*c8dee2aaSAndroid Build Coastguard Worker * and invalidation. 29*c8dee2aaSAndroid Build Coastguard Worker * 30*c8dee2aaSAndroid Build Coastguard Worker * Note: egress edges are only implemented/supported in container subclasses 31*c8dee2aaSAndroid Build Coastguard Worker * (e.g. Group, Effect, Draw). 32*c8dee2aaSAndroid Build Coastguard Worker */ 33*c8dee2aaSAndroid Build Coastguard Worker class Node : public SkRefCnt { 34*c8dee2aaSAndroid Build Coastguard Worker public: 35*c8dee2aaSAndroid Build Coastguard Worker // Traverse the DAG and revalidate any dependant/invalidated nodes. 36*c8dee2aaSAndroid Build Coastguard Worker // Returns the bounding box for the DAG fragment. 37*c8dee2aaSAndroid Build Coastguard Worker const SkRect& revalidate(InvalidationController*, const SkMatrix&); 38*c8dee2aaSAndroid Build Coastguard Worker 39*c8dee2aaSAndroid Build Coastguard Worker // Tag this node for invalidation and optional damage. 40*c8dee2aaSAndroid Build Coastguard Worker void invalidate(bool damage = true); 41*c8dee2aaSAndroid Build Coastguard Worker 42*c8dee2aaSAndroid Build Coastguard Worker protected: 43*c8dee2aaSAndroid Build Coastguard Worker enum InvalTraits { 44*c8dee2aaSAndroid Build Coastguard Worker // Nodes with this trait never generate direct damage -- instead, 45*c8dee2aaSAndroid Build Coastguard Worker // the damage bubbles up to ancestors. 46*c8dee2aaSAndroid Build Coastguard Worker kBubbleDamage_Trait = 1 << 0, 47*c8dee2aaSAndroid Build Coastguard Worker 48*c8dee2aaSAndroid Build Coastguard Worker // Nodes with this trait obscure the descendants' damage and always override it. 49*c8dee2aaSAndroid Build Coastguard Worker kOverrideDamage_Trait = 1 << 1, 50*c8dee2aaSAndroid Build Coastguard Worker }; 51*c8dee2aaSAndroid Build Coastguard Worker 52*c8dee2aaSAndroid Build Coastguard Worker explicit Node(uint32_t invalTraits); 53*c8dee2aaSAndroid Build Coastguard Worker ~Node() override; 54*c8dee2aaSAndroid Build Coastguard Worker bounds()55*c8dee2aaSAndroid Build Coastguard Worker const SkRect& bounds() const { 56*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!this->hasInval()); 57*c8dee2aaSAndroid Build Coastguard Worker return fBounds; 58*c8dee2aaSAndroid Build Coastguard Worker } 59*c8dee2aaSAndroid Build Coastguard Worker hasInval()60*c8dee2aaSAndroid Build Coastguard Worker bool hasInval() const { return fFlags & kInvalidated_Flag; } 61*c8dee2aaSAndroid Build Coastguard Worker 62*c8dee2aaSAndroid Build Coastguard Worker // Dispatched on revalidation. Subclasses are expected to recompute/cache their properties 63*c8dee2aaSAndroid Build Coastguard Worker // and return their bounding box in local coordinates. 64*c8dee2aaSAndroid Build Coastguard Worker virtual SkRect onRevalidate(InvalidationController*, const SkMatrix& ctm) = 0; 65*c8dee2aaSAndroid Build Coastguard Worker 66*c8dee2aaSAndroid Build Coastguard Worker // Register/unregister |this| to receive invalidation events from a descendant. 67*c8dee2aaSAndroid Build Coastguard Worker void observeInval(const sk_sp<Node>&); 68*c8dee2aaSAndroid Build Coastguard Worker void unobserveInval(const sk_sp<Node>&); 69*c8dee2aaSAndroid Build Coastguard Worker 70*c8dee2aaSAndroid Build Coastguard Worker private: 71*c8dee2aaSAndroid Build Coastguard Worker enum Flags { 72*c8dee2aaSAndroid Build Coastguard Worker kInvalidated_Flag = 1 << 0, // the node or its descendants require revalidation 73*c8dee2aaSAndroid Build Coastguard Worker kDamage_Flag = 1 << 1, // the node contributes damage during revalidation 74*c8dee2aaSAndroid Build Coastguard Worker kObserverArray_Flag = 1 << 2, // the node has more than one inval observer 75*c8dee2aaSAndroid Build Coastguard Worker kInTraversal_Flag = 1 << 3, // the node is part of a traversal (cycle detection) 76*c8dee2aaSAndroid Build Coastguard Worker }; 77*c8dee2aaSAndroid Build Coastguard Worker 78*c8dee2aaSAndroid Build Coastguard Worker template <typename Func> 79*c8dee2aaSAndroid Build Coastguard Worker void forEachInvalObserver(Func&&) const; 80*c8dee2aaSAndroid Build Coastguard Worker 81*c8dee2aaSAndroid Build Coastguard Worker class ScopedFlag; 82*c8dee2aaSAndroid Build Coastguard Worker 83*c8dee2aaSAndroid Build Coastguard Worker union { 84*c8dee2aaSAndroid Build Coastguard Worker Node* fInvalObserver; 85*c8dee2aaSAndroid Build Coastguard Worker std::vector<Node*>* fInvalObserverArray; 86*c8dee2aaSAndroid Build Coastguard Worker }; 87*c8dee2aaSAndroid Build Coastguard Worker SkRect fBounds; 88*c8dee2aaSAndroid Build Coastguard Worker const uint32_t fInvalTraits : 2; 89*c8dee2aaSAndroid Build Coastguard Worker uint32_t fFlags : 4; // Internal flags. 90*c8dee2aaSAndroid Build Coastguard Worker uint32_t fNodeFlags : 8; // Accessible from select subclasses. 91*c8dee2aaSAndroid Build Coastguard Worker // Free bits : 18; 92*c8dee2aaSAndroid Build Coastguard Worker 93*c8dee2aaSAndroid Build Coastguard Worker friend class NodePriv; 94*c8dee2aaSAndroid Build Coastguard Worker friend class RenderNode; // node flags access 95*c8dee2aaSAndroid Build Coastguard Worker 96*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = SkRefCnt; 97*c8dee2aaSAndroid Build Coastguard Worker }; 98*c8dee2aaSAndroid Build Coastguard Worker 99*c8dee2aaSAndroid Build Coastguard Worker // Helper for defining attribute getters/setters in subclasses. 100*c8dee2aaSAndroid Build Coastguard Worker #define SG_ATTRIBUTE(attr_name, attr_type, attr_container) \ 101*c8dee2aaSAndroid Build Coastguard Worker const attr_type& get##attr_name() const { return attr_container; } \ 102*c8dee2aaSAndroid Build Coastguard Worker void set##attr_name(const attr_type& v) { \ 103*c8dee2aaSAndroid Build Coastguard Worker if (attr_container == v) return; \ 104*c8dee2aaSAndroid Build Coastguard Worker attr_container = v; \ 105*c8dee2aaSAndroid Build Coastguard Worker this->invalidate(); \ 106*c8dee2aaSAndroid Build Coastguard Worker } \ 107*c8dee2aaSAndroid Build Coastguard Worker void set##attr_name(attr_type&& v) { \ 108*c8dee2aaSAndroid Build Coastguard Worker if (attr_container == v) return; \ 109*c8dee2aaSAndroid Build Coastguard Worker attr_container = std::move(v); \ 110*c8dee2aaSAndroid Build Coastguard Worker this->invalidate(); \ 111*c8dee2aaSAndroid Build Coastguard Worker } 112*c8dee2aaSAndroid Build Coastguard Worker 113*c8dee2aaSAndroid Build Coastguard Worker #define SG_MAPPED_ATTRIBUTE(attr_name, attr_type, attr_container) \ 114*c8dee2aaSAndroid Build Coastguard Worker attr_type get##attr_name() const { return attr_container.get##attr_name(); } \ 115*c8dee2aaSAndroid Build Coastguard Worker void set##attr_name(const attr_type& v) { \ 116*c8dee2aaSAndroid Build Coastguard Worker if (attr_container.get##attr_name() == v) return; \ 117*c8dee2aaSAndroid Build Coastguard Worker attr_container.set##attr_name(v); \ 118*c8dee2aaSAndroid Build Coastguard Worker this->invalidate(); \ 119*c8dee2aaSAndroid Build Coastguard Worker } \ 120*c8dee2aaSAndroid Build Coastguard Worker void set##attr_name(attr_type&& v) { \ 121*c8dee2aaSAndroid Build Coastguard Worker if (attr_container.get##attr_name() == v) return; \ 122*c8dee2aaSAndroid Build Coastguard Worker attr_container.set##attr_name(std::move(v)); \ 123*c8dee2aaSAndroid Build Coastguard Worker this->invalidate(); \ 124*c8dee2aaSAndroid Build Coastguard Worker } 125*c8dee2aaSAndroid Build Coastguard Worker 126*c8dee2aaSAndroid Build Coastguard Worker } // namespace sksg 127*c8dee2aaSAndroid Build Coastguard Worker 128*c8dee2aaSAndroid Build Coastguard Worker #endif // SkSGNode_DEFINED 129