Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(235)

Unified Diff: src/gpu/GrAtlasTextContext.cpp

Issue 1092283002: Add support for rotating / scaling / translating gpu cached distance field textblobs (Closed) Base URL: https://skia.googlesource.com/skia.git@atdfopt3
Patch Set: adding comment Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/GrAtlasTextContext.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/GrAtlasTextContext.cpp
diff --git a/src/gpu/GrAtlasTextContext.cpp b/src/gpu/GrAtlasTextContext.cpp
index b5e8693e8db2e44f2191528f02da09d035500529..8c162220f9e2ec98d31e50e2a8c83cd6c57cc976 100644
--- a/src/gpu/GrAtlasTextContext.cpp
+++ b/src/gpu/GrAtlasTextContext.cpp
@@ -287,15 +287,14 @@ bool GrAtlasTextContext::MustRegenerateBlob(SkScalar* outTransX, SkScalar* outTr
return true;
}
- // TODO distance fields can handle many of these conditions
- if (blob.fViewMatrix.getScaleX() != viewMatrix.getScaleX() ||
- blob.fViewMatrix.getScaleY() != viewMatrix.getScaleY() ||
- blob.fViewMatrix.getSkewX() != viewMatrix.getSkewX() ||
- blob.fViewMatrix.getSkewY() != viewMatrix.getSkewY()) {
- return true;
- }
-
if (blob.hasBitmap()) {
+ if (blob.fViewMatrix.getScaleX() != viewMatrix.getScaleX() ||
+ blob.fViewMatrix.getScaleY() != viewMatrix.getScaleY() ||
+ blob.fViewMatrix.getSkewX() != viewMatrix.getSkewX() ||
+ blob.fViewMatrix.getSkewY() != viewMatrix.getSkewY()) {
+ return true;
+ }
+
// We can update the positions in the cachedtextblobs without regenerating the whole blob,
// but only for integer translations.
// This cool bit of math will determine the necessary translation to apply to the already
@@ -328,9 +327,18 @@ bool GrAtlasTextContext::MustRegenerateBlob(SkScalar* outTransX, SkScalar* outTr
(*outTransX) = transX;
(*outTransY) = transY;
} else {
- // blob.hasDistanceField()
- // TODO figure out the regen formula
- return true;
+ SkASSERT(blob.hasDistanceField());
+ // A scale outside of [blob.fMaxMinScale, blob.fMinMaxScale] would result in a different
+ // distance field being generated, so we have to regenerate in those cases
+ SkScalar newMaxScale = viewMatrix.getMaxScale();
+ SkScalar oldMaxScale = blob.fViewMatrix.getMaxScale();
+ SkScalar scaleAdjust = newMaxScale / oldMaxScale;
+ if (scaleAdjust < blob.fMaxMinScale || scaleAdjust > blob.fMinMaxScale) {
+ return true;
+ }
+
+ (*outTransX) = x - blob.fX;
+ (*outTransY) = y - blob.fY;
}
return false;
@@ -503,7 +511,7 @@ void GrAtlasTextContext::regenerateTextBlob(BitmapTextBlob* cacheBlob,
cacheBlob->setHasDistanceField();
SkPaint dfPaint = runPaint;
SkScalar textRatio;
- this->initDistanceFieldPaint(&dfPaint, &textRatio, viewMatrix);
+ this->initDistanceFieldPaint(cacheBlob, &dfPaint, &textRatio, viewMatrix);
Run& runIdx = cacheBlob->fRuns[run];
PerSubRunInfo& subRun = runIdx.fSubRunInfo.back();
subRun.fUseLCDText = runPaint.isLCDRenderText();
@@ -581,7 +589,9 @@ void GrAtlasTextContext::regenerateTextBlob(BitmapTextBlob* cacheBlob,
}
}
-inline void GrAtlasTextContext::initDistanceFieldPaint(SkPaint* skPaint, SkScalar* textRatio,
+inline void GrAtlasTextContext::initDistanceFieldPaint(BitmapTextBlob* blob,
+ SkPaint* skPaint,
+ SkScalar* textRatio,
const SkMatrix& viewMatrix) {
// getMaxScale doesn't support perspective, so neither do we at the moment
SkASSERT(!viewMatrix.hasPerspective());
@@ -595,17 +605,37 @@ inline void GrAtlasTextContext::initDistanceFieldPaint(SkPaint* skPaint, SkScala
scaledTextSize *= maxScale;
}
+ // We have three sizes of distance field text, and within each size 'bucket' there is a floor
+ // and ceiling. A scale outside of this range would require regenerating the distance fields
+ SkScalar dfMaskScaleFloor;
+ SkScalar dfMaskScaleCeil;
if (scaledTextSize <= kSmallDFFontLimit) {
+ dfMaskScaleFloor = kMinDFFontSize;
+ dfMaskScaleCeil = kMediumDFFontLimit;
*textRatio = textSize / kSmallDFFontSize;
skPaint->setTextSize(SkIntToScalar(kSmallDFFontSize));
} else if (scaledTextSize <= kMediumDFFontLimit) {
+ dfMaskScaleFloor = kMediumDFFontLimit;
+ dfMaskScaleCeil = kLargeDFFontSize;
*textRatio = textSize / kMediumDFFontSize;
skPaint->setTextSize(SkIntToScalar(kMediumDFFontSize));
} else {
+ dfMaskScaleFloor = kLargeDFFontSize;
+ dfMaskScaleCeil = 2 * kLargeDFFontSize;
*textRatio = textSize / kLargeDFFontSize;
skPaint->setTextSize(SkIntToScalar(kLargeDFFontSize));
}
+ // Because there can be multiple runs in the blob, we want the overall maxMinScale, and
+ // minMaxScale to make regeneration decisions. Specifically, we want the maximum minimum scale
+ // we can tolerate before we'd drop to a lower mip size, and the minimum maximum scale we can
+ // tolerate before we'd have to move to a large mip size. When we actually test these values
+ // we look at the delta in scale between the new viewmatrix and the old viewmatrix, and test
+ // against these values to decide if we can reuse or not(ie, will a given scale change our mip
+ // level)
+ blob->fMaxMinScale = SkMaxScalar(dfMaskScaleFloor / scaledTextSize, blob->fMaxMinScale);
+ blob->fMinMaxScale = SkMinScalar(dfMaskScaleCeil / scaledTextSize, blob->fMinMaxScale);
+
skPaint->setLCDRenderText(false);
skPaint->setAutohinted(false);
skPaint->setHinting(SkPaint::kNormal_Hinting);
@@ -645,7 +675,7 @@ GrAtlasTextContext::setupDFBlob(int glyphCount, const SkPaint& origPaint,
BitmapTextBlob* blob = fCache->createBlob(glyphCount, 1, kGrayTextVASize);
*dfPaint = origPaint;
- this->initDistanceFieldPaint(dfPaint, textRatio, viewMatrix);
+ this->initDistanceFieldPaint(blob, dfPaint, textRatio, viewMatrix);
blob->fViewMatrix = viewMatrix;
Run& run = blob->fRuns[0];
PerSubRunInfo& subRun = run.fSubRunInfo.back();
« no previous file with comments | « src/gpu/GrAtlasTextContext.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698