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