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