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