blob: 4629cb173b4149addd717ef0b53f308e0c745dae [file] [log] [blame]
Robert Phillipsacf17902018-02-27 16:43:18 -05001/*
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 "GrDrawOpAtlas.h"
12#include "GrOnFlushResourceProvider.h"
13
14class GrAtlasGlypCache;
15class GrAtlasTextStrike;
16struct GrGlyph;
17
18 /** The GrAtlasManager classes manage the lifetime of and access to GrDrawOpAtlases.
19 * The restricted version is available at op creation time and only allows basic access
20 * to the proxies (so the created ops can reference them). The full GrAtlasManager class
21 * is only available at flush time and only via the GrOpFlushState.
22 *
23 * This organization implies that all of the advanced atlasManager functionality (i.e.,
24 * adding glyphs to the atlas) are only available at flush time.
25 */
26class GrRestrictedAtlasManager : public GrOnFlushCallbackObject {
27public:
28 GrRestrictedAtlasManager(sk_sp<const GrCaps>, float maxTextureBytes,
29 GrDrawOpAtlas::AllowMultitexturing);
30 ~GrRestrictedAtlasManager() override;
31
32 // if getProxies returns nullptr, the client must not try to use other functions on the
33 // GrGlyphCache which use the atlas. This function *must* be called first, before other
34 // functions which use the atlas.
35 const sk_sp<GrTextureProxy>* getProxies(GrMaskFormat format, unsigned int* numProxies) {
36 if (this->initAtlas(format)) {
37 *numProxies = this->getAtlas(format)->numActivePages();
38 return this->getAtlas(format)->getProxies();
39 }
40 *numProxies = 0;
41 return nullptr;
42 }
43
44 SkScalar getGlyphSizeLimit() const { return fGlyphSizeLimit; }
45
46protected:
47 // There is a 1:1 mapping between GrMaskFormats and atlas indices
48 static int MaskFormatToAtlasIndex(GrMaskFormat format) {
49 static const int sAtlasIndices[] = {
50 kA8_GrMaskFormat,
51 kA565_GrMaskFormat,
52 kARGB_GrMaskFormat,
53 };
54 static_assert(SK_ARRAY_COUNT(sAtlasIndices) == kMaskFormatCount, "array_size_mismatch");
55
56 SkASSERT(sAtlasIndices[format] < kMaskFormatCount);
57 return sAtlasIndices[format];
58 }
59
60 GrDrawOpAtlas* getAtlas(GrMaskFormat format) const {
61 int atlasIndex = MaskFormatToAtlasIndex(format);
62 SkASSERT(fAtlases[atlasIndex]);
63 return fAtlases[atlasIndex].get();
64 }
65
66 sk_sp<const GrCaps> fCaps;
67 GrDrawOpAtlas::AllowMultitexturing fAllowMultitexturing;
68 std::unique_ptr<GrDrawOpAtlas> fAtlases[kMaskFormatCount];
69 GrDrawOpAtlasConfig fAtlasConfigs[kMaskFormatCount];
70 SkScalar fGlyphSizeLimit;
71
72private:
73 virtual bool initAtlas(GrMaskFormat) = 0;
74
75 typedef GrOnFlushCallbackObject INHERITED;
76};
77
78//////////////////////////////////////////////////////////////////////////////////////////////////
79class GrAtlasManager : public GrRestrictedAtlasManager {
80public:
81 GrAtlasManager(GrProxyProvider*, GrGlyphCache*,
82 float maxTextureBytes, GrDrawOpAtlas::AllowMultitexturing);
83
84 void freeAll();
85
86 bool hasGlyph(GrGlyph* glyph);
87
88 // To ensure the GrDrawOpAtlas does not evict the Glyph Mask from its texture backing store,
89 // the client must pass in the current op token along with the GrGlyph.
90 // A BulkUseTokenUpdater is used to manage bulk last use token updating in the Atlas.
91 // For convenience, this function will also set the use token for the current glyph if required
92 // NOTE: the bulk uploader is only valid if the subrun has a valid atlasGeneration
93 void addGlyphToBulkAndSetUseToken(GrDrawOpAtlas::BulkUseTokenUpdater*, GrGlyph*,
94 GrDeferredUploadToken);
95
96 void setUseTokenBulk(const GrDrawOpAtlas::BulkUseTokenUpdater& updater,
97 GrDeferredUploadToken token,
98 GrMaskFormat format) {
99 this->getAtlas(format)->setLastUseTokenBulk(updater, token);
100 }
101
102 // add to texture atlas that matches this format
103 bool addToAtlas(GrResourceProvider*, GrGlyphCache*, GrAtlasTextStrike*,
104 GrDrawOpAtlas::AtlasID*, GrDeferredUploadTarget*, GrMaskFormat,
105 int width, int height, const void* image, SkIPoint16* loc);
106
107 // Some clients may wish to verify the integrity of the texture backing store of the
108 // GrDrawOpAtlas. The atlasGeneration returned below is a monotonically increasing number which
109 // changes every time something is removed from the texture backing store.
110 uint64_t atlasGeneration(GrMaskFormat format) const {
111 return this->getAtlas(format)->atlasGeneration();
112 }
113
114 // GrOnFlushCallbackObject overrides
115
116 void preFlush(GrOnFlushResourceProvider* onFlushResourceProvider, const uint32_t*, int,
117 SkTArray<sk_sp<GrRenderTargetContext>>*) override {
118 for (int i = 0; i < kMaskFormatCount; ++i) {
119 if (fAtlases[i]) {
120 fAtlases[i]->instantiate(onFlushResourceProvider);
121 }
122 }
123 }
124
125 void postFlush(GrDeferredUploadToken startTokenForNextFlush,
126 const uint32_t* opListIDs, int numOpListIDs) override {
127 for (int i = 0; i < kMaskFormatCount; ++i) {
128 if (fAtlases[i]) {
129 fAtlases[i]->compact(startTokenForNextFlush);
130 }
131 }
132 }
133
134 // The AtlasGlyph cache always survives freeGpuResources so we want it to remain in the active
135 // OnFlushCallbackObject list
136 bool retainOnFreeGpuResources() override { return true; }
137
138 ///////////////////////////////////////////////////////////////////////////
139 // Functions intended debug only
140#ifdef SK_DEBUG
141 void dump(GrContext* context) const;
142#endif
143
144 void setAtlasSizes_ForTesting(const GrDrawOpAtlasConfig configs[3]);
145
146private:
147 bool initAtlas(GrMaskFormat) override;
148
149 GrProxyProvider* fProxyProvider;
150 GrGlyphCache* fGlyphCache;
151
152 typedef GrRestrictedAtlasManager INHERITED;
153};
154
155#endif // GrAtlasManager_DEFINED