Home | History | Annotate | Download | only in builders
      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 "GrGLGeometryShaderBuilder.h"
      9 #include "GrGLShaderStringBuilder.h"
     10 #include "GrGLProgramBuilder.h"
     11 #include "../GrGpuGL.h"
     12 
     13 GrGLGeometryShaderBuilder::GrGLGeometryShaderBuilder(GrGLFullProgramBuilder* program)
     14     : INHERITED(program) {
     15 
     16 }
     17 
     18 void GrGLGeometryShaderBuilder::addVarying(GrSLType type,
     19                const char* name,
     20                const char** gsOutName) {
     21     // if we have a GS take each varying in as an array
     22     // and output as non-array.
     23     fInputs.push_back();
     24     fInputs.back().setType(type);
     25     fInputs.back().setTypeModifier(GrGLShaderVar::kVaryingIn_TypeModifier);
     26     fInputs.back().setUnsizedArray();
     27     *fInputs.back().accessName() = name;
     28     fOutputs.push_back();
     29     fOutputs.back().setType(type);
     30     fOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier);
     31     fProgramBuilder->nameVariable(fOutputs.back().accessName(), 'g', name);
     32     if (gsOutName) {
     33         *gsOutName = fOutputs.back().getName().c_str();
     34     }
     35 }
     36 
     37 
     38 bool GrGLGeometryShaderBuilder::compileAndAttachShaders(GrGLuint programId,
     39         SkTDArray<GrGLuint>* shaderIds) const {
     40     const GrGLContext& glCtx = fProgramBuilder->gpu()->glContext();
     41     SkASSERT(fProgramBuilder->ctxInfo().glslGeneration() >= k150_GrGLSLGeneration);
     42     SkString geomShaderSrc(GrGetGLSLVersionDecl(fProgramBuilder->ctxInfo()));
     43     geomShaderSrc.append("layout(triangles) in;\n"
     44                          "layout(triangle_strip, max_vertices = 6) out;\n");
     45     fProgramBuilder->appendDecls(fInputs, &geomShaderSrc);
     46     fProgramBuilder->appendDecls(fOutputs, &geomShaderSrc);
     47     geomShaderSrc.append("void main() {\n");
     48     geomShaderSrc.append("\tfor (int i = 0; i < 3; ++i) {\n"
     49                          "\t\tgl_Position = gl_in[i].gl_Position;\n");
     50     if (fProgramBuilder->desc().getHeader().fEmitsPointSize) {
     51         geomShaderSrc.append("\t\tgl_PointSize = 1.0;\n");
     52     }
     53     SkASSERT(fInputs.count() == fOutputs.count());
     54     for (int i = 0; i < fInputs.count(); ++i) {
     55         geomShaderSrc.appendf("\t\t%s = %s[i];\n",
     56                               fOutputs[i].getName().c_str(),
     57                               fInputs[i].getName().c_str());
     58     }
     59     geomShaderSrc.append("\t\tEmitVertex();\n"
     60                          "\t}\n"
     61                          "\tEndPrimitive();\n");
     62     geomShaderSrc.append("}\n");
     63     GrGLuint geomShaderId =
     64         GrGLCompileAndAttachShader(glCtx, programId,
     65                                    GR_GL_GEOMETRY_SHADER, geomShaderSrc,
     66                                    fProgramBuilder->gpu()->gpuStats());
     67     if (!geomShaderId) {
     68         return false;
     69     }
     70     *shaderIds->append() = geomShaderId;
     71     return true;
     72 }
     73