Convert geometry shaders to operate in Skia device space
Defers the transformation to normalized window coordinates until after
the geometry shader. Merges vertex and a geometry shader builders into
a single compilation unit with a common base class. Updates CCPR
geometry shaders accordingly.
Bug: skia:
Change-Id: If93c90e978b1fdc7120febd05cfb05810fd496b5
Reviewed-on: https://skia-review.googlesource.com/62980
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
diff --git a/src/gpu/glsl/GrGLSLVertexGeoBuilder.cpp b/src/gpu/glsl/GrGLSLVertexGeoBuilder.cpp
new file mode 100644
index 0000000..1cf85f7
--- /dev/null
+++ b/src/gpu/glsl/GrGLSLVertexGeoBuilder.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrGLSLVertexGeoBuilder.h"
+
+#include "GrGLSLProgramBuilder.h"
+#include "GrGLSLVarying.h"
+#include "GrTypes.h"
+
+void GrGLSLVertexGeoBuilder::emitNormalizedSkPosition(SkString* out, const char* devPos,
+ const char* rtAdjustName,
+ GrSLType devPosType) {
+ if (this->getProgramBuilder()->desc()->header().fSnapVerticesToPixelCenters) {
+ if (kFloat3_GrSLType == devPosType) {
+ const char* p = devPos;
+ out->appendf("{float2 _posTmp = float2(%s.x/%s.z, %s.y/%s.z);", p, p, p, p);
+ } else {
+ SkASSERT(kFloat2_GrSLType == devPosType);
+ out->appendf("{float2 _posTmp = %s;", devPos);
+ }
+ out->appendf("_posTmp = floor(_posTmp) + half2(0.5, 0.5);"
+ "sk_Position = float4(_posTmp.x * %s.x + %s.y,"
+ "_posTmp.y * %s.z + %s.w, 0, 1);}",
+ rtAdjustName, rtAdjustName, rtAdjustName, rtAdjustName);
+ } else if (kFloat3_GrSLType == devPosType) {
+ out->appendf("sk_Position = float4(dot(%s.xz, %s.xy), dot(%s.yz, %s.zw), 0, %s.z);",
+ devPos, rtAdjustName, devPos, rtAdjustName, devPos);
+ } else {
+ SkASSERT(kFloat2_GrSLType == devPosType);
+ out->appendf("sk_Position = float4(%s.x * %s.x + %s.y, %s.y * %s.z + %s.w, 0, 1);",
+ devPos, rtAdjustName, rtAdjustName, devPos, rtAdjustName, rtAdjustName);
+ }
+}
+
+void GrGLSLVertexBuilder::onFinalize() {
+ // We could have the GrGeometryProcessor do this, but its just easier to have it performed
+ // here. If we ever need to set variable pointsize, then we can reinvestigate.
+ if (this->getProgramBuilder()->desc()->header().fHasPointSize) {
+ this->codeAppend("sk_PointSize = 1.0;");
+ }
+ fProgramBuilder->varyingHandler()->getVertexDecls(&this->inputs(), &this->outputs());
+}
+
+static const char* input_type_name(GrGLSLGeometryBuilder::InputType in) {
+ using InputType = GrGLSLGeometryBuilder::InputType;
+ switch (in) {
+ case InputType::kPoints: return "points";
+ case InputType::kLines: return "lines";
+ case InputType::kLinesAdjacency: return "lines_adjacency";
+ case InputType::kTriangles: return "triangles";
+ case InputType::kTrianglesAdjacency: return "triangles_adjacency";
+ }
+ SK_ABORT("invalid input type");
+ return "unknown_input";
+}
+
+static const char* output_type_name(GrGLSLGeometryBuilder::OutputType out) {
+ using OutputType = GrGLSLGeometryBuilder::OutputType;
+ switch (out) {
+ case OutputType::kPoints: return "points";
+ case OutputType::kLineStrip: return "line_strip";
+ case OutputType::kTriangleStrip: return "triangle_strip";
+ }
+ SK_ABORT("invalid output type");
+ return "unknown_output";
+}
+
+void GrGLSLGeometryBuilder::configure(InputType inputType, OutputType outputType, int maxVertices,
+ int numInvocations) {
+ SkASSERT(!this->isConfigured());
+ fNumInvocations = numInvocations;
+ this->addLayoutQualifier(input_type_name(inputType), kIn_InterfaceQualifier);
+ this->addLayoutQualifier(SkStringPrintf("invocations = %i", numInvocations).c_str(),
+ kIn_InterfaceQualifier);
+ this->addLayoutQualifier(output_type_name(outputType), kOut_InterfaceQualifier);
+ this->addLayoutQualifier(SkStringPrintf("max_vertices = %i", maxVertices).c_str(),
+ kOut_InterfaceQualifier);
+}
+
+void GrGLSLGeometryBuilder::emitVertex(SkString* out, const char* devPos, const char* rtAdjustName,
+ GrSLType devPosType) {
+ this->emitNormalizedSkPosition(out, devPos, rtAdjustName, devPosType);
+ out->append("EmitVertex();");
+}
+
+void GrGLSLGeometryBuilder::endPrimitive() {
+ this->codeAppend("EndPrimitive();");
+}
+
+void GrGLSLGeometryBuilder::onFinalize() {
+ SkASSERT(this->isConfigured());
+ fProgramBuilder->varyingHandler()->getGeomDecls(&this->inputs(), &this->outputs());
+}