1 /* 2 * Copyright 2021 Google LLC 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 #ifndef skgpu_geom_BoundsManager_DEFINED 9 #define skgpu_geom_BoundsManager_DEFINED 10 11 #include "experimental/graphite/src/DrawOrder.h" 12 #include "experimental/graphite/src/geom/Rect.h" 13 14 #include "src/core/SkTBlockList.h" 15 16 #include <cstdint> 17 18 namespace skgpu { 19 20 /** 21 * BoundsManager is an acceleration structure for device-space related pixel bounds queries. 22 * The BoundsManager relies on two related ordinal values: the CompressedPaintersOrder of a draw 23 * and the Z/depth value of the draw. The CompressedPaintersOrder enforces a specific submission 24 * order of draws to the GPU but can re-arrange draws out of their original painter's order if the 25 * GREATER depth test and the draw's Z value resolve out-of-order rendering. 26 * 27 * It supports querying the most recent draw intersecting a bounding rect (represented as a 28 * CompressedPaintersOrder value), recording a (bounds, CompressedPaintersOrder, and Z value) tuple, 29 * and querying if a (bounds, Z value) pair is fully occluded by another draw. 30 */ 31 class BoundsManager { 32 public: ~BoundsManager()33 virtual ~BoundsManager() {} 34 35 virtual CompressedPaintersOrder getMostRecentDraw(const Rect& bounds) const = 0; 36 37 virtual bool isOccluded(const Rect& bounds, PaintersDepth z) const = 0; 38 39 virtual void recordDraw(const Rect& bounds, 40 CompressedPaintersOrder order, 41 PaintersDepth z, 42 bool fullyOpaque=false) = 0; 43 }; 44 45 // TODO: Select one most-effective BoundsManager implementation, make it the only option, and remove 46 // virtual-ness. For now, this seems useful for correctness testing by comparing against trivial 47 // implementations and for identifying how much "smarts" are actually worthwhile. 48 49 // A BoundsManager that produces exact painter's order and assumes nothing is occluded. 50 class NaiveBoundsManager final : public BoundsManager { 51 public: ~NaiveBoundsManager()52 ~NaiveBoundsManager() override {} 53 getMostRecentDraw(const Rect & bounds)54 CompressedPaintersOrder getMostRecentDraw(const Rect& bounds) const override { 55 return fLatestDraw; 56 } 57 isOccluded(const Rect & bounds,PaintersDepth z)58 bool isOccluded(const Rect& bounds, PaintersDepth z) const override { return false; } 59 60 void recordDraw(const Rect& bounds, CompressedPaintersOrder order, PaintersDepth z, 61 bool fullyOpaque=false) override { 62 if (fLatestDraw < order) { 63 fLatestDraw = order; 64 } 65 } 66 67 private: 68 CompressedPaintersOrder fLatestDraw = CompressedPaintersOrder::First(); 69 }; 70 71 // A BoundsManager that tracks every draw and can exactly determine all queries 72 // using a brute force search. 73 class BruteForceBoundsManager : public BoundsManager { 74 public: ~BruteForceBoundsManager()75 ~BruteForceBoundsManager() override {} 76 getMostRecentDraw(const Rect & bounds)77 CompressedPaintersOrder getMostRecentDraw(const Rect& bounds) const override { 78 CompressedPaintersOrder max = CompressedPaintersOrder::First(); 79 for (const Record& r : fRects.items()) { 80 if (max < r.fOrder && r.fBounds.intersects(bounds)) { 81 max = r.fOrder; 82 } 83 } 84 return max; 85 } 86 isOccluded(const Rect & bounds,PaintersDepth z)87 bool isOccluded(const Rect& bounds, PaintersDepth z) const override { 88 // Iterate in reverse since the records were likely recorded in increasing Z 89 for (const Record& r : fRects.ritems()) { 90 if (r.fOpaque && z < r.fZ && r.fBounds.contains(bounds)) { 91 return true; 92 } 93 } 94 return false; 95 } 96 97 void recordDraw(const Rect& bounds, CompressedPaintersOrder order, PaintersDepth z, 98 bool fullyOpaque=false) override { 99 fRects.push_back({bounds, order, z, fullyOpaque}); 100 } 101 102 private: 103 struct Record { 104 Rect fBounds; 105 CompressedPaintersOrder fOrder; 106 PaintersDepth fZ; 107 bool fOpaque; 108 }; 109 110 SkTBlockList<Record> fRects{16, SkBlockAllocator::GrowthPolicy::kFibonacci}; 111 }; 112 113 } // namespace skgpu 114 115 #endif // skgpu_geom_BoundsManager_DEFINED 116