Use GrVertexWriter in GrSmallPathRenderer
Make TriStrip a templated rect, with a helper for SkRect.
Added writeQuadValue overload for GrQuad.
Bug: skia:
Change-Id: I2934e5dbb086c5dbe0cc4846176bab8ccc324cf6
Reviewed-on: https://skia-review.googlesource.com/c/171534
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/gpu/GrVertexWriter.h b/src/gpu/GrVertexWriter.h
index 6026348..2c6fbfd 100644
--- a/src/gpu/GrVertexWriter.h
+++ b/src/gpu/GrVertexWriter.h
@@ -8,6 +8,7 @@
#ifndef GrVertexWriter_DEFINED
#define GrVertexWriter_DEFINED
+#include "GrQuad.h"
#include "SkTemplates.h"
#include <type_traits>
@@ -26,7 +27,10 @@
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, "");
+ // This assert is barely related to what we're trying to check - that our vertex data
+ // matches our attribute layouts, where each attribute is aligned to four bytes. If this
+ // becomes a problem, just remove it.
+ static_assert(alignof(T) <= 4, "");
memcpy(fPtr, &val, sizeof(T));
fPtr = SkTAddOffset<void>(fPtr, sizeof(T));
this->write(remainder...);
@@ -35,7 +39,7 @@
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, "");
+ static_assert(alignof(T) <= 4, "");
memcpy(fPtr, val, N * sizeof(T));
fPtr = SkTAddOffset<void>(fPtr, N * sizeof(T));
this->write(remainder...);
@@ -54,7 +58,12 @@
* - For any arguments of type TriStrip, a unique SkPoint will be written at each vertex,
* in this order: left-top, left-bottom, right-top, right-bottom.
*/
- struct TriStrip { const SkRect& fRect; };
+ template <typename T>
+ struct TriStrip { T l, t, r, b; };
+
+ static TriStrip<float> TriStripFromRect(const SkRect& r) {
+ return { r.fLeft, r.fTop, r.fRight, r.fBottom };
+ }
template <typename... Args>
void writeQuad(const Args&... remainder) {
@@ -79,15 +88,20 @@
this->write(val);
}
- template <int corner>
- void writeQuadValue(const TriStrip& r) {
+ template <int corner, typename T>
+ void writeQuadValue(const TriStrip<T>& r) {
switch (corner) {
- case 0: this->write(r.fRect.fLeft , r.fRect.fTop); break;
- case 1: this->write(r.fRect.fLeft , r.fRect.fBottom); break;
- case 2: this->write(r.fRect.fRight, r.fRect.fTop); break;
- case 3: this->write(r.fRect.fRight, r.fRect.fBottom); break;
+ case 0: this->write(r.l, r.t); break;
+ case 1: this->write(r.l, r.b); break;
+ case 2: this->write(r.r, r.t); break;
+ case 3: this->write(r.r, r.b); break;
}
}
+
+ template <int corner>
+ void writeQuadValue(const GrQuad& q) {
+ this->write(q.point(corner));
+ }
};
#endif
diff --git a/src/gpu/ops/GrLatticeOp.cpp b/src/gpu/ops/GrLatticeOp.cpp
index 4cc766b..7551668 100644
--- a/src/gpu/ops/GrLatticeOp.cpp
+++ b/src/gpu/ops/GrLatticeOp.cpp
@@ -255,8 +255,8 @@
domain.store(&texDomain);
coords.store(&texCoords);
- vertices.writeQuad(GrVertexWriter::TriStrip{ dstR },
- GrVertexWriter::TriStrip{ texCoords },
+ vertices.writeQuad(GrVertexWriter::TriStripFromRect(dstR),
+ GrVertexWriter::TriStripFromRect(texCoords),
texDomain,
patchColor);
}
diff --git a/src/gpu/ops/GrRegionOp.cpp b/src/gpu/ops/GrRegionOp.cpp
index d824609..7f1ad81 100644
--- a/src/gpu/ops/GrRegionOp.cpp
+++ b/src/gpu/ops/GrRegionOp.cpp
@@ -121,7 +121,7 @@
SkRegion::Iterator iter(fRegions[i].fRegion);
while (!iter.done()) {
SkRect rect = SkRect::Make(iter.rect());
- vertices.writeQuad(GrVertexWriter::TriStrip{ rect }, color);
+ vertices.writeQuad(GrVertexWriter::TriStripFromRect(rect), color);
iter.next();
}
}
diff --git a/src/gpu/ops/GrSmallPathRenderer.cpp b/src/gpu/ops/GrSmallPathRenderer.cpp
index 215178c..2582262 100644
--- a/src/gpu/ops/GrSmallPathRenderer.cpp
+++ b/src/gpu/ops/GrSmallPathRenderer.cpp
@@ -15,6 +15,7 @@
#include "GrRenderTargetContext.h"
#include "GrResourceProvider.h"
#include "GrSimpleMeshDrawOpHelper.h"
+#include "GrVertexWriter.h"
#include "SkAutoMalloc.h"
#include "SkAutoPixmapStorage.h"
#include "SkDistanceFieldGen.h"
@@ -367,8 +368,7 @@
}
// allocate vertices
- size_t kVertexStride = flushInfo.fGeometryProcessor->vertexStride();
-
+ const size_t kVertexStride = flushInfo.fGeometryProcessor->vertexStride();
const GrBuffer* vertexBuffer;
// We need to make sure we don't overflow a 32 bit int when we request space in the
@@ -376,20 +376,18 @@
if (instanceCount > SK_MaxS32 / kVerticesPerQuad) {
return;
}
- void* vertices = target->makeVertexSpace(kVertexStride,
- kVerticesPerQuad * instanceCount,
- &vertexBuffer,
- &flushInfo.fVertexOffset);
+ GrVertexWriter vertices{target->makeVertexSpace(kVertexStride,
+ kVerticesPerQuad * instanceCount,
+ &vertexBuffer,
+ &flushInfo.fVertexOffset)};
flushInfo.fVertexBuffer.reset(SkRef(vertexBuffer));
flushInfo.fIndexBuffer = target->resourceProvider()->refQuadIndexBuffer();
- if (!vertices || !flushInfo.fIndexBuffer) {
+ if (!vertices.fPtr || !flushInfo.fIndexBuffer) {
SkDebugf("Could not allocate vertices\n");
return;
}
flushInfo.fInstancesToFlush = 0;
- // Pointer to the next set of vertices to write.
- intptr_t offset = reinterpret_cast<intptr_t>(vertices);
for (int i = 0; i < instanceCount; i++) {
const Entry& args = fShapes[i];
@@ -492,9 +490,8 @@
fAtlas->setLastUseToken(shapeData->fID, uploadTarget->tokenTracker()->nextDrawToken());
// TODO4F: Preserve float colors
- this->writePathVertices(fAtlas, offset, args.fColor.toBytes_RGBA(), kVertexStride,
- args.fViewMatrix, shapeData);
- offset += kVerticesPerQuad * kVertexStride;
+ this->writePathVertices(fAtlas, vertices, args.fColor.toBytes_RGBA(), args.fViewMatrix,
+ shapeData);
flushInfo.fInstancesToFlush++;
}
@@ -747,69 +744,34 @@
}
void writePathVertices(GrDrawOpAtlas* atlas,
- intptr_t offset,
+ GrVertexWriter& vertices,
GrColor color,
- size_t vertexStride,
const SkMatrix& ctm,
const ShapeData* shapeData) const {
- SkPoint* positions = reinterpret_cast<SkPoint*>(offset);
-
- SkRect bounds = shapeData->fBounds;
- SkRect translatedBounds(bounds);
+ SkRect translatedBounds(shapeData->fBounds);
if (!fUsesDistanceField) {
translatedBounds.offset(SkScalarFloorToScalar(ctm.get(SkMatrix::kMTransX)),
SkScalarFloorToScalar(ctm.get(SkMatrix::kMTransY)));
}
- // vertex positions
- // TODO make the vertex attributes a struct
+ // set up texture coordinates
+ GrVertexWriter::TriStrip<uint16_t> texCoords{
+ (uint16_t)shapeData->fTextureCoords.fLeft,
+ (uint16_t)shapeData->fTextureCoords.fTop,
+ (uint16_t)shapeData->fTextureCoords.fRight,
+ (uint16_t)shapeData->fTextureCoords.fBottom
+ };
+
if (fUsesDistanceField && !ctm.hasPerspective()) {
GrQuad quad(translatedBounds, ctm);
- intptr_t positionOffset = offset;
- SkPoint* position = (SkPoint*)positionOffset;
- *position = quad.point(0);
- positionOffset += vertexStride;
- position = (SkPoint*)positionOffset;
- *position = quad.point(1);
- positionOffset += vertexStride;
- position = (SkPoint*)positionOffset;
- *position = quad.point(2);
- positionOffset += vertexStride;
- position = (SkPoint*)positionOffset;
- *position = quad.point(3);
+ vertices.writeQuad(quad,
+ color,
+ texCoords);
} else {
- SkPointPriv::SetRectTriStrip(positions, translatedBounds, vertexStride);
+ vertices.writeQuad(GrVertexWriter::TriStripFromRect(translatedBounds),
+ color,
+ texCoords);
}
-
- // colors
- for (int i = 0; i < kVerticesPerQuad; i++) {
- GrColor* colorPtr = (GrColor*)(offset + sizeof(SkPoint) + i * vertexStride);
- *colorPtr = color;
- }
-
- // set up texture coordinates
- uint16_t l = shapeData->fTextureCoords.fLeft;
- uint16_t t = shapeData->fTextureCoords.fTop;
- uint16_t r = shapeData->fTextureCoords.fRight;
- uint16_t b = shapeData->fTextureCoords.fBottom;
-
- // set vertex texture coords
- intptr_t textureCoordOffset = offset + sizeof(SkPoint) + sizeof(GrColor);
- uint16_t* textureCoords = (uint16_t*) textureCoordOffset;
- textureCoords[0] = l;
- textureCoords[1] = t;
- textureCoordOffset += vertexStride;
- textureCoords = (uint16_t*)textureCoordOffset;
- textureCoords[0] = l;
- textureCoords[1] = b;
- textureCoordOffset += vertexStride;
- textureCoords = (uint16_t*)textureCoordOffset;
- textureCoords[0] = r;
- textureCoords[1] = t;
- textureCoordOffset += vertexStride;
- textureCoords = (uint16_t*)textureCoordOffset;
- textureCoords[0] = r;
- textureCoords[1] = b;
}
void flush(GrMeshDrawOp::Target* target, FlushInfo* flushInfo) const {