aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp
blob: e50037d098518c4eed01b783e2e6ef34d0c5e873 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrGLNvprProgramBuilder.h"
#include "../GrGLGpu.h"

#define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X)
#define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X)

GrGLNvprProgramBuilder::GrGLNvprProgramBuilder(GrGLGpu* gpu,
                                               const GrOptDrawState& optState)
        : INHERITED(gpu, optState)
        , fSeparableVaryingInfos(kVarsPerBlock) {
}

void GrGLNvprProgramBuilder::emitTransforms(const GrPendingFragmentStage& processorStage,
                                            GrGLProcessor::TransformedCoordsArray* outCoords,
                                            GrGLInstalledFragProc* ifp) {
    const GrFragmentProcessor* effect = processorStage.processor();
    int numTransforms = effect->numTransforms();

    ifp->fTransforms.push_back_n(numTransforms);

    for (int t = 0; t < numTransforms; t++) {
        GrSLType varyingType =
                processorStage.isPerspectiveCoordTransform(t) ?
                        kVec3f_GrSLType :
                        kVec2f_GrSLType;

        const char* varyingName = "MatrixCoord";
        SkString suffixedVaryingName;
        if (0 != t) {
            suffixedVaryingName.append(varyingName);
            suffixedVaryingName.appendf("_%i", t);
            varyingName = suffixedVaryingName.c_str();
        }
        GrGLVertToFrag v(varyingType);
        ifp->fTransforms[t].fHandle = this->addSeparableVarying(varyingName, &v);
        ifp->fTransforms[t].fType = varyingType;

        SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords,
                               (SkString(v.fsIn()), varyingType));
    }
}

GrGLInstalledFragProc::ShaderVarHandle
GrGLNvprProgramBuilder::addSeparableVarying(const char* name, GrGLVarying* v) {
    this->addVarying(name, v);
    SeparableVaryingInfo& varying = fSeparableVaryingInfos.push_back();
    varying.fVariable = fFS.fInputs.back();
    return GrGLInstalledFragProc::ShaderVarHandle(fSeparableVaryingInfos.count() - 1);
}

void GrGLNvprProgramBuilder::resolveSeparableVaryings(GrGLuint programId) {
    int count = fSeparableVaryingInfos.count();
    for (int i = 0; i < count; ++i) {
        GrGLint location;
        GL_CALL_RET(location,
                    GetProgramResourceLocation(programId,
                                               GR_GL_FRAGMENT_INPUT,
                                               fSeparableVaryingInfos[i].fVariable.c_str()));
        fSeparableVaryingInfos[i].fLocation = location;
    }
}

GrGLProgram* GrGLNvprProgramBuilder::createProgram(GrGLuint programID) {
    // this is just for nvpr es, which has separable varyings that are plugged in after
    // building
    this->resolveSeparableVaryings(programID);
    return SkNEW_ARGS(GrGLNvprProgram, (fGpu, fDesc, fUniformHandles, programID, fUniforms,
                                        fGeometryProcessor,
                                        fXferProcessor, fFragmentProcessors.get(),
                                        fSeparableVaryingInfos));
}