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