Optimize GPU text regen for full pixel position text
If the GrTextBlob does not contain any subpixel position text, then any translation is ok. This is because all positions and SkGlyphCache entries will be aligned to pixel boundaries. Change-Id: Ie2bfd72710295b98c65052a857b6bd33a4858b65 Reviewed-on: https://skia-review.googlesource.com/c/162860 Commit-Queue: Herb Derby <herb@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
b093c82b0f
commit
0edb2149e4
@ -104,6 +104,15 @@ bool SkGlyphRunList::anyRunsLCD() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SkGlyphRunList::anyRunsSubpixelPositioned() const {
|
||||
for (const auto& r : fGlyphRuns) {
|
||||
if (r.paint().isSubpixelText()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SkGlyphRunList::temporaryShuntBlobNotifyAddedToCache(uint32_t cacheID) const {
|
||||
SkASSERT(fOriginalTextBlob != nullptr);
|
||||
fOriginalTextBlob->notifyAddedToCache(cacheID);
|
||||
|
@ -151,6 +151,7 @@ public:
|
||||
|
||||
uint64_t uniqueID() const;
|
||||
bool anyRunsLCD() const;
|
||||
bool anyRunsSubpixelPositioned() const;
|
||||
void temporaryShuntBlobNotifyAddedToCache(uint32_t cacheID) const;
|
||||
|
||||
bool canCache() const { return fOriginalTextBlob != nullptr; }
|
||||
|
@ -388,7 +388,8 @@ void GrTextContext::drawGlyphRunList(
|
||||
}
|
||||
|
||||
if (cacheBlob) {
|
||||
if (cacheBlob->mustRegenerate(listPaint, blurRec, viewMatrix, origin.x(), origin.y())) {
|
||||
if (cacheBlob->mustRegenerate(listPaint, glyphRunList.anyRunsSubpixelPositioned(),
|
||||
blurRec, viewMatrix, origin.x(),origin.y())) {
|
||||
// We have to remake the blob because changes may invalidate our masks.
|
||||
// TODO we could probably get away reuse most of the time if the pointer is unique,
|
||||
// but we'd have to clear the subrun information
|
||||
|
@ -144,9 +144,9 @@ void GrTextBlob::appendPathGlyph(int runIndex, const SkPath& path, SkScalar x, S
|
||||
run.fPathGlyphs.push_back(GrTextBlob::Run::PathGlyph(path, x, y, scale, preTransformed));
|
||||
}
|
||||
|
||||
bool GrTextBlob::mustRegenerate(const SkPaint& paint,
|
||||
const SkMaskFilterBase::BlurRec& blurRec,
|
||||
const SkMatrix& viewMatrix, SkScalar x, SkScalar y) {
|
||||
bool GrTextBlob::mustRegenerate(const SkPaint& paint, bool anyRunHasSubpixelPosition,
|
||||
const SkMaskFilterBase::BlurRec& blurRec,
|
||||
const SkMatrix& viewMatrix, SkScalar x, SkScalar y) {
|
||||
// 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
|
||||
@ -196,20 +196,22 @@ bool GrTextBlob::mustRegenerate(const SkPaint& paint,
|
||||
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
|
||||
// generated vertex coordinates to move them to the correct position
|
||||
SkScalar transX = viewMatrix.getTranslateX() +
|
||||
viewMatrix.getScaleX() * (x - fInitialX) +
|
||||
viewMatrix.getSkewX() * (y - fInitialY) -
|
||||
fInitialViewMatrix.getTranslateX();
|
||||
SkScalar transY = viewMatrix.getTranslateY() +
|
||||
viewMatrix.getSkewY() * (x - fInitialX) +
|
||||
viewMatrix.getScaleY() * (y - fInitialY) -
|
||||
fInitialViewMatrix.getTranslateY();
|
||||
if (!SkScalarIsInt(transX) || !SkScalarIsInt(transY)) {
|
||||
return true;
|
||||
if (!anyRunHasSubpixelPosition) {
|
||||
// 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 generated vertex coordinates to move them to the correct position.
|
||||
SkScalar transX = viewMatrix.getTranslateX() +
|
||||
viewMatrix.getScaleX() * (x - fInitialX) +
|
||||
viewMatrix.getSkewX() * (y - fInitialY) -
|
||||
fInitialViewMatrix.getTranslateX();
|
||||
SkScalar transY = viewMatrix.getTranslateY() +
|
||||
viewMatrix.getSkewY() * (x - fInitialX) +
|
||||
viewMatrix.getScaleY() * (y - fInitialY) -
|
||||
fInitialViewMatrix.getTranslateY();
|
||||
if (!SkScalarIsInt(transX) || !SkScalarIsInt(transY)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (this->hasDistanceField()) {
|
||||
// A scale outside of [blob.fMaxMinScale, blob.fMinMaxScale] would result in a different
|
||||
|
@ -196,7 +196,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool mustRegenerate(const SkPaint&, const SkMaskFilterBase::BlurRec& blurRec,
|
||||
bool mustRegenerate(const SkPaint&, bool, const SkMaskFilterBase::BlurRec& blurRec,
|
||||
const SkMatrix& viewMatrix, SkScalar x, SkScalar y);
|
||||
|
||||
void flush(GrTextTarget*, const SkSurfaceProps& props,
|
||||
|
Loading…
Reference in New Issue
Block a user