Move new WriteVertexData utility to a GrVertexWriter helper struct
Encapsulates the pointer storage and advancement, shortens usage.
Bug: skia:
Change-Id: Id06cd273ed638395d1fd53b3b66f87d4d33a4f3b
Reviewed-on: https://skia-review.googlesource.com/c/170727
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
diff --git a/src/gpu/GrTessellator.cpp b/src/gpu/GrTessellator.cpp
index b5209a3..19b859e 100644
--- a/src/gpu/GrTessellator.cpp
+++ b/src/gpu/GrTessellator.cpp
@@ -9,7 +9,7 @@
#include "GrDefaultGeoProcFactory.h"
#include "GrPathUtils.h"
-#include "ops/GrMeshDrawOp.h"
+#include "GrVertexWriter.h"
#include "SkArenaAlloc.h"
#include "SkGeometry.h"
@@ -200,15 +200,17 @@
};
inline void* emit_vertex(Vertex* v, const AAParams* aaParams, void* data) {
- if (!aaParams) {
- return GrMeshDrawOp::WriteVertexData(data, v->fPoint);
+ GrVertexWriter verts{data};
+ verts.write(v->fPoint);
+
+ if (aaParams) {
+ if (aaParams->fTweakAlpha) {
+ verts.write(SkAlphaMulQ(aaParams->fColor, SkAlpha255To256(v->fAlpha)));
+ } else {
+ verts.write(aaParams->fColor, GrNormalizeByteToFloat(v->fAlpha));
+ }
}
- if (aaParams->fTweakAlpha) {
- GrColor color = SkAlphaMulQ(aaParams->fColor, SkAlpha255To256(v->fAlpha));
- return GrMeshDrawOp::WriteVertexData(data, v->fPoint, color);
- }
- float coverage = GrNormalizeByteToFloat(v->fAlpha);
- return GrMeshDrawOp::WriteVertexData(data, v->fPoint, aaParams->fColor, coverage);
+ return verts.fPtr;
}
void* emit_triangle(Vertex* v0, Vertex* v1, Vertex* v2, const AAParams* aaParams, void* data) {
diff --git a/src/gpu/GrVertexWriter.h b/src/gpu/GrVertexWriter.h
new file mode 100644
index 0000000..8bfcef7
--- /dev/null
+++ b/src/gpu/GrVertexWriter.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrVertexWriter_DEFINED
+#define GrVertexWriter_DEFINED
+
+#include "SkTemplates.h"
+#include <type_traits>
+
+/**
+ * Helper for writing vertex data to a buffer. Usage:
+ * GrVertexWriter vertices{target->makeVertexSpace(...)};
+ * vertices.write(A0, B0, C0, ...);
+ * vertices.write(A1, B1, C1, ...);
+ *
+ * Supports any number of arguments. Each argument must be POD (plain old data), or an array
+ * thereof.
+ */
+struct GrVertexWriter {
+ template <typename T, typename... Args>
+ void write(const T& val, const Args&... remainder) {
+ static_assert(std::is_pod<T>::value, "");
+ static_assert(alignof(T) == 4, "");
+ memcpy(fPtr, &val, sizeof(T));
+ fPtr = SkTAddOffset<void>(fPtr, sizeof(T));
+ this->write(remainder...);
+ }
+
+ template <typename T, size_t N, typename... Args>
+ void write(const T(&val)[N], const Args&... remainder) {
+ static_assert(std::is_pod<T>::value, "");
+ static_assert(alignof(T) == 4, "");
+ memcpy(fPtr, val, N * sizeof(T));
+ fPtr = SkTAddOffset<void>(fPtr, N * sizeof(T));
+ this->write(remainder...);
+ }
+
+ void write() {}
+
+ void* fPtr;
+};
+
+#endif
diff --git a/src/gpu/ops/GrAAConvexPathRenderer.cpp b/src/gpu/ops/GrAAConvexPathRenderer.cpp
index 1f2b703..624c261 100644
--- a/src/gpu/ops/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/ops/GrAAConvexPathRenderer.cpp
@@ -18,6 +18,7 @@
#include "GrRenderTargetContext.h"
#include "GrShape.h"
#include "GrSimpleMeshDrawOpHelper.h"
+#include "GrVertexWriter.h"
#include "SkGeometry.h"
#include "SkPathPriv.h"
#include "SkPointPriv.h"
@@ -690,19 +691,20 @@
// extract the result vertices and indices from the GrAAConvexTessellator
static void extract_lines_only_verts(const GrAAConvexTessellator& tess,
- void* vertices,
+ void* vertData,
GrColor color,
uint16_t* idxs,
bool tweakAlphaForCoverage) {
+ GrVertexWriter verts{vertData};
for (int i = 0; i < tess.numPts(); ++i) {
- vertices = GrMeshDrawOp::WriteVertexData(vertices, tess.point(i));
+ verts.write(tess.point(i));
if (tweakAlphaForCoverage) {
SkASSERT(SkScalarRoundToInt(255.0f * tess.coverage(i)) <= 255);
unsigned scale = SkScalarRoundToInt(255.0f * tess.coverage(i));
GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, scale);
- vertices = GrMeshDrawOp::WriteVertexData(vertices, scaledColor);
+ verts.write(scaledColor);
} else {
- vertices = GrMeshDrawOp::WriteVertexData(vertices, color, tess.coverage(i));
+ verts.write(color, tess.coverage(i));
}
}
diff --git a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
index 996fa33..52785eb 100644
--- a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
+++ b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
@@ -17,6 +17,7 @@
#include "GrRenderTargetContext.h"
#include "GrShape.h"
#include "GrStyle.h"
+#include "GrVertexWriter.h"
#include "SkGeometry.h"
#include "SkPathPriv.h"
#include "SkString.h"
@@ -80,21 +81,22 @@
// extract the result vertices and indices from the GrAAConvexTessellator
static void extract_verts(const GrAAConvexTessellator& tess,
- void* vertices,
+ void* vertData,
size_t vertexStride,
GrColor color,
uint16_t firstIndex,
uint16_t* idxs,
bool tweakAlphaForCoverage) {
+ GrVertexWriter verts{vertData};
for (int i = 0; i < tess.numPts(); ++i) {
- vertices = GrMeshDrawOp::WriteVertexData(vertices, tess.point(i));
+ verts.write(tess.point(i));
if (tweakAlphaForCoverage) {
SkASSERT(SkScalarRoundToInt(255.0f * tess.coverage(i)) <= 255);
unsigned scale = SkScalarRoundToInt(255.0f * tess.coverage(i));
GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, scale);
- vertices = GrMeshDrawOp::WriteVertexData(vertices, scaledColor);
+ verts.write(scaledColor);
} else {
- vertices = GrMeshDrawOp::WriteVertexData(vertices, color, tess.coverage(i));
+ verts.write(color, tess.coverage(i));
}
}
diff --git a/src/gpu/ops/GrMeshDrawOp.h b/src/gpu/ops/GrMeshDrawOp.h
index c300f33..fc25cb1 100644
--- a/src/gpu/ops/GrMeshDrawOp.h
+++ b/src/gpu/ops/GrMeshDrawOp.h
@@ -27,35 +27,6 @@
/** Abstract interface that represents a destination for a GrMeshDrawOp. */
class Target;
- /**
- * Helpers for writing vertex data to a buffer. Usage:
- * void* vertices = ...;
- * vertices = WriteVertexData(vertices, A0, B0, C0, ...);
- * vertices = WriteVertexData(vertices, A1, B1, C1, ...);
- *
- * Supports any number of arguments. Each argument must be trivially copyable (or an array
- * thereof).
- */
- template <typename T, typename... Args>
- static inline void* SK_WARN_UNUSED_RESULT WriteVertexData(void* verts, const T& val,
- const Args&... remainder) {
- static_assert(std::is_pod<T>::value, "");
- static_assert(alignof(T) == 4, "");
- memcpy(verts, &val, sizeof(T));
- return WriteVertexData((char*)verts + sizeof(T), remainder...);
- }
-
- template <typename T, size_t N, typename... Args>
- static inline void* SK_WARN_UNUSED_RESULT WriteVertexData(void* verts, const T (&val)[N],
- const Args&... remainder) {
- static_assert(std::is_pod<T>::value, "");
- static_assert(alignof(T) == 4, "");
- memcpy(verts, val, N * sizeof(T));
- return WriteVertexData((char*)verts + (N * sizeof(T)), remainder...);
- }
-
- static inline void* SK_WARN_UNUSED_RESULT WriteVertexData(void* verts) { return verts; }
-
protected:
GrMeshDrawOp(uint32_t classID);
diff --git a/src/gpu/ops/GrOvalOpFactory.cpp b/src/gpu/ops/GrOvalOpFactory.cpp
index 546b95d..20f55a2 100644
--- a/src/gpu/ops/GrOvalOpFactory.cpp
+++ b/src/gpu/ops/GrOvalOpFactory.cpp
@@ -13,6 +13,7 @@
#include "GrResourceProvider.h"
#include "GrShaderCaps.h"
#include "GrStyle.h"
+#include "GrVertexWriter.h"
#include "SkRRectPriv.h"
#include "SkStrokeRec.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
@@ -1163,9 +1164,9 @@
const GrBuffer* vertexBuffer;
int firstVertex;
- void* vertices = target->makeVertexSpace(gp->vertexStride(), fVertCount, &vertexBuffer,
- &firstVertex);
- if (!vertices) {
+ GrVertexWriter vertices{target->makeVertexSpace(gp->vertexStride(), fVertCount,
+ &vertexBuffer, &firstVertex)};
+ if (!vertices.fPtr) {
SkDebugf("Could not allocate vertices\n");
return;
}
@@ -1188,6 +1189,7 @@
// The inner radius in the vertex data must be specified in normalized space.
innerRadius = innerRadius / outerRadius;
+ SkPoint radii = { outerRadius, innerRadius };
SkPoint center = SkPoint::Make(bounds.centerX(), bounds.centerY());
SkScalar halfWidth = 0.5f * bounds.width();
@@ -1212,19 +1214,21 @@
// compute the vertex position from this.
SkScalar dist = SkTMin(kOctagonOuter[i].dot(geoClipPlane) + offsetClipDist, 0.0f);
SkVector offset = kOctagonOuter[i] - geoClipPlane * dist;
- vertices = WriteVertexData(vertices, center + offset * halfWidth, color, offset,
- outerRadius, innerRadius);
+ vertices.write(center + offset * halfWidth,
+ color,
+ offset,
+ radii);
if (fClipPlane) {
- vertices = WriteVertexData(vertices, circle.fClipPlane);
+ vertices.write(circle.fClipPlane);
}
if (fClipPlaneIsect) {
- vertices = WriteVertexData(vertices, circle.fIsectPlane);
+ vertices.write(circle.fIsectPlane);
}
if (fClipPlaneUnion) {
- vertices = WriteVertexData(vertices, circle.fUnionPlane);
+ vertices.write(circle.fUnionPlane);
}
if (fRoundCaps) {
- vertices = WriteVertexData(vertices, circle.fRoundCapCenters);
+ vertices.write(circle.fRoundCapCenters);
}
}
@@ -1232,36 +1236,34 @@
// compute the inner ring
for (int i = 0; i < 8; ++i) {
- vertices = WriteVertexData(vertices,
- center + kOctagonInner[i] * circle.fInnerRadius,
- color,
- kOctagonInner[i] * innerRadius,
- outerRadius, innerRadius);
+ vertices.write(center + kOctagonInner[i] * circle.fInnerRadius,
+ color,
+ kOctagonInner[i] * innerRadius,
+ radii);
if (fClipPlane) {
- vertices = WriteVertexData(vertices, circle.fClipPlane);
+ vertices.write(circle.fClipPlane);
}
if (fClipPlaneIsect) {
- vertices = WriteVertexData(vertices, circle.fIsectPlane);
+ vertices.write(circle.fIsectPlane);
}
if (fClipPlaneUnion) {
- vertices = WriteVertexData(vertices, circle.fUnionPlane);
+ vertices.write(circle.fUnionPlane);
}
if (fRoundCaps) {
- vertices = WriteVertexData(vertices, circle.fRoundCapCenters);
+ vertices.write(circle.fRoundCapCenters);
}
}
} else {
// filled
- vertices = WriteVertexData(vertices, center, color, SkPoint::Make(0, 0),
- outerRadius, innerRadius);
+ vertices.write(center, color, SkPoint::Make(0, 0), radii);
if (fClipPlane) {
- vertices = WriteVertexData(vertices, circle.fClipPlane);
+ vertices.write(circle.fClipPlane);
}
if (fClipPlaneIsect) {
- vertices = WriteVertexData(vertices, circle.fIsectPlane);
+ vertices.write(circle.fIsectPlane);
}
if (fClipPlaneUnion) {
- vertices = WriteVertexData(vertices, circle.fUnionPlane);
+ vertices.write(circle.fUnionPlane);
}
SkASSERT(!fRoundCaps);
}
@@ -1482,9 +1484,9 @@
const GrBuffer* vertexBuffer;
int firstVertex;
- void* vertices = target->makeVertexSpace(gp->vertexStride(), fVertCount, &vertexBuffer,
- &firstVertex);
- if (!vertices) {
+ GrVertexWriter vertices{target->makeVertexSpace(gp->vertexStride(), fVertCount,
+ &vertexBuffer, &firstVertex)};
+ if (!vertices.fPtr) {
SkDebugf("Could not allocate vertices\n");
return;
}
@@ -1529,24 +1531,22 @@
};
for (int i = 0; i < 8; ++i) {
- vertices = WriteVertexData(vertices,
- center + kOctagonOuter[i] * halfWidth,
- color,
- reflectY(kOctagonOuter[i]),
- circle.fOuterRadius,
- normInnerRadius,
- dashParams);
+ vertices.write(center + kOctagonOuter[i] * halfWidth,
+ color,
+ reflectY(kOctagonOuter[i]),
+ circle.fOuterRadius,
+ normInnerRadius,
+ dashParams);
}
// Compute the vertices of the inner octagon.
for (int i = 0; i < 8; ++i) {
- vertices = WriteVertexData(vertices,
- center + kOctagonInner[i] * circle.fInnerRadius,
- color,
- reflectY(kOctagonInner[i]) * normInnerRadius,
- circle.fOuterRadius,
- normInnerRadius,
- dashParams);
+ vertices.write(center + kOctagonInner[i] * circle.fInnerRadius,
+ color,
+ reflectY(kOctagonInner[i]) * normInnerRadius,
+ circle.fOuterRadius,
+ normInnerRadius,
+ dashParams);
}
const uint16_t* primIndices = circle_type_to_indices(true);
@@ -1758,8 +1758,8 @@
// Setup geometry processor
sk_sp<GrGeometryProcessor> gp(new EllipseGeometryProcessor(fStroked, localMatrix));
QuadHelper helper(target, gp->vertexStride(), fEllipses.count());
- void* verts = helper.vertices();
- if (!verts) {
+ GrVertexWriter verts{helper.vertices()};
+ if (!verts.fPtr) {
return;
}
@@ -1788,29 +1788,25 @@
}
// The inner radius in the vertex data must be specified in normalized space.
- verts = WriteVertexData(verts,
- SkPoint::Make(bounds.fLeft, bounds.fTop),
- color,
- SkPoint::Make(-xMaxOffset, -yMaxOffset),
- invRadii);
+ verts.write(SkPoint::Make(bounds.fLeft, bounds.fTop),
+ color,
+ SkPoint::Make(-xMaxOffset, -yMaxOffset),
+ invRadii);
- verts = WriteVertexData(verts,
- SkPoint::Make(bounds.fLeft, bounds.fBottom),
- color,
- SkPoint::Make(-xMaxOffset, yMaxOffset),
- invRadii);
+ verts.write(SkPoint::Make(bounds.fLeft, bounds.fBottom),
+ color,
+ SkPoint::Make(-xMaxOffset, yMaxOffset),
+ invRadii);
- verts = WriteVertexData(verts,
- SkPoint::Make(bounds.fRight, bounds.fTop),
- color,
- SkPoint::Make(xMaxOffset, -yMaxOffset),
- invRadii);
+ verts.write(SkPoint::Make(bounds.fRight, bounds.fTop),
+ color,
+ SkPoint::Make(xMaxOffset, -yMaxOffset),
+ invRadii);
- verts = WriteVertexData(verts,
- SkPoint::Make(bounds.fRight, bounds.fBottom),
- color,
- SkPoint::Make(xMaxOffset, yMaxOffset),
- invRadii);
+ verts.write(SkPoint::Make(bounds.fRight, bounds.fBottom),
+ color,
+ SkPoint::Make(xMaxOffset, yMaxOffset),
+ invRadii);
}
auto pipe = fHelper.makePipeline(target);
helper.recordDraw(target, std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState);
@@ -1993,8 +1989,8 @@
new DIEllipseGeometryProcessor(this->viewMatrix(), this->style()));
QuadHelper helper(target, gp->vertexStride(), fEllipses.count());
- void* verts = helper.vertices();
- if (!verts) {
+ GrVertexWriter verts{helper.vertices()};
+ if (!verts.fPtr) {
return;
}
@@ -2020,33 +2016,29 @@
innerRatioY = yRadius / ellipse.fInnerYRadius;
}
- verts = WriteVertexData(verts,
- SkPoint::Make(bounds.fLeft, bounds.fTop),
- color,
- SkPoint::Make(-1.0f - offsetDx, -1.0f - offsetDy),
- SkPoint::Make(-innerRatioX - offsetDx,
- -innerRatioY - offsetDy));
+ verts.write(SkPoint::Make(bounds.fLeft, bounds.fTop),
+ color,
+ SkPoint::Make(-1.0f - offsetDx, -1.0f - offsetDy),
+ SkPoint::Make(-innerRatioX - offsetDx,
+ -innerRatioY - offsetDy));
- verts = WriteVertexData(verts,
- SkPoint::Make(bounds.fLeft, bounds.fBottom),
- color,
- SkPoint::Make(-1.0f - offsetDx, 1.0f + offsetDy),
- SkPoint::Make(-innerRatioX - offsetDx,
- innerRatioY + offsetDy));
+ verts.write(SkPoint::Make(bounds.fLeft, bounds.fBottom),
+ color,
+ SkPoint::Make(-1.0f - offsetDx, 1.0f + offsetDy),
+ SkPoint::Make(-innerRatioX - offsetDx,
+ innerRatioY + offsetDy));
- verts = WriteVertexData(verts,
- SkPoint::Make(bounds.fRight, bounds.fTop),
- color,
- SkPoint::Make(1.0f + offsetDx, -1.0f - offsetDy),
- SkPoint::Make( innerRatioX + offsetDx,
- -innerRatioY - offsetDy));
+ verts.write(SkPoint::Make(bounds.fRight, bounds.fTop),
+ color,
+ SkPoint::Make(1.0f + offsetDx, -1.0f - offsetDy),
+ SkPoint::Make( innerRatioX + offsetDx,
+ -innerRatioY - offsetDy));
- verts = WriteVertexData(verts,
- SkPoint::Make(bounds.fRight, bounds.fBottom),
- color,
- SkPoint::Make(1.0f + offsetDx, 1.0f + offsetDy),
- SkPoint::Make(innerRatioX + offsetDx,
- innerRatioY + offsetDy));
+ verts.write(SkPoint::Make(bounds.fRight, bounds.fBottom),
+ color,
+ SkPoint::Make(1.0f + offsetDx, 1.0f + offsetDy),
+ SkPoint::Make(innerRatioX + offsetDx,
+ innerRatioY + offsetDy));
}
auto pipe = fHelper.makePipeline(target);
helper.recordDraw(target, std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState);