diff --git a/skia/include/gpu/GrContextOptions.h b/skia/include/gpu/GrContextOptions.h index 7c2d97b8047cd3f0790f86b568d13b3403408a7e..a9728719e55f090d4994846ae946897028e000ed 100644 --- a/skia/include/gpu/GrContextOptions.h +++ b/skia/include/gpu/GrContextOptions.h @@ -117,8 +117,11 @@ struct SK_API GrContextOptions { /** * The maximum size of cache textures used for Skia's Glyph cache. */ - size_t fGlyphCacheTextureMaximumBytes = 2048 * 1024 * 4; + size_t fGlyphCacheTextureMaximumBytes = 512 * 512 * 16; + int fAtlasPageNum = 16; + + int fPlotOldThreshold = 128; /** * Below this threshold size in device space distance field fonts won't be used. Distance field * fonts don't support hinting which is more important at smaller sizes. A negative value means diff --git a/skia/src/gpu/GrDrawOpAtlas.cpp b/skia/src/gpu/GrDrawOpAtlas.cpp index e11d857c4ff9c9611784780c8abfce45fa3bc0c2..6a646cfa8da4058617055caf63c2a4fd8712aef9 100644 --- a/skia/src/gpu/GrDrawOpAtlas.cpp +++ b/skia/src/gpu/GrDrawOpAtlas.cpp @@ -38,6 +38,8 @@ std::unique_ptr GrDrawOpAtlas::Make(GrProxyProvider* proxyProvide GrColorType colorType, int width, int height, int plotWidth, int plotHeight, AllowMultitexturing allowMultitexturing, + int atlasPageNum, + int plotOldThreshold, GrDrawOpAtlas::EvictionFunc func, void* data) { if (!format.isValid()) { return nullptr; @@ -45,7 +47,7 @@ std::unique_ptr GrDrawOpAtlas::Make(GrProxyProvider* proxyProvide std::unique_ptr atlas(new GrDrawOpAtlas(proxyProvider, format, colorType, width, height, plotWidth, plotHeight, - allowMultitexturing)); + allowMultitexturing, atlasPageNum, plotOldThreshold)); if (!atlas->getProxies()[0]) { return nullptr; } @@ -184,7 +186,8 @@ void GrDrawOpAtlas::Plot::resetRects() { GrDrawOpAtlas::GrDrawOpAtlas(GrProxyProvider* proxyProvider, const GrBackendFormat& format, GrColorType colorType, int width, int height, - int plotWidth, int plotHeight, AllowMultitexturing allowMultitexturing) + int plotWidth, int plotHeight, AllowMultitexturing allowMultitexturing, + int atlasPageNum, int plotOldThreshold) : fFormat(format) , fColorType(colorType) , fTextureWidth(width) @@ -193,8 +196,9 @@ GrDrawOpAtlas::GrDrawOpAtlas(GrProxyProvider* proxyProvider, const GrBackendForm , fPlotHeight(plotHeight) , fAtlasGeneration(kInvalidAtlasGeneration + 1) , fPrevFlushToken(GrDeferredUploadToken::AlreadyFlushedToken()) - , fMaxPages(AllowMultitexturing::kYes == allowMultitexturing ? kMaxMultitexturePages : 1) - , fNumActivePages(0) { + , fMaxPages(AllowMultitexturing::kYes == allowMultitexturing ? atlasPageNum : 1) + , fNumActivePages(0) + , fPlotOldThreshold(plotOldThreshold) { int numPlotsX = width/plotWidth; int numPlotsY = height/plotHeight; SkASSERT(numPlotsX * numPlotsY <= GrDrawOpAtlas::kMaxPlots); @@ -204,6 +208,9 @@ GrDrawOpAtlas::GrDrawOpAtlas(GrProxyProvider* proxyProvider, const GrBackendForm fNumPlots = numPlotsX * numPlotsY; this->createPages(proxyProvider); + + SkDebugf("TW:%{public}d, TH:%{public}d, PW:%{public}d, PH:%{public}d, MP:%{public}d, POT:%{public}d.", + fTextureWidth, fTextureHeight, fPlotWidth, fPlotHeight, fMaxPages, fPlotOldThreshold); } inline void GrDrawOpAtlas::processEviction(AtlasID id) { @@ -262,7 +269,6 @@ bool GrDrawOpAtlas::uploadToPage(unsigned int pageIdx, AtlasID* id, GrDeferredUp // a page with unused plots will get removed reasonably quickly, but allow it // to hang around for a bit in case it's needed. The assumption is that flushes // are rare; i.e., we are not continually refreshing the frame. -static constexpr auto kRecentlyUsedCount = 256; GrDrawOpAtlas::ErrorCode GrDrawOpAtlas::addToAtlas(GrResourceProvider* resourceProvider, AtlasID* id, GrDeferredUploadTarget* target, @@ -298,6 +304,9 @@ GrDrawOpAtlas::ErrorCode GrDrawOpAtlas::addToAtlas(GrResourceProvider* resourceP if (!this->updatePlot(target, id, plot)) { return ErrorCode::kError; } +#ifdef SK_DEBUG_PAGE + SkDebugf("----- addToAtlas overwrite page# %{public}d.", pageIdx); +#endif return ErrorCode::kSucceeded; } } @@ -366,7 +375,9 @@ GrDrawOpAtlas::ErrorCode GrDrawOpAtlas::addToAtlas(GrResourceProvider* resourceP newPlot->setLastUploadToken(lastUploadToken); *id = newPlot->id(); - +#ifdef SK_DEBUG_PAGE + SkDebugf("----- addToAtlas addInlineUpload page# %{public}d.", pageIdx); +#endif return ErrorCode::kSucceeded; } @@ -425,7 +436,7 @@ void GrDrawOpAtlas::compact(GrDeferredUploadToken startTokenForNextFlush) { #endif // Count plots we can potentially upload to in all pages except the last one // (the potential compactee). - if (plot->flushesSinceLastUsed() > kRecentlyUsedCount) { + if (plot->flushesSinceLastUsed() > fPlotOldThreshold) { availablePlots.push_back() = plot; } @@ -460,7 +471,7 @@ void GrDrawOpAtlas::compact(GrDeferredUploadToken startTokenForNextFlush) { } #endif // If this plot was used recently - if (plot->flushesSinceLastUsed() <= kRecentlyUsedCount) { + if (plot->flushesSinceLastUsed() <= fPlotOldThreshold) { usedPlots++; } else if (plot->lastUseToken() != GrDeferredUploadToken::AlreadyFlushedToken()) { // otherwise if aged out just evict it. @@ -482,7 +493,7 @@ void GrDrawOpAtlas::compact(GrDeferredUploadToken startTokenForNextFlush) { plotIter.init(fPages[lastPageIndex].fPlotList, PlotList::Iter::kHead_IterStart); while (Plot* plot = plotIter.get()) { // If this plot was used recently - if (plot->flushesSinceLastUsed() <= kRecentlyUsedCount) { + if (plot->flushesSinceLastUsed() <= fPlotOldThreshold) { // See if there's room in an earlier page and if so evict. // We need to be somewhat harsh here so that a handful of plots that are // consistently in use don't end up locking the page in memory. @@ -506,6 +517,9 @@ void GrDrawOpAtlas::compact(GrDeferredUploadToken startTokenForNextFlush) { if (gDumpAtlasData) { SkDebugf("delete %d\n", fNumPages-1); } +#endif +#ifdef SK_DEBUG_PAGE + SkDebugf("----- availablePlots %{public}d.", availablePlots.count()); #endif this->deactivateLastPage(); } @@ -569,7 +583,9 @@ bool GrDrawOpAtlas::activateNewPage(GrResourceProvider* resourceProvider) { SkDebugf("activated page#: %d\n", fNumActivePages); } #endif - +#ifdef SK_DEBUG_PAGE + SkDebugf("----- activated page#: %{public}d.", fNumActivePages); +#endif ++fNumActivePages; return true; } @@ -598,33 +614,32 @@ inline void GrDrawOpAtlas::deactivateLastPage() { fPages[lastPageIndex].fPlotList.addToHead(currPlot); } } - // remove ref to the backing texture fProxies[lastPageIndex]->deinstantiate(); --fNumActivePages; +#ifdef SK_DEBUG_PAGE + SkDebugf("----- deactivateLastPage %{public}d.", lastPageIndex); +#endif } -GrDrawOpAtlasConfig::GrDrawOpAtlasConfig(int maxTextureSize, size_t maxBytes) { - static const SkISize kARGBDimensions[] = { - {256, 256}, // maxBytes < 2^19 - {512, 256}, // 2^19 <= maxBytes < 2^20 - {512, 512}, // 2^20 <= maxBytes < 2^21 - {1024, 512}, // 2^21 <= maxBytes < 2^22 - {1024, 1024}, // 2^22 <= maxBytes < 2^23 - {2048, 1024}, // 2^23 <= maxBytes - }; - - // Index 0 corresponds to maxBytes of 2^18, so start by dividing it by that - maxBytes >>= 18; - // Take the floor of the log to get the index - int index = maxBytes > 0 - ? SkTPin(SkPrevLog2(maxBytes), 0, SK_ARRAY_COUNT(kARGBDimensions) - 1) - : 0; - - SkASSERT(kARGBDimensions[index].width() <= kMaxAtlasDim); - SkASSERT(kARGBDimensions[index].height() <= kMaxAtlasDim); - fARGBDimensions.set(SkTMin(kARGBDimensions[index].width(), maxTextureSize), - SkTMin(kARGBDimensions[index].height(), maxTextureSize)); +GrDrawOpAtlasConfig::GrDrawOpAtlasConfig(int maxTextureSize, size_t maxBytes, int atlasPageNum) + : fAtlasPageNum(atlasPageNum) { + + size_t pageBytes = maxBytes / atlasPageNum; + int index = SkPrevLog2(pageBytes); + int width, height; + if (index % 2 == 0) { + width = std::pow(2, index / 2); + height = std::pow(2, index / 2); + } else { + width = std::pow(2, index / 2 + 1); + height = std::pow(2, index / 2); + } + SkASSERT(width <= kMaxAtlasDim); + SkASSERT(height <= kMaxAtlasDim); + + fARGBDimensions.set(SkTMin(width, maxTextureSize), + SkTMin(height, maxTextureSize)); fMaxTextureSize = SkTMin(maxTextureSize, kMaxAtlasDim); } @@ -647,8 +662,8 @@ SkISize GrDrawOpAtlasConfig::plotDimensions(GrMaskFormat type) const { // This will give us 512x256 plots for 2048x1024, 512x512 plots for 2048x2048, // and 256x256 plots otherwise. - int plotWidth = atlasDimensions.width() >= 2048 ? 512 : 256; - int plotHeight = atlasDimensions.height() >= 2048 ? 512 : 256; + int plotWidth = atlasDimensions.width() >= 1024 ? 512 : 256; + int plotHeight = atlasDimensions.height() >= 1024 ? 512 : 256; return { plotWidth, plotHeight }; } else { diff --git a/skia/src/gpu/GrDrawOpAtlas.h b/skia/src/gpu/GrDrawOpAtlas.h index f488f6ecb1871669218d2940347d0d8648af8827..57db4a910642004fb12d34e956218944fce1009c 100644 --- a/skia/src/gpu/GrDrawOpAtlas.h +++ b/skia/src/gpu/GrDrawOpAtlas.h @@ -49,7 +49,7 @@ class GrRectanizer; */ class GrDrawOpAtlas { private: - static constexpr auto kMaxMultitexturePages = 4; + static constexpr auto kMaxMultitexturePages = 16; public: @@ -97,6 +97,8 @@ public: int width, int height, int plotWidth, int plotHeight, AllowMultitexturing allowMultitexturing, + int atlasPageCount, + int plotOldThreshold, GrDrawOpAtlas::EvictionFunc func, void* data); /** @@ -248,7 +250,7 @@ public: private: GrDrawOpAtlas(GrProxyProvider*, const GrBackendFormat& format, GrColorType, int width, int height, int plotWidth, int plotHeight, - AllowMultitexturing allowMultitexturing); + AllowMultitexturing allowMultitexturing, int atlasPageCount, int plotOldThreshold); /** * The backing GrTexture for a GrDrawOpAtlas is broken into a spatial grid of Plots. The Plots @@ -416,6 +418,7 @@ private: uint32_t fMaxPages; uint32_t fNumActivePages; + int fPlotOldThreshold; }; // There are three atlases (A8, 565, ARGB) that are kept in relation with one another. In @@ -427,11 +430,11 @@ public: // The capabilities of the GPU define maxTextureSize. The client provides maxBytes, and this // represents the largest they want a single atlas texture to be. Due to multitexturing, we // may expand temporarily to use more space as needed. - GrDrawOpAtlasConfig(int maxTextureSize, size_t maxBytes); + GrDrawOpAtlasConfig(int maxTextureSize, size_t maxBytes, int atlasPageNum); // For testing only - make minimum sized atlases -- a single plot for ARGB, four for A8 - GrDrawOpAtlasConfig() : GrDrawOpAtlasConfig(kMaxAtlasDim, 0) {} - + GrDrawOpAtlasConfig() : GrDrawOpAtlasConfig(kMaxAtlasDim, 0, 1) {} + int getAtlasPageNum(){return fAtlasPageNum;} SkISize atlasDimensions(GrMaskFormat type) const; SkISize plotDimensions(GrMaskFormat type) const; @@ -441,9 +444,9 @@ private: // For simplicity we'll use this constraint for all of our atlas textures. // This can be revisited later if we need larger atlases. static constexpr int kMaxAtlasDim = 2048; - SkISize fARGBDimensions; int fMaxTextureSize; + int fAtlasPageNum; }; #endif diff --git a/skia/src/gpu/GrLegacyDirectContext.cpp b/skia/src/gpu/GrLegacyDirectContext.cpp index 932c2411a5d2b380ec5fb067314b7069bab2601c..1ccbe0db1da011692091a3298794e6d9453e6372 100644 --- a/skia/src/gpu/GrLegacyDirectContext.cpp +++ b/skia/src/gpu/GrLegacyDirectContext.cpp @@ -108,7 +108,9 @@ protected: fAtlasManager = new GrAtlasManager(proxyProvider, glyphCache, this->options().fGlyphCacheTextureMaximumBytes, - allowMultitexturing); + allowMultitexturing, + this->options().fAtlasPageNum, + this->options().fPlotOldThreshold); this->priv().addOnFlushCallbackObject(fAtlasManager); return true; diff --git a/skia/src/gpu/effects/GrAtlasedShaderHelpers.h b/skia/src/gpu/effects/GrAtlasedShaderHelpers.h index 94b6f98a512f1e50ad241964d997e256dbb43b2a..ac8846806d30f8c59421ad3bd6db480053ad24e0 100644 --- a/skia/src/gpu/effects/GrAtlasedShaderHelpers.h +++ b/skia/src/gpu/effects/GrAtlasedShaderHelpers.h @@ -28,8 +28,8 @@ static void append_index_uv_varyings(GrGLSLPrimitiveProcessor::EmitArgs& args, if (args.fShaderCaps->integerSupport()) { args.fVertBuilder->codeAppendf("int2 signedCoords = int2(%s.x, %s.y);", inTexCoordsName, inTexCoordsName); - args.fVertBuilder->codeAppend("int texIdx = 2*(signedCoords.x & 0x1) + (signedCoords.y & 0x1);"); - args.fVertBuilder->codeAppend("float2 unormTexCoords = float2(signedCoords.x/2, signedCoords.y/2);"); + args.fVertBuilder->codeAppend("int texIdx = 8*(signedCoords.x & 0x7) + (signedCoords.y & 0x7);"); + args.fVertBuilder->codeAppend("float2 unormTexCoords = float2(signedCoords.x/8, signedCoords.y/8);"); } else { args.fVertBuilder->codeAppendf("float2 indexTexCoords = float2(%s.x, %s.y);", inTexCoordsName, inTexCoordsName); diff --git a/skia/src/gpu/effects/GrBitmapTextGeoProc.h b/skia/src/gpu/effects/GrBitmapTextGeoProc.h index 3c29c4a58535e99315eb19560a8e2c1516666dac..238293b50b03d0aa4a8e133b7400d74b4cbb7edf 100644 --- a/skia/src/gpu/effects/GrBitmapTextGeoProc.h +++ b/skia/src/gpu/effects/GrBitmapTextGeoProc.h @@ -21,7 +21,7 @@ class GrInvariantOutput; */ class GrBitmapTextGeoProc : public GrGeometryProcessor { public: - static constexpr int kMaxTextures = 4; + static constexpr int kMaxTextures = 16; static sk_sp Make(const GrShaderCaps& caps, const SkPMColor4f& color, bool wideColor, diff --git a/skia/src/gpu/effects/GrDistanceFieldGeoProc.h b/skia/src/gpu/effects/GrDistanceFieldGeoProc.h index 20bb6262ae68abbe8916fb0f1c51331ee9eb6055..7657f66dc64492a13406177192992b67d387e527 100644 --- a/skia/src/gpu/effects/GrDistanceFieldGeoProc.h +++ b/skia/src/gpu/effects/GrDistanceFieldGeoProc.h @@ -53,7 +53,7 @@ enum GrDistanceFieldEffectFlags { */ class GrDistanceFieldA8TextGeoProc : public GrGeometryProcessor { public: - static constexpr int kMaxTextures = 4; + static constexpr int kMaxTextures = 16; /** The local matrix should be identity if local coords are not required by the GrPipeline. */ #ifdef SK_GAMMA_APPLY_TO_A8 @@ -132,7 +132,7 @@ private: */ class GrDistanceFieldPathGeoProc : public GrGeometryProcessor { public: - static constexpr int kMaxTextures = 4; + static constexpr int kMaxTextures = 16; /** The local matrix should be identity if local coords are not required by the GrPipeline. */ static sk_sp Make(const GrShaderCaps& caps, @@ -194,7 +194,7 @@ private: */ class GrDistanceFieldLCDTextGeoProc : public GrGeometryProcessor { public: - static constexpr int kMaxTextures = 4; + static constexpr int kMaxTextures = 16; struct DistanceAdjust { SkScalar fR, fG, fB; diff --git a/skia/src/gpu/ops/GrAtlasTextOp.cpp b/skia/src/gpu/ops/GrAtlasTextOp.cpp index 1761acc82727c6f72fedeca9e7bf5db9594bc194..b00c4c91803a5b39ba6fc9709690f10ff0363f0f 100644 --- a/skia/src/gpu/ops/GrAtlasTextOp.cpp +++ b/skia/src/gpu/ops/GrAtlasTextOp.cpp @@ -197,12 +197,12 @@ static void clip_quads(const SkIRect& clipRect, char* currVertex, const char* bl auto* blobCoordsRB = reinterpret_cast(blobVertices + 3 * vertexStride + coordOffset); // Pull out the texel coordinates and texture index bits - uint16_t coordsRectL = blobCoordsLT[0] >> 1; - uint16_t coordsRectT = blobCoordsLT[1] >> 1; - uint16_t coordsRectR = blobCoordsRB[0] >> 1; - uint16_t coordsRectB = blobCoordsRB[1] >> 1; - uint16_t pageIndexX = blobCoordsLT[0] & 0x1; - uint16_t pageIndexY = blobCoordsLT[1] & 0x1; + uint16_t coordsRectL = blobCoordsLT[0] >> 3; + uint16_t coordsRectT = blobCoordsLT[1] >> 3; + uint16_t coordsRectR = blobCoordsRB[0] >> 3; + uint16_t coordsRectB = blobCoordsRB[1] >> 3; + uint16_t pageIndexX = blobCoordsLT[0] & 0x7; + uint16_t pageIndexY = blobCoordsLT[1] & 0x7; int positionRectWidth = positionRect.width(); int positionRectHeight = positionRect.height(); @@ -228,10 +228,10 @@ static void clip_quads(const SkIRect& clipRect, char* currVertex, const char* bl positionRect.fBottom -= delta; // Repack texel coordinates and index - coordsRectL = coordsRectL << 1 | pageIndexX; - coordsRectT = coordsRectT << 1 | pageIndexY; - coordsRectR = coordsRectR << 1 | pageIndexX; - coordsRectB = coordsRectB << 1 | pageIndexY; + coordsRectL = coordsRectL << 3 | pageIndexX; + coordsRectT = coordsRectT << 3 | pageIndexY; + coordsRectR = coordsRectR << 3 | pageIndexX; + coordsRectB = coordsRectB << 3 | pageIndexY; // Set new positions and coords SkPoint* currPosition = reinterpret_cast(currVertex); @@ -275,6 +275,9 @@ static void clip_quads(const SkIRect& clipRect, char* currVertex, const char* bl } } +#ifdef SK_DEGUB_ATLAS_HIT_RATE +static int count = 0; +#endif void GrAtlasTextOp::onPrepareDraws(Target* target) { auto resourceProvider = target->resourceProvider(); @@ -288,6 +291,17 @@ void GrAtlasTextOp::onPrepareDraws(Target* target) { GrAtlasManager* atlasManager = target->atlasManager(); GrStrikeCache* glyphCache = target->glyphCache(); +#ifdef SK_DEGUB_ATLAS_HIT_RATE + count++; + if (count == 0 || count % 20 == 0) { + float hitRate = GrTextBlob::AtlasHitRate(); + if (!(fabs(hitRate-0)<=1.0e-6)) { + SkDebugf("--------- Since Last 100 prepareDraws, AtlasHitRate = %{public}6.2f.", hitRate); + } + GrTextBlob::resetHitCount(); + } +#endif + GrMaskFormat maskFormat = this->maskFormat(); unsigned int numActiveProxies; diff --git a/skia/src/gpu/ops/GrSmallPathRenderer.cpp b/skia/src/gpu/ops/GrSmallPathRenderer.cpp index f6a370525c24b1a306d4270c5031eb464d437235..71314d690a7ce65cb6c14887ebedaef58ef1d45c 100644 --- a/skia/src/gpu/ops/GrSmallPathRenderer.cpp +++ b/skia/src/gpu/ops/GrSmallPathRenderer.cpp @@ -33,6 +33,8 @@ #define ATLAS_TEXTURE_HEIGHT 2048 #define PLOT_WIDTH 512 #define PLOT_HEIGHT 256 +#define ATLAS_PAGE_NUM 4 +#define PLOT_OLD_THRESHOLD 256 #define NUM_PLOTS_X (ATLAS_TEXTURE_WIDTH / PLOT_WIDTH) #define NUM_PLOTS_Y (ATLAS_TEXTURE_HEIGHT / PLOT_HEIGHT) @@ -882,6 +884,8 @@ bool GrSmallPathRenderer::onDrawPath(const DrawPathArgs& args) { ATLAS_TEXTURE_WIDTH, ATLAS_TEXTURE_HEIGHT, PLOT_WIDTH, PLOT_HEIGHT, GrDrawOpAtlas::AllowMultitexturing::kYes, + ATLAS_PAGE_NUM, + PLOT_OLD_THRESHOLD, &GrSmallPathRenderer::HandleEviction, (void*)this); if (!fAtlas) { @@ -971,6 +975,8 @@ GR_DRAW_OP_TEST_DEFINE(SmallPathOp) { ATLAS_TEXTURE_WIDTH, ATLAS_TEXTURE_HEIGHT, PLOT_WIDTH, PLOT_HEIGHT, GrDrawOpAtlas::AllowMultitexturing::kYes, + ATLAS_PAGE_NUM, + PLOT_OLD_THRESHOLD, &PathTestStruct::HandleEviction, (void*)&gTestStruct); } diff --git a/skia/src/gpu/text/GrAtlasManager.cpp b/skia/src/gpu/text/GrAtlasManager.cpp index 6ae06a4341c70fab3f0c02bcba900c015996a950..cf145bbb1abb8406ac186b35a117aa263e059d9f 100644 --- a/skia/src/gpu/text/GrAtlasManager.cpp +++ b/skia/src/gpu/text/GrAtlasManager.cpp @@ -12,12 +12,14 @@ GrAtlasManager::GrAtlasManager(GrProxyProvider* proxyProvider, GrStrikeCache* glyphCache, size_t maxTextureBytes, - GrDrawOpAtlas::AllowMultitexturing allowMultitexturing) + GrDrawOpAtlas::AllowMultitexturing allowMultitexturing, + int atlasPageNum, int plotOldThreshold) : fAllowMultitexturing{allowMultitexturing} , fProxyProvider{proxyProvider} , fCaps{fProxyProvider->refCaps()} , fGlyphCache{glyphCache} - , fAtlasConfig{fCaps->maxTextureSize(), maxTextureBytes} { } + , fAtlasConfig{fCaps->maxTextureSize(), maxTextureBytes, atlasPageNum} + , fPlotOldThreshold(plotOldThreshold){ } GrAtlasManager::~GrAtlasManager() = default; @@ -67,7 +69,7 @@ void GrAtlasManager::addGlyphToBulkAndSetUseToken(GrDrawOpAtlas::BulkUseTokenUpd } } -#ifdef SK_DEBUG +#ifdef SK_DUMP_ATLAS_IMAGE #include "src/gpu/GrContextPriv.h" #include "src/gpu/GrSurfaceContext.h" #include "src/gpu/GrSurfaceProxy.h" @@ -137,7 +139,7 @@ void GrAtlasManager::dump(GrContext* context) const { #ifdef SK_BUILD_FOR_ANDROID filename.printf("/sdcard/fontcache_%d%d%d.png", gDumpCount, i, pageIdx); #else - filename.printf("fontcache_%d%d%d.png", gDumpCount, i, pageIdx); + filename.printf("/data/storage/el2/base/cache/fontcache_%d_%d_%d.png", gDumpCount, i, pageIdx); #endif auto ct = mask_format_to_gr_color_type(AtlasIndexToMaskFormat(i)); save_pixels(context, proxies[pageIdx].get(), ct, filename.c_str()); @@ -163,9 +165,10 @@ bool GrAtlasManager::initAtlas(GrMaskFormat format) { int index = MaskFormatToAtlasIndex(format); if (fAtlases[index] == nullptr) { GrColorType grColorType = mask_format_to_gr_color_type(format); + SkISize atlasDimensions = fAtlasConfig.atlasDimensions(format); SkISize plotDimensions = fAtlasConfig.plotDimensions(format); - + const GrBackendFormat format = fCaps->getDefaultBackendFormat(grColorType, GrRenderable::kNo); @@ -173,7 +176,7 @@ bool GrAtlasManager::initAtlas(GrMaskFormat format) { fProxyProvider, format, grColorType, atlasDimensions.width(), atlasDimensions.height(), plotDimensions.width(), plotDimensions.height(), - fAllowMultitexturing, &GrStrikeCache::HandleEviction, fGlyphCache); + fAllowMultitexturing, fAtlasConfig.getAtlasPageNum(), fPlotOldThreshold, &GrStrikeCache::HandleEviction, fGlyphCache); if (!fAtlases[index]) { return false; } diff --git a/skia/src/gpu/text/GrAtlasManager.h b/skia/src/gpu/text/GrAtlasManager.h index 1a2871e7a9aaf4c2467b2b943c320fedbcaa66dc..3036b55a93611a1a336cd0cbf7d769a72ce3af6c 100644 --- a/skia/src/gpu/text/GrAtlasManager.h +++ b/skia/src/gpu/text/GrAtlasManager.h @@ -26,7 +26,7 @@ class GrTextStrike; class GrAtlasManager : public GrOnFlushCallbackObject { public: GrAtlasManager(GrProxyProvider*, GrStrikeCache*, - size_t maxTextureBytes, GrDrawOpAtlas::AllowMultitexturing); + size_t maxTextureBytes, GrDrawOpAtlas::AllowMultitexturing, int atlasPageNum, int plotOldThreshold); ~GrAtlasManager() override; // Change an expected 565 mask format to 8888 if 565 is not supported (will happen when using @@ -112,7 +112,7 @@ public: /////////////////////////////////////////////////////////////////////////// // Functions intended debug only -#ifdef SK_DEBUG +#ifdef SK_DUMP_ATLAS_IMAGE void dump(GrContext* context) const; #endif @@ -139,6 +139,7 @@ private: sk_sp fCaps; GrStrikeCache* fGlyphCache; GrDrawOpAtlasConfig fAtlasConfig; + int fPlotOldThreshold; typedef GrOnFlushCallbackObject INHERITED; }; diff --git a/skia/src/gpu/text/GrTextBlob.h b/skia/src/gpu/text/GrTextBlob.h index ddea88d15fe5bbae3661d656768d1058209931e0..e5a1a6d02f58294cff3977a44cda1cde924efdaa 100644 --- a/skia/src/gpu/text/GrTextBlob.h +++ b/skia/src/gpu/text/GrTextBlob.h @@ -56,6 +56,14 @@ public: class VertexRegenerator; +#ifdef SK_DEGUB_ATLAS_HIT_RATE + static float AtlasHitRate(); + static void resetHitCount(){ + fAtlasMissCount = 0; + fAtlasHitCount = 0; + } +#endif + void generateFromGlyphRunList(const GrShaderCaps& shaderCaps, const GrTextContext::Options& options, const SkPaint& paint, @@ -253,6 +261,11 @@ public: GrTextTarget*); private: + +#ifdef SK_DEGUB_ATLAS_HIT_RATE + static int fAtlasMissCount; + static int fAtlasHitCount; +#endif GrTextBlob(GrStrikeCache* strikeCache) : fStrikeCache{strikeCache} { } // This function will only be called when we are generating a blob from scratch. We record the diff --git a/skia/src/gpu/text/GrTextBlobVertexRegenerator.cpp b/skia/src/gpu/text/GrTextBlobVertexRegenerator.cpp index 976beaf3d4e336e6b8b6ae45eb69b76ca8e0814a..66c8630086fc847c25686f82d780f7541d05a18f 100644 --- a/skia/src/gpu/text/GrTextBlobVertexRegenerator.cpp +++ b/skia/src/gpu/text/GrTextBlobVertexRegenerator.cpp @@ -11,6 +11,7 @@ #include "src/gpu/text/GrTextBlob.h" #include "src/gpu/text/GrTextTarget.h" + enum RegenMask { kNoRegen = 0x0, kRegenPos = 0x1, @@ -65,16 +66,16 @@ static void regen_texcoords(char* vertex, size_t vertexStride, const GrGlyph* gl } // We pack the 2bit page index in the low bit of the u and v texture coords uint32_t pageIndex = glyph->pageIndex(); - SkASSERT(pageIndex < 4); - uint16_t uBit = (pageIndex >> 1) & 0x1; - uint16_t vBit = pageIndex & 0x1; - u0 <<= 1; + SkASSERT(pageIndex < 16); + uint16_t uBit = (pageIndex >> 3) & 0x7; + uint16_t vBit = pageIndex & 0x7; + u0 <<= 3; u0 |= uBit; - v0 <<= 1; + v0 <<= 3; v0 |= vBit; - u1 <<= 1; + u1 <<= 3; u1 |= uBit; - v1 <<= 1; + v1 <<= 3; v1 |= vBit; uint16_t* textureCoords = reinterpret_cast(vertex + texCoordOffset); @@ -99,7 +100,7 @@ static void regen_texcoords(char* vertex, size_t vertexStride, const GrGlyph* gl hackColor = GrColorPackRGBA(0, 255, 0, 255); break; case 1: - hackColor = GrColorPackRGBA(255, 0, 0, 255);; + hackColor = GrColorPackRGBA(255, 0, 0, 255); break; case 2: hackColor = GrColorPackRGBA(255, 0, 255, 255); @@ -107,6 +108,42 @@ static void regen_texcoords(char* vertex, size_t vertexStride, const GrGlyph* gl case 3: hackColor = GrColorPackRGBA(0, 255, 255, 255); break; + case 4: + hackColor = GrColorPackRGBA(0, 32, 0, 255); + break; + case 5: + hackColor = GrColorPackRGBA(32, 0, 0, 255); + break; + case 6: + hackColor = GrColorPackRGBA(32, 0, 255, 255); + break; + case 7: + hackColor = GrColorPackRGBA(0, 64, 255, 255); + break; + case 8: + hackColor = GrColorPackRGBA(0, 64, 0, 255); + break; + case 9: + hackColor = GrColorPackRGBA(64, 0, 0, 255); + break; + case 10: + hackColor = GrColorPackRGBA(128, 0, 255, 255); + break; + case 11: + hackColor = GrColorPackRGBA(0, 32, 128, 255); + break; + case 12: + hackColor = GrColorPackRGBA(0, 128, 0, 255); + break; + case 13: + hackColor = GrColorPackRGBA(128, 0, 0, 255); + break; + case 14: + hackColor = GrColorPackRGBA(255, 0, 32, 255); + break; + case 15: + hackColor = GrColorPackRGBA(0, 64, 32, 255); + break; default: hackColor = GrColorPackRGBA(0, 0, 0, 255); break; @@ -156,6 +193,19 @@ GrTextBlob::VertexRegenerator::VertexRegenerator(GrResourceProvider* resourcePro } } +#ifdef SK_DEGUB_ATLAS_HIT_RATE + int GrTextBlob::fAtlasMissCount = 0; + int GrTextBlob::fAtlasHitCount = 0; + float GrTextBlob::AtlasHitRate() { + if (fAtlasHitCount + fAtlasHitCount == 0) { + return 0; + } + return (float)fAtlasHitCount / (fAtlasHitCount + fAtlasMissCount); + } +#endif + + + bool GrTextBlob::VertexRegenerator::doRegen(GrTextBlob::VertexRegenerator::Result* result, bool regenPos, bool regenCol, bool regenTexCoords, bool regenGlyphs) { @@ -200,6 +250,9 @@ bool GrTextBlob::VertexRegenerator::doRegen(GrTextBlob::VertexRegenerator::Resul SkASSERT(glyph && glyph->fMaskFormat == fSubRun->maskFormat()); if (!fFullAtlasManager->hasGlyph(glyph)) { +#ifdef SK_DEGUB_ATLAS_HIT_RATE + fAtlasMissCount++; +#endif GrDrawOpAtlas::ErrorCode code; code = strike->addGlyphToAtlas(fResourceProvider, fUploadTarget, fGlyphCache, fFullAtlasManager, glyph, @@ -214,6 +267,10 @@ bool GrTextBlob::VertexRegenerator::doRegen(GrTextBlob::VertexRegenerator::Resul result->fFinished = false; return true; } + } else { +#ifdef SK_DEGUB_ATLAS_HIT_RATE + fAtlasHitCount++; +#endif } auto tokenTracker = fUploadTarget->tokenTracker(); fFullAtlasManager->addGlyphToBulkAndSetUseToken(fSubRun->bulkUseToken(), glyph,