1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2021 Google LLC 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#ifndef skgpu_geom_IntersectionTree_DEFINED 9cb93a386Sopenharmony_ci#define skgpu_geom_IntersectionTree_DEFINED 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ci#include "experimental/graphite/src/geom/Rect.h" 12cb93a386Sopenharmony_ci#include "src/core/SkArenaAlloc.h" 13cb93a386Sopenharmony_ci 14cb93a386Sopenharmony_cinamespace skgpu { 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_ci// Maintains a collection of non-overlapping rectangles. 17cb93a386Sopenharmony_ci// 18cb93a386Sopenharmony_ci// add() either adds the given rect to the collection, or returns false if it intersected with a 19cb93a386Sopenharmony_ci// rect already in the collection. 20cb93a386Sopenharmony_ciclass IntersectionTree { 21cb93a386Sopenharmony_cipublic: 22cb93a386Sopenharmony_ci IntersectionTree(); 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_ci bool add(Rect rect) { 25cb93a386Sopenharmony_ci if (rect.isEmptyNegativeOrNaN()) { 26cb93a386Sopenharmony_ci // Empty and undefined rects can simply pass without modifying the tree. 27cb93a386Sopenharmony_ci return true; 28cb93a386Sopenharmony_ci } 29cb93a386Sopenharmony_ci if (!fRoot->intersects(rect)) { 30cb93a386Sopenharmony_ci fRoot = fRoot->addNonIntersecting(rect, &fArena); 31cb93a386Sopenharmony_ci return true; 32cb93a386Sopenharmony_ci } 33cb93a386Sopenharmony_ci return false; 34cb93a386Sopenharmony_ci } 35cb93a386Sopenharmony_ci 36cb93a386Sopenharmony_ciprivate: 37cb93a386Sopenharmony_ci class Node { 38cb93a386Sopenharmony_ci public: 39cb93a386Sopenharmony_ci virtual ~Node() = default; 40cb93a386Sopenharmony_ci 41cb93a386Sopenharmony_ci virtual bool intersects(Rect) = 0; 42cb93a386Sopenharmony_ci virtual Node* addNonIntersecting(Rect, SkArenaAlloc*) = 0; 43cb93a386Sopenharmony_ci }; 44cb93a386Sopenharmony_ci 45cb93a386Sopenharmony_ci enum class SplitType : bool { 46cb93a386Sopenharmony_ci kX, 47cb93a386Sopenharmony_ci kY 48cb93a386Sopenharmony_ci }; 49cb93a386Sopenharmony_ci 50cb93a386Sopenharmony_ci template<SplitType kSplitType> class TreeNode; 51cb93a386Sopenharmony_ci class LeafNode; 52cb93a386Sopenharmony_ci 53cb93a386Sopenharmony_ci constexpr static int kTreeNodeSize = 16 + sizeof(Node*) * 2; 54cb93a386Sopenharmony_ci constexpr static int kLeafNodeSize = 16 + (2 + 64) * sizeof(float4); 55cb93a386Sopenharmony_ci constexpr static int kPadSize = 256; // For footers and alignment. 56cb93a386Sopenharmony_ci SkArenaAlloc fArena{kLeafNodeSize + kTreeNodeSize + kPadSize*2}; 57cb93a386Sopenharmony_ci Node* fRoot; 58cb93a386Sopenharmony_ci}; 59cb93a386Sopenharmony_ci 60cb93a386Sopenharmony_ci 61cb93a386Sopenharmony_ci} // namespace skgpu 62cb93a386Sopenharmony_ci 63cb93a386Sopenharmony_ci#endif // skgpu_geom_IntersectionTree_DEFINED 64