| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrGLProgramBuilder.h" | 8 #include "GrGLProgramBuilder.h" |
| 9 | 9 |
| 10 #include "gl/GrGLGeometryProcessor.h" | 10 #include "gl/GrGLGeometryProcessor.h" |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 return fGpu->ctxInfo(); | 179 return fGpu->ctxInfo(); |
| 180 } | 180 } |
| 181 | 181 |
| 182 bool GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr
4* inputCoverage) { | 182 bool GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr
4* inputCoverage) { |
| 183 // First we loop over all of the installed processors and collect coord tran
sforms. These will | 183 // First we loop over all of the installed processors and collect coord tran
sforms. These will |
| 184 // be sent to the GrGLPrimitiveProcessor in its emitCode function | 184 // be sent to the GrGLPrimitiveProcessor in its emitCode function |
| 185 const GrPrimitiveProcessor& primProc = this->primitiveProcessor(); | 185 const GrPrimitiveProcessor& primProc = this->primitiveProcessor(); |
| 186 int totalTextures = primProc.numTextures(); | 186 int totalTextures = primProc.numTextures(); |
| 187 const int maxTextureUnits = fGpu->glCaps().maxFragmentTextureUnits(); | 187 const int maxTextureUnits = fGpu->glCaps().maxFragmentTextureUnits(); |
| 188 | 188 |
| 189 for (int i = 0; i < this->pipeline().numFragmentStages(); i++) { | 189 for (int i = 0; i < this->pipeline().numFragmentProcessors(); i++) { |
| 190 const GrFragmentProcessor* processor = this->pipeline().getFragmentStage
(i).processor(); | 190 const GrFragmentProcessor& processor = this->pipeline().getFragmentProce
ssor(i); |
| 191 | 191 |
| 192 if (!primProc.hasTransformedLocalCoords()) { | 192 if (!primProc.hasTransformedLocalCoords()) { |
| 193 SkSTArray<2, const GrCoordTransform*, true>& procCoords = fCoordTran
sforms.push_back(); | 193 SkTArray<const GrCoordTransform*, true>& procCoords = fCoordTransfor
ms.push_back(); |
| 194 processor->gatherCoordTransforms(&procCoords); | 194 processor.gatherCoordTransforms(&procCoords); |
| 195 } | 195 } |
| 196 | 196 |
| 197 totalTextures += processor->numTextures(); | 197 totalTextures += processor.numTextures(); |
| 198 if (totalTextures >= maxTextureUnits) { | 198 if (totalTextures >= maxTextureUnits) { |
| 199 GrCapsDebugf(fGpu->caps(), "Program would use too many texture units
\n"); | 199 GrCapsDebugf(fGpu->caps(), "Program would use too many texture units
\n"); |
| 200 return false; | 200 return false; |
| 201 } | 201 } |
| 202 } | 202 } |
| 203 | 203 |
| 204 this->emitAndInstallProc(primProc, inputColor, inputCoverage); | 204 this->emitAndInstallProc(primProc, inputColor, inputCoverage); |
| 205 | 205 |
| 206 fFragmentProcessors.reset(new GrGLInstalledFragProcs); | 206 fFragmentProcessors.reset(new GrGLInstalledFragProcs); |
| 207 int numProcs = this->pipeline().numFragmentStages(); | 207 int numProcs = this->pipeline().numFragmentProcessors(); |
| 208 this->emitAndInstallFragProcs(0, this->pipeline().numColorFragmentStages(),
inputColor); | 208 this->emitAndInstallFragProcs(0, this->pipeline().numColorFragmentProcessors
(), inputColor); |
| 209 this->emitAndInstallFragProcs(this->pipeline().numColorFragmentStages(), num
Procs, | 209 this->emitAndInstallFragProcs(this->pipeline().numColorFragmentProcessors(),
numProcs, |
| 210 inputCoverage); | 210 inputCoverage); |
| 211 this->emitAndInstallXferProc(*this->pipeline().getXferProcessor(), *inputCol
or, *inputCoverage); | 211 this->emitAndInstallXferProc(*this->pipeline().getXferProcessor(), *inputCol
or, *inputCoverage); |
| 212 return true; | 212 return true; |
| 213 } | 213 } |
| 214 | 214 |
| 215 void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset, | 215 void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset, |
| 216 int numProcs, | 216 int numProcs, |
| 217 GrGLSLExpr4* inOut) { | 217 GrGLSLExpr4* inOut) { |
| 218 for (int e = procOffset; e < numProcs; ++e) { | 218 for (int i = procOffset; i < numProcs; ++i) { |
| 219 GrGLSLExpr4 output; | 219 GrGLSLExpr4 output; |
| 220 const GrPendingFragmentStage& stage = this->pipeline().getFragmentStage(
e); | 220 const GrFragmentProcessor& fp = this->pipeline().getFragmentProcessor(i)
; |
| 221 this->emitAndInstallProc(stage, e, *inOut, &output); | 221 this->emitAndInstallProc(fp, i, *inOut, &output); |
| 222 *inOut = output; | 222 *inOut = output; |
| 223 } | 223 } |
| 224 } | 224 } |
| 225 | 225 |
| 226 void GrGLProgramBuilder::nameExpression(GrGLSLExpr4* output, const char* baseNam
e) { | 226 void GrGLProgramBuilder::nameExpression(GrGLSLExpr4* output, const char* baseNam
e) { |
| 227 // create var to hold stage result. If we already have a valid output name,
just use that | 227 // create var to hold stage result. If we already have a valid output name,
just use that |
| 228 // otherwise create a new mangled one. This name is only valid if we are re
ordering stages | 228 // otherwise create a new mangled one. This name is only valid if we are re
ordering stages |
| 229 // and have to tell stage exactly where to put its output. | 229 // and have to tell stage exactly where to put its output. |
| 230 SkString outName; | 230 SkString outName; |
| 231 if (output->isValid()) { | 231 if (output->isValid()) { |
| 232 outName = output->c_str(); | 232 outName = output->c_str(); |
| 233 } else { | 233 } else { |
| 234 this->nameVariable(&outName, '\0', baseName); | 234 this->nameVariable(&outName, '\0', baseName); |
| 235 } | 235 } |
| 236 fFS.codeAppendf("vec4 %s;", outName.c_str()); | 236 fFS.codeAppendf("vec4 %s;", outName.c_str()); |
| 237 *output = outName; | 237 *output = outName; |
| 238 } | 238 } |
| 239 | 239 |
| 240 // TODO Processors cannot output zeros because an empty string is all 1s | 240 // TODO Processors cannot output zeros because an empty string is all 1s |
| 241 // the fix is to allow effects to take the GrGLSLExpr4 directly | 241 // the fix is to allow effects to take the GrGLSLExpr4 directly |
| 242 void GrGLProgramBuilder::emitAndInstallProc(const GrPendingFragmentStage& proc, | 242 void GrGLProgramBuilder::emitAndInstallProc(const GrFragmentProcessor& fp, |
| 243 int index, | 243 int index, |
| 244 const GrGLSLExpr4& input, | 244 const GrGLSLExpr4& input, |
| 245 GrGLSLExpr4* output) { | 245 GrGLSLExpr4* output) { |
| 246 // Program builders have a bit of state we need to clear with each effect | 246 // Program builders have a bit of state we need to clear with each effect |
| 247 AutoStageAdvance adv(this); | 247 AutoStageAdvance adv(this); |
| 248 this->nameExpression(output, "output"); | 248 this->nameExpression(output, "output"); |
| 249 | 249 |
| 250 // Enclose custom code in a block to avoid namespace conflicts | 250 // Enclose custom code in a block to avoid namespace conflicts |
| 251 SkString openBrace; | 251 SkString openBrace; |
| 252 openBrace.printf("{ // Stage %d, %s\n", fStageIndex, proc.name()); | 252 openBrace.printf("{ // Stage %d, %s\n", fStageIndex, fp.name()); |
| 253 fFS.codeAppend(openBrace.c_str()); | 253 fFS.codeAppend(openBrace.c_str()); |
| 254 | 254 |
| 255 this->emitAndInstallProc(proc, index, output->c_str(), input.isOnes() ? NULL
: input.c_str()); | 255 this->emitAndInstallProc(fp, index, output->c_str(), input.isOnes() ? NULL :
input.c_str()); |
| 256 | 256 |
| 257 fFS.codeAppend("}"); | 257 fFS.codeAppend("}"); |
| 258 } | 258 } |
| 259 | 259 |
| 260 void GrGLProgramBuilder::emitAndInstallProc(const GrPrimitiveProcessor& proc, | 260 void GrGLProgramBuilder::emitAndInstallProc(const GrPrimitiveProcessor& proc, |
| 261 GrGLSLExpr4* outputColor, | 261 GrGLSLExpr4* outputColor, |
| 262 GrGLSLExpr4* outputCoverage) { | 262 GrGLSLExpr4* outputCoverage) { |
| 263 // Program builders have a bit of state we need to clear with each effect | 263 // Program builders have a bit of state we need to clear with each effect |
| 264 AutoStageAdvance adv(this); | 264 AutoStageAdvance adv(this); |
| 265 this->nameExpression(outputColor, "outputColor"); | 265 this->nameExpression(outputColor, "outputColor"); |
| 266 this->nameExpression(outputCoverage, "outputCoverage"); | 266 this->nameExpression(outputCoverage, "outputCoverage"); |
| 267 | 267 |
| 268 // Enclose custom code in a block to avoid namespace conflicts | 268 // Enclose custom code in a block to avoid namespace conflicts |
| 269 SkString openBrace; | 269 SkString openBrace; |
| 270 openBrace.printf("{ // Stage %d, %s\n", fStageIndex, proc.name()); | 270 openBrace.printf("{ // Stage %d, %s\n", fStageIndex, proc.name()); |
| 271 fFS.codeAppend(openBrace.c_str()); | 271 fFS.codeAppend(openBrace.c_str()); |
| 272 fVS.codeAppendf("// Primitive Processor %s\n", proc.name()); | 272 fVS.codeAppendf("// Primitive Processor %s\n", proc.name()); |
| 273 | 273 |
| 274 this->emitAndInstallProc(proc, outputColor->c_str(), outputCoverage->c_str()
); | 274 this->emitAndInstallProc(proc, outputColor->c_str(), outputCoverage->c_str()
); |
| 275 | 275 |
| 276 fFS.codeAppend("}"); | 276 fFS.codeAppend("}"); |
| 277 } | 277 } |
| 278 | 278 |
| 279 void GrGLProgramBuilder::emitAndInstallProc(const GrPendingFragmentStage& fs, | 279 void GrGLProgramBuilder::emitAndInstallProc(const GrFragmentProcessor& fp, |
| 280 int index, | 280 int index, |
| 281 const char* outColor, | 281 const char* outColor, |
| 282 const char* inColor) { | 282 const char* inColor) { |
| 283 GrGLInstalledFragProc* ifp = new GrGLInstalledFragProc; | 283 GrGLInstalledFragProc* ifp = new GrGLInstalledFragProc; |
| 284 | 284 |
| 285 const GrFragmentProcessor& fp = *fs.processor(); | |
| 286 ifp->fGLProc.reset(fp.createGLInstance()); | 285 ifp->fGLProc.reset(fp.createGLInstance()); |
| 287 | 286 |
| 288 SkSTArray<4, GrGLProcessor::TextureSampler> samplers(fp.numTextures()); | 287 SkSTArray<4, GrGLProcessor::TextureSampler> samplers(fp.numTextures()); |
| 289 this->emitSamplers(fp, &samplers, ifp); | 288 this->emitSamplers(fp, &samplers, ifp); |
| 290 | 289 |
| 291 GrGLFragmentProcessor::EmitArgs args(this, fp, outColor, inColor, fOutCoords
[index], samplers); | 290 GrGLFragmentProcessor::EmitArgs args(this, fp, outColor, inColor, fOutCoords
[index], samplers); |
| 292 ifp->fGLProc->emitCode(args); | 291 ifp->fGLProc->emitCode(args); |
| 293 | 292 |
| 294 // We have to check that effects and the code they emit are consistent, ie i
f an effect | 293 // We have to check that effects and the code they emit are consistent, ie i
f an effect |
| 295 // asks for dst color, then the emit code needs to follow suit | 294 // asks for dst color, then the emit code needs to follow suit |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) { | 493 GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) { |
| 495 return new GrGLProgram(fGpu, this->desc(), fUniformHandles, programID, fUnif
orms, | 494 return new GrGLProgram(fGpu, this->desc(), fUniformHandles, programID, fUnif
orms, |
| 496 fGeometryProcessor, fXferProcessor, fFragmentProcesso
rs.get(), | 495 fGeometryProcessor, fXferProcessor, fFragmentProcesso
rs.get(), |
| 497 &fSamplerUniforms); | 496 &fSamplerUniforms); |
| 498 } | 497 } |
| 499 | 498 |
| 500 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 499 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 501 | 500 |
| 502 GrGLInstalledFragProcs::~GrGLInstalledFragProcs() { | 501 GrGLInstalledFragProcs::~GrGLInstalledFragProcs() { |
| 503 int numProcs = fProcs.count(); | 502 int numProcs = fProcs.count(); |
| 504 for (int e = 0; e < numProcs; ++e) { | 503 for (int i = 0; i < numProcs; ++i) { |
| 505 delete fProcs[e]; | 504 delete fProcs[i]; |
| 506 } | 505 } |
| 507 } | 506 } |
| OLD | NEW |