Improve SkVerticesPriv ergonomics
Rather than two separate (partially overlapping) ways of accessing the
private portions of SkVertices, use a single privileged helper class
(similar to GrContextPriv).
Change-Id: I76b14b63088658ed8726719cce126577e5a52078
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/280601
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
diff --git a/gm/3d.cpp b/gm/3d.cpp
index 0625042..99e65e9 100644
--- a/gm/3d.cpp
+++ b/gm/3d.cpp
@@ -7,6 +7,7 @@
#include "gm/gm.h"
#include "include/core/SkCanvas.h"
+#include "include/core/SkData.h"
struct Info {
float fNear = 0.05f;
diff --git a/gm/vertices.cpp b/gm/vertices.cpp
index 715ee0d..196e504 100644
--- a/gm/vertices.cpp
+++ b/gm/vertices.cpp
@@ -352,17 +352,16 @@
{256, 256}, {171, 256}, {85, 256}, {0, 256}, {0, 171}, {0, 85}};
auto patchVerts = SkPatchUtils::MakeVertices(pts, nullptr, nullptr, 12, 12);
- SkVertices::Info info;
- patchVerts->getInfo(&info);
+ SkVerticesPriv pv(patchVerts->priv());
SkVertices::CustomLayout customLayout { 1 };
- SkVertices::Builder builder(info.fMode, info.fVertexCount, info.fIndexCount, customLayout);
+ SkVertices::Builder builder(pv.mode(), pv.vertexCount(), pv.indexCount(), customLayout);
- memcpy(builder.positions(), info.fPositions, info.fVertexCount * sizeof(SkPoint));
- memcpy(builder.indices(), info.fIndices, info.fIndexCount * sizeof(uint16_t));
+ memcpy(builder.positions(), pv.positions(), pv.vertexCount() * sizeof(SkPoint));
+ memcpy(builder.indices(), pv.indices(), pv.indexCount() * sizeof(uint16_t));
SkRandom rnd;
- for (int i = 0; i < info.fVertexCount; ++i) {
+ for (int i = 0; i < pv.vertexCount(); ++i) {
builder.perVertexData()[i] = rnd.nextBool() ? 1.0f : 0.0f;
}
diff --git a/include/core/SkVertices.h b/include/core/SkVertices.h
index f789cc8..2a4c299 100644
--- a/include/core/SkVertices.h
+++ b/include/core/SkVertices.h
@@ -9,11 +9,13 @@
#define SkVertices_DEFINED
#include "include/core/SkColor.h"
-#include "include/core/SkData.h"
-#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
+class SkData;
+struct SkPoint;
+class SkVerticesPriv;
+
/**
* An immutable set of vertex data that can be used with SkCanvas::drawVertices.
*/
@@ -120,23 +122,20 @@
*/
sk_sp<SkData> encode() const;
- struct Info;
- void getInfo(Info*) const;
+ // Provides access to functions that aren't part of the public API.
+ SkVerticesPriv priv();
+ const SkVerticesPriv priv() const;
private:
SkVertices() {}
friend class SkVerticesPriv;
friend class SkDraw;
- friend class SkGpuDevice;
// these are needed since we've manually sized our allocation (see Builder::init)
friend class SkNVRefCnt<SkVertices>;
void operator delete(void* p);
- static sk_sp<SkVertices> Alloc(int vCount, int iCount, uint32_t builderFlags,
- size_t* arraySize);
-
Sizes getSizes() const;
VertexMode mode() const { return fMode; }
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index c6a25d6..85a1bcb 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -1986,16 +1986,13 @@
TRACE_EVENT0("skia", TRACE_FUNC);
RETURN_ON_NULL(vertices);
- SkVertices::Info info;
- vertices->getInfo(&info);
-
// We expect fans to be converted to triangles when building or deserializing SkVertices.
- SkASSERT(info.fMode != SkVertices::kTriangleFan_VertexMode);
+ SkASSERT(vertices->priv().mode() != SkVertices::kTriangleFan_VertexMode);
// If the vertices contain custom attributes, ensure they line up with the paint's shader
const SkRuntimeEffect* effect =
paint.getShader() ? as_SB(paint.getShader())->asRuntimeEffect() : nullptr;
- if (info.fPerVertexDataCount != (effect ? effect->varyingCount() : 0)) {
+ if (vertices->priv().perVertexDataCount() != (effect ? effect->varyingCount() : 0)) {
return;
}
diff --git a/src/core/SkVertices.cpp b/src/core/SkVertices.cpp
index 94fc5b3..f2abaad 100644
--- a/src/core/SkVertices.cpp
+++ b/src/core/SkVertices.cpp
@@ -415,21 +415,6 @@
return builder.detach();
}
-void SkVertices::operator delete(void* p)
-{
+void SkVertices::operator delete(void* p) {
::operator delete(p);
}
-
-void SkVertices::getInfo(Info* info) const {
- info->fMode = fMode;
-
- info->fVertexCount = fVertexCount;
- info->fIndexCount = fIndexCount;
- info->fPerVertexDataCount = fPerVertexDataCount;
-
- info->fPositions = fPositions;
- info->fIndices = fIndices;
- info->fTexCoords = fTexs;
- info->fColors = fColors;
- info->fPerVertexData = fPerVertexData;
-}
diff --git a/src/core/SkVerticesPriv.h b/src/core/SkVerticesPriv.h
index 5366188..fd7cbef 100644
--- a/src/core/SkVerticesPriv.h
+++ b/src/core/SkVerticesPriv.h
@@ -14,38 +14,46 @@
struct SkVertices_DeprecatedBoneWeights { float values[4]; };
struct SkVertices_DeprecatedBone { float values[6]; };
-struct SkVertices::Info {
- VertexMode fMode;
- bool fIsVolatile;
-
- int fVertexCount,
- fIndexCount,
- fPerVertexDataCount;
-
- const SkPoint* fPositions;
- const uint16_t* fIndices;
-
- // old version
- const SkPoint* fTexCoords; // may be null
- const SkColor* fColors; // may be null
-
- // new, per-vertex-data, version
- const float* fPerVertexData;
-
- bool hasTexCoords() const { return fTexCoords != nullptr; }
- bool hasColors() const { return fColors != nullptr; }
- bool hasPerVertexData() const { return fPerVertexData != nullptr; }
-};
-
+/** Class that adds methods to SkVertices that are only intended for use internal to Skia.
+ This class is purely a privileged window into SkVertices. It should never have additional
+ data members or virtual methods. */
class SkVerticesPriv {
public:
- static int VertexCount(const SkVertices* v) { return v->fVertexCount; }
+ SkVertices::VertexMode mode() const { return fVertices->fMode; }
- static bool HasTexCoords(const SkVertices* v) { return v->fTexs != nullptr; }
- static bool HasColors(const SkVertices* v) { return v->fColors != nullptr; }
- static bool HasIndices(const SkVertices* v) { return v->fIndices != nullptr; }
+ bool hasColors() const { return fVertices->hasColors(); }
+ bool hasTexCoords() const { return fVertices->hasTexCoords(); }
+ bool hasIndices() const { return fVertices->hasIndices(); }
+ bool hasPerVertexData() const { return fVertices->hasPerVertexData(); }
- static SkVertices::VertexMode Mode(const SkVertices* v) { return v->fMode; }
+ int vertexCount() const { return fVertices->fVertexCount; }
+ int indexCount() const { return fVertices->fIndexCount; }
+ int perVertexDataCount() const { return fVertices->fPerVertexDataCount; }
+
+ const SkPoint* positions() const { return fVertices->fPositions; }
+ const float* perVertexData() const { return fVertices->fPerVertexData; }
+ const SkPoint* texCoords() const { return fVertices->fTexs; }
+ const SkColor* colors() const { return fVertices->fColors; }
+ const uint16_t* indices() const { return fVertices->fIndices; }
+
+private:
+ explicit SkVerticesPriv(SkVertices* vertices) : fVertices(vertices) {}
+ SkVerticesPriv(const SkVerticesPriv&) = delete;
+ SkVerticesPriv& operator=(const SkVerticesPriv&) = delete;
+
+ // No taking addresses of this type
+ const SkVerticesPriv* operator&() const = delete;
+ SkVerticesPriv* operator&() = delete;
+
+ SkVertices* fVertices;
+
+ friend class SkVertices; // to construct this type
};
+inline SkVerticesPriv SkVertices::priv() { return SkVerticesPriv(this); }
+
+inline const SkVerticesPriv SkVertices::priv() const {
+ return SkVerticesPriv(const_cast<SkVertices*>(this));
+}
+
#endif
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 6ce878d..cceefdb 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1034,12 +1034,11 @@
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawVertices", fContext.get());
SkASSERT(vertices);
- SkVertices::Info info;
- vertices->getInfo(&info);
+ SkVerticesPriv info(vertices->priv());
const SkRuntimeEffect* effect =
paint.getShader() ? as_SB(paint.getShader())->asRuntimeEffect() : nullptr;
- SkASSERT(info.fPerVertexDataCount == (effect ? effect->varyingCount() : 0));
+ SkASSERT(info.perVertexDataCount() == (effect ? effect->varyingCount() : 0));
// Pretend that we have tex coords when using custom per-vertex data. The shader is going to
// use those (rather than local coords), but our paint conversion remains the same.
@@ -1048,9 +1047,8 @@
bool hasTexs = info.hasTexCoords() || info.hasPerVertexData();
if ((!hasTexs || !paint.getShader()) && !hasColors) {
// The dreaded wireframe mode. Fallback to drawVertices and go so slooooooow.
- this->wireframeVertices(vertices->mode(), vertices->vertexCount(), vertices->positions(),
- mode, vertices->indices(), vertices->indexCount(),
- paint);
+ this->wireframeVertices(info.mode(), info.vertexCount(), info.positions(), mode,
+ info.indices(), info.indexCount(), paint);
return;
}
if (!init_vertices_paint(fContext.get(), fRenderTargetContext->colorInfo(), paint,
diff --git a/src/gpu/ops/GrDrawVerticesOp.cpp b/src/gpu/ops/GrDrawVerticesOp.cpp
index d5d464b..87c15ae 100644
--- a/src/gpu/ops/GrDrawVerticesOp.cpp
+++ b/src/gpu/ops/GrDrawVerticesOp.cpp
@@ -301,13 +301,13 @@
bool fIgnoreColors;
bool hasPerVertexColors() const {
- return SkVerticesPriv::HasColors(fVertices.get()) && !fIgnoreColors;
+ return fVertices->priv().hasColors() && !fIgnoreColors;
}
};
bool isIndexed() const {
// Consistency enforced in onCombineIfPossible.
- return SkVerticesPriv::HasIndices(fMeshes[0].fVertices.get());
+ return fMeshes[0].fVertices->priv().hasIndices();
}
bool requiresPerVertexColors() const {
@@ -319,13 +319,10 @@
}
size_t vertexStride() const {
- SkVertices::Info info;
- fMeshes[0].fVertices->getInfo(&info);
-
return sizeof(SkPoint) +
(this->requiresPerVertexColors() ? sizeof(uint32_t) : 0) +
(this->requiresPerVertexLocalCoords() ? sizeof(SkPoint) : 0) +
- info.fPerVertexDataCount * sizeof(float);
+ fMeshes[0].fVertices->priv().perVertexDataCount() * sizeof(float);
}
Helper fHelper;
@@ -358,23 +355,22 @@
, fColorSpaceXform(std::move(colorSpaceXform)) {
SkASSERT(vertices);
- SkVertices::Info info;
- vertices->getInfo(&info);
+ SkVerticesPriv info(vertices->priv());
- fVertexCount = info.fVertexCount;
- fIndexCount = info.fIndexCount;
+ fVertexCount = info.vertexCount();
+ fIndexCount = info.indexCount();
fColorArrayType = info.hasColors() ? ColorArrayType::kSkColor
: ColorArrayType::kUnused;
fLocalCoordsType = info.hasTexCoords() ? LocalCoordsType::kExplicit
: LocalCoordsType::kUsePosition;
if (effect) {
- SkASSERT(info.fPerVertexDataCount == effect->varyingCount());
+ SkASSERT(info.perVertexDataCount() == effect->varyingCount());
for (const auto& v : effect->varyings()) {
fAttrWidths.push_back(v.fWidth);
}
} else {
- SkASSERT(info.fPerVertexDataCount == 0);
+ SkASSERT(info.perVertexDataCount() == 0);
}
Mesh& mesh = fMeshes.push_back();
@@ -483,22 +479,23 @@
int vertexOffset = 0;
for (const auto& mesh : fMeshes) {
- SkVertices::Info info;
- mesh.fVertices->getInfo(&info);
+ SkVerticesPriv info(mesh.fVertices->priv());
+
// Copy data into the index buffer.
if (indices) {
- int indexCount = info.fIndexCount;
+ int indexCount = info.indexCount();
for (int i = 0; i < indexCount; ++i) {
- *indices++ = info.fIndices[i] + vertexOffset;
+ *indices++ = info.indices()[i] + vertexOffset;
}
}
// Copy data into the vertex buffer.
- int vertexCount = info.fVertexCount;
- const SkPoint* positions = info.fPositions;
- const SkColor* colors = info.fColors;
- const SkPoint* localCoords = info.fTexCoords ? info.fTexCoords : positions;
- const float* custom = info.fPerVertexData;
+ int vertexCount = info.vertexCount();
+ const SkPoint* positions = info.positions();
+ const SkColor* colors = info.colors();
+ const SkPoint* localCoords = info.texCoords() ? info.texCoords() : positions;
+ const float* custom = info.perVertexData();
+ int customCount = info.perVertexDataCount();
// TODO4F: Preserve float colors
GrColor meshColor = mesh.fColor.toBytes_RGBA();
@@ -513,7 +510,7 @@
if (hasLocalCoordsAttribute) {
verts.write(localCoords[i]);
}
- for (int j = 0; j < info.fPerVertexDataCount; ++j) {
+ for (int j = 0; j < customCount; ++j) {
verts.write(*custom++);
}
}
@@ -643,8 +640,8 @@
const SkRuntimeEffect* effect) {
SkASSERT(vertices);
GrPrimitiveType primType = overridePrimType
- ? *overridePrimType
- : SkVertexModeToGrPrimitiveType(SkVerticesPriv::Mode(vertices.get()));
+ ? *overridePrimType
+ : SkVertexModeToGrPrimitiveType(vertices->priv().mode());
return GrSimpleMeshDrawOpHelper::FactoryHelper<DrawVerticesOp>(context, std::move(paint),
std::move(vertices),
primType, aaType,
diff --git a/src/pdf/SkDocument_PDF_None.cpp b/src/pdf/SkDocument_PDF_None.cpp
index 1b482ef..9593a5b 100644
--- a/src/pdf/SkDocument_PDF_None.cpp
+++ b/src/pdf/SkDocument_PDF_None.cpp
@@ -6,6 +6,7 @@
*/
#include "include/core/SkCanvas.h"
+#include "include/core/SkData.h"
#include "include/docs/SkPDFDocument.h"
class SkPDFArray {};
diff --git a/src/utils/SkShadowUtils.cpp b/src/utils/SkShadowUtils.cpp
index 73005fe..9d272e1 100644
--- a/src/utils/SkShadowUtils.cpp
+++ b/src/utils/SkShadowUtils.cpp
@@ -589,7 +589,7 @@
void SkBaseDevice::drawShadow(const SkPath& path, const SkDrawShadowRec& rec) {
auto drawVertsProc = [this](const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint,
SkScalar tx, SkScalar ty, bool hasPerspective) {
- if (SkVerticesPriv::VertexCount(vertices)) {
+ if (vertices->priv().vertexCount()) {
// For perspective shadows we've already computed the shadow in world space,
// and we can't translate it without changing it. Otherwise we concat the
// change in translation from the cached version.
diff --git a/tests/ShadowTest.cpp b/tests/ShadowTest.cpp
index 20bb826..8594010 100644
--- a/tests/ShadowTest.cpp
+++ b/tests/ShadowTest.cpp
@@ -26,9 +26,9 @@
expectSuccess ? "succeed" : "fail");
}
if (SkToBool(verts)) {
- if (kDont_ExpectVerts == expectVerts && SkVerticesPriv::VertexCount(verts.get())) {
+ if (kDont_ExpectVerts == expectVerts && verts->priv().vertexCount()) {
ERRORF(reporter, "Expected shadow tessellation to generate no vertices but it did.");
- } else if (kDo_ExpectVerts == expectVerts && !SkVerticesPriv::VertexCount(verts.get())) {
+ } else if (kDo_ExpectVerts == expectVerts && !verts->priv().vertexCount()) {
ERRORF(reporter, "Expected shadow tessellation to generate vertices but it didn't.");
}
}
diff --git a/tests/VerticesTest.cpp b/tests/VerticesTest.cpp
index 399bff2..7a7bff3 100644
--- a/tests/VerticesTest.cpp
+++ b/tests/VerticesTest.cpp
@@ -13,56 +13,54 @@
#include "tools/ToolUtils.h"
static bool equal(const SkVertices* vert0, const SkVertices* vert1) {
- SkVertices::Info v0, v1;
- vert0->getInfo(&v0);
- vert1->getInfo(&v1);
+ SkVerticesPriv v0(vert0->priv()), v1(vert1->priv());
- if (v0.fMode != v1.fMode) {
+ if (v0.mode() != v1.mode()) {
return false;
}
- if (v0.fVertexCount != v1.fVertexCount) {
+ if (v0.vertexCount() != v1.vertexCount()) {
return false;
}
- if (v0.fIndexCount != v1.fIndexCount) {
+ if (v0.indexCount() != v1.indexCount()) {
return false;
}
- if (v0.fPerVertexDataCount != v1.fPerVertexDataCount) {
+ if (v0.perVertexDataCount() != v1.perVertexDataCount()) {
return false;
}
- if (!!v0.fPerVertexData != !!v1.fPerVertexData) {
+ if (!!v0.perVertexData() != !!v1.perVertexData()) {
return false;
}
- if (!!v0.fTexCoords != !!v1.fTexCoords) {
+ if (!!v0.texCoords() != !!v1.texCoords()) {
return false;
}
- if (!!v0.fColors != !!v1.fColors) {
+ if (!!v0.colors() != !!v1.colors()) {
return false;
}
- for (int i = 0; i < v0.fVertexCount; ++i) {
- if (v0.fPositions[i] != v1.fPositions[i]) {
+ for (int i = 0; i < v0.vertexCount(); ++i) {
+ if (v0.positions()[i] != v1.positions()[i]) {
return false;
}
- if (v0.fTexCoords) {
- if (v0.fTexCoords[i] != v1.fTexCoords[i]) {
+ if (v0.texCoords()) {
+ if (v0.texCoords()[i] != v1.texCoords()[i]) {
return false;
}
}
- if (v0.fColors) {
- if (v0.fColors[i] != v1.fColors[i]) {
+ if (v0.colors()) {
+ if (v0.colors()[i] != v1.colors()[i]) {
return false;
}
}
}
- int totalVertexDataCount = v0.fVertexCount * v0.fPerVertexDataCount;
+ int totalVertexDataCount = v0.vertexCount() * v0.perVertexDataCount();
for (int i = 0; i < totalVertexDataCount; ++i) {
- if (v0.fPerVertexData[i] != v1.fPerVertexData[i]) {
+ if (v0.perVertexData()[i] != v1.perVertexData()[i]) {
return false;
}
}
- for (int i = 0; i < v0.fIndexCount; ++i) {
- if (v0.fIndices[i] != v1.fIndices[i]) {
+ for (int i = 0; i < v0.indexCount(); ++i) {
+ if (v0.indices()[i] != v1.indices()[i]) {
return false;
}
}