• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 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 "GrGLSLGeometryShaderBuilder.h"
9 #include "GrGLSLProgramBuilder.h"
10 #include "GrGLSLVarying.h"
11 
input_type_name(GrGLSLGeometryBuilder::InputType in)12 static const char* input_type_name(GrGLSLGeometryBuilder::InputType in) {
13     using InputType = GrGLSLGeometryBuilder::InputType;
14     switch (in) {
15         case InputType::kPoints: return "points";
16         case InputType::kLines: return "lines";
17         case InputType::kLinesAdjacency: return "lines_adjacency";
18         case InputType::kTriangles: return "triangles";
19         case InputType::kTrianglesAdjacency: return "triangles_adjacency";
20     }
21     SkFAIL("invalid input type");
22     return "unknown_input";
23 }
24 
output_type_name(GrGLSLGeometryBuilder::OutputType out)25 static const char* output_type_name(GrGLSLGeometryBuilder::OutputType out) {
26     using OutputType = GrGLSLGeometryBuilder::OutputType;
27     switch (out) {
28         case OutputType::kPoints: return "points";
29         case OutputType::kLineStrip: return "line_strip";
30         case OutputType::kTriangleStrip: return "triangle_strip";
31     }
32     SkFAIL("invalid output type");
33     return "unknown_output";
34 }
35 
GrGLSLGeometryBuilder(GrGLSLProgramBuilder * program)36 GrGLSLGeometryBuilder::GrGLSLGeometryBuilder(GrGLSLProgramBuilder* program)
37     : INHERITED(program)
38     , fNumInvocations(0) {
39 }
40 
configure(InputType inputType,OutputType outputType,int maxVertices,int numInvocations)41 void GrGLSLGeometryBuilder::configure(InputType inputType, OutputType outputType, int maxVertices,
42                                       int numInvocations) {
43     SkASSERT(!this->isConfigured());
44     fNumInvocations = numInvocations;
45     if (this->getProgramBuilder()->shaderCaps()->mustImplementGSInvocationsWithLoop()) {
46         maxVertices *= numInvocations;
47         numInvocations = 1;
48     }
49     this->addLayoutQualifier(input_type_name(inputType), kIn_InterfaceQualifier);
50     this->addLayoutQualifier(SkStringPrintf("invocations = %i", numInvocations).c_str(),
51                              kIn_InterfaceQualifier);
52     this->addLayoutQualifier(output_type_name(outputType), kOut_InterfaceQualifier);
53     this->addLayoutQualifier(SkStringPrintf("max_vertices = %i", maxVertices).c_str(),
54                              kOut_InterfaceQualifier);
55 }
56 
onFinalize()57 void GrGLSLGeometryBuilder::onFinalize() {
58     SkASSERT(this->isConfigured());
59     fProgramBuilder->varyingHandler()->getGeomDecls(&this->inputs(), &this->outputs());
60     GrShaderVar sk_InvocationID("sk_InvocationID", kInt_GrSLType);
61     this->declareGlobal(sk_InvocationID);
62     SkASSERT(sk_InvocationID.getName() == SkString("sk_InvocationID"));
63     if (this->getProgramBuilder()->shaderCaps()->mustImplementGSInvocationsWithLoop()) {
64         SkString invokeFn;
65         this->emitFunction(kVoid_GrSLType, "invoke", 0, nullptr, this->code().c_str(), &invokeFn);
66         this->code().printf("for (sk_InvocationID = 0; sk_InvocationID < %i; ++sk_InvocationID) {"
67                                 "%s();"
68                                 "EndPrimitive();"
69                             "}", fNumInvocations, invokeFn.c_str());
70     } else {
71         this->codePrependf("sk_InvocationID = gl_InvocationID;");
72     }
73 }
74