| Index: src/gpu/text/GrAtlasTextContext.cpp
|
| diff --git a/src/gpu/text/GrAtlasTextContext.cpp b/src/gpu/text/GrAtlasTextContext.cpp
|
| index ac2df24e48144abb62f62473c495c63cd488fcb9..8f45731bc3289ab16cbd31679de185420dc31316 100644
|
| --- a/src/gpu/text/GrAtlasTextContext.cpp
|
| +++ b/src/gpu/text/GrAtlasTextContext.cpp
|
| @@ -8,53 +8,27 @@
|
|
|
| #include "GrDrawContext.h"
|
| #include "GrDrawTarget.h"
|
| -#include "GrFontScaler.h"
|
| -#include "GrStrokeInfo.h"
|
| #include "GrTextBlobCache.h"
|
| -#include "GrTexturePriv.h"
|
| #include "GrTextUtils.h"
|
| -#include "GrVertexBuffer.h"
|
|
|
| -#include "SkAutoKern.h"
|
| -#include "SkColorPriv.h"
|
| -#include "SkColorFilter.h"
|
| -#include "SkDistanceFieldGen.h"
|
| #include "SkDraw.h"
|
| #include "SkDrawFilter.h"
|
| -#include "SkDrawProcs.h"
|
| -#include "SkFindAndPlaceGlyph.h"
|
| -#include "SkGlyphCache.h"
|
| -#include "SkGpuDevice.h"
|
| #include "SkGrPriv.h"
|
| -#include "SkPath.h"
|
| -#include "SkRTConf.h"
|
| -#include "SkStrokeRec.h"
|
| -#include "SkTextBlob.h"
|
| -#include "SkTextMapStateProc.h"
|
| -
|
| -#include "batches/GrAtlasTextBatch.h"
|
| -
|
| -GrAtlasTextContext::GrAtlasTextContext(GrContext* context)
|
| - : INHERITED(context)
|
| - , fDistanceAdjustTable(new GrDistanceFieldAdjustTable) {
|
| - // We overallocate vertices in our textblobs based on the assumption that A8 has the greatest
|
| - // vertexStride
|
| - static_assert(GrAtlasTextBlob::kGrayTextVASize >= GrAtlasTextBlob::kColorTextVASize &&
|
| - GrAtlasTextBlob::kGrayTextVASize >= GrAtlasTextBlob::kLCDTextVASize,
|
| - "vertex_attribute_changed");
|
| - fCache = context->getTextBlobCache();
|
| +
|
| +GrAtlasTextContext::GrAtlasTextContext()
|
| + : fDistanceAdjustTable(new GrDistanceFieldAdjustTable) {
|
| }
|
|
|
|
|
| -GrAtlasTextContext* GrAtlasTextContext::Create(GrContext* context) {
|
| - return new GrAtlasTextContext(context);
|
| +GrAtlasTextContext* GrAtlasTextContext::Create() {
|
| + return new GrAtlasTextContext();
|
| }
|
|
|
| bool GrAtlasTextContext::canDraw(const SkPaint& skPaint,
|
| const SkMatrix& viewMatrix,
|
| - const SkSurfaceProps& props) {
|
| - return GrTextUtils::CanDrawAsDistanceFields(skPaint, viewMatrix, props,
|
| - *fContext->caps()->shaderCaps()) ||
|
| + const SkSurfaceProps& props,
|
| + const GrShaderCaps& shaderCaps) {
|
| + return GrTextUtils::CanDrawAsDistanceFields(skPaint, viewMatrix, props, shaderCaps) ||
|
| !SkDraw::ShouldDrawTextAsPaths(skPaint, viewMatrix);
|
| }
|
|
|
| @@ -92,14 +66,14 @@ bool GrAtlasTextContext::HasLCD(const SkTextBlob* blob) {
|
| return false;
|
| }
|
|
|
| -void GrAtlasTextContext::drawTextBlob(GrDrawContext* dc,
|
| +void GrAtlasTextContext::drawTextBlob(GrContext* context, GrDrawContext* dc,
|
| 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 (fContext->abandoned()) {
|
| + if (context->abandoned()) {
|
| return;
|
| }
|
|
|
| @@ -113,6 +87,7 @@ void GrAtlasTextContext::drawTextBlob(GrDrawContext* dc,
|
| (mf && !mf->asABlur(&blurRec)) ||
|
| drawFilter);
|
|
|
| + GrTextBlobCache* cache = context->getTextBlobCache();
|
| if (canCache) {
|
| bool hasLCD = HasLCD(blob);
|
|
|
| @@ -131,7 +106,7 @@ void GrAtlasTextContext::drawTextBlob(GrDrawContext* dc,
|
| key.fStyle = skPaint.getStyle();
|
| key.fHasBlur = SkToBool(mf);
|
| key.fCanonicalColor = canonicalColor;
|
| - cacheBlob.reset(SkSafeRef(fCache->find(key)));
|
| + cacheBlob.reset(SkSafeRef(cache->find(key)));
|
| }
|
|
|
| SkScalar transX = 0.f;
|
| @@ -140,7 +115,7 @@ void GrAtlasTextContext::drawTextBlob(GrDrawContext* dc,
|
| // Though for the time being runs in the textblob can override the paint, they only touch font
|
| // info.
|
| GrPaint grPaint;
|
| - if (!SkPaintToGrPaint(fContext, skPaint, viewMatrix, &grPaint)) {
|
| + if (!SkPaintToGrPaint(context, skPaint, viewMatrix, &grPaint)) {
|
| return;
|
| }
|
|
|
| @@ -150,39 +125,47 @@ void GrAtlasTextContext::drawTextBlob(GrDrawContext* dc,
|
| // 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
|
| - fCache->remove(cacheBlob);
|
| - cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, skPaint)));
|
| - this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), viewMatrix, props,
|
| - blob, x, y, drawFilter);
|
| + cache->remove(cacheBlob);
|
| + cacheBlob.reset(SkRef(cache->createCachedBlob(blob, key, blurRec, skPaint)));
|
| + RegenerateTextBlob(cacheBlob, context->getBatchFontCache(),
|
| + *context->caps()->shaderCaps(), skPaint, grPaint.getColor(),
|
| + viewMatrix, props,
|
| + blob, x, y, drawFilter);
|
| } else {
|
| - fCache->makeMRU(cacheBlob);
|
| + cache->makeMRU(cacheBlob);
|
|
|
| if (CACHE_SANITY_CHECK) {
|
| int glyphCount = 0;
|
| int runCount = 0;
|
| GrTextBlobCache::BlobGlyphCount(&glyphCount, &runCount, blob);
|
| - SkAutoTUnref<GrAtlasTextBlob> sanityBlob(fCache->createBlob(glyphCount, runCount));
|
| + SkAutoTUnref<GrAtlasTextBlob> sanityBlob(cache->createBlob(glyphCount, runCount));
|
| sanityBlob->setupKey(key, blurRec, skPaint);
|
| - this->regenerateTextBlob(sanityBlob, skPaint, grPaint.getColor(), viewMatrix, props,
|
| - blob, x, y, drawFilter);
|
| + RegenerateTextBlob(sanityBlob, context->getBatchFontCache(),
|
| + *context->caps()->shaderCaps(), skPaint,
|
| + grPaint.getColor(), viewMatrix, props,
|
| + blob, x, y, drawFilter);
|
| GrAtlasTextBlob::AssertEqual(*sanityBlob, *cacheBlob);
|
| }
|
| }
|
| } else {
|
| if (canCache) {
|
| - cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, skPaint)));
|
| + cacheBlob.reset(SkRef(cache->createCachedBlob(blob, key, blurRec, skPaint)));
|
| } else {
|
| - cacheBlob.reset(fCache->createBlob(blob));
|
| + cacheBlob.reset(cache->createBlob(blob));
|
| }
|
| - this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), viewMatrix, props,
|
| - blob, x, y, drawFilter);
|
| + RegenerateTextBlob(cacheBlob, context->getBatchFontCache(),
|
| + *context->caps()->shaderCaps(), skPaint, grPaint.getColor(),
|
| + viewMatrix, props,
|
| + blob, x, y, drawFilter);
|
| }
|
|
|
| - cacheBlob->flushCached(fContext, dc, blob, props, fDistanceAdjustTable, skPaint,
|
| + cacheBlob->flushCached(context, dc, blob, props, fDistanceAdjustTable, skPaint,
|
| grPaint, drawFilter, clip, viewMatrix, clipBounds, x, y, transX, transY);
|
| }
|
|
|
| -void GrAtlasTextContext::regenerateTextBlob(GrAtlasTextBlob* cacheBlob,
|
| +void GrAtlasTextContext::RegenerateTextBlob(GrAtlasTextBlob* cacheBlob,
|
| + GrBatchFontCache* fontCache,
|
| + const GrShaderCaps& shaderCaps,
|
| const SkPaint& skPaint, GrColor color,
|
| const SkMatrix& viewMatrix,
|
| const SkSurfaceProps& props,
|
| @@ -211,11 +194,10 @@ void GrAtlasTextContext::regenerateTextBlob(GrAtlasTextBlob* cacheBlob,
|
|
|
| cacheBlob->push_back_run(run);
|
|
|
| - if (GrTextUtils::CanDrawAsDistanceFields(runPaint, viewMatrix, props,
|
| - *fContext->caps()->shaderCaps())) {
|
| + if (GrTextUtils::CanDrawAsDistanceFields(runPaint, viewMatrix, props, shaderCaps)) {
|
| switch (it.positioning()) {
|
| case SkTextBlob::kDefault_Positioning: {
|
| - GrTextUtils::DrawDFText(cacheBlob, run, fContext->getBatchFontCache(),
|
| + GrTextUtils::DrawDFText(cacheBlob, run, fontCache,
|
| props, runPaint, color, viewMatrix,
|
| (const char *)it.glyphs(), textLen,
|
| x + offset.x(), y + offset.y());
|
| @@ -223,7 +205,7 @@ void GrAtlasTextContext::regenerateTextBlob(GrAtlasTextBlob* cacheBlob,
|
| }
|
| case SkTextBlob::kHorizontal_Positioning: {
|
| SkPoint dfOffset = SkPoint::Make(x, y + offset.y());
|
| - GrTextUtils::DrawDFPosText(cacheBlob, run, fContext->getBatchFontCache(),
|
| + GrTextUtils::DrawDFPosText(cacheBlob, run, fontCache,
|
| props, runPaint, color, viewMatrix,
|
| (const char*)it.glyphs(), textLen, it.pos(),
|
| 1, dfOffset);
|
| @@ -231,7 +213,7 @@ void GrAtlasTextContext::regenerateTextBlob(GrAtlasTextBlob* cacheBlob,
|
| }
|
| case SkTextBlob::kFull_Positioning: {
|
| SkPoint dfOffset = SkPoint::Make(x, y);
|
| - GrTextUtils::DrawDFPosText(cacheBlob, run, fContext->getBatchFontCache(),
|
| + GrTextUtils::DrawDFPosText(cacheBlob, run, fontCache,
|
| props, runPaint, color, viewMatrix,
|
| (const char*)it.glyphs(), textLen, it.pos(),
|
| 2, dfOffset);
|
| @@ -243,19 +225,19 @@ void GrAtlasTextContext::regenerateTextBlob(GrAtlasTextBlob* cacheBlob,
|
| } else {
|
| switch (it.positioning()) {
|
| case SkTextBlob::kDefault_Positioning:
|
| - GrTextUtils::DrawBmpText(cacheBlob, run, fContext->getBatchFontCache(),
|
| + GrTextUtils::DrawBmpText(cacheBlob, run, fontCache,
|
| props, runPaint, color, viewMatrix,
|
| (const char *)it.glyphs(), textLen,
|
| x + offset.x(), y + offset.y());
|
| break;
|
| case SkTextBlob::kHorizontal_Positioning:
|
| - GrTextUtils::DrawBmpPosText(cacheBlob, run, fContext->getBatchFontCache(),
|
| + GrTextUtils::DrawBmpPosText(cacheBlob, run, fontCache,
|
| props, runPaint, color, viewMatrix,
|
| (const char*)it.glyphs(), textLen, it.pos(), 1,
|
| SkPoint::Make(x, y + offset.y()));
|
| break;
|
| case SkTextBlob::kFull_Positioning:
|
| - GrTextUtils::DrawBmpPosText(cacheBlob, run, fContext->getBatchFontCache(),
|
| + GrTextUtils::DrawBmpPosText(cacheBlob, run, fontCache,
|
| props, runPaint, color, viewMatrix,
|
| (const char*)it.glyphs(), textLen, it.pos(), 2,
|
| SkPoint::Make(x, y));
|
| @@ -271,7 +253,10 @@ void GrAtlasTextContext::regenerateTextBlob(GrAtlasTextBlob* cacheBlob,
|
| }
|
|
|
| inline GrAtlasTextBlob*
|
| -GrAtlasTextContext::createDrawTextBlob(const GrPaint& paint,
|
| +GrAtlasTextContext::CreateDrawTextBlob(GrTextBlobCache* blobCache,
|
| + GrBatchFontCache* fontCache,
|
| + const GrShaderCaps& shaderCaps,
|
| + const GrPaint& paint,
|
| const SkPaint& skPaint,
|
| const SkMatrix& viewMatrix,
|
| const SkSurfaceProps& props,
|
| @@ -279,68 +264,74 @@ GrAtlasTextContext::createDrawTextBlob(const GrPaint& paint,
|
| SkScalar x, SkScalar y) {
|
| int glyphCount = skPaint.countText(text, byteLength);
|
|
|
| - GrAtlasTextBlob* blob = fCache->createBlob(glyphCount, 1);
|
| + GrAtlasTextBlob* blob = blobCache->createBlob(glyphCount, 1);
|
| blob->initThrowawayBlob(viewMatrix, x, y);
|
|
|
| - if (GrTextUtils::CanDrawAsDistanceFields(skPaint, viewMatrix, props,
|
| - *fContext->caps()->shaderCaps())) {
|
| - GrTextUtils::DrawDFText(blob, 0, fContext->getBatchFontCache(), props,
|
| + if (GrTextUtils::CanDrawAsDistanceFields(skPaint, viewMatrix, props, shaderCaps)) {
|
| + GrTextUtils::DrawDFText(blob, 0, fontCache, props,
|
| skPaint, paint.getColor(), viewMatrix, text,
|
| byteLength, x, y);
|
| } else {
|
| - GrTextUtils::DrawBmpText(blob, 0, fContext->getBatchFontCache(), props, skPaint,
|
| + GrTextUtils::DrawBmpText(blob, 0, fontCache, props, skPaint,
|
| paint.getColor(), viewMatrix, text, byteLength, x, y);
|
| }
|
| return blob;
|
| }
|
|
|
| inline GrAtlasTextBlob*
|
| -GrAtlasTextContext::createDrawPosTextBlob(const GrPaint& paint, const SkPaint& skPaint,
|
| +GrAtlasTextContext::CreateDrawPosTextBlob(GrTextBlobCache* blobCache, GrBatchFontCache* fontCache,
|
| + const GrShaderCaps& shaderCaps, const GrPaint& paint,
|
| + const SkPaint& skPaint,
|
| const SkMatrix& viewMatrix, const SkSurfaceProps& props,
|
| const char text[], size_t byteLength,
|
| const SkScalar pos[], int scalarsPerPosition,
|
| const SkPoint& offset) {
|
| int glyphCount = skPaint.countText(text, byteLength);
|
|
|
| - GrAtlasTextBlob* blob = fCache->createBlob(glyphCount, 1);
|
| + GrAtlasTextBlob* blob = blobCache->createBlob(glyphCount, 1);
|
| blob->initThrowawayBlob(viewMatrix, offset.x(), offset.y());
|
|
|
| - if (GrTextUtils::CanDrawAsDistanceFields(skPaint, viewMatrix, props,
|
| - *fContext->caps()->shaderCaps())) {
|
| - GrTextUtils::DrawDFPosText(blob, 0, fContext->getBatchFontCache(), props,
|
| + if (GrTextUtils::CanDrawAsDistanceFields(skPaint, viewMatrix, props, shaderCaps)) {
|
| + GrTextUtils::DrawDFPosText(blob, 0, fontCache, props,
|
| skPaint, paint.getColor(), viewMatrix, text,
|
| byteLength, pos, scalarsPerPosition, offset);
|
| } else {
|
| - GrTextUtils::DrawBmpPosText(blob, 0, fContext->getBatchFontCache(), props, skPaint,
|
| + GrTextUtils::DrawBmpPosText(blob, 0, fontCache, props, skPaint,
|
| paint.getColor(), viewMatrix, text,
|
| byteLength, pos, scalarsPerPosition, offset);
|
| }
|
| return blob;
|
| }
|
|
|
| -void GrAtlasTextContext::drawText(GrDrawContext* dc,
|
| +void GrAtlasTextContext::drawText(GrContext* context,
|
| + GrDrawContext* dc,
|
| const GrClip& clip,
|
| const GrPaint& paint, const SkPaint& skPaint,
|
| const SkMatrix& viewMatrix,
|
| const SkSurfaceProps& props,
|
| const char text[], size_t byteLength,
|
| SkScalar x, SkScalar y, const SkIRect& regionClipBounds) {
|
| - if (fContext->abandoned()) {
|
| + if (context->abandoned()) {
|
| return;
|
| - } else if (this->canDraw(skPaint, viewMatrix, props)) {
|
| + } else if (this->canDraw(skPaint, viewMatrix, props, *context->caps()->shaderCaps())) {
|
| SkAutoTUnref<GrAtlasTextBlob> blob(
|
| - this->createDrawTextBlob(paint, skPaint, viewMatrix, props, text, byteLength, x, y));
|
| - blob->flushThrowaway(fContext, dc, props, fDistanceAdjustTable, skPaint, paint,
|
| + CreateDrawTextBlob(context->getTextBlobCache(), context->getBatchFontCache(),
|
| + *context->caps()->shaderCaps(),
|
| + paint, skPaint,
|
| + viewMatrix, props,
|
| + text, byteLength, x, y));
|
| + blob->flushThrowaway(context, dc, props, fDistanceAdjustTable, skPaint, paint,
|
| clip, regionClipBounds);
|
| return;
|
| }
|
|
|
| // fall back to drawing as a path
|
| - GrTextUtils::DrawTextAsPath(fContext, dc, clip, skPaint, viewMatrix, text, byteLength, x, y,
|
| + GrTextUtils::DrawTextAsPath(context, dc, clip, skPaint, viewMatrix, text, byteLength, x, y,
|
| regionClipBounds);
|
| }
|
|
|
| -void GrAtlasTextContext::drawPosText(GrDrawContext* dc,
|
| +void GrAtlasTextContext::drawPosText(GrContext* context,
|
| + GrDrawContext* dc,
|
| const GrClip& clip,
|
| const GrPaint& paint, const SkPaint& skPaint,
|
| const SkMatrix& viewMatrix,
|
| @@ -348,21 +339,24 @@ void GrAtlasTextContext::drawPosText(GrDrawContext* dc,
|
| const char text[], size_t byteLength,
|
| const SkScalar pos[], int scalarsPerPosition,
|
| const SkPoint& offset, const SkIRect& regionClipBounds) {
|
| - if (fContext->abandoned()) {
|
| + if (context->abandoned()) {
|
| return;
|
| - } else if (this->canDraw(skPaint, viewMatrix, props)) {
|
| + } else if (this->canDraw(skPaint, viewMatrix, props, *context->caps()->shaderCaps())) {
|
| SkAutoTUnref<GrAtlasTextBlob> blob(
|
| - this->createDrawPosTextBlob(paint, skPaint, viewMatrix, props,
|
| - text, byteLength,
|
| - pos, scalarsPerPosition,
|
| - offset));
|
| - blob->flushThrowaway(fContext, dc, props, fDistanceAdjustTable, skPaint, paint,
|
| + CreateDrawPosTextBlob(context->getTextBlobCache(),
|
| + context->getBatchFontCache(),
|
| + *context->caps()->shaderCaps(),
|
| + paint, skPaint, viewMatrix, props,
|
| + text, byteLength,
|
| + pos, scalarsPerPosition,
|
| + offset));
|
| + blob->flushThrowaway(context, dc, props, fDistanceAdjustTable, skPaint, paint,
|
| clip, regionClipBounds);
|
| return;
|
| }
|
|
|
| // fall back to drawing as a path
|
| - GrTextUtils::DrawPosTextAsPath(fContext, dc, props, clip, skPaint, viewMatrix, text,
|
| + GrTextUtils::DrawPosTextAsPath(context, dc, props, clip, skPaint, viewMatrix, text,
|
| byteLength, pos, scalarsPerPosition, offset, regionClipBounds);
|
| }
|
|
|
| @@ -382,7 +376,7 @@ DRAW_BATCH_TEST_DEFINE(TextBlobBatch) {
|
| // We don't yet test the fall back to paths in the GrTextContext base class. This is mostly
|
| // because we don't really want to have a gpu device here.
|
| // We enable distance fields by twiddling a knob on the paint
|
| - gTextContext = GrAtlasTextContext::Create(context);
|
| + gTextContext = GrAtlasTextContext::Create();
|
| }
|
|
|
| // Setup dummy SkPaint / GrPaint
|
| @@ -408,8 +402,12 @@ DRAW_BATCH_TEST_DEFINE(TextBlobBatch) {
|
| // right now we don't handle textblobs, nor do we handle drawPosText. Since we only
|
| // intend to test the batch with this unit test, that is okay.
|
| SkAutoTUnref<GrAtlasTextBlob> blob(
|
| - gTextContext->createDrawTextBlob(grPaint, skPaint, viewMatrix, gSurfaceProps, text,
|
| - static_cast<size_t>(textLen), 0, 0));
|
| + GrAtlasTextContext::CreateDrawTextBlob(context->getTextBlobCache(),
|
| + context->getBatchFontCache(),
|
| + *context->caps()->shaderCaps(), grPaint, skPaint,
|
| + viewMatrix,
|
| + gSurfaceProps, text,
|
| + static_cast<size_t>(textLen), 0, 0));
|
|
|
| // We'd like to be able to test this with random translations, but currently the vertex
|
| // bounds and vertices will get out of sync
|
|
|