blob: 116ba09b99bd9d2b797a328494bd49b903d5ca81 [file] [log] [blame]
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrGLSLVarying_DEFINED
#define GrGLSLVarying_DEFINED
#include "GrAllocator.h"
#include "GrGeometryProcessor.h"
#include "GrTypesPriv.h"
#include "glsl/GrGLSLProgramDataManager.h"
#include "glsl/GrGLSLShaderVar.h"
class GrGLSLProgramBuilder;
class GrGLSLVarying {
public:
bool vsVarying() const { return kVertToFrag_Varying == fVarying ||
kVertToGeo_Varying == fVarying; }
bool fsVarying() const { return kVertToFrag_Varying == fVarying ||
kGeoToFrag_Varying == fVarying; }
const char* vsOut() const { return fVsOut; }
const char* gsIn() const { return fGsIn; }
const char* gsOut() const { return fGsOut; }
const char* fsIn() const { return fFsIn; }
GrSLType type() const { return fType; }
protected:
enum Varying {
kVertToFrag_Varying,
kVertToGeo_Varying,
kGeoToFrag_Varying,
};
GrGLSLVarying(GrSLType type, Varying varying)
: fVarying(varying), fType(type), fVsOut(nullptr), fGsIn(nullptr), fGsOut(nullptr),
fFsIn(nullptr) {}
Varying fVarying;
private:
GrSLType fType;
const char* fVsOut;
const char* fGsIn;
const char* fGsOut;
const char* fFsIn;
friend class GrGLSLVaryingHandler;
};
struct GrGLSLVertToFrag : public GrGLSLVarying {
GrGLSLVertToFrag(GrSLType type)
: GrGLSLVarying(type, kVertToFrag_Varying) {}
};
struct GrGLSLVertToGeo : public GrGLSLVarying {
GrGLSLVertToGeo(GrSLType type)
: GrGLSLVarying(type, kVertToGeo_Varying) {}
};
struct GrGLSLGeoToFrag : public GrGLSLVarying {
GrGLSLGeoToFrag(GrSLType type)
: GrGLSLVarying(type, kGeoToFrag_Varying) {}
};
static const int kVaryingsPerBlock = 8;
class GrGLSLVaryingHandler {
public:
explicit GrGLSLVaryingHandler(GrGLSLProgramBuilder* program)
: fVertexInputs(kVaryingsPerBlock)
, fVertexOutputs(kVaryingsPerBlock)
, fGeomInputs(kVaryingsPerBlock)
, fGeomOutputs(kVaryingsPerBlock)
, fFragInputs(kVaryingsPerBlock)
, fFragOutputs(kVaryingsPerBlock)
, fProgramBuilder(program) {}
typedef GrTAllocator<GrGLSLShaderVar> VarArray;
typedef GrGLSLProgramDataManager::VaryingHandle VaryingHandle;
/*
* addVarying allows fine grained control for setting up varyings between stages. Calling this
* functions will make sure all necessary decls are setup for the client. The client however is
* responsible for setting up all shader code (e.g "vOut = vIn;") If you just need to take an
* attribute and pass it through to an output value in a fragment shader, use
* addPassThroughAttribute.
* TODO convert most uses of addVarying to addPassThroughAttribute
*/
void addVarying(const char* name,
GrGLSLVarying*,
GrSLPrecision precision = kDefault_GrSLPrecision);
/*
* This call can be used by GP to pass an attribute through all shaders directly to 'output' in
* the fragment shader. Though this call effects both the vertex shader and fragment shader,
* it expects 'output' to be defined in the fragment shader before this call is made. If there
* is a geometry shader, we will simply take the value of the varying from the first vertex and
* that will be set as the output varying for all emitted vertices.
* TODO it might be nicer behavior to have a flag to declare output inside this call
*/
void addPassThroughAttribute(const GrGeometryProcessor::Attribute*, const char* output);
void emitAttributes(const GrGeometryProcessor& gp);
void getVertexDecls(SkString* inputDecls, SkString* outputDecls) const;
void getGeomDecls(SkString* inputDecls, SkString* outputDecls) const;
void getFragDecls(SkString* inputDecls, SkString* outputDecls) const;
protected:
VarArray fVertexInputs;
VarArray fVertexOutputs;
VarArray fGeomInputs;
VarArray fGeomOutputs;
VarArray fFragInputs;
VarArray fFragOutputs;
// This is not owned by the class
GrGLSLProgramBuilder* fProgramBuilder;
private:
void addVertexVarying(const char* name, GrSLPrecision precision, GrGLSLVarying* v);
void addGeomVarying(const char* name, GrSLPrecision precision, GrGLSLVarying* v);
void addFragVarying(GrSLPrecision precision, GrGLSLVarying* v);
void addAttribute(const GrShaderVar& var);
// helper function for get*Decls
void appendDecls(const VarArray& vars, SkString* out) const;
friend class GrGLSLProgramBuilder;
};
#endif