Don't call bindTexture from GrGLProgram
Updates GrGLProgram to tell the gpu object which textures it wants bound, instead of calling bindTexture directly. This begins to break its dependence on the specific GrGLGpu object. BUG=skia: Review URL: https://codereview.chromium.org/1192463003
This commit is contained in:
parent
241b56db1d
commit
4271765d11
@ -1492,7 +1492,14 @@ bool GrGLGpu::flushGLState(const DrawArgs& args) {
|
||||
this->flushBlend(blendInfo);
|
||||
}
|
||||
|
||||
program->setData(*args.fPrimitiveProcessor, pipeline, *args.fBatchTracker);
|
||||
SkSTArray<8, const GrTextureAccess*> textureAccesses;
|
||||
program->setData(*args.fPrimitiveProcessor, pipeline, *args.fBatchTracker, &textureAccesses);
|
||||
|
||||
int numTextureAccesses = textureAccesses.count();
|
||||
for (int i = 0; i < numTextureAccesses; i++) {
|
||||
this->bindTexture(i, textureAccesses[i]->getParams(),
|
||||
static_cast<GrGLTexture*>(textureAccesses[i]->getTexture()));
|
||||
}
|
||||
|
||||
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTarget());
|
||||
this->flushStencil(pipeline.getStencil());
|
||||
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void GrGLProgram::setData(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline,
|
||||
const GrBatchTracker& batchTracker) {
|
||||
template <class Proc>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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 =
|
||||
|
@ -90,12 +90,13 @@ public:
|
||||
};
|
||||
|
||||
/**
|
||||
* This function uploads uniforms and calls each GrGLProcessor's setData. It is called before a
|
||||
* draw occurs using the program after the program has already been bound. It also uses the
|
||||
* GrGLGpu object to bind the textures required by the GrGLProcessors. The color and coverage
|
||||
* stages come from GrGLProgramDesc::Build().
|
||||
* This function uploads uniforms, calls each GrGLProcessor's setData, and retrieves the
|
||||
* textures that need to be bound on each unit. It is the caller's responsibility to ensure
|
||||
* the program is bound before calling, and to bind the outgoing textures to their respective
|
||||
* units upon return. (Each index in the array corresponds to its matching GL texture unit.)
|
||||
*/
|
||||
void setData(const GrPrimitiveProcessor&, const GrPipeline&, const GrBatchTracker&);
|
||||
void setData(const GrPrimitiveProcessor&, const GrPipeline&, const GrBatchTracker&,
|
||||
SkTArray<const GrTextureAccess*>* textureBindings);
|
||||
|
||||
protected:
|
||||
typedef GrGLProgramDataManager::UniformHandle UniformHandle;
|
||||
@ -108,21 +109,16 @@ protected:
|
||||
const UniformInfoArray&,
|
||||
GrGLInstalledGeoProc* geometryProcessor,
|
||||
GrGLInstalledXferProc* xferProcessor,
|
||||
GrGLInstalledFragProcs* fragmentProcessors);
|
||||
|
||||
// Sets the texture units for samplers.
|
||||
void initSamplerUniforms();
|
||||
template <class Proc>
|
||||
void initSamplers(Proc*, int* texUnitIdx);
|
||||
GrGLInstalledFragProcs* fragmentProcessors,
|
||||
SkTArray<UniformHandle>* passSamplerUniforms);
|
||||
|
||||
// A templated helper to loop over effects, set the transforms(via subclass) and bind textures
|
||||
void setFragmentData(const GrPrimitiveProcessor&, const GrPipeline&);
|
||||
void setFragmentData(const GrPrimitiveProcessor&, const GrPipeline&,
|
||||
SkTArray<const GrTextureAccess*>* textureBindings);
|
||||
virtual void setTransformData(const GrPrimitiveProcessor&,
|
||||
const GrPendingFragmentStage&,
|
||||
int index,
|
||||
GrGLInstalledFragProc*);
|
||||
template <class Proc>
|
||||
void bindTextures(const Proc*, const GrProcessor&);
|
||||
|
||||
/*
|
||||
* Legacy NVPR needs a hook here to flush path tex gen settings.
|
||||
@ -150,6 +146,7 @@ protected:
|
||||
GrProgramDesc fDesc;
|
||||
GrGLGpu* fGpu;
|
||||
GrGLProgramDataManager fProgramDataManager;
|
||||
SkTArray<UniformHandle> fSamplerUniforms;
|
||||
|
||||
friend class GrGLProgramBuilder;
|
||||
|
||||
@ -172,7 +169,8 @@ protected:
|
||||
const UniformInfoArray&,
|
||||
GrGLInstalledGeoProc*,
|
||||
GrGLInstalledXferProc* xferProcessor,
|
||||
GrGLInstalledFragProcs* fragmentProcessors);
|
||||
GrGLInstalledFragProcs* fragmentProcessors,
|
||||
SkTArray<UniformHandle>* passSamplerUniforms);
|
||||
|
||||
private:
|
||||
void didSetData() override;
|
||||
|
@ -38,9 +38,8 @@ public:
|
||||
static_cast<GrGLPathProcessor*>(fGeometryProcessor->fGLProc.get());
|
||||
pathProc->resolveSeparableVaryings(fGpu, programID);
|
||||
return SkNEW_ARGS(GrGLNvprProgram, (fGpu, this->desc(), fUniformHandles, programID,
|
||||
fUniforms,
|
||||
fGeometryProcessor,
|
||||
fXferProcessor, fFragmentProcessors.get()));
|
||||
fUniforms, fGeometryProcessor, fXferProcessor,
|
||||
fFragmentProcessors.get(), &fSamplerUniforms));
|
||||
}
|
||||
|
||||
private:
|
||||
@ -98,7 +97,8 @@ GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu, const DrawArgs& args)
|
||||
, fXferProcessor(NULL)
|
||||
, fArgs(args)
|
||||
, fGpu(gpu)
|
||||
, fUniforms(kVarsPerBlock) {
|
||||
, fUniforms(kVarsPerBlock)
|
||||
, fSamplerUniforms(4) {
|
||||
}
|
||||
|
||||
void GrGLProgramBuilder::addVarying(const char* name,
|
||||
@ -381,16 +381,17 @@ template <class Proc>
|
||||
void GrGLProgramBuilder::emitSamplers(const GrProcessor& processor,
|
||||
GrGLProcessor::TextureSamplerArray* outSamplers,
|
||||
GrGLInstalledProc<Proc>* ip) {
|
||||
SkDEBUGCODE(ip->fSamplersIdx = fSamplerUniforms.count();)
|
||||
int numTextures = processor.numTextures();
|
||||
ip->fSamplers.push_back_n(numTextures);
|
||||
UniformHandle* localSamplerUniforms = fSamplerUniforms.push_back_n(numTextures);
|
||||
SkString name;
|
||||
for (int t = 0; t < numTextures; ++t) {
|
||||
name.printf("Sampler%d", t);
|
||||
ip->fSamplers[t].fUniform = this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
|
||||
kSampler2D_GrSLType, kDefault_GrSLPrecision,
|
||||
name.c_str());
|
||||
localSamplerUniforms[t] = this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
|
||||
kSampler2D_GrSLType, kDefault_GrSLPrecision,
|
||||
name.c_str());
|
||||
SkNEW_APPEND_TO_TARRAY(outSamplers, GrGLProcessor::TextureSampler,
|
||||
(ip->fSamplers[t].fUniform, processor.textureAccess(t)));
|
||||
(localSamplerUniforms[t], processor.textureAccess(t)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -498,7 +499,8 @@ void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) {
|
||||
|
||||
GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) {
|
||||
return SkNEW_ARGS(GrGLProgram, (fGpu, this->desc(), fUniformHandles, programID, fUniforms,
|
||||
fGeometryProcessor, fXferProcessor, fFragmentProcessors.get()));
|
||||
fGeometryProcessor, fXferProcessor, fFragmentProcessors.get(),
|
||||
&fSamplerUniforms));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -188,15 +188,8 @@ public:
|
||||
*/
|
||||
template <class Proc>
|
||||
struct GrGLInstalledProc {
|
||||
typedef GrGLProgramDataManager::UniformHandle UniformHandle;
|
||||
|
||||
struct Sampler {
|
||||
SkDEBUGCODE(Sampler() : fTextureUnit(-1) {})
|
||||
UniformHandle fUniform;
|
||||
int fTextureUnit;
|
||||
};
|
||||
SkSTArray<4, Sampler, true> fSamplers;
|
||||
SkAutoTDelete<Proc> fGLProc;
|
||||
SkDEBUGCODE(int fSamplersIdx;)
|
||||
SkAutoTDelete<Proc> fGLProc;
|
||||
};
|
||||
|
||||
typedef GrGLInstalledProc<GrGLPrimitiveProcessor> GrGLInstalledGeoProc;
|
||||
@ -390,6 +383,7 @@ protected:
|
||||
UniformInfoArray fUniforms;
|
||||
GrGLPrimitiveProcessor::TransformsIn fCoordTransforms;
|
||||
GrGLPrimitiveProcessor::TransformsOut fOutCoords;
|
||||
SkTArray<UniformHandle> fSamplerUniforms;
|
||||
|
||||
friend class GrGLShaderBuilder;
|
||||
friend class GrGLVertexBuilder;
|
||||
|
Loading…
Reference in New Issue
Block a user