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