| Index: src/gpu/GrStencilAndCoverTextContext.cpp
|
| diff --git a/src/gpu/GrStencilAndCoverTextContext.cpp b/src/gpu/GrStencilAndCoverTextContext.cpp
|
| index 77960dbe7a8f6ec8beeee92e3840ec040369d92d..d28f1a803a0abe7df26843e7848fd21821d8b4f5 100644
|
| --- a/src/gpu/GrStencilAndCoverTextContext.cpp
|
| +++ b/src/gpu/GrStencilAndCoverTextContext.cpp
|
| @@ -233,7 +233,7 @@ void GrStencilAndCoverTextContext::TextBlob::init(const SkTextBlob* skBlob,
|
|
|
| class GrStencilAndCoverTextContext::FallbackBlobBuilder {
|
| public:
|
| - FallbackBlobBuilder() : fBuffIdx(0) {}
|
| + FallbackBlobBuilder() : fBuffIdx(0), fCount(0) {}
|
|
|
| bool isInitialized() const { return SkToBool(fBuilder); }
|
|
|
| @@ -241,7 +241,7 @@ public:
|
|
|
| void appendGlyph(uint16_t glyphId, const SkPoint& pos);
|
|
|
| - const SkTextBlob* buildIfInitialized();
|
| + const SkTextBlob* buildIfNeeded(int* count);
|
|
|
| private:
|
| enum { kWriteBufferSize = 1024 };
|
| @@ -251,6 +251,7 @@ private:
|
| SkAutoTDelete<SkTextBlobBuilder> fBuilder;
|
| SkPaint fFont;
|
| int fBuffIdx;
|
| + int fCount;
|
| uint16_t fGlyphIds[kWriteBufferSize];
|
| SkPoint fPositions[kWriteBufferSize];
|
| };
|
| @@ -261,6 +262,7 @@ GrStencilAndCoverTextContext::TextRun::TextRun(const SkPaint& fontAndStroke)
|
| : fStroke(fontAndStroke),
|
| fFont(fontAndStroke),
|
| fTotalGlyphCount(0),
|
| + fFallbackGlyphCount(0),
|
| fDetachedGlyphCache(nullptr),
|
| fLastDrawnGlyphsID(SK_InvalidUniqueID) {
|
| SkASSERT(!fStroke.isHairlineStyle()); // Hairlines are not supported.
|
| @@ -339,9 +341,6 @@ GrStencilAndCoverTextContext::TextRun::TextRun(const SkPaint& fontAndStroke)
|
| memcpy(&builder[2 + strokeDataCount], desc, desc->getLength());
|
| }
|
| }
|
| -
|
| - // When drawing from canonically sized paths, the actual local coords are fTextRatio * coords.
|
| - fLocalMatrixTemplate.setScale(fTextRatio, fTextRatio);
|
| }
|
|
|
| GrStencilAndCoverTextContext::TextRun::~TextRun() {
|
| @@ -355,8 +354,9 @@ void GrStencilAndCoverTextContext::TextRun::setText(const char text[], size_t by
|
| SkGlyphCache* glyphCache = this->getGlyphCache();
|
| SkDrawCacheProc glyphCacheProc = fFont.getDrawCacheProc();
|
|
|
| - fDraw.reset(GrPathRangeDraw::Create(GrPathRendering::kTranslate_PathTransformType,
|
| - fTotalGlyphCount = fFont.countText(text, byteLength)));
|
| + fTotalGlyphCount = fFont.countText(text, byteLength);
|
| + fInstanceData.reset(InstanceData::Alloc(GrPathRendering::kTranslate_PathTransformType,
|
| + fTotalGlyphCount));
|
|
|
| const char* stop = text + byteLength;
|
|
|
| @@ -407,7 +407,7 @@ void GrStencilAndCoverTextContext::TextRun::setText(const char text[], size_t by
|
| fy += SkFixedMul(glyph.fAdvanceY, fixedSizeRatio);
|
| }
|
|
|
| - fFallbackTextBlob.reset(fallback.buildIfInitialized());
|
| + fFallbackTextBlob.reset(fallback.buildIfNeeded(&fFallbackGlyphCount));
|
| }
|
|
|
| void GrStencilAndCoverTextContext::TextRun::setPosText(const char text[], size_t byteLength,
|
| @@ -419,8 +419,9 @@ void GrStencilAndCoverTextContext::TextRun::setPosText(const char text[], size_t
|
| SkGlyphCache* glyphCache = this->getGlyphCache();
|
| SkDrawCacheProc glyphCacheProc = fFont.getDrawCacheProc();
|
|
|
| - fDraw.reset(GrPathRangeDraw::Create(GrPathRendering::kTranslate_PathTransformType,
|
| - fTotalGlyphCount = fFont.countText(text, byteLength)));
|
| + fTotalGlyphCount = fFont.countText(text, byteLength);
|
| + fInstanceData.reset(InstanceData::Alloc(GrPathRendering::kTranslate_PathTransformType,
|
| + fTotalGlyphCount));
|
|
|
| const char* stop = text + byteLength;
|
|
|
| @@ -440,7 +441,7 @@ void GrStencilAndCoverTextContext::TextRun::setPosText(const char text[], size_t
|
| pos += scalarsPerPosition;
|
| }
|
|
|
| - fFallbackTextBlob.reset(fallback.buildIfInitialized());
|
| + fFallbackTextBlob.reset(fallback.buildIfNeeded(&fFallbackGlyphCount));
|
| }
|
|
|
| GrPathRange* GrStencilAndCoverTextContext::TextRun::createGlyphs(GrContext* ctx) const {
|
| @@ -470,8 +471,8 @@ inline void GrStencilAndCoverTextContext::TextRun::appendGlyph(const SkGlyph& gl
|
| }
|
| fallback->appendGlyph(glyph.getGlyphID(), pos);
|
| } else {
|
| - float translate[] = { fTextInverseRatio * pos.x(), fTextInverseRatio * pos.y() };
|
| - fDraw->append(glyph.getGlyphID(), translate);
|
| + fInstanceData->append(glyph.getGlyphID(), fTextInverseRatio * pos.x(),
|
| + fTextInverseRatio * pos.y());
|
| }
|
| }
|
|
|
| @@ -484,10 +485,10 @@ void GrStencilAndCoverTextContext::TextRun::draw(GrContext* ctx,
|
| const SkIRect& clipBounds,
|
| GrTextContext* fallbackTextContext,
|
| const SkPaint& originalSkPaint) const {
|
| - SkASSERT(fDraw);
|
| + SkASSERT(fInstanceData);
|
| SkASSERT(dc->accessRenderTarget()->isStencilBufferMultisampled() || !fFont.isAntiAlias());
|
|
|
| - if (fDraw->count()) {
|
| + if (fInstanceData->count()) {
|
| pipelineBuilder->setState(GrPipelineBuilder::kHWAntialias_Flag, fFont.isAntiAlias());
|
|
|
| GR_STATIC_CONST_SAME_STENCIL(kStencilPass,
|
| @@ -503,18 +504,10 @@ void GrStencilAndCoverTextContext::TextRun::draw(GrContext* ctx,
|
| SkAutoTUnref<GrPathRange> glyphs(this->createGlyphs(ctx));
|
| if (fLastDrawnGlyphsID != glyphs->getUniqueID()) {
|
| // Either this is the first draw or the glyphs object was purged since last draw.
|
| - glyphs->loadPathsIfNeeded(fDraw->indices(), fDraw->count());
|
| + glyphs->loadPathsIfNeeded(fInstanceData->indices(), fInstanceData->count());
|
| fLastDrawnGlyphsID = glyphs->getUniqueID();
|
| }
|
|
|
| - SkMatrix drawMatrix(viewMatrix);
|
| - drawMatrix.preTranslate(x, y);
|
| - drawMatrix.preScale(fTextRatio, fTextRatio);
|
| -
|
| - SkMatrix& localMatrix = fLocalMatrixTemplate;
|
| - localMatrix.setTranslateX(x);
|
| - localMatrix.setTranslateY(y);
|
| -
|
| // Don't compute a bounding box. For dst copy texture, we'll opt instead for it to just copy
|
| // the entire dst. Realistically this is a moot point, because any context that supports
|
| // NV_path_rendering will also support NV_blend_equation_advanced.
|
| @@ -524,8 +517,9 @@ void GrStencilAndCoverTextContext::TextRun::draw(GrContext* ctx,
|
| pipelineBuilder->getRenderTarget()->height());
|
|
|
| SkAutoTUnref<GrDrawPathBatchBase> batch(
|
| - GrDrawPathRangeBatch::Create(drawMatrix, localMatrix, color,
|
| - GrPathRendering::kWinding_FillType, glyphs, fDraw,
|
| + GrDrawPathRangeBatch::Create(viewMatrix, fTextRatio, fTextInverseRatio * x,
|
| + fTextInverseRatio * y, color,
|
| + GrPathRendering::kWinding_FillType, glyphs, fInstanceData,
|
| bounds));
|
|
|
| dc->drawPathBatch(*pipelineBuilder, batch);
|
| @@ -559,11 +553,11 @@ void GrStencilAndCoverTextContext::TextRun::releaseGlyphCache() const {
|
| }
|
|
|
| size_t GrStencilAndCoverTextContext::TextRun::computeSizeInCache() const {
|
| - size_t size = sizeof(TextRun) +
|
| - fGlyphPathsKey.size() +
|
| - fTotalGlyphCount * (sizeof(uint16_t) + 2 * sizeof(float));
|
| - if (fDraw) {
|
| - size += sizeof(GrPathRangeDraw);
|
| + size_t size = sizeof(TextRun) + fGlyphPathsKey.size();
|
| + // The instance data always reserves enough space for every glyph.
|
| + size += (fTotalGlyphCount + fFallbackGlyphCount) * (sizeof(uint16_t) + 2 * sizeof(float));
|
| + if (fInstanceData) {
|
| + size += sizeof(InstanceData);
|
| }
|
| if (fFallbackTextBlob) {
|
| size += sizeof(SkTextBlob);
|
| @@ -596,6 +590,7 @@ void GrStencilAndCoverTextContext::FallbackBlobBuilder::appendGlyph(uint16_t gly
|
| fGlyphIds[fBuffIdx] = glyphId;
|
| fPositions[fBuffIdx] = pos;
|
| fBuffIdx++;
|
| + fCount++;
|
| }
|
|
|
| void GrStencilAndCoverTextContext::FallbackBlobBuilder::flush() {
|
| @@ -611,10 +606,11 @@ void GrStencilAndCoverTextContext::FallbackBlobBuilder::flush() {
|
| fBuffIdx = 0;
|
| }
|
|
|
| -const SkTextBlob* GrStencilAndCoverTextContext::FallbackBlobBuilder::buildIfInitialized() {
|
| - if (!this->isInitialized()) {
|
| - return nullptr;
|
| +const SkTextBlob* GrStencilAndCoverTextContext::FallbackBlobBuilder::buildIfNeeded(int *count) {
|
| + *count = fCount;
|
| + if (fCount) {
|
| + this->flush();
|
| + return fBuilder->build();
|
| }
|
| - this->flush();
|
| - return fBuilder->build();
|
| + return nullptr;
|
| }
|
|
|