Home | History | Annotate | Download | only in text
      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 "GrCaps.h"
     12 #include "GrDrawOpAtlas.h"
     13 #include "GrOnFlushResourceProvider.h"
     14 #include "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);
     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
     35     GrMaskFormat resolveMaskFormat(GrMaskFormat format) const {
     36         if (kA565_GrMaskFormat == format &&
     37             !fProxyProvider->caps()->isConfigTexturable(kRGB_565_GrPixelConfig)) {
     38             format = kARGB_GrMaskFormat;
     39         }
     40         return format;
     41     }
     42 
     43     // if getProxies returns nullptr, the client must not try to use other functions on the
     44     // GrStrikeCache which use the atlas.  This function *must* be called first, before other
     45     // functions which use the atlas. Note that we can have proxies available but none active
     46     // (i.e., none instantiated).
     47     const sk_sp<GrTextureProxy>* getProxies(GrMaskFormat format, unsigned int* numActiveProxies) {
     48         format = this->resolveMaskFormat(format);
     49         if (this->initAtlas(format)) {
     50             *numActiveProxies = this->getAtlas(format)->numActivePages();
     51             return this->getAtlas(format)->getProxies();
     52         }
     53         *numActiveProxies = 0;
     54         return nullptr;
     55     }
     56 
     57     void freeAll();
     58 
     59     bool hasGlyph(GrGlyph* glyph);
     60 
     61     // To ensure the GrDrawOpAtlas does not evict the Glyph Mask from its texture backing store,
     62     // the client must pass in the current op token along with the GrGlyph.
     63     // A BulkUseTokenUpdater is used to manage bulk last use token updating in the Atlas.
     64     // For convenience, this function will also set the use token for the current glyph if required
     65     // NOTE: the bulk uploader is only valid if the subrun has a valid atlasGeneration
     66     void addGlyphToBulkAndSetUseToken(GrDrawOpAtlas::BulkUseTokenUpdater*, GrGlyph*,
     67                                       GrDeferredUploadToken);
     68 
     69     void setUseTokenBulk(const GrDrawOpAtlas::BulkUseTokenUpdater& updater,
     70                          GrDeferredUploadToken token,
     71                          GrMaskFormat format) {
     72         this->getAtlas(format)->setLastUseTokenBulk(updater, token);
     73     }
     74 
     75     // add to texture atlas that matches this format
     76     GrDrawOpAtlas::ErrorCode addToAtlas(
     77                     GrResourceProvider*, GrStrikeCache*, GrTextStrike*,
     78                     GrDrawOpAtlas::AtlasID*, GrDeferredUploadTarget*, GrMaskFormat,
     79                     int width, int height, const void* image, SkIPoint16* loc);
     80 
     81     // Some clients may wish to verify the integrity of the texture backing store of the
     82     // GrDrawOpAtlas. The atlasGeneration returned below is a monotonically increasing number which
     83     // changes every time something is removed from the texture backing store.
     84     uint64_t atlasGeneration(GrMaskFormat format) const {
     85         return this->getAtlas(format)->atlasGeneration();
     86     }
     87 
     88     // GrOnFlushCallbackObject overrides
     89 
     90     void preFlush(GrOnFlushResourceProvider* onFlushResourceProvider, const uint32_t*, int,
     91                   SkTArray<sk_sp<GrRenderTargetContext>>*) override {
     92         for (int i = 0; i < kMaskFormatCount; ++i) {
     93             if (fAtlases[i]) {
     94                 fAtlases[i]->instantiate(onFlushResourceProvider);
     95             }
     96         }
     97     }
     98 
     99     void postFlush(GrDeferredUploadToken startTokenForNextFlush,
    100                    const uint32_t* opListIDs, int numOpListIDs) 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
    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 setAtlasSizesToMinimum_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
    125     static int MaskFormatToAtlasIndex(GrMaskFormat format) {
    126         static const int sAtlasIndices[] = {
    127             kA8_GrMaskFormat,
    128             kA565_GrMaskFormat,
    129             kARGB_GrMaskFormat,
    130         };
    131         static_assert(SK_ARRAY_COUNT(sAtlasIndices) == kMaskFormatCount, "array_size_mismatch");
    132 
    133         SkASSERT(sAtlasIndices[format] < kMaskFormatCount);
    134         return sAtlasIndices[format];
    135     }
    136 
    137     GrDrawOpAtlas* getAtlas(GrMaskFormat format) const {
    138         format = this->resolveMaskFormat(format);
    139         int atlasIndex = MaskFormatToAtlasIndex(format);
    140         SkASSERT(fAtlases[atlasIndex]);
    141         return fAtlases[atlasIndex].get();
    142     }
    143 
    144     GrDrawOpAtlas::AllowMultitexturing fAllowMultitexturing;
    145     std::unique_ptr<GrDrawOpAtlas> fAtlases[kMaskFormatCount];
    146     GrProxyProvider* fProxyProvider;
    147     sk_sp<const GrCaps> fCaps;
    148     GrStrikeCache* fGlyphCache;
    149     GrDrawOpAtlasConfig fAtlasConfig;
    150 
    151     typedef GrOnFlushCallbackObject INHERITED;
    152 };
    153 
    154 #endif // GrAtlasManager_DEFINED
    155