GrGLSLFragmentProcessor.cpp 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /*
  2. * Copyright 2015 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. #include "src/gpu/GrFragmentProcessor.h"
  8. #include "src/gpu/GrProcessor.h"
  9. #include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
  10. #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
  11. #include "src/gpu/glsl/GrGLSLUniformHandler.h"
  12. void GrGLSLFragmentProcessor::setData(const GrGLSLProgramDataManager& pdman,
  13. const GrFragmentProcessor& processor) {
  14. this->onSetData(pdman, processor);
  15. }
  16. void GrGLSLFragmentProcessor::emitChild(int childIndex, const char* inputColor, EmitArgs& args) {
  17. this->internalEmitChild(childIndex, inputColor, args.fOutputColor, args);
  18. }
  19. void GrGLSLFragmentProcessor::emitChild(int childIndex, const char* inputColor,
  20. SkString* outputColor, EmitArgs& args) {
  21. SkASSERT(outputColor);
  22. GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
  23. outputColor->append(fragBuilder->getMangleString());
  24. fragBuilder->codeAppendf("half4 %s;", outputColor->c_str());
  25. this->internalEmitChild(childIndex, inputColor, outputColor->c_str(), args);
  26. }
  27. void GrGLSLFragmentProcessor::internalEmitChild(int childIndex, const char* inputColor,
  28. const char* outputColor, EmitArgs& args) {
  29. GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
  30. fragBuilder->onBeforeChildProcEmitCode(); // call first so mangleString is updated
  31. // Prepare a mangled input color variable if the default is not used,
  32. // inputName remains the empty string if no variable is needed.
  33. SkString inputName;
  34. if (inputColor&& strcmp("half4(1.0)", inputColor) != 0 && strcmp("half4(1)", inputColor) != 0) {
  35. // The input name is based off of the current mangle string, and
  36. // since this is called after onBeforeChildProcEmitCode(), it will be
  37. // unique to the child processor (exactly what we want for its input).
  38. inputName.appendf("_childInput%s", fragBuilder->getMangleString().c_str());
  39. fragBuilder->codeAppendf("half4 %s = %s;", inputName.c_str(), inputColor);
  40. }
  41. const GrFragmentProcessor& childProc = args.fFp.childProcessor(childIndex);
  42. // emit the code for the child in its own scope
  43. fragBuilder->codeAppend("{\n");
  44. fragBuilder->codeAppendf("// Child Index %d (mangle: %s): %s\n", childIndex,
  45. fragBuilder->getMangleString().c_str(), childProc.name());
  46. TransformedCoordVars coordVars = args.fTransformedCoords.childInputs(childIndex);
  47. TextureSamplers textureSamplers = args.fTexSamplers.childInputs(childIndex);
  48. // EmitArgs properly updates inputColor to half4(1) if it was null
  49. EmitArgs childArgs(fragBuilder,
  50. args.fUniformHandler,
  51. args.fShaderCaps,
  52. childProc,
  53. outputColor,
  54. inputName.size() > 0 ? inputName.c_str() : nullptr,
  55. coordVars,
  56. textureSamplers);
  57. this->childProcessor(childIndex)->emitCode(childArgs);
  58. fragBuilder->codeAppend("}\n");
  59. fragBuilder->onAfterChildProcEmitCode();
  60. }
  61. //////////////////////////////////////////////////////////////////////////////
  62. GrGLSLFragmentProcessor* GrGLSLFragmentProcessor::Iter::next() {
  63. if (fFPStack.empty()) {
  64. return nullptr;
  65. }
  66. GrGLSLFragmentProcessor* back = fFPStack.back();
  67. fFPStack.pop_back();
  68. for (int i = back->numChildProcessors() - 1; i >= 0; --i) {
  69. fFPStack.push_back(back->childProcessor(i));
  70. }
  71. return back;
  72. }