aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl
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
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')
-rw-r--r--src/gpu/gl/GrGLPathProcessor.cpp36
-rw-r--r--src/gpu/gl/GrGLPathProcessor.h16
-rw-r--r--src/gpu/gl/GrGLPathProgram.cpp52
-rw-r--r--src/gpu/gl/GrGLPathProgram.h49
-rw-r--r--src/gpu/gl/GrGLPathProgramDataManager.cpp48
-rw-r--r--src/gpu/gl/GrGLPathProgramDataManager.h75
-rw-r--r--src/gpu/gl/GrGLPrimitiveProcessor.h6
-rw-r--r--src/gpu/gl/GrGLProgram.cpp40
-rw-r--r--src/gpu/gl/GrGLProgram.h32
-rw-r--r--src/gpu/gl/GrGLProgramDataManager.cpp2
-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
15 files changed, 374 insertions, 163 deletions
diff --git a/src/gpu/gl/GrGLPathProcessor.cpp b/src/gpu/gl/GrGLPathProcessor.cpp
index e8c10a3c9d..b0ab10a473 100644
--- a/src/gpu/gl/GrGLPathProcessor.cpp
+++ b/src/gpu/gl/GrGLPathProcessor.cpp
@@ -71,16 +71,11 @@ void GrGLPathProcessor::emitTransforms(GrGLGPBuilder* pb, const TransformsIn& ti
coordTransforms[t]->getMatrix().hasPerspective() ? kVec3f_GrSLType :
kVec2f_GrSLType;
-
SkString strVaryingName("MatrixCoord");
strVaryingName.appendf("_%i_%i", i, t);
GrGLVertToFrag v(varyingType);
- pb->addVarying(strVaryingName.c_str(), &v);
- SeparableVaryingInfo& varyingInfo = fSeparableVaryingInfos.push_back();
- varyingInfo.fVariable = pb->getFragmentShaderBuilder()->fInputs.back();
- varyingInfo.fLocation = fSeparableVaryingInfos.count() - 1;
- varyingInfo.fType = varyingType;
- fInstalledTransforms[i][t].fHandle = ShaderVarHandle(varyingInfo.fLocation);
+ fInstalledTransforms[i][t].fHandle =
+ pb->addSeparableVarying(strVaryingName.c_str(), &v).toShaderBuilderIndex();
fInstalledTransforms[i][t].fType = varyingType;
SkNEW_APPEND_TO_TARRAY(&(*tout)[i], GrGLProcessor::TransformedCoords,
@@ -89,25 +84,11 @@ void GrGLPathProcessor::emitTransforms(GrGLGPBuilder* pb, const TransformsIn& ti
}
}
-void GrGLPathProcessor::resolveSeparableVaryings(GrGLGpu* gpu, GrGLuint programId) {
- int count = fSeparableVaryingInfos.count();
- for (int i = 0; i < count; ++i) {
- GrGLint location;
- GR_GL_CALL_RET(gpu->glInterface(),
- location,
- GetProgramResourceLocation(programId,
- GR_GL_FRAGMENT_INPUT,
- fSeparableVaryingInfos[i].fVariable.c_str()));
- fSeparableVaryingInfos[i].fLocation = location;
- }
-}
-
void GrGLPathProcessor::setTransformData(
const GrPrimitiveProcessor& primProc,
+ const GrGLPathProgramDataManager& pdman,
int index,
- const SkTArray<const GrCoordTransform*, true>& coordTransforms,
- GrGLPathRendering* glpr,
- GrGLuint programID) {
+ const SkTArray<const GrCoordTransform*, true>& coordTransforms) {
const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
SkSTArray<2, Transform, true>& transforms = fInstalledTransforms[index];
int numTransforms = transforms.count();
@@ -119,15 +100,10 @@ void GrGLPathProcessor::setTransformData(
continue;
}
transforms[t].fCurrentValue = transform;
- const SeparableVaryingInfo& fragmentInput =
- fSeparableVaryingInfos[transforms[t].fHandle.handle()];
+
SkASSERT(transforms[t].fType == kVec2f_GrSLType ||
transforms[t].fType == kVec3f_GrSLType);
unsigned components = transforms[t].fType == kVec2f_GrSLType ? 2 : 3;
- glpr->setProgramPathFragmentInputTransform(programID,
- fragmentInput.fLocation,
- GR_GL_OBJECT_LINEAR,
- components,
- transform);
+ pdman.setPathFragmentInputTransform(transforms[t].fHandle.handle(), components, transform);
}
}
diff --git a/src/gpu/gl/GrGLPathProcessor.h b/src/gpu/gl/GrGLPathProcessor.h
index d6fc1706d7..0f5cad2013 100644
--- a/src/gpu/gl/GrGLPathProcessor.h
+++ b/src/gpu/gl/GrGLPathProcessor.h
@@ -13,6 +13,7 @@
class GrPathProcessor;
class GrGLPathRendering;
class GrGLGpu;
+class GrGLPathProgramDataManager;
class GrGLPathProcessor : public GrGLPrimitiveProcessor {
public:
@@ -27,6 +28,7 @@ public:
void emitTransforms(GrGLGPBuilder*, const TransformsIn&, TransformsOut*);
+ void bindSeparableVaryings(GrGLGpu* gpu, GrGLuint programID);
void resolveSeparableVaryings(GrGLGpu* gpu, GrGLuint programId);
void setData(const GrGLProgramDataManager&,
@@ -34,25 +36,15 @@ public:
const GrBatchTracker&) override;
void setTransformData(const GrPrimitiveProcessor&,
+ const GrGLPathProgramDataManager&,
int index,
- const SkTArray<const GrCoordTransform*, true>& transforms,
- GrGLPathRendering*,
- GrGLuint programID);
+ const SkTArray<const GrCoordTransform*, true>& transforms);
virtual void didSetData(GrGLPathRendering*) {}
private:
UniformHandle fColorUniform;
GrColor fColor;
- struct SeparableVaryingInfo {
- GrSLType fType;
- GrGLShaderVar fVariable;
- GrGLint fLocation;
- };
-
- typedef SkSTArray<8, SeparableVaryingInfo, true> SeparableVaryingInfoArray;
-
- SeparableVaryingInfoArray fSeparableVaryingInfos;
typedef GrGLPrimitiveProcessor INHERITED;
};
diff --git a/src/gpu/gl/GrGLPathProgram.cpp b/src/gpu/gl/GrGLPathProgram.cpp
new file mode 100644
index 0000000000..4b31f02dac
--- /dev/null
+++ b/src/gpu/gl/GrGLPathProgram.cpp
@@ -0,0 +1,52 @@
+/*
+ * 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 "GrGLPathProgram.h"
+#include "GrGLPathProcessor.h"
+#include "GrGLGpu.h"
+#include "GrPathProcessor.h"
+
+GrGLPathProgram::GrGLPathProgram(GrGLGpu* gpu,
+ const GrProgramDesc& desc,
+ const BuiltinUniformHandles& builtinUniforms,
+ GrGLuint programID,
+ const UniformInfoArray& uniforms,
+ const SeparableVaryingInfoArray& separableVaryings,
+ GrGLInstalledGeoProc* primProc,
+ GrGLInstalledXferProc* xferProcessor,
+ GrGLInstalledFragProcs* fragmentProcessors,
+ SkTArray<UniformHandle>* passSamplerUniforms)
+ : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, primProc,
+ xferProcessor, fragmentProcessors, passSamplerUniforms)
+ , fPathProgramDataManager(gpu, fProgramID, separableVaryings) {
+}
+void GrGLPathProgram::didSetData() {
+ GrGLPathProcessor* pathProc =
+ static_cast<GrGLPathProcessor*>(fGeometryProcessor.get()->fGLProc.get());
+ pathProc->didSetData(fGpu->glPathRendering());
+}
+
+void GrGLPathProgram::setTransformData(const GrPrimitiveProcessor& primProc,
+ const GrPendingFragmentStage& proc,
+ int index,
+ GrGLInstalledFragProc* ip) {
+ GrGLPathProcessor* pathProc =
+ static_cast<GrGLPathProcessor*>(fGeometryProcessor.get()->fGLProc.get());
+ pathProc->setTransformData(primProc, fPathProgramDataManager, index,
+ proc.processor()->coordTransforms());
+}
+
+void GrGLPathProgram::onSetRenderTargetState(const GrPrimitiveProcessor& primProc,
+ const GrPipeline& pipeline) {
+ SkASSERT(!primProc.willUseGeoShader() && primProc.numAttribs() == 0);
+ const GrRenderTarget* rt = pipeline.getRenderTarget();
+ SkISize size;
+ size.set(rt->width(), rt->height());
+ const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
+ fGpu->glPathRendering()->setProjectionMatrix(pathProc.viewMatrix(),
+ size, rt->origin());
+}
diff --git a/src/gpu/gl/GrGLPathProgram.h b/src/gpu/gl/GrGLPathProgram.h
new file mode 100644
index 0000000000..503940c015
--- /dev/null
+++ b/src/gpu/gl/GrGLPathProgram.h
@@ -0,0 +1,49 @@
+/*
+ * 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 GrGLPathProgram_DEFINED
+#define GrGLPathProgram_DEFINED
+
+#include "gl/GrGLProgram.h"
+#include "gl/GrGLPathProgramDataManager.h"
+
+/*
+ * The default GrGL programs consist of at the very least a vertex and fragment shader.
+ * 1.3+ Nvpr ignores the vertex shader, but both require
+ * specialized methods for setting transform data. NVPR also requires setting the
+ * projection matrix through a special function call.
+ */
+class GrGLPathProgram : public GrGLProgram {
+protected:
+ typedef GrGLPathProgramDataManager::SeparableVaryingInfoArray SeparableVaryingInfoArray;
+ GrGLPathProgram(GrGLGpu*,
+ const GrProgramDesc&,
+ const BuiltinUniformHandles&,
+ GrGLuint programID,
+ const UniformInfoArray&,
+ const SeparableVaryingInfoArray&,
+ GrGLInstalledGeoProc*,
+ GrGLInstalledXferProc* xferProcessor,
+ GrGLInstalledFragProcs* fragmentProcessors,
+ SkTArray<UniformHandle>* passSamplerUniforms);
+
+private:
+ void didSetData() override;
+ virtual void setTransformData(const GrPrimitiveProcessor&,
+ const GrPendingFragmentStage&,
+ int index,
+ GrGLInstalledFragProc*) override;
+ virtual void onSetRenderTargetState(const GrPrimitiveProcessor&, const GrPipeline&);
+
+ friend class GrGLPathProgramBuilder;
+
+ GrGLPathProgramDataManager fPathProgramDataManager;
+
+ typedef GrGLProgram INHERITED;
+};
+
+#endif
diff --git a/src/gpu/gl/GrGLPathProgramDataManager.cpp b/src/gpu/gl/GrGLPathProgramDataManager.cpp
new file mode 100644
index 0000000000..f165015a21
--- /dev/null
+++ b/src/gpu/gl/GrGLPathProgramDataManager.cpp
@@ -0,0 +1,48 @@
+ /*
+ * 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 "gl/GrGLPathProgramDataManager.h"
+#include "gl/GrGLPathRendering.h"
+#include "gl/GrGLUniformHandle.h"
+#include "gl/GrGLGpu.h"
+#include "SkMatrix.h"
+
+GrGLPathProgramDataManager::GrGLPathProgramDataManager(
+ GrGLGpu* gpu, GrGLuint programID, const SeparableVaryingInfoArray& separableVaryings)
+ : fGpu(gpu)
+ , fProgramID(programID) {
+ int count = separableVaryings.count();
+ fSeparableVaryings.push_back_n(count);
+ for (int i = 0; i < count; i++) {
+ SeparableVarying& separableVarying = fSeparableVaryings[i];
+ const SeparableVaryingInfo& builderSeparableVarying = separableVaryings[i];
+ SkASSERT(GrGLShaderVar::kNonArray == builderSeparableVarying.fVariable.getArrayCount() ||
+ builderSeparableVarying.fVariable.getArrayCount() > 0);
+ SkDEBUGCODE(
+ separableVarying.fArrayCount = builderSeparableVarying.fVariable.getArrayCount();
+ separableVarying.fType = builderSeparableVarying.fVariable.getType();
+ );
+ separableVarying.fLocation = builderSeparableVarying.fLocation;
+ }
+}
+
+void GrGLPathProgramDataManager::setPathFragmentInputTransform(SeparableVaryingHandle u,
+ int components,
+ const SkMatrix& matrix) const {
+ const SeparableVarying& fragmentInput =
+ fSeparableVaryings[u.toProgramDataIndex()];
+
+ SkASSERT((components == 2 && fragmentInput.fType == kVec2f_GrSLType) ||
+ (components == 3 && fragmentInput.fType == kVec3f_GrSLType));
+
+ fGpu->glPathRendering()->setProgramPathFragmentInputTransform(fProgramID,
+ fragmentInput.fLocation,
+ GR_GL_OBJECT_LINEAR,
+ components,
+ matrix);
+}
+
diff --git a/src/gpu/gl/GrGLPathProgramDataManager.h b/src/gpu/gl/GrGLPathProgramDataManager.h
new file mode 100644
index 0000000000..9eeac7ea20
--- /dev/null
+++ b/src/gpu/gl/GrGLPathProgramDataManager.h
@@ -0,0 +1,75 @@
+/*
+ * 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 GrGLPathProgramDataManager_DEFINED
+#define GrGLPathProgramDataManager_DEFINED
+
+#include "gl/GrGLProgramDataManager.h"
+
+class GrGLPathProgram;
+class GrGLPathProgramBuilder;
+
+/** Manages the resources used by a shader program for NVPR rendering.
+ */
+class GrGLPathProgramDataManager : SkNoncopyable {
+public:
+ class SeparableVaryingHandle : public GrGLProgramDataManager::ShaderResourceHandle {
+ public:
+ /*
+ * Creates a reference to a separable varying of a GrGLShaderBuilder. The ref can be used
+ * to set the varying with the corresponding GrGLPathProgramDataManager.
+ */
+ static SeparableVaryingHandle CreateFromSeparableVaryingIndex(int i) {
+ return GrGLPathProgramDataManager::SeparableVaryingHandle(i);
+ }
+ SeparableVaryingHandle() { }
+ bool operator==(const SeparableVaryingHandle& other) {
+ return other.fValue == fValue;
+ }
+ private:
+ SeparableVaryingHandle(int value) : ShaderResourceHandle(value) { }
+ int toProgramDataIndex() const { SkASSERT(isValid()); return fValue; }
+ int toShaderBuilderIndex() const { return toProgramDataIndex(); }
+
+ friend class GrGLPathProgramDataManager; // For accessing toProgramDataIndex().
+ friend class GrGLPathProcessor; // For accessing toShaderBuilderIndex().
+ };
+
+ struct SeparableVaryingInfo {
+ GrGLShaderVar fVariable;
+ GrGLint fLocation;
+ };
+
+ // This uses an allocator rather than array so that the GrGLShaderVars don't move in memory
+ // after they are inserted. Users of GrGLShaderBuilder get refs to the vars and ptrs to their
+ // name strings. Otherwise, we'd have to hand out copies.
+ typedef GrTAllocator<SeparableVaryingInfo> SeparableVaryingInfoArray;
+
+ GrGLPathProgramDataManager(GrGLGpu*, GrGLuint programID, const SeparableVaryingInfoArray&);
+
+ /** Functions for uploading the varying values.
+ */
+ void setPathFragmentInputTransform(SeparableVaryingHandle u,
+ int components,
+ const SkMatrix& matrix) const;
+private:
+ enum {
+ kUnusedSeparableVarying = -1,
+ };
+ struct SeparableVarying {
+ GrGLint fLocation;
+ SkDEBUGCODE(
+ GrSLType fType;
+ int fArrayCount;
+ );
+ };
+ SkTArray<SeparableVarying, true> fSeparableVaryings;
+ GrGLGpu* fGpu;
+ GrGLuint fProgramID;
+ typedef SkNoncopyable INHERITED;
+};
+#endif
diff --git a/src/gpu/gl/GrGLPrimitiveProcessor.h b/src/gpu/gl/GrGLPrimitiveProcessor.h
index 7345eae35b..474b5f460c 100644
--- a/src/gpu/gl/GrGLPrimitiveProcessor.h
+++ b/src/gpu/gl/GrGLPrimitiveProcessor.h
@@ -10,6 +10,7 @@
#include "GrPrimitiveProcessor.h"
#include "GrGLProcessor.h"
+#include "GrGLPathProgramDataManager.h"
class GrBatchTracker;
class GrPrimitiveProcessor;
@@ -20,6 +21,7 @@ public:
virtual ~GrGLPrimitiveProcessor() {}
typedef GrGLProgramDataManager::UniformHandle UniformHandle;
+ typedef GrGLPathProgramDataManager::SeparableVaryingHandle SeparableVaryingHandle;
typedef GrGLProcessor::TextureSamplerArray TextureSamplerArray;
typedef SkSTArray<2, const GrCoordTransform*, true> ProcCoords;
@@ -85,6 +87,10 @@ protected:
SkASSERT(this->isValid());
return GrGLProgramDataManager::UniformHandle::CreateFromUniformIndex(fHandle);
}
+ SeparableVaryingHandle convertToSeparableVaryingHandle() {
+ SkASSERT(this->isValid());
+ return SeparableVaryingHandle::CreateFromSeparableVaryingIndex(fHandle);
+ }
private:
int fHandle;
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 7a6c5974d8..589b963a8b 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -155,43 +155,3 @@ void GrGLProgram::onSetRenderTargetState(const GrPrimitiveProcessor&,
}
}
-/////////////////////////////////////////////////////////////////////////////////////////
-
-GrGLNvprProgram::GrGLNvprProgram(GrGLGpu* gpu,
- const GrProgramDesc& desc,
- const BuiltinUniformHandles& builtinUniforms,
- GrGLuint programID,
- const UniformInfoArray& uniforms,
- GrGLInstalledGeoProc* primProc,
- GrGLInstalledXferProc* xferProcessor,
- GrGLInstalledFragProcs* fragmentProcessors,
- SkTArray<UniformHandle>* passSamplerUniforms)
- : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, primProc,
- xferProcessor, fragmentProcessors, passSamplerUniforms) {
-}
-void GrGLNvprProgram::didSetData() {
- GrGLPathProcessor* pathProc =
- static_cast<GrGLPathProcessor*>(fGeometryProcessor.get()->fGLProc.get());
- pathProc->didSetData(fGpu->glPathRendering());
-}
-
-void GrGLNvprProgram::setTransformData(const GrPrimitiveProcessor& primProc,
- const GrPendingFragmentStage& proc,
- int index,
- GrGLInstalledFragProc* ip) {
- GrGLPathProcessor* pathProc =
- static_cast<GrGLPathProcessor*>(fGeometryProcessor.get()->fGLProc.get());
- pathProc->setTransformData(primProc, index, proc.processor()->coordTransforms(),
- fGpu->glPathRendering(), fProgramID);
-}
-
-void GrGLNvprProgram::onSetRenderTargetState(const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline) {
- SkASSERT(!primProc.willUseGeoShader() && primProc.numAttribs() == 0);
- const GrRenderTarget* rt = pipeline.getRenderTarget();
- SkISize size;
- size.set(rt->width(), rt->height());
- const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
- fGpu->glPathRendering()->setProjectionMatrix(pathProc.viewMatrix(),
- size, rt->origin());
-}
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index dd86640195..c8fa1b1fec 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -152,36 +152,4 @@ protected:
typedef SkRefCnt INHERITED;
};
-/*
- * Below are slight specializations of the program object for the different types of programs
- * The default GrGL programs consist of at the very least a vertex and fragment shader.
- * Legacy Nvpr only has a fragment shader, 1.3+ Nvpr ignores the vertex shader, but both require
- * specialized methods for setting transform data. Both types of NVPR also require setting the
- * projection matrix through a special function call
- */
-class GrGLNvprProgram : public GrGLProgram {
-protected:
- GrGLNvprProgram(GrGLGpu*,
- const GrProgramDesc&,
- const BuiltinUniformHandles&,
- GrGLuint programID,
- const UniformInfoArray&,
- GrGLInstalledGeoProc*,
- GrGLInstalledXferProc* xferProcessor,
- GrGLInstalledFragProcs* fragmentProcessors,
- SkTArray<UniformHandle>* passSamplerUniforms);
-
-private:
- void didSetData() override;
- virtual void setTransformData(const GrPrimitiveProcessor&,
- const GrPendingFragmentStage&,
- int index,
- GrGLInstalledFragProc*) override;
- virtual void onSetRenderTargetState(const GrPrimitiveProcessor&, const GrPipeline&);
-
- friend class GrGLNvprProgramBuilder;
-
- typedef GrGLProgram INHERITED;
-};
-
#endif
diff --git a/src/gpu/gl/GrGLProgramDataManager.cpp b/src/gpu/gl/GrGLProgramDataManager.cpp
index ce2598e246..93e9a5d931 100644
--- a/src/gpu/gl/GrGLProgramDataManager.cpp
+++ b/src/gpu/gl/GrGLProgramDataManager.cpp
@@ -5,7 +5,7 @@
* found in the LICENSE file.
*/
-#include "gl/GrGLPathRendering.h"
+#include "gl/GrGLProgramDataManager.h"
#include "gl/GrGLUniformHandle.h"
#include "gl/GrGLGpu.h"
#include "SkMatrix.h"
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