| Index: src/gpu/glsl/GrGLSLProgramBuilder.h
|
| diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.h b/src/gpu/glsl/GrGLSLProgramBuilder.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..f783a40db43e03203dafee8f469d7e03861688a5
|
| --- /dev/null
|
| +++ b/src/gpu/glsl/GrGLSLProgramBuilder.h
|
| @@ -0,0 +1,261 @@
|
| +/*
|
| + * 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 GrGLSLProgramBuilder_DEFINED
|
| +#define GrGLSLProgramBuilder_DEFINED
|
| +
|
| +#include "GrGeometryProcessor.h"
|
| +#include "GrGpu.h"
|
| +#include "gl/builders/GrGLFragmentShaderBuilder.h"
|
| +#include "gl/builders/GrGLGeometryShaderBuilder.h"
|
| +#include "gl/builders/GrGLVertexShaderBuilder.h"
|
| +#include "glsl/GrGLSLProgramDataManager.h"
|
| +
|
| +class GrGLSLCaps;
|
| +class GrGLSLShaderVar;
|
| +
|
| +class GrGLSLUniformBuilder {
|
| +public:
|
| + enum ShaderVisibility {
|
| + kVertex_Visibility = 1 << kVertex_GrShaderType,
|
| + kGeometry_Visibility = 1 << kGeometry_GrShaderType,
|
| + kFragment_Visibility = 1 << kFragment_GrShaderType,
|
| + };
|
| +
|
| + virtual ~GrGLSLUniformBuilder() {}
|
| +
|
| + typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
|
| + typedef GrGLSLProgramDataManager::SeparableVaryingHandle SeparableVaryingHandle;
|
| +
|
| + /** Add a uniform variable to the current program, that has visibility in one or more shaders.
|
| + visibility is a bitfield of ShaderVisibility values indicating from which shaders the
|
| + uniform should be accessible. At least one bit must be set. Geometry shader uniforms are not
|
| + supported at this time. The actual uniform name will be mangled. If outName is not nullptr
|
| + then it will refer to the final uniform name after return. Use the addUniformArray variant
|
| + to add an array of uniforms. */
|
| + UniformHandle addUniform(uint32_t visibility,
|
| + GrSLType type,
|
| + GrSLPrecision precision,
|
| + const char* name,
|
| + const char** outName = nullptr) {
|
| + return this->addUniformArray(visibility, type, precision, name, 0, outName);
|
| + }
|
| +
|
| + UniformHandle addUniformArray(uint32_t visibility,
|
| + GrSLType type,
|
| + GrSLPrecision precision,
|
| + const char* name,
|
| + int arrayCount,
|
| + const char** outName = nullptr) {
|
| + return this->internalAddUniformArray(visibility, type, precision, name, true, arrayCount,
|
| + outName);
|
| + }
|
| +
|
| + virtual const GrGLSLShaderVar& getUniformVariable(UniformHandle u) const = 0;
|
| +
|
| + /**
|
| + * Shortcut for getUniformVariable(u).c_str()
|
| + */
|
| + virtual const char* getUniformCStr(UniformHandle u) const = 0;
|
| +
|
| + virtual const GrGLSLCaps* glslCaps() const = 0;
|
| +
|
| + /*
|
| + * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE
|
| + */
|
| +protected:
|
| + virtual UniformHandle internalAddUniformArray(
|
| + uint32_t visibility,
|
| + GrSLType type,
|
| + GrSLPrecision precision,
|
| + const char* name,
|
| + bool mangleName,
|
| + int arrayCount,
|
| + const char** outName) = 0;
|
| +};
|
| +
|
| +// TODO move this into GrGLSLGPBuilder and move them both out of this file
|
| +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 GrGLVertexBuilder;
|
| + friend class GrGLGeometryBuilder;
|
| + friend class GrGLXferBuilder;
|
| + friend class GrGLFragmentShaderBuilder;
|
| +};
|
| +
|
| +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) {}
|
| +};
|
| +
|
| +/* a specialization of the above for GPs. Lets the user add uniforms, varyings, and VS / FS code */
|
| +class GrGLSLGPBuilder : public virtual GrGLSLUniformBuilder {
|
| +public:
|
| + /*
|
| + * addVarying allows fine grained control for setting up varyings between stages. 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
|
| + */
|
| + virtual void addVarying(const char* name,
|
| + GrGLSLVarying*,
|
| + GrSLPrecision precision = kDefault_GrSLPrecision) = 0;
|
| +
|
| + /*
|
| + * 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.
|
| + * TODO it might be nicer behavior to have a flag to declare output inside this call
|
| + */
|
| + virtual void addPassThroughAttribute(const GrGeometryProcessor::Attribute*,
|
| + const char* output) = 0;
|
| +
|
| + /*
|
| + * Creates a fragment shader varying that can be referred to.
|
| + * Comparable to GrGLSLUniformBuilder::addUniform().
|
| + */
|
| + virtual SeparableVaryingHandle addSeparableVarying(
|
| + const char* name, GrGLSLVertToFrag*,
|
| + GrSLPrecision fsPrecision = kDefault_GrSLPrecision) = 0;
|
| +
|
| + // TODO rename getFragmentBuilder
|
| + virtual GrGLFragmentBuilder* getFragmentShaderBuilder() = 0;
|
| + virtual GrGLVertexBuilder* getVertexShaderBuilder() = 0;
|
| +
|
| + /*
|
| + * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE
|
| + */
|
| +};
|
| +
|
| +
|
| +/* a specializations for FPs. Lets the user add uniforms and FS code */
|
| +class GrGLSLFPBuilder : public virtual GrGLSLUniformBuilder {
|
| +public:
|
| + virtual GrGLFragmentBuilder* getFragmentShaderBuilder() = 0;
|
| +
|
| + /*
|
| + * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE
|
| + */
|
| +};
|
| +
|
| +/* a specializations for XPs. Lets the user add uniforms and FS code */
|
| +class GrGLSLXPBuilder : public virtual GrGLSLUniformBuilder {
|
| +public:
|
| + virtual GrGLXPFragmentBuilder* getFragmentShaderBuilder() = 0;
|
| +
|
| + /*
|
| + * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE
|
| + */
|
| +};
|
| +
|
| +class GrGLSLProgramBuilder : public GrGLSLGPBuilder,
|
| + public GrGLSLFPBuilder,
|
| + public GrGLSLXPBuilder {
|
| +public:
|
| + typedef GrGpu::DrawArgs DrawArgs;
|
| +
|
| + GrGLXPFragmentBuilder* getFragmentShaderBuilder() override { return &fFS; }
|
| + GrGLVertexBuilder* getVertexShaderBuilder() override { return &fVS; }
|
| +
|
| + // Handles for program uniforms (other than per-effect uniforms)
|
| + struct BuiltinUniformHandles {
|
| + UniformHandle fRTAdjustmentUni;
|
| +
|
| + // We use the render target height to provide a y-down frag coord when specifying
|
| + // origin_upper_left is not supported.
|
| + UniformHandle fRTHeightUni;
|
| + };
|
| +
|
| +protected:
|
| + explicit GrGLSLProgramBuilder(const DrawArgs& args);
|
| +
|
| + const GrPrimitiveProcessor& primitiveProcessor() const { return *fArgs.fPrimitiveProcessor; }
|
| + const GrPipeline& pipeline() const { return *fArgs.fPipeline; }
|
| + const GrProgramDesc& desc() const { return *fArgs.fDesc; }
|
| + const GrProgramDesc::KeyHeader& header() const { return fArgs.fDesc->header(); }
|
| +
|
| + void appendUniformDecls(ShaderVisibility, SkString*) const;
|
| +
|
| + // Used to add a uniform for frag position without mangling the name of the uniform inside of a
|
| + // stage.
|
| + UniformHandle addFragPosUniform(uint32_t visibility,
|
| + GrSLType type,
|
| + GrSLPrecision precision,
|
| + const char* name,
|
| + const char** outName) {
|
| + return this->internalAddUniformArray(visibility, type, precision, name, false, 0, outName);
|
| + }
|
| +
|
| + const char* rtAdjustment() const { return "rtAdjustment"; }
|
| +
|
| + // Generates a name for a variable. The generated string will be name prefixed by the prefix
|
| + // char (unless the prefix is '\0'). It also will mangle the name to be stage-specific unless
|
| + // explicitly asked not to.
|
| + void nameVariable(SkString* out, char prefix, const char* name, bool mangle = true);
|
| +
|
| + // number of each input/output type in a single allocation block, used by many builders
|
| + static const int kVarsPerBlock;
|
| +
|
| + GrGLVertexBuilder fVS;
|
| + GrGLGeometryBuilder fGS;
|
| + GrGLFragmentShaderBuilder fFS;
|
| + int fStageIndex;
|
| +
|
| + BuiltinUniformHandles fUniformHandles;
|
| +
|
| + const DrawArgs& fArgs;
|
| +
|
| +private:
|
| + virtual void onAppendUniformDecls(ShaderVisibility visibility, SkString* out) const = 0;
|
| +
|
| + friend class GrGLShaderBuilder;
|
| + friend class GrGLVertexBuilder;
|
| + friend class GrGLFragmentShaderBuilder;
|
| + friend class GrGLGeometryBuilder;
|
| +};
|
| +
|
| +#endif
|
|
|