Move ARGB fallback helper into Painter
Currently, the fallback helper is a static used by the GPU code to handle fallback glyphs. This code must be common to both GPU and Renderer so it needs to be in the Painter. Change-Id: I367a87b1dc785d67996a13ee42d74f2162c1b765 Reviewed-on: https://skia-review.googlesource.com/157300 Reviewed-by: Ben Wagner <bungeman@google.com> Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
parent
b6ef9e43d7
commit
93ba1e0041
@ -413,8 +413,6 @@ void GrTextContext::AppendGlyph(GrTextBlob* blob, int runIndex,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum NeedsTransform : bool {kTransformDone = false, kDoTransform = true };
|
|
||||||
|
|
||||||
// Getting glyphs to the screen in a fallback situation can be complex. Here is the set of
|
// 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
|
// 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
|
// scaler, but the atlas has an upper limit to the glyphs it can handle. So the GPU is used to
|
||||||
@ -437,49 +435,37 @@ enum NeedsTransform : bool {kTransformDone = false, kDoTransform = true };
|
|||||||
// scale factor is used to increase the size of the destination rectangles. The destination
|
// 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.
|
// rectangles are then scaled, rotated, etc. by the GPU using the view matrix.
|
||||||
|
|
||||||
using ARGBFallback =
|
void SkGlyphRunListPainter::processARGBFallback(
|
||||||
std::function<void(const SkPaint& fallbackPaint, // The run paint maybe with a new text size
|
SkScalar maxGlyphDimension, const SkPaint& runPaint, SkPoint origin,
|
||||||
SkSpan<const SkGlyphID> fallbackGlyphIDs, // Colored glyphs that need to be handled
|
const SkMatrix& viewMatrix, SkScalar textScale, ARGBFallback argbFallback) {
|
||||||
SkSpan<const SkPoint> fallbackPositions, // Positions of above glyphs
|
SkASSERT(!fARGBGlyphsIDs.empty());
|
||||||
SkScalar fallbackTextScale, // Factor to go from text size to final size
|
|
||||||
const SkMatrix& glyphCacheMatrix, // Transformation performed by the glyph cache
|
|
||||||
NeedsTransform handleTransformLater)>;
|
|
||||||
|
|
||||||
static void ARGB_fallback_helper(
|
|
||||||
SkSpan<const SkGlyphID> glyphIDs,
|
|
||||||
SkSpan<const SkPoint> positions,
|
|
||||||
SkScalar maxGlyphDimension,
|
|
||||||
const SkPaint& runPaint,
|
|
||||||
const SkMatrix& viewMatrix,
|
|
||||||
SkScalar pathScale,
|
|
||||||
ARGBFallback fallback) {
|
|
||||||
SkASSERT(!glyphIDs.empty());
|
|
||||||
|
|
||||||
SkScalar maxScale = viewMatrix.getMaxScale();
|
SkScalar maxScale = viewMatrix.getMaxScale();
|
||||||
|
|
||||||
// This is a conservative estimate of the longest dimension among all the glyph widths and
|
// This is a conservative estimate of the longest dimension among all the glyph widths and
|
||||||
// heights.
|
// heights.
|
||||||
SkScalar conservativeMaxGlyphDimension = maxGlyphDimension * pathScale * maxScale;
|
SkScalar conservativeMaxGlyphDimension = maxGlyphDimension * textScale * maxScale;
|
||||||
|
|
||||||
// If the situation that the matrix is simple, and all the glyphs are small enough. Go fast!
|
// If the situation that the matrix is simple, and all the glyphs are small enough. Go fast!
|
||||||
bool useFastPath =
|
bool useFastPath =
|
||||||
viewMatrix.isScaleTranslate() && conservativeMaxGlyphDimension <= maxGlyphDimension;
|
viewMatrix.isScaleTranslate() && conservativeMaxGlyphDimension <= maxGlyphDimension;
|
||||||
|
|
||||||
|
auto glyphIDs = SkSpan<const SkGlyphID>{fARGBGlyphsIDs};
|
||||||
|
|
||||||
// A scaled and translated transform is the common case, and is handled directly in fallback.
|
// 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
|
// 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
|
// fit in the atlas. If a glyph will not fit in the atlas, then the general transform case is
|
||||||
// used to render the glyphs.
|
// used to render the glyphs.
|
||||||
if (useFastPath) {
|
if (useFastPath) {
|
||||||
// Translate the positions to device space.
|
// Translate the positions to device space.
|
||||||
std::vector<SkPoint> transformedPositions{positions.begin(), positions.end()};
|
viewMatrix.mapPoints(fARGBPositions.data(), fARGBPositions.size());
|
||||||
viewMatrix.mapPoints(transformedPositions.data(), transformedPositions.size());
|
for (SkPoint& point : fARGBPositions) {
|
||||||
for (SkPoint& point : transformedPositions) {
|
|
||||||
point.fX = SkScalarFloorToScalar(point.fX);
|
point.fX = SkScalarFloorToScalar(point.fX);
|
||||||
point.fY = SkScalarFloorToScalar(point.fY);
|
point.fY = SkScalarFloorToScalar(point.fY);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pos = SkSpan<const SkPoint>{transformedPositions};
|
auto positions = SkSpan<const SkPoint>{fARGBPositions};
|
||||||
fallback(runPaint, glyphIDs, pos, SK_Scalar1, viewMatrix, kTransformDone);
|
argbFallback(runPaint, glyphIDs, positions, SK_Scalar1, viewMatrix, kTransformDone);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// If the matrix is complicated or if scaling is used to fit the glyphs in the cache,
|
// If the matrix is complicated or if scaling is used to fit the glyphs in the cache,
|
||||||
@ -508,13 +494,12 @@ static void ARGB_fallback_helper(
|
|||||||
SkPaint fallbackPaint{runPaint};
|
SkPaint fallbackPaint{runPaint};
|
||||||
fallbackPaint.setTextSize(fallbackTextSize);
|
fallbackPaint.setTextSize(fallbackTextSize);
|
||||||
SkScalar fallbackTextScale = runPaintTextSize / fallbackTextSize;
|
SkScalar fallbackTextScale = runPaintTextSize / fallbackTextSize;
|
||||||
|
auto positions = SkSpan<const SkPoint>{fARGBPositions};
|
||||||
fallback(
|
argbFallback(
|
||||||
fallbackPaint, glyphIDs, positions, fallbackTextScale, SkMatrix::I(), kDoTransform);
|
fallbackPaint, glyphIDs, positions, fallbackTextScale, SkMatrix::I(), kDoTransform);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GrTextContext::regenerateGlyphRunList(GrTextBlob* cacheBlob,
|
void GrTextContext::regenerateGlyphRunList(GrTextBlob* cacheBlob,
|
||||||
GrGlyphCache* glyphCache,
|
GrGlyphCache* glyphCache,
|
||||||
const GrShaderCaps& shaderCaps,
|
const GrShaderCaps& shaderCaps,
|
||||||
@ -622,7 +607,8 @@ void GrTextContext::regenerateGlyphRunList(GrTextBlob* cacheBlob,
|
|||||||
[blob{cacheBlob}, runIndex, props, scalerContextFlags, glyphCache, filteredColor]
|
[blob{cacheBlob}, runIndex, props, scalerContextFlags, glyphCache, filteredColor]
|
||||||
(const SkPaint& fallbackPaint, SkSpan<const SkGlyphID> glyphIDs,
|
(const SkPaint& fallbackPaint, SkSpan<const SkGlyphID> glyphIDs,
|
||||||
SkSpan<const SkPoint> positions, SkScalar textScale,
|
SkSpan<const SkPoint> positions, SkScalar textScale,
|
||||||
const SkMatrix& glyphCacheMatrix, NeedsTransform needsTransform) {
|
const SkMatrix& glyphCacheMatrix,
|
||||||
|
SkGlyphRunListPainter::NeedsTransform needsTransform) {
|
||||||
blob->initOverride(runIndex);
|
blob->initOverride(runIndex);
|
||||||
blob->setHasBitmap();
|
blob->setHasBitmap();
|
||||||
blob->setSubRunHasW(runIndex, glyphCacheMatrix.hasPerspective());
|
blob->setSubRunHasW(runIndex, glyphCacheMatrix.hasPerspective());
|
||||||
@ -641,18 +627,8 @@ void GrTextContext::regenerateGlyphRunList(GrTextBlob* cacheBlob,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Calculate paint, matrix, scale and positions for the fallback glyphs.
|
|
||||||
auto fallbackARGB = [&runPaint, &viewMatrix, textScale, argbFallback]
|
|
||||||
(SkSpan<const SkGlyphID> glyphIDs,
|
|
||||||
SkSpan<const SkPoint>positions,
|
|
||||||
SkScalar maxGlyphDimension) {
|
|
||||||
|
|
||||||
ARGB_fallback_helper(glyphIDs, positions, maxGlyphDimension, runPaint,
|
|
||||||
viewMatrix, textScale, argbFallback);
|
|
||||||
};
|
|
||||||
|
|
||||||
glyphPainter->drawGlyphRunAsPathWithARGBFallback(
|
glyphPainter->drawGlyphRunAsPathWithARGBFallback(
|
||||||
pathCache.get(), glyphRun, origin, perPath, fallbackARGB);
|
pathCache.get(), glyphRun, origin, viewMatrix, textScale, perPath, argbFallback);
|
||||||
} else {
|
} else {
|
||||||
// Ensure the blob is set for bitmaptext
|
// Ensure the blob is set for bitmaptext
|
||||||
cacheBlob->setHasBitmap();
|
cacheBlob->setHasBitmap();
|
||||||
|
@ -46,16 +46,27 @@ public:
|
|||||||
SkPoint origin, const SkMatrix& deviceMatrix,
|
SkPoint origin, const SkMatrix& deviceMatrix,
|
||||||
PerGlyphT perGlyph, PerPathT perPath);
|
PerGlyphT perGlyph, PerPathT perPath);
|
||||||
|
|
||||||
|
enum NeedsTransform : bool { kTransformDone = false, kDoTransform = true };
|
||||||
|
|
||||||
|
using ARGBFallback =
|
||||||
|
std::function<void(const SkPaint& fallbackPaint, // The run paint maybe with a new text size
|
||||||
|
SkSpan<const SkGlyphID> fallbackGlyphIDs, // Colored glyphs
|
||||||
|
SkSpan<const SkPoint> fallbackPositions, // Positions of above glyphs
|
||||||
|
SkScalar fallbackTextScale, // Scale factor for glyph
|
||||||
|
const SkMatrix& glyphCacheMatrix, // Matrix of glyph cache
|
||||||
|
NeedsTransform handleTransformLater)>; // Positions / glyph transformed
|
||||||
|
|
||||||
// Draw glyphs as paths with fallback to scaled ARGB glyphs if color is needed.
|
// Draw glyphs as paths with fallback to scaled ARGB glyphs if color is needed.
|
||||||
// PerPath - perPath(const SkGlyph&, SkPoint position)
|
// PerPath - perPath(const SkGlyph&, SkPoint position)
|
||||||
// FallbackARGB - fallbackARGB(SkSpan<const SkGlyphID>, SkSpan<const SkPoint>)
|
// FallbackARGB - fallbackARGB(SkSpan<const SkGlyphID>, SkSpan<const SkPoint>)
|
||||||
// For each glyph that is not ARGB call perPath. If the glyph is ARGB then store the glyphID
|
// For each glyph that is not ARGB call perPath. If the glyph is ARGB then store the glyphID
|
||||||
// and the position in fallback vectors. After all the glyphs are processed, pass the
|
// and the position in fallback vectors. After all the glyphs are processed, pass the
|
||||||
// fallback glyphIDs and positions to fallbackARGB.
|
// fallback glyphIDs and positions to fallbackARGB.
|
||||||
template <typename PerPath, typename FallbackARGB>
|
template <typename PerPath>
|
||||||
void drawGlyphRunAsPathWithARGBFallback(
|
void drawGlyphRunAsPathWithARGBFallback(
|
||||||
SkGlyphCacheInterface* cache, const SkGlyphRun& glyphRun,
|
SkGlyphCacheInterface* cache, const SkGlyphRun& glyphRun,
|
||||||
SkPoint origin, PerPath perPath, FallbackARGB fallbackARGB);
|
SkPoint origin, const SkMatrix& viewMatrix, SkScalar textScale,
|
||||||
|
PerPath perPath, ARGBFallback fallbackARGB);
|
||||||
|
|
||||||
template <typename PerSDFT, typename PerPathT, typename PerFallbackT>
|
template <typename PerSDFT, typename PerPathT, typename PerFallbackT>
|
||||||
void drawGlyphRunAsSDFWithFallback(
|
void drawGlyphRunAsSDFWithFallback(
|
||||||
@ -67,6 +78,9 @@ private:
|
|||||||
static bool ShouldDrawAsPath(const SkPaint& paint, const SkMatrix& matrix);
|
static bool ShouldDrawAsPath(const SkPaint& paint, const SkMatrix& matrix);
|
||||||
bool ensureBitmapBuffers(size_t runSize);
|
bool ensureBitmapBuffers(size_t runSize);
|
||||||
|
|
||||||
|
void processARGBFallback(
|
||||||
|
SkScalar maxGlyphDimension, const SkPaint& runPaint, SkPoint origin,
|
||||||
|
const SkMatrix& viewMatrix, SkScalar textScale, ARGBFallback argbFallback);
|
||||||
|
|
||||||
template <typename EachGlyph>
|
template <typename EachGlyph>
|
||||||
void forEachMappedDrawableGlyph(
|
void forEachMappedDrawableGlyph(
|
||||||
@ -91,6 +105,10 @@ private:
|
|||||||
const SkScalerContextFlags fScalerContextFlags;
|
const SkScalerContextFlags fScalerContextFlags;
|
||||||
size_t fMaxRunSize{0};
|
size_t fMaxRunSize{0};
|
||||||
SkAutoTMalloc<SkPoint> fPositions;
|
SkAutoTMalloc<SkPoint> fPositions;
|
||||||
|
|
||||||
|
// Vectors for tracking ARGB fallback information.
|
||||||
|
std::vector<SkGlyphID> fARGBGlyphsIDs;
|
||||||
|
std::vector<SkPoint> fARGBPositions;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline static SkRect rect_to_draw(
|
inline static SkRect rect_to_draw(
|
||||||
@ -143,17 +161,17 @@ void SkGlyphRunListPainter::forEachMappedDrawableGlyph(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename PerPathT, typename FallbackARGB>
|
template <typename PerPathT>
|
||||||
void SkGlyphRunListPainter::drawGlyphRunAsPathWithARGBFallback(
|
void SkGlyphRunListPainter::drawGlyphRunAsPathWithARGBFallback(
|
||||||
SkGlyphCacheInterface* pathCache, const SkGlyphRun& glyphRun,
|
SkGlyphCacheInterface* pathCache, const SkGlyphRun& glyphRun,
|
||||||
SkPoint origin, PerPathT perPath, FallbackARGB fallbackARGB) {
|
SkPoint origin, const SkMatrix& viewMatrix, SkScalar textScale,
|
||||||
std::vector<SkGlyphID> fallbackGlyphIDs;
|
PerPathT perPath, ARGBFallback argbFallback) {
|
||||||
std::vector<SkPoint> fallbackPositions;
|
fARGBGlyphsIDs.clear();
|
||||||
|
fARGBPositions.clear();
|
||||||
SkScalar maxFallbackDimension{-SK_ScalarInfinity};
|
SkScalar maxFallbackDimension{-SK_ScalarInfinity};
|
||||||
|
|
||||||
auto eachGlyph =
|
auto eachGlyph =
|
||||||
[pathCache, origin, perPath{std::move(perPath)},
|
[this, pathCache, origin, perPath{std::move(perPath)}, &maxFallbackDimension]
|
||||||
&fallbackGlyphIDs, &fallbackPositions, &maxFallbackDimension]
|
|
||||||
(SkGlyphID glyphID, SkPoint position) {
|
(SkGlyphID glyphID, SkPoint position) {
|
||||||
if (SkScalarsAreFinite(position.x(), position.y())) {
|
if (SkScalarsAreFinite(position.x(), position.y())) {
|
||||||
const SkGlyph& glyph = pathCache->getGlyphMetrics(glyphID, {0, 0});
|
const SkGlyph& glyph = pathCache->getGlyphMetrics(glyphID, {0, 0});
|
||||||
@ -163,8 +181,8 @@ void SkGlyphRunListPainter::drawGlyphRunAsPathWithARGBFallback(
|
|||||||
} else {
|
} else {
|
||||||
SkScalar largestDimension = std::max(glyph.fWidth, glyph.fHeight);
|
SkScalar largestDimension = std::max(glyph.fWidth, glyph.fHeight);
|
||||||
maxFallbackDimension = std::max(maxFallbackDimension, largestDimension);
|
maxFallbackDimension = std::max(maxFallbackDimension, largestDimension);
|
||||||
fallbackGlyphIDs.push_back(glyphID);
|
fARGBGlyphsIDs.push_back(glyphID);
|
||||||
fallbackPositions.push_back(position);
|
fARGBPositions.push_back(position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,10 +190,10 @@ void SkGlyphRunListPainter::drawGlyphRunAsPathWithARGBFallback(
|
|||||||
|
|
||||||
glyphRun.forEachGlyphAndPosition(eachGlyph);
|
glyphRun.forEachGlyphAndPosition(eachGlyph);
|
||||||
|
|
||||||
if (!fallbackGlyphIDs.empty()) {
|
if (!fARGBGlyphsIDs.empty()) {
|
||||||
fallbackARGB(SkSpan<const SkGlyphID>{fallbackGlyphIDs},
|
this->processARGBFallback(
|
||||||
SkSpan<const SkPoint>{fallbackPositions},
|
maxFallbackDimension, glyphRun.paint(), origin, viewMatrix, textScale, argbFallback);
|
||||||
maxFallbackDimension);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user