diff options
Diffstat (limited to 'src/gpu/GrDefaultGeoProcFactory.cpp')
-rw-r--r-- | src/gpu/GrDefaultGeoProcFactory.cpp | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/src/gpu/GrDefaultGeoProcFactory.cpp b/src/gpu/GrDefaultGeoProcFactory.cpp new file mode 100644 index 0000000000..8e93f379b6 --- /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(); +} |