18072caa80384292858d31ae34b7e19768875866bjoshualitt/*
28072caa80384292858d31ae34b7e19768875866bjoshualitt * Copyright 2014 Google Inc.
38072caa80384292858d31ae34b7e19768875866bjoshualitt *
48072caa80384292858d31ae34b7e19768875866bjoshualitt * Use of this source code is governed by a BSD-style license that can be
58072caa80384292858d31ae34b7e19768875866bjoshualitt * found in the LICENSE file.
68072caa80384292858d31ae34b7e19768875866bjoshualitt */
78072caa80384292858d31ae34b7e19768875866bjoshualitt
88072caa80384292858d31ae34b7e19768875866bjoshualitt#include "GrGLGeometryProcessor.h"
98072caa80384292858d31ae34b7e19768875866bjoshualitt
108072caa80384292858d31ae34b7e19768875866bjoshualitt#include "builders/GrGLProgramBuilder.h"
118072caa80384292858d31ae34b7e19768875866bjoshualitt
128072caa80384292858d31ae34b7e19768875866bjoshualittvoid GrGLGeometryProcessor::emitCode(EmitArgs& args) {
138072caa80384292858d31ae34b7e19768875866bjoshualitt    GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
148072caa80384292858d31ae34b7e19768875866bjoshualitt    GrGPArgs gpArgs;
158072caa80384292858d31ae34b7e19768875866bjoshualitt    this->onEmitCode(args, &gpArgs);
168072caa80384292858d31ae34b7e19768875866bjoshualitt    vsBuilder->transformToNormalizedDeviceSpace(gpArgs.fPositionVar);
178072caa80384292858d31ae34b7e19768875866bjoshualitt}
188072caa80384292858d31ae34b7e19768875866bjoshualitt
198072caa80384292858d31ae34b7e19768875866bjoshualittvoid GrGLGeometryProcessor::emitTransforms(GrGLGPBuilder* pb,
208072caa80384292858d31ae34b7e19768875866bjoshualitt                                           const GrShaderVar& posVar,
218072caa80384292858d31ae34b7e19768875866bjoshualitt                                           const char* localCoords,
228072caa80384292858d31ae34b7e19768875866bjoshualitt                                           const SkMatrix& localMatrix,
238072caa80384292858d31ae34b7e19768875866bjoshualitt                                           const TransformsIn& tin,
248072caa80384292858d31ae34b7e19768875866bjoshualitt                                           TransformsOut* tout) {
258072caa80384292858d31ae34b7e19768875866bjoshualitt    GrGLVertexBuilder* vb = pb->getVertexShaderBuilder();
268072caa80384292858d31ae34b7e19768875866bjoshualitt    tout->push_back_n(tin.count());
278072caa80384292858d31ae34b7e19768875866bjoshualitt    fInstalledTransforms.push_back_n(tin.count());
288072caa80384292858d31ae34b7e19768875866bjoshualitt    for (int i = 0; i < tin.count(); i++) {
298072caa80384292858d31ae34b7e19768875866bjoshualitt        const ProcCoords& coordTransforms = tin[i];
308072caa80384292858d31ae34b7e19768875866bjoshualitt        fInstalledTransforms[i].push_back_n(coordTransforms.count());
318072caa80384292858d31ae34b7e19768875866bjoshualitt        for (int t = 0; t < coordTransforms.count(); t++) {
328072caa80384292858d31ae34b7e19768875866bjoshualitt            SkString strUniName("StageMatrix");
338072caa80384292858d31ae34b7e19768875866bjoshualitt            strUniName.appendf("_%i_%i", i, t);
348072caa80384292858d31ae34b7e19768875866bjoshualitt            GrSLType varyingType;
358072caa80384292858d31ae34b7e19768875866bjoshualitt
368072caa80384292858d31ae34b7e19768875866bjoshualitt            GrCoordSet coordType = coordTransforms[t]->sourceCoords();
378072caa80384292858d31ae34b7e19768875866bjoshualitt            uint32_t type = coordTransforms[t]->getMatrix().getType();
388072caa80384292858d31ae34b7e19768875866bjoshualitt            if (kLocal_GrCoordSet == coordType) {
398072caa80384292858d31ae34b7e19768875866bjoshualitt                type |= localMatrix.getType();
408072caa80384292858d31ae34b7e19768875866bjoshualitt            }
418072caa80384292858d31ae34b7e19768875866bjoshualitt            varyingType = SkToBool(SkMatrix::kPerspective_Mask & type) ? kVec3f_GrSLType :
428072caa80384292858d31ae34b7e19768875866bjoshualitt                                                                         kVec2f_GrSLType;
438072caa80384292858d31ae34b7e19768875866bjoshualitt            GrSLPrecision precision = coordTransforms[t]->precision();
448072caa80384292858d31ae34b7e19768875866bjoshualitt
458072caa80384292858d31ae34b7e19768875866bjoshualitt            const char* uniName;
468072caa80384292858d31ae34b7e19768875866bjoshualitt            fInstalledTransforms[i][t].fHandle =
478072caa80384292858d31ae34b7e19768875866bjoshualitt                    pb->addUniform(GrGLProgramBuilder::kVertex_Visibility,
488072caa80384292858d31ae34b7e19768875866bjoshualitt                                   kMat33f_GrSLType, precision,
498072caa80384292858d31ae34b7e19768875866bjoshualitt                                   strUniName.c_str(),
508072caa80384292858d31ae34b7e19768875866bjoshualitt                                   &uniName).toShaderBuilderIndex();
518072caa80384292858d31ae34b7e19768875866bjoshualitt
528072caa80384292858d31ae34b7e19768875866bjoshualitt            SkString strVaryingName("MatrixCoord");
538072caa80384292858d31ae34b7e19768875866bjoshualitt            strVaryingName.appendf("_%i_%i", i, t);
548072caa80384292858d31ae34b7e19768875866bjoshualitt
558072caa80384292858d31ae34b7e19768875866bjoshualitt            GrGLVertToFrag v(varyingType);
568072caa80384292858d31ae34b7e19768875866bjoshualitt            pb->addVarying(strVaryingName.c_str(), &v, precision);
578072caa80384292858d31ae34b7e19768875866bjoshualitt
588072caa80384292858d31ae34b7e19768875866bjoshualitt            SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
598072caa80384292858d31ae34b7e19768875866bjoshualitt            SkNEW_APPEND_TO_TARRAY(&(*tout)[i], GrGLProcessor::TransformedCoords,
608072caa80384292858d31ae34b7e19768875866bjoshualitt                                   (SkString(v.fsIn()), varyingType));
618072caa80384292858d31ae34b7e19768875866bjoshualitt
628072caa80384292858d31ae34b7e19768875866bjoshualitt            // varying = matrix * coords (logically)
638072caa80384292858d31ae34b7e19768875866bjoshualitt            if (kDevice_GrCoordSet == coordType) {
648072caa80384292858d31ae34b7e19768875866bjoshualitt                if (kVec2f_GrSLType == varyingType) {
658072caa80384292858d31ae34b7e19768875866bjoshualitt                    if (kVec2f_GrSLType == posVar.getType()) {
668072caa80384292858d31ae34b7e19768875866bjoshualitt                        vb->codeAppendf("%s = (%s * vec3(%s, 1)).xy;",
678072caa80384292858d31ae34b7e19768875866bjoshualitt                                        v.vsOut(), uniName, posVar.c_str());
688072caa80384292858d31ae34b7e19768875866bjoshualitt                    } else {
698072caa80384292858d31ae34b7e19768875866bjoshualitt                        // The brackets here are just to scope the temp variable
708072caa80384292858d31ae34b7e19768875866bjoshualitt                        vb->codeAppendf("{ vec3 temp = %s * %s;", uniName, posVar.c_str());
718072caa80384292858d31ae34b7e19768875866bjoshualitt                        vb->codeAppendf("%s = vec2(temp.x/temp.z, temp.y/temp.z); }", v.vsOut());
728072caa80384292858d31ae34b7e19768875866bjoshualitt                    }
738072caa80384292858d31ae34b7e19768875866bjoshualitt                } else {
748072caa80384292858d31ae34b7e19768875866bjoshualitt                    if (kVec2f_GrSLType == posVar.getType()) {
758072caa80384292858d31ae34b7e19768875866bjoshualitt                        vb->codeAppendf("%s = %s * vec3(%s, 1);",
768072caa80384292858d31ae34b7e19768875866bjoshualitt                                        v.vsOut(), uniName, posVar.c_str());
778072caa80384292858d31ae34b7e19768875866bjoshualitt                    } else {
788072caa80384292858d31ae34b7e19768875866bjoshualitt                        vb->codeAppendf("%s = %s * %s;", v.vsOut(), uniName, posVar.c_str());
798072caa80384292858d31ae34b7e19768875866bjoshualitt                    }
808072caa80384292858d31ae34b7e19768875866bjoshualitt                }
818072caa80384292858d31ae34b7e19768875866bjoshualitt            } else {
828072caa80384292858d31ae34b7e19768875866bjoshualitt                if (kVec2f_GrSLType == varyingType) {
838072caa80384292858d31ae34b7e19768875866bjoshualitt                    vb->codeAppendf("%s = (%s * vec3(%s, 1)).xy;", v.vsOut(), uniName, localCoords);
848072caa80384292858d31ae34b7e19768875866bjoshualitt                } else {
858072caa80384292858d31ae34b7e19768875866bjoshualitt                    vb->codeAppendf("%s = %s * vec3(%s, 1);", v.vsOut(), uniName, localCoords);
868072caa80384292858d31ae34b7e19768875866bjoshualitt                }
878072caa80384292858d31ae34b7e19768875866bjoshualitt            }
888072caa80384292858d31ae34b7e19768875866bjoshualitt        }
898072caa80384292858d31ae34b7e19768875866bjoshualitt    }
908072caa80384292858d31ae34b7e19768875866bjoshualitt}
918072caa80384292858d31ae34b7e19768875866bjoshualitt
92dd2198701b0ec9da61ecf73418cad03642d715e7joshualittvoid GrGLGeometryProcessor::setupPosition(GrGLGPBuilder* pb,
938072caa80384292858d31ae34b7e19768875866bjoshualitt                                          GrGPArgs* gpArgs,
948072caa80384292858d31ae34b7e19768875866bjoshualitt                                          const char* posName,
95dd2198701b0ec9da61ecf73418cad03642d715e7joshualitt                                          const SkMatrix& mat) {
96dd2198701b0ec9da61ecf73418cad03642d715e7joshualitt    GrGLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder();
978072caa80384292858d31ae34b7e19768875866bjoshualitt    if (mat.isIdentity()) {
988072caa80384292858d31ae34b7e19768875866bjoshualitt        gpArgs->fPositionVar.set(kVec2f_GrSLType, "pos2");
998072caa80384292858d31ae34b7e19768875866bjoshualitt
1008072caa80384292858d31ae34b7e19768875866bjoshualitt        vsBuilder->codeAppendf("vec2 %s = %s;", gpArgs->fPositionVar.c_str(), posName);
1018072caa80384292858d31ae34b7e19768875866bjoshualitt    } else if (!mat.hasPerspective()) {
102dd2198701b0ec9da61ecf73418cad03642d715e7joshualitt        this->addUniformViewMatrix(pb);
1038072caa80384292858d31ae34b7e19768875866bjoshualitt        gpArgs->fPositionVar.set(kVec2f_GrSLType, "pos2");
1048072caa80384292858d31ae34b7e19768875866bjoshualitt
1058072caa80384292858d31ae34b7e19768875866bjoshualitt        vsBuilder->codeAppendf("vec2 %s = vec2(%s * vec3(%s, 1));",
106dd2198701b0ec9da61ecf73418cad03642d715e7joshualitt                               gpArgs->fPositionVar.c_str(), this->uViewM(), posName);
1078072caa80384292858d31ae34b7e19768875866bjoshualitt    } else {
108dd2198701b0ec9da61ecf73418cad03642d715e7joshualitt        this->addUniformViewMatrix(pb);
1098072caa80384292858d31ae34b7e19768875866bjoshualitt        gpArgs->fPositionVar.set(kVec3f_GrSLType, "pos3");
1108072caa80384292858d31ae34b7e19768875866bjoshualitt
1118072caa80384292858d31ae34b7e19768875866bjoshualitt        vsBuilder->codeAppendf("vec3 %s = %s * vec3(%s, 1);",
112dd2198701b0ec9da61ecf73418cad03642d715e7joshualitt                               gpArgs->fPositionVar.c_str(), this->uViewM(), posName);
1138072caa80384292858d31ae34b7e19768875866bjoshualitt    }
1148072caa80384292858d31ae34b7e19768875866bjoshualitt}
115