aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl/builders
diff options
context:
space:
mode:
authorGravatar kkinnunen <kkinnunen@nvidia.com>2015-06-29 23:01:28 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-06-29 23:01:28 -0700
commit7aedda57f84f942b5f0ba6c1b6e7ba329e6b18f1 (patch)
treec05dd8eb983a44df9cecf410ff5604ffd4593a38 /src/gpu/gl/builders
parente04edd8c8618f1a637f0cdbe340474e2c10a60ad (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.cpp50
-rw-r--r--src/gpu/gl/builders/GrGLPathProgramBuilder.h31
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.cpp82
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.h17
-rw-r--r--src/gpu/gl/builders/GrGLShaderBuilder.h1
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