Use GrVertexWriter in AA convex path renderer
Bug: skia: Change-Id: I7f4107ee64079a00302fc3fa9b81fba73b5f3219 Reviewed-on: https://skia-review.googlesource.com/c/179989 Commit-Queue: Brian Osman <brianosman@google.com> Reviewed-by: Chris Dalton <csmartdalton@google.com>
This commit is contained in:
parent
0b5370363d
commit
d2fa2eb59f
@ -41,6 +41,9 @@ struct GrVertexWriter {
|
|||||||
return Conditional<T>(condition, value);
|
return Conditional<T>(condition, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct Skip {};
|
||||||
|
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
void write(const T& val, const Args&... remainder) {
|
void write(const T& val, const Args&... remainder) {
|
||||||
static_assert(std::is_pod<T>::value, "");
|
static_assert(std::is_pod<T>::value, "");
|
||||||
@ -79,6 +82,12 @@ struct GrVertexWriter {
|
|||||||
this->write(remainder...);
|
this->write(remainder...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
void write(const Skip<T>& val, const Args&... remainder) {
|
||||||
|
fPtr = SkTAddOffset<void>(fPtr, sizeof(T));
|
||||||
|
this->write(remainder...);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
void write(const Sk4f& vector, const Args&... remainder) {
|
void write(const Sk4f& vector, const Args&... remainder) {
|
||||||
float buffer[4];
|
float buffer[4];
|
||||||
|
@ -340,14 +340,6 @@ static bool get_segments(const SkPath& path,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct QuadVertex {
|
|
||||||
SkPoint fPos;
|
|
||||||
GrColor fColor;
|
|
||||||
SkPoint fUV;
|
|
||||||
SkScalar fD0;
|
|
||||||
SkScalar fD1;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Draw {
|
struct Draw {
|
||||||
Draw() : fVertexCnt(0), fIndexCnt(0) {}
|
Draw() : fVertexCnt(0), fIndexCnt(0) {}
|
||||||
int fVertexCnt;
|
int fVertexCnt;
|
||||||
@ -360,8 +352,9 @@ static void create_vertices(const SegmentArray& segments,
|
|||||||
const SkPoint& fanPt,
|
const SkPoint& fanPt,
|
||||||
GrColor color,
|
GrColor color,
|
||||||
DrawArray* draws,
|
DrawArray* draws,
|
||||||
QuadVertex* verts,
|
GrVertexWriter& verts,
|
||||||
uint16_t* idxs) {
|
uint16_t* idxs,
|
||||||
|
size_t vertexStride) {
|
||||||
Draw* draw = &draws->push_back();
|
Draw* draw = &draws->push_back();
|
||||||
// alias just to make vert/index assignments easier to read.
|
// alias just to make vert/index assignments easier to read.
|
||||||
int* v = &draw->fVertexCnt;
|
int* v = &draw->fVertexCnt;
|
||||||
@ -382,30 +375,21 @@ static void create_vertices(const SegmentArray& segments,
|
|||||||
vCount += 6;
|
vCount += 6;
|
||||||
}
|
}
|
||||||
if (draw->fVertexCnt + vCount > (1 << 16)) {
|
if (draw->fVertexCnt + vCount > (1 << 16)) {
|
||||||
verts += *v;
|
|
||||||
idxs += *i;
|
idxs += *i;
|
||||||
draw = &draws->push_back();
|
draw = &draws->push_back();
|
||||||
v = &draw->fVertexCnt;
|
v = &draw->fVertexCnt;
|
||||||
i = &draw->fIndexCnt;
|
i = &draw->fIndexCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SkScalar negOneDists[2] = { -SK_Scalar1, -SK_Scalar1 };
|
||||||
|
|
||||||
// FIXME: These tris are inset in the 1 unit arc around the corner
|
// FIXME: These tris are inset in the 1 unit arc around the corner
|
||||||
verts[*v + 0].fPos = sega.endPt();
|
SkPoint p0 = sega.endPt();
|
||||||
verts[*v + 1].fPos = verts[*v + 0].fPos + sega.endNorm();
|
// Position, Color, UV, D0, D1
|
||||||
verts[*v + 2].fPos = verts[*v + 0].fPos + segb.fMid;
|
verts.write(p0, color, SkPoint{0, 0}, negOneDists);
|
||||||
verts[*v + 3].fPos = verts[*v + 0].fPos + segb.fNorms[0];
|
verts.write(p0 + sega.endNorm(), color, SkPoint{0, -SK_Scalar1}, negOneDists);
|
||||||
verts[*v + 0].fColor = color;
|
verts.write(p0 + segb.fMid, color, SkPoint{0, -SK_Scalar1}, negOneDists);
|
||||||
verts[*v + 1].fColor = color;
|
verts.write(p0 + segb.fNorms[0], color, SkPoint{0, -SK_Scalar1}, negOneDists);
|
||||||
verts[*v + 2].fColor = color;
|
|
||||||
verts[*v + 3].fColor = color;
|
|
||||||
verts[*v + 0].fUV.set(0,0);
|
|
||||||
verts[*v + 1].fUV.set(0,-SK_Scalar1);
|
|
||||||
verts[*v + 2].fUV.set(0,-SK_Scalar1);
|
|
||||||
verts[*v + 3].fUV.set(0,-SK_Scalar1);
|
|
||||||
verts[*v + 0].fD0 = verts[*v + 0].fD1 = -SK_Scalar1;
|
|
||||||
verts[*v + 1].fD0 = verts[*v + 1].fD1 = -SK_Scalar1;
|
|
||||||
verts[*v + 2].fD0 = verts[*v + 2].fD1 = -SK_Scalar1;
|
|
||||||
verts[*v + 3].fD0 = verts[*v + 3].fD1 = -SK_Scalar1;
|
|
||||||
|
|
||||||
idxs[*i + 0] = *v + 0;
|
idxs[*i + 0] = *v + 0;
|
||||||
idxs[*i + 1] = *v + 2;
|
idxs[*i + 1] = *v + 2;
|
||||||
@ -418,34 +402,17 @@ static void create_vertices(const SegmentArray& segments,
|
|||||||
*i += 6;
|
*i += 6;
|
||||||
|
|
||||||
if (Segment::kLine == segb.fType) {
|
if (Segment::kLine == segb.fType) {
|
||||||
verts[*v + 0].fPos = fanPt;
|
|
||||||
verts[*v + 1].fPos = sega.endPt();
|
|
||||||
verts[*v + 2].fPos = segb.fPts[0];
|
|
||||||
|
|
||||||
verts[*v + 3].fPos = verts[*v + 1].fPos + segb.fNorms[0];
|
|
||||||
verts[*v + 4].fPos = verts[*v + 2].fPos + segb.fNorms[0];
|
|
||||||
|
|
||||||
verts[*v + 0].fColor = color;
|
|
||||||
verts[*v + 1].fColor = color;
|
|
||||||
verts[*v + 2].fColor = color;
|
|
||||||
verts[*v + 3].fColor = color;
|
|
||||||
verts[*v + 4].fColor = color;
|
|
||||||
|
|
||||||
// we draw the line edge as a degenerate quad (u is 0, v is the
|
// we draw the line edge as a degenerate quad (u is 0, v is the
|
||||||
// signed distance to the edge)
|
// signed distance to the edge)
|
||||||
SkScalar dist = SkPointPriv::DistanceToLineBetween(fanPt, verts[*v + 1].fPos,
|
SkPoint v1Pos = sega.endPt();
|
||||||
verts[*v + 2].fPos);
|
SkPoint v2Pos = segb.fPts[0];
|
||||||
verts[*v + 0].fUV.set(0, dist);
|
SkScalar dist = SkPointPriv::DistanceToLineBetween(fanPt, v1Pos, v2Pos);
|
||||||
verts[*v + 1].fUV.set(0, 0);
|
|
||||||
verts[*v + 2].fUV.set(0, 0);
|
|
||||||
verts[*v + 3].fUV.set(0, -SK_Scalar1);
|
|
||||||
verts[*v + 4].fUV.set(0, -SK_Scalar1);
|
|
||||||
|
|
||||||
verts[*v + 0].fD0 = verts[*v + 0].fD1 = -SK_Scalar1;
|
verts.write(fanPt, color, SkPoint{0, dist}, negOneDists);
|
||||||
verts[*v + 1].fD0 = verts[*v + 1].fD1 = -SK_Scalar1;
|
verts.write(v1Pos, color, SkPoint{0, 0}, negOneDists);
|
||||||
verts[*v + 2].fD0 = verts[*v + 2].fD1 = -SK_Scalar1;
|
verts.write(v2Pos, color, SkPoint{0, 0}, negOneDists);
|
||||||
verts[*v + 3].fD0 = verts[*v + 3].fD1 = -SK_Scalar1;
|
verts.write(v1Pos + segb.fNorms[0], color, SkPoint{0, -SK_Scalar1}, negOneDists);
|
||||||
verts[*v + 4].fD0 = verts[*v + 4].fD1 = -SK_Scalar1;
|
verts.write(v2Pos + segb.fNorms[0], color, SkPoint{0, -SK_Scalar1}, negOneDists);
|
||||||
|
|
||||||
idxs[*i + 0] = *v + 3;
|
idxs[*i + 0] = *v + 3;
|
||||||
idxs[*i + 1] = *v + 1;
|
idxs[*i + 1] = *v + 1;
|
||||||
@ -470,43 +437,49 @@ static void create_vertices(const SegmentArray& segments,
|
|||||||
|
|
||||||
*v += 5;
|
*v += 5;
|
||||||
} else {
|
} else {
|
||||||
|
void* quadVertsBegin = verts.fPtr;
|
||||||
|
|
||||||
SkPoint qpts[] = {sega.endPt(), segb.fPts[0], segb.fPts[1]};
|
SkPoint qpts[] = {sega.endPt(), segb.fPts[0], segb.fPts[1]};
|
||||||
|
|
||||||
|
SkScalar c0 = segb.fNorms[0].dot(qpts[0]);
|
||||||
|
SkScalar c1 = segb.fNorms[1].dot(qpts[2]);
|
||||||
|
GrVertexWriter::Skip<SkPoint> skipUVs;
|
||||||
|
|
||||||
|
verts.write(fanPt,
|
||||||
|
color, skipUVs,
|
||||||
|
-segb.fNorms[0].dot(fanPt) + c0,
|
||||||
|
-segb.fNorms[1].dot(fanPt) + c1);
|
||||||
|
|
||||||
|
verts.write(qpts[0],
|
||||||
|
color, skipUVs,
|
||||||
|
0.0f,
|
||||||
|
-segb.fNorms[1].dot(qpts[0]) + c1);
|
||||||
|
|
||||||
|
verts.write(qpts[2],
|
||||||
|
color, skipUVs,
|
||||||
|
-segb.fNorms[0].dot(qpts[2]) + c0,
|
||||||
|
0.0f);
|
||||||
|
|
||||||
|
verts.write(qpts[0] + segb.fNorms[0],
|
||||||
|
color, skipUVs,
|
||||||
|
-SK_ScalarMax/100,
|
||||||
|
-SK_ScalarMax/100);
|
||||||
|
|
||||||
|
verts.write(qpts[2] + segb.fNorms[1],
|
||||||
|
color, skipUVs,
|
||||||
|
-SK_ScalarMax/100,
|
||||||
|
-SK_ScalarMax/100);
|
||||||
|
|
||||||
SkVector midVec = segb.fNorms[0] + segb.fNorms[1];
|
SkVector midVec = segb.fNorms[0] + segb.fNorms[1];
|
||||||
midVec.normalize();
|
midVec.normalize();
|
||||||
|
|
||||||
verts[*v + 0].fPos = fanPt;
|
verts.write(qpts[1] + midVec,
|
||||||
verts[*v + 1].fPos = qpts[0];
|
color, skipUVs,
|
||||||
verts[*v + 2].fPos = qpts[2];
|
-SK_ScalarMax/100,
|
||||||
verts[*v + 3].fPos = qpts[0] + segb.fNorms[0];
|
-SK_ScalarMax/100);
|
||||||
verts[*v + 4].fPos = qpts[2] + segb.fNorms[1];
|
|
||||||
verts[*v + 5].fPos = qpts[1] + midVec;
|
|
||||||
|
|
||||||
verts[*v + 0].fColor = color;
|
|
||||||
verts[*v + 1].fColor = color;
|
|
||||||
verts[*v + 2].fColor = color;
|
|
||||||
verts[*v + 3].fColor = color;
|
|
||||||
verts[*v + 4].fColor = color;
|
|
||||||
verts[*v + 5].fColor = color;
|
|
||||||
|
|
||||||
SkScalar c = segb.fNorms[0].dot(qpts[0]);
|
|
||||||
verts[*v + 0].fD0 = -segb.fNorms[0].dot(fanPt) + c;
|
|
||||||
verts[*v + 1].fD0 = 0.f;
|
|
||||||
verts[*v + 2].fD0 = -segb.fNorms[0].dot(qpts[2]) + c;
|
|
||||||
verts[*v + 3].fD0 = -SK_ScalarMax/100;
|
|
||||||
verts[*v + 4].fD0 = -SK_ScalarMax/100;
|
|
||||||
verts[*v + 5].fD0 = -SK_ScalarMax/100;
|
|
||||||
|
|
||||||
c = segb.fNorms[1].dot(qpts[2]);
|
|
||||||
verts[*v + 0].fD1 = -segb.fNorms[1].dot(fanPt) + c;
|
|
||||||
verts[*v + 1].fD1 = -segb.fNorms[1].dot(qpts[0]) + c;
|
|
||||||
verts[*v + 2].fD1 = 0.f;
|
|
||||||
verts[*v + 3].fD1 = -SK_ScalarMax/100;
|
|
||||||
verts[*v + 4].fD1 = -SK_ScalarMax/100;
|
|
||||||
verts[*v + 5].fD1 = -SK_ScalarMax/100;
|
|
||||||
|
|
||||||
GrPathUtils::QuadUVMatrix toUV(qpts);
|
GrPathUtils::QuadUVMatrix toUV(qpts);
|
||||||
toUV.apply(verts + *v, 6, sizeof(QuadVertex), offsetof(QuadVertex, fUV));
|
toUV.apply(quadVertsBegin, 6, vertexStride, sizeof(SkPoint) + sizeof(GrColor));
|
||||||
|
|
||||||
idxs[*i + 0] = *v + 3;
|
idxs[*i + 0] = *v + 3;
|
||||||
idxs[*i + 1] = *v + 1;
|
idxs[*i + 1] = *v + 1;
|
||||||
@ -785,11 +758,11 @@ private:
|
|||||||
const GrBuffer* vertexBuffer;
|
const GrBuffer* vertexBuffer;
|
||||||
int firstVertex;
|
int firstVertex;
|
||||||
|
|
||||||
SkASSERT(sizeof(QuadVertex) == quadProcessor->vertexStride());
|
const size_t kVertexStride = quadProcessor->vertexStride();
|
||||||
QuadVertex* verts = reinterpret_cast<QuadVertex*>(target->makeVertexSpace(
|
GrVertexWriter verts{target->makeVertexSpace(kVertexStride, vertexCount,
|
||||||
sizeof(QuadVertex), vertexCount, &vertexBuffer, &firstVertex));
|
&vertexBuffer, &firstVertex)};
|
||||||
|
|
||||||
if (!verts) {
|
if (!verts.fPtr) {
|
||||||
SkDebugf("Could not allocate vertices\n");
|
SkDebugf("Could not allocate vertices\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -805,7 +778,8 @@ private:
|
|||||||
|
|
||||||
SkSTArray<kPreallocDrawCnt, Draw, true> draws;
|
SkSTArray<kPreallocDrawCnt, Draw, true> draws;
|
||||||
// TODO4F: Preserve float colors
|
// TODO4F: Preserve float colors
|
||||||
create_vertices(segments, fanPt, args.fColor.toBytes_RGBA(), &draws, verts, idxs);
|
create_vertices(segments, fanPt, args.fColor.toBytes_RGBA(), &draws, verts, idxs,
|
||||||
|
kVertexStride);
|
||||||
|
|
||||||
GrMesh* meshes = target->allocMeshes(draws.count());
|
GrMesh* meshes = target->allocMeshes(draws.count());
|
||||||
for (int j = 0; j < draws.count(); ++j) {
|
for (int j = 0; j < draws.count(); ++j) {
|
||||||
|
Loading…
Reference in New Issue
Block a user