1 /* 2 * Copyright 2022 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_AtlasManager_DEFINED 9 #define skgpu_graphite_AtlasManager_DEFINED 10 11 #include "include/gpu/graphite/TextureInfo.h" 12 #include "src/gpu/AtlasTypes.h" 13 #include "src/gpu/graphite/Caps.h" 14 #include "src/gpu/graphite/DrawAtlas.h" 15 16 namespace sktext::gpu { 17 class Glyph; 18 } 19 class SkGlyph; 20 21 namespace skgpu::graphite { 22 23 class Recorder; 24 class UploadList; 25 26 ////////////////////////////////////////////////////////////////////////////////////////////////// 27 /** The AtlasManager manages the lifetime of and access to DrawAtlases. 28 */ 29 class AtlasManager : public AtlasGenerationCounter { 30 public: 31 AtlasManager(Recorder*); 32 ~AtlasManager(); 33 34 // If getProxies returns nullptr, the client must not try to use other functions on the 35 // StrikeCache which use the atlas. This function *must* be called first, before other 36 // functions which use the atlas. getProxies(MaskFormat format,unsigned int * numActiveProxies)37 const sk_sp<TextureProxy>* getProxies(MaskFormat format, 38 unsigned int* numActiveProxies) { 39 format = this->resolveMaskFormat(format); 40 if (this->initAtlas(format)) { 41 *numActiveProxies = this->getAtlas(format)->numActivePages(); 42 return this->getAtlas(format)->getProxies(); 43 } 44 *numActiveProxies = 0; 45 return nullptr; 46 } 47 48 void freeAll(); 49 50 bool hasGlyph(MaskFormat, sktext::gpu::Glyph*); 51 52 DrawAtlas::ErrorCode addGlyphToAtlas(const SkGlyph&, 53 sktext::gpu::Glyph*, 54 int srcPadding); 55 56 // To ensure the DrawAtlas does not evict the Glyph Mask from its texture backing store, 57 // the client must pass in the current draw token along with the sktext::gpu::Glyph. 58 // A BulkUsePlotUpdater is used to manage bulk last use token updating in the Atlas. 59 // For convenience, this function will also set the use token for the current glyph if required 60 // NOTE: the bulk uploader is only valid if the subrun has a valid atlasGeneration 61 void addGlyphToBulkAndSetUseToken(BulkUsePlotUpdater*, MaskFormat, 62 sktext::gpu::Glyph*, AtlasToken); 63 setUseTokenBulk(const BulkUsePlotUpdater & updater,AtlasToken token,MaskFormat format)64 void setUseTokenBulk(const BulkUsePlotUpdater& updater, 65 AtlasToken token, 66 MaskFormat format) { 67 this->getAtlas(format)->setLastUseTokenBulk(updater, token); 68 } 69 70 bool recordUploads(UploadList*, bool useCachedUploads); 71 evictAtlases()72 void evictAtlases() { 73 for (int i = 0; i < kMaskFormatCount; ++i) { 74 if (fAtlases[i]) { 75 fAtlases[i]->evictAllPlots(); 76 } 77 } 78 } 79 80 // Some clients may wish to verify the integrity of the texture backing store of the 81 // GrDrawOpAtlas. The atlasGeneration returned below is a monotonically increasing number which 82 // changes every time something is removed from the texture backing store. atlasGeneration(skgpu::MaskFormat format)83 uint64_t atlasGeneration(skgpu::MaskFormat format) const { 84 return this->getAtlas(format)->atlasGeneration(); 85 } 86 87 /////////////////////////////////////////////////////////////////////////// 88 // Functions intended debug only 89 90 void setAtlasDimensionsToMinimum_ForTesting(); 91 void setMaxPages_TestingOnly(uint32_t maxPages); 92 93 private: 94 bool initAtlas(MaskFormat); 95 // Change an expected 565 mask format to 8888 if 565 is not supported (will happen when using 96 // Metal on Intel MacOS). The actual conversion of the data is handled in 97 // get_packed_glyph_image() in StrikeCache.cpp 98 MaskFormat resolveMaskFormat(MaskFormat format) const; 99 100 // There is a 1:1 mapping between skgpu::MaskFormats and atlas indices MaskFormatToAtlasIndex(skgpu::MaskFormat format)101 static int MaskFormatToAtlasIndex(skgpu::MaskFormat format) { 102 return static_cast<int>(format); 103 } AtlasIndexToMaskFormat(int idx)104 static skgpu::MaskFormat AtlasIndexToMaskFormat(int idx) { 105 return static_cast<skgpu::MaskFormat>(idx); 106 } 107 getAtlas(skgpu::MaskFormat format)108 DrawAtlas* getAtlas(skgpu::MaskFormat format) const { 109 format = this->resolveMaskFormat(format); 110 int atlasIndex = MaskFormatToAtlasIndex(format); 111 SkASSERT(fAtlases[atlasIndex]); 112 return fAtlases[atlasIndex].get(); 113 } 114 115 Recorder* fRecorder; 116 DrawAtlas::AllowMultitexturing fAllowMultitexturing; 117 std::unique_ptr<DrawAtlas> fAtlases[kMaskFormatCount]; 118 static_assert(kMaskFormatCount == 3); 119 bool fSupportBilerpAtlas; 120 DrawAtlasConfig fAtlasConfig; 121 }; 122 123 } // namespace skgpu::graphite 124 125 #endif // skgpu_graphite_AtlasManager_DEFINED 126