1 /*
2 * Copyright 2017 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
9
10 #include "include/gpu/GrTypes.h"
11 #include "src/gpu/glsl/GrGLSLProgramBuilder.h"
12 #include "src/gpu/glsl/GrGLSLVarying.h"
13
emitNormalizedSkPosition(SkString * out,const char * devPos,GrSLType devPosType)14 void GrGLSLVertexGeoBuilder::emitNormalizedSkPosition(SkString* out, const char* devPos,
15 GrSLType devPosType) {
16 if (this->getProgramBuilder()->snapVerticesToPixelCenters()) {
17 if (kFloat3_GrSLType == devPosType) {
18 const char* p = devPos;
19 out->appendf("{float2 _posTmp = float2(%s.x/%s.z, %s.y/%s.z);", p, p, p, p);
20 } else {
21 SkASSERT(kFloat2_GrSLType == devPosType);
22 out->appendf("{float2 _posTmp = %s;", devPos);
23 }
24 out->appendf("_posTmp = floor(_posTmp) + half2(0.5, 0.5);"
25 "sk_Position = float4(_posTmp, 0, 1);}");
26 } else if (kFloat3_GrSLType == devPosType) {
27 out->appendf("sk_Position = float4(%s.x , %s.y, 0, %s.z);",
28 devPos, devPos, devPos);
29 } else {
30 SkASSERT(kFloat2_GrSLType == devPosType);
31 out->appendf("sk_Position = float4(%s.x , %s.y, 0, 1);",
32 devPos, devPos);
33 }
34 }
35
onFinalize()36 void GrGLSLVertexBuilder::onFinalize() {
37 // We could have the GrGeometryProcessor do this, but its just easier to have it performed
38 // here. If we ever need to set variable pointsize, then we can reinvestigate.
39 if (this->getProgramBuilder()->hasPointSize()) {
40 this->codeAppend("sk_PointSize = 1.0;");
41 }
42 fProgramBuilder->varyingHandler()->getVertexDecls(&this->inputs(), &this->outputs());
43 }
44
input_type_name(GrGLSLGeometryBuilder::InputType in)45 static const char* input_type_name(GrGLSLGeometryBuilder::InputType in) {
46 using InputType = GrGLSLGeometryBuilder::InputType;
47 switch (in) {
48 case InputType::kPoints: return "points";
49 case InputType::kLines: return "lines";
50 case InputType::kTriangles: return "triangles";
51 }
52 SK_ABORT("invalid input type");
53 }
54
output_type_name(GrGLSLGeometryBuilder::OutputType out)55 static const char* output_type_name(GrGLSLGeometryBuilder::OutputType out) {
56 using OutputType = GrGLSLGeometryBuilder::OutputType;
57 switch (out) {
58 case OutputType::kPoints: return "points";
59 case OutputType::kLineStrip: return "line_strip";
60 case OutputType::kTriangleStrip: return "triangle_strip";
61 }
62 SK_ABORT("invalid output type");
63 }
64
configure(InputType inputType,OutputType outputType,int maxVertices,int numInvocations)65 void GrGLSLGeometryBuilder::configure(InputType inputType, OutputType outputType, int maxVertices,
66 int numInvocations) {
67 SkASSERT(!this->isConfigured());
68 fNumInvocations = numInvocations;
69 this->addLayoutQualifier(input_type_name(inputType), kIn_InterfaceQualifier);
70 this->addLayoutQualifier(SkStringPrintf("invocations = %i", numInvocations).c_str(),
71 kIn_InterfaceQualifier);
72 this->addLayoutQualifier(output_type_name(outputType), kOut_InterfaceQualifier);
73 this->addLayoutQualifier(SkStringPrintf("max_vertices = %i", maxVertices).c_str(),
74 kOut_InterfaceQualifier);
75 }
76
emitVertex(SkString * out,const char * devPos,GrSLType devPosType)77 void GrGLSLGeometryBuilder::emitVertex(SkString* out, const char* devPos, GrSLType devPosType) {
78 this->emitNormalizedSkPosition(out, devPos, devPosType);
79 out->append("EmitVertex();");
80 }
81
endPrimitive()82 void GrGLSLGeometryBuilder::endPrimitive() {
83 this->codeAppend("EndPrimitive();");
84 }
85
onFinalize()86 void GrGLSLGeometryBuilder::onFinalize() {
87 SkASSERT(this->isConfigured());
88 fProgramBuilder->varyingHandler()->getGeomDecls(&this->inputs(), &this->outputs());
89 }
90