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