aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar Hal Canary <halcanary@google.com>2018-06-06 13:29:51 +0000
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-06 13:29:57 +0000
commit74b390d6b136a60f1df15ac5ecd19bd8ad5a394b (patch)
treeafba5f9d8d8d802e9b6873c5f4c7948a94f76762 /src/gpu
parent102c8cf26e2886ba783a2b54827e1f5d1cf0a774 (diff)
Revert "Have draw(Text|PosText|PosTextH) use a single entry on the device"
This reverts commit 4225b3220ef4bf50f0d9403f812ea94d50c4ee59. Reason for revert: made valgrind unhappy. Original change's description: > Have draw(Text|PosText|PosTextH) use a single entry on the device > > Handle the positioning of drawText at the canvas layer. Simplify > the code by removing similar implementations. > > Change-Id: I8b711783435072f560e29fca1dd934fa2e345ed2 > Reviewed-on: https://skia-review.googlesource.com/127131 > Reviewed-by: Ben Wagner <bungeman@google.com> > Commit-Queue: Herb Derby <herb@google.com> TBR=jvanverth@google.com,bungeman@google.com,herb@google.com Change-Id: I65c9d30ae6ecb1f87e8660e56d8f8ce5daab7551 No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://skia-review.googlesource.com/132403 Reviewed-by: Hal Canary <halcanary@google.com> Commit-Queue: Hal Canary <halcanary@google.com>
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/GrRenderTargetContext.cpp14
-rw-r--r--src/gpu/GrRenderTargetContext.h3
-rw-r--r--src/gpu/SkGpuDevice.cpp11
-rw-r--r--src/gpu/SkGpuDevice.h2
-rw-r--r--src/gpu/text/GrTextContext.cpp227
-rw-r--r--src/gpu/text/GrTextContext.h28
6 files changed, 259 insertions, 26 deletions
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index a79f9d113d..e5bda32354 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -217,6 +217,20 @@ GrOpList* GrRenderTargetContext::getOpList() {
return this->getRTOpList();
}
+void GrRenderTargetContext::drawText(const GrClip& clip, const SkPaint& skPaint,
+ const SkMatrix& viewMatrix, const char text[],
+ size_t byteLength, SkScalar x, SkScalar y,
+ const SkIRect& clipBounds) {
+ ASSERT_SINGLE_OWNER
+ RETURN_IF_ABANDONED
+ SkDEBUGCODE(this->validate();)
+ GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawText", fContext);
+
+ GrTextContext* atlasTextContext = this->drawingManager()->getTextContext();
+ atlasTextContext->drawText(fContext, fTextTarget.get(), clip, skPaint, viewMatrix,
+ fSurfaceProps, text, byteLength, x, y, clipBounds);
+}
+
void GrRenderTargetContext::drawPosText(const GrClip& clip, const SkPaint& paint,
const SkMatrix& viewMatrix, const char text[],
size_t byteLength, const SkScalar pos[],
diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h
index d605314385..acbf963c06 100644
--- a/src/gpu/GrRenderTargetContext.h
+++ b/src/gpu/GrRenderTargetContext.h
@@ -63,6 +63,9 @@ public:
// we could use GrPaint except that
// * SkPaint->GrPaint conversion depends upon whether the glyphs are color or grayscale and
// this can vary within a text run.
+ virtual void drawText(const GrClip&, const SkPaint&, const SkMatrix& viewMatrix,
+ const char text[], size_t byteLength, SkScalar x, SkScalar y,
+ const SkIRect& clipBounds);
virtual void drawPosText(const GrClip&, const SkPaint&, const SkMatrix& viewMatrix,
const char text[], size_t byteLength, const SkScalar pos[],
int scalarsPerPosition, const SkPoint& offset,
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 210cefc7a7..06307a1af2 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1611,6 +1611,17 @@ void SkGpuDevice::drawAtlas(const SkImage* atlas, const SkRSXform xform[],
///////////////////////////////////////////////////////////////////////////////
+void SkGpuDevice::drawText(const void* text,
+ size_t byteLength, SkScalar x, SkScalar y,
+ const SkPaint& paint) {
+ ASSERT_SINGLE_OWNER
+ GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawText", fContext.get());
+ SkDEBUGCODE(this->validate();)
+
+ fRenderTargetContext->drawText(this->clip(), paint, this->ctm(), (const char*)text, byteLength,
+ x, y, this->devClipBounds());
+}
+
void SkGpuDevice::drawPosText(const void* text, size_t byteLength,
const SkScalar pos[], int scalarsPerPos,
const SkPoint& offset, const SkPaint& paint) {
diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h
index 7c7030e1ab..d98dbffe1d 100644
--- a/src/gpu/SkGpuDevice.h
+++ b/src/gpu/SkGpuDevice.h
@@ -87,6 +87,8 @@ public:
const SkPaint& paint, SkCanvas::SrcRectConstraint) override;
void drawSprite(const SkBitmap& bitmap, int x, int y,
const SkPaint& paint) override;
+ void drawText(const void* text, size_t len, SkScalar x, SkScalar y,
+ const SkPaint&) override;
void drawPosText(const void* text, size_t len, const SkScalar pos[],
int scalarsPerPos, const SkPoint& offset, const SkPaint&) override;
void drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y,
diff --git a/src/gpu/text/GrTextContext.cpp b/src/gpu/text/GrTextContext.cpp
index 72926fe280..f662fa9c12 100644
--- a/src/gpu/text/GrTextContext.cpp
+++ b/src/gpu/text/GrTextContext.cpp
@@ -17,7 +17,6 @@
#include "SkFindAndPlaceGlyph.h"
#include "SkGr.h"
#include "SkGraphics.h"
-#include "SkGlyphRun.h"
#include "SkMakeUnique.h"
#include "SkMaskFilterBase.h"
#include "SkPaintPriv.h"
@@ -210,17 +209,11 @@ void GrTextContext::regenerateTextBlob(GrTextBlob* cacheBlob,
shaderCaps.supportsDistanceFieldText(), fOptions)) {
switch (it.positioning()) {
case SkTextBlob::kDefault_Positioning: {
- auto origin = SkPoint::Make(x + offset.x(), y + offset.y());
- auto glyphRun =
- SkGlyphRun::MakeFromDrawText(runPaint.skPaint(),
- (const char*)it.glyphs(), textLen, origin);
-
- this->drawDFPosText(cacheBlob, run, glyphCache, props, runPaint,
- scalerContextFlags, viewMatrix, (const char*)it.glyphs(),
- textLen, glyphRun.getPositions(), 2, SkPoint::Make(0,0));
+ this->drawDFText(cacheBlob, run, glyphCache, props, runPaint, scalerContextFlags,
+ viewMatrix, (const char*)it.glyphs(), textLen, x + offset.x(),
+ y + offset.y());
break;
}
-
case SkTextBlob::kHorizontal_Positioning: {
SkPoint dfOffset = SkPoint::Make(x, y + offset.y());
this->drawDFPosText(cacheBlob, run, glyphCache, props, runPaint,
@@ -238,17 +231,11 @@ void GrTextContext::regenerateTextBlob(GrTextBlob* cacheBlob,
}
} else {
switch (it.positioning()) {
- case SkTextBlob::kDefault_Positioning: {
- auto origin = SkPoint::Make(x + offset.x(), y + offset.y());
- auto glyphRun =
- SkGlyphRun::MakeFromDrawText(
- runPaint.skPaint(), (const char*) it.glyphs(), textLen, origin);
-
- this->DrawBmpPosText(cacheBlob, run, glyphCache, props, runPaint,
- scalerContextFlags, viewMatrix, (const char*) it.glyphs(),
- textLen, glyphRun.getPositions(), 2, SkPoint::Make(0, 0));
+ case SkTextBlob::kDefault_Positioning:
+ DrawBmpText(cacheBlob, run, glyphCache, props, runPaint, scalerContextFlags,
+ viewMatrix, (const char*)it.glyphs(), textLen, x + offset.x(),
+ y + offset.y());
break;
- }
case SkTextBlob::kHorizontal_Positioning:
DrawBmpPosText(cacheBlob, run, glyphCache, props, runPaint, scalerContextFlags,
viewMatrix, (const char*)it.glyphs(), textLen, it.pos(), 1,
@@ -265,6 +252,35 @@ void GrTextContext::regenerateTextBlob(GrTextBlob* cacheBlob,
}
inline sk_sp<GrTextBlob>
+GrTextContext::makeDrawTextBlob(GrTextBlobCache* blobCache,
+ GrGlyphCache* glyphCache,
+ const GrShaderCaps& shaderCaps,
+ const GrTextUtils::Paint& paint,
+ SkScalerContextFlags scalerContextFlags,
+ const SkMatrix& viewMatrix,
+ const SkSurfaceProps& props,
+ const char text[], size_t byteLength,
+ SkScalar x, SkScalar y) const {
+ int glyphCount = paint.skPaint().countText(text, byteLength);
+ if (!glyphCount) {
+ return nullptr;
+ }
+ sk_sp<GrTextBlob> blob = blobCache->makeBlob(glyphCount, 1);
+ blob->initThrowawayBlob(viewMatrix, x, y);
+ blob->setRunPaintFlags(0, paint.skPaint().getFlags());
+
+ if (CanDrawAsDistanceFields(paint, viewMatrix, props, shaderCaps.supportsDistanceFieldText(),
+ fOptions)) {
+ this->drawDFText(blob.get(), 0, glyphCache, props, paint, scalerContextFlags, viewMatrix,
+ text, byteLength, x, y);
+ } else {
+ DrawBmpText(blob.get(), 0, glyphCache, props, paint, scalerContextFlags, viewMatrix, text,
+ byteLength, x, y);
+ }
+ return blob;
+}
+
+inline sk_sp<GrTextBlob>
GrTextContext::makeDrawPosTextBlob(GrTextBlobCache* blobCache,
GrGlyphCache* glyphCache,
const GrShaderCaps& shaderCaps,
@@ -295,6 +311,29 @@ GrTextContext::makeDrawPosTextBlob(GrTextBlobCache* blobCache,
return blob;
}
+void GrTextContext::drawText(GrContext* context, GrTextUtils::Target* target,
+ const GrClip& clip, const SkPaint& skPaint,
+ const SkMatrix& viewMatrix, const SkSurfaceProps& props,
+ const char text[], size_t byteLength, SkScalar x, SkScalar y,
+ const SkIRect& regionClipBounds) {
+ if (context->contextPriv().abandoned()) {
+ return;
+ }
+
+ auto glyphCache = context->contextPriv().getGlyphCache();
+ auto textBlobCache = context->contextPriv().getTextBlobCache();
+
+ GrTextUtils::Paint paint(&skPaint, &target->colorSpaceInfo());
+ sk_sp<GrTextBlob> blob(this->makeDrawTextBlob(
+ textBlobCache, glyphCache, *context->contextPriv().caps()->shaderCaps(), paint,
+ ComputeScalerContextFlags(target->colorSpaceInfo()), viewMatrix, props, text,
+ byteLength, x, y));
+ if (blob) {
+ blob->flush(target, props, fDistanceAdjustTable.get(), paint,
+ clip, viewMatrix, regionClipBounds, x, y);
+ }
+}
+
void GrTextContext::drawPosText(GrContext* context, GrTextUtils::Target* target,
const GrClip& clip, const SkPaint& skPaint,
const SkMatrix& viewMatrix, const SkSurfaceProps& props,
@@ -319,6 +358,41 @@ void GrTextContext::drawPosText(GrContext* context, GrTextUtils::Target* target,
}
}
+void GrTextContext::DrawBmpText(GrTextBlob* blob, int runIndex,
+ GrGlyphCache* glyphCache, const SkSurfaceProps& props,
+ const GrTextUtils::Paint& paint,
+ SkScalerContextFlags scalerContextFlags,
+ const SkMatrix& viewMatrix, const char text[],
+ size_t byteLength, SkScalar x, SkScalar y) {
+ SkASSERT(byteLength == 0 || text != nullptr);
+
+ // nothing to draw
+ if (text == nullptr || byteLength == 0) {
+ return;
+ }
+
+ // Ensure the blob is set for bitmaptext
+ blob->setHasBitmap();
+
+ if (SkDraw::ShouldDrawTextAsPaths(paint, viewMatrix)) {
+ DrawBmpTextAsPaths(blob, runIndex, glyphCache, props, paint, scalerContextFlags, viewMatrix,
+ text, byteLength, x, y);
+ return;
+ }
+
+ sk_sp<GrTextStrike> currStrike;
+ auto cache = blob->setupCache(runIndex, props, scalerContextFlags, paint, &viewMatrix);
+ SkFindAndPlaceGlyph::ProcessText(paint.skPaint().getTextEncoding(), text, byteLength, {x, y},
+ viewMatrix, paint.skPaint().getTextAlign(), cache.get(),
+ [&](const SkGlyph& glyph, SkPoint position, SkPoint rounding) {
+ position += rounding;
+ BmpAppendGlyph(blob, runIndex, glyphCache, &currStrike,
+ glyph, SkScalarFloorToScalar(position.fX),
+ SkScalarFloorToScalar(position.fY),
+ paint.filteredPremulColor(), cache.get(),
+ SK_Scalar1, false);
+ });
+}
void GrTextContext::DrawBmpPosText(GrTextBlob* blob, int runIndex,
GrGlyphCache* glyphCache, const SkSurfaceProps& props,
@@ -358,6 +432,43 @@ void GrTextContext::DrawBmpPosText(GrTextBlob* blob, int runIndex,
});
}
+void GrTextContext::DrawBmpTextAsPaths(GrTextBlob* blob, int runIndex,
+ GrGlyphCache* glyphCache,
+ const SkSurfaceProps& props,
+ const GrTextUtils::Paint& origPaint,
+ SkScalerContextFlags scalerContextFlags,
+ const SkMatrix& viewMatrix, const char text[],
+ size_t byteLength, SkScalar x, SkScalar y) {
+ // nothing to draw
+ if (text == nullptr || byteLength == 0) {
+ return;
+ }
+
+ // Temporarily jam in kFill, so we only ever ask for the raw outline from the cache.
+ SkPaint pathPaint(origPaint);
+ pathPaint.setStyle(SkPaint::kFill_Style);
+ pathPaint.setPathEffect(nullptr);
+
+ GrTextUtils::PathTextIter iter(text, byteLength, pathPaint, true);
+ FallbackTextHelper fallbackTextHelper(viewMatrix, pathPaint, glyphCache, iter.getPathScale());
+
+ const SkGlyph* iterGlyph;
+ const SkPath* iterPath;
+ SkScalar xpos = 0;
+ const char* lastText = text;
+ while (iter.next(&iterGlyph, &iterPath, &xpos)) {
+ if (iterGlyph) {
+ SkPoint pos = SkPoint::Make(xpos + x, y);
+ fallbackTextHelper.appendText(*iterGlyph, iter.getText() - lastText, lastText, pos);
+ } else if (iterPath) {
+ blob->appendPathGlyph(runIndex, *iterPath, xpos + x, y, iter.getPathScale(), false);
+ }
+ lastText = iter.getText();
+ }
+
+ fallbackTextHelper.drawText(blob, runIndex, glyphCache, props, origPaint, scalerContextFlags);
+}
+
void GrTextContext::DrawBmpPosTextAsPaths(GrTextBlob* blob, int runIndex,
GrGlyphCache* glyphCache,
const SkSurfaceProps& props,
@@ -567,6 +678,74 @@ void GrTextContext::InitDistanceFieldPaint(GrTextBlob* blob,
*flags = SkScalerContextFlags::kNone;
}
+void GrTextContext::drawDFText(GrTextBlob* blob, int runIndex,
+ GrGlyphCache* glyphCache, const SkSurfaceProps& props,
+ const GrTextUtils::Paint& paint,
+ SkScalerContextFlags scalerContextFlags,
+ const SkMatrix& viewMatrix, const char text[],
+ size_t byteLength, SkScalar x, SkScalar y) const {
+ SkASSERT(byteLength == 0 || text != nullptr);
+
+ // nothing to draw
+ if (text == nullptr || byteLength == 0) {
+ return;
+ }
+
+ const SkPaint& skPaint = paint.skPaint();
+ SkPaint::GlyphCacheProc glyphCacheProc =
+ SkPaint::GetGlyphCacheProc(skPaint.getTextEncoding(), true);
+
+ SkTArray<SkScalar> positions;
+
+ const char* textPtr = text;
+ SkScalar stopX = 0;
+ SkScalar stopY = 0;
+
+ SkAutoDescriptor desc;
+ SkScalerContextEffects effects;
+ // We apply the fake-gamma by altering the distance in the shader, so we ignore the
+ // passed-in scaler context flags. (It's only used when we fall-back to bitmap text).
+ SkScalerContext::CreateDescriptorAndEffectsUsingPaint(
+ skPaint, &props, SkScalerContextFlags::kNone, nullptr, &desc, &effects);
+ auto typeface = SkPaintPriv::GetTypefaceOrDefault(skPaint);
+
+ {
+ auto origPaintCache =
+ SkStrikeCache::FindOrCreateStrikeExclusive(*desc.getDesc(), effects, *typeface);
+
+ const char* stop = text + byteLength;
+ while (textPtr < stop) {
+ // don't need x, y here, since all subpixel variants will have the
+ // same advance
+ const SkGlyph& glyph = glyphCacheProc(origPaintCache.get(), &textPtr);
+
+ positions.push_back(stopX);
+ positions.push_back(stopY);
+
+ stopX += SkFloatToScalar(glyph.fAdvanceX);
+ stopY += SkFloatToScalar(glyph.fAdvanceY);
+ }
+ SkASSERT(textPtr == stop);
+ }
+
+ // now adjust starting point depending on alignment
+ SkScalar alignX = stopX;
+ SkScalar alignY = stopY;
+ if (skPaint.getTextAlign() == SkPaint::kCenter_Align) {
+ alignX = SkScalarHalf(alignX);
+ alignY = SkScalarHalf(alignY);
+ } else if (skPaint.getTextAlign() == SkPaint::kLeft_Align) {
+ alignX = 0;
+ alignY = 0;
+ }
+ x -= alignX;
+ y -= alignY;
+ SkPoint offset = SkPoint::Make(x, y);
+
+ this->drawDFPosText(blob, runIndex, glyphCache, props, paint, scalerContextFlags,
+ viewMatrix, text, byteLength, positions.begin(), 2, offset);
+}
+
void GrTextContext::drawDFPosText(GrTextBlob* blob, int runIndex,
GrGlyphCache* glyphCache, const SkSurfaceProps& props,
const GrTextUtils::Paint& paint,
@@ -757,15 +936,11 @@ std::unique_ptr<GrDrawOp> GrTextContext::createOp_TestingOnly(GrContext* context
// right now we don't handle textblobs, nor do we handle drawPosText. Since we only intend to
// test the text op with this unit test, that is okay.
-
- auto origin = SkPoint::Make(x, y);
- auto glyphRun = SkGlyphRun::MakeFromDrawText(skPaint, text, textLen, origin);
-
- sk_sp<GrTextBlob> blob(textContext->makeDrawPosTextBlob(
+ sk_sp<GrTextBlob> blob(textContext->makeDrawTextBlob(
context->contextPriv().getTextBlobCache(), glyphCache,
*context->contextPriv().caps()->shaderCaps(), utilsPaint,
GrTextContext::kTextBlobOpScalerContextFlags, viewMatrix, surfaceProps, text,
- static_cast<size_t>(textLen), glyphRun.getPositions(), 2, origin));
+ static_cast<size_t>(textLen), SkIntToScalar(x), SkIntToScalar(y)));
return blob->test_makeOp(textLen, 0, 0, viewMatrix, x, y, utilsPaint, surfaceProps,
textContext->dfAdjustTable(), rtc->textTarget());
diff --git a/src/gpu/text/GrTextContext.h b/src/gpu/text/GrTextContext.h
index 7d31d84a05..3dab70ba9b 100644
--- a/src/gpu/text/GrTextContext.h
+++ b/src/gpu/text/GrTextContext.h
@@ -44,6 +44,9 @@ public:
static std::unique_ptr<GrTextContext> Make(const Options& options);
+ void drawText(GrContext*, GrTextUtils::Target*, const GrClip&, const SkPaint&,
+ const SkMatrix& viewMatrix, const SkSurfaceProps&, const char text[],
+ size_t byteLength, SkScalar x, SkScalar y, const SkIRect& regionClipBounds);
void drawPosText(GrContext*, GrTextUtils::Target*, const GrClip&, const SkPaint&,
const SkMatrix& viewMatrix, const SkSurfaceProps&, const char text[],
size_t byteLength, const SkScalar pos[], int scalarsPerPosition,
@@ -120,6 +123,15 @@ private:
static bool HasLCD(const SkTextBlob*);
+ sk_sp<GrTextBlob> makeDrawTextBlob(GrTextBlobCache*, GrGlyphCache*,
+ const GrShaderCaps&,
+ const GrTextUtils::Paint&,
+ SkScalerContextFlags scalerContextFlags,
+ const SkMatrix& viewMatrix,
+ const SkSurfaceProps&,
+ const char text[], size_t byteLength,
+ SkScalar x, SkScalar y) const;
+
sk_sp<GrTextBlob> makeDrawPosTextBlob(GrTextBlobCache*, GrGlyphCache*,
const GrShaderCaps&,
const GrTextUtils::Paint&,
@@ -132,12 +144,23 @@ private:
const SkPoint& offset) const;
// Functions for appending BMP text to GrTextBlob
+ static void DrawBmpText(GrTextBlob*, int runIndex, GrGlyphCache*,
+ const SkSurfaceProps&, const GrTextUtils::Paint& paint,
+ SkScalerContextFlags scalerContextFlags, const SkMatrix& viewMatrix,
+ const char text[], size_t byteLength, SkScalar x, SkScalar y);
+
static void DrawBmpPosText(GrTextBlob*, int runIndex, GrGlyphCache*,
const SkSurfaceProps&, const GrTextUtils::Paint& paint,
SkScalerContextFlags scalerContextFlags, const SkMatrix& viewMatrix,
const char text[], size_t byteLength, const SkScalar pos[],
int scalarsPerPosition, const SkPoint& offset);
+ static void DrawBmpTextAsPaths(GrTextBlob*, int runIndex, GrGlyphCache*,
+ const SkSurfaceProps&, const GrTextUtils::Paint& paint,
+ SkScalerContextFlags scalerContextFlags,
+ const SkMatrix& viewMatrix, const char text[],
+ size_t byteLength, SkScalar x, SkScalar y);
+
static void DrawBmpPosTextAsPaths(GrTextBlob*, int runIndex, GrGlyphCache*,
const SkSurfaceProps&, const GrTextUtils::Paint& paint,
SkScalerContextFlags scalerContextFlags,
@@ -147,6 +170,11 @@ private:
const SkPoint& offset);
// functions for appending distance field text
+ void drawDFText(GrTextBlob* blob, int runIndex, GrGlyphCache*, const SkSurfaceProps&,
+ const GrTextUtils::Paint& paint, SkScalerContextFlags scalerContextFlags,
+ const SkMatrix& viewMatrix, const char text[], size_t byteLength, SkScalar x,
+ SkScalar y) const;
+
void drawDFPosText(GrTextBlob* blob, int runIndex, GrGlyphCache*,
const SkSurfaceProps&, const GrTextUtils::Paint& paint,
SkScalerContextFlags scalerContextFlags,