1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2021 Google LLC 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 skgpu_graphite_geom_IntersectionTree_DEFINED 9*c8dee2aaSAndroid Build Coastguard Worker #define skgpu_graphite_geom_IntersectionTree_DEFINED 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAlign.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkArenaAlloc.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/geom/Rect.h" 14*c8dee2aaSAndroid Build Coastguard Worker 15*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu::graphite { 16*c8dee2aaSAndroid Build Coastguard Worker 17*c8dee2aaSAndroid Build Coastguard Worker /** 18*c8dee2aaSAndroid Build Coastguard Worker * Maintains a collection of non-overlapping rectangles. 19*c8dee2aaSAndroid Build Coastguard Worker * 20*c8dee2aaSAndroid Build Coastguard Worker * add() either adds the given rect to the collection, or returns false if it intersected with a 21*c8dee2aaSAndroid Build Coastguard Worker * rect already in the collection. 22*c8dee2aaSAndroid Build Coastguard Worker */ 23*c8dee2aaSAndroid Build Coastguard Worker class IntersectionTree { 24*c8dee2aaSAndroid Build Coastguard Worker public: 25*c8dee2aaSAndroid Build Coastguard Worker enum class SplitType : bool { 26*c8dee2aaSAndroid Build Coastguard Worker kX, 27*c8dee2aaSAndroid Build Coastguard Worker kY 28*c8dee2aaSAndroid Build Coastguard Worker }; 29*c8dee2aaSAndroid Build Coastguard Worker 30*c8dee2aaSAndroid Build Coastguard Worker IntersectionTree(); 31*c8dee2aaSAndroid Build Coastguard Worker add(Rect rect)32*c8dee2aaSAndroid Build Coastguard Worker bool add(Rect rect) { 33*c8dee2aaSAndroid Build Coastguard Worker if (rect.isEmptyNegativeOrNaN()) { 34*c8dee2aaSAndroid Build Coastguard Worker // Empty and undefined rects can simply pass without modifying the tree. 35*c8dee2aaSAndroid Build Coastguard Worker return true; 36*c8dee2aaSAndroid Build Coastguard Worker } 37*c8dee2aaSAndroid Build Coastguard Worker if (!fRoot->intersects(rect)) { 38*c8dee2aaSAndroid Build Coastguard Worker fRoot = fRoot->addNonIntersecting(rect, &fArena); 39*c8dee2aaSAndroid Build Coastguard Worker return true; 40*c8dee2aaSAndroid Build Coastguard Worker } 41*c8dee2aaSAndroid Build Coastguard Worker return false; 42*c8dee2aaSAndroid Build Coastguard Worker } 43*c8dee2aaSAndroid Build Coastguard Worker 44*c8dee2aaSAndroid Build Coastguard Worker private: 45*c8dee2aaSAndroid Build Coastguard Worker class Node { 46*c8dee2aaSAndroid Build Coastguard Worker public: 47*c8dee2aaSAndroid Build Coastguard Worker virtual ~Node() = default; 48*c8dee2aaSAndroid Build Coastguard Worker 49*c8dee2aaSAndroid Build Coastguard Worker virtual bool intersects(Rect) = 0; 50*c8dee2aaSAndroid Build Coastguard Worker virtual Node* addNonIntersecting(Rect, SkArenaAlloc*) = 0; 51*c8dee2aaSAndroid Build Coastguard Worker }; 52*c8dee2aaSAndroid Build Coastguard Worker 53*c8dee2aaSAndroid Build Coastguard Worker template<SplitType kSplitType> class TreeNode; 54*c8dee2aaSAndroid Build Coastguard Worker class LeafNode; 55*c8dee2aaSAndroid Build Coastguard Worker 56*c8dee2aaSAndroid Build Coastguard Worker // The TreeNode size is made of a vtable (i.e. sizeof(void*)), float, and two Node* pointers. 57*c8dee2aaSAndroid Build Coastguard Worker // We also align between the Node* and the float which may add some extra padding. 58*c8dee2aaSAndroid Build Coastguard Worker constexpr static int kTreeNodeSize = SkAlignTo(sizeof(void*) + sizeof(float), alignof(void*)) + 59*c8dee2aaSAndroid Build Coastguard Worker 2 * sizeof(Node*); 60*c8dee2aaSAndroid Build Coastguard Worker constexpr static int kLeafNodeSize = 16 + (2 + 64) * sizeof(Rect); 61*c8dee2aaSAndroid Build Coastguard Worker constexpr static int kPadSize = 256; // For footers and alignment. 62*c8dee2aaSAndroid Build Coastguard Worker SkArenaAlloc fArena{kLeafNodeSize + kTreeNodeSize + kPadSize*2}; 63*c8dee2aaSAndroid Build Coastguard Worker Node* fRoot; 64*c8dee2aaSAndroid Build Coastguard Worker }; 65*c8dee2aaSAndroid Build Coastguard Worker 66*c8dee2aaSAndroid Build Coastguard Worker } // namespace skgpu::graphite 67*c8dee2aaSAndroid Build Coastguard Worker 68*c8dee2aaSAndroid Build Coastguard Worker #endif // skgpu_graphite_geom_IntersectionTree_DEFINED 69