aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar cdalton <cdalton@nvidia.com>2015-10-05 15:28:20 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-10-05 15:28:21 -0700
commit02015e51d90597e13525d46aa1757f34fc19307b (patch)
tree7cc73e2fd26fe5aab75d9b8322bcb00fa641445c /src/gpu
parent3bd909a44c46976e81d806dcaf69dbf0bbbb8501 (diff)
Use SkTextBlob for nvpr color bitmap fallbacks
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/GrStencilAndCoverTextContext.cpp121
-rw-r--r--src/gpu/GrStencilAndCoverTextContext.h7
2 files changed, 98 insertions, 30 deletions
diff --git a/src/gpu/GrStencilAndCoverTextContext.cpp b/src/gpu/GrStencilAndCoverTextContext.cpp
index 9f394f9018..61f7f864d7 100644
--- a/src/gpu/GrStencilAndCoverTextContext.cpp
+++ b/src/gpu/GrStencilAndCoverTextContext.cpp
@@ -92,6 +92,32 @@ void GrStencilAndCoverTextContext::onDrawPosText(GrDrawContext* dc, GrRenderTarg
////////////////////////////////////////////////////////////////////////////////////////////////////
+class GrStencilAndCoverTextContext::FallbackBlobBuilder {
+public:
+ FallbackBlobBuilder() : fBuffIdx(0) {}
+
+ bool isInitialized() const { return SkToBool(fBuilder); }
+
+ void init(const SkPaint& font, SkScalar textRatio);
+
+ void appendGlyph(uint16_t glyphId, const SkPoint& pos);
+
+ const SkTextBlob* buildIfInitialized();
+
+private:
+ enum { kWriteBufferSize = 1024 };
+
+ void flush();
+
+ SkAutoTDelete<SkTextBlobBuilder> fBuilder;
+ SkPaint fFont;
+ int fBuffIdx;
+ uint16_t fGlyphIds[kWriteBufferSize];
+ SkPoint fPositions[kWriteBufferSize];
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
GrStencilAndCoverTextContext::TextRun::TextRun(const SkPaint& fontAndStroke)
: fStroke(fontAndStroke),
fFont(fontAndStroke) {
@@ -198,16 +224,20 @@ void GrStencilAndCoverTextContext::TextRun::setText(const char text[], size_t by
SkFixed fx = SkScalarToFixed(x);
SkFixed fy = SkScalarToFixed(y);
+ FallbackBlobBuilder fallback;
while (text < stop) {
const SkGlyph& glyph = glyphCacheProc(glyphCache, &text, 0, 0);
fx += SkFixedMul(autokern.adjust(glyph), fixedSizeRatio);
if (glyph.fWidth) {
- this->appendGlyph(glyph, SkPoint::Make(SkFixedToScalar(fx), SkFixedToScalar(fy)));
+ this->appendGlyph(glyph, SkPoint::Make(SkFixedToScalar(fx), SkFixedToScalar(fy)),
+ &fallback);
}
fx += SkFixedMul(glyph.fAdvanceX, fixedSizeRatio);
fy += SkFixedMul(glyph.fAdvanceY, fixedSizeRatio);
}
+
+ fFallbackTextBlob.reset(fallback.buildIfInitialized());
}
void GrStencilAndCoverTextContext::TextRun::setPosText(const char text[], size_t byteLength,
@@ -230,6 +260,7 @@ void GrStencilAndCoverTextContext::TextRun::setPosText(const char text[], size_t
SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition);
SkTextAlignProc alignProc(fFont.getTextAlign());
+ FallbackBlobBuilder fallback;
while (text < stop) {
const SkGlyph& glyph = glyphCacheProc(glyphCache, &text, 0, 0);
if (glyph.fWidth) {
@@ -238,10 +269,12 @@ void GrStencilAndCoverTextContext::TextRun::setPosText(const char text[], size_t
SkPoint loc;
alignProc(tmsLoc, glyph, &loc);
- this->appendGlyph(glyph, loc);
+ this->appendGlyph(glyph, loc, &fallback);
}
pos += scalarsPerPosition;
}
+
+ fFallbackTextBlob.reset(fallback.buildIfInitialized());
}
GrPathRange* GrStencilAndCoverTextContext::TextRun::createGlyphs(GrContext* ctx,
@@ -275,11 +308,14 @@ GrPathRange* GrStencilAndCoverTextContext::TextRun::createGlyphs(GrContext* ctx,
}
inline void GrStencilAndCoverTextContext::TextRun::appendGlyph(const SkGlyph& glyph,
- const SkPoint& pos) {
- // Stick the glyphs we can't draw into the fallback arrays.
+ const SkPoint& pos,
+ FallbackBlobBuilder* fallback) {
+ // Stick the glyphs we can't draw into the fallback text blob.
if (SkMask::kARGB32_Format == glyph.fMaskFormat) {
- fFallbackIndices.push_back(glyph.getGlyphID());
- fFallbackPositions.push_back(pos);
+ if (!fallback->isInitialized()) {
+ fallback->init(fFont, fTextRatio);
+ }
+ fallback->appendGlyph(glyph.getGlyphID(), pos);
} else {
float translate[] = { fTextInverseRatio * pos.x(), fTextInverseRatio * pos.y() };
fDraw->append(glyph.getGlyphID(), translate);
@@ -318,31 +354,62 @@ void GrStencilAndCoverTextContext::TextRun::draw(GrDrawContext* dc,
GrPathRendering::kWinding_FillType);
}
- if (fFallbackIndices.count()) {
- SkASSERT(fFallbackPositions.count() == fFallbackIndices.count());
-
- enum { kPreservedFlags = SkPaint::kFakeBoldText_Flag | SkPaint::kLinearText_Flag |
- SkPaint::kLCDRenderText_Flag | SkPaint::kAutoHinting_Flag };
-
+ if (fFallbackTextBlob) {
SkPaint fallbackSkPaint(originalSkPaint);
fStroke.applyToPaint(&fallbackSkPaint);
if (!fStroke.isFillStyle()) {
fallbackSkPaint.setStrokeWidth(fStroke.getWidth() * fTextRatio);
}
- fallbackSkPaint.setTextAlign(SkPaint::kLeft_Align); // Align has already been accounted for.
- fallbackSkPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
- fallbackSkPaint.setHinting(fFont.getHinting());
- fallbackSkPaint.setFlags((fFont.getFlags() & kPreservedFlags) |
- (originalSkPaint.getFlags() & ~kPreservedFlags));
- // No need for subpixel positioning with bitmap glyphs. TODO: revisit if non-bitmap color
- // glyphs show up and https://code.google.com/p/skia/issues/detail?id=4408 gets resolved.
- fallbackSkPaint.setSubpixelText(false);
- fallbackSkPaint.setTextSize(fFont.getTextSize() * fTextRatio);
-
- fallbackTextContext->drawPosText(dc, rt, clip, paint, fallbackSkPaint, viewMatrix,
- (char*)fFallbackIndices.begin(),
- sizeof(uint16_t) * fFallbackIndices.count(),
- fFallbackPositions[0].asScalars(), 2, SkPoint::Make(0, 0),
- regionClipBounds);
+
+ fallbackTextContext->drawTextBlob(dc, rt, clip, fallbackSkPaint, viewMatrix,
+ fFallbackTextBlob, 0, 0, nullptr, regionClipBounds);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void GrStencilAndCoverTextContext::FallbackBlobBuilder::init(const SkPaint& font,
+ SkScalar textRatio) {
+ SkASSERT(!this->isInitialized());
+ fBuilder.reset(new SkTextBlobBuilder);
+ fFont = font;
+ fFont.setTextAlign(SkPaint::kLeft_Align); // The glyph positions will already account for align.
+ fFont.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+ // No need for subpixel positioning with bitmap glyphs. TODO: revisit if non-bitmap color glyphs
+ // show up and https://code.google.com/p/skia/issues/detail?id=4408 gets resolved.
+ fFont.setSubpixelText(false);
+ fFont.setTextSize(fFont.getTextSize() * textRatio);
+ fBuffIdx = 0;
+}
+
+void GrStencilAndCoverTextContext::FallbackBlobBuilder::appendGlyph(uint16_t glyphId,
+ const SkPoint& pos) {
+ SkASSERT(this->isInitialized());
+ if (fBuffIdx >= kWriteBufferSize) {
+ this->flush();
+ }
+ fGlyphIds[fBuffIdx] = glyphId;
+ fPositions[fBuffIdx] = pos;
+ fBuffIdx++;
+}
+
+void GrStencilAndCoverTextContext::FallbackBlobBuilder::flush() {
+ SkASSERT(this->isInitialized());
+ SkASSERT(fBuffIdx <= kWriteBufferSize);
+ if (!fBuffIdx) {
+ return;
+ }
+ // This will automatically merge with previous runs since we use the same font.
+ const SkTextBlobBuilder::RunBuffer& buff = fBuilder->allocRunPos(fFont, fBuffIdx);
+ memcpy(buff.glyphs, fGlyphIds, fBuffIdx * sizeof(uint16_t));
+ memcpy(buff.pos, fPositions[0].asScalars(), fBuffIdx * 2 * sizeof(SkScalar));
+ fBuffIdx = 0;
+}
+
+const SkTextBlob* GrStencilAndCoverTextContext::FallbackBlobBuilder::buildIfInitialized() {
+ if (!this->isInitialized()) {
+ return nullptr;
}
+ this->flush();
+ return fBuilder->build();
}
diff --git a/src/gpu/GrStencilAndCoverTextContext.h b/src/gpu/GrStencilAndCoverTextContext.h
index c5c29ad86f..9e85e89c88 100644
--- a/src/gpu/GrStencilAndCoverTextContext.h
+++ b/src/gpu/GrStencilAndCoverTextContext.h
@@ -45,6 +45,8 @@ private:
const SkScalar pos[], int scalarsPerPosition,
const SkPoint& offset, const SkIRect& regionClipBounds) override;
+ class FallbackBlobBuilder;
+
class TextRun {
public:
TextRun(const SkPaint& fontAndStroke);
@@ -64,7 +66,7 @@ private:
private:
GrPathRange* createGlyphs(GrContext*, SkGlyphCache*);
- void appendGlyph(const SkGlyph&, const SkPoint&);
+ void appendGlyph(const SkGlyph&, const SkPoint&, FallbackBlobBuilder*);
GrStrokeInfo fStroke;
SkPaint fFont;
@@ -73,8 +75,7 @@ private:
SkMatrix fLocalMatrix;
bool fUsingRawGlyphPaths;
SkAutoTUnref<GrPathRangeDraw> fDraw;
- SkSTArray<32, uint16_t, true> fFallbackIndices;
- SkSTArray<32, SkPoint, true> fFallbackPositions;
+ SkAutoTUnref<const SkTextBlob> fFallbackTextBlob;
};
typedef GrTextContext INHERITED;