diff options
author | egdaniel <egdaniel@google.com> | 2015-11-13 09:55:43 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-11-13 09:55:43 -0800 |
commit | e659a581f63fdccb64dce2dc8a478cf56831feea (patch) | |
tree | efef38bff117135e343b7b2b192af10b1f2262e3 /src/gpu/glsl | |
parent | 60795d99fff8caedc2e82bebcfa8bd4fa07231b7 (diff) |
Move GrGLPrimitive/GeometryProc to GLSL
BUG=skia:
Review URL: https://codereview.chromium.org/1441683008
Diffstat (limited to 'src/gpu/glsl')
-rw-r--r-- | src/gpu/glsl/GrGLSLGeometryProcessor.cpp | 157 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLGeometryProcessor.h | 110 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp | 47 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLPrimitiveProcessor.h | 92 |
4 files changed, 406 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); + } + } +} diff --git a/src/gpu/glsl/GrGLSLGeometryProcessor.h b/src/gpu/glsl/GrGLSLGeometryProcessor.h new file mode 100644 index 0000000000..1064eb02c2 --- /dev/null +++ b/src/gpu/glsl/GrGLSLGeometryProcessor.h @@ -0,0 +1,110 @@ +/* + * Copyright 2013 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrGLSLGeometryProcessor_DEFINED +#define GrGLSLGeometryProcessor_DEFINED + +#include "GrGLSLPrimitiveProcessor.h" + +class GrGLSLGPBuilder; + +/** + * If a GL effect needs a GrGLFullShaderBuilder* object to emit vertex code, then it must inherit + * from this class. Since paths don't have vertices, this class is only meant to be used internally + * by skia, for special cases. + */ +class GrGLSLGeometryProcessor : public GrGLSLPrimitiveProcessor { +public: + /* Any general emit code goes in the base class emitCode. Subclasses override onEmitCode */ + void emitCode(EmitArgs&) override; + + // By default we use the identity matrix + void setTransformData(const GrPrimitiveProcessor&, + const GrGLSLProgramDataManager& pdman, + int index, + const SkTArray<const GrCoordTransform*, true>& transforms) override { + this->setTransformDataMatrix(SkMatrix::I(), pdman, index, transforms); + } + + // A helper which subclasses can use if needed + template <class GeometryProcessor> + void setTransformDataHelper(const GrPrimitiveProcessor& primProc, + const GrGLSLProgramDataManager& pdman, + int index, + const SkTArray<const GrCoordTransform*, true>& transforms) { + const GeometryProcessor& gp = primProc.cast<GeometryProcessor>(); + this->setTransformDataMatrix(gp.localMatrix(), pdman, index, transforms); + } + +protected: + // Emit a uniform matrix for each coord transform. + void emitTransforms(GrGLSLGPBuilder* gp, + const GrShaderVar& posVar, + const char* localCoords, + const TransformsIn& tin, + TransformsOut* tout) { + this->emitTransforms(gp, posVar, localCoords, SkMatrix::I(), tin, tout); + } + + // Emit pre-transformed coords as a vertex attribute per coord-transform. + void emitTransforms(GrGLSLGPBuilder*, + const GrShaderVar& posVar, + const char* localCoords, + const SkMatrix& localMatrix, + const TransformsIn&, + TransformsOut*); + + // caller has emitted transforms via attributes + void emitTransforms(GrGLSLGPBuilder*, + const char* localCoords, + const TransformsIn& tin, + TransformsOut* tout); + + struct GrGPArgs { + // The variable used by a GP to store its position. It can be + // either a vec2 or a vec3 depending on the presence of perspective. + GrShaderVar fPositionVar; + }; + + // Create the correct type of position variable given the CTM + void setupPosition(GrGLSLGPBuilder*, GrGPArgs*, const char* posName); + void setupPosition(GrGLSLGPBuilder*, GrGPArgs*, const char* posName, const SkMatrix& mat, + UniformHandle* viewMatrixUniform); + + static uint32_t ComputePosKey(const SkMatrix& mat) { + if (mat.isIdentity()) { + return 0x0; + } else if (!mat.hasPerspective()) { + return 0x01; + } else { + return 0x02; + } + } + +private: + void setTransformDataMatrix(const SkMatrix& localMatrix, + const GrGLSLProgramDataManager& pdman, + int index, + const SkTArray<const GrCoordTransform*, true>& transforms) { + SkSTArray<2, Transform, true>& procTransforms = fInstalledTransforms[index]; + int numTransforms = transforms.count(); + for (int t = 0; t < numTransforms; ++t) { + SkASSERT(procTransforms[t].fHandle.isValid()); + const SkMatrix& transform = GetTransformMatrix(localMatrix, *transforms[t]); + if (!procTransforms[t].fCurrentValue.cheapEqualTo(transform)) { + pdman.setSkMatrix(procTransforms[t].fHandle.toIndex(), transform); + procTransforms[t].fCurrentValue = transform; + } + } + } + + virtual void onEmitCode(EmitArgs&, GrGPArgs*) = 0; + + typedef GrGLSLPrimitiveProcessor INHERITED; +}; + +#endif diff --git a/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp b/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp new file mode 100644 index 0000000000..abb3abcb0d --- /dev/null +++ b/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp @@ -0,0 +1,47 @@ +/* + * 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 "GrGLSLPrimitiveProcessor.h" + +#include "glsl/GrGLSLProgramBuilder.h" +#include "glsl/GrGLSLFragmentShaderBuilder.h" + +SkMatrix GrGLSLPrimitiveProcessor::GetTransformMatrix(const SkMatrix& localMatrix, + const GrCoordTransform& coordTransform) { + SkMatrix combined; + // We only apply the localmatrix to localcoords + if (kLocal_GrCoordSet == coordTransform.sourceCoords()) { + combined.setConcat(coordTransform.getMatrix(), localMatrix); + } else { + combined = coordTransform.getMatrix(); + } + if (coordTransform.reverseY()) { + // combined.postScale(1,-1); + // combined.postTranslate(0,1); + combined.set(SkMatrix::kMSkewY, + combined[SkMatrix::kMPersp0] - combined[SkMatrix::kMSkewY]); + combined.set(SkMatrix::kMScaleY, + combined[SkMatrix::kMPersp1] - combined[SkMatrix::kMScaleY]); + combined.set(SkMatrix::kMTransY, + combined[SkMatrix::kMPersp2] - combined[SkMatrix::kMTransY]); + } + return combined; +} + +void GrGLSLPrimitiveProcessor::setupUniformColor(GrGLSLGPBuilder* pb, + const char* outputName, + UniformHandle* colorUniform) { + GrGLSLFragmentBuilder* fs = pb->getFragmentShaderBuilder(); + SkASSERT(colorUniform); + const char* stagedLocalVarName; + *colorUniform = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visibility, + kVec4f_GrSLType, + kDefault_GrSLPrecision, + "Color", + &stagedLocalVarName); + fs->codeAppendf("%s = %s;", outputName, stagedLocalVarName); +} diff --git a/src/gpu/glsl/GrGLSLPrimitiveProcessor.h b/src/gpu/glsl/GrGLSLPrimitiveProcessor.h new file mode 100644 index 0000000000..537aaed8f2 --- /dev/null +++ b/src/gpu/glsl/GrGLSLPrimitiveProcessor.h @@ -0,0 +1,92 @@ +/* + * Copyright 2013 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrGLSLPrimitiveProcessor_DEFINED +#define GrGLSLPrimitiveProcessor_DEFINED + +#include "GrPrimitiveProcessor.h" +#include "glsl/GrGLSLProcessorTypes.h" +#include "glsl/GrGLSLProgramDataManager.h" +#include "glsl/GrGLSLTextureSampler.h" + +class GrBatchTracker; +class GrPrimitiveProcessor; +class GrGLSLGPBuilder; + +class GrGLSLPrimitiveProcessor { +public: + virtual ~GrGLSLPrimitiveProcessor() {} + + typedef GrGLSLProgramDataManager::UniformHandle UniformHandle; + typedef GrGLSLTextureSampler::TextureSamplerArray TextureSamplerArray; + + typedef SkSTArray<2, const GrCoordTransform*, true> ProcCoords; + typedef SkSTArray<8, ProcCoords> TransformsIn; + typedef SkSTArray<8, GrGLSLTransformedCoordsArray> TransformsOut; + + struct EmitArgs { + EmitArgs(GrGLSLGPBuilder* pb, + const GrPrimitiveProcessor& gp, + const char* outputColor, + const char* outputCoverage, + const TextureSamplerArray& samplers, + const TransformsIn& transformsIn, + TransformsOut* transformsOut) + : fPB(pb) + , fGP(gp) + , fOutputColor(outputColor) + , fOutputCoverage(outputCoverage) + , fSamplers(samplers) + , fTransformsIn(transformsIn) + , fTransformsOut(transformsOut) {} + GrGLSLGPBuilder* fPB; + const GrPrimitiveProcessor& fGP; + const char* fOutputColor; + const char* fOutputCoverage; + const TextureSamplerArray& fSamplers; + const TransformsIn& fTransformsIn; + TransformsOut* fTransformsOut; + }; + + /** + * This is similar to emitCode() in the base class, except it takes a full shader builder. + * This allows the effect subclass to emit vertex code. + */ + virtual void emitCode(EmitArgs&) = 0; + + + /** A GrGLSLPrimitiveProcessor instance can be reused with any GrGLSLPrimitiveProcessor that + produces the same stage key; this function reads data from a GrGLSLPrimitiveProcessor and + uploads any uniform variables required by the shaders created in emitCode(). The + GrPrimitiveProcessor parameter is guaranteed to be of the same type that created this + GrGLSLPrimitiveProcessor and to have an identical processor key as the one that created this + GrGLSLPrimitiveProcessor. */ + virtual void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&) = 0; + + static SkMatrix GetTransformMatrix(const SkMatrix& localMatrix, const GrCoordTransform&); + + virtual void setTransformData(const GrPrimitiveProcessor&, + const GrGLSLProgramDataManager& pdman, + int index, + const SkTArray<const GrCoordTransform*, true>& transforms) = 0; + +protected: + void setupUniformColor(GrGLSLGPBuilder* pb, + const char* outputName, + UniformHandle* colorUniform); + + struct Transform { + Transform() : fType(kVoid_GrSLType) { fCurrentValue = SkMatrix::InvalidMatrix(); } + UniformHandle fHandle; + SkMatrix fCurrentValue; + GrSLType fType; + }; + + SkSTArray<8, SkSTArray<2, Transform, true> > fInstalledTransforms; +}; + +#endif |