Index: src/gpu/gl/GrGLProgram.cpp |
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp |
index 480e1b77352c99b59fbf33a84357d0b293e0153d..e0d4939323b0f2438944fcaad78712d7b6120d63 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,45 +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 GrOptDrawState& optState, |
- 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, optState, 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, optState, 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(); |
} |
@@ -83,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, |
@@ -126,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 GLProgram determine how to set coord transforms |
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)); |
+} |
+ |
void GrGLProgram::setColor(const GrOptDrawState& optState, |
GrColor color, |
SharedGLState* sharedState) { |
@@ -220,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()->height()) { |
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(); |
@@ -251,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); |
+ } |
+} |