1 /* 2 * Copyright 2024 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_graphite_ClipAtlasManager_DEFINED 9 #define skgpu_graphite_ClipAtlasManager_DEFINED 10 11 #include "include/gpu/graphite/TextureInfo.h" 12 #include "src/base/SkTInternalLList.h" 13 #include "src/gpu/AtlasTypes.h" 14 #include "src/gpu/ResourceKey.h" 15 #include "src/gpu/graphite/ClipStack.h" 16 #include "src/gpu/graphite/DrawAtlas.h" 17 #include "src/gpu/graphite/geom/Rect.h" 18 19 namespace skgpu::graphite { 20 21 class Recorder; 22 23 ////////////////////////////////////////////////////////////////////////////////////////////////// 24 /** The ClipAtlasManager manages the lifetime of and access to rasterized clip masks. 25 */ 26 class ClipAtlasManager { 27 public: 28 ClipAtlasManager(Recorder* recorder); 29 ~ClipAtlasManager() = default; 30 31 const TextureProxy* findOrCreateEntry(uint32_t stackRecordID, 32 const ClipStack::ElementList*, 33 SkIRect iBounds, 34 SkIPoint* outPos); 35 36 bool recordUploads(DrawContext* dc); 37 void compact(); 38 void freeGpuResources(); 39 40 void evictAtlases(); 41 42 private: 43 // Wrapper class to manage DrawAtlas and associated caching operations 44 class DrawAtlasMgr : public AtlasGenerationCounter, public PlotEvictionCallback { 45 public: 46 DrawAtlasMgr(size_t width, size_t height, 47 size_t plotWidth, size_t plotHeight, 48 DrawAtlas::UseStorageTextures useStorageTextures, 49 std::string_view label, const Caps*); 50 51 const TextureProxy* findOrCreateEntry(Recorder* recorder, 52 const skgpu::UniqueKey&, 53 const ClipStack::ElementList*, 54 SkIRect iBounds, 55 SkIPoint* outPos); 56 // Adds to DrawAtlas but not the cache 57 const TextureProxy* addToAtlas(Recorder* recorder, 58 const ClipStack::ElementList*, 59 SkIRect iBounds, 60 SkIPoint* outPos, 61 AtlasLocator* locator); 62 bool recordUploads(DrawContext*, Recorder*); 63 void evict(PlotLocator) override; 64 void compact(Recorder*); 65 void freeGpuResources(Recorder*); 66 67 void evictAll(); 68 69 private: 70 std::unique_ptr<DrawAtlas> fDrawAtlas; 71 72 // Tracks whether a combined clip mask is already in the DrawAtlas and its location 73 struct MaskHashEntry { 74 SkIRect fBounds; 75 AtlasLocator fLocator; 76 MaskHashEntry* fNext = nullptr; 77 }; 78 struct UniqueKeyHash { operatorUniqueKeyHash79 uint32_t operator()(const skgpu::UniqueKey& key) const { return key.hash(); } 80 }; 81 using MaskCache = skia_private::THashMap<skgpu::UniqueKey, MaskHashEntry, UniqueKeyHash>; 82 MaskCache fMaskCache; 83 int fHashEntryCount = 0; 84 85 // List of stored keys per Plot, used to invalidate cache entries. 86 // When a Plot is invalidated via evict(), we'll get its index and Page index from the 87 // PlotLocator, index into the fKeyLists array to get the MaskKeyList for that Plot, 88 // then iterate through the list and remove entries matching those keys from the MaskCache. 89 struct MaskKeyEntry { 90 skgpu::UniqueKey fKey; 91 SkIRect fBounds; 92 SK_DECLARE_INTERNAL_LLIST_INTERFACE(MaskKeyEntry); 93 }; 94 using MaskKeyList = SkTInternalLList<MaskKeyEntry>; 95 SkTDArray<MaskKeyList> fKeyLists; 96 int fListEntryCount = 0; 97 }; 98 99 Recorder* fRecorder; 100 DrawAtlasMgr fDrawAtlasMgr; 101 }; 102 103 } // namespace skgpu::graphite 104 105 #endif // skgpu_graphite_ClipAtlasManager_DEFINED 106