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
8#include "GrGLSLFragmentProcessor.h"
9#include "GrFragmentProcessor.h"
10#include "GrProcessor.h"
11#include "glsl/GrGLSLFragmentShaderBuilder.h"
12#include "glsl/GrGLSLUniformHandler.h"
13
14void GrGLSLFragmentProcessor::setData(const GrGLSLProgramDataManager& pdman,
15                                      const GrFragmentProcessor& processor) {
16    this->onSetData(pdman, processor);
17    SkASSERT(fChildProcessors.count() == processor.numChildProcessors());
18    for (int i = 0; i < fChildProcessors.count(); ++i) {
19        fChildProcessors[i]->setData(pdman, processor.childProcessor(i));
20    }
21}
22
23void GrGLSLFragmentProcessor::emitChild(int childIndex, const char* inputColor, EmitArgs& args) {
24    this->internalEmitChild(childIndex, inputColor, args.fOutputColor, args);
25}
26
27void GrGLSLFragmentProcessor::emitChild(int childIndex, const char* inputColor,
28                                        SkString* outputColor, EmitArgs& args) {
29
30    SkASSERT(outputColor);
31    GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
32    outputColor->append(fragBuilder->getMangleString());
33    fragBuilder->codeAppendf("vec4 %s;", outputColor->c_str());
34    this->internalEmitChild(childIndex, inputColor, outputColor->c_str(), args);
35}
36
37void GrGLSLFragmentProcessor::internalEmitChild(int childIndex, const char* inputColor,
38                                                const char* outputColor, EmitArgs& args) {
39    GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
40
41    fragBuilder->onBeforeChildProcEmitCode();  // call first so mangleString is updated
42
43    const GrFragmentProcessor& childProc = args.fFp.childProcessor(childIndex);
44
45    // emit the code for the child in its own scope
46    fragBuilder->codeAppend("{\n");
47    fragBuilder->codeAppendf("// Child Index %d (mangle: %s): %s\n", childIndex,
48                             fragBuilder->getMangleString().c_str(), childProc.name());
49    TransformedCoordVars coordVars = args.fTransformedCoords.childInputs(childIndex);
50    TextureSamplers textureSamplers = args.fTexSamplers.childInputs(childIndex);
51    BufferSamplers bufferSamplers = args.fBufferSamplers.childInputs(childIndex);
52    ImageStorages imageStorages = args.fImageStorages.childInputs(childIndex);
53    EmitArgs childArgs(fragBuilder,
54                       args.fUniformHandler,
55                       args.fShaderCaps,
56                       childProc,
57                       outputColor,
58                       inputColor,
59                       coordVars,
60                       textureSamplers,
61                       bufferSamplers,
62                       imageStorages,
63                       args.fGpImplementsDistanceVector);
64    this->childProcessor(childIndex)->emitCode(childArgs);
65    fragBuilder->codeAppend("}\n");
66
67    fragBuilder->onAfterChildProcEmitCode();
68}
69
70//////////////////////////////////////////////////////////////////////////////
71
72GrGLSLFragmentProcessor* GrGLSLFragmentProcessor::Iter::next() {
73    if (fFPStack.empty()) {
74        return nullptr;
75    }
76    GrGLSLFragmentProcessor* back = fFPStack.back();
77    fFPStack.pop_back();
78    for (int i = back->numChildProcessors() - 1; i >= 0; --i) {
79        fFPStack.push_back(back->childProcessor(i));
80    }
81    return back;
82}
83