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, public GrDrawOpAtlas::GenerationCounter { 27 public: 28 GrAtlasManager(GrProxyProvider*, GrStrikeCache*, 29 size_t maxTextureBytes, GrDrawOpAtlas::AllowMultitexturing); 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 getViews 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). getViews(GrMaskFormat format,unsigned int * numActiveProxies)48 const GrSurfaceProxyView* getViews(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)->getViews(); 53 } 54 *numActiveProxies = 0; 55 return nullptr; 56 } 57 58 void freeAll(); 59 60 bool hasGlyph(GrGlyph* glyph); 61 62 // To ensure the GrDrawOpAtlas does not evict the Glyph Mask from its texture backing store, 63 // the client must pass in the current op token along with the GrGlyph. 64 // A BulkUseTokenUpdater is used to manage bulk last use token updating in the Atlas. 65 // For convenience, this function will also set the use token for the current glyph if required 66 // NOTE: the bulk uploader is only valid if the subrun has a valid atlasGeneration 67 void addGlyphToBulkAndSetUseToken(GrDrawOpAtlas::BulkUseTokenUpdater*, GrGlyph*, 68 GrDeferredUploadToken); 69 setUseTokenBulk(const GrDrawOpAtlas::BulkUseTokenUpdater & updater,GrDeferredUploadToken token,GrMaskFormat format)70 void setUseTokenBulk(const GrDrawOpAtlas::BulkUseTokenUpdater& updater, 71 GrDeferredUploadToken token, 72 GrMaskFormat format) { 73 this->getAtlas(format)->setLastUseTokenBulk(updater, token); 74 } 75 76 // add to texture atlas that matches this format 77 GrDrawOpAtlas::ErrorCode addToAtlas( 78 GrResourceProvider*, 79 GrDrawOpAtlas::PlotLocator*, GrDeferredUploadTarget*, GrMaskFormat, 80 int width, int height, const void* image, SkIPoint16* loc); 81 82 // Some clients may wish to verify the integrity of the texture backing store of the 83 // GrDrawOpAtlas. The atlasGeneration returned below is a monotonically increasing number which 84 // changes every time something is removed from the texture backing store. atlasGeneration(GrMaskFormat format)85 uint64_t atlasGeneration(GrMaskFormat format) const { 86 return this->getAtlas(format)->atlasGeneration(); 87 } 88 89 // GrOnFlushCallbackObject overrides 90 preFlush(GrOnFlushResourceProvider * onFlushRP,const uint32_t *,int)91 void preFlush(GrOnFlushResourceProvider* onFlushRP, const uint32_t*, int) override { 92 for (int i = 0; i < kMaskFormatCount; ++i) { 93 if (fAtlases[i]) { 94 fAtlases[i]->instantiate(onFlushRP); 95 } 96 } 97 } 98 postFlush(GrDeferredUploadToken startTokenForNextFlush,const uint32_t * opsTaskIDs,int numOpsTaskIDs)99 void postFlush(GrDeferredUploadToken startTokenForNextFlush, 100 const uint32_t* opsTaskIDs, int numOpsTaskIDs) override { 101 for (int i = 0; i < kMaskFormatCount; ++i) { 102 if (fAtlases[i]) { 103 fAtlases[i]->compact(startTokenForNextFlush); 104 } 105 } 106 } 107 108 // The AtlasGlyph cache always survives freeGpuResources so we want it to remain in the active 109 // OnFlushCallbackObject list retainOnFreeGpuResources()110 bool retainOnFreeGpuResources() override { return true; } 111 112 /////////////////////////////////////////////////////////////////////////// 113 // Functions intended debug only 114 #ifdef SK_DEBUG 115 void dump(GrContext* context) const; 116 #endif 117 118 void setAtlasDimensionsToMinimum_ForTesting(); 119 void setMaxPages_TestingOnly(uint32_t maxPages); 120 121 private: 122 bool initAtlas(GrMaskFormat); 123 124 // There is a 1:1 mapping between GrMaskFormats and atlas indices MaskFormatToAtlasIndex(GrMaskFormat format)125 static int MaskFormatToAtlasIndex(GrMaskFormat format) { return static_cast<int>(format); } AtlasIndexToMaskFormat(int idx)126 static GrMaskFormat AtlasIndexToMaskFormat(int idx) { return static_cast<GrMaskFormat>(idx); } 127 getAtlas(GrMaskFormat format)128 GrDrawOpAtlas* getAtlas(GrMaskFormat format) const { 129 format = this->resolveMaskFormat(format); 130 int atlasIndex = MaskFormatToAtlasIndex(format); 131 SkASSERT(fAtlases[atlasIndex]); 132 return fAtlases[atlasIndex].get(); 133 } 134 135 GrDrawOpAtlas::AllowMultitexturing fAllowMultitexturing; 136 std::unique_ptr<GrDrawOpAtlas> fAtlases[kMaskFormatCount]; 137 static_assert(kMaskFormatCount == 3); 138 GrProxyProvider* fProxyProvider; 139 sk_sp<const GrCaps> fCaps; 140 GrStrikeCache* fGlyphCache; 141 GrDrawOpAtlasConfig fAtlasConfig; 142 143 typedef GrOnFlushCallbackObject INHERITED; 144 }; 145 146 #endif // GrAtlasManager_DEFINED 147