add SkVertices::Builder
Possible next iterations:
- remove another allocation use the SkData trick to share
the object and its (trailing) data
- store a bit that tells use to free each pointer, allowing
the builder to "adopt" some allocations instead of copy.
Larger idea:
- merge with drawPoints to have a single object for both.
BUG=skia:6366
Change-Id: Iec33239aa2ad5d00b36469ca0b88934ddf6f22eb
Reviewed-on: https://skia-review.googlesource.com/9604
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Mike Reed <reed@google.com>
diff --git a/gm/vertices.cpp b/gm/vertices.cpp
index a8f74bf..864ac3d 100644
--- a/gm/vertices.cpp
+++ b/gm/vertices.cpp
@@ -105,24 +105,8 @@
fShader2 = make_shader2();
fColorFilter = make_color_filter();
if (fUseObject) {
- std::unique_ptr<SkPoint[]> points(new SkPoint[kMeshVertexCnt]);
- std::unique_ptr<SkPoint[]> texs(new SkPoint[kMeshVertexCnt]);
- std::unique_ptr<SkColor[]> colors(new SkColor[kMeshVertexCnt]);
- std::unique_ptr<uint16_t[]> indices(new uint16_t[kMeshIndexCnt]);
- memcpy(points.get(), fPts, sizeof(SkPoint) * kMeshVertexCnt);
- memcpy(colors.get(), fColors, sizeof(SkColor) * kMeshVertexCnt);
- memcpy(texs.get(), fTexs, sizeof(SkPoint) * kMeshVertexCnt);
- memcpy(indices.get(), kMeshFan, sizeof(uint16_t) * kMeshIndexCnt);
- // Older libstdc++ does not allow moving a std::unique_ptr<T[]> into a
- // std::unique_ptr<const T[]>. Hence the release() calls below.
- fVertices = SkVertices::MakeIndexed(
- SkCanvas::kTriangleFan_VertexMode,
- std::unique_ptr<const SkPoint[]>((const SkPoint*)points.release()),
- std::unique_ptr<const SkColor[]>((const SkColor*)colors.release()),
- std::unique_ptr<const SkPoint[]>((const SkPoint*)texs.release()),
- kMeshVertexCnt,
- std::unique_ptr<const uint16_t[]>((const uint16_t*)indices.release()),
- kMeshIndexCnt);
+ fVertices = SkVertices::MakeCopy(SkCanvas::kTriangleFan_VertexMode, kMeshVertexCnt,
+ fPts, fTexs, fColors, kMeshIndexCnt, kMeshFan);
}
}
@@ -227,10 +211,15 @@
DEF_GM(return new VerticesGM(false, 1 / kShaderSize);)
static void draw_batching(SkCanvas* canvas, bool useObject) {
- std::unique_ptr<SkPoint[]> pts(new SkPoint[kMeshVertexCnt]);
- std::unique_ptr<SkPoint[]> texs(new SkPoint[kMeshVertexCnt]);
- std::unique_ptr<SkColor[]> colors(new SkColor[kMeshVertexCnt]);
- fill_mesh(pts.get(), texs.get(), colors.get(), 1);
+ // Triangle fans can't batch so we convert to regular triangles,
+ static constexpr int kNumTris = kMeshIndexCnt - 2;
+ SkVertices::Builder builder(SkCanvas::kTriangles_VertexMode, kMeshVertexCnt, 3 * kNumTris,
+ SkVertices::kHasColors_Flag | SkVertices::kHasTexs_Flag);
+
+ SkPoint* pts = builder.positions();
+ SkPoint* texs = builder.texCoords();
+ SkColor* colors = builder.colors();
+ fill_mesh(pts, texs, colors, 1);
SkTDArray<SkMatrix> matrices;
matrices.push()->reset();
@@ -242,26 +231,17 @@
auto shader = make_shader1(1);
- // Triangle fans can't batch so we convert to regular triangles,
- static constexpr int kNumTris = kMeshIndexCnt - 2;
- std::unique_ptr<uint16_t[]> indices(new uint16_t[3 * kNumTris]);
+ uint16_t* indices = builder.indices();
for (size_t i = 0; i < kNumTris; ++i) {
indices[3 * i] = kMeshFan[0];
indices[3 * i + 1] = kMeshFan[i + 1];
indices[3 * i + 2] = kMeshFan[i + 2];
+
}
sk_sp<SkVertices> vertices;
if (useObject) {
- // Older libstdc++ does not allow moving a std::unique_ptr<T[]> into a
- // std::unique_ptr<const T[]>. Hence the release() calls below.
- vertices = SkVertices::MakeIndexed(
- SkCanvas::kTriangles_VertexMode,
- std::unique_ptr<const SkPoint[]>((const SkPoint*)pts.release()),
- std::unique_ptr<const SkColor[]>((const SkColor*)colors.release()),
- std::unique_ptr<const SkPoint[]>((const SkPoint*)texs.release()), kMeshVertexCnt,
- std::unique_ptr<const uint16_t[]>((const uint16_t*)indices.release()),
- 3 * kNumTris);
+ vertices = builder.detach();
}
canvas->save();
canvas->translate(10, 10);
@@ -276,9 +256,9 @@
uint32_t flags = useTex ? 0 : SkCanvas::kIgnoreTexCoords_VerticesFlag;
canvas->drawVertices(vertices, SkBlendMode::kModulate, paint, flags);
} else {
- const SkPoint* t = useTex ? texs.get() : nullptr;
- canvas->drawVertices(SkCanvas::kTriangles_VertexMode, kMeshVertexCnt, pts.get(),
- t, colors.get(), indices.get(), kNumTris * 3, paint);
+ const SkPoint* t = useTex ? texs : nullptr;
+ canvas->drawVertices(SkCanvas::kTriangles_VertexMode, kMeshVertexCnt, pts,
+ t, colors, indices, kNumTris * 3, paint);
}
canvas->restore();
}