blob: 1799d8d6b1612c1e31f08bb1ac8dcb69aa3b5b0a [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "src/gpu/GrCaps.h"
12#include "src/gpu/GrDrawOpAtlas.h"
13#include "src/gpu/GrOnFlushResourceProvider.h"
14#include "src/gpu/GrProxyProvider.h"
Robert Phillipsc4039ea2018-03-01 11:36:45 -050015
Robert Phillipsc4039ea2018-03-01 11:36:45 -050016struct GrGlyph;
Herb Derby081e6f32019-01-16 13:46:02 -050017class GrTextStrike;
Robert Phillipsc4039ea2018-03-01 11:36:45 -050018
Robert Phillips5a66efb2018-03-07 15:13:18 -050019//////////////////////////////////////////////////////////////////////////////////////////////////
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 */
26class GrAtlasManager : public GrOnFlushCallbackObject {
Robert Phillipsc4039ea2018-03-01 11:36:45 -050027public:
Herb Derby081e6f32019-01-16 13:46:02 -050028 GrAtlasManager(GrProxyProvider*, GrStrikeCache*,
Herb Derby3c4d5332018-09-07 15:27:57 -040029 size_t maxTextureBytes, GrDrawOpAtlas::AllowMultitexturing);
Robert Phillips5a66efb2018-03-07 15:13:18 -050030 ~GrAtlasManager() override;
Robert Phillipsc4039ea2018-03-01 11:36:45 -050031
Timothy Liang91e260f2018-06-15 13:28:35 -040032 // 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
Herb Derby081e6f32019-01-16 13:46:02 -050034 // GrStrikeCache.cpp
Timothy Liang91e260f2018-06-15 13:28:35 -040035 GrMaskFormat resolveMaskFormat(GrMaskFormat format) const {
36 if (kA565_GrMaskFormat == format &&
Greg Daniel7bfc9132019-08-14 14:23:53 -040037 !fProxyProvider->caps()->getDefaultBackendFormat(GrColorType::kBGR_565,
38 GrRenderable::kNo).isValid()) {
Timothy Liang91e260f2018-06-15 13:28:35 -040039 format = kARGB_GrMaskFormat;
40 }
41 return format;
42 }
43
Robert Phillipsc4039ea2018-03-01 11:36:45 -050044 // if getProxies returns nullptr, the client must not try to use other functions on the
Herb Derby081e6f32019-01-16 13:46:02 -050045 // GrStrikeCache which use the atlas. This function *must* be called first, before other
Jim Van Verthcbeae032018-05-16 14:54:41 -040046 // functions which use the atlas. Note that we can have proxies available but none active
47 // (i.e., none instantiated).
48 const sk_sp<GrTextureProxy>* getProxies(GrMaskFormat format, unsigned int* numActiveProxies) {
Timothy Liang91e260f2018-06-15 13:28:35 -040049 format = this->resolveMaskFormat(format);
Robert Phillipsc4039ea2018-03-01 11:36:45 -050050 if (this->initAtlas(format)) {
Jim Van Verthcbeae032018-05-16 14:54:41 -040051 *numActiveProxies = this->getAtlas(format)->numActivePages();
Robert Phillipsc4039ea2018-03-01 11:36:45 -050052 return this->getAtlas(format)->getProxies();
53 }
Jim Van Verthcbeae032018-05-16 14:54:41 -040054 *numActiveProxies = 0;
Robert Phillipsc4039ea2018-03-01 11:36:45 -050055 return nullptr;
56 }
57
Robert Phillipsc4039ea2018-03-01 11:36:45 -050058 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
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
Robert Phillipsd2e9f762018-03-07 11:54:37 -050077 GrDrawOpAtlas::ErrorCode addToAtlas(
Herb Derby081e6f32019-01-16 13:46:02 -050078 GrResourceProvider*, GrStrikeCache*, GrTextStrike*,
Robert Phillipsc4039ea2018-03-01 11:36:45 -050079 GrDrawOpAtlas::AtlasID*, 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.
85 uint64_t atlasGeneration(GrMaskFormat format) const {
86 return this->getAtlas(format)->atlasGeneration();
87 }
88
89 // GrOnFlushCallbackObject overrides
90
Chris Daltonc4b47352019-08-23 10:10:36 -060091 void preFlush(GrOnFlushResourceProvider* onFlushRP, const uint32_t*, int) override {
Robert Phillipsc4039ea2018-03-01 11:36:45 -050092 for (int i = 0; i < kMaskFormatCount; ++i) {
93 if (fAtlases[i]) {
Chris Daltonc4b47352019-08-23 10:10:36 -060094 fAtlases[i]->instantiate(onFlushRP);
Robert Phillipsc4039ea2018-03-01 11:36:45 -050095 }
96 }
97 }
98
99 void postFlush(GrDeferredUploadToken startTokenForNextFlush,
Greg Danielf41b2bd2019-08-22 16:19:24 -0400100 const uint32_t* opsTaskIDs, int numOpsTaskIDs) override {
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500101 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
Herb Derby3c4d5332018-09-07 15:27:57 -0400118 void setAtlasSizesToMinimum_ForTesting();
Robert Phillipsd2e9f762018-03-07 11:54:37 -0500119 void setMaxPages_TestingOnly(uint32_t maxPages);
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500120
121private:
Robert Phillips5a66efb2018-03-07 15:13:18 -0500122 bool initAtlas(GrMaskFormat);
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500123
Robert Phillips5a66efb2018-03-07 15:13:18 -0500124 // There is a 1:1 mapping between GrMaskFormats and atlas indices
Brian Salomond6287472019-06-24 15:50:07 -0400125 static int MaskFormatToAtlasIndex(GrMaskFormat format) { return static_cast<int>(format); }
126 static GrMaskFormat AtlasIndexToMaskFormat(int idx) { return static_cast<GrMaskFormat>(idx); }
Robert Phillips5a66efb2018-03-07 15:13:18 -0500127
128 GrDrawOpAtlas* getAtlas(GrMaskFormat format) const {
Timothy Liang91e260f2018-06-15 13:28:35 -0400129 format = this->resolveMaskFormat(format);
Robert Phillips5a66efb2018-03-07 15:13:18 -0500130 int atlasIndex = MaskFormatToAtlasIndex(format);
131 SkASSERT(fAtlases[atlasIndex]);
132 return fAtlases[atlasIndex].get();
133 }
134
Robert Phillips5a66efb2018-03-07 15:13:18 -0500135 GrDrawOpAtlas::AllowMultitexturing fAllowMultitexturing;
136 std::unique_ptr<GrDrawOpAtlas> fAtlases[kMaskFormatCount];
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500137 GrProxyProvider* fProxyProvider;
Herb Derby3c4d5332018-09-07 15:27:57 -0400138 sk_sp<const GrCaps> fCaps;
Herb Derby081e6f32019-01-16 13:46:02 -0500139 GrStrikeCache* fGlyphCache;
Jim Van Verthf6206f92018-12-14 08:22:24 -0500140 GrDrawOpAtlasConfig fAtlasConfig;
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500141
Robert Phillips5a66efb2018-03-07 15:13:18 -0500142 typedef GrOnFlushCallbackObject INHERITED;
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500143};
144
145#endif // GrAtlasManager_DEFINED