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