diff options
author | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-09-30 19:55:49 +0000 |
---|---|---|
committer | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-09-30 19:55:49 +0000 |
commit | 234d4fba75aac009e34c088037fcd9e244798c40 (patch) | |
tree | b2a103963d3e85c3aed67947bf10827b48744483 | |
parent | 3400f4b00aaf9159713d9a7bb0a4f828fd6899c3 (diff) |
Mark when effects and programs have vertex code
Adds a 'hasVertexCode' method to GrEffect and a 'fHasVertexCode' field
to GrGLProgramDesc::KeyHeader. Also adds a GrVertexEffect class that
effects have to inherit from in order to set the 'hasVertexCode' flag
and be able to emit vertex code, and updates the existing effects to
use it as needed.
R=bsalomon@google.com
Author: cdalton@nvidia.com
Review URL: https://codereview.chromium.org/23653059
git-svn-id: http://skia.googlecode.com/svn/trunk@11537 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | include/gpu/GrEffect.h | 33 | ||||
-rw-r--r-- | src/gpu/GrAAConvexPathRenderer.cpp | 6 | ||||
-rw-r--r-- | src/gpu/GrAARectRenderer.cpp | 13 | ||||
-rw-r--r-- | src/gpu/GrEffect.cpp | 5 | ||||
-rw-r--r-- | src/gpu/GrOvalRenderer.cpp | 20 | ||||
-rw-r--r-- | src/gpu/effects/GrBezierEffect.cpp | 6 | ||||
-rw-r--r-- | src/gpu/effects/GrBezierEffect.h | 15 | ||||
-rw-r--r-- | src/gpu/effects/GrCustomCoordsTextureEffect.h | 5 | ||||
-rw-r--r-- | src/gpu/effects/GrVertexEffect.h | 37 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramDesc.cpp | 16 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramDesc.h | 1 |
11 files changed, 107 insertions, 50 deletions
diff --git a/include/gpu/GrEffect.h b/include/gpu/GrEffect.h index e7590b6793..4dc294bfe8 100644 --- a/include/gpu/GrEffect.h +++ b/include/gpu/GrEffect.h @@ -17,6 +17,7 @@ class GrBackendEffectFactory; class GrContext; class GrEffect; +class GrVertexEffect; class SkString; /** @@ -152,7 +153,14 @@ public: /** Will this effect read the fragment position? */ bool willReadFragmentPosition() const { return fWillReadFragmentPosition; } - int numVertexAttribs() const { return fVertexAttribTypes.count(); } + /** Will this effect emit custom vertex shader code? + (To set this value the effect must inherit from GrVertexEffect.) */ + bool hasVertexCode() const { return fHasVertexCode; } + + int numVertexAttribs() const { + SkASSERT(0 == fVertexAttribTypes.count() || fHasVertexCode); + return fVertexAttribTypes.count(); + } GrSLType vertexAttribType(int index) const { return fVertexAttribTypes[index]; } @@ -204,14 +212,11 @@ protected: */ void addTextureAccess(const GrTextureAccess* textureAccess); - /** - * Subclasses call this from their constructor to register vertex attributes (at most - * kMaxVertexAttribs). This must only be called from the constructor because GrEffects are - * immutable. - */ - void addVertexAttrib(GrSLType type); - - GrEffect() : fWillReadDstColor(false), fWillReadFragmentPosition(false), fEffectRef(NULL) {} + GrEffect() + : fWillReadDstColor(false) + , fWillReadFragmentPosition(false) + , fHasVertexCode(false) + , fEffectRef(NULL) {} /** This should be called by GrEffect subclass factories. See the comment on AutoEffectUnref for an example factory function. */ @@ -300,15 +305,17 @@ private: void EffectRefDestroyed() { fEffectRef = NULL; } - friend class GrEffectRef; // to call EffectRefDestroyed() - friend class GrEffectStage; // to rewrap GrEffect in GrEffectRef when restoring an effect-stage - // from deferred state, to call isEqual on naked GrEffects, and - // to inc/dec deferred ref counts. + friend class GrEffectRef; // to call EffectRefDestroyed() + friend class GrEffectStage; // to rewrap GrEffect in GrEffectRef when restoring an effect-stage + // from deferred state, to call isEqual on naked GrEffects, and + // to inc/dec deferred ref counts. + friend class GrVertexEffect; // to set fHasVertexCode and build fVertexAttribTypes. SkSTArray<4, const GrTextureAccess*, true> fTextureAccesses; SkSTArray<kMaxVertexAttribs, GrSLType, true> fVertexAttribTypes; bool fWillReadDstColor; bool fWillReadFragmentPosition; + bool fHasVertexCode; GrEffectRef* fEffectRef; typedef SkRefCnt INHERITED; diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp index 6749b46539..7063440ba4 100644 --- a/src/gpu/GrAAConvexPathRenderer.cpp +++ b/src/gpu/GrAAConvexPathRenderer.cpp @@ -21,6 +21,8 @@ #include "gl/GrGLEffect.h" #include "gl/GrGLSL.h" +#include "effects/GrVertexEffect.h" + GrAAConvexPathRenderer::GrAAConvexPathRenderer() { } @@ -497,7 +499,7 @@ static void create_vertices(const SegmentArray& segments, * Requires shader derivative instruction support. */ -class QuadEdgeEffect : public GrEffect { +class QuadEdgeEffect : public GrVertexEffect { public: static GrEffectRef* Create() { @@ -586,7 +588,7 @@ private: GR_DECLARE_EFFECT_TEST; - typedef GrEffect INHERITED; + typedef GrVertexEffect INHERITED; }; GR_DEFINE_EFFECT_TEST(QuadEdgeEffect); diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp index 4856bb5418..e4bf853e36 100644 --- a/src/gpu/GrAARectRenderer.cpp +++ b/src/gpu/GrAARectRenderer.cpp @@ -10,6 +10,7 @@ #include "gl/GrGLEffect.h" #include "GrTBackendEffectFactory.h" #include "SkColorPriv.h" +#include "effects/GrVertexEffect.h" SK_DEFINE_INST_COUNT(GrAARectRenderer) @@ -17,7 +18,7 @@ SK_DEFINE_INST_COUNT(GrAARectRenderer) class GrGLAlignedRectEffect; // Axis Aligned special case -class GrAlignedRectEffect : public GrEffect { +class GrAlignedRectEffect : public GrVertexEffect { public: static GrEffectRef* Create() { GR_CREATE_STATIC_EFFECT(gAlignedRectEffect, GrAlignedRectEffect, ()); @@ -101,7 +102,7 @@ public: private: - GrAlignedRectEffect() : GrEffect() { + GrAlignedRectEffect() : GrVertexEffect() { this->addVertexAttrib(kVec4f_GrSLType); } @@ -109,7 +110,7 @@ private: GR_DECLARE_EFFECT_TEST; - typedef GrEffect INHERITED; + typedef GrVertexEffect INHERITED; }; @@ -137,7 +138,7 @@ class GrGLRectEffect; * The munged width and height are stored in a vec2 varying ("WidthHeight") * with the width in x and the height in y. */ -class GrRectEffect : public GrEffect { +class GrRectEffect : public GrVertexEffect { public: static GrEffectRef* Create() { GR_CREATE_STATIC_EFFECT(gRectEffect, GrRectEffect, ()); @@ -236,7 +237,7 @@ public: private: - GrRectEffect() : GrEffect() { + GrRectEffect() : GrVertexEffect() { this->addVertexAttrib(kVec4f_GrSLType); this->addVertexAttrib(kVec2f_GrSLType); this->setWillReadFragmentPosition(); @@ -246,7 +247,7 @@ private: GR_DECLARE_EFFECT_TEST; - typedef GrEffect INHERITED; + typedef GrVertexEffect INHERITED; }; diff --git a/src/gpu/GrEffect.cpp b/src/gpu/GrEffect.cpp index dc83f7b7cb..53dabb619c 100644 --- a/src/gpu/GrEffect.cpp +++ b/src/gpu/GrEffect.cpp @@ -90,11 +90,6 @@ void GrEffect::addTextureAccess(const GrTextureAccess* access) { fTextureAccesses.push_back(access); } -void GrEffect::addVertexAttrib(GrSLType type) { - SkASSERT(fVertexAttribTypes.count() < kMaxVertexAttribs); - fVertexAttribTypes.push_back(type); -} - void* GrEffect::operator new(size_t size) { return GrEffect_Globals::GetTLS()->allocate(size); } diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp index 013c7ab7e8..66ca05351a 100644 --- a/src/gpu/GrOvalRenderer.cpp +++ b/src/gpu/GrOvalRenderer.cpp @@ -19,6 +19,8 @@ #include "SkRRect.h" #include "SkStrokeRec.h" +#include "effects/GrVertexEffect.h" + SK_DEFINE_INST_COUNT(GrOvalRenderer) namespace { @@ -56,7 +58,7 @@ inline bool circle_stays_circle(const SkMatrix& m) { * specified as offset_x, offset_y (both from center point), outer radius and inner radius. */ -class CircleEdgeEffect : public GrEffect { +class CircleEdgeEffect : public GrVertexEffect { public: static GrEffectRef* Create(bool stroke) { GR_CREATE_STATIC_EFFECT(gCircleStrokeEdge, CircleEdgeEffect, (true)); @@ -134,7 +136,7 @@ public: private: - CircleEdgeEffect(bool stroke) : GrEffect() { + CircleEdgeEffect(bool stroke) : GrVertexEffect() { this->addVertexAttrib(kVec4f_GrSLType); fStroke = stroke; } @@ -148,7 +150,7 @@ private: GR_DECLARE_EFFECT_TEST; - typedef GrEffect INHERITED; + typedef GrVertexEffect INHERITED; }; GR_DEFINE_EFFECT_TEST(CircleEdgeEffect); @@ -170,7 +172,7 @@ GrEffectRef* CircleEdgeEffect::TestCreate(SkRandom* random, * We are using an implicit function of x^2/a^2 + y^2/b^2 - 1 = 0. */ -class EllipseEdgeEffect : public GrEffect { +class EllipseEdgeEffect : public GrVertexEffect { public: static GrEffectRef* Create(bool stroke) { GR_CREATE_STATIC_EFFECT(gEllipseStrokeEdge, EllipseEdgeEffect, (true)); @@ -269,7 +271,7 @@ public: }; private: - EllipseEdgeEffect(bool stroke) : GrEffect() { + EllipseEdgeEffect(bool stroke) : GrVertexEffect() { this->addVertexAttrib(kVec2f_GrSLType); this->addVertexAttrib(kVec4f_GrSLType); fStroke = stroke; @@ -284,7 +286,7 @@ private: GR_DECLARE_EFFECT_TEST; - typedef GrEffect INHERITED; + typedef GrVertexEffect INHERITED; }; GR_DEFINE_EFFECT_TEST(EllipseEdgeEffect); @@ -307,7 +309,7 @@ GrEffectRef* EllipseEdgeEffect::TestCreate(SkRandom* random, * The result is device-independent and can be used with any affine matrix. */ -class DIEllipseEdgeEffect : public GrEffect { +class DIEllipseEdgeEffect : public GrVertexEffect { public: enum Mode { kStroke = 0, kHairline, kFill }; @@ -430,7 +432,7 @@ public: }; private: - DIEllipseEdgeEffect(Mode mode) : GrEffect() { + DIEllipseEdgeEffect(Mode mode) : GrVertexEffect() { this->addVertexAttrib(kVec2f_GrSLType); this->addVertexAttrib(kVec2f_GrSLType); fMode = mode; @@ -445,7 +447,7 @@ private: GR_DECLARE_EFFECT_TEST; - typedef GrEffect INHERITED; + typedef GrVertexEffect INHERITED; }; GR_DEFINE_EFFECT_TEST(DIEllipseEdgeEffect); diff --git a/src/gpu/effects/GrBezierEffect.cpp b/src/gpu/effects/GrBezierEffect.cpp index c7eadb783a..b3e9f62f69 100644 --- a/src/gpu/effects/GrBezierEffect.cpp +++ b/src/gpu/effects/GrBezierEffect.cpp @@ -128,7 +128,7 @@ const GrBackendEffectFactory& GrConicEffect::getFactory() const { return GrTBackendEffectFactory<GrConicEffect>::getInstance(); } -GrConicEffect::GrConicEffect(GrBezierEdgeType edgeType) : GrEffect() { +GrConicEffect::GrConicEffect(GrBezierEdgeType edgeType) : GrVertexEffect() { this->addVertexAttrib(kVec4f_GrSLType); fEdgeType = edgeType; } @@ -260,7 +260,7 @@ const GrBackendEffectFactory& GrQuadEffect::getFactory() const { return GrTBackendEffectFactory<GrQuadEffect>::getInstance(); } -GrQuadEffect::GrQuadEffect(GrBezierEdgeType edgeType) : GrEffect() { +GrQuadEffect::GrQuadEffect(GrBezierEdgeType edgeType) : GrVertexEffect() { this->addVertexAttrib(kVec4f_GrSLType); fEdgeType = edgeType; } @@ -403,7 +403,7 @@ const GrBackendEffectFactory& GrCubicEffect::getFactory() const { return GrTBackendEffectFactory<GrCubicEffect>::getInstance(); } -GrCubicEffect::GrCubicEffect(GrBezierEdgeType edgeType) : GrEffect() { +GrCubicEffect::GrCubicEffect(GrBezierEdgeType edgeType) : GrVertexEffect() { this->addVertexAttrib(kVec4f_GrSLType); fEdgeType = edgeType; } diff --git a/src/gpu/effects/GrBezierEffect.h b/src/gpu/effects/GrBezierEffect.h index d31cd7e4c8..5de7b80b75 100644 --- a/src/gpu/effects/GrBezierEffect.h +++ b/src/gpu/effects/GrBezierEffect.h @@ -8,8 +8,9 @@ #ifndef GrBezierEffect_DEFINED #define GrBezierEffect_DEFINED -#include "GrEffect.h" #include "GrDrawTargetCaps.h" +#include "GrEffect.h" +#include "GrVertexEffect.h" enum GrBezierEdgeType { kFillAA_GrBezierEdgeType, @@ -67,7 +68,7 @@ static inline bool GrBezierEdgeTypeIsAA(const GrBezierEdgeType edgeType) { */ class GrGLConicEffect; -class GrConicEffect : public GrEffect { +class GrConicEffect : public GrVertexEffect { public: static GrEffectRef* Create(const GrBezierEdgeType edgeType, const GrDrawTargetCaps& caps) { GR_CREATE_STATIC_EFFECT(gConicFillAA, GrConicEffect, (kFillAA_GrBezierEdgeType)); @@ -117,7 +118,7 @@ private: GR_DECLARE_EFFECT_TEST; - typedef GrEffect INHERITED; + typedef GrVertexEffect INHERITED; }; /////////////////////////////////////////////////////////////////////////////// @@ -131,7 +132,7 @@ private: */ class GrGLQuadEffect; -class GrQuadEffect : public GrEffect { +class GrQuadEffect : public GrVertexEffect { public: static GrEffectRef* Create(const GrBezierEdgeType edgeType, const GrDrawTargetCaps& caps) { GR_CREATE_STATIC_EFFECT(gQuadFillAA, GrQuadEffect, (kFillAA_GrBezierEdgeType)); @@ -181,7 +182,7 @@ private: GR_DECLARE_EFFECT_TEST; - typedef GrEffect INHERITED; + typedef GrVertexEffect INHERITED; }; ////////////////////////////////////////////////////////////////////////////// @@ -197,7 +198,7 @@ private: */ class GrGLCubicEffect; -class GrCubicEffect : public GrEffect { +class GrCubicEffect : public GrVertexEffect { public: static GrEffectRef* Create(const GrBezierEdgeType edgeType, const GrDrawTargetCaps& caps) { GR_CREATE_STATIC_EFFECT(gCubicFillAA, GrCubicEffect, (kFillAA_GrBezierEdgeType)); @@ -247,7 +248,7 @@ private: GR_DECLARE_EFFECT_TEST; - typedef GrEffect INHERITED; + typedef GrVertexEffect INHERITED; }; #endif diff --git a/src/gpu/effects/GrCustomCoordsTextureEffect.h b/src/gpu/effects/GrCustomCoordsTextureEffect.h index fad35c8804..1caecf2f6d 100644 --- a/src/gpu/effects/GrCustomCoordsTextureEffect.h +++ b/src/gpu/effects/GrCustomCoordsTextureEffect.h @@ -9,6 +9,7 @@ #define GrCustomCoordsTextureEffect_DEFINED #include "GrEffect.h" +#include "GrVertexEffect.h" class GrGLCustomCoordsTextureEffect; @@ -17,7 +18,7 @@ class GrGLCustomCoordsTextureEffect; * It allows explicit specification of the filtering and wrap modes (GrTextureParams). The input * coords are a custom attribute. */ -class GrCustomCoordsTextureEffect : public GrEffect { +class GrCustomCoordsTextureEffect : public GrVertexEffect { public: static GrEffectRef* Create(GrTexture* tex, const GrTextureParams& p) { AutoEffectUnref effect(SkNEW_ARGS(GrCustomCoordsTextureEffect, (tex, p))); @@ -43,7 +44,7 @@ private: GR_DECLARE_EFFECT_TEST; - typedef GrEffect INHERITED; + typedef GrVertexEffect INHERITED; }; #endif diff --git a/src/gpu/effects/GrVertexEffect.h b/src/gpu/effects/GrVertexEffect.h new file mode 100644 index 0000000000..387ec7aee9 --- /dev/null +++ b/src/gpu/effects/GrVertexEffect.h @@ -0,0 +1,37 @@ +/* + * 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 GrVertexEffect_DEFINED +#define GrVertexEffect_DEFINED + +#include "GrEffect.h" + +/** + * If an effect needs specialized vertex shader code, then it must inherit from this class. + * Otherwise it won't be able to add vertex attribs, and it might be given a vertexless shader + * program in emitCode. + */ +class GrVertexEffect : public GrEffect { +public: + GrVertexEffect() { fHasVertexCode = true; } + +protected: + /** + * Subclasses call this from their constructor to register vertex attributes (at most + * kMaxVertexAttribs). This must only be called from the constructor because GrEffects are + * immutable. + */ + void addVertexAttrib(GrSLType type) { + SkASSERT(fVertexAttribTypes.count() < kMaxVertexAttribs); + fVertexAttribTypes.push_back(type); + } + +private: + typedef GrEffect INHERITED; +}; + +#endif diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp index 91ac266093..8b731fbc2c 100644 --- a/src/gpu/gl/GrGLProgramDesc.cpp +++ b/src/gpu/gl/GrGLProgramDesc.cpp @@ -19,7 +19,8 @@ inline GrGLEffect::EffectKey get_key_and_update_stats(const GrEffectStage& stage const GrGLCaps& caps, bool useExplicitLocalCoords, bool* setTrueIfReadsDst, - bool* setTrueIfReadsPos) { + bool* setTrueIfReadsPos, + bool* setTrueIfHasVertexCode) { const GrEffectRef& effect = *stage.getEffect(); const GrBackendEffectFactory& factory = effect->getFactory(); GrDrawEffect drawEffect(stage, useExplicitLocalCoords); @@ -29,6 +30,9 @@ inline GrGLEffect::EffectKey get_key_and_update_stats(const GrEffectStage& stage if (effect->willReadFragmentPosition()) { *setTrueIfReadsPos = true; } + if (effect->hasVertexCode()) { + *setTrueIfHasVertexCode = true; + } return factory.glEffectKey(drawEffect, caps); } } @@ -87,21 +91,25 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState, int currEffectKey = 0; bool readsDst = false; bool readFragPosition = false; + bool hasVertexCode = false; if (!skipColor) { for (int s = 0; s < drawState.numColorStages(); ++s) { effectKeys[currEffectKey++] = get_key_and_update_stats(drawState.getColorStage(s), gpu->glCaps(), - requiresLocalCoordAttrib, &readsDst, &readFragPosition); + requiresLocalCoordAttrib, &readsDst, &readFragPosition, + &hasVertexCode); } } if (!skipCoverage) { for (int s = 0; s < drawState.numCoverageStages(); ++s) { effectKeys[currEffectKey++] = get_key_and_update_stats(drawState.getCoverageStage(s), gpu->glCaps(), - requiresLocalCoordAttrib, &readsDst, &readFragPosition); + requiresLocalCoordAttrib, &readsDst, &readFragPosition, + &hasVertexCode); } } + header->fHasVertexCode = hasVertexCode || requiresLocalCoordAttrib; header->fEmitsPointSize = isPoints; header->fColorFilterXfermode = skipColor ? SkXfermode::kDst_Mode : drawState.getColorFilterMode(); @@ -122,6 +130,7 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState, header->fColorInput = kUniform_ColorInput; } else { header->fColorInput = kAttribute_ColorInput; + header->fHasVertexCode = true; } bool covIsSolidWhite = !requiresCoverageAttrib && 0xffffffff == drawState.getCoverage(); @@ -134,6 +143,7 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState, header->fCoverageInput = kUniform_ColorInput; } else { header->fCoverageInput = kAttribute_ColorInput; + header->fHasVertexCode = true; } if (readsDst) { diff --git a/src/gpu/gl/GrGLProgramDesc.h b/src/gpu/gl/GrGLProgramDesc.h index fb67a97e85..308b0c787f 100644 --- a/src/gpu/gl/GrGLProgramDesc.h +++ b/src/gpu/gl/GrGLProgramDesc.h @@ -158,6 +158,7 @@ private: uint8_t fCoverageInput; // casts to enum ColorInput uint8_t fCoverageOutput; // casts to enum CoverageOutput + SkBool8 fHasVertexCode; SkBool8 fEmitsPointSize; uint8_t fColorFilterXfermode; // casts to enum SkXfermode::Mode |