Use GrVertexWriter for GrAAStrokeRectOp
Bug: skia:
Change-Id: I2d166ed6c1cb1c13a91526e2f0340623e0436003
Reviewed-on: https://skia-review.googlesource.com/c/171782
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
diff --git a/src/gpu/ops/GrAAStrokeRectOp.cpp b/src/gpu/ops/GrAAStrokeRectOp.cpp
index f9dea5d..d6c4d97 100644
--- a/src/gpu/ops/GrAAStrokeRectOp.cpp
+++ b/src/gpu/ops/GrAAStrokeRectOp.cpp
@@ -11,16 +11,12 @@
#include "GrResourceKey.h"
#include "GrResourceProvider.h"
#include "GrSimpleMeshDrawOpHelper.h"
-#include "SkPointPriv.h"
+#include "GrVertexWriter.h"
#include "SkStrokeRec.h"
GR_DECLARE_STATIC_UNIQUE_KEY(gMiterIndexBufferKey);
GR_DECLARE_STATIC_UNIQUE_KEY(gBevelIndexBufferKey);
-static void set_inset_fan(SkPoint* pts, size_t stride, const SkRect& r, SkScalar dx, SkScalar dy) {
- SkPointPriv::SetRectFan(pts, r.fLeft + dx, r.fTop + dy, r.fRight - dx, r.fBottom - dy, stride);
-}
-
// We support all hairlines, bevels, and miters, but not round joins. Also, check whether the miter
// limit makes a miter join effectively beveled.
inline static bool allowed_stroke(const SkStrokeRec& stroke, bool* isMiter) {
@@ -232,11 +228,7 @@
CombineResult onCombineIfPossible(GrOp* t, const GrCaps&) override;
- void generateAAStrokeRectGeometry(void* vertices,
- size_t offset,
- size_t vertexStride,
- int outerVertexNum,
- int innerVertexNum,
+ void generateAAStrokeRectGeometry(GrVertexWriter& vertices,
GrColor color,
const SkRect& devOutside,
const SkRect& devOutsideAssist,
@@ -274,7 +266,6 @@
return;
}
- size_t vertexStride = gp->vertexStride();
int innerVertexNum = 4;
int outerVertexNum = this->miterStroke() ? 4 : 8;
int verticesPerInstance = (outerVertexNum + innerVertexNum) * 2;
@@ -283,10 +274,10 @@
sk_sp<const GrBuffer> indexBuffer =
GetIndexBuffer(target->resourceProvider(), this->miterStroke());
- PatternHelper helper(target, GrPrimitiveType::kTriangles, vertexStride, indexBuffer.get(),
+ PatternHelper helper(target, GrPrimitiveType::kTriangles, gp->vertexStride(), indexBuffer.get(),
verticesPerInstance, indicesPerInstance, instanceCount);
- void* vertices = helper.vertices();
- if (!vertices || !indexBuffer) {
+ GrVertexWriter vertices{ helper.vertices() };
+ if (!vertices.fPtr || !indexBuffer) {
SkDebugf("Could not allocate vertices\n");
return;
}
@@ -294,10 +285,6 @@
for (int i = 0; i < instanceCount; i++) {
const RectInfo& info = fRects[i];
this->generateAAStrokeRectGeometry(vertices,
- i * verticesPerInstance * vertexStride,
- vertexStride,
- outerVertexNum,
- innerVertexNum,
info.fColor.toBytes_RGBA(), // TODO4F
info.fDevOutside,
info.fDevOutsideAssist,
@@ -435,11 +422,7 @@
}
}
-void AAStrokeRectOp::generateAAStrokeRectGeometry(void* vertices,
- size_t offset,
- size_t vertexStride,
- int outerVertexNum,
- int innerVertexNum,
+void AAStrokeRectOp::generateAAStrokeRectGeometry(GrVertexWriter& vertices,
GrColor color,
const SkRect& devOutside,
const SkRect& devOutsideAssist,
@@ -447,16 +430,8 @@
bool miterStroke,
bool degenerate,
bool tweakAlphaForCoverage) const {
- intptr_t verts = reinterpret_cast<intptr_t>(vertices) + offset;
-
// We create vertices for four nested rectangles. There are two ramps from 0 to full
// coverage, one on the exterior of the stroke and the other on the interior.
- // The following pointers refer to the four rects, from outermost to innermost.
- SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts);
- SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + outerVertexNum * vertexStride);
- SkPoint* fan2Pos = reinterpret_cast<SkPoint*>(verts + 2 * outerVertexNum * vertexStride);
- SkPoint* fan3Pos = reinterpret_cast<SkPoint*>(
- verts + (2 * outerVertexNum + innerVertexNum) * vertexStride);
// TODO: this only really works if the X & Y margins are the same all around
// the rect (or if they are all >= 1.0).
@@ -479,59 +454,26 @@
SkMinScalar(inset, SkTMax(devOutside.height(), devOutsideAssist.height()));
}
- if (miterStroke) {
- // outermost
- set_inset_fan(fan0Pos, vertexStride, devOutside, -SK_ScalarHalf, -SK_ScalarHalf);
- // inner two
- set_inset_fan(fan1Pos, vertexStride, devOutside, inset, inset);
- if (!degenerate) {
- set_inset_fan(fan2Pos, vertexStride, devInside, -inset, -inset);
- // innermost
- set_inset_fan(fan3Pos, vertexStride, devInside, SK_ScalarHalf, SK_ScalarHalf);
- } else {
- // When the interior rect has become degenerate we smoosh to a single point
- SkASSERT(devInside.fLeft == devInside.fRight && devInside.fTop == devInside.fBottom);
- SkPointPriv::SetRectFan(fan2Pos, devInside.fLeft, devInside.fTop, devInside.fRight,
- devInside.fBottom, vertexStride);
- SkPointPriv::SetRectFan(fan3Pos, devInside.fLeft, devInside.fTop, devInside.fRight,
- devInside.fBottom, vertexStride);
- }
- } else {
- SkPoint* fan0AssistPos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride);
- SkPoint* fan1AssistPos =
- reinterpret_cast<SkPoint*>(verts + (outerVertexNum + 4) * vertexStride);
- // outermost
- set_inset_fan(fan0Pos, vertexStride, devOutside, -SK_ScalarHalf, -SK_ScalarHalf);
- set_inset_fan(fan0AssistPos, vertexStride, devOutsideAssist, -SK_ScalarHalf,
- -SK_ScalarHalf);
- // outer one of the inner two
- set_inset_fan(fan1Pos, vertexStride, devOutside, inset, inset);
- set_inset_fan(fan1AssistPos, vertexStride, devOutsideAssist, inset, inset);
- if (!degenerate) {
- // inner one of the inner two
- set_inset_fan(fan2Pos, vertexStride, devInside, -inset, -inset);
- // innermost
- set_inset_fan(fan3Pos, vertexStride, devInside, SK_ScalarHalf, SK_ScalarHalf);
- } else {
- // When the interior rect has become degenerate we smoosh to a single point
- SkASSERT(devInside.fLeft == devInside.fRight && devInside.fTop == devInside.fBottom);
- SkPointPriv::SetRectFan(fan2Pos, devInside.fLeft, devInside.fTop, devInside.fRight,
- devInside.fBottom, vertexStride);
- SkPointPriv::SetRectFan(fan3Pos, devInside.fLeft, devInside.fTop, devInside.fRight,
- devInside.fBottom, vertexStride);
- }
- }
+ auto inset_fan = [](const SkRect& r, SkScalar dx, SkScalar dy) {
+ return GrVertexWriter::TriFanFromRect(r.makeInset(dx, dy));
+ };
- // Make verts point to vertex color and then set all the color and coverage vertex attrs
- // values. The outermost rect has 0 coverage
- verts += sizeof(SkPoint);
- for (int i = 0; i < outerVertexNum; ++i) {
- if (tweakAlphaForCoverage) {
- *reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0;
- } else {
- *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color;
- *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor)) = 0;
- }
+ auto maybe_coverage = [tweakAlphaForCoverage](float coverage) {
+ return GrVertexWriter::If(!tweakAlphaForCoverage, coverage);
+ };
+
+ GrColor outerColor = tweakAlphaForCoverage ? 0 : color;
+
+ // Outermost rect
+ vertices.writeQuad(inset_fan(devOutside, -SK_ScalarHalf, -SK_ScalarHalf),
+ outerColor,
+ maybe_coverage(0.0f));
+
+ if (!miterStroke) {
+ // Second outermost
+ vertices.writeQuad(inset_fan(devOutsideAssist, -SK_ScalarHalf, -SK_ScalarHalf),
+ outerColor,
+ maybe_coverage(0.0f));
}
// scale is the coverage for the the inner two rects.
@@ -540,32 +482,41 @@
float innerCoverage = GrNormalizeByteToFloat(scale);
GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, scale);
+ GrColor innerColor = tweakAlphaForCoverage ? scaledColor : color;
- verts += outerVertexNum * vertexStride;
- for (int i = 0; i < outerVertexNum + innerVertexNum; ++i) {
- if (tweakAlphaForCoverage) {
- *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor;
- } else {
- *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color;
- *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor)) = innerCoverage;
- }
+ // Inner rect
+ vertices.writeQuad(inset_fan(devOutside, inset, inset),
+ innerColor,
+ maybe_coverage(innerCoverage));
+
+ if (!miterStroke) {
+ // Second inner
+ vertices.writeQuad(inset_fan(devOutsideAssist, inset, inset),
+ innerColor,
+ maybe_coverage(innerCoverage));
}
- // The innermost rect has 0 coverage, unless we are degenerate, in which case we must apply the
- // scaled coverage
- verts += (outerVertexNum + innerVertexNum) * vertexStride;
if (!degenerate) {
- innerCoverage = 0;
- scaledColor = 0;
- }
+ vertices.writeQuad(inset_fan(devInside, -inset, -inset),
+ innerColor,
+ maybe_coverage(innerCoverage));
- for (int i = 0; i < innerVertexNum; ++i) {
- if (tweakAlphaForCoverage) {
- *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor;
- } else {
- *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color;
- *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor)) = innerCoverage;
- }
+ // The innermost rect has 0 coverage...
+ vertices.writeQuad(inset_fan(devInside, SK_ScalarHalf, SK_ScalarHalf),
+ (GrColor)0,
+ maybe_coverage(0.0f));
+ } else {
+ // When the interior rect has become degenerate we smoosh to a single point
+ SkASSERT(devInside.fLeft == devInside.fRight && devInside.fTop == devInside.fBottom);
+
+ vertices.writeQuad(GrVertexWriter::TriFanFromRect(devInside),
+ innerColor,
+ maybe_coverage(innerCoverage));
+
+ // ... unless we are degenerate, in which case we must apply the scaled coverage
+ vertices.writeQuad(GrVertexWriter::TriFanFromRect(devInside),
+ innerColor,
+ maybe_coverage(innerCoverage));
}
}