aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/text
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2017-12-19 11:09:32 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-12-19 20:23:06 +0000
commit5c6ac64516bb56bbdb5d7aedee1a348acc16e29b (patch)
treeb712f1e75a1d2f6cfc1c1d7a5453982787a829cf /src/gpu/text
parent394197d064d976675a7952857ed5ee98e0c9edca (diff)
Revert "Revert "move homogenous with stride to matrixpriv""
This reverts commit de71572f650005e36d4fc2fe95fb5677a25ae4f6. Revert "Revert "Transform vertices for distance field glyphs on CPU."" This reverts commit f226e66d75374e370f3ae2c6895bc689670e9e18. Change-Id: I2545afae3beb1d6b14bba056853ed826ae7a4679 Reviewed-on: https://skia-review.googlesource.com/86603 Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'src/gpu/text')
-rw-r--r--src/gpu/text/GrAtlasTextBlob.cpp79
-rw-r--r--src/gpu/text/GrAtlasTextBlob.h29
-rw-r--r--src/gpu/text/GrAtlasTextBlobVertexRegenerator.cpp8
-rw-r--r--src/gpu/text/GrAtlasTextContext.cpp3
4 files changed, 61 insertions, 58 deletions
diff --git a/src/gpu/text/GrAtlasTextBlob.cpp b/src/gpu/text/GrAtlasTextBlob.cpp
index 0b25a34ed1..02f3ab0a21 100644
--- a/src/gpu/text/GrAtlasTextBlob.cpp
+++ b/src/gpu/text/GrAtlasTextBlob.cpp
@@ -96,7 +96,13 @@ void GrAtlasTextBlob::appendGlyph(int runIndex,
run.fInitialized = true;
- size_t vertexStride = GetVertexStride(format);
+ bool hasW = subRun->hasWCoord();
+ // DF glyphs drawn in perspective must always have a w coord.
+ SkASSERT(hasW || !subRun->drawAsDistanceFields() || !fInitialViewMatrix.hasPerspective());
+ // Non-DF glyphs should never have a w coord.
+ SkASSERT(!hasW || subRun->drawAsDistanceFields());
+
+ size_t vertexStride = GetVertexStride(format, hasW);
subRun->setMaskFormat(format);
@@ -105,53 +111,29 @@ void GrAtlasTextBlob::appendGlyph(int runIndex,
intptr_t vertex = reinterpret_cast<intptr_t>(this->fVertices + subRun->vertexEndIndex());
- if (kARGB_GrMaskFormat != glyph->fMaskFormat) {
- // V0
- SkPoint* position = reinterpret_cast<SkPoint*>(vertex);
- position->set(positions.fLeft, positions.fTop);
- SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint));
- *colorPtr = color;
- vertex += vertexStride;
-
- // V1
- position = reinterpret_cast<SkPoint*>(vertex);
- position->set(positions.fLeft, positions.fBottom);
- colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint));
- *colorPtr = color;
- vertex += vertexStride;
-
- // V2
- position = reinterpret_cast<SkPoint*>(vertex);
- position->set(positions.fRight, positions.fTop);
- colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint));
- *colorPtr = color;
- vertex += vertexStride;
-
- // V3
- position = reinterpret_cast<SkPoint*>(vertex);
- position->set(positions.fRight, positions.fBottom);
- colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint));
- *colorPtr = color;
- } else {
- // V0
- SkPoint* position = reinterpret_cast<SkPoint*>(vertex);
- position->set(positions.fLeft, positions.fTop);
- vertex += vertexStride;
-
- // V1
- position = reinterpret_cast<SkPoint*>(vertex);
- position->set(positions.fLeft, positions.fBottom);
- vertex += vertexStride;
-
- // V2
- position = reinterpret_cast<SkPoint*>(vertex);
- position->set(positions.fRight, positions.fTop);
- vertex += vertexStride;
-
- // V3
- position = reinterpret_cast<SkPoint*>(vertex);
- position->set(positions.fRight, positions.fBottom);
- }
+ // We always write the third position component used by SDFs. If it is unused it gets
+ // overwritten. Similarly, we always write the color and the blob will later overwrite it
+ // with texture coords if it is unused.
+ size_t colorOffset = hasW ? sizeof(SkPoint3) : sizeof(SkPoint);
+ // V0
+ *reinterpret_cast<SkPoint3*>(vertex) = {positions.fLeft, positions.fTop, 1.f};
+ *reinterpret_cast<GrColor*>(vertex + colorOffset) = color;
+ vertex += vertexStride;
+
+ // V1
+ *reinterpret_cast<SkPoint3*>(vertex) = {positions.fLeft, positions.fBottom, 1.f};
+ *reinterpret_cast<GrColor*>(vertex + colorOffset) = color;
+ vertex += vertexStride;
+
+ // V2
+ *reinterpret_cast<SkPoint3*>(vertex) = {positions.fRight, positions.fTop, 1.f};
+ *reinterpret_cast<GrColor*>(vertex + colorOffset) = color;
+ vertex += vertexStride;
+
+ // V3
+ *reinterpret_cast<SkPoint3*>(vertex) = {positions.fRight, positions.fBottom, 1.f};
+ *reinterpret_cast<GrColor*>(vertex + colorOffset) = color;
+
subRun->appendVertices(vertexStride);
fGlyphs[subRun->glyphEndIndex()] = glyph;
subRun->glyphAppended();
@@ -185,6 +167,7 @@ bool GrAtlasTextBlob::mustRegenerate(const GrTextUtils::Paint& paint,
return true;
}
+ /** This could be relaxed for blobs with only distance field glyphs. */
if (fInitialViewMatrix.hasPerspective() && !fInitialViewMatrix.cheapEqualTo(viewMatrix)) {
return true;
}
diff --git a/src/gpu/text/GrAtlasTextBlob.h b/src/gpu/text/GrAtlasTextBlob.h
index 450e256d38..282fa98141 100644
--- a/src/gpu/text/GrAtlasTextBlob.h
+++ b/src/gpu/text/GrAtlasTextBlob.h
@@ -17,6 +17,7 @@
#include "SkMaskFilter.h"
#include "SkOpts.h"
#include "SkPathEffect.h"
+#include "SkPoint3.h"
#include "SkRasterizer.h"
#include "SkSurfaceProps.h"
#include "SkTInternalLList.h"
@@ -53,6 +54,12 @@ public:
static sk_sp<GrAtlasTextBlob> Make(GrMemoryPool* pool, int glyphCount, int runCount);
+ /**
+ * We currently force regeneration of a blob if old or new matrix differ in having perspective.
+ * If we ever change that then the key must contain the perspectiveness when there are distance
+ * fields as perspective distance field use 3 component vertex positions and non-perspective
+ * uses 2.
+ */
struct Key {
Key() {
sk_bzero(this, sizeof(Key));
@@ -126,12 +133,13 @@ public:
}
// sets the last subrun of runIndex to use distance field text
- void setSubRunHasDistanceFields(int runIndex, bool hasLCD, bool isAntiAlias) {
+ void setSubRunHasDistanceFields(int runIndex, bool hasLCD, bool isAntiAlias, bool hasWCoord) {
Run& run = fRuns[runIndex];
Run::SubRunInfo& subRun = run.fSubRunInfo.back();
subRun.setUseLCDText(hasLCD);
subRun.setAntiAliased(isAntiAlias);
subRun.setDrawAsDistanceFields();
+ subRun.setHasWCoord(hasWCoord);
}
void setRunDrawAsPaths(int runIndex) {
@@ -169,13 +177,15 @@ public:
SkGlyphCache*, const SkGlyph& skGlyph,
SkScalar x, SkScalar y, SkScalar scale, bool treatAsBMP);
- static size_t GetVertexStride(GrMaskFormat maskFormat) {
+ static size_t GetVertexStride(GrMaskFormat maskFormat, bool isDistanceFieldWithWCoord) {
switch (maskFormat) {
case kA8_GrMaskFormat:
- return kGrayTextVASize;
+ return isDistanceFieldWithWCoord ? kGrayTextDFPerspectiveVASize : kGrayTextVASize;
case kARGB_GrMaskFormat:
+ SkASSERT(!isDistanceFieldWithWCoord);
return kColorTextVASize;
default:
+ SkASSERT(!isDistanceFieldWithWCoord);
return kLCDTextVASize;
}
}
@@ -232,8 +242,10 @@ public:
// position + local coord
static const size_t kColorTextVASize = sizeof(SkPoint) + sizeof(SkIPoint16);
static const size_t kGrayTextVASize = sizeof(SkPoint) + sizeof(GrColor) + sizeof(SkIPoint16);
+ static const size_t kGrayTextDFPerspectiveVASize =
+ sizeof(SkPoint3) + sizeof(GrColor) + sizeof(SkIPoint16);
static const size_t kLCDTextVASize = kGrayTextVASize;
- static const size_t kMaxVASize = kGrayTextVASize;
+ static const size_t kMaxVASize = kGrayTextDFPerspectiveVASize;
static const int kVerticesPerGlyph = 4;
static void AssertEqual(const GrAtlasTextBlob&, const GrAtlasTextBlob&);
@@ -419,7 +431,7 @@ private:
// This function assumes the translation will be applied before it is called again
void computeTranslation(const SkMatrix& viewMatrix, SkScalar x, SkScalar y,
- SkScalar*transX, SkScalar* transY);
+ SkScalar* transX, SkScalar* transY);
// df properties
void setDrawAsDistanceFields() { fFlags |= kDrawAsSDF_Flag; }
@@ -432,12 +444,17 @@ private:
fFlags = antiAliased ? fFlags | kAntiAliased_Flag : fFlags & ~kAntiAliased_Flag;
}
bool isAntiAliased() const { return SkToBool(fFlags & kAntiAliased_Flag); }
+ void setHasWCoord(bool hasW) {
+ fFlags = hasW ? (fFlags | kHasWCoord_Flag) : fFlags & ~kHasWCoord_Flag;
+ }
+ bool hasWCoord() const { return SkToBool(fFlags & kHasWCoord_Flag); }
private:
enum Flag {
kDrawAsSDF_Flag = 0x1,
kUseLCDText_Flag = 0x2,
- kAntiAliased_Flag = 0x4
+ kAntiAliased_Flag = 0x4,
+ kHasWCoord_Flag = 0x8
};
GrDrawOpAtlas::BulkUseTokenUpdater fBulkUseToken;
diff --git a/src/gpu/text/GrAtlasTextBlobVertexRegenerator.cpp b/src/gpu/text/GrAtlasTextBlobVertexRegenerator.cpp
index 28b2e0f0c0..1be5ae330c 100644
--- a/src/gpu/text/GrAtlasTextBlobVertexRegenerator.cpp
+++ b/src/gpu/text/GrAtlasTextBlobVertexRegenerator.cpp
@@ -71,8 +71,8 @@ inline void regen_vertices(char* vertex, const GrGlyph* glyph, size_t vertexStri
// This is a bit wonky, but sometimes we have LCD text, in which case we won't have color
// vertices, hence vertexStride - sizeof(SkIPoint16)
- intptr_t colorOffset = sizeof(SkPoint);
intptr_t texCoordOffset = vertexStride - sizeof(SkIPoint16);
+ intptr_t colorOffset = texCoordOffset - sizeof(GrColor);
// V0
if (regenPos) {
@@ -211,8 +211,9 @@ Regenerator::Result Regenerator::doRegen() {
}
}
+ bool hasW = fSubRun->hasWCoord();
Result result;
- auto vertexStride = GetVertexStride(fSubRun->maskFormat());
+ auto vertexStride = GetVertexStride(fSubRun->maskFormat(), hasW);
char* currVertex = fBlob->fVertices + fSubRun->vertexStartIndex() +
fCurrGlyph * kVerticesPerGlyph * vertexStride;
result.fFirstVertex = currVertex;
@@ -300,7 +301,8 @@ Regenerator::Result Regenerator::regenerate() {
return this->doRegen<false, true, true, true>();
case kNoRegen: {
Result result;
- auto vertexStride = GetVertexStride(fSubRun->maskFormat());
+ bool hasW = fSubRun->hasWCoord();
+ auto vertexStride = GetVertexStride(fSubRun->maskFormat(), hasW);
result.fGlyphsRegenerated = fSubRun->glyphCount() - fCurrGlyph;
result.fFirstVertex = fBlob->fVertices + fSubRun->vertexStartIndex() +
fCurrGlyph * kVerticesPerGlyph * vertexStride;
diff --git a/src/gpu/text/GrAtlasTextContext.cpp b/src/gpu/text/GrAtlasTextContext.cpp
index d617786944..3faa0f7b87 100644
--- a/src/gpu/text/GrAtlasTextContext.cpp
+++ b/src/gpu/text/GrAtlasTextContext.cpp
@@ -646,13 +646,14 @@ void GrAtlasTextContext::drawDFPosText(GrAtlasTextBlob* blob, int runIndex,
SkTDArray<char> fallbackTxt;
SkTDArray<SkScalar> fallbackPos;
+ bool hasWCoord = viewMatrix.hasPerspective();
// Setup distance field paint and text ratio
SkScalar textRatio;
SkPaint dfPaint(paint);
this->initDistanceFieldPaint(blob, &dfPaint, &textRatio, viewMatrix);
blob->setHasDistanceField();
blob->setSubRunHasDistanceFields(runIndex, paint.skPaint().isLCDRenderText(),
- paint.skPaint().isAntiAlias());
+ paint.skPaint().isAntiAlias(), hasWCoord);
GrAtlasTextStrike* currStrike = nullptr;