diff options
author | kkinnunen <kkinnunen@nvidia.com> | 2015-06-29 23:01:28 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-06-29 23:01:28 -0700 |
commit | 7aedda57f84f942b5f0ba6c1b6e7ba329e6b18f1 (patch) | |
tree | c05dd8eb983a44df9cecf410ff5604ffd4593a38 /src/gpu/gl/builders | |
parent | e04edd8c8618f1a637f0cdbe340474e2c10a60ad (diff) |
Refactor separable varying location info to be stored in GrGLProgram subclass
Refactor separable varying location info to be stored in GrGLProgram
subclass GrGLProgram instead of storing it in GrGLPathProcessor.
Separable varyings are exactly analoguous to uniforms: they are inputs
to the shader program. Shader compile-time information about uniforms is gathered to
GrGLProgramBuilder. This information is the converted to link-time
information, uniform locations, when constructing the program. Separable
varyings need to have same lifetime model.
This is needed in the future to support path rendering in Chromium. The
Chromium pseudo-extension will expose program fragment input binding
function similar to uniform binding function. Thus the separable varying
locations need to be decided and bound before link, e.g. before
GrGLProgram is created. This will be achieved in further patches by
overloading GrGLProgramBuilder::bindProgramResourceLocations() in
GrGLNvprProgramBuilder.
BUG=chromium:344330
Review URL: https://codereview.chromium.org/1186113007
Diffstat (limited to 'src/gpu/gl/builders')
-rw-r--r-- | src/gpu/gl/builders/GrGLPathProgramBuilder.cpp | 50 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLPathProgramBuilder.h | 31 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLProgramBuilder.cpp | 82 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLProgramBuilder.h | 17 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLShaderBuilder.h | 1 |
5 files changed, 133 insertions, 48 deletions
diff --git a/src/gpu/gl/builders/GrGLPathProgramBuilder.cpp b/src/gpu/gl/builders/GrGLPathProgramBuilder.cpp new file mode 100644 index 0000000000..c9f88cd702 --- /dev/null +++ b/src/gpu/gl/builders/GrGLPathProgramBuilder.cpp @@ -0,0 +1,50 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "GrGLPathProgramBuilder.h" +#include "gl/GrGLGpu.h" +#include "gl/GrGLPathProgram.h" + +#define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X) +#define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X) + +GrGLPathProgramBuilder::GrGLPathProgramBuilder(GrGLGpu* gpu, const DrawArgs& args) + : INHERITED(gpu, args) + , fSeparableVaryingInfos(kVarsPerBlock) { +} + +GrGLProgram* GrGLPathProgramBuilder::createProgram(GrGLuint programID) { + return SkNEW_ARGS(GrGLPathProgram, (fGpu, this->desc(), fUniformHandles, programID, + fUniforms, + fSeparableVaryingInfos, + fGeometryProcessor, + fXferProcessor, fFragmentProcessors.get(), + &fSamplerUniforms)); +} + +GrGLProgramBuilder::SeparableVaryingHandle GrGLPathProgramBuilder::addSeparableVarying( + const char* name, GrGLVertToFrag* v, GrSLPrecision fsPrecision) { + this->addVarying(name, v, fsPrecision); + SeparableVaryingInfo& varyingInfo = fSeparableVaryingInfos.push_back(); + varyingInfo.fVariable = this->getFragmentShaderBuilder()->fInputs.back(); + varyingInfo.fLocation = fSeparableVaryingInfos.count() - 1; + return SeparableVaryingHandle::CreateFromSeparableVaryingIndex(varyingInfo.fLocation); +} + +void GrGLPathProgramBuilder::resolveProgramResourceLocations(GrGLuint programID) { + this->INHERITED::resolveProgramResourceLocations(programID); + + int count = fSeparableVaryingInfos.count(); + for (int i = 0; i < count; ++i) { + GrGLint location; + GL_CALL_RET(location, + GetProgramResourceLocation(programID, + GR_GL_FRAGMENT_INPUT, + fSeparableVaryingInfos[i].fVariable.c_str())); + fSeparableVaryingInfos[i].fLocation = location; + } +} diff --git a/src/gpu/gl/builders/GrGLPathProgramBuilder.h b/src/gpu/gl/builders/GrGLPathProgramBuilder.h new file mode 100644 index 0000000000..28260cf760 --- /dev/null +++ b/src/gpu/gl/builders/GrGLPathProgramBuilder.h @@ -0,0 +1,31 @@ +/* + * 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 GrGLPathProgramBuilder_DEFINED +#define GrGLPathProgramBuilder_DEFINED + +#include "GrGLProgramBuilder.h" + +class GrGLPathProgramBuilder : public GrGLProgramBuilder { +public: + GrGLPathProgramBuilder(GrGLGpu* gpu, const DrawArgs& args); + + GrGLProgram* createProgram(GrGLuint programID) override; + + SeparableVaryingHandle addSeparableVarying(const char* name, GrGLVertToFrag* v, + GrSLPrecision fsPrecision) override; + void resolveProgramResourceLocations(GrGLuint programID) override; + +private: + typedef GrGLPathProgramDataManager::SeparableVaryingInfo SeparableVaryingInfo; + typedef GrGLPathProgramDataManager::SeparableVaryingInfoArray SeparableVaryingInfoArray; + + SeparableVaryingInfoArray fSeparableVaryingInfos; + + typedef GrGLProgramBuilder INHERITED; +}; + +#endif diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp index e253ab233b..a07bd732af 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp +++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp @@ -17,6 +17,7 @@ #include "glsl/GrGLSLCaps.h" #include "GrAutoLocaleSetter.h" #include "GrCoordTransform.h" +#include "GrGLPathProgramBuilder.h" #include "GrGLProgramBuilder.h" #include "GrTexture.h" #include "SkRTConf.h" @@ -25,32 +26,6 @@ #define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X) #define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X) -/////////////////////////////////////////////////////////////////////////////////////////////////// - -class GrGLNvprProgramBuilder : public GrGLProgramBuilder { -public: - GrGLNvprProgramBuilder(GrGLGpu* gpu, const DrawArgs& args) - : INHERITED(gpu, args) {} - - GrGLProgram* createProgram(GrGLuint programID) override { - // this is just for nvpr es, which has separable varyings that are plugged in after - // building - GrGLPathProcessor* pathProc = - static_cast<GrGLPathProcessor*>(fGeometryProcessor->fGLProc.get()); - pathProc->resolveSeparableVaryings(fGpu, programID); - return SkNEW_ARGS(GrGLNvprProgram, (fGpu, this->desc(), fUniformHandles, programID, - fUniforms, fGeometryProcessor, fXferProcessor, - fFragmentProcessors.get(), &fSamplerUniforms)); - } - -private: - typedef GrGLProgramBuilder INHERITED; -}; - - - -////////////////////////////////////////////////////////////////////////////// - const int GrGLProgramBuilder::kVarsPerBlock = 8; GrGLProgram* GrGLProgramBuilder::CreateProgram(const DrawArgs& args, GrGLGpu* gpu) { @@ -80,7 +55,7 @@ GrGLProgramBuilder* GrGLProgramBuilder::CreateProgramBuilder(const DrawArgs& arg SkASSERT(gpu->glCaps().shaderCaps()->pathRenderingSupport() && !args.fPrimitiveProcessor->willUseGeoShader() && args.fPrimitiveProcessor->numAttribs() == 0); - return SkNEW_ARGS(GrGLNvprProgramBuilder, (gpu, args)); + return SkNEW_ARGS(GrGLPathProgramBuilder, (gpu, args)); } else { return SkNEW_ARGS(GrGLProgramBuilder, (gpu, args)); } @@ -126,6 +101,18 @@ void GrGLProgramBuilder::addPassThroughAttribute(const GrPrimitiveProcessor::Att fFS.codeAppendf("%s = %s;", output, v.fsIn()); } +GrGLProgramBuilder::SeparableVaryingHandle GrGLProgramBuilder::addSeparableVarying(const char*, + GrGLVertToFrag*, + GrSLPrecision) { + // This call is not used for non-NVPR backends. However, the polymorphism between + // GrPrimitiveProcessor, GrGLPrimitiveProcessor and GrGLProgramBuilder does not allow for + // a system where GrGLPathProcessor would be able to refer to a primitive-specific builder + // that would understand separable varyings. Thus separable varyings need to be present + // early in the inheritance chain of builders. + SkASSERT(false); + return SeparableVaryingHandle(); +} + void GrGLProgramBuilder::nameVariable(SkString* out, char prefix, const char* name) { if ('\0' == prefix) { *out = name; @@ -423,11 +410,8 @@ GrGLProgram* GrGLProgramBuilder::finalize() { return NULL; } - bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL; - if (usingBindUniform) { - this->bindUniformLocations(programID); - } - fFS.bindFragmentShaderLocations(programID); + this->bindProgramResourceLocations(programID); + GL_CALL(LinkProgram(programID)); // Calling GetProgramiv is expensive in Chromium. Assume success in release builds. @@ -438,21 +422,24 @@ GrGLProgram* GrGLProgramBuilder::finalize() { if (checkLinked) { checkLinkStatus(programID); } - if (!usingBindUniform) { - this->resolveUniformLocations(programID); - } + this->resolveProgramResourceLocations(programID); this->cleanupShaders(shadersToDelete); return this->createProgram(programID); } -void GrGLProgramBuilder::bindUniformLocations(GrGLuint programID) { - int count = fUniforms.count(); - for (int i = 0; i < count; ++i) { - GL_CALL(BindUniformLocation(programID, i, fUniforms[i].fVariable.c_str())); - fUniforms[i].fLocation = i; +void GrGLProgramBuilder::bindProgramResourceLocations(GrGLuint programID) { + bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL; + if (usingBindUniform) { + int count = fUniforms.count(); + for (int i = 0; i < count; ++i) { + GL_CALL(BindUniformLocation(programID, i, fUniforms[i].fVariable.c_str())); + fUniforms[i].fLocation = i; + } } + + fFS.bindFragmentShaderLocations(programID); } bool GrGLProgramBuilder::checkLinkStatus(GrGLuint programID) { @@ -479,12 +466,15 @@ bool GrGLProgramBuilder::checkLinkStatus(GrGLuint programID) { return SkToBool(linked); } -void GrGLProgramBuilder::resolveUniformLocations(GrGLuint programID) { - int count = fUniforms.count(); - for (int i = 0; i < count; ++i) { - GrGLint location; - GL_CALL_RET(location, GetUniformLocation(programID, fUniforms[i].fVariable.c_str())); - fUniforms[i].fLocation = location; +void GrGLProgramBuilder::resolveProgramResourceLocations(GrGLuint programID) { + bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL; + if (!usingBindUniform) { + int count = fUniforms.count(); + for (int i = 0; i < count; ++i) { + GrGLint location; + GL_CALL_RET(location, GetUniformLocation(programID, fUniforms[i].fVariable.c_str())); + fUniforms[i].fLocation = location; + } } } diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h index 4cfe0286d8..4b784aceea 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.h +++ b/src/gpu/gl/builders/GrGLProgramBuilder.h @@ -12,6 +12,7 @@ #include "GrGLGeometryShaderBuilder.h" #include "GrGLVertexShaderBuilder.h" #include "../GrGLProgramDataManager.h" +#include "../GrGLPathProgramDataManager.h" #include "../GrGLUniformHandle.h" #include "../GrGLPrimitiveProcessor.h" #include "../GrGLXferProcessor.h" @@ -39,6 +40,7 @@ public: virtual ~GrGLUniformBuilder() {} typedef GrGLProgramDataManager::UniformHandle UniformHandle; + typedef GrGLPathProgramDataManager::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 @@ -154,6 +156,13 @@ public: virtual void addPassThroughAttribute(const GrGeometryProcessor::Attribute*, const char* output) = 0; + /* + * Creates a fragment shader varying that can be referred to. + * Comparable to GrGLUniformBuilder::addUniform(). + */ + virtual SeparableVaryingHandle addSeparableVarying( + const char* name, GrGLVertToFrag*, GrSLPrecision fsPrecision = kDefault_GrSLPrecision) = 0; + // TODO rename getFragmentBuilder virtual GrGLFragmentBuilder* getFragmentShaderBuilder() = 0; virtual GrGLVertexBuilder* getVertexShaderBuilder() = 0; @@ -252,6 +261,10 @@ public: void addPassThroughAttribute(const GrPrimitiveProcessor::Attribute*, const char* output) override; + SeparableVaryingHandle addSeparableVarying( + const char* name, + GrGLVertToFrag*, + GrSLPrecision fsPrecision = kDefault_GrSLPrecision) override; // Handles for program uniforms (other than per-effect uniforms) struct BuiltinUniformHandles { @@ -315,9 +328,9 @@ protected: GrGLInstalledProc<Proc>*); GrGLProgram* finalize(); - void bindUniformLocations(GrGLuint programID); + void bindProgramResourceLocations(GrGLuint programID); bool checkLinkStatus(GrGLuint programID); - void resolveUniformLocations(GrGLuint programID); + virtual void resolveProgramResourceLocations(GrGLuint programID); void cleanupProgram(GrGLuint programID, const SkTDArray<GrGLuint>& shaderIDs); void cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs); diff --git a/src/gpu/gl/builders/GrGLShaderBuilder.h b/src/gpu/gl/builders/GrGLShaderBuilder.h index 0416dbeab6..95337683c6 100644 --- a/src/gpu/gl/builders/GrGLShaderBuilder.h +++ b/src/gpu/gl/builders/GrGLShaderBuilder.h @@ -203,5 +203,6 @@ protected: bool fFinalized; friend class GrGLProgramBuilder; + friend class GrGLPathProgramBuilder; // to access fInputs. }; #endif |