blob: 30ff85d3c7518f3631aa676e045fa802f78c6957 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
/*
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkSGNode_DEFINED
#define SkSGNode_DEFINED
#include "SkRefCnt.h"
#include "SkTDArray.h"
class SkCanvas;
class SkMatrix;
namespace sksg {
class InvalidationController;
/**
* Base class for all scene graph nodes.
*
* Handles ingress edge management for the DAG (i.e. node -> "parent" node mapping),
* and invalidation.
*
* Note: egress edges are only implemented/supported in container subclasses
* (e.g. Group, Effect, Draw).
*/
class Node : public SkRefCnt {
public:
// Traverse the DAG and revalidate any connected/invalidated nodes.
void revalidate(InvalidationController*, const SkMatrix&);
protected:
Node();
~Node() override;
// Mark this node and (transitively) any invalidation receivers for revalidation.
void invalidate();
bool isInvalidated() const { return fFlags & kInvalidated_Flag; }
// Dispatched on revalidation. Subclasses are expected to recompute their geometry
// and push dirty rects to the InvalidationController.
virtual void onRevalidate(InvalidationController*, const SkMatrix& ctm) = 0;
private:
void addInvalReceiver(Node*);
void removeInvalReceiver(Node*);
friend class Draw;
friend class EffectNode;
friend class Group;
friend class Stroke;
template <typename Func>
void forEachInvalReceiver(Func&&) const;
enum Flags {
kInvalidated_Flag = 1 << 0, // the node requires revalidation
kReceiverArray_Flag = 1 << 1, // the node has more than one inval receiver
kInTraversal_Flag = 1 << 2, // the node is part of a traversal (cycle detection)
};
class ScopedFlag;
union {
Node* fInvalReceiver;
SkTDArray<Node*>* fInvalReceiverArray;
};
uint32_t fFlags;
typedef SkRefCnt INHERITED;
};
// Helper for defining attribute getters/setters in subclasses.
#define SG_ATTRIBUTE(attr_name, attr_type, attr_container) \
attr_type get##attr_name() const { return attr_container; } \
void set##attr_name(attr_type v) { \
if (attr_container == v) return; \
attr_container = v; \
this->invalidate(); \
}
} // namespace sksg
#endif // SkSGNode_DEFINED
|