GrGLProgram.cpp revision 50785a3d10b53bea5beb6e18431a2449860be237
1/* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "GrGLProgram.h" 9 10#include "GrAllocator.h" 11#include "GrProcessor.h" 12#include "GrCoordTransform.h" 13#include "GrGLGeometryProcessor.h" 14#include "GrGLProcessor.h" 15#include "GrGLXferProcessor.h" 16#include "GrGLGpu.h" 17#include "GrGLPathRendering.h" 18#include "GrGLShaderVar.h" 19#include "GrGLSL.h" 20#include "GrPipeline.h" 21#include "GrXferProcessor.h" 22#include "SkXfermode.h" 23 24#define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X) 25#define GL_CALL_RET(R, X) GR_GL_CALL_RET(fGpu->glInterface(), R, X) 26 27/////////////////////////////////////////////////////////////////////////////////////////////////// 28 29GrGLProgram::GrGLProgram(GrGLGpu* gpu, 30 const GrProgramDesc& desc, 31 const BuiltinUniformHandles& builtinUniforms, 32 GrGLuint programID, 33 const UniformInfoArray& uniforms, 34 GrGLInstalledGeoProc* geometryProcessor, 35 GrGLInstalledXferProc* xferProcessor, 36 GrGLInstalledFragProcs* fragmentProcessors) 37 : fColor(GrColor_ILLEGAL) 38 , fCoverage(0) 39 , fDstCopyTexUnit(-1) 40 , fBuiltinUniformHandles(builtinUniforms) 41 , fProgramID(programID) 42 , fGeometryProcessor(geometryProcessor) 43 , fXferProcessor(xferProcessor) 44 , fFragmentProcessors(SkRef(fragmentProcessors)) 45 , fDesc(desc) 46 , fGpu(gpu) 47 , fProgramDataManager(gpu, uniforms) { 48 this->initSamplerUniforms(); 49} 50 51GrGLProgram::~GrGLProgram() { 52 if (fProgramID) { 53 GL_CALL(DeleteProgram(fProgramID)); 54 } 55} 56 57void GrGLProgram::abandon() { 58 fProgramID = 0; 59} 60 61void GrGLProgram::initSamplerUniforms() { 62 GL_CALL(UseProgram(fProgramID)); 63 GrGLint texUnitIdx = 0; 64 this->initSamplers(fGeometryProcessor.get(), &texUnitIdx); 65 if (fXferProcessor.get()) { 66 this->initSamplers(fXferProcessor.get(), &texUnitIdx); 67 } 68 int numProcs = fFragmentProcessors->fProcs.count(); 69 for (int i = 0; i < numProcs; i++) { 70 this->initSamplers(fFragmentProcessors->fProcs[i], &texUnitIdx); 71 } 72} 73 74template <class Proc> 75void GrGLProgram::initSamplers(Proc* ip, int* texUnitIdx) { 76 SkTArray<typename Proc::Sampler, true>& samplers = ip->fSamplers; 77 int numSamplers = samplers.count(); 78 for (int s = 0; s < numSamplers; ++s) { 79 SkASSERT(samplers[s].fUniform.isValid()); 80 fProgramDataManager.setSampler(samplers[s].fUniform, *texUnitIdx); 81 samplers[s].fTextureUnit = (*texUnitIdx)++; 82 } 83} 84 85template <class Proc> 86void GrGLProgram::bindTextures(const Proc* ip, const GrProcessor& processor) { 87 const SkTArray<typename Proc::Sampler, true>& samplers = ip->fSamplers; 88 int numSamplers = samplers.count(); 89 SkASSERT(numSamplers == processor.numTextures()); 90 for (int s = 0; s < numSamplers; ++s) { 91 SkASSERT(samplers[s].fTextureUnit >= 0); 92 const GrTextureAccess& textureAccess = processor.textureAccess(s); 93 fGpu->bindTexture(samplers[s].fTextureUnit, 94 textureAccess.getParams(), 95 static_cast<GrGLTexture*>(textureAccess.getTexture())); 96 } 97} 98 99 100/////////////////////////////////////////////////////////////////////////////// 101 102void GrGLProgram::setData(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline, 103 const GrBatchTracker& batchTracker) { 104 this->setRenderTargetState(primProc, pipeline); 105 106 // we set the textures, and uniforms for installed processors in a generic way, but subclasses 107 // of GLProgram determine how to set coord transforms 108 fGeometryProcessor->fGLProc->setData(fProgramDataManager, primProc, batchTracker); 109 this->bindTextures(fGeometryProcessor.get(), primProc); 110 111 const GrXferProcessor& xp = *pipeline.getXferProcessor(); 112 fXferProcessor->fGLProc->setData(fProgramDataManager, xp); 113 this->bindTextures(fXferProcessor.get(), xp); 114 115 this->setFragmentData(primProc, pipeline); 116 117 // Some of GrGLProgram subclasses need to update state here 118 this->didSetData(); 119} 120 121void GrGLProgram::setFragmentData(const GrPrimitiveProcessor& primProc, 122 const GrPipeline& pipeline) { 123 int numProcessors = fFragmentProcessors->fProcs.count(); 124 for (int e = 0; e < numProcessors; ++e) { 125 const GrPendingFragmentStage& stage = pipeline.getFragmentStage(e); 126 const GrProcessor& processor = *stage.processor(); 127 fFragmentProcessors->fProcs[e]->fGLProc->setData(fProgramDataManager, processor); 128 this->setTransformData(primProc, 129 stage, 130 e, 131 fFragmentProcessors->fProcs[e]); 132 this->bindTextures(fFragmentProcessors->fProcs[e], processor); 133 } 134} 135void GrGLProgram::setTransformData(const GrPrimitiveProcessor& primProc, 136 const GrPendingFragmentStage& processor, 137 int index, 138 GrGLInstalledFragProc* ip) { 139 GrGLGeometryProcessor* gp = 140 static_cast<GrGLGeometryProcessor*>(fGeometryProcessor.get()->fGLProc.get()); 141 gp->setTransformData(primProc, fProgramDataManager, index, 142 processor.processor()->coordTransforms()); 143} 144 145void GrGLProgram::setRenderTargetState(const GrPrimitiveProcessor& primProc, 146 const GrPipeline& pipeline) { 147 // Load the RT height uniform if it is needed to y-flip gl_FragCoord. 148 if (fBuiltinUniformHandles.fRTHeightUni.isValid() && 149 fRenderTargetState.fRenderTargetSize.fHeight != pipeline.getRenderTarget()->height()) { 150 fProgramDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, 151 SkIntToScalar(pipeline.getRenderTarget()->height())); 152 } 153 154 // call subclasses to set the actual view matrix 155 this->onSetRenderTargetState(primProc, pipeline); 156} 157 158void GrGLProgram::onSetRenderTargetState(const GrPrimitiveProcessor&, 159 const GrPipeline& pipeline) { 160 const GrRenderTarget* rt = pipeline.getRenderTarget(); 161 SkISize size; 162 size.set(rt->width(), rt->height()); 163 if (fRenderTargetState.fRenderTargetOrigin != rt->origin() || 164 fRenderTargetState.fRenderTargetSize != size) { 165 fRenderTargetState.fRenderTargetSize = size; 166 fRenderTargetState.fRenderTargetOrigin = rt->origin(); 167 168 GrGLfloat rtAdjustmentVec[4]; 169 fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec); 170 fProgramDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec); 171 } 172} 173 174///////////////////////////////////////////////////////////////////////////////////////// 175 176GrGLNvprProgram::GrGLNvprProgram(GrGLGpu* gpu, 177 const GrProgramDesc& desc, 178 const BuiltinUniformHandles& builtinUniforms, 179 GrGLuint programID, 180 const UniformInfoArray& uniforms, 181 GrGLInstalledGeoProc* primProc, 182 GrGLInstalledXferProc* xferProcessor, 183 GrGLInstalledFragProcs* fragmentProcessors) 184 : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, primProc, 185 xferProcessor, fragmentProcessors) { 186} 187void GrGLNvprProgram::didSetData() { 188 GrGLPathProcessor* pathProc = 189 static_cast<GrGLPathProcessor*>(fGeometryProcessor.get()->fGLProc.get()); 190 pathProc->didSetData(fGpu->glPathRendering()); 191} 192 193void GrGLNvprProgram::setTransformData(const GrPrimitiveProcessor& primProc, 194 const GrPendingFragmentStage& proc, 195 int index, 196 GrGLInstalledFragProc* ip) { 197 GrGLPathProcessor* pathProc = 198 static_cast<GrGLPathProcessor*>(fGeometryProcessor.get()->fGLProc.get()); 199 pathProc->setTransformData(primProc, index, proc.processor()->coordTransforms(), 200 fGpu->glPathRendering(), fProgramID); 201} 202 203void GrGLNvprProgram::onSetRenderTargetState(const GrPrimitiveProcessor& primProc, 204 const GrPipeline& pipeline) { 205 SkASSERT(!primProc.willUseGeoShader() && primProc.numAttribs() == 0); 206 const GrRenderTarget* rt = pipeline.getRenderTarget(); 207 SkISize size; 208 size.set(rt->width(), rt->height()); 209 fGpu->glPathRendering()->setProjectionMatrix(primProc.viewMatrix(), 210 size, rt->origin()); 211} 212