blob: 7fbb232fe230ed95376f2126c19e1a5b3ccce030 [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
8#include "src/gpu/ops/GrSmallPathAtlasMgr.h"
9
10#include "src/gpu/geometry/GrStyledShape.h"
11#include "src/gpu/ops/GrSmallPathShapeData.h"
12
13#ifdef DF_PATH_TRACKING
14static int g_NumCachedShapes = 0;
15static int g_NumFreedShapes = 0;
16#endif
17
18GrSmallPathAtlasMgr::GrSmallPathAtlasMgr() {}
19
20GrSmallPathAtlasMgr::~GrSmallPathAtlasMgr() {
Robert Phillipsa4bb0642020-08-11 09:55:17 -040021 this->reset();
22}
23
24void GrSmallPathAtlasMgr::reset() {
Robert Phillips46a324a2020-08-10 13:08:12 -040025 ShapeDataList::Iter iter;
26 iter.init(fShapeList, ShapeDataList::Iter::kHead_IterStart);
27 GrSmallPathShapeData* shapeData;
28 while ((shapeData = iter.get())) {
29 iter.next();
30 delete shapeData;
31 }
32
Robert Phillipsa4bb0642020-08-11 09:55:17 -040033 fShapeCache.reset();
34
Robert Phillips46a324a2020-08-10 13:08:12 -040035#ifdef DF_PATH_TRACKING
36 SkDebugf("Cached shapes: %d, freed shapes: %d\n", g_NumCachedShapes, g_NumFreedShapes);
37#endif
Robert Phillipsa4bb0642020-08-11 09:55:17 -040038
39 fAtlas = nullptr;
Robert Phillips46a324a2020-08-10 13:08:12 -040040}
41
42bool GrSmallPathAtlasMgr::initAtlas(GrProxyProvider* proxyProvider, const GrCaps* caps) {
43 if (fAtlas) {
44 return true;
45 }
46
47 static constexpr size_t kMaxAtlasTextureBytes = 2048 * 2048;
48 static constexpr size_t kPlotWidth = 512;
49 static constexpr size_t kPlotHeight = 256;
50
51 const GrBackendFormat format = caps->getDefaultBackendFormat(GrColorType::kAlpha_8,
Robert Phillips109ff202020-08-10 16:39:31 -040052 GrRenderable::kNo);
Robert Phillips46a324a2020-08-10 13:08:12 -040053
54 GrDrawOpAtlasConfig atlasConfig(caps->maxTextureSize(), kMaxAtlasTextureBytes);
55 SkISize size = atlasConfig.atlasDimensions(kA8_GrMaskFormat);
56 fAtlas = GrDrawOpAtlas::Make(proxyProvider, format,
57 GrColorType::kAlpha_8, size.width(), size.height(),
58 kPlotWidth, kPlotHeight, this,
59 GrDrawOpAtlas::AllowMultitexturing::kYes, this);
60
61 return SkToBool(fAtlas);
62}
63
64void GrSmallPathAtlasMgr::deleteCacheEntry(GrSmallPathShapeData* shapeData) {
65 fShapeCache.remove(shapeData->fKey);
66 fShapeList.remove(shapeData);
67 delete shapeData;
68}
69
70GrSmallPathShapeData* GrSmallPathAtlasMgr::findOrCreate(const GrSmallPathShapeDataKey& key) {
71 auto shapeData = fShapeCache.find(key);
72 if (!shapeData) {
Robert Phillips109ff202020-08-10 16:39:31 -040073 // TODO: move the key into the ctor
Robert Phillips46a324a2020-08-10 13:08:12 -040074 shapeData = new GrSmallPathShapeData(key);
75 fShapeCache.add(shapeData);
76 fShapeList.addToTail(shapeData);
77#ifdef DF_PATH_TRACKING
78 ++g_NumCachedShapes;
79#endif
80 } else if (!fAtlas->hasID(shapeData->fAtlasLocator.plotLocator())) {
81 shapeData->fAtlasLocator.invalidatePlotLocator();
82 }
83
84 return shapeData;
85}
86
Robert Phillips109ff202020-08-10 16:39:31 -040087GrSmallPathShapeData* GrSmallPathAtlasMgr::findOrCreate(const GrStyledShape& shape,
88 int desiredDimension) {
89 GrSmallPathShapeDataKey key(shape, desiredDimension);
90
91 // TODO: move the key into 'findOrCreate'
92 return this->findOrCreate(key);
93}
94
95GrSmallPathShapeData* GrSmallPathAtlasMgr::findOrCreate(const GrStyledShape& shape,
96 const SkMatrix& ctm) {
97 GrSmallPathShapeDataKey key(shape, ctm);
98
99 // TODO: move the key into 'findOrCreate'
100 return this->findOrCreate(key);
101}
102
Robert Phillips46a324a2020-08-10 13:08:12 -0400103void GrSmallPathAtlasMgr::setUseToken(GrSmallPathShapeData* shapeData,
104 GrDeferredUploadToken token) {
105 fAtlas->setLastUseToken(shapeData->fAtlasLocator, token);
106}
107
108// Callback to clear out internal path cache when eviction occurs
109void GrSmallPathAtlasMgr::evict(GrDrawOpAtlas::PlotLocator plotLocator) {
110 // remove any paths that use this plot
111 ShapeDataList::Iter iter;
112 iter.init(fShapeList, ShapeDataList::Iter::kHead_IterStart);
113 GrSmallPathShapeData* shapeData;
114 while ((shapeData = iter.get())) {
115 iter.next();
116 if (plotLocator == shapeData->fAtlasLocator.plotLocator()) {
117 fShapeCache.remove(shapeData->fKey);
118 fShapeList.remove(shapeData);
119 delete shapeData;
120#ifdef DF_PATH_TRACKING
121 ++g_NumFreedShapes;
122#endif
123 }
124 }
125}