130ba436f04e61d4505fb854d5fc56079636e0788joshualitt/*
230ba436f04e61d4505fb854d5fc56079636e0788joshualitt * Copyright 2014 Google Inc.
330ba436f04e61d4505fb854d5fc56079636e0788joshualitt *
430ba436f04e61d4505fb854d5fc56079636e0788joshualitt * Use of this source code is governed by a BSD-style license that can be
530ba436f04e61d4505fb854d5fc56079636e0788joshualitt * found in the LICENSE file.
630ba436f04e61d4505fb854d5fc56079636e0788joshualitt */
730ba436f04e61d4505fb854d5fc56079636e0788joshualitt
830ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "GrGLGeometryShaderBuilder.h"
930ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "GrGLShaderStringBuilder.h"
1030ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "GrGLProgramBuilder.h"
1130ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "../GrGpuGL.h"
1230ba436f04e61d4505fb854d5fc56079636e0788joshualitt
1330ba436f04e61d4505fb854d5fc56079636e0788joshualittGrGLGeometryShaderBuilder::GrGLGeometryShaderBuilder(GrGLFullProgramBuilder* program)
1430ba436f04e61d4505fb854d5fc56079636e0788joshualitt    : INHERITED(program) {
1530ba436f04e61d4505fb854d5fc56079636e0788joshualitt
1630ba436f04e61d4505fb854d5fc56079636e0788joshualitt}
1730ba436f04e61d4505fb854d5fc56079636e0788joshualitt
1830ba436f04e61d4505fb854d5fc56079636e0788joshualittvoid GrGLGeometryShaderBuilder::addVarying(GrSLType type,
1930ba436f04e61d4505fb854d5fc56079636e0788joshualitt               const char* name,
2030ba436f04e61d4505fb854d5fc56079636e0788joshualitt               const char** gsOutName) {
2130ba436f04e61d4505fb854d5fc56079636e0788joshualitt    // if we have a GS take each varying in as an array
2230ba436f04e61d4505fb854d5fc56079636e0788joshualitt    // and output as non-array.
2330ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fInputs.push_back();
2430ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fInputs.back().setType(type);
2530ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fInputs.back().setTypeModifier(GrGLShaderVar::kVaryingIn_TypeModifier);
2630ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fInputs.back().setUnsizedArray();
2730ba436f04e61d4505fb854d5fc56079636e0788joshualitt    *fInputs.back().accessName() = name;
2830ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fOutputs.push_back();
2930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fOutputs.back().setType(type);
3030ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier);
3130ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fProgramBuilder->nameVariable(fOutputs.back().accessName(), 'g', name);
3230ba436f04e61d4505fb854d5fc56079636e0788joshualitt    if (gsOutName) {
3330ba436f04e61d4505fb854d5fc56079636e0788joshualitt        *gsOutName = fOutputs.back().getName().c_str();
3430ba436f04e61d4505fb854d5fc56079636e0788joshualitt    }
3530ba436f04e61d4505fb854d5fc56079636e0788joshualitt}
3630ba436f04e61d4505fb854d5fc56079636e0788joshualitt
3730ba436f04e61d4505fb854d5fc56079636e0788joshualitt
3830ba436f04e61d4505fb854d5fc56079636e0788joshualittbool GrGLGeometryShaderBuilder::compileAndAttachShaders(GrGLuint programId,
3930ba436f04e61d4505fb854d5fc56079636e0788joshualitt        SkTDArray<GrGLuint>* shaderIds) const {
4030ba436f04e61d4505fb854d5fc56079636e0788joshualitt    const GrGLContext& glCtx = fProgramBuilder->gpu()->glContext();
4130ba436f04e61d4505fb854d5fc56079636e0788joshualitt    SkASSERT(fProgramBuilder->ctxInfo().glslGeneration() >= k150_GrGLSLGeneration);
4230ba436f04e61d4505fb854d5fc56079636e0788joshualitt    SkString geomShaderSrc(GrGetGLSLVersionDecl(fProgramBuilder->ctxInfo()));
4330ba436f04e61d4505fb854d5fc56079636e0788joshualitt    geomShaderSrc.append("layout(triangles) in;\n"
4430ba436f04e61d4505fb854d5fc56079636e0788joshualitt                         "layout(triangle_strip, max_vertices = 6) out;\n");
4530ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fProgramBuilder->appendDecls(fInputs, &geomShaderSrc);
4630ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fProgramBuilder->appendDecls(fOutputs, &geomShaderSrc);
4730ba436f04e61d4505fb854d5fc56079636e0788joshualitt    geomShaderSrc.append("void main() {\n");
4830ba436f04e61d4505fb854d5fc56079636e0788joshualitt    geomShaderSrc.append("\tfor (int i = 0; i < 3; ++i) {\n"
4930ba436f04e61d4505fb854d5fc56079636e0788joshualitt                         "\t\tgl_Position = gl_in[i].gl_Position;\n");
5030ba436f04e61d4505fb854d5fc56079636e0788joshualitt    if (fProgramBuilder->desc().getHeader().fEmitsPointSize) {
5130ba436f04e61d4505fb854d5fc56079636e0788joshualitt        geomShaderSrc.append("\t\tgl_PointSize = 1.0;\n");
5230ba436f04e61d4505fb854d5fc56079636e0788joshualitt    }
5330ba436f04e61d4505fb854d5fc56079636e0788joshualitt    SkASSERT(fInputs.count() == fOutputs.count());
5430ba436f04e61d4505fb854d5fc56079636e0788joshualitt    for (int i = 0; i < fInputs.count(); ++i) {
5530ba436f04e61d4505fb854d5fc56079636e0788joshualitt        geomShaderSrc.appendf("\t\t%s = %s[i];\n",
5630ba436f04e61d4505fb854d5fc56079636e0788joshualitt                              fOutputs[i].getName().c_str(),
5730ba436f04e61d4505fb854d5fc56079636e0788joshualitt                              fInputs[i].getName().c_str());
5830ba436f04e61d4505fb854d5fc56079636e0788joshualitt    }
5930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    geomShaderSrc.append("\t\tEmitVertex();\n"
6030ba436f04e61d4505fb854d5fc56079636e0788joshualitt                         "\t}\n"
6130ba436f04e61d4505fb854d5fc56079636e0788joshualitt                         "\tEndPrimitive();\n");
6230ba436f04e61d4505fb854d5fc56079636e0788joshualitt    geomShaderSrc.append("}\n");
6330ba436f04e61d4505fb854d5fc56079636e0788joshualitt    GrGLuint geomShaderId =
64754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips        GrGLCompileAndAttachShader(glCtx, programId,
65754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips                                   GR_GL_GEOMETRY_SHADER, geomShaderSrc,
66754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips                                   fProgramBuilder->gpu()->gpuStats());
6730ba436f04e61d4505fb854d5fc56079636e0788joshualitt    if (!geomShaderId) {
6830ba436f04e61d4505fb854d5fc56079636e0788joshualitt        return false;
6930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    }
7030ba436f04e61d4505fb854d5fc56079636e0788joshualitt    *shaderIds->append() = geomShaderId;
7130ba436f04e61d4505fb854d5fc56079636e0788joshualitt    return true;
7230ba436f04e61d4505fb854d5fc56079636e0788joshualitt}
73