Chromium Code Reviews| Index: src/gpu/gl/GrGLProgram.cpp |
| diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp |
| index aae9bd8ce19bb463ba17dec926a74449da7bdcff..847137179473d3cb982f506fb097e4b42c2a9f14 100644 |
| --- a/src/gpu/gl/GrGLProgram.cpp |
| +++ b/src/gpu/gl/GrGLProgram.cpp |
| @@ -7,8 +7,6 @@ |
| #include "GrGLProgram.h" |
| -#include "builders/GrGLFullProgramBuilder.h" |
| -#include "builders/GrGLFragmentOnlyProgramBuilder.h" |
| #include "GrAllocator.h" |
| #include "GrProcessor.h" |
| #include "GrCoordTransform.h" |
| @@ -23,44 +21,58 @@ |
| #define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X) |
| #define GL_CALL_RET(R, X) GR_GL_CALL_RET(fGpu->glInterface(), R, X) |
| -GrGLProgram* GrGLProgram::Create(GrGpuGL* gpu, |
| - const GrGLProgramDesc& desc, |
| - const GrGeometryStage* geometryProcessor, |
| - const GrFragmentStage* colorStages[], |
| - const GrFragmentStage* coverageStages[]) { |
| - SkAutoTDelete<GrGLProgramBuilder> builder; |
| - if (desc.getHeader().fUseFragShaderOnly) { |
| - SkASSERT(gpu->glCaps().pathRenderingSupport()); |
| - SkASSERT(gpu->glPathRendering()->texturingMode() == |
| - GrGLPathRendering::FixedFunction_TexturingMode); |
| - SkASSERT(NULL == geometryProcessor); |
| - builder.reset(SkNEW_ARGS(GrGLFragmentOnlyProgramBuilder, (gpu, desc))); |
| +/** |
| + * Retrieves the final matrix that a transform needs to apply to its source coords. |
| + */ |
| +static SkMatrix get_transform_matrix(const GrProcessorStage& processorStage, |
| + bool useExplicitLocalCoords, |
| + int transformIdx) { |
| + const GrCoordTransform& coordTransform = |
| + processorStage.getProcessor()->coordTransform(transformIdx); |
| + SkMatrix combined; |
| + |
| + if (kLocal_GrCoordSet == coordTransform.sourceCoords()) { |
| + // If we have explicit local coords then we shouldn't need a coord change. |
| + const SkMatrix& ccm = |
| + useExplicitLocalCoords ? SkMatrix::I() : processorStage.getCoordChangeMatrix(); |
| + combined.setConcat(coordTransform.getMatrix(), ccm); |
| } else { |
| - builder.reset(SkNEW_ARGS(GrGLFullProgramBuilder, (gpu, desc))); |
| + combined = coordTransform.getMatrix(); |
| } |
| - if (builder->genProgram(geometryProcessor, colorStages, coverageStages)) { |
| - SkASSERT(0 != builder->getProgramID()); |
| - return SkNEW_ARGS(GrGLProgram, (gpu, desc, *builder)); |
| + if (coordTransform.reverseY()) { |
| + // combined.postScale(1,-1); |
| + // combined.postTranslate(0,1); |
| + combined.set(SkMatrix::kMSkewY, |
| + combined[SkMatrix::kMPersp0] - combined[SkMatrix::kMSkewY]); |
| + combined.set(SkMatrix::kMScaleY, |
| + combined[SkMatrix::kMPersp1] - combined[SkMatrix::kMScaleY]); |
| + combined.set(SkMatrix::kMTransY, |
| + combined[SkMatrix::kMPersp2] - combined[SkMatrix::kMTransY]); |
| } |
| - return NULL; |
| + return combined; |
| } |
| +/////////////////////////////////////////////////////////////////////////////////////////////////// |
| + |
| GrGLProgram::GrGLProgram(GrGpuGL* gpu, |
| const GrGLProgramDesc& desc, |
| - const GrGLProgramBuilder& builder) |
| + const BuiltinUniformHandles& builtinUniforms, |
| + GrGLuint programID, |
| + const UniformInfoArray& uniforms, |
| + GrGLInstalledProcessors* geometryProcessor, |
| + GrGLInstalledProcessors* colorProcessors, |
| + GrGLInstalledProcessors* coverageProcessors) |
| : fColor(GrColor_ILLEGAL) |
| , fCoverage(GrColor_ILLEGAL) |
| , fDstCopyTexUnit(-1) |
| - , fBuiltinUniformHandles(builder.getBuiltinUniformHandles()) |
| - , fGeometryProcessor(SkSafeRef(builder.getGeometryProcessor())) |
| - , fColorEffects(SkRef(builder.getColorEffects())) |
| - , fCoverageEffects(SkRef(builder.getCoverageEffects())) |
| - , fProgramID(builder.getProgramID()) |
| - , fHasVertexShader(builder.hasVertexShader()) |
| - , fTexCoordSetCnt(builder.getTexCoordSetCount()) |
| + , fBuiltinUniformHandles(builtinUniforms) |
| + , fProgramID(programID) |
| + , fGeometryProcessor(SkSafeRef(geometryProcessor)) |
| + , fColorEffects(SkRef(colorProcessors)) |
| + , fCoverageEffects(SkRef(coverageProcessors)) |
| , fDesc(desc) |
| , fGpu(gpu) |
| - , fProgramDataManager(gpu, this, builder) { |
| + , fProgramDataManager(gpu, uniforms) { |
| this->initSamplerUniforms(); |
| } |
| @@ -82,12 +94,42 @@ void GrGLProgram::initSamplerUniforms() { |
| fDstCopyTexUnit = texUnitIdx++; |
| } |
| if (fGeometryProcessor.get()) { |
| - fGeometryProcessor->initSamplers(fProgramDataManager, &texUnitIdx); |
| + this->initSamplers(fGeometryProcessor.get(), &texUnitIdx); |
| + } |
| + this->initSamplers(fColorEffects.get(), &texUnitIdx); |
| + this->initSamplers(fCoverageEffects.get(), &texUnitIdx); |
| +} |
| + |
| +void GrGLProgram::initSamplers(GrGLInstalledProcessors* ip, int* texUnitIdx) { |
| + int numEffects = ip->fGLProcessors.count(); |
| + SkASSERT(numEffects == ip->fSamplers.count()); |
| + for (int e = 0; e < numEffects; ++e) { |
| + SkTArray<GrGLInstalledProcessors::Sampler, true>& samplers = ip->fSamplers[e]; |
| + 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)++; |
| + } |
| + } |
| +} |
| + |
| +void GrGLProgram::bindTextures(const GrGLInstalledProcessors* ip, |
| + const GrProcessor& processor, |
| + int effectIdx) { |
| + const SkTArray<GrGLInstalledProcessors::Sampler, true>& samplers = ip->fSamplers[effectIdx]; |
| + 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())); |
| } |
| - fColorEffects->initSamplers(fProgramDataManager, &texUnitIdx); |
| - fCoverageEffects->initSamplers(fProgramDataManager, &texUnitIdx); |
| } |
| + |
| /////////////////////////////////////////////////////////////////////////////// |
| void GrGLProgram::setData(const GrOptDrawState& optState, |
| @@ -125,21 +167,39 @@ void GrGLProgram::setData(const GrOptDrawState& optState, |
| SkASSERT(!fBuiltinUniformHandles.fDstCopySamplerUni.isValid()); |
| } |
| + // we set the textures, and uniforms for installed processors in a generic way, but subclasses |
| + // of GLPrograms determine how to set coord transforms |
|
bsalomon
2014/10/06 18:49:40
GLProgram? no s?
|
| if (fGeometryProcessor.get()) { |
| SkASSERT(geometryProcessor); |
| - fGeometryProcessor->setData(fGpu, drawType, fProgramDataManager, geometryProcessor); |
| + this->setData<GrGeometryStage>(&geometryProcessor, fGeometryProcessor.get()); |
| } |
| - fColorEffects->setData(fGpu, drawType, fProgramDataManager, colorStages); |
| - fCoverageEffects->setData(fGpu, drawType, fProgramDataManager, coverageStages); |
| + this->setData<GrFragmentStage>(colorStages, fColorEffects.get()); |
| + this->setData<GrFragmentStage>(coverageStages, fCoverageEffects.get()); |
| + |
| + // Some of GrGLProgram subclasses need to update state here |
| + this->didSetData(drawType); |
| +} |
| - // PathTexGen state applies to the the fixed function vertex shader. For |
| - // custom shaders, it's ignored, so we don't need to change the texgen |
| - // settings in that case. |
| - if (!fHasVertexShader) { |
| - fGpu->glPathRendering()->flushPathTexGenSettings(fTexCoordSetCnt); |
| +void GrGLProgram::setTransformData(const GrProcessorStage& processor, |
| + int effectIdx, |
| + GrGLInstalledProcessors* ip) { |
| + SkTArray<GrGLInstalledProcessors::Transform, true>& transforms = ip->fTransforms[effectIdx]; |
| + int numTransforms = transforms.count(); |
| + SkASSERT(numTransforms == processor.getProcessor()->numTransforms()); |
| + for (int t = 0; t < numTransforms; ++t) { |
| + SkASSERT(transforms[t].fHandle.isValid()); |
| + const SkMatrix& matrix = get_transform_matrix(processor, ip->fHasExplicitLocalCoords, t); |
| + if (!transforms[t].fCurrentValue.cheapEqualTo(matrix)) { |
| + fProgramDataManager.setSkMatrix(transforms[t].fHandle.convertToUniformHandle(), matrix); |
| + transforms[t].fCurrentValue = matrix; |
| + } |
| } |
| } |
| +void GrGLProgram::didSetData(GrGpu::DrawType drawType) { |
| + SkASSERT(!GrGpu::IsPathRenderingDrawType(drawType)); |
|
bsalomon
2014/10/06 18:49:40
why don't we set data for nvpr? or is this just a
joshua.litt
2014/10/06 19:16:57
Exactly, this is just a generic assert. The only
|
| +} |
| + |
| void GrGLProgram::setColor(const GrOptDrawState& optState, |
| GrColor color, |
| SharedGLState* sharedState) { |
| @@ -219,22 +279,25 @@ void GrGLProgram::setCoverage(const GrOptDrawState& optState, |
| void GrGLProgram::setMatrixAndRenderTargetHeight(GrGpu::DrawType drawType, |
| const GrOptDrawState& optState) { |
| - const GrRenderTarget* rt = optState.getRenderTarget(); |
| - SkISize size; |
| - size.set(rt->width(), rt->height()); |
| - |
| // Load the RT height uniform if it is needed to y-flip gl_FragCoord. |
| if (fBuiltinUniformHandles.fRTHeightUni.isValid() && |
| - fMatrixState.fRenderTargetSize.fHeight != size.fHeight) { |
| + fMatrixState.fRenderTargetSize.fHeight != optState.getRenderTarget()->width()) { |
| fProgramDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, |
| - SkIntToScalar(size.fHeight)); |
| + SkIntToScalar(optState.getRenderTarget()->height())); |
| } |
| - if (GrGpu::IsPathRenderingDrawType(drawType)) { |
| - fGpu->glPathRendering()->setProjectionMatrix(optState.getViewMatrix(), size, rt->origin()); |
| - } else if (fMatrixState.fRenderTargetOrigin != rt->origin() || |
| - fMatrixState.fRenderTargetSize != size || |
| - !fMatrixState.fViewMatrix.cheapEqualTo(optState.getViewMatrix())) { |
| + // call subclasses to set the actual view matrix |
| + this->onSetMatrixAndRenderTargetHeight(drawType, optState); |
| +} |
| + |
| +void GrGLProgram::onSetMatrixAndRenderTargetHeight(GrGpu::DrawType drawType, |
| + const GrOptDrawState& optState) { |
| + const GrRenderTarget* rt = optState.getRenderTarget(); |
| + SkISize size; |
| + size.set(rt->width(), rt->height()); |
| + if (fMatrixState.fRenderTargetOrigin != rt->origin() || |
| + fMatrixState.fRenderTargetSize != size || |
| + !fMatrixState.fViewMatrix.cheapEqualTo(optState.getViewMatrix())) { |
| SkASSERT(fBuiltinUniformHandles.fViewMatrixUni.isValid()); |
| fMatrixState.fViewMatrix = optState.getViewMatrix(); |
| @@ -250,3 +313,115 @@ void GrGLProgram::setMatrixAndRenderTargetHeight(GrGpu::DrawType drawType, |
| fProgramDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec); |
| } |
| } |
| + |
| +///////////////////////////////////////////////////////////////////////////////////////// |
| + |
| +GrGLNvprProgramBase::GrGLNvprProgramBase(GrGpuGL* gpu, |
| + const GrGLProgramDesc& desc, |
| + const BuiltinUniformHandles& builtinUniforms, |
| + GrGLuint programID, |
| + const UniformInfoArray& uniforms, |
| + GrGLInstalledProcessors* colorProcessors, |
| + GrGLInstalledProcessors* coverageProcessors) |
| + : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, NULL, colorProcessors, |
| + coverageProcessors) { |
| +} |
| + |
| +void GrGLNvprProgramBase::onSetMatrixAndRenderTargetHeight(GrGpu::DrawType drawType, |
| + const GrOptDrawState& optState) { |
| + SkASSERT(GrGpu::IsPathRenderingDrawType(drawType)); |
| + const GrRenderTarget* rt = optState.getRenderTarget(); |
| + SkISize size; |
| + size.set(rt->width(), rt->height()); |
| + fGpu->glPathRendering()->setProjectionMatrix(optState.getViewMatrix(), size, rt->origin()); |
| +} |
| + |
| +///////////////////////////////////////////////////////////////////////////////////////// |
| + |
| +GrGLNvprProgram::GrGLNvprProgram(GrGpuGL* gpu, |
| + const GrGLProgramDesc& desc, |
| + const BuiltinUniformHandles& builtinUniforms, |
| + GrGLuint programID, |
| + const UniformInfoArray& uniforms, |
| + GrGLInstalledProcessors* colorProcessors, |
| + GrGLInstalledProcessors* coverageProcessors, |
| + const SeparableVaryingInfoArray& separableVaryings) |
| + : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, colorProcessors, |
| + coverageProcessors) { |
| + int count = separableVaryings.count(); |
| + fVaryings.push_back_n(count); |
| + for (int i = 0; i < count; i++) { |
| + Varying& varying = fVaryings[i]; |
| + const SeparableVaryingInfo& builderVarying = separableVaryings[i]; |
| + SkASSERT(GrGLShaderVar::kNonArray == builderVarying.fVariable.getArrayCount()); |
| + SkDEBUGCODE( |
| + varying.fType = builderVarying.fVariable.getType(); |
| + ); |
| + varying.fLocation = builderVarying.fLocation; |
| + } |
| +} |
| + |
| +void GrGLNvprProgram::didSetData(GrGpu::DrawType drawType) { |
| + SkASSERT(GrGpu::IsPathRenderingDrawType(drawType)); |
| +} |
| + |
| +void GrGLNvprProgram::setTransformData(const GrProcessorStage& processor, |
| + int effectIdx, |
| + GrGLInstalledProcessors* ip) { |
| + SkTArray<GrGLInstalledProcessors::Transform, true>& transforms = ip->fTransforms[effectIdx]; |
| + int numTransforms = transforms.count(); |
| + SkASSERT(numTransforms == processor.getProcessor()->numTransforms()); |
| + for (int t = 0; t < numTransforms; ++t) { |
| + SkASSERT(transforms[t].fHandle.isValid()); |
| + const SkMatrix& transform = get_transform_matrix(processor, ip->fHasExplicitLocalCoords, t); |
| + if (transforms[t].fCurrentValue.cheapEqualTo(transform)) { |
| + continue; |
| + } |
| + transforms[t].fCurrentValue = transform; |
| + const Varying& fragmentInput = fVaryings[transforms[t].fHandle.handle()]; |
| + SkASSERT(transforms[t].fType == kVec2f_GrSLType || transforms[t].fType == kVec3f_GrSLType); |
| + unsigned components = transforms[t].fType == kVec2f_GrSLType ? 2 : 3; |
| + fGpu->glPathRendering()->setProgramPathFragmentInputTransform(fProgramID, |
| + fragmentInput.fLocation, |
| + GR_GL_OBJECT_LINEAR, |
| + components, |
| + transform); |
| + } |
| +} |
| + |
| +////////////////////////////////////////////////////////////////////////////////////// |
| + |
| +GrGLLegacyNvprProgram::GrGLLegacyNvprProgram(GrGpuGL* gpu, |
| + const GrGLProgramDesc& desc, |
| + const BuiltinUniformHandles& builtinUniforms, |
| + GrGLuint programID, |
| + const UniformInfoArray& uniforms, |
| + GrGLInstalledProcessors* colorProcessors, |
| + GrGLInstalledProcessors* coverageProcessors, |
| + int texCoordSetCnt) |
| + : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, colorProcessors, |
| + coverageProcessors) |
| + , fTexCoordSetCnt(texCoordSetCnt) { |
| +} |
| + |
| +void GrGLLegacyNvprProgram::didSetData(GrGpu::DrawType drawType) { |
| + SkASSERT(GrGpu::IsPathRenderingDrawType(drawType)); |
| + fGpu->glPathRendering()->flushPathTexGenSettings(fTexCoordSetCnt); |
| +} |
| + |
| +void GrGLLegacyNvprProgram::setTransformData(const GrProcessorStage& processorStage, |
| + int effectIdx, |
| + GrGLInstalledProcessors* ip) { |
| + // We've hidden the texcoord index in the first entry of the transforms array for each effect |
| + int texCoordIndex = ip->fTransforms[effectIdx][0].fHandle.handle(); |
| + int numTransforms = processorStage.getProcessor()->numTransforms(); |
| + for (int t = 0; t < numTransforms; ++t) { |
| + const SkMatrix& transform = get_transform_matrix(processorStage, false, t); |
| + GrGLPathRendering::PathTexGenComponents components = |
| + GrGLPathRendering::kST_PathTexGenComponents; |
| + if (processorStage.isPerspectiveCoordTransform(t, false)) { |
| + components = GrGLPathRendering::kSTR_PathTexGenComponents; |
| + } |
| + fGpu->glPathRendering()->enablePathTexGen(texCoordIndex++, components, transform); |
| + } |
| +} |