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 = |