diff options
author | Robert Phillips <robertphillips@google.com> | 2018-06-28 12:00:35 +0000 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-06-28 12:00:47 +0000 |
commit | 385804514edf602f978975c825b78692a044c6b9 (patch) | |
tree | 891790d5b77fa447c75ec9a25487ecd8ae22c332 /src/gpu/text | |
parent | e97bb26893a1c24deeb38b818a1f4c1638a9983d (diff) |
Revert "Remove drawTextBlob from device use drawGlyphRunList"
This reverts commit e2e52e46ca63540d429656baeee48fd3a402be26.
Reason for revert: See if this is blocking the Chrome roll
Original change's description:
> Remove drawTextBlob from device use drawGlyphRunList
>
> Convert all backends to use GlyphRunList instead of
> text blobs. If the device did not originally implement
> drawTextBlob it will be simulated by drawPosText on the
> device.
>
> Other changes:
> Change to using an origin from absolulte positioning. The GPU
> code uses origin change to update blobs under translation.
>
> Change cluster to use const uint32_t instead of just
> uint32_t.
>
> Add SkPaint to runs.
>
> The draw filter is hosted up to the canavas level and applied there.
>
> Change-Id: Ib105b6bd26b67db55f1c954e37c79fbdcaa9d4a2
> Reviewed-on: https://skia-review.googlesource.com/137224
> Reviewed-by: Herb Derby <herb@google.com>
> Reviewed-by: Khusal Sagar <khushalsagar@chromium.org>
> Reviewed-by: Hal Canary <halcanary@google.com>
> Reviewed-by: Jim Van Verth <jvanverth@google.com>
> Commit-Queue: Herb Derby <herb@google.com>
TBR=jvanverth@google.com,halcanary@google.com,bungeman@google.com,herb@google.com,reed@google.com,khushalsagar@chromium.org,khushalsagar@google.com
Change-Id: I4d93a534990c89deee7d3aaa00ec40d47e0d2ece
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/138120
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src/gpu/text')
-rw-r--r-- | src/gpu/text/GrTextBlobCache.h | 14 | ||||
-rw-r--r-- | src/gpu/text/GrTextContext.cpp | 156 | ||||
-rw-r--r-- | src/gpu/text/GrTextContext.h | 14 |
3 files changed, 120 insertions, 64 deletions
diff --git a/src/gpu/text/GrTextBlobCache.h b/src/gpu/text/GrTextBlobCache.h index 7a8ea0bcfe..b41d401aee 100644 --- a/src/gpu/text/GrTextBlobCache.h +++ b/src/gpu/text/GrTextBlobCache.h @@ -55,20 +55,6 @@ public: blob->notifyAddedToCache(fUniqueID); return cacheBlob; } - sk_sp<GrTextBlob> makeBlob(SkGlyphRunList* glyphRunList) { - return GrTextBlob::Make(glyphRunList->totalGlyphCount(), glyphRunList->size()); - } - - sk_sp<GrTextBlob> makeCachedBlob(SkGlyphRunList* glyphRunList, - const GrTextBlob::Key& key, - const SkMaskFilterBase::BlurRec& blurRec, - const SkPaint& paint) { - sk_sp<GrTextBlob> cacheBlob(makeBlob(glyphRunList)); - cacheBlob->setupKey(key, blurRec, paint); - this->add(cacheBlob); - glyphRunList->temporaryShuntBlobnotifyAddedToCache(fUniqueID); - return cacheBlob; - } sk_sp<GrTextBlob> find(const GrTextBlob::Key& key) const { const auto* idEntry = fBlobIDCache.find(key.fUniqueID); diff --git a/src/gpu/text/GrTextContext.cpp b/src/gpu/text/GrTextContext.cpp index 3309d22d09..a20ba4424a 100644 --- a/src/gpu/text/GrTextContext.cpp +++ b/src/gpu/text/GrTextContext.cpp @@ -84,48 +84,58 @@ SkScalerContextFlags GrTextContext::ComputeScalerContextFlags( } } -void GrTextContext::drawGlyphRunList( - GrContext* context, GrTextUtils::Target* target, const GrClip& clip, - const SkMatrix& viewMatrix, const SkSurfaceProps& props, SkGlyphRunList* glyphRunList, - const SkIRect& clipBounds) { - SkPoint origin = glyphRunList->origin(); - - // Get the first paint to use as the key paint. - const SkPaint& skPaint = (*glyphRunList)[0].paint(); +// TODO if this function ever shows up in profiling, then we can compute this value when the +// textblob is being built and cache it. However, for the time being textblobs mostly only have 1 +// run so this is not a big deal to compute here. +bool GrTextContext::HasLCD(const SkTextBlob* blob) { + SkTextBlobRunIterator it(blob); + for (; !it.done(); it.next()) { + if (it.isLCD()) { + return true; + } + } + return false; +} +void GrTextContext::drawTextBlob(GrContext* context, GrTextUtils::Target* target, + const GrClip& clip, const SkPaint& skPaint, + const SkMatrix& viewMatrix, const SkSurfaceProps& props, + const SkTextBlob* blob, SkScalar x, SkScalar y, + SkDrawFilter* drawFilter, const SkIRect& clipBounds) { // If we have been abandoned, then don't draw if (context->abandoned()) { return; } + sk_sp<GrTextBlob> cacheBlob; SkMaskFilterBase::BlurRec blurRec; + GrTextBlob::Key key; // It might be worth caching these things, but its not clear at this time // TODO for animated mask filters, this will fill up our cache. We need a safeguard here const SkMaskFilter* mf = skPaint.getMaskFilter(); - bool canCache = glyphRunList->canCache() && !(skPaint.getPathEffect() || - (mf && !as_MFB(mf)->asABlur(&blurRec))); + bool canCache = !(skPaint.getPathEffect() || + (mf && !as_MFB(mf)->asABlur(&blurRec)) || + drawFilter); SkScalerContextFlags scalerContextFlags = ComputeScalerContextFlags(target->colorSpaceInfo()); auto glyphCache = context->contextPriv().getGlyphCache(); GrTextBlobCache* textBlobCache = context->contextPriv().getTextBlobCache(); - sk_sp<GrTextBlob> cacheBlob; - GrTextBlob::Key key; if (canCache) { - bool hasLCD = glyphRunList->anyRunsLCD(); + bool hasLCD = HasLCD(blob); // We canonicalize all non-lcd draws to use kUnknown_SkPixelGeometry SkPixelGeometry pixelGeometry = hasLCD ? props.pixelGeometry() : - kUnknown_SkPixelGeometry; + kUnknown_SkPixelGeometry; // TODO we want to figure out a way to be able to use the canonical color on LCD text, // see the note on ComputeCanonicalColor above. We pick a dummy value for LCD text to // ensure we always match the same key GrColor canonicalColor = hasLCD ? SK_ColorTRANSPARENT : - ComputeCanonicalColor(skPaint, hasLCD); + ComputeCanonicalColor(skPaint, hasLCD); key.fPixelGeometry = pixelGeometry; - key.fUniqueID = glyphRunList->uniqueID(); + key.fUniqueID = blob->uniqueID(); key.fStyle = skPaint.getStyle(); key.fHasBlur = SkToBool(mf); key.fCanonicalColor = canonicalColor; @@ -135,77 +145,135 @@ void GrTextContext::drawGlyphRunList( GrTextUtils::Paint paint(&skPaint, &target->colorSpaceInfo()); if (cacheBlob) { - if (cacheBlob->mustRegenerate(paint, blurRec, viewMatrix, origin.x(), origin.y())) { + if (cacheBlob->mustRegenerate(paint, blurRec, viewMatrix, x, 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 textBlobCache->remove(cacheBlob.get()); - cacheBlob = textBlobCache->makeCachedBlob(glyphRunList, key, blurRec, skPaint); - this->regenerateGlyphRunList(cacheBlob.get(), glyphCache, + cacheBlob = textBlobCache->makeCachedBlob(blob, key, blurRec, skPaint); + this->regenerateTextBlob(cacheBlob.get(), glyphCache, *context->contextPriv().caps()->shaderCaps(), paint, - scalerContextFlags, viewMatrix, props, glyphRunList); + scalerContextFlags, viewMatrix, props, blob, x, y, drawFilter); } else { textBlobCache->makeMRU(cacheBlob.get()); if (CACHE_SANITY_CHECK) { - int glyphCount = glyphRunList->totalGlyphCount(); - int runCount = glyphRunList->runCount(); + int glyphCount = 0; + int runCount = 0; + GrTextBlobCache::BlobGlyphCount(&glyphCount, &runCount, blob); sk_sp<GrTextBlob> sanityBlob(textBlobCache->makeBlob(glyphCount, runCount)); sanityBlob->setupKey(key, blurRec, skPaint); - this->regenerateGlyphRunList( + this->regenerateTextBlob( sanityBlob.get(), glyphCache, *context->contextPriv().caps()->shaderCaps(), - paint, scalerContextFlags, viewMatrix, props, glyphRunList); + paint, scalerContextFlags, viewMatrix, props, blob, x, y, drawFilter); GrTextBlob::AssertEqual(*sanityBlob, *cacheBlob); } } } else { if (canCache) { - cacheBlob = textBlobCache->makeCachedBlob(glyphRunList, key, blurRec, skPaint); + cacheBlob = textBlobCache->makeCachedBlob(blob, key, blurRec, skPaint); } else { - cacheBlob = textBlobCache->makeBlob(glyphRunList); + cacheBlob = textBlobCache->makeBlob(blob); } - this->regenerateGlyphRunList(cacheBlob.get(), glyphCache, + this->regenerateTextBlob(cacheBlob.get(), glyphCache, *context->contextPriv().caps()->shaderCaps(), paint, - scalerContextFlags, viewMatrix, props, glyphRunList); + scalerContextFlags, viewMatrix, props, blob, x, y, drawFilter); } cacheBlob->flush(target, props, fDistanceAdjustTable.get(), paint, - clip, viewMatrix, clipBounds, origin.x(), origin.y()); + clip, viewMatrix, clipBounds, x, y); } -void GrTextContext::regenerateGlyphRunList(GrTextBlob* cacheBlob, +void GrTextContext::regenerateTextBlob(GrTextBlob* cacheBlob, GrGlyphCache* glyphCache, const GrShaderCaps& shaderCaps, const GrTextUtils::Paint& paint, SkScalerContextFlags scalerContextFlags, const SkMatrix& viewMatrix, - const SkSurfaceProps& props, - SkGlyphRunList* glyphRunList) const { - SkPoint origin = glyphRunList->origin(); - cacheBlob->initReusableBlob(paint.luminanceColor(), viewMatrix, origin.x(), origin.y()); + const SkSurfaceProps& props, const SkTextBlob* blob, + SkScalar x, SkScalar y, + SkDrawFilter* drawFilter) const { + cacheBlob->initReusableBlob(paint.luminanceColor(), viewMatrix, x, y); // Regenerate textblob - SkGlyphRunListIterator it(glyphRunList); - GrTextUtils::RunPaint runPaint(&paint, nullptr); + SkTextBlobRunIterator it(blob); + GrTextUtils::RunPaint runPaint(&paint, drawFilter); for (int run = 0; !it.done(); it.next(), run++) { int glyphCount = it.glyphCount(); size_t textLen = glyphCount * sizeof(uint16_t); + const SkPoint& offset = it.offset(); cacheBlob->push_back_run(run); if (!runPaint.modifyForRun([it](SkPaint* p) { it.applyFontToPaint(p); })) { continue; } cacheBlob->setRunPaintFlags(run, runPaint.skPaint().getFlags()); - SkASSERT(it.positioning() == SkTextBlob::kFull_Positioning); if (CanDrawAsDistanceFields(runPaint, viewMatrix, props, shaderCaps.supportsDistanceFieldText(), fOptions)) { - this->drawDFPosText(cacheBlob, run, glyphCache, props, runPaint, - scalerContextFlags, viewMatrix, (const char*)it.glyphs(), - textLen, it.pos(), 2, origin); + switch (it.positioning()) { + case SkTextBlob::kDefault_Positioning: { + auto origin = SkPoint::Make(x + offset.x(), y + offset.y()); + SkGlyphRunBuilder builder; + builder.prepareDrawText(runPaint.skPaint(), + (const char*)it.glyphs(), textLen, origin); + + auto glyphRun = builder.useGlyphRun(); + + glyphRun->temporaryShuntToCallback( + [&](size_t runSize, const char* glyphIDs, const SkScalar* pos) { + this->drawDFPosText( + cacheBlob, run, glyphCache, props, runPaint, scalerContextFlags, + viewMatrix, glyphIDs, 2 * runSize, pos, 2, + SkPoint::Make(0,0)); + }); + break; + } + + case SkTextBlob::kHorizontal_Positioning: { + SkPoint dfOffset = SkPoint::Make(x, y + offset.y()); + this->drawDFPosText(cacheBlob, run, glyphCache, props, runPaint, + scalerContextFlags, viewMatrix, (const char*)it.glyphs(), + textLen, it.pos(), 1, dfOffset); + break; + } + case SkTextBlob::kFull_Positioning: { + SkPoint dfOffset = SkPoint::Make(x, y); + this->drawDFPosText(cacheBlob, run, glyphCache, props, runPaint, + scalerContextFlags, viewMatrix, (const char*)it.glyphs(), + textLen, it.pos(), 2, dfOffset); + break; + } + } } else { - DrawBmpPosText(cacheBlob, run, glyphCache, props, runPaint, scalerContextFlags, - viewMatrix, (const char*)it.glyphs(), textLen, it.pos(), 2, - origin); + switch (it.positioning()) { + case SkTextBlob::kDefault_Positioning: { + auto origin = SkPoint::Make(x + offset.x(), y + offset.y()); + SkGlyphRunBuilder builder; + builder.prepareDrawText(runPaint.skPaint(), + (const char*)it.glyphs(), textLen, origin); + + auto glyphRun = builder.useGlyphRun(); + + glyphRun->temporaryShuntToCallback( + [&](size_t runSize, const char* glyphIDs, const SkScalar* pos) { + this->DrawBmpPosText( + cacheBlob, run, glyphCache, props, runPaint, scalerContextFlags, + viewMatrix, glyphIDs, 2 * runSize, + pos, 2, SkPoint::Make(0, 0)); + }); + break; + } + case SkTextBlob::kHorizontal_Positioning: + DrawBmpPosText(cacheBlob, run, glyphCache, props, runPaint, scalerContextFlags, + viewMatrix, (const char*)it.glyphs(), textLen, it.pos(), 1, + SkPoint::Make(x, y + offset.y())); + break; + case SkTextBlob::kFull_Positioning: + DrawBmpPosText(cacheBlob, run, glyphCache, props, runPaint, scalerContextFlags, + viewMatrix, (const char*)it.glyphs(), textLen, it.pos(), 2, + SkPoint::Make(x, y)); + break; + } } } } @@ -265,6 +333,7 @@ void GrTextContext::drawPosText(GrContext* context, GrTextUtils::Target* target, } } + void GrTextContext::DrawBmpPosText(GrTextBlob* blob, int runIndex, GrGlyphCache* glyphCache, const SkSurfaceProps& props, const GrTextUtils::Paint& paint, @@ -717,7 +786,6 @@ std::unique_ptr<GrDrawOp> GrTextContext::createOp_TestingOnly(GrContext* context builder.prepareDrawText(skPaint, text, textLen, origin); sk_sp<GrTextBlob> blob; - // TODO - remove shunt call when removing drawPosText from device. auto glyphRun = builder.useGlyphRun(); // Use the text and textLen below, because we don't want to mess with the paint. glyphRun->temporaryShuntToCallback( diff --git a/src/gpu/text/GrTextContext.h b/src/gpu/text/GrTextContext.h index 25aeea0c7a..dd82b3ce7d 100644 --- a/src/gpu/text/GrTextContext.h +++ b/src/gpu/text/GrTextContext.h @@ -48,9 +48,9 @@ public: const SkMatrix& viewMatrix, const SkSurfaceProps&, const char text[], size_t byteLength, const SkScalar pos[], int scalarsPerPosition, const SkPoint& offset, const SkIRect& regionClipBounds); - void drawGlyphRunList(GrContext*, GrTextUtils::Target*, const GrClip&, - const SkMatrix& viewMatrix, const SkSurfaceProps&, SkGlyphRunList*, - const SkIRect& clipBounds); + void drawTextBlob(GrContext*, GrTextUtils::Target*, const GrClip&, const SkPaint&, + const SkMatrix& viewMatrix, const SkSurfaceProps&, const SkTextBlob*, + SkScalar x, SkScalar y, SkDrawFilter*, const SkIRect& clipBounds); std::unique_ptr<GrDrawOp> createOp_TestingOnly(GrContext*, GrTextContext*, @@ -115,15 +115,17 @@ private: static SkColor ComputeCanonicalColor(const SkPaint&, bool lcd); // Determines if we need to use fake gamma (and contrast boost): static SkScalerContextFlags ComputeScalerContextFlags(const GrColorSpaceInfo&); - - void regenerateGlyphRunList(GrTextBlob* bmp, + void regenerateTextBlob(GrTextBlob* bmp, GrGlyphCache*, const GrShaderCaps&, const GrTextUtils::Paint&, SkScalerContextFlags scalerContextFlags, const SkMatrix& viewMatrix, const SkSurfaceProps&, - SkGlyphRunList* glyphRunList) const; + const SkTextBlob* blob, SkScalar x, SkScalar y, + SkDrawFilter* drawFilter) const; + + static bool HasLCD(const SkTextBlob*); sk_sp<GrTextBlob> makeDrawPosTextBlob(GrTextBlobCache*, GrGlyphCache*, const GrShaderCaps&, |