aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gyp/gpu.gypi6
-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
16 files changed, 380 insertions, 163 deletions
diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi
index f15f1f143a..4d0efba96c 100644
--- a/gyp/gpu.gypi
+++ b/gyp/gpu.gypi
@@ -295,6 +295,10 @@
'<(skia_src_path)/gpu/gl/GrGLNameAllocator.h',
'<(skia_src_path)/gpu/gl/GrGLNoOpInterface.cpp',
'<(skia_src_path)/gpu/gl/GrGLNoOpInterface.h',
+ '<(skia_src_path)/gpu/gl/GrGLPathProgram.cpp',
+ '<(skia_src_path)/gpu/gl/GrGLPathProgram.h',
+ '<(skia_src_path)/gpu/gl/GrGLPathProgramDataManager.cpp',
+ '<(skia_src_path)/gpu/gl/GrGLPathProgramDataManager.h',
'<(skia_src_path)/gpu/gl/GrGLPath.cpp',
'<(skia_src_path)/gpu/gl/GrGLPath.h',
'<(skia_src_path)/gpu/gl/GrGLPathProcessor.cpp',
@@ -331,6 +335,8 @@
'<(skia_src_path)/gpu/gl/GrGLXferProcessor.h',
# Files for building GLSL shaders
+ '<(skia_src_path)/gpu/gl/builders/GrGLPathProgramBuilder.cpp',
+ '<(skia_src_path)/gpu/gl/builders/GrGLPathProgramBuilder.h',
'<(skia_src_path)/gpu/gl/builders/GrGLProgramBuilder.cpp',
'<(skia_src_path)/gpu/gl/builders/GrGLProgramBuilder.h',
'<(skia_src_path)/gpu/gl/builders/GrGLShaderBuilder.cpp',
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