diff options
Diffstat (limited to 'src/gpu/glsl/GrGLSLGeometryProcessor.cpp')
-rw-r--r-- | src/gpu/glsl/GrGLSLGeometryProcessor.cpp | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp new file mode 100644 index 0000000000..c9f8c71383 --- /dev/null +++ b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp @@ -0,0 +1,157 @@ +/* + * 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 "GrGLSLGeometryProcessor.h" + +#include "glsl/GrGLSLFragmentShaderBuilder.h" +#include "glsl/GrGLSLProcessorTypes.h" +#include "glsl/GrGLSLProgramBuilder.h" +#include "glsl/GrGLSLVertexShaderBuilder.h" + +void GrGLSLGeometryProcessor::emitCode(EmitArgs& args) { + GrGLSLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); + GrGPArgs gpArgs; + this->onEmitCode(args, &gpArgs); + vsBuilder->transformToNormalizedDeviceSpace(gpArgs.fPositionVar); +} + +void GrGLSLGeometryProcessor::emitTransforms(GrGLSLGPBuilder* pb, + const GrShaderVar& posVar, + const char* localCoords, + const SkMatrix& localMatrix, + const TransformsIn& tin, + TransformsOut* tout) { + GrGLSLVertexBuilder* vb = pb->getVertexShaderBuilder(); + tout->push_back_n(tin.count()); + fInstalledTransforms.push_back_n(tin.count()); + for (int i = 0; i < tin.count(); i++) { + const ProcCoords& coordTransforms = tin[i]; + fInstalledTransforms[i].push_back_n(coordTransforms.count()); + for (int t = 0; t < coordTransforms.count(); t++) { + SkString strUniName("StageMatrix"); + strUniName.appendf("_%i_%i", i, t); + GrSLType varyingType; + + GrCoordSet coordType = coordTransforms[t]->sourceCoords(); + uint32_t type = coordTransforms[t]->getMatrix().getType(); + if (kLocal_GrCoordSet == coordType) { + type |= localMatrix.getType(); + } + varyingType = SkToBool(SkMatrix::kPerspective_Mask & type) ? kVec3f_GrSLType : + kVec2f_GrSLType; + GrSLPrecision precision = coordTransforms[t]->precision(); + + const char* uniName; + fInstalledTransforms[i][t].fHandle = + pb->addUniform(GrGLSLProgramBuilder::kVertex_Visibility, + kMat33f_GrSLType, precision, + strUniName.c_str(), + &uniName).toIndex(); + + SkString strVaryingName("MatrixCoord"); + strVaryingName.appendf("_%i_%i", i, t); + + GrGLSLVertToFrag v(varyingType); + pb->addVarying(strVaryingName.c_str(), &v, precision); + + SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType); + SkNEW_APPEND_TO_TARRAY(&(*tout)[i], GrGLSLTransformedCoords, + (SkString(v.fsIn()), varyingType)); + + // varying = matrix * coords (logically) + if (kDevice_GrCoordSet == coordType) { + if (kVec2f_GrSLType == varyingType) { + if (kVec2f_GrSLType == posVar.getType()) { + vb->codeAppendf("%s = (%s * vec3(%s, 1)).xy;", + v.vsOut(), uniName, posVar.c_str()); + } else { + // The brackets here are just to scope the temp variable + vb->codeAppendf("{ vec3 temp = %s * %s;", uniName, posVar.c_str()); + vb->codeAppendf("%s = vec2(temp.x/temp.z, temp.y/temp.z); }", v.vsOut()); + } + } else { + if (kVec2f_GrSLType == posVar.getType()) { + vb->codeAppendf("%s = %s * vec3(%s, 1);", + v.vsOut(), uniName, posVar.c_str()); + } else { + vb->codeAppendf("%s = %s * %s;", v.vsOut(), uniName, posVar.c_str()); + } + } + } else { + if (kVec2f_GrSLType == varyingType) { + vb->codeAppendf("%s = (%s * vec3(%s, 1)).xy;", v.vsOut(), uniName, localCoords); + } else { + vb->codeAppendf("%s = %s * vec3(%s, 1);", v.vsOut(), uniName, localCoords); + } + } + } + } +} + +void GrGLSLGeometryProcessor::emitTransforms(GrGLSLGPBuilder* pb, + const char* localCoords, + const TransformsIn& tin, + TransformsOut* tout) { + GrGLSLVertexBuilder* vb = pb->getVertexShaderBuilder(); + tout->push_back_n(tin.count()); + for (int i = 0; i < tin.count(); i++) { + const ProcCoords& coordTransforms = tin[i]; + for (int t = 0; t < coordTransforms.count(); t++) { + GrSLType varyingType = kVec2f_GrSLType; + + // Device coords aren't supported + SkASSERT(kDevice_GrCoordSet != coordTransforms[t]->sourceCoords()); + GrSLPrecision precision = coordTransforms[t]->precision(); + + SkString strVaryingName("MatrixCoord"); + strVaryingName.appendf("_%i_%i", i, t); + + GrGLSLVertToFrag v(varyingType); + pb->addVarying(strVaryingName.c_str(), &v, precision); + vb->codeAppendf("%s = %s;", v.vsOut(), localCoords); + + SkNEW_APPEND_TO_TARRAY(&(*tout)[i], + GrGLSLTransformedCoords, + (SkString(v.fsIn()), varyingType)); + } + } +} + +void GrGLSLGeometryProcessor::setupPosition(GrGLSLGPBuilder* pb, + GrGPArgs* gpArgs, + const char* posName) { + GrGLSLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); + gpArgs->fPositionVar.set(kVec2f_GrSLType, "pos2"); + vsBuilder->codeAppendf("vec2 %s = %s;", gpArgs->fPositionVar.c_str(), posName); +} + +void GrGLSLGeometryProcessor::setupPosition(GrGLSLGPBuilder* pb, + GrGPArgs* gpArgs, + const char* posName, + const SkMatrix& mat, + UniformHandle* viewMatrixUniform) { + GrGLSLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); + if (mat.isIdentity()) { + gpArgs->fPositionVar.set(kVec2f_GrSLType, "pos2"); + vsBuilder->codeAppendf("vec2 %s = %s;", gpArgs->fPositionVar.c_str(), posName); + } else { + const char* viewMatrixName; + *viewMatrixUniform = pb->addUniform(GrGLSLProgramBuilder::kVertex_Visibility, + kMat33f_GrSLType, kHigh_GrSLPrecision, + "uViewM", + &viewMatrixName); + if (!mat.hasPerspective()) { + gpArgs->fPositionVar.set(kVec2f_GrSLType, "pos2"); + vsBuilder->codeAppendf("vec2 %s = vec2(%s * vec3(%s, 1));", + gpArgs->fPositionVar.c_str(), viewMatrixName, posName); + } else { + gpArgs->fPositionVar.set(kVec3f_GrSLType, "pos3"); + vsBuilder->codeAppendf("vec3 %s = %s * vec3(%s, 1);", + gpArgs->fPositionVar.c_str(), viewMatrixName, posName); + } + } +} |