blob: 4b1c6674e00c1faaff5a049908eab9c6e1a0d9a1 [file] [log] [blame]
Robert Phillipsc4039ea2018-03-01 11:36:45 -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;
Robert Phillipscaf1ebb2018-03-01 14:28:44 -050015class GrTextStrike;
Robert Phillipsc4039ea2018-03-01 11:36:45 -050016struct 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
Robert Phillipsaf4adef2018-03-07 11:59:37 -050046 static void ComputeAtlasLimits(const GrCaps* caps, float maxTextureBytes,
47 int* maxDim, int* minDim, int* maxPlot, int* minPlot);
48
Robert Phillipsc4039ea2018-03-01 11:36:45 -050049protected:
50 // There is a 1:1 mapping between GrMaskFormats and atlas indices
51 static int MaskFormatToAtlasIndex(GrMaskFormat format) {
52 static const int sAtlasIndices[] = {
53 kA8_GrMaskFormat,
54 kA565_GrMaskFormat,
55 kARGB_GrMaskFormat,
56 };
57 static_assert(SK_ARRAY_COUNT(sAtlasIndices) == kMaskFormatCount, "array_size_mismatch");
58
59 SkASSERT(sAtlasIndices[format] < kMaskFormatCount);
60 return sAtlasIndices[format];
61 }
62
63 GrDrawOpAtlas* getAtlas(GrMaskFormat format) const {
64 int atlasIndex = MaskFormatToAtlasIndex(format);
65 SkASSERT(fAtlases[atlasIndex]);
66 return fAtlases[atlasIndex].get();
67 }
68
69 sk_sp<const GrCaps> fCaps;
70 GrDrawOpAtlas::AllowMultitexturing fAllowMultitexturing;
71 std::unique_ptr<GrDrawOpAtlas> fAtlases[kMaskFormatCount];
72 GrDrawOpAtlasConfig fAtlasConfigs[kMaskFormatCount];
73 SkScalar fGlyphSizeLimit;
74
75private:
76 virtual bool initAtlas(GrMaskFormat) = 0;
77
78 typedef GrOnFlushCallbackObject INHERITED;
79};
80
81//////////////////////////////////////////////////////////////////////////////////////////////////
82class GrAtlasManager : public GrRestrictedAtlasManager {
83public:
84 GrAtlasManager(GrProxyProvider*, GrGlyphCache*,
85 float maxTextureBytes, GrDrawOpAtlas::AllowMultitexturing);
86
87 void freeAll();
88
89 bool hasGlyph(GrGlyph* glyph);
90
91 // To ensure the GrDrawOpAtlas does not evict the Glyph Mask from its texture backing store,
92 // the client must pass in the current op token along with the GrGlyph.
93 // A BulkUseTokenUpdater is used to manage bulk last use token updating in the Atlas.
94 // For convenience, this function will also set the use token for the current glyph if required
95 // NOTE: the bulk uploader is only valid if the subrun has a valid atlasGeneration
96 void addGlyphToBulkAndSetUseToken(GrDrawOpAtlas::BulkUseTokenUpdater*, GrGlyph*,
97 GrDeferredUploadToken);
98
99 void setUseTokenBulk(const GrDrawOpAtlas::BulkUseTokenUpdater& updater,
100 GrDeferredUploadToken token,
101 GrMaskFormat format) {
102 this->getAtlas(format)->setLastUseTokenBulk(updater, token);
103 }
104
105 // add to texture atlas that matches this format
Robert Phillipsd2e9f762018-03-07 11:54:37 -0500106 GrDrawOpAtlas::ErrorCode addToAtlas(
107 GrResourceProvider*, GrGlyphCache*, GrTextStrike*,
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500108 GrDrawOpAtlas::AtlasID*, GrDeferredUploadTarget*, GrMaskFormat,
109 int width, int height, const void* image, SkIPoint16* loc);
110
111 // Some clients may wish to verify the integrity of the texture backing store of the
112 // GrDrawOpAtlas. The atlasGeneration returned below is a monotonically increasing number which
113 // changes every time something is removed from the texture backing store.
114 uint64_t atlasGeneration(GrMaskFormat format) const {
115 return this->getAtlas(format)->atlasGeneration();
116 }
117
118 // GrOnFlushCallbackObject overrides
119
120 void preFlush(GrOnFlushResourceProvider* onFlushResourceProvider, const uint32_t*, int,
121 SkTArray<sk_sp<GrRenderTargetContext>>*) override {
122 for (int i = 0; i < kMaskFormatCount; ++i) {
123 if (fAtlases[i]) {
124 fAtlases[i]->instantiate(onFlushResourceProvider);
125 }
126 }
127 }
128
129 void postFlush(GrDeferredUploadToken startTokenForNextFlush,
130 const uint32_t* opListIDs, int numOpListIDs) override {
131 for (int i = 0; i < kMaskFormatCount; ++i) {
132 if (fAtlases[i]) {
133 fAtlases[i]->compact(startTokenForNextFlush);
134 }
135 }
136 }
137
138 // The AtlasGlyph cache always survives freeGpuResources so we want it to remain in the active
139 // OnFlushCallbackObject list
140 bool retainOnFreeGpuResources() override { return true; }
141
142 ///////////////////////////////////////////////////////////////////////////
143 // Functions intended debug only
144#ifdef SK_DEBUG
145 void dump(GrContext* context) const;
146#endif
147
148 void setAtlasSizes_ForTesting(const GrDrawOpAtlasConfig configs[3]);
Robert Phillipsd2e9f762018-03-07 11:54:37 -0500149 void setMaxPages_TestingOnly(uint32_t maxPages);
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500150
151private:
152 bool initAtlas(GrMaskFormat) override;
153
154 GrProxyProvider* fProxyProvider;
155 GrGlyphCache* fGlyphCache;
156
157 typedef GrRestrictedAtlasManager INHERITED;
158};
159
160#endif // GrAtlasManager_DEFINED