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