• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/ganesh/ops/SmallPathAtlasMgr.h"
9 
10 #include "src/gpu/ganesh/GrCaps.h"
11 #include "src/gpu/ganesh/geometry/GrStyledShape.h"
12 #include "src/gpu/ganesh/ops/SmallPathShapeData.h"
13 
14 #if !defined(SK_ENABLE_OPTIMIZE_SIZE)
15 
16 using MaskFormat = skgpu::MaskFormat;
17 
18 #ifdef DF_PATH_TRACKING
19 static int g_NumCachedShapes = 0;
20 static int g_NumFreedShapes = 0;
21 #endif
22 
23 namespace skgpu::v1 {
24 
SmallPathAtlasMgr()25 SmallPathAtlasMgr::SmallPathAtlasMgr() {}
26 
~SmallPathAtlasMgr()27 SmallPathAtlasMgr::~SmallPathAtlasMgr() {
28     this->reset();
29 }
30 
reset()31 void SmallPathAtlasMgr::reset() {
32     ShapeDataList::Iter iter;
33     iter.init(fShapeList, ShapeDataList::Iter::kHead_IterStart);
34     SmallPathShapeData* shapeData;
35     while ((shapeData = iter.get())) {
36         iter.next();
37         delete shapeData;
38     }
39 
40     fShapeList.reset();
41     fShapeCache.reset();
42 
43 #ifdef DF_PATH_TRACKING
44     SkDebugf("Cached shapes: %d, freed shapes: %d\n", g_NumCachedShapes, g_NumFreedShapes);
45 #endif
46 
47     fAtlas = nullptr;
48 }
49 
initAtlas(GrProxyProvider * proxyProvider,const GrCaps * caps)50 bool SmallPathAtlasMgr::initAtlas(GrProxyProvider* proxyProvider, const GrCaps* caps) {
51     if (fAtlas) {
52         return true;
53     }
54 
55     static constexpr size_t kMaxAtlasTextureBytes = 2048 * 2048;
56     static constexpr size_t kPlotWidth = 512;
57     static constexpr size_t kPlotHeight = 256;
58 
59     GrColorType atlasColorType = GrColorType::kAlpha_8;
60     const GrBackendFormat format = caps->getDefaultBackendFormat(atlasColorType,
61                                                                  GrRenderable::kNo);
62 
63     GrDrawOpAtlasConfig atlasConfig(caps->maxTextureSize(), kMaxAtlasTextureBytes);
64     SkISize size = atlasConfig.atlasDimensions(MaskFormat::kA8);
65     fAtlas = GrDrawOpAtlas::Make(proxyProvider, format,
66                                  GrColorTypeToSkColorType(atlasColorType),
67                                  GrColorTypeBytesPerPixel(atlasColorType),
68                                  size.width(), size.height(),
69                                  kPlotWidth, kPlotHeight, this,
70                                  GrDrawOpAtlas::AllowMultitexturing::kYes,
71                                  this,
72                                  /*label=*/"SmallPathAtlas");
73 
74     return SkToBool(fAtlas);
75 }
76 
deleteCacheEntry(SmallPathShapeData * shapeData)77 void SmallPathAtlasMgr::deleteCacheEntry(SmallPathShapeData* shapeData) {
78     fShapeCache.remove(shapeData->fKey);
79     fShapeList.remove(shapeData);
80     delete shapeData;
81 }
82 
findOrCreate(const SmallPathShapeDataKey & key)83 SmallPathShapeData* SmallPathAtlasMgr::findOrCreate(const SmallPathShapeDataKey& key) {
84     auto shapeData = fShapeCache.find(key);
85     if (!shapeData) {
86         // TODO: move the key into the ctor
87         shapeData = new SmallPathShapeData(key);
88         fShapeCache.add(shapeData);
89         fShapeList.addToTail(shapeData);
90 #ifdef DF_PATH_TRACKING
91         ++g_NumCachedShapes;
92 #endif
93     } else if (!fAtlas->hasID(shapeData->fAtlasLocator.plotLocator())) {
94         shapeData->fAtlasLocator.invalidatePlotLocator();
95     }
96 
97     return shapeData;
98 }
99 
findOrCreate(const GrStyledShape & shape,int desiredDimension)100 SmallPathShapeData* SmallPathAtlasMgr::findOrCreate(const GrStyledShape& shape,
101                                                     int desiredDimension) {
102     SmallPathShapeDataKey key(shape, desiredDimension);
103 
104     // TODO: move the key into 'findOrCreate'
105     return this->findOrCreate(key);
106 }
107 
findOrCreate(const GrStyledShape & shape,const SkMatrix & ctm)108 SmallPathShapeData* SmallPathAtlasMgr::findOrCreate(const GrStyledShape& shape,
109                                                     const SkMatrix& ctm) {
110     SmallPathShapeDataKey key(shape, ctm);
111 
112     // TODO: move the key into 'findOrCreate'
113     return this->findOrCreate(key);
114 }
115 
addToAtlas(GrResourceProvider * resourceProvider,GrDeferredUploadTarget * target,int width,int height,const void * image,skgpu::AtlasLocator * locator)116 GrDrawOpAtlas::ErrorCode SmallPathAtlasMgr::addToAtlas(GrResourceProvider* resourceProvider,
117                                                        GrDeferredUploadTarget* target,
118                                                        int width, int height, const void* image,
119                                                        skgpu::AtlasLocator* locator) {
120     return fAtlas->addToAtlas(resourceProvider, target, width, height, image, locator);
121 }
122 
setUseToken(SmallPathShapeData * shapeData,skgpu::AtlasToken token)123 void SmallPathAtlasMgr::setUseToken(SmallPathShapeData* shapeData,
124                                     skgpu::AtlasToken token) {
125     fAtlas->setLastUseToken(shapeData->fAtlasLocator, token);
126 }
127 
128 // Callback to clear out internal path cache when eviction occurs
evict(skgpu::PlotLocator plotLocator)129 void SmallPathAtlasMgr::evict(skgpu::PlotLocator plotLocator) {
130     // remove any paths that use this plot
131     ShapeDataList::Iter iter;
132     iter.init(fShapeList, ShapeDataList::Iter::kHead_IterStart);
133     SmallPathShapeData* shapeData;
134     while ((shapeData = iter.get())) {
135         iter.next();
136         if (plotLocator == shapeData->fAtlasLocator.plotLocator()) {
137             fShapeCache.remove(shapeData->fKey);
138             fShapeList.remove(shapeData);
139             delete shapeData;
140 #ifdef DF_PATH_TRACKING
141             ++g_NumFreedShapes;
142 #endif
143         }
144     }
145 }
146 
147 } // namespace skgpu::v1
148 
149 #endif // SK_ENABLE_OPTIMIZE_SIZE
150