| 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);
|
| + }
|
| +}
|
|
|