Validate per-vertex vertices data against effect in SkCanvas
Updates the vertices_data GM to work on the GPU backend, too. For now,
it still works on the CPU via the original hack.
Bug: skia:9984
Change-Id: I2e11bd01e3cc953d2837ecd6ca8b2305b060e5fc
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/278857
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/gm/vertices.cpp b/gm/vertices.cpp
index 5950263..715ee0d 100644
--- a/gm/vertices.cpp
+++ b/gm/vertices.cpp
@@ -297,7 +297,14 @@
auto vert = builder.detach();
SkPaint paint;
- // paint.setShader(sksl_shader);
+ const char* gProg = R"(
+ varying float4 vtx_color;
+ void main(float2 p, inout half4 color) {
+ color = half4(vtx_color);
+ }
+ )";
+ auto [effect, errorText] = SkRuntimeEffect::Make(SkString(gProg));
+ paint.setShader(effect->makeShader(nullptr, nullptr, 0, nullptr, true));
canvas->drawVertices(vert, paint);
}
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 01ca4b0..61e7b89 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -17,6 +17,7 @@
#include "include/core/SkString.h"
#include "include/core/SkTextBlob.h"
#include "include/core/SkVertices.h"
+#include "include/effects/SkRuntimeEffect.h"
#include "include/private/SkNx.h"
#include "include/private/SkTo.h"
#include "include/utils/SkNoDrawCanvas.h"
@@ -1984,8 +1985,20 @@
void SkCanvas::drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint) {
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(SkVerticesPriv::Mode(vertices) != SkVertices::kTriangleFan_VertexMode);
+ SkASSERT(info.fMode != 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)) {
+ return;
+ }
+
this->onDrawVerticesObject(vertices, mode, paint);
}
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 22ee64f..6ce878d 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1039,12 +1039,7 @@
const SkRuntimeEffect* effect =
paint.getShader() ? as_SB(paint.getShader())->asRuntimeEffect() : nullptr;
- int shaderVaryingCount = effect ? effect->varyingCount() : 0;
-
- // TODO: Hoist this check up to SkCanvas
- if (shaderVaryingCount != info.fPerVertexDataCount) {
- return;
- }
+ SkASSERT(info.fPerVertexDataCount == (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.