blob: bdd8027cdd8368dcf03cce00f9e59d0bc8874bda [file] [log] [blame]
Robert Phillips46a324a2020-08-10 13:08:12 -04001/*
2 * Copyright 2020 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
Robert Phillipsde60d7a2021-09-13 17:17:45 -04008#include "src/gpu/ops/SmallPathAtlasMgr.h"
Robert Phillips46a324a2020-08-10 13:08:12 -04009
10#include "src/gpu/geometry/GrStyledShape.h"
Robert Phillipsde60d7a2021-09-13 17:17:45 -040011#include "src/gpu/ops/SmallPathShapeData.h"
Robert Phillips46a324a2020-08-10 13:08:12 -040012
13#ifdef DF_PATH_TRACKING
14static int g_NumCachedShapes = 0;
15static int g_NumFreedShapes = 0;
16#endif
17
Robert Phillipsde60d7a2021-09-13 17:17:45 -040018namespace skgpu::v1 {
Robert Phillips46a324a2020-08-10 13:08:12 -040019
Robert Phillipsde60d7a2021-09-13 17:17:45 -040020SmallPathAtlasMgr::SmallPathAtlasMgr() {}
21
22SmallPathAtlasMgr::~SmallPathAtlasMgr() {
Robert Phillipsa4bb0642020-08-11 09:55:17 -040023 this->reset();
24}
25
Robert Phillipsde60d7a2021-09-13 17:17:45 -040026void SmallPathAtlasMgr::reset() {
Robert Phillips46a324a2020-08-10 13:08:12 -040027 ShapeDataList::Iter iter;
28 iter.init(fShapeList, ShapeDataList::Iter::kHead_IterStart);
Robert Phillipsde60d7a2021-09-13 17:17:45 -040029 SmallPathShapeData* shapeData;
Robert Phillips46a324a2020-08-10 13:08:12 -040030 while ((shapeData = iter.get())) {
31 iter.next();
32 delete shapeData;
33 }
34
Robert Phillips079455c2020-08-11 15:18:46 -040035 fShapeList.reset();
Robert Phillipsa4bb0642020-08-11 09:55:17 -040036 fShapeCache.reset();
37
Robert Phillips46a324a2020-08-10 13:08:12 -040038#ifdef DF_PATH_TRACKING
39 SkDebugf("Cached shapes: %d, freed shapes: %d\n", g_NumCachedShapes, g_NumFreedShapes);
40#endif
Robert Phillipsa4bb0642020-08-11 09:55:17 -040041
42 fAtlas = nullptr;
Robert Phillips46a324a2020-08-10 13:08:12 -040043}
44
Robert Phillipsde60d7a2021-09-13 17:17:45 -040045bool SmallPathAtlasMgr::initAtlas(GrProxyProvider* proxyProvider, const GrCaps* caps) {
Robert Phillips46a324a2020-08-10 13:08:12 -040046 if (fAtlas) {
47 return true;
48 }
49
50 static constexpr size_t kMaxAtlasTextureBytes = 2048 * 2048;
51 static constexpr size_t kPlotWidth = 512;
52 static constexpr size_t kPlotHeight = 256;
53
54 const GrBackendFormat format = caps->getDefaultBackendFormat(GrColorType::kAlpha_8,
Robert Phillips109ff202020-08-10 16:39:31 -040055 GrRenderable::kNo);
Robert Phillips46a324a2020-08-10 13:08:12 -040056
57 GrDrawOpAtlasConfig atlasConfig(caps->maxTextureSize(), kMaxAtlasTextureBytes);
58 SkISize size = atlasConfig.atlasDimensions(kA8_GrMaskFormat);
59 fAtlas = GrDrawOpAtlas::Make(proxyProvider, format,
60 GrColorType::kAlpha_8, size.width(), size.height(),
61 kPlotWidth, kPlotHeight, this,
62 GrDrawOpAtlas::AllowMultitexturing::kYes, this);
63
64 return SkToBool(fAtlas);
65}
66
Robert Phillipsde60d7a2021-09-13 17:17:45 -040067void SmallPathAtlasMgr::deleteCacheEntry(SmallPathShapeData* shapeData) {
Robert Phillips46a324a2020-08-10 13:08:12 -040068 fShapeCache.remove(shapeData->fKey);
69 fShapeList.remove(shapeData);
70 delete shapeData;
71}
72
Robert Phillipsde60d7a2021-09-13 17:17:45 -040073SmallPathShapeData* SmallPathAtlasMgr::findOrCreate(const SmallPathShapeDataKey& key) {
Robert Phillips46a324a2020-08-10 13:08:12 -040074 auto shapeData = fShapeCache.find(key);
75 if (!shapeData) {
Robert Phillips109ff202020-08-10 16:39:31 -040076 // TODO: move the key into the ctor
Robert Phillipsde60d7a2021-09-13 17:17:45 -040077 shapeData = new SmallPathShapeData(key);
Robert Phillips46a324a2020-08-10 13:08:12 -040078 fShapeCache.add(shapeData);
79 fShapeList.addToTail(shapeData);
80#ifdef DF_PATH_TRACKING
81 ++g_NumCachedShapes;
82#endif
83 } else if (!fAtlas->hasID(shapeData->fAtlasLocator.plotLocator())) {
84 shapeData->fAtlasLocator.invalidatePlotLocator();
85 }
86
87 return shapeData;
88}
89
Robert Phillipsde60d7a2021-09-13 17:17:45 -040090SmallPathShapeData* SmallPathAtlasMgr::findOrCreate(const GrStyledShape& shape,
91 int desiredDimension) {
92 SmallPathShapeDataKey key(shape, desiredDimension);
Robert Phillips109ff202020-08-10 16:39:31 -040093
94 // TODO: move the key into 'findOrCreate'
95 return this->findOrCreate(key);
96}
97
Robert Phillipsde60d7a2021-09-13 17:17:45 -040098SmallPathShapeData* SmallPathAtlasMgr::findOrCreate(const GrStyledShape& shape,
99 const SkMatrix& ctm) {
100 SmallPathShapeDataKey key(shape, ctm);
Robert Phillips109ff202020-08-10 16:39:31 -0400101
102 // TODO: move the key into 'findOrCreate'
103 return this->findOrCreate(key);
104}
105
Robert Phillipsde60d7a2021-09-13 17:17:45 -0400106GrDrawOpAtlas::ErrorCode SmallPathAtlasMgr::addToAtlas(GrResourceProvider* resourceProvider,
107 GrDeferredUploadTarget* target,
108 int width, int height, const void* image,
109 GrDrawOpAtlas::AtlasLocator* locator) {
Robert Phillips6704bc82020-08-14 12:45:07 -0400110 return fAtlas->addToAtlas(resourceProvider, target, width, height, image, locator);
111}
112
Robert Phillipsde60d7a2021-09-13 17:17:45 -0400113void SmallPathAtlasMgr::setUseToken(SmallPathShapeData* shapeData,
114 GrDeferredUploadToken token) {
Robert Phillips46a324a2020-08-10 13:08:12 -0400115 fAtlas->setLastUseToken(shapeData->fAtlasLocator, token);
116}
117
118// Callback to clear out internal path cache when eviction occurs
Robert Phillipsde60d7a2021-09-13 17:17:45 -0400119void SmallPathAtlasMgr::evict(GrDrawOpAtlas::PlotLocator plotLocator) {
Robert Phillips46a324a2020-08-10 13:08:12 -0400120 // remove any paths that use this plot
121 ShapeDataList::Iter iter;
122 iter.init(fShapeList, ShapeDataList::Iter::kHead_IterStart);
Robert Phillipsde60d7a2021-09-13 17:17:45 -0400123 SmallPathShapeData* shapeData;
Robert Phillips46a324a2020-08-10 13:08:12 -0400124 while ((shapeData = iter.get())) {
125 iter.next();
126 if (plotLocator == shapeData->fAtlasLocator.plotLocator()) {
127 fShapeCache.remove(shapeData->fKey);
128 fShapeList.remove(shapeData);
129 delete shapeData;
130#ifdef DF_PATH_TRACKING
131 ++g_NumFreedShapes;
132#endif
133 }
134 }
135}
Robert Phillipsde60d7a2021-09-13 17:17:45 -0400136
137} // namespace skgpu::v1