• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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