diff options
-rw-r--r-- | gyp/gpu.gypi | 6 | ||||
-rw-r--r-- | src/gpu/gl/GrGLPathProcessor.cpp | 36 | ||||
-rw-r--r-- | src/gpu/gl/GrGLPathProcessor.h | 16 | ||||
-rw-r--r-- | src/gpu/gl/GrGLPathProgram.cpp | 52 | ||||
-rw-r--r-- | src/gpu/gl/GrGLPathProgram.h | 49 | ||||
-rw-r--r-- | src/gpu/gl/GrGLPathProgramDataManager.cpp | 48 | ||||
-rw-r--r-- | src/gpu/gl/GrGLPathProgramDataManager.h | 75 | ||||
-rw-r--r-- | src/gpu/gl/GrGLPrimitiveProcessor.h | 6 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.cpp | 40 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.h | 32 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramDataManager.cpp | 2 | ||||
-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 |
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 |