1 /* 2 * Copyright 2018 Google Inc. 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 GrAtlasManager_DEFINED 9 #define GrAtlasManager_DEFINED 10 11 #include "src/gpu/GrCaps.h" 12 #include "src/gpu/GrDrawOpAtlas.h" 13 #include "src/gpu/GrOnFlushResourceProvider.h" 14 #include "src/gpu/GrProxyProvider.h" 15 16 struct GrGlyph; 17 class GrTextStrike; 18 19 ////////////////////////////////////////////////////////////////////////////////////////////////// 20 /** The GrAtlasManager manages the lifetime of and access to GrDrawOpAtlases. 21 * It is only available at flush and only via the GrOpFlushState. 22 * 23 * This implies that all of the advanced atlasManager functionality (i.e., 24 * adding glyphs to the atlas) are only available at flush time. 25 */ 26 class GrAtlasManager : public GrOnFlushCallbackObject { 27 public: 28 GrAtlasManager(GrProxyProvider*, GrStrikeCache*, 29 size_t maxTextureBytes, GrDrawOpAtlas::AllowMultitexturing, int plotOldThreshold); 30 ~GrAtlasManager() override; 31 32 // Change an expected 565 mask format to 8888 if 565 is not supported (will happen when using 33 // Metal on macOS). The actual conversion of the data is handled in get_packed_glyph_image() in 34 // GrStrikeCache.cpp resolveMaskFormat(GrMaskFormat format)35 GrMaskFormat resolveMaskFormat(GrMaskFormat format) const { 36 if (kA565_GrMaskFormat == format && 37 !fProxyProvider->caps()->getDefaultBackendFormat(GrColorType::kBGR_565, 38 GrRenderable::kNo).isValid()) { 39 format = kARGB_GrMaskFormat; 40 } 41 return format; 42 } 43 44 // if getProxies returns nullptr, the client must not try to use other functions on the 45 // GrStrikeCache which use the atlas. This function *must* be called first, before other 46 // functions which use the atlas. Note that we can have proxies available but none active 47 // (i.e., none instantiated). getProxies(GrMaskFormat format,unsigned int * numActiveProxies)48 const sk_sp<GrTextureProxy>* getProxies(GrMaskFormat format, unsigned int* numActiveProxies) { 49 format = this->resolveMaskFormat(format); 50 if (this->initAtlas(format)) { 51 *numActiveProxies = this->getAtlas(format)->numActivePages(); 52 return this->getAtlas(format)->getProxies(); 53 } 54 *numActiveProxies = 0; 55 return nullptr; 56 } 57 58 void freeAll(); 59 60 bool hasGlyph(GrGlyph* glyph); 61 incAtlasHitCount()62 void incAtlasHitCount() { fAtlasHitCount++; } incAtlasMissCount()63 void incAtlasMissCount() { fAtlasMissCount++; } atlasHitRate()64 float atlasHitRate() { 65 if (fAtlasHitCount + fAtlasMissCount == 0) { 66 return 0; 67 } 68 return (float)fAtlasHitCount / (fAtlasHitCount + fAtlasMissCount); 69 } resetHitCount()70 void resetHitCount() { 71 fAtlasHitCount = 0; 72 fAtlasMissCount = 0; 73 } 74 75 // To ensure the GrDrawOpAtlas does not evict the Glyph Mask from its texture backing store, 76 // the client must pass in the current op token along with the GrGlyph. 77 // A BulkUseTokenUpdater is used to manage bulk last use token updating in the Atlas. 78 // For convenience, this function will also set the use token for the current glyph if required 79 // NOTE: the bulk uploader is only valid if the subrun has a valid atlasGeneration 80 void addGlyphToBulkAndSetUseToken(GrDrawOpAtlas::BulkUseTokenUpdater*, GrGlyph*, 81 GrDeferredUploadToken); 82 setUseTokenBulk(const GrDrawOpAtlas::BulkUseTokenUpdater & updater,GrDeferredUploadToken token,GrMaskFormat format)83 void setUseTokenBulk(const GrDrawOpAtlas::BulkUseTokenUpdater& updater, 84 GrDeferredUploadToken token, 85 GrMaskFormat format) { 86 this->getAtlas(format)->setLastUseTokenBulk(updater, token); 87 } 88 89 // add to texture atlas that matches this format 90 GrDrawOpAtlas::ErrorCode addToAtlas( 91 GrResourceProvider*, GrStrikeCache*, GrTextStrike*, 92 GrDrawOpAtlas::AtlasID*, GrDeferredUploadTarget*, GrMaskFormat, 93 int width, int height, const void* image, SkIPoint16* loc); 94 95 // Some clients may wish to verify the integrity of the texture backing store of the 96 // GrDrawOpAtlas. The atlasGeneration returned below is a monotonically increasing number which 97 // changes every time something is removed from the texture backing store. atlasGeneration(GrMaskFormat format)98 uint64_t atlasGeneration(GrMaskFormat format) const { 99 return this->getAtlas(format)->atlasGeneration(); 100 } 101 102 // GrOnFlushCallbackObject overrides 103 preFlush(GrOnFlushResourceProvider * onFlushResourceProvider,const uint32_t *,int,SkTArray<sk_sp<GrRenderTargetContext>> *)104 void preFlush(GrOnFlushResourceProvider* onFlushResourceProvider, const uint32_t*, int, 105 SkTArray<sk_sp<GrRenderTargetContext>>*) override { 106 for (int i = 0; i < kMaskFormatCount; ++i) { 107 if (fAtlases[i]) { 108 fAtlases[i]->instantiate(onFlushResourceProvider); 109 } 110 } 111 } 112 113 void postFlush(GrDeferredUploadToken startTokenForNextFlush, 114 const uint32_t* opListIDs, int numOpListIDs) override; 115 116 // The AtlasGlyph cache always survives freeGpuResources so we want it to remain in the active 117 // OnFlushCallbackObject list retainOnFreeGpuResources()118 bool retainOnFreeGpuResources() override { return true; } 119 120 /////////////////////////////////////////////////////////////////////////// 121 // Functions intended debug only 122 #ifdef SK_DUMP_ATLAS_IMAGE 123 void dump(GrContext* context) const; 124 #endif 125 126 void setAtlasSizesToMinimum_ForTesting(); 127 void setMaxPages_TestingOnly(uint32_t maxPages); 128 129 private: 130 bool initAtlas(GrMaskFormat); 131 132 // There is a 1:1 mapping between GrMaskFormats and atlas indices MaskFormatToAtlasIndex(GrMaskFormat format)133 static int MaskFormatToAtlasIndex(GrMaskFormat format) { return static_cast<int>(format); } AtlasIndexToMaskFormat(int idx)134 static GrMaskFormat AtlasIndexToMaskFormat(int idx) { return static_cast<GrMaskFormat>(idx); } 135 getAtlas(GrMaskFormat format)136 GrDrawOpAtlas* getAtlas(GrMaskFormat format) const { 137 format = this->resolveMaskFormat(format); 138 int atlasIndex = MaskFormatToAtlasIndex(format); 139 SkASSERT(fAtlases[atlasIndex]); 140 return fAtlases[atlasIndex].get(); 141 } 142 143 GrDrawOpAtlas::AllowMultitexturing fAllowMultitexturing; 144 std::unique_ptr<GrDrawOpAtlas> fAtlases[kMaskFormatCount]; 145 GrProxyProvider* fProxyProvider; 146 sk_sp<const GrCaps> fCaps; 147 GrStrikeCache* fGlyphCache; 148 GrDrawOpAtlasConfig fAtlasConfig; 149 int fPlotOldThreshold; 150 int fAtlasHitCount; 151 int fAtlasMissCount; 152 153 typedef GrOnFlushCallbackObject INHERITED; 154 }; 155 156 #endif // GrAtlasManager_DEFINED 157