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