Chromium Code Reviews| Index: src/gpu/gl/GrGLProgram.cpp |
| diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp |
| index 3a4ac980ed2afa30a2759c697e4331554e1900a5..679e3ba4ca23af5fa189d59c50dbbd6e3c433dab 100644 |
| --- a/src/gpu/gl/GrGLProgram.cpp |
| +++ b/src/gpu/gl/GrGLProgram.cpp |
| @@ -34,7 +34,8 @@ GrGLProgram::GrGLProgram(GrGLGpu* gpu, |
| const UniformInfoArray& uniforms, |
| GrGLInstalledGeoProc* geometryProcessor, |
| GrGLInstalledXferProc* xferProcessor, |
| - GrGLInstalledFragProcs* fragmentProcessors) |
| + GrGLInstalledFragProcs* fragmentProcessors, |
| + SkTArray<UniformHandle>* passSamplerUniforms) |
| : fColor(GrColor_ILLEGAL) |
| , fCoverage(0) |
| , fDstTextureUnit(-1) |
| @@ -46,7 +47,12 @@ GrGLProgram::GrGLProgram(GrGLGpu* gpu, |
| , fDesc(desc) |
| , fGpu(gpu) |
| , fProgramDataManager(gpu, uniforms) { |
| - this->initSamplerUniforms(); |
| + fSamplerUniforms.swap(passSamplerUniforms); |
| + // Assign texture units to sampler uniforms one time up front. |
| + GL_CALL(UseProgram(fProgramID)); |
| + for (int i = 0; i < fSamplerUniforms.count(); i++) { |
| + fProgramDataManager.setSampler(fSamplerUniforms[i], i); |
| + } |
| } |
| GrGLProgram::~GrGLProgram() { |
| @@ -59,68 +65,46 @@ void GrGLProgram::abandon() { |
| fProgramID = 0; |
| } |
| -void GrGLProgram::initSamplerUniforms() { |
| - GL_CALL(UseProgram(fProgramID)); |
| - GrGLint texUnitIdx = 0; |
| - this->initSamplers(fGeometryProcessor.get(), &texUnitIdx); |
| - if (fXferProcessor.get()) { |
| - this->initSamplers(fXferProcessor.get(), &texUnitIdx); |
| - } |
| - int numProcs = fFragmentProcessors->fProcs.count(); |
| - for (int i = 0; i < numProcs; i++) { |
| - this->initSamplers(fFragmentProcessors->fProcs[i], &texUnitIdx); |
| - } |
| -} |
| - |
| -template <class Proc> |
| -void GrGLProgram::initSamplers(Proc* ip, int* texUnitIdx) { |
| - SkTArray<typename Proc::Sampler, true>& samplers = ip->fSamplers; |
| - int numSamplers = samplers.count(); |
| - for (int s = 0; s < numSamplers; ++s) { |
| - SkASSERT(samplers[s].fUniform.isValid()); |
| - fProgramDataManager.setSampler(samplers[s].fUniform, *texUnitIdx); |
| - samplers[s].fTextureUnit = (*texUnitIdx)++; |
| - } |
| -} |
| +/////////////////////////////////////////////////////////////////////////////// |
| template <class Proc> |
| -void GrGLProgram::bindTextures(const Proc* ip, const GrProcessor& processor) { |
| - const SkTArray<typename Proc::Sampler, true>& samplers = ip->fSamplers; |
| - int numSamplers = samplers.count(); |
| - SkASSERT(numSamplers == processor.numTextures()); |
| - for (int s = 0; s < numSamplers; ++s) { |
| - SkASSERT(samplers[s].fTextureUnit >= 0); |
| - const GrTextureAccess& textureAccess = processor.textureAccess(s); |
| - fGpu->bindTexture(samplers[s].fTextureUnit, |
| - textureAccess.getParams(), |
| - static_cast<GrGLTexture*>(textureAccess.getTexture())); |
| +static void append_texture_bindings(const Proc* ip, |
| + const GrProcessor& processor, |
| + SkTArray<const GrTextureAccess*>* textureBindings) { |
| + if (int numTextures = processor.numTextures()) { |
| + SkASSERT(textureBindings->count() == ip->fSamplersIdx); |
| + const GrTextureAccess** bindings = textureBindings->push_back_n(numTextures); |
| + int i = 0; |
| + do { |
| + bindings[i] = &processor.textureAccess(i); |
| + } while (++i < numTextures); |
|
joshualitt
2015/06/18 15:51:27
why not just a regular for loop?
Chris Dalton
2015/06/18 18:13:51
Philosophical reasons I guess. No need for a top t
|
| } |
| } |
| - |
| -/////////////////////////////////////////////////////////////////////////////// |
| - |
| -void GrGLProgram::setData(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline, |
| - const GrBatchTracker& batchTracker) { |
| +void GrGLProgram::setData(const GrPrimitiveProcessor& primProc, |
| + const GrPipeline& pipeline, |
| + const GrBatchTracker& batchTracker, |
| + SkTArray<const GrTextureAccess*>* textureBindings) { |
| this->setRenderTargetState(primProc, pipeline); |
| // we set the textures, and uniforms for installed processors in a generic way, but subclasses |
| // of GLProgram determine how to set coord transforms |
| fGeometryProcessor->fGLProc->setData(fProgramDataManager, primProc, batchTracker); |
| - this->bindTextures(fGeometryProcessor.get(), primProc); |
| + append_texture_bindings(fGeometryProcessor.get(), primProc, textureBindings); |
| + |
| + this->setFragmentData(primProc, pipeline, textureBindings); |
| const GrXferProcessor& xp = *pipeline.getXferProcessor(); |
| fXferProcessor->fGLProc->setData(fProgramDataManager, xp); |
| - this->bindTextures(fXferProcessor.get(), xp); |
| - |
| - this->setFragmentData(primProc, pipeline); |
| + append_texture_bindings(fXferProcessor.get(), xp, textureBindings); |
| // Some of GrGLProgram subclasses need to update state here |
| this->didSetData(); |
| } |
| void GrGLProgram::setFragmentData(const GrPrimitiveProcessor& primProc, |
| - const GrPipeline& pipeline) { |
| + const GrPipeline& pipeline, |
| + SkTArray<const GrTextureAccess*>* textureBindings) { |
| int numProcessors = fFragmentProcessors->fProcs.count(); |
| for (int e = 0; e < numProcessors; ++e) { |
| const GrPendingFragmentStage& stage = pipeline.getFragmentStage(e); |
| @@ -130,7 +114,7 @@ void GrGLProgram::setFragmentData(const GrPrimitiveProcessor& primProc, |
| stage, |
| e, |
| fFragmentProcessors->fProcs[e]); |
| - this->bindTextures(fFragmentProcessors->fProcs[e], processor); |
| + append_texture_bindings(fFragmentProcessors->fProcs[e], processor, textureBindings); |
| } |
| } |
| void GrGLProgram::setTransformData(const GrPrimitiveProcessor& primProc, |
| @@ -181,9 +165,10 @@ GrGLNvprProgram::GrGLNvprProgram(GrGLGpu* gpu, |
| const UniformInfoArray& uniforms, |
| GrGLInstalledGeoProc* primProc, |
| GrGLInstalledXferProc* xferProcessor, |
| - GrGLInstalledFragProcs* fragmentProcessors) |
| + GrGLInstalledFragProcs* fragmentProcessors, |
| + SkTArray<UniformHandle>* passSamplerUniforms) |
| : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, primProc, |
| - xferProcessor, fragmentProcessors) { |
| + xferProcessor, fragmentProcessors, passSamplerUniforms) { |
| } |
| void GrGLNvprProgram::didSetData() { |
| GrGLPathProcessor* pathProc = |