| Index: src/gpu/GrAtlasTextContext.cpp
|
| diff --git a/src/gpu/GrAtlasTextContext.cpp b/src/gpu/GrAtlasTextContext.cpp
|
| index 9dbe6312cba74834c86de0464db5f4aad0ea3538..59a875e422284e34682cdbf0a0679221f9b298d8 100644
|
| --- a/src/gpu/GrAtlasTextContext.cpp
|
| +++ b/src/gpu/GrAtlasTextContext.cpp
|
| @@ -91,13 +91,47 @@ bool GrAtlasTextContext::canDraw(const GrRenderTarget*,
|
| return !SkDraw::ShouldDrawTextAsPaths(skPaint, viewMatrix);
|
| }
|
|
|
| +GrColor GrAtlasTextContext::ComputeCanonicalColor(const SkPaint& paint, bool lcd) {
|
| + GrColor canonicalColor = paint.computeLuminanceColor();
|
| + if (lcd) {
|
| + // This is the correct computation, but there are tons of cases where LCD can be overridden.
|
| + // For now we just regenerate if any run in a textblob has LCD.
|
| + // TODO figure out where all of these overrides are and see if we can incorporate that logic
|
| + // at a higher level *OR* use sRGB
|
| + SkASSERT(false);
|
| + //canonicalColor = SkMaskGamma::CanonicalColor(canonicalColor);
|
| + } else {
|
| + // A8, though can have mixed BMP text but it shouldn't matter because BMP text won't have
|
| + // gamma corrected masks anyways, nor color
|
| + U8CPU lum = SkComputeLuminance(SkColorGetR(canonicalColor),
|
| + SkColorGetG(canonicalColor),
|
| + SkColorGetB(canonicalColor));
|
| + // reduce to our finite number of bits
|
| + canonicalColor = SkMaskGamma::CanonicalColor(SkColorSetRGB(lum, lum, lum));
|
| + }
|
| + return canonicalColor;
|
| +}
|
| +
|
| +// 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 GrAtlasTextContext::HasLCD(const SkTextBlob* blob) {
|
| + SkTextBlob::RunIterator it(blob);
|
| + for (; !it.done(); it.next()) {
|
| + if (it.isLCD()) {
|
| + return true;
|
| + }
|
| + }
|
| + return false;
|
| +}
|
| +
|
| bool GrAtlasTextContext::MustRegenerateBlob(SkScalar* outTransX, SkScalar* outTransY,
|
| const BitmapTextBlob& blob, const SkPaint& paint,
|
| const SkMaskFilter::BlurRec& blurRec,
|
| const SkMatrix& viewMatrix, SkScalar x, SkScalar y) {
|
| - // Color can affect the mask
|
| - // TODO we can adjust the color within specific gamma slots
|
| - if (blob.fColor != paint.getColor()) {
|
| + // 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
|
| + if (blob.fKey.fCanonicalColor == SK_ColorTRANSPARENT && blob.fPaintColor != paint.getColor()) {
|
| return true;
|
| }
|
|
|
| @@ -180,7 +214,6 @@ void GrAtlasTextContext::drawTextBlob(GrRenderTarget* rt, const GrClip& clip,
|
| const SkTextBlob* blob, SkScalar x, SkScalar y,
|
| SkDrawFilter* drawFilter, const SkIRect& clipBounds) {
|
| SkAutoTUnref<BitmapTextBlob> cacheBlob;
|
| -
|
| SkMaskFilter::BlurRec blurRec;
|
| BitmapTextBlob::Key key;
|
| // It might be worth caching these things, but its not clear at this time
|
| @@ -191,9 +224,17 @@ void GrAtlasTextContext::drawTextBlob(GrRenderTarget* rt, const GrClip& clip,
|
| drawFilter);
|
|
|
| if (canCache) {
|
| + bool hasLCD = HasLCD(blob);
|
| + // 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);
|
| +
|
| key.fUniqueID = blob->uniqueID();
|
| key.fStyle = skPaint.getStyle();
|
| key.fHasBlur = SkToBool(mf);
|
| + key.fCanonicalColor = canonicalColor;
|
| cacheBlob.reset(SkSafeRef(fCache->find(key)));
|
| }
|
|
|
| @@ -203,6 +244,11 @@ void GrAtlasTextContext::drawTextBlob(GrRenderTarget* rt, const GrClip& clip,
|
| SkScalar transX = 0.f;
|
| SkScalar transY = 0.f;
|
|
|
| + // Though for the time being runs in the textblob can override the paint, they only touch font
|
| + // info.
|
| + GrPaint grPaint;
|
| + SkPaint2GrPaintShader(fContext, rt, skPaint, viewMatrix, true, &grPaint);
|
| +
|
| if (cacheBlob) {
|
| if (MustRegenerateBlob(&transX, &transY, *cacheBlob, skPaint, blurRec, viewMatrix, x, y)) {
|
| // We have to remake the blob because changes may invalidate our masks.
|
| @@ -211,11 +257,11 @@ void GrAtlasTextContext::drawTextBlob(GrRenderTarget* rt, const GrClip& clip,
|
| fCache->remove(cacheBlob);
|
| cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, skPaint,
|
| kGrayTextVASize)));
|
| - this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, drawFilter,
|
| - clipRect);
|
| + this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), viewMatrix, blob, x, y,
|
| + drawFilter, clipRect);
|
| } else {
|
| - // If we can reuse the blob, then make sure we update the blob's viewmatrix and x/y
|
| - // offsets to reflect the results of any translations we may apply in generateGeometry
|
| + // If we can reuse the blob, then make sure we update the blob's viewmatrix, and x/y
|
| + // offsets
|
| cacheBlob->fViewMatrix = viewMatrix;
|
| cacheBlob->fX = x;
|
| cacheBlob->fY = y;
|
| @@ -228,26 +274,23 @@ void GrAtlasTextContext::drawTextBlob(GrRenderTarget* rt, const GrClip& clip,
|
| } else {
|
| cacheBlob.reset(fCache->createBlob(blob, kGrayTextVASize));
|
| }
|
| - this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, drawFilter, clipRect);
|
| + this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), viewMatrix, blob, x, y,
|
| + drawFilter, clipRect);
|
| }
|
|
|
| - // Though for the time being runs in the textblob can override the paint, they only touch font
|
| - // info.
|
| - GrPaint grPaint;
|
| - SkPaint2GrPaintShader(fContext, rt, skPaint, viewMatrix, true, &grPaint);
|
| -
|
| + cacheBlob->fPaintColor = skPaint.getColor();
|
| this->flush(fContext->getTextTarget(), blob, cacheBlob, rt, skPaint, grPaint, drawFilter,
|
| clip, viewMatrix, clipBounds, x, y, transX, transY);
|
| }
|
|
|
| void GrAtlasTextContext::regenerateTextBlob(BitmapTextBlob* cacheBlob,
|
| - const SkPaint& skPaint, const SkMatrix& viewMatrix,
|
| + const SkPaint& skPaint, GrColor color,
|
| + const SkMatrix& viewMatrix,
|
| const SkTextBlob* blob, SkScalar x, SkScalar y,
|
| SkDrawFilter* drawFilter, const SkIRect& clipRect) {
|
| cacheBlob->fViewMatrix = viewMatrix;
|
| cacheBlob->fX = x;
|
| cacheBlob->fY = y;
|
| - cacheBlob->fColor = skPaint.getColor();
|
|
|
| // Regenerate textblob
|
| SkPaint runPaint = skPaint;
|
| @@ -290,17 +333,17 @@ void GrAtlasTextContext::regenerateTextBlob(BitmapTextBlob* cacheBlob,
|
|
|
| switch (it.positioning()) {
|
| case SkTextBlob::kDefault_Positioning:
|
| - this->internalDrawText(cacheBlob, run, cache, runPaint, viewMatrix,
|
| + this->internalDrawText(cacheBlob, run, cache, runPaint, color, viewMatrix,
|
| (const char *)it.glyphs(), textLen,
|
| x + offset.x(), y + offset.y(), clipRect);
|
| break;
|
| case SkTextBlob::kHorizontal_Positioning:
|
| - this->internalDrawPosText(cacheBlob, run, cache, runPaint, viewMatrix,
|
| + this->internalDrawPosText(cacheBlob, run, cache, runPaint, color, viewMatrix,
|
| (const char*)it.glyphs(), textLen, it.pos(), 1,
|
| SkPoint::Make(x, y + offset.y()), clipRect);
|
| break;
|
| case SkTextBlob::kFull_Positioning:
|
| - this->internalDrawPosText(cacheBlob, run, cache, runPaint, viewMatrix,
|
| + this->internalDrawPosText(cacheBlob, run, cache, runPaint, color, viewMatrix,
|
| (const char*)it.glyphs(), textLen, it.pos(), 2,
|
| SkPoint::Make(x, y), clipRect);
|
| break;
|
| @@ -331,7 +374,8 @@ void GrAtlasTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip,
|
|
|
| // setup cache
|
| SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, viewMatrix);
|
| - this->internalDrawText(blob, 0, cache, skPaint, viewMatrix, text, byteLength, x, y, clipRect);
|
| + this->internalDrawText(blob, 0, cache, skPaint, paint.getColor(), viewMatrix, text, byteLength,
|
| + x, y, clipRect);
|
| SkGlyphCache::AttachCache(cache);
|
|
|
| this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip, viewMatrix);
|
| @@ -339,6 +383,7 @@ void GrAtlasTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip,
|
|
|
| void GrAtlasTextContext::internalDrawText(BitmapTextBlob* blob, int runIndex,
|
| SkGlyphCache* cache, const SkPaint& skPaint,
|
| + GrColor color,
|
| const SkMatrix& viewMatrix,
|
| const char text[], size_t byteLength,
|
| SkScalar x, SkScalar y, const SkIRect& clipRect) {
|
| @@ -417,7 +462,7 @@ void GrAtlasTextContext::internalDrawText(BitmapTextBlob* blob, int runIndex,
|
| GrGlyph::kCoverage_MaskStyle),
|
| Sk48Dot16FloorToInt(fx),
|
| Sk48Dot16FloorToInt(fy),
|
| - skPaint.getColor(),
|
| + color,
|
| fontScaler,
|
| clipRect);
|
| }
|
| @@ -442,8 +487,8 @@ void GrAtlasTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip,
|
|
|
| // setup cache
|
| SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, viewMatrix);
|
| - this->internalDrawPosText(blob, 0, cache, skPaint, viewMatrix, text, byteLength, pos,
|
| - scalarsPerPosition, offset, clipRect);
|
| + this->internalDrawPosText(blob, 0, cache, skPaint, paint.getColor(), viewMatrix, text,
|
| + byteLength, pos, scalarsPerPosition, offset, clipRect);
|
| SkGlyphCache::AttachCache(cache);
|
|
|
| this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip, viewMatrix);
|
| @@ -451,6 +496,7 @@ void GrAtlasTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip,
|
|
|
| void GrAtlasTextContext::internalDrawPosText(BitmapTextBlob* blob, int runIndex,
|
| SkGlyphCache* cache, const SkPaint& skPaint,
|
| + GrColor color,
|
| const SkMatrix& viewMatrix,
|
| const char text[], size_t byteLength,
|
| const SkScalar pos[], int scalarsPerPosition,
|
| @@ -508,7 +554,7 @@ void GrAtlasTextContext::internalDrawPosText(BitmapTextBlob* blob, int runIndex,
|
| GrGlyph::kCoverage_MaskStyle),
|
| Sk48Dot16FloorToInt(fx),
|
| Sk48Dot16FloorToInt(fy),
|
| - skPaint.getColor(),
|
| + color,
|
| fontScaler,
|
| clipRect);
|
| }
|
| @@ -546,7 +592,7 @@ void GrAtlasTextContext::internalDrawPosText(BitmapTextBlob* blob, int runIndex,
|
| GrGlyph::kCoverage_MaskStyle),
|
| Sk48Dot16FloorToInt(fx),
|
| Sk48Dot16FloorToInt(fy),
|
| - skPaint.getColor(),
|
| + color,
|
| fontScaler,
|
| clipRect);
|
| }
|
| @@ -574,7 +620,7 @@ void GrAtlasTextContext::internalDrawPosText(BitmapTextBlob* blob, int runIndex,
|
| GrGlyph::kCoverage_MaskStyle),
|
| Sk48Dot16FloorToInt(fx),
|
| Sk48Dot16FloorToInt(fy),
|
| - skPaint.getColor(),
|
| + color,
|
| fontScaler,
|
| clipRect);
|
| }
|
| @@ -602,7 +648,7 @@ void GrAtlasTextContext::internalDrawPosText(BitmapTextBlob* blob, int runIndex,
|
| GrGlyph::kCoverage_MaskStyle),
|
| Sk48Dot16FloorToInt(fx),
|
| Sk48Dot16FloorToInt(fy),
|
| - skPaint.getColor(),
|
| + color,
|
| fontScaler,
|
| clipRect);
|
| }
|
|
|