Index: src/gpu/GrDefaultGeoProcFactory.cpp |
diff --git a/src/gpu/GrDefaultGeoProcFactory.cpp b/src/gpu/GrDefaultGeoProcFactory.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..8e93f379b6dda98f3259547e0f132ce596bce0a5 |
--- /dev/null |
+++ b/src/gpu/GrDefaultGeoProcFactory.cpp |
@@ -0,0 +1,182 @@ |
+/* |
+ * 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 "GrDefaultGeoProcFactory.h" |
+ |
+#include "gl/builders/GrGLProgramBuilder.h" |
+#include "gl/GrGLGeometryProcessor.h" |
+#include "GrDrawState.h" |
+#include "GrTBackendProcessorFactory.h" |
+ |
+/* |
+ * The default Geometry Processor simply takes position and multiplies it by the uniform view |
+ * matrix. It also leaves coverage untouched. Behind the scenes, we may add per vertex color or |
+ * local coords. |
+ */ |
+class DefaultGeoProc : public GrGeometryProcessor { |
+public: |
+ static GrGeometryProcessor* Create() { |
+ GR_CREATE_STATIC_PROCESSOR(gDefaultGeoProc, DefaultGeoProc, ()); |
+ return SkRef(gDefaultGeoProc); |
+ } |
+ |
+ static const char* Name() { return "DefaultGeometryProcessor"; } |
+ |
+ virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE { |
+ return GrTBackendGeometryProcessorFactory<DefaultGeoProc>::getInstance(); |
+ } |
+ |
+ class GLProcessor : public GrGLGeometryProcessor { |
+ public: |
+ GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&) |
+ : INHERITED (factory) {} |
+ |
+ virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { |
+ GrGLVertexBuilder* vs = args.fPB->getVertexShaderBuilder(); |
+ |
+ // setup position varying |
+ vs->codeAppendf("%s = %s * vec3(%s, 1);", vs->glPosition(), vs->uViewM(), |
+ vs->inPosition()); |
+ |
+ // output coverage in FS(pass through) |
+ GrGLGPFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder(); |
+ fs->codeAppendf("%s = %s;", args.fOutput, GrGLSLExpr4(args.fInput).c_str()); |
+ } |
+ |
+ static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {} |
+ |
+ virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {} |
+ |
+ private: |
+ typedef GrGLGeometryProcessor INHERITED; |
+ }; |
+ |
+private: |
+ DefaultGeoProc() {} |
+ |
+ virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE { |
+ return true; |
+ } |
+ |
+ virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE { |
+ inout->mulByUnknownAlpha(); |
+ } |
+ |
+ GR_DECLARE_GEOMETRY_PROCESSOR_TEST; |
+ |
+ typedef GrFragmentProcessor INHERITED; |
+}; |
+ |
+GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DefaultGeoProc); |
+ |
+GrGeometryProcessor* DefaultGeoProc::TestCreate(SkRandom* random, |
+ GrContext*, |
+ const GrDrawTargetCaps& caps, |
+ GrTexture*[]) { |
+ return DefaultGeoProc::Create(); |
+} |
+ |
+// We use these arrays to customize our default GP. We only need 4 because we omit coverage if |
+// coverage is not requested in the flags to the create function. |
+GrVertexAttrib kDefaultPositionGeoProc[] = { |
+ { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding }, |
+ { kVec4ub_GrVertexAttribType, sizeof(SkPoint), kCoverage_GrVertexAttribBinding }, |
+}; |
+ |
+GrVertexAttrib kDefaultPosColorGeoProc[] = { |
+ { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding }, |
+ { kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVertexAttribBinding }, |
+ { kVec4ub_GrVertexAttribType, sizeof(SkPoint) + sizeof(GrColor), kCoverage_GrVertexAttribBinding }, |
+}; |
+ |
+GrVertexAttrib kDefaultPosUVGeoProc[] = { |
+ { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding }, |
+ { kVec2f_GrVertexAttribType, sizeof(SkPoint), kLocalCoord_GrVertexAttribBinding }, |
+ { kVec4ub_GrVertexAttribType, 2 * sizeof(SkPoint), kCoverage_GrVertexAttribBinding }, |
+}; |
+ |
+GrVertexAttrib kDefaultPosColUVGeoProc[] = { |
+ { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding }, |
+ { kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVertexAttribBinding }, |
+ { kVec2f_GrVertexAttribType, sizeof(SkPoint) + sizeof(GrColor), kLocalCoord_GrVertexAttribBinding }, |
+ { kVec4ub_GrVertexAttribType, 2 * sizeof(SkPoint) + sizeof(GrColor), kCoverage_GrVertexAttribBinding }, |
+}; |
+ |
+static size_t get_size(GrDefaultGeoProcFactory::GPType flag) { |
+ switch (flag) { |
+ case GrDefaultGeoProcFactory::kPosition_GPType: |
+ return GrVertexAttribTypeSize(kVec2f_GrVertexAttribType); |
+ case GrDefaultGeoProcFactory::kColor_GPType: |
+ return GrVertexAttribTypeSize(kVec4ub_GrVertexAttribType); |
+ case GrDefaultGeoProcFactory::kLocalCoord_GPType: |
+ return GrVertexAttribTypeSize(kVec2f_GrVertexAttribType); |
+ case GrDefaultGeoProcFactory::kCoverage_GPType: |
+ return GrVertexAttribTypeSize(kVec4ub_GrVertexAttribType); |
+ default: |
+ SkFAIL("Should never get here"); |
+ return 0; |
+ } |
+} |
+ |
+const GrGeometryProcessor* |
+GrDefaultGeoProcFactory::CreateAndSetAttribs(GrDrawState* ds, uint32_t gpTypeFlags) { |
+ SkASSERT(ds); |
+ // always atleast position in the GP |
+ size_t size = get_size(kPosition_GPType); |
+ int count = 1; |
+ |
+ bool hasColor = SkToBool(gpTypeFlags & kColor_GPType); |
+ bool hasLocalCoord = SkToBool(gpTypeFlags & kLocalCoord_GPType); |
+ bool hasCoverage = SkToBool(gpTypeFlags & kCoverage_GPType); |
+ |
+ if (hasColor) { |
+ size += get_size(kColor_GPType); |
+ count++; |
+ if (hasLocalCoord) { |
+ size += get_size(kLocalCoord_GPType); |
+ count++; |
+ if (hasCoverage) { |
+ size += get_size(kCoverage_GPType); |
+ count++; |
+ ds->setVertexAttribs<kDefaultPosColUVGeoProc>(count, size); |
+ } else { |
+ ds->setVertexAttribs<kDefaultPosColUVGeoProc>(count, size); |
+ |
+ } |
+ } else { |
+ if (hasCoverage) { |
+ size += get_size(kCoverage_GPType); |
+ count++; |
+ ds->setVertexAttribs<kDefaultPosColorGeoProc>(count, size); |
+ } else { |
+ ds->setVertexAttribs<kDefaultPosColorGeoProc>(count, size); |
+ } |
+ } |
+ } else if (hasLocalCoord) { |
+ size += get_size(kLocalCoord_GPType); |
+ count++; |
+ if (hasCoverage) { |
+ size += get_size(kCoverage_GPType); |
+ count++; |
+ ds->setVertexAttribs<kDefaultPosUVGeoProc>(count, size); |
+ } else { |
+ ds->setVertexAttribs<kDefaultPosUVGeoProc>(count, size); |
+ } |
+ } else if (hasCoverage) { |
+ size += get_size(kCoverage_GPType); |
+ count++; |
+ ds->setVertexAttribs<kDefaultPositionGeoProc>(count, size); |
+ } else { |
+ // Just position |
+ ds->setVertexAttribs<kDefaultPositionGeoProc>(count, size); |
+ } |
+ return DefaultGeoProc::Create(); |
+} |
+ |
+const GrGeometryProcessor* GrDefaultGeoProcFactory::Create() { |
+ return DefaultGeoProc::Create(); |
+} |