From afa90369cb3592fc70869e43ac95c3865b104777 Mon Sep 17 00:00:00 2001 From: Herb Derby Date: Wed, 8 Jul 2020 12:20:11 -0400 Subject: [PATCH] don't produce empty SubRuns Change-Id: Ib2d91afebbf6b7300a5820b25661a33b57996f42 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/301304 Commit-Queue: Herb Derby Reviewed-by: Ben Wagner --- src/core/SkGlyphBuffer.h | 5 +++++ src/core/SkGlyphRunPainter.cpp | 8 ++++---- src/gpu/text/GrTextBlob.cpp | 10 +++++++--- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/core/SkGlyphBuffer.h b/src/core/SkGlyphBuffer.h index 8458afdbc5..cf4230acf0 100644 --- a/src/core/SkGlyphBuffer.h +++ b/src/core/SkGlyphBuffer.h @@ -209,6 +209,11 @@ public: return SkZip{fDrawableSize, fMultiBuffer, fPositions}; } + bool drawableIsEmpty() const { + SkASSERT(fPhase == kProcess || fPhase == kDraw); + return fDrawableSize == 0; + } + void reset(); template diff --git a/src/core/SkGlyphRunPainter.cpp b/src/core/SkGlyphRunPainter.cpp index c991238d40..60960f690e 100644 --- a/src/core/SkGlyphRunPainter.cpp +++ b/src/core/SkGlyphRunPainter.cpp @@ -173,7 +173,7 @@ void SkGlyphRunListPainter::processGlyphRunList(const SkGlyphRunList& glyphRunLi strike->prepareForSDFTDrawing(&fDrawable, &fRejects); fRejects.flipRejectsToSource(); - if (process) { + if (process && !fDrawable.drawableIsEmpty()) { // processSourceSDFT must be called even if there are no glyphs to make sure // runs are set correctly. process->processSourceSDFT( @@ -194,7 +194,7 @@ void SkGlyphRunListPainter::processGlyphRunList(const SkGlyphRunList& glyphRunLi strike->prepareForMaskDrawing(&fDrawable, &fRejects); fRejects.flipRejectsToSource(); - if (process) { + if (process && !fDrawable.drawableIsEmpty()) { // processDeviceMasks must be called even if there are no glyphs to make sure runs // are set correctly. process->processDeviceMasks(fDrawable.drawable(), strikeSpec); @@ -220,7 +220,7 @@ void SkGlyphRunListPainter::processGlyphRunList(const SkGlyphRunList& glyphRunLi maxDimensionInSourceSpace = fRejects.rejectedMaxDimension() * strikeSpec.strikeToSourceRatio(); - if (process) { + if (process && !fDrawable.drawableIsEmpty()) { // processSourcePaths must be called even if there are no glyphs to make sure // runs are set correctly. process->processSourcePaths(fDrawable.drawable(), runFont, strikeSpec); @@ -242,7 +242,7 @@ void SkGlyphRunListPainter::processGlyphRunList(const SkGlyphRunList& glyphRunLi fRejects.flipRejectsToSource(); SkASSERT(fRejects.source().empty()); - if (process) { + if (process && !fDrawable.drawableIsEmpty()) { process->processSourceMasks(fDrawable.drawable(), strikeSpec); } } diff --git a/src/gpu/text/GrTextBlob.cpp b/src/gpu/text/GrTextBlob.cpp index 9307eb6231..a22233426b 100644 --- a/src/gpu/text/GrTextBlob.cpp +++ b/src/gpu/text/GrTextBlob.cpp @@ -389,6 +389,7 @@ void GrTextBlob::SubRun::insertSubRunOpsIntoTarget(GrTextTarget* target, const SkMatrixProvider& deviceMatrix, SkPoint drawOrigin) { if (this->drawAsPaths()) { + SkASSERT(!fPaths.empty()); SkPaint runPaint{paint}; runPaint.setAntiAlias(this->isAntiAliased()); // If there are shaders, blurs or styles, the path must be scaled into source @@ -434,10 +435,8 @@ void GrTextBlob::SubRun::insertSubRunOpsIntoTarget(GrTextTarget* target, } } } else { - if (this->glyphCount() == 0) { - return; - } // Handle the mask and distance field cases. + SkASSERT(this->glyphCount() != 0); // We can clip geometrically using clipRect and ignore clip if we're not using SDFs or // transformed glyphs, and we have an axis-aligned rectangular non-AA clip. @@ -588,6 +587,11 @@ bool GrTextBlob::canReuse(const SkPaint& paint, const SkMaskFilterBase::BlurRec& blurRec, const SkMatrix& drawMatrix, SkPoint drawOrigin) { + // A singular matrix will create a GrTextBlob with no subRuns. Assume that, and just regenerate. + if (fSubRunList.isEmpty()) { + return false; + } + // If we have LCD text then our canonical color will be set to transparent, in this case we have // to regenerate the blob on any color change // We use the grPaint to get any color filter effects