Inline fallback code
Change-Id: I49adc018dc4b486edb7be8aa55f86f248bb39c83 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/251212 Reviewed-by: Ben Wagner <bungeman@google.com> Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
parent
aacbd44cad
commit
9e1909f03d
@ -122,94 +122,6 @@ void SkGlyphRunListPainter::drawForBitmapDevice(
|
||||
}
|
||||
}
|
||||
|
||||
// Getting glyphs to the screen in a fallback situation can be complex. Here is the set of
|
||||
// transformations that have to happen. Normally, they would all be accommodated by the font
|
||||
// scaler, but the atlas has an upper limit to the glyphs it can handle. So the GPU is used to
|
||||
// make up the difference from the smaller atlas size to the larger size needed by the final
|
||||
// transform. Here are the transformations that are applied.
|
||||
//
|
||||
// final transform = [view matrix] * [text scale] * [text size]
|
||||
//
|
||||
// There are three cases:
|
||||
// * Go Fast - view matrix is scale and translate, and all the glyphs are small enough
|
||||
// Just scale the positions, and have the glyph cache handle the view matrix transformation.
|
||||
// The text scale is 1.
|
||||
// * It's complicated - view matrix is not scale and translate, and the glyphs are small enough
|
||||
// The glyph cache does not handle the view matrix, but stores the glyphs at the text size
|
||||
// specified by the run paint. The GPU handles the rotation, etc. specified by the view matrix.
|
||||
// The text scale is 1.
|
||||
// * Too big - The glyphs are too big to fit in the atlas
|
||||
// Reduce the text size so the glyphs will fit in the atlas, but don't apply any
|
||||
// transformations from the view matrix. Calculate a text scale based on that reduction. This
|
||||
// scale factor is used to increase the size of the destination rectangles. The destination
|
||||
// rectangles are then scaled, rotated, etc. by the GPU using the view matrix.
|
||||
void SkGlyphRunListPainter::processARGBFallback(SkScalar maxSourceGlyphDimension,
|
||||
const SkPaint& runPaint,
|
||||
const SkFont& runFont,
|
||||
SkPoint origin,
|
||||
const SkMatrix& viewMatrix,
|
||||
SkGlyphRunPainterInterface* process) {
|
||||
// if maxSourceGlyphDimension then no pixels will change.
|
||||
if (maxSourceGlyphDimension == 0) { return; }
|
||||
|
||||
SkScalar maxScale = viewMatrix.getMaxScale();
|
||||
|
||||
// This is a linear estimate of the longest dimension among all the glyph widths and heights.
|
||||
SkScalar conservativeMaxGlyphDimension = maxSourceGlyphDimension * maxScale;
|
||||
|
||||
// If the situation that the matrix is simple, and all the glyphs are small enough. Go fast!
|
||||
// N.B. If the matrix has scale, that will be reflected in the strike through the viewMatrix
|
||||
// in the useFastPath case.
|
||||
bool useDeviceCache =
|
||||
viewMatrix.isScaleTranslate()
|
||||
&& conservativeMaxGlyphDimension <= SkStrikeCommon::kSkSideTooBigForAtlas;
|
||||
|
||||
// A scaled and translated transform is the common case, and is handled directly in fallback.
|
||||
// Even if the transform is scale and translate, fallback must be careful to use glyphs that
|
||||
// fit in the atlas. If a glyph will not fit in the atlas, then the general transform case is
|
||||
// used to render the glyphs.
|
||||
if (useDeviceCache) {
|
||||
SkStrikeSpec strikeSpec = SkStrikeSpec::MakeMask(
|
||||
runFont, runPaint, fDeviceProps, fScalerContextFlags, viewMatrix);
|
||||
|
||||
SkScopedStrikeForGPU strike = strikeSpec.findOrCreateScopedStrike(fStrikeCache);
|
||||
|
||||
fDrawable.startDevice(fRejects.source(), origin, viewMatrix, strike->roundingSpec());
|
||||
|
||||
strike->prepareForMaskDrawing(&fDrawable, &fRejects);
|
||||
// There better not be any rejects.
|
||||
fRejects.flipRejectsToSource();
|
||||
SkASSERT(fRejects.source().empty());
|
||||
|
||||
if (process) {
|
||||
process->processDeviceFallback(fDrawable.drawable(), strikeSpec);
|
||||
}
|
||||
|
||||
} else {
|
||||
// If the matrix is complicated or if scaling is used to fit the glyphs in the cache,
|
||||
// then this case is used.
|
||||
|
||||
SkStrikeSpec strikeSpec = SkStrikeSpec::MakeSourceFallback(
|
||||
runFont, runPaint, fDeviceProps, fScalerContextFlags, maxSourceGlyphDimension);
|
||||
|
||||
SkScopedStrikeForGPU strike = strikeSpec.findOrCreateScopedStrike(fStrikeCache);
|
||||
|
||||
fDrawable.startSource(fRejects.source(), origin);
|
||||
|
||||
strike->prepareForMaskDrawing(&fDrawable, &fRejects);
|
||||
// There better not be any rejects.
|
||||
fRejects.flipRejectsToSource();
|
||||
SkASSERT(fRejects.source().empty());
|
||||
|
||||
if (process) {
|
||||
process->processSourceFallback(
|
||||
fDrawable.drawable(),
|
||||
strikeSpec,
|
||||
viewMatrix.hasPerspective());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
void SkGlyphRunListPainter::processGlyphRunList(const SkGlyphRunList& glyphRunList,
|
||||
const SkMatrix& viewMatrix,
|
||||
@ -302,10 +214,88 @@ void SkGlyphRunListPainter::processGlyphRunList(const SkGlyphRunList& glyphRunLi
|
||||
}
|
||||
}
|
||||
|
||||
// Handle fallback for all cases.
|
||||
if (!fRejects.source().empty()) {
|
||||
this->processARGBFallback(
|
||||
maxDimensionInSourceSpace, runPaint, runFont, origin, viewMatrix, process);
|
||||
// Getting glyphs to the screen in a fallback situation can be complex. Here is the set of
|
||||
// transformations that have to happen. Normally, they would all be accommodated by the font
|
||||
// scaler, but the atlas has an upper limit to the glyphs it can handle. So the GPU is used
|
||||
// to make up the difference from the smaller atlas size to the larger size needed by the
|
||||
// final transform. Here are the transformations that are applied.
|
||||
//
|
||||
// final transform = [view matrix] * [text scale] * [text size]
|
||||
//
|
||||
// There are three cases:
|
||||
// * Go Fast - view matrix is scale and translate, and all the glyphs are small enough
|
||||
// Just scale the positions, and have the glyph cache handle the view matrix
|
||||
// transformation.
|
||||
// The text scale is 1.
|
||||
// * It's complicated - view matrix is not scale and translate, and the glyphs are small
|
||||
// enough The glyph cache does not handle the view matrix, but stores the glyphs at the
|
||||
// text size specified by the run paint. The GPU handles the rotation, etc. specified
|
||||
// by the view matrix.
|
||||
// The text scale is 1.
|
||||
// * Too big - The glyphs are too big to fit in the atlas
|
||||
// Reduce the text size so the glyphs will fit in the atlas, but don't apply any
|
||||
// transformations from the view matrix. Calculate a text scale based on that reduction.
|
||||
// This scale factor is used to increase the size of the destination rectangles. The
|
||||
// destination rectangles are then scaled, rotated, etc. by the GPU using the view matrix.
|
||||
|
||||
if (!fRejects.source().empty() && maxDimensionInSourceSpace != 0) {
|
||||
|
||||
SkScalar maxScale = viewMatrix.getMaxScale();
|
||||
|
||||
// This is a linear estimate of the longest dimension among all the glyph widths and
|
||||
// heights.
|
||||
SkScalar conservativeMaxGlyphDimension = maxDimensionInSourceSpace * maxScale;
|
||||
|
||||
// If the situation that the matrix is simple, and all the glyphs are small enough.
|
||||
// Go fast!
|
||||
// N.B. If the matrix has scale, that will be reflected in the strike through the
|
||||
// viewMatrix in the useFastPath case.
|
||||
bool useDeviceCache =
|
||||
viewMatrix.isScaleTranslate()
|
||||
&& conservativeMaxGlyphDimension <= SkStrikeCommon::kSkSideTooBigForAtlas;
|
||||
|
||||
// A scaled and translated transform is the common case, and is handled directly in
|
||||
// fallback. Even if the transform is scale and translate, fallback must be careful
|
||||
// to use glyphs that fit in the atlas. If a glyph will not fit in the atlas, then
|
||||
// the general transform case is used to render the glyphs.
|
||||
if (useDeviceCache) {
|
||||
SkStrikeSpec strikeSpec = SkStrikeSpec::MakeMask(
|
||||
runFont, runPaint, fDeviceProps, fScalerContextFlags, viewMatrix);
|
||||
|
||||
SkScopedStrikeForGPU strike = strikeSpec.findOrCreateScopedStrike(fStrikeCache);
|
||||
|
||||
fDrawable.startDevice(
|
||||
fRejects.source(), origin, viewMatrix, strike->roundingSpec());
|
||||
|
||||
strike->prepareForMaskDrawing(&fDrawable, &fRejects);
|
||||
fRejects.flipRejectsToSource();
|
||||
SkASSERT(fRejects.source().empty());
|
||||
|
||||
if (process) {
|
||||
process->processDeviceFallback(fDrawable.drawable(), strikeSpec);
|
||||
}
|
||||
} else {
|
||||
// If the matrix is complicated or if scaling is used to fit the glyphs in the
|
||||
// atlas, then this case is used.
|
||||
|
||||
SkStrikeSpec strikeSpec = SkStrikeSpec::MakeSourceFallback(
|
||||
runFont, runPaint, fDeviceProps,
|
||||
fScalerContextFlags, maxDimensionInSourceSpace);
|
||||
|
||||
SkScopedStrikeForGPU strike = strikeSpec.findOrCreateScopedStrike(fStrikeCache);
|
||||
|
||||
fDrawable.startSource(fRejects.source(), origin);
|
||||
strike->prepareForMaskDrawing(&fDrawable, &fRejects);
|
||||
fRejects.flipRejectsToSource();
|
||||
SkASSERT(fRejects.source().empty());
|
||||
|
||||
if (process) {
|
||||
process->processSourceFallback(
|
||||
fDrawable.drawable(),
|
||||
strikeSpec,
|
||||
viewMatrix.hasPerspective());
|
||||
}
|
||||
}
|
||||
}
|
||||
} // For all glyph runs
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user