blob: 18ccfd096f6a9e214e874953bd2fc1586f0b4a74 [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
Robert Phillips5a66efb2018-03-07 15:13:18 -050018//////////////////////////////////////////////////////////////////////////////////////////////////
19/** The GrAtlasManager manages the lifetime of and access to GrDrawOpAtlases.
20 * It is only available at flush and only via the GrOpFlushState.
21 *
22 * This implies that all of the advanced atlasManager functionality (i.e.,
23 * adding glyphs to the atlas) are only available at flush time.
24 */
25class GrAtlasManager : public GrOnFlushCallbackObject {
Robert Phillipsc4039ea2018-03-01 11:36:45 -050026public:
Robert Phillips5a66efb2018-03-07 15:13:18 -050027 GrAtlasManager(GrProxyProvider*, GrGlyphCache*,
28 float maxTextureBytes, GrDrawOpAtlas::AllowMultitexturing);
29 ~GrAtlasManager() override;
Robert Phillipsc4039ea2018-03-01 11:36:45 -050030
31 // if getProxies returns nullptr, the client must not try to use other functions on the
32 // GrGlyphCache which use the atlas. This function *must* be called first, before other
Jim Van Verthcbeae032018-05-16 14:54:41 -040033 // functions which use the atlas. Note that we can have proxies available but none active
34 // (i.e., none instantiated).
35 const sk_sp<GrTextureProxy>* getProxies(GrMaskFormat format, unsigned int* numActiveProxies) {
Robert Phillipsc4039ea2018-03-01 11:36:45 -050036 if (this->initAtlas(format)) {
Jim Van Verthcbeae032018-05-16 14:54:41 -040037 *numActiveProxies = this->getAtlas(format)->numActivePages();
Robert Phillipsc4039ea2018-03-01 11:36:45 -050038 return this->getAtlas(format)->getProxies();
39 }
Jim Van Verthcbeae032018-05-16 14:54:41 -040040 *numActiveProxies = 0;
Robert Phillipsc4039ea2018-03-01 11:36:45 -050041 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 -050049 void freeAll();
50
51 bool hasGlyph(GrGlyph* glyph);
52
53 // To ensure the GrDrawOpAtlas does not evict the Glyph Mask from its texture backing store,
54 // the client must pass in the current op token along with the GrGlyph.
55 // A BulkUseTokenUpdater is used to manage bulk last use token updating in the Atlas.
56 // For convenience, this function will also set the use token for the current glyph if required
57 // NOTE: the bulk uploader is only valid if the subrun has a valid atlasGeneration
58 void addGlyphToBulkAndSetUseToken(GrDrawOpAtlas::BulkUseTokenUpdater*, GrGlyph*,
59 GrDeferredUploadToken);
60
61 void setUseTokenBulk(const GrDrawOpAtlas::BulkUseTokenUpdater& updater,
62 GrDeferredUploadToken token,
63 GrMaskFormat format) {
64 this->getAtlas(format)->setLastUseTokenBulk(updater, token);
65 }
66
67 // add to texture atlas that matches this format
Robert Phillipsd2e9f762018-03-07 11:54:37 -050068 GrDrawOpAtlas::ErrorCode addToAtlas(
69 GrResourceProvider*, GrGlyphCache*, GrTextStrike*,
Robert Phillipsc4039ea2018-03-01 11:36:45 -050070 GrDrawOpAtlas::AtlasID*, GrDeferredUploadTarget*, GrMaskFormat,
71 int width, int height, const void* image, SkIPoint16* loc);
72
73 // Some clients may wish to verify the integrity of the texture backing store of the
74 // GrDrawOpAtlas. The atlasGeneration returned below is a monotonically increasing number which
75 // changes every time something is removed from the texture backing store.
76 uint64_t atlasGeneration(GrMaskFormat format) const {
77 return this->getAtlas(format)->atlasGeneration();
78 }
79
80 // GrOnFlushCallbackObject overrides
81
82 void preFlush(GrOnFlushResourceProvider* onFlushResourceProvider, const uint32_t*, int,
83 SkTArray<sk_sp<GrRenderTargetContext>>*) override {
84 for (int i = 0; i < kMaskFormatCount; ++i) {
85 if (fAtlases[i]) {
86 fAtlases[i]->instantiate(onFlushResourceProvider);
87 }
88 }
89 }
90
91 void postFlush(GrDeferredUploadToken startTokenForNextFlush,
92 const uint32_t* opListIDs, int numOpListIDs) override {
93 for (int i = 0; i < kMaskFormatCount; ++i) {
94 if (fAtlases[i]) {
95 fAtlases[i]->compact(startTokenForNextFlush);
96 }
97 }
98 }
99
100 // The AtlasGlyph cache always survives freeGpuResources so we want it to remain in the active
101 // OnFlushCallbackObject list
102 bool retainOnFreeGpuResources() override { return true; }
103
104 ///////////////////////////////////////////////////////////////////////////
105 // Functions intended debug only
106#ifdef SK_DEBUG
107 void dump(GrContext* context) const;
108#endif
109
110 void setAtlasSizes_ForTesting(const GrDrawOpAtlasConfig configs[3]);
Robert Phillipsd2e9f762018-03-07 11:54:37 -0500111 void setMaxPages_TestingOnly(uint32_t maxPages);
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500112
113private:
Robert Phillips5a66efb2018-03-07 15:13:18 -0500114 bool initAtlas(GrMaskFormat);
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500115
Robert Phillips5a66efb2018-03-07 15:13:18 -0500116 // There is a 1:1 mapping between GrMaskFormats and atlas indices
117 static int MaskFormatToAtlasIndex(GrMaskFormat format) {
118 static const int sAtlasIndices[] = {
119 kA8_GrMaskFormat,
120 kA565_GrMaskFormat,
121 kARGB_GrMaskFormat,
122 };
123 static_assert(SK_ARRAY_COUNT(sAtlasIndices) == kMaskFormatCount, "array_size_mismatch");
124
125 SkASSERT(sAtlasIndices[format] < kMaskFormatCount);
126 return sAtlasIndices[format];
127 }
128
129 GrDrawOpAtlas* getAtlas(GrMaskFormat format) const {
130 int atlasIndex = MaskFormatToAtlasIndex(format);
131 SkASSERT(fAtlases[atlasIndex]);
132 return fAtlases[atlasIndex].get();
133 }
134
135 sk_sp<const GrCaps> fCaps;
136 GrDrawOpAtlas::AllowMultitexturing fAllowMultitexturing;
137 std::unique_ptr<GrDrawOpAtlas> fAtlases[kMaskFormatCount];
138 GrDrawOpAtlasConfig fAtlasConfigs[kMaskFormatCount];
139 SkScalar fGlyphSizeLimit;
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500140 GrProxyProvider* fProxyProvider;
141 GrGlyphCache* fGlyphCache;
142
Robert Phillips5a66efb2018-03-07 15:13:18 -0500143 typedef GrOnFlushCallbackObject INHERITED;
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500144};
145
146#endif // GrAtlasManager_DEFINED