aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-10-30 20:17:54 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-10-30 20:17:54 +0000
commit175fe75654a6a9bf8cb1570d057fa04f018c5437 (patch)
tree91d0c37b115bc84851363ec016569ea0f671c700
parentd4501a0aba2541489c32c89426bbfc59ed945da2 (diff)
parent17504f5d5ea2550d29d2118193627129beb7f8b2 (diff)
Upstreaming changes from gpu_dev to trunk.
git-svn-id: http://skia.googlecode.com/svn/trunk@6207 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--gyp/gpu.gypi1
-rw-r--r--include/gpu/GrBackendEffectFactory.h70
-rw-r--r--include/gpu/GrEffect.h6
-rw-r--r--include/gpu/GrEffectStage.h23
-rw-r--r--include/gpu/GrRenderTarget.h11
-rw-r--r--include/gpu/GrSurface.h31
-rw-r--r--include/gpu/GrTBackendEffectFactory.h73
-rw-r--r--include/gpu/GrTexture.h4
-rw-r--r--include/gpu/GrTypes.h2
-rw-r--r--src/effects/SkBlendImageFilter.cpp36
-rw-r--r--src/effects/SkColorMatrixFilter.cpp28
-rw-r--r--src/effects/SkLightingImageFilter.cpp282
-rw-r--r--src/effects/SkMagnifierImageFilter.cpp74
-rw-r--r--src/effects/SkMatrixConvolutionImageFilter.cpp72
-rw-r--r--src/effects/SkMorphologyImageFilter.cpp50
-rw-r--r--src/effects/SkTableColorFilter.cpp32
-rw-r--r--src/effects/gradients/SkGradientShader.cpp6
-rw-r--r--src/effects/gradients/SkGradientShaderPriv.h19
-rw-r--r--src/effects/gradients/SkLinearGradient.cpp30
-rw-r--r--src/effects/gradients/SkRadialGradient.cpp29
-rw-r--r--src/effects/gradients/SkSweepGradient.cpp29
-rw-r--r--src/effects/gradients/SkTwoPointConicalGradient.cpp311
-rw-r--r--src/effects/gradients/SkTwoPointRadialGradient.cpp200
-rw-r--r--src/gpu/GrDrawState.h1
-rw-r--r--src/gpu/GrEffect.cpp8
-rw-r--r--src/gpu/effects/GrConfigConversionEffect.cpp23
-rw-r--r--src/gpu/effects/GrConvolutionEffect.cpp50
-rw-r--r--src/gpu/effects/GrSingleTextureEffect.cpp22
-rw-r--r--src/gpu/effects/GrTextureDomainEffect.cpp46
-rw-r--r--src/gpu/gl/GrGLEffect.cpp4
-rw-r--r--src/gpu/gl/GrGLEffect.h50
-rw-r--r--src/gpu/gl/GrGLProgram.cpp61
-rw-r--r--src/gpu/gl/GrGLProgram.h28
-rw-r--r--src/gpu/gl/GrGLRenderTarget.cpp7
-rw-r--r--src/gpu/gl/GrGLRenderTarget.h4
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.cpp10
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.h12
-rw-r--r--src/gpu/gl/GrGLTexture.cpp9
-rw-r--r--src/gpu/gl/GrGLTexture.h18
-rw-r--r--src/gpu/gl/GrGpuGL.cpp9
-rw-r--r--src/gpu/gl/GrGpuGL.h6
-rw-r--r--src/gpu/gl/GrGpuGL_program.cpp54
-rw-r--r--tests/GLProgramsTest.cpp34
43 files changed, 947 insertions, 928 deletions
diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi
index 8650f3cd3f..c01174797e 100644
--- a/gyp/gpu.gypi
+++ b/gyp/gpu.gypi
@@ -33,6 +33,7 @@
'<(skia_include_path)/gpu/GrResource.h',
'<(skia_include_path)/gpu/GrScalar.h',
'<(skia_include_path)/gpu/GrSurface.h',
+ '<(skia_include_path)/gpu/GrTBackendEffectFactory.h',
'<(skia_include_path)/gpu/GrTextContext.h',
'<(skia_include_path)/gpu/GrTexture.h',
'<(skia_include_path)/gpu/GrTextureAccess.h',
diff --git a/include/gpu/GrBackendEffectFactory.h b/include/gpu/GrBackendEffectFactory.h
index 89562d5239..c496f5a13a 100644
--- a/include/gpu/GrBackendEffectFactory.h
+++ b/include/gpu/GrBackendEffectFactory.h
@@ -10,14 +10,21 @@
#include "GrTypes.h"
#include "SkTemplates.h"
+#include "SkThread_platform.h"
#include "GrNoncopyable.h"
-/** Given a GrEffect of a particular type, creates the corresponding
- graphics-backend-specific GrGLEffect. Also tracks equivalence
- of shaders generated via a key.
+/** Given a GrEffect of a particular type, creates the corresponding graphics-backend-specific
+ effect object. Also tracks equivalence of shaders generated via a key. Each factory instance
+ is assigned a generation ID at construction. The ID of the return of GrEffect::getFactory()
+ is used as a type identifier. Thus a GrEffect subclass must return a singleton from
+ getFactory(). GrEffect subclasses should use the derived class GrTBackendEffectFactory that is
+ templated on the GrEffect subclass as their factory object. It requires that the GrEffect
+ subclass has a nested class (or typedef) GLEffect which is its GL implementation and a subclass
+ of GrGLEffect.
*/
class GrEffect;
+class GrEffectStage;
class GrGLEffect;
class GrGLCaps;
@@ -35,7 +42,7 @@ public:
kTextureKeyBits = 6
};
- virtual EffectKey glEffectKey(const GrEffect&, const GrGLCaps&) const = 0;
+ virtual EffectKey glEffectKey(const GrEffectStage&, const GrGLCaps&) const = 0;
virtual GrGLEffect* createGLInstance(const GrEffect&) const = 0;
bool operator ==(const GrBackendEffectFactory& b) const {
@@ -71,59 +78,4 @@ private:
static int32_t fCurrEffectClassID;
};
-template <typename EffectClass>
-class GrTBackendEffectFactory : public GrBackendEffectFactory {
-
-public:
- typedef typename EffectClass::GLEffect GLEffect;
-
- /** Returns a human-readable name that is accessible via GrEffect or
- GrGLEffect and is consistent between the two of them.
- */
- virtual const char* name() const SK_OVERRIDE { return EffectClass::Name(); }
-
- /** Returns a value that identifies the GLSL shader code generated by
- a GrEffect. This enables caching of generated shaders. Part of the
- id identifies the GrEffect subclass. The remainder is based
- on the aspects of the GrEffect object's configuration that affect
- GLSL code generation. */
- virtual EffectKey glEffectKey(const GrEffect& effect, const GrGLCaps& caps) const SK_OVERRIDE {
- GrAssert(kIllegalEffectClassID != fEffectClassID);
- EffectKey effectKey = GLEffect::GenKey(effect, caps);
- EffectKey textureKey = GLEffect::GenTextureKey(effect, caps);
-#if GR_DEBUG
- static const EffectKey kIllegalIDMask = (uint16_t) (~((1U << kEffectKeyBits) - 1));
- GrAssert(!(kIllegalIDMask & effectKey));
-
- static const EffectKey kIllegalTextureKeyMask = (uint16_t) (~((1U << kTextureKeyBits) - 1));
- GrAssert(!(kIllegalTextureKeyMask & textureKey));
-#endif
- return fEffectClassID | (textureKey << kEffectKeyBits) | effectKey;
- }
-
- /** Returns a new instance of the appropriate *GL* implementation class
- for the given GrEffect; caller is responsible for deleting
- the object. */
- virtual GLEffect* createGLInstance(const GrEffect& effect) const SK_OVERRIDE {
- return SkNEW_ARGS(GLEffect, (*this, effect));
- }
-
- /** This class is a singleton. This function returns the single instance.
- */
- static const GrBackendEffectFactory& getInstance() {
- static SkAlignedSTStorage<1, GrTBackendEffectFactory> gInstanceMem;
- static const GrTBackendEffectFactory* gInstance;
- if (!gInstance) {
- gInstance = SkNEW_PLACEMENT(gInstanceMem.get(),
- GrTBackendEffectFactory);
- }
- return *gInstance;
- }
-
-protected:
- GrTBackendEffectFactory() {
- fEffectClassID = GenID() << (kEffectKeyBits + kTextureKeyBits) ;
- }
-};
-
#endif
diff --git a/include/gpu/GrEffect.h b/include/gpu/GrEffect.h
index d7209ff563..0adc00be00 100644
--- a/include/gpu/GrEffect.h
+++ b/include/gpu/GrEffect.h
@@ -10,10 +10,10 @@
#include "GrRefCnt.h"
#include "GrNoncopyable.h"
-#include "GrBackendEffectFactory.h"
#include "GrEffectUnitTest.h"
#include "GrTextureAccess.h"
+class GrBackendEffectFactory;
class GrContext;
class GrTexture;
class SkString;
@@ -33,8 +33,6 @@ class GrEffect : public GrRefCnt {
public:
SK_DECLARE_INST_COUNT(GrEffect)
- typedef GrBackendEffectFactory::EffectKey EffectKey;
-
explicit GrEffect(int numTextures);
virtual ~GrEffect();
@@ -77,7 +75,7 @@ public:
/** Human-meaningful string to identify this effect; may be embedded
in generated shader code. */
- const char* name() const { return this->getFactory().name(); }
+ const char* name() const;
int numTextures() const { return fNumTextures; }
diff --git a/include/gpu/GrEffectStage.h b/include/gpu/GrEffectStage.h
index 6f8b23fea9..5cd0af3b83 100644
--- a/include/gpu/GrEffectStage.h
+++ b/include/gpu/GrEffectStage.h
@@ -8,9 +8,10 @@
-#ifndef GrSamplerState_DEFINED
-#define GrSamplerState_DEFINED
+#ifndef GrEffectStage_DEFINED
+#define GrEffectStage_DEFINED
+#include "GrBackendEffectFactory.h"
#include "GrEffect.h"
#include "GrMatrix.h"
#include "GrTypes.h"
@@ -70,7 +71,7 @@ public:
class SavedCoordChange {
private:
GrMatrix fCoordChangeMatrix;
- GR_DEBUGCODE(mutable SkAutoTUnref<GrEffect> fEffect;)
+ GR_DEBUGCODE(mutable SkAutoTUnref<const GrEffect> fEffect;)
friend class GrEffectStage;
};
@@ -79,7 +80,7 @@ public:
* This gets the current coordinate system change. It is the accumulation of
* preConcatCoordChange calls since the effect was installed. It is used when then caller
* wants to temporarily change the source geometry coord system, draw something, and then
- * restore the previous coord system (e.g. temporarily draw in device coords).s
+ * restore the previous coord system (e.g. temporarily draw in device coords).
*/
void saveCoordChange(SavedCoordChange* savedCoordChange) const {
savedCoordChange->fCoordChangeMatrix = fCoordChangeMatrix;
@@ -106,18 +107,24 @@ public:
/**
* Gets the matrix to apply at draw time. This is the original texture matrix combined with
- * any coord system changes.
+ * any coord system changes. This will be removed when the matrix is managed by GrEffect.
*/
void getTotalMatrix(GrMatrix* matrix) const {
*matrix = fMatrix;
matrix->preConcat(fCoordChangeMatrix);
}
+ /**
+ * Gets the matrix representing all changes of coordinate system since the GrEffect was
+ * installed in the stage.
+ */
+ const GrMatrix& getCoordChangeMatrix() const { return fCoordChangeMatrix; }
+
void reset() {
GrSafeSetNull(fEffect);
}
- GrEffect* setEffect(GrEffect* effect) {
+ const GrEffect* setEffect(const GrEffect* effect) {
GrAssert(0 == fSavedCoordChangeCnt);
GrSafeAssign(fEffect, effect);
fMatrix.reset();
@@ -125,7 +132,7 @@ public:
return effect;
}
- GrEffect* setEffect(GrEffect* effect, const GrMatrix& matrix) {
+ const GrEffect* setEffect(const GrEffect* effect, const GrMatrix& matrix) {
GrAssert(0 == fSavedCoordChangeCnt);
GrSafeAssign(fEffect, effect);
fMatrix = matrix;
@@ -138,7 +145,7 @@ public:
private:
GrMatrix fCoordChangeMatrix;
GrMatrix fMatrix; // TODO: remove this, store in GrEffect
- GrEffect* fEffect;
+ const GrEffect* fEffect;
GR_DEBUGCODE(mutable int fSavedCoordChangeCnt;)
};
diff --git a/include/gpu/GrRenderTarget.h b/include/gpu/GrRenderTarget.h
index 58a3aa5220..2a6e62ac01 100644
--- a/include/gpu/GrRenderTarget.h
+++ b/include/gpu/GrRenderTarget.h
@@ -40,7 +40,7 @@ public:
// GrSurface overrides
/**
- * @return the texture associated with the rendertarget, may be NULL.
+ * @return the texture associated with the render target, may be NULL.
*/
virtual GrTexture* asTexture() SK_OVERRIDE { return fTexture; }
virtual const GrTexture* asTexture() const SK_OVERRIDE { return fTexture; }
@@ -75,7 +75,7 @@ public:
/**
* If this RT is multisampled, this is the buffer it is resolved to.
* Otherwise, same as getRenderTargetHandle().
- * (In GL a separate FBO ID is used for the msaa and resolved buffers)
+ * (In GL a separate FBO ID is used for the MSAA and resolved buffers)
* @return the 3D API's handle to this object (e.g. FBO ID in OpenGL)
*/
virtual GrBackendObject getRenderTargetResolvedHandle() const = 0;
@@ -150,15 +150,16 @@ public:
protected:
GrRenderTarget(GrGpu* gpu,
GrTexture* texture,
- const GrTextureDesc& desc)
- : INHERITED(gpu, desc)
+ const GrTextureDesc& desc,
+ Origin origin)
+ : INHERITED(gpu, desc, origin)
, fStencilBuffer(NULL)
, fTexture(texture) {
fResolveRect.setLargestInverted();
}
friend class GrTexture;
- // When a texture unrefs an owned rendertarget this func
+ // When a texture unrefs an owned render target this func
// removes the back pointer. This could be called from
// texture's destructor but would have to be done in derived
// classes. By the time of texture base destructor it has already
diff --git a/include/gpu/GrSurface.h b/include/gpu/GrSurface.h
index aa237aee4d..d7aa2672d8 100644
--- a/include/gpu/GrSurface.h
+++ b/include/gpu/GrSurface.h
@@ -34,6 +34,22 @@ public:
int height() const { return fDesc.fHeight; }
/**
+ * Some surfaces will be stored such that the upper and left edges of the content meet at the
+ * the origin (in texture coord space) and for other surfaces the lower and left edges meet at
+ * the origin. Render-targets are always consistent with the convention of the underlying
+ * backend API to make it easier to mix native backend rendering with Skia rendering. Wrapped
+ * backend surfaces always use the backend's convention as well.
+ */
+ enum Origin {
+ kTopLeft_Origin,
+ kBottomLeft_Origin,
+ };
+ Origin origin() const {
+ GrAssert(kTopLeft_Origin == fOrigin || kBottomLeft_Origin == fOrigin);
+ return fOrigin;
+ }
+
+ /**
* Retrieves the pixel config specified when the surface was created.
* For render targets this can be kUnknown_GrPixelConfig
* if client asked us to render to a target that has a pixel
@@ -66,7 +82,7 @@ public:
* @param height height of rectangle to read in pixels.
* @param config the pixel config of the destination buffer
* @param buffer memory to read the rectangle into.
- * @param rowBytes number of bytes bewtween consecutive rows. Zero means rows are tightly
+ * @param rowBytes number of bytes between consecutive rows. Zero means rows are tightly
* packed.
* @param pixelOpsFlags See the GrContext::PixelOpsFlags enum.
*
@@ -88,7 +104,7 @@ public:
* @param height height of rectangle to write in pixels.
* @param config the pixel config of the source buffer
* @param buffer memory to read the rectangle from.
- * @param rowBytes number of bytes bewtween consecutive rows. Zero means rows are tightly
+ * @param rowBytes number of bytes between consecutive rows. Zero means rows are tightly
* packed.
* @param pixelOpsFlags See the GrContext::PixelOpsFlags enum.
*/
@@ -99,14 +115,17 @@ public:
uint32_t pixelOpsFlags = 0) = 0;
protected:
- GrTextureDesc fDesc;
-
- GrSurface(GrGpu* gpu, const GrTextureDesc& desc)
+ GrSurface(GrGpu* gpu, const GrTextureDesc& desc, Origin origin)
: INHERITED(gpu)
- , fDesc(desc) {
+ , fDesc(desc)
+ , fOrigin(origin) {
}
+ GrTextureDesc fDesc;
+
private:
+ Origin fOrigin;
+
typedef GrResource INHERITED;
};
diff --git a/include/gpu/GrTBackendEffectFactory.h b/include/gpu/GrTBackendEffectFactory.h
new file mode 100644
index 0000000000..52dbc64dd8
--- /dev/null
+++ b/include/gpu/GrTBackendEffectFactory.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrTBackendEffectFactory_DEFINED
+#define GrTBackendEffectFactory_DEFINED
+
+#include "GrBackendEffectFactory.h"
+#include "GrEffectStage.h"
+
+/**
+ * Implements GrBackendEffectFactory for a GrEffect subclass as a singleton.
+ */
+template <typename EffectClass>
+class GrTBackendEffectFactory : public GrBackendEffectFactory {
+
+public:
+ typedef typename EffectClass::GLEffect GLEffect;
+
+ /** Returns a human-readable name that is accessible via GrEffect or
+ GrGLEffect and is consistent between the two of them.
+ */
+ virtual const char* name() const SK_OVERRIDE { return EffectClass::Name(); }
+
+ /** Returns a value that identifies the GLSL shader code generated by
+ a GrEffect. This enables caching of generated shaders. Part of the
+ id identifies the GrEffect subclass. The remainder is based
+ on the aspects of the GrEffect object's configuration that affect
+ GLSL code generation. */
+ virtual EffectKey glEffectKey(const GrEffectStage& stage,
+ const GrGLCaps& caps) const SK_OVERRIDE {
+ GrAssert(kIllegalEffectClassID != fEffectClassID);
+ EffectKey effectKey = GLEffect::GenKey(stage, caps);
+ EffectKey textureKey = GLEffect::GenTextureKey(*stage.getEffect(), caps);
+#if GR_DEBUG
+ static const EffectKey kIllegalIDMask = (uint16_t) (~((1U << kEffectKeyBits) - 1));
+ GrAssert(!(kIllegalIDMask & effectKey));
+
+ static const EffectKey kIllegalTextureKeyMask = (uint16_t) (~((1U << kTextureKeyBits) - 1));
+ GrAssert(!(kIllegalTextureKeyMask & textureKey));
+#endif
+ return fEffectClassID | (textureKey << kEffectKeyBits) | effectKey;
+ }
+
+ /** Returns a new instance of the appropriate *GL* implementation class
+ for the given GrEffect; caller is responsible for deleting
+ the object. */
+ virtual GLEffect* createGLInstance(const GrEffect& effect) const SK_OVERRIDE {
+ return SkNEW_ARGS(GLEffect, (*this, effect));
+ }
+
+ /** This class is a singleton. This function returns the single instance.
+ */
+ static const GrBackendEffectFactory& getInstance() {
+ static SkAlignedSTStorage<1, GrTBackendEffectFactory> gInstanceMem;
+ static const GrTBackendEffectFactory* gInstance;
+ if (!gInstance) {
+ gInstance = SkNEW_PLACEMENT(gInstanceMem.get(),
+ GrTBackendEffectFactory);
+ }
+ return *gInstance;
+ }
+
+protected:
+ GrTBackendEffectFactory() {
+ fEffectClassID = GenID() << (kEffectKeyBits + kTextureKeyBits) ;
+ }
+};
+
+#endif
diff --git a/include/gpu/GrTexture.h b/include/gpu/GrTexture.h
index a8d67e7529..65950a6a96 100644
--- a/include/gpu/GrTexture.h
+++ b/include/gpu/GrTexture.h
@@ -146,8 +146,8 @@ protected:
// base class cons sets to NULL
// subclass cons can create and set
- GrTexture(GrGpu* gpu, const GrTextureDesc& desc)
- : INHERITED(gpu, desc)
+ GrTexture(GrGpu* gpu, const GrTextureDesc& desc, Origin origin)
+ : INHERITED(gpu, desc, origin)
, fRenderTarget(NULL) {
// only make sense if alloc size is pow2
diff --git a/include/gpu/GrTypes.h b/include/gpu/GrTypes.h
index 8bd1f2f8a8..9723868be9 100644
--- a/include/gpu/GrTypes.h
+++ b/include/gpu/GrTypes.h
@@ -457,7 +457,7 @@ struct GrTextureDesc {
* applies if the kRenderTarget_GrTextureFlagBit is set. The actual number
* of samples may not exactly match the request. The request will be rounded
* up to the next supported sample count, or down if it is larger than the
- * max supportex count.
+ * max supported count.
*/
int fSampleCnt;
};
diff --git a/src/effects/SkBlendImageFilter.cpp b/src/effects/SkBlendImageFilter.cpp
index fdbf070560..fb0e4d089a 100644
--- a/src/effects/SkBlendImageFilter.cpp
+++ b/src/effects/SkBlendImageFilter.cpp
@@ -13,6 +13,7 @@
#include "SkGr.h"
#include "SkGrPixelRef.h"
#include "gl/GrGLEffect.h"
+#include "GrTBackendEffectFactory.h"
#endif
namespace {
@@ -110,24 +111,24 @@ bool SkBlendImageFilter::onFilterImage(Proxy* proxy,
///////////////////////////////////////////////////////////////////////////////
#if SK_SUPPORT_GPU
-class GrGLBlendEffect : public GrGLLegacyEffect {
+class GrGLBlendEffect : public GrGLEffect {
public:
GrGLBlendEffect(const GrBackendEffectFactory& factory,
const GrEffect& effect);
virtual ~GrGLBlendEffect();
- virtual void emitFS(GrGLShaderBuilder* builder,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray&) SK_OVERRIDE;
+ virtual void emitCode(GrGLShaderBuilder*,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray&) SK_OVERRIDE;
- virtual void emitVS(GrGLShaderBuilder* builder,
- const char* vertexCoords) SK_OVERRIDE {}
-
- static inline EffectKey GenKey(const GrEffect& s, const GrGLCaps&);
+ static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&);
private:
- typedef GrGLLegacyEffect INHERITED;
+ typedef GrGLEffect INHERITED;
SkBlendImageFilter::Mode fMode;
};
@@ -245,10 +246,13 @@ GrGLBlendEffect::GrGLBlendEffect(const GrBackendEffectFactory& factory,
GrGLBlendEffect::~GrGLBlendEffect() {
}
-void GrGLBlendEffect::emitFS(GrGLShaderBuilder* builder,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray& samplers) {
+void GrGLBlendEffect::emitCode(GrGLShaderBuilder* builder,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray& samplers) {
SkString* code = &builder->fFSCode;
const char* bgColor = inputColor;
const char* fgColor = "fgColor";
@@ -275,7 +279,7 @@ void GrGLBlendEffect::emitFS(GrGLShaderBuilder* builder,
}
}
-GrGLEffect::EffectKey GrGLBlendEffect::GenKey(const GrEffect& s, const GrGLCaps&) {
- return static_cast<const GrBlendEffect&>(s).mode();
+GrGLEffect::EffectKey GrGLBlendEffect::GenKey(const GrEffectStage& s, const GrGLCaps&) {
+ return static_cast<const GrBlendEffect&>(*s.getEffect()).mode();
}
#endif
diff --git a/src/effects/SkColorMatrixFilter.cpp b/src/effects/SkColorMatrixFilter.cpp
index ca23452f93..58d26735a1 100644
--- a/src/effects/SkColorMatrixFilter.cpp
+++ b/src/effects/SkColorMatrixFilter.cpp
@@ -320,6 +320,7 @@ bool SkColorMatrixFilter::asColorMatrix(SkScalar matrix[20]) {
#if SK_SUPPORT_GPU
#include "GrEffect.h"
+#include "GrTBackendEffectFactory.h"
#include "gl/GrGLEffect.h"
class ColorMatrixEffect : public GrEffect {
@@ -339,10 +340,10 @@ public:
GR_DECLARE_EFFECT_TEST;
- class GLEffect : public GrGLLegacyEffect {
+ class GLEffect : public GrGLEffect {
public:
// this class always generates the same code.
- static EffectKey GenKey(const GrEffect& s, const GrGLCaps&) { return 0; }
+ static EffectKey GenKey(const GrEffectStage&, const GrGLCaps&) { return 0; }
GLEffect(const GrBackendEffectFactory& factory,
const GrEffect& effect)
@@ -351,22 +352,20 @@ public:
, fVectorHandle(GrGLUniformManager::kInvalidUniformHandle) {
}
- virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE {
+ virtual void emitCode(GrGLShaderBuilder* builder,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray&) SK_OVERRIDE {
fMatrixHandle = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
kMat44f_GrSLType,
"ColorMatrix");
fVectorHandle = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
kVec4f_GrSLType,
"ColorMatrixVector");
- }
-
- virtual void emitVS(GrGLShaderBuilder* builder, const char* vertexCoords) SK_OVERRIDE {
- }
- virtual void emitFS(GrGLShaderBuilder* builder,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray&) SK_OVERRIDE {
if (NULL == inputColor) {
// could optimize this case, but we aren't for now.
inputColor = GrGLSLOnesVecf(4);
@@ -383,8 +382,9 @@ public:
}
virtual void setData(const GrGLUniformManager& uniManager,
- const GrEffect& effect) SK_OVERRIDE {
- const ColorMatrixEffect& cme = static_cast<const ColorMatrixEffect&>(effect);
+ const GrEffectStage& stage) SK_OVERRIDE {
+ const ColorMatrixEffect& cme =
+ static_cast<const ColorMatrixEffect&>(*stage.getEffect());
const float* m = cme.fMatrix.fMat;
// The GL matrix is transposed from SkColorMatrix.
GrGLfloat mt[] = {
@@ -409,7 +409,7 @@ public:
private:
SkColorMatrix fMatrix;
- typedef GrGLLegacyEffect INHERITED;
+ typedef GrGLEffect INHERITED;
};
GR_DEFINE_EFFECT_TEST(ColorMatrixEffect);
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index f17318cecf..82e1f22e4d 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -14,11 +14,10 @@
#include "SkTypes.h"
#if SK_SUPPORT_GPU
-#include "GrBackendEffectFactory.h"
#include "effects/GrSingleTextureEffect.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLTexture.h"
#include "GrEffect.h"
+#include "GrTBackendEffectFactory.h"
class GrGLDiffuseLightingEffect;
class GrGLSpecularLightingEffect;
@@ -366,21 +365,39 @@ private:
class GrGLLight {
public:
virtual ~GrGLLight() {}
- virtual void setupVariables(GrGLShaderBuilder* builder);
- virtual void emitVS(SkString* out) const {}
- virtual void emitFuncs(GrGLShaderBuilder* builder) {}
- virtual void emitSurfaceToLight(GrGLShaderBuilder*,
- SkString* out,
- const char* z) const = 0;
- virtual void emitLightColor(GrGLShaderBuilder*,
- const char *surfaceToLight) const;
- virtual void setData(const GrGLUniformManager&, const SkLight* light) const;
-private:
- typedef SkRefCnt INHERITED;
+ /**
+ * This is called by GrGLLightingEffect::emitCode() before either of the two virtual functions
+ * below. It adds a vec3f uniform visible in the FS that represents the constant light color.
+ */
+ void emitLightColorUniform(GrGLShaderBuilder*);
+
+ /**
+ * These two functions are called from GrGLLightingEffect's emitCode() function.
+ * emitSurfaceToLight places an expression in param out that is the vector from the surface to
+ * the light. The expression will be used in the FS. emitLightColor writes an expression into
+ * the FS that is the color of the light. Either function may add functions and/or uniforms to
+ * the FS. The default of emitLightColor appends the name of the constant light color uniform
+ * and so this function only needs to be overridden if the light color varies spatially.
+ */
+ virtual void emitSurfaceToLight(GrGLShaderBuilder*, SkString* out, const char* z) = 0;
+ virtual void emitLightColor(GrGLShaderBuilder*, const char *surfaceToLight);
+
+ // This is called from GrGLLightingEffect's setData(). Subclasses of GrGLLight must call
+ // INHERITED::setData().
+ virtual void setData(const GrGLUniformManager&, const SkLight* light) const;
protected:
+ /**
+ * Gets the constant light color uniform. Subclasses can use this in their emitLightColor
+ * function.
+ */
+ UniformHandle lightColorUni() const { return fColorUni; }
+
+private:
UniformHandle fColorUni;
+
+ typedef SkRefCnt INHERITED;
};
///////////////////////////////////////////////////////////////////////////////
@@ -388,11 +405,8 @@ protected:
class GrGLDistantLight : public GrGLLight {
public:
virtual ~GrGLDistantLight() {}
- virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE;
virtual void setData(const GrGLUniformManager&, const SkLight* light) const SK_OVERRIDE;
- virtual void emitSurfaceToLight(GrGLShaderBuilder*,
- SkString* out,
- const char* z) const SK_OVERRIDE;
+ virtual void emitSurfaceToLight(GrGLShaderBuilder*, SkString* out, const char* z) SK_OVERRIDE;
private:
typedef GrGLLight INHERITED;
UniformHandle fDirectionUni;
@@ -403,12 +417,8 @@ private:
class GrGLPointLight : public GrGLLight {
public:
virtual ~GrGLPointLight() {}
- virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE;
virtual void setData(const GrGLUniformManager&, const SkLight* light) const SK_OVERRIDE;
- virtual void emitVS(SkString* out) const SK_OVERRIDE;
- virtual void emitSurfaceToLight(GrGLShaderBuilder*,
- SkString* out,
- const char* z) const SK_OVERRIDE;
+ virtual void emitSurfaceToLight(GrGLShaderBuilder*, SkString* out, const char* z) SK_OVERRIDE;
private:
typedef GrGLLight INHERITED;
SkPoint3 fLocation;
@@ -420,16 +430,9 @@ private:
class GrGLSpotLight : public GrGLLight {
public:
virtual ~GrGLSpotLight() {}
- virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE;
virtual void setData(const GrGLUniformManager&, const SkLight* light) const SK_OVERRIDE;
- virtual void emitVS(SkString* out) const SK_OVERRIDE;
- virtual void emitFuncs(GrGLShaderBuilder* builder);
- virtual void emitSurfaceToLight(GrGLShaderBuilder* builder,
- SkString* out,
- const char* z) const SK_OVERRIDE;
- virtual void emitLightColor(GrGLShaderBuilder*,
- const char *surfaceToLight) const SK_OVERRIDE;
-
+ virtual void emitSurfaceToLight(GrGLShaderBuilder*, SkString* out, const char* z) SK_OVERRIDE;
+ virtual void emitLightColor(GrGLShaderBuilder*, const char *surfaceToLight) SK_OVERRIDE;
private:
typedef GrGLLight INHERITED;
@@ -939,28 +942,32 @@ SkLight* create_random_light(SkRandom* random) {
}
-class GrGLLightingEffect : public GrGLLegacyEffect {
+class GrGLLightingEffect : public GrGLEffect {
public:
GrGLLightingEffect(const GrBackendEffectFactory& factory,
const GrEffect& effect);
virtual ~GrGLLightingEffect();
- virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE;
- virtual void emitVS(GrGLShaderBuilder* builder,
- const char* vertexCoords) SK_OVERRIDE;
- virtual void emitFS(GrGLShaderBuilder* builder,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray&) SK_OVERRIDE;
+ virtual void emitCode(GrGLShaderBuilder*,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray&) SK_OVERRIDE;
- virtual void emitLightFunc(GrGLShaderBuilder*, SkString* funcName) = 0;
+ static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&);
- static inline EffectKey GenKey(const GrEffect& s, const GrGLCaps& caps);
+ /**
+ * Subclasses of GrGLLightingEffect must call INHERITED::setData();
+ */
+ virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE;
- virtual void setData(const GrGLUniformManager&, const GrEffect&) SK_OVERRIDE;
+protected:
+ virtual void emitLightFunc(GrGLShaderBuilder*, SkString* funcName) = 0;
private:
- typedef GrGLLegacyEffect INHERITED;
+ typedef GrGLEffect INHERITED;
UniformHandle fImageIncrementUni;
UniformHandle fSurfaceScaleUni;
@@ -973,9 +980,8 @@ class GrGLDiffuseLightingEffect : public GrGLLightingEffect {
public:
GrGLDiffuseLightingEffect(const GrBackendEffectFactory& factory,
const GrEffect& effect);
- virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE;
virtual void emitLightFunc(GrGLShaderBuilder*, SkString* funcName) SK_OVERRIDE;
- virtual void setData(const GrGLUniformManager&, const GrEffect&) SK_OVERRIDE;
+ virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE;
private:
typedef GrGLLightingEffect INHERITED;
@@ -989,9 +995,8 @@ class GrGLSpecularLightingEffect : public GrGLLightingEffect {
public:
GrGLSpecularLightingEffect(const GrBackendEffectFactory& factory,
const GrEffect& effect);
- virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE;
virtual void emitLightFunc(GrGLShaderBuilder*, SkString* funcName) SK_OVERRIDE;
- virtual void setData(const GrGLUniformManager&, const GrEffect&) SK_OVERRIDE;
+ virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE;
private:
typedef GrGLLightingEffect INHERITED;
@@ -1066,27 +1071,21 @@ GrGLLightingEffect::~GrGLLightingEffect() {
delete fLight;
}
-void GrGLLightingEffect::setupVariables(GrGLShaderBuilder* builder) {
+void GrGLLightingEffect::emitCode(GrGLShaderBuilder* builder,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray& samplers) {
fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
kVec2f_GrSLType,
"ImageIncrement");
fSurfaceScaleUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
kFloat_GrSLType,
"SurfaceScale");
- fLight->setupVariables(builder);
-}
-
-void GrGLLightingEffect::emitVS(GrGLShaderBuilder* builder,
- const char* vertexCoords) {
- fLight->emitVS(&builder->fVSCode);
-}
-
-void GrGLLightingEffect::emitFS(GrGLShaderBuilder* builder,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray& samplers) {
+ fLight->emitLightColorUniform(builder);
SkString* code = &builder->fFSCode;
- fLight->emitFuncs(builder);
SkString lightFunc;
this->emitLightFunc(builder, &lightFunc);
static const GrGLShaderVar gSobelArgs[] = {
@@ -1168,16 +1167,15 @@ void GrGLLightingEffect::emitFS(GrGLShaderBuilder* builder,
GrGLSLMulVarBy4f(code, 2, outputColor, inputColor);
}
-GrGLEffect::EffectKey GrGLLightingEffect::GenKey(const GrEffect& s,
- const GrGLCaps& caps) {
- return static_cast<const GrLightingEffect&>(s).light()->type();
+GrGLEffect::EffectKey GrGLLightingEffect::GenKey(const GrEffectStage& s,
+ const GrGLCaps& caps) {
+ return static_cast<const GrLightingEffect&>(*s.getEffect()).light()->type();
}
-void GrGLLightingEffect::setData(const GrGLUniformManager& uman, const GrEffect& data) {
- const GrLightingEffect& effect =
- static_cast<const GrLightingEffect&>(data);
- GrGLTexture* texture = static_cast<GrGLTexture*>(data.texture(0));
- float ySign = texture->orientation() == GrGLTexture::kTopDown_Orientation ? -1.0f : 1.0f;
+void GrGLLightingEffect::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
+ const GrLightingEffect& effect =static_cast<const GrLightingEffect&>(*stage.getEffect());
+ GrTexture* texture = effect.texture(0);
+ float ySign = texture->origin() == GrSurface::kTopLeft_Origin ? -1.0f : 1.0f;
uman.set2f(fImageIncrementUni, 1.0f / texture->width(), ySign / texture->height());
uman.set1f(fSurfaceScaleUni, effect.surfaceScale());
fLight->setData(uman, effect.light());
@@ -1193,13 +1191,13 @@ GrGLDiffuseLightingEffect::GrGLDiffuseLightingEffect(const GrBackendEffectFactor
, fKDUni(kInvalidUniformHandle) {
}
-void GrGLDiffuseLightingEffect::setupVariables(GrGLShaderBuilder* builder) {
- INHERITED::setupVariables(builder);
- fKDUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, kFloat_GrSLType, "KD");
-}
-
void GrGLDiffuseLightingEffect::emitLightFunc(GrGLShaderBuilder* builder, SkString* funcName) {
- const char* kd = builder->getUniformCStr(fKDUni);
+ const char* kd;
+ fKDUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
+ kFloat_GrSLType,
+ "KD",
+ &kd);
+
static const GrGLShaderVar gLightArgs[] = {
GrGLShaderVar("normal", kVec3f_GrSLType),
GrGLShaderVar("surfaceToLight", kVec3f_GrSLType),
@@ -1217,10 +1215,11 @@ void GrGLDiffuseLightingEffect::emitLightFunc(GrGLShaderBuilder* builder, SkStri
funcName);
}
-void GrGLDiffuseLightingEffect::setData(const GrGLUniformManager& uman, const GrEffect& data) {
- INHERITED::setData(uman, data);
+void GrGLDiffuseLightingEffect::setData(const GrGLUniformManager& uman,
+ const GrEffectStage& stage) {
+ INHERITED::setData(uman, stage);
const GrDiffuseLightingEffect& effect =
- static_cast<const GrDiffuseLightingEffect&>(data);
+ static_cast<const GrDiffuseLightingEffect&>(*stage.getEffect());
uman.set1f(fKDUni, effect.kd());
}
@@ -1266,17 +1265,14 @@ GrGLSpecularLightingEffect::GrGLSpecularLightingEffect(const GrBackendEffectFact
, fShininessUni(kInvalidUniformHandle) {
}
-void GrGLSpecularLightingEffect::setupVariables(GrGLShaderBuilder* builder) {
- INHERITED::setupVariables(builder);
+void GrGLSpecularLightingEffect::emitLightFunc(GrGLShaderBuilder* builder, SkString* funcName) {
+ const char* ks;
+ const char* shininess;
+
fKSUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
- kFloat_GrSLType, "KS");
+ kFloat_GrSLType, "KS", &ks);
fShininessUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
- kFloat_GrSLType, "Shininess");
-}
-
-void GrGLSpecularLightingEffect::emitLightFunc(GrGLShaderBuilder* builder, SkString* funcName) {
- const char* ks = builder->getUniformCStr(fKSUni);
- const char* shininess = builder->getUniformCStr(fShininessUni);
+ kFloat_GrSLType, "Shininess", &shininess);
static const GrGLShaderVar gLightArgs[] = {
GrGLShaderVar("normal", kVec3f_GrSLType),
@@ -1298,26 +1294,25 @@ void GrGLSpecularLightingEffect::emitLightFunc(GrGLShaderBuilder* builder, SkStr
}
void GrGLSpecularLightingEffect::setData(const GrGLUniformManager& uman,
- const GrEffect& data) {
- INHERITED::setData(uman, data);
- const GrSpecularLightingEffect& effect = static_cast<const GrSpecularLightingEffect&>(data);
+ const GrEffectStage& stage) {
+ INHERITED::setData(uman, stage);
+ const GrSpecularLightingEffect& effect =
+ static_cast<const GrSpecularLightingEffect&>(*stage.getEffect());
uman.set1f(fKSUni, effect.ks());
uman.set1f(fShininessUni, effect.shininess());
}
///////////////////////////////////////////////////////////////////////////////
-
-void GrGLLight::emitLightColor(GrGLShaderBuilder* builder,
- const char *surfaceToLight) const {
- const char* color = builder->getUniformCStr(fColorUni);
- builder->fFSCode.append(color);
-}
-
-void GrGLLight::setupVariables(GrGLShaderBuilder* builder) {
+void GrGLLight::emitLightColorUniform(GrGLShaderBuilder* builder) {
fColorUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
kVec3f_GrSLType, "LightColor");
}
+void GrGLLight::emitLightColor(GrGLShaderBuilder* builder,
+ const char *surfaceToLight) {
+ builder->fFSCode.append(builder->getUniformCStr(this->lightColorUni()));
+}
+
void GrGLLight::setData(const GrGLUniformManager& uman,
const SkLight* light) const {
setUniformPoint3(uman, fColorUni, light->color() * SkScalarInvert(SkIntToScalar(255)));
@@ -1325,12 +1320,6 @@ void GrGLLight::setData(const GrGLUniformManager& uman,
///////////////////////////////////////////////////////////////////////////////
-void GrGLDistantLight::setupVariables(GrGLShaderBuilder* builder) {
- INHERITED::setupVariables(builder);
- fDirectionUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, kVec3f_GrSLType,
- "LightDirection");
-}
-
void GrGLDistantLight::setData(const GrGLUniformManager& uman, const SkLight* light) const {
INHERITED::setData(uman, light);
SkASSERT(light->type() == SkLight::kDistant_LightType);
@@ -1340,19 +1329,15 @@ void GrGLDistantLight::setData(const GrGLUniformManager& uman, const SkLight* li
void GrGLDistantLight::emitSurfaceToLight(GrGLShaderBuilder* builder,
SkString* out,
- const char* z) const {
- const char* dir = builder->getUniformCStr(fDirectionUni);
+ const char* z) {
+ const char* dir;
+ fDirectionUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, kVec3f_GrSLType,
+ "LightDirection", &dir);
out->append(dir);
}
///////////////////////////////////////////////////////////////////////////////
-void GrGLPointLight::setupVariables(GrGLShaderBuilder* builder) {
- INHERITED::setupVariables(builder);
- fLocationUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, kVec3f_GrSLType,
- "LightLocation");
-}
-
void GrGLPointLight::setData(const GrGLUniformManager& uman,
const SkLight* light) const {
INHERITED::setData(uman, light);
@@ -1361,34 +1346,17 @@ void GrGLPointLight::setData(const GrGLUniformManager& uman,
setUniformPoint3(uman, fLocationUni, pointLight->location());
}
-void GrGLPointLight::emitVS(SkString* out) const {
-}
-
void GrGLPointLight::emitSurfaceToLight(GrGLShaderBuilder* builder,
SkString* out,
- const char* z) const {
- const char* loc = builder->getUniformCStr(fLocationUni);
+ const char* z) {
+ const char* loc;
+ fLocationUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, kVec3f_GrSLType,
+ "LightLocation", &loc);
out->appendf("normalize(%s - vec3(%s.xy, %s))", loc, builder->fragmentPosition(), z);
}
///////////////////////////////////////////////////////////////////////////////
-void GrGLSpotLight::setupVariables(GrGLShaderBuilder* builder) {
- INHERITED::setupVariables(builder);
- fLocationUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
- kVec3f_GrSLType, "LightLocation");
- fExponentUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
- kFloat_GrSLType, "Exponent");
- fCosInnerConeAngleUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
- kFloat_GrSLType, "CosInnerConeAngle");
- fCosOuterConeAngleUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
- kFloat_GrSLType, "CosOuterConeAngle");
- fConeScaleUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
- kFloat_GrSLType, "ConeScale");
- fSUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
- kVec3f_GrSLType, "S");
-}
-
void GrGLSpotLight::setData(const GrGLUniformManager& uman,
const SkLight* light) const {
INHERITED::setData(uman, light);
@@ -1402,16 +1370,36 @@ void GrGLSpotLight::setData(const GrGLUniformManager& uman,
setUniformNormal3(uman, fSUni, spotLight->s());
}
-void GrGLSpotLight::emitVS(SkString* out) const {
+void GrGLSpotLight::emitSurfaceToLight(GrGLShaderBuilder* builder,
+ SkString* out,
+ const char* z) {
+ const char* location;
+ fLocationUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
+ kVec3f_GrSLType, "LightLocation", &location);
+ out->appendf("normalize(%s - vec3(%s.xy, %s))", location, builder->fragmentPosition(), z);
}
-void GrGLSpotLight::emitFuncs(GrGLShaderBuilder* builder) {
- const char* exponent = builder->getUniformCStr(fExponentUni);
- const char* cosInner = builder->getUniformCStr(fCosInnerConeAngleUni);
- const char* cosOuter = builder->getUniformCStr(fCosOuterConeAngleUni);
- const char* coneScale = builder->getUniformCStr(fConeScaleUni);
- const char* s = builder->getUniformCStr(fSUni);
- const char* color = builder->getUniformCStr(fColorUni);
+void GrGLSpotLight::emitLightColor(GrGLShaderBuilder* builder,
+ const char *surfaceToLight) {
+
+ const char* color = builder->getUniformCStr(this->lightColorUni()); // created by parent class.
+
+ const char* exponent;
+ const char* cosInner;
+ const char* cosOuter;
+ const char* coneScale;
+ const char* s;
+ fExponentUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
+ kFloat_GrSLType, "Exponent", &exponent);
+ fCosInnerConeAngleUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
+ kFloat_GrSLType, "CosInnerConeAngle", &cosInner);
+ fCosOuterConeAngleUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
+ kFloat_GrSLType, "CosOuterConeAngle", &cosOuter);
+ fConeScaleUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
+ kFloat_GrSLType, "ConeScale", &coneScale);
+ fSUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
+ kVec3f_GrSLType, "S", &s);
+
static const GrGLShaderVar gLightColorArgs[] = {
GrGLShaderVar("surfaceToLight", kVec3f_GrSLType)
};
@@ -1433,17 +1421,7 @@ void GrGLSpotLight::emitFuncs(GrGLShaderBuilder* builder) {
gLightColorArgs,
lightColorBody.c_str(),
&fLightColorFunc);
-}
-
-void GrGLSpotLight::emitSurfaceToLight(GrGLShaderBuilder* builder,
- SkString* out,
- const char* z) const {
- const char* location= builder->getUniformCStr(fLocationUni);
- out->appendf("normalize(%s - vec3(%s.xy, %s))", location, builder->fragmentPosition(), z);
-}
-
-void GrGLSpotLight::emitLightColor(GrGLShaderBuilder* builder,
- const char *surfaceToLight) const {
+
builder->fFSCode.appendf("%s(%s)", fLightColorFunc.c_str(), surfaceToLight);
}
diff --git a/src/effects/SkMagnifierImageFilter.cpp b/src/effects/SkMagnifierImageFilter.cpp
index ea64e530e3..1097273057 100644
--- a/src/effects/SkMagnifierImageFilter.cpp
+++ b/src/effects/SkMagnifierImageFilter.cpp
@@ -18,7 +18,7 @@
#include "gl/GrGLEffect.h"
#include "gl/GrGLSL.h"
#include "gl/GrGLTexture.h"
-#include "GrBackendEffectFactory.h"
+#include "GrTBackendEffectFactory.h"
class GrGLMagnifierEffect;
@@ -72,23 +72,22 @@ private:
// For brevity
typedef GrGLUniformManager::UniformHandle UniformHandle;
-class GrGLMagnifierEffect : public GrGLLegacyEffect {
+class GrGLMagnifierEffect : public GrGLEffect {
public:
GrGLMagnifierEffect(const GrBackendEffectFactory& factory,
const GrEffect& effect);
- virtual void setupVariables(GrGLShaderBuilder* state) SK_OVERRIDE;
- virtual void emitVS(GrGLShaderBuilder* state,
- const char* vertexCoords) SK_OVERRIDE;
- virtual void emitFS(GrGLShaderBuilder* state,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray&) SK_OVERRIDE;
+ virtual void emitCode(GrGLShaderBuilder*,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray&) SK_OVERRIDE;
- virtual void setData(const GrGLUniformManager& uman,
- const GrEffect& data) SK_OVERRIDE;
+ virtual void setData(const GrGLUniformManager& uman, const GrEffectStage& stage) SK_OVERRIDE;
- static inline EffectKey GenKey(const GrEffect&, const GrGLCaps&);
+ static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&);
private:
@@ -96,7 +95,7 @@ private:
UniformHandle fZoomVar;
UniformHandle fInsetVar;
- typedef GrGLLegacyEffect INHERITED;
+ typedef GrGLEffect INHERITED;
};
GrGLMagnifierEffect::GrGLMagnifierEffect(const GrBackendEffectFactory& factory,
@@ -107,41 +106,37 @@ GrGLMagnifierEffect::GrGLMagnifierEffect(const GrBackendEffectFactory& factory,
, fInsetVar(GrGLUniformManager::kInvalidUniformHandle) {
}
-void GrGLMagnifierEffect::setupVariables(GrGLShaderBuilder* state) {
- fOffsetVar = state->addUniform(
+void GrGLMagnifierEffect::emitCode(GrGLShaderBuilder* builder,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray& samplers) {
+ fOffsetVar = builder->addUniform(
GrGLShaderBuilder::kFragment_ShaderType |
GrGLShaderBuilder::kVertex_ShaderType,
kVec2f_GrSLType, "uOffset");
- fZoomVar = state->addUniform(
+ fZoomVar = builder->addUniform(
GrGLShaderBuilder::kFragment_ShaderType |
GrGLShaderBuilder::kVertex_ShaderType,
kVec2f_GrSLType, "uZoom");
- fInsetVar = state->addUniform(
+ fInsetVar = builder->addUniform(
GrGLShaderBuilder::kFragment_ShaderType |
GrGLShaderBuilder::kVertex_ShaderType,
kVec2f_GrSLType, "uInset");
-}
-
-void GrGLMagnifierEffect::emitVS(GrGLShaderBuilder* state,
- const char* vertexCoords) {
-}
-void GrGLMagnifierEffect::emitFS(GrGLShaderBuilder* state,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray& samplers) {
- SkString* code = &state->fFSCode;
+ SkString* code = &builder->fFSCode;
- code->appendf("\t\tvec2 coord = %s;\n", state->defaultTexCoordsName());
+ code->appendf("\t\tvec2 coord = %s;\n", builder->defaultTexCoordsName());
code->appendf("\t\tvec2 zoom_coord = %s + %s / %s;\n",
- state->getUniformCStr(fOffsetVar),
- state->defaultTexCoordsName(),
- state->getUniformCStr(fZoomVar));
+ builder->getUniformCStr(fOffsetVar),
+ builder->defaultTexCoordsName(),
+ builder->getUniformCStr(fZoomVar));
code->appendf("\t\tvec2 delta = min(coord, vec2(1.0, 1.0) - coord);\n");
- code->appendf(
- "\t\tdelta = delta / %s;\n", state->getUniformCStr(fInsetVar));
+ code->appendf("\t\tdelta = delta / %s;\n", builder->getUniformCStr(fInsetVar));
code->appendf("\t\tfloat weight = 0.0;\n");
code->appendf("\t\tif (delta.s < 2.0 && delta.t < 2.0) {\n");
@@ -151,13 +146,12 @@ void GrGLMagnifierEffect::emitFS(GrGLShaderBuilder* state,
code->appendf("\t\t\tweight = min(dist * dist, 1.0);\n");
code->appendf("\t\t} else {\n");
code->appendf("\t\t\tvec2 delta_squared = delta * delta;\n");
- code->appendf(
- "\t\t\tweight = min(min(delta_squared.s, delta_squared.y), 1.0);\n");
+ code->appendf("\t\t\tweight = min(min(delta_squared.s, delta_squared.y), 1.0);\n");
code->appendf("\t\t}\n");
code->appendf("\t\tvec2 mix_coord = mix(coord, zoom_coord, weight);\n");
code->appendf("\t\tvec4 output_color = ");
- state->appendTextureLookup(code, samplers[0], "mix_coord");
+ builder->appendTextureLookup(code, samplers[0], "mix_coord");
code->append(";\n");
code->appendf("\t\t%s = output_color;", outputColor);
@@ -165,17 +159,15 @@ void GrGLMagnifierEffect::emitFS(GrGLShaderBuilder* state,
}
void GrGLMagnifierEffect::setData(const GrGLUniformManager& uman,
- const GrEffect& data) {
- const GrMagnifierEffect& zoom =
- static_cast<const GrMagnifierEffect&>(data);
+ const GrEffectStage& stage) {
+ const GrMagnifierEffect& zoom = static_cast<const GrMagnifierEffect&>(*stage.getEffect());
uman.set2f(fOffsetVar, zoom.x_offset(), zoom.y_offset());
uman.set2f(fZoomVar, zoom.x_zoom(), zoom.y_zoom());
uman.set2f(fInsetVar, zoom.x_inset(), zoom.y_inset());
}
-GrGLEffect::EffectKey GrGLMagnifierEffect::GenKey(const GrEffect& s,
- const GrGLCaps& caps) {
+GrGLEffect::EffectKey GrGLMagnifierEffect::GenKey(const GrEffectStage&, const GrGLCaps&) {
return 0;
}
diff --git a/src/effects/SkMatrixConvolutionImageFilter.cpp b/src/effects/SkMatrixConvolutionImageFilter.cpp
index a1ece00895..f8d1c093b5 100644
--- a/src/effects/SkMatrixConvolutionImageFilter.cpp
+++ b/src/effects/SkMatrixConvolutionImageFilter.cpp
@@ -14,6 +14,7 @@
#if SK_SUPPORT_GPU
#include "gl/GrGLEffect.h"
+#include "GrTBackendEffectFactory.h"
#endif
SkMatrixConvolutionImageFilter::SkMatrixConvolutionImageFilter(const SkISize& kernelSize, const SkScalar* kernel, SkScalar gain, SkScalar bias, const SkIPoint& target, TileMode tileMode, bool convolveAlpha, SkImageFilter* input)
@@ -279,21 +280,21 @@ private:
typedef GrSingleTextureEffect INHERITED;
};
-class GrGLMatrixConvolutionEffect : public GrGLLegacyEffect {
+class GrGLMatrixConvolutionEffect : public GrGLEffect {
public:
GrGLMatrixConvolutionEffect(const GrBackendEffectFactory& factory,
const GrEffect& effect);
- virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE;
- virtual void emitVS(GrGLShaderBuilder* state,
- const char* vertexCoords) SK_OVERRIDE {}
- virtual void emitFS(GrGLShaderBuilder* state,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray&) SK_OVERRIDE;
+ virtual void emitCode(GrGLShaderBuilder*,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray&) SK_OVERRIDE;
- static inline EffectKey GenKey(const GrEffect& s, const GrGLCaps& caps);
+ static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&);
- virtual void setData(const GrGLUniformManager&, const GrEffect&) SK_OVERRIDE;
+ virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE;
private:
typedef GrGLUniformManager::UniformHandle UniformHandle;
@@ -308,7 +309,7 @@ private:
UniformHandle fGainUni;
UniformHandle fBiasUni;
- typedef GrGLLegacyEffect INHERITED;
+ typedef GrGLEffect INHERITED;
};
GrGLMatrixConvolutionEffect::GrGLMatrixConvolutionEffect(const GrBackendEffectFactory& factory,
@@ -325,19 +326,6 @@ GrGLMatrixConvolutionEffect::GrGLMatrixConvolutionEffect(const GrBackendEffectFa
fConvolveAlpha = m.convolveAlpha();
}
-void GrGLMatrixConvolutionEffect::setupVariables(GrGLShaderBuilder* builder) {
- fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
- kVec2f_GrSLType, "ImageIncrement");
- fKernelUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_ShaderType,
- kFloat_GrSLType, "Kernel", fKernelSize.width() * fKernelSize.height());
- fTargetUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
- kVec2f_GrSLType, "Target");
- fGainUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
- kFloat_GrSLType, "Gain");
- fBiasUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
- kFloat_GrSLType, "Bias");
-}
-
static void appendTextureLookup(GrGLShaderBuilder* builder,
const GrGLShaderBuilder::TextureSampler& sampler,
const char* coord,
@@ -360,10 +348,25 @@ static void appendTextureLookup(GrGLShaderBuilder* builder,
builder->appendTextureLookup(code, sampler, coord);
}
-void GrGLMatrixConvolutionEffect::emitFS(GrGLShaderBuilder* builder,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray& samplers) {
+void GrGLMatrixConvolutionEffect::emitCode(GrGLShaderBuilder* builder,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray& samplers) {
+
+ fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
+ kVec2f_GrSLType, "ImageIncrement");
+ fKernelUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_ShaderType,
+ kFloat_GrSLType, "Kernel", fKernelSize.width() * fKernelSize.height());
+ fTargetUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
+ kVec2f_GrSLType, "Target");
+ fGainUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
+ kFloat_GrSLType, "Gain");
+ fBiasUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
+ kFloat_GrSLType, "Bias");
+
SkString* code = &builder->fFSCode;
const char* target = builder->getUniformCStr(fTargetUni);
@@ -415,9 +418,9 @@ int encodeXY(int x, int y) {
};
-GrGLEffect::EffectKey GrGLMatrixConvolutionEffect::GenKey(const GrEffect& s,
- const GrGLCaps& caps) {
- const GrMatrixConvolutionEffect& m = static_cast<const GrMatrixConvolutionEffect&>(s);
+GrGLEffect::EffectKey GrGLMatrixConvolutionEffect::GenKey(const GrEffectStage& s, const GrGLCaps&) {
+ const GrMatrixConvolutionEffect& m =
+ static_cast<const GrMatrixConvolutionEffect&>(*s.getEffect());
EffectKey key = encodeXY(m.kernelSize().width(), m.kernelSize().height());
key |= m.tileMode() << 7;
key |= m.convolveAlpha() ? 1 << 9 : 0;
@@ -425,11 +428,10 @@ GrGLEffect::EffectKey GrGLMatrixConvolutionEffect::GenKey(const GrEffect& s,
}
void GrGLMatrixConvolutionEffect::setData(const GrGLUniformManager& uman,
- const GrEffect& data) {
+ const GrEffectStage& stage) {
const GrMatrixConvolutionEffect& effect =
- static_cast<const GrMatrixConvolutionEffect&>(data);
- GrGLTexture& texture =
- *static_cast<GrGLTexture*>(data.texture(0));
+ static_cast<const GrMatrixConvolutionEffect&>(*stage.getEffect());
+ GrTexture& texture = *effect.texture(0);
// the code we generated was for a specific kernel size
GrAssert(effect.kernelSize() == fKernelSize);
GrAssert(effect.tileMode() == fTileMode);
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
index 3273798b9d..0e6a3186a2 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -13,7 +13,7 @@
#if SK_SUPPORT_GPU
#include "GrContext.h"
#include "GrTexture.h"
-#include "GrGpu.h"
+#include "GrTBackendEffectFactory.h"
#include "gl/GrGLEffect.h"
#include "effects/Gr1DKernelEffect.h"
#endif
@@ -266,22 +266,22 @@ private:
///////////////////////////////////////////////////////////////////////////////
-class GrGLMorphologyEffect : public GrGLLegacyEffect {
+class GrGLMorphologyEffect : public GrGLEffect {
public:
GrGLMorphologyEffect (const GrBackendEffectFactory& factory,
const GrEffect& effect);
- virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE;
- virtual void emitVS(GrGLShaderBuilder* state,
- const char* vertexCoords) SK_OVERRIDE {};
- virtual void emitFS(GrGLShaderBuilder* state,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray&) SK_OVERRIDE;
+ virtual void emitCode(GrGLShaderBuilder*,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray&) SK_OVERRIDE;
- static inline EffectKey GenKey(const GrEffect& s, const GrGLCaps& caps);
+ static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&);
- virtual void setData(const GrGLUniformManager&, const GrEffect&) SK_OVERRIDE;
+ virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE;
private:
int width() const { return GrMorphologyEffect::WidthFromRadius(fRadius); }
@@ -290,7 +290,7 @@ private:
GrMorphologyEffect::MorphologyType fType;
GrGLUniformManager::UniformHandle fImageIncrementUni;
- typedef GrGLLegacyEffect INHERITED;
+ typedef GrGLEffect INHERITED;
};
GrGLMorphologyEffect::GrGLMorphologyEffect(const GrBackendEffectFactory& factory,
@@ -302,15 +302,16 @@ GrGLMorphologyEffect::GrGLMorphologyEffect(const GrBackendEffectFactory& factory
fType = m.type();
}
-void GrGLMorphologyEffect::setupVariables(GrGLShaderBuilder* builder) {
+void GrGLMorphologyEffect::emitCode(GrGLShaderBuilder* builder,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray& samplers) {
fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
kVec2f_GrSLType, "ImageIncrement");
-}
-void GrGLMorphologyEffect::emitFS(GrGLShaderBuilder* builder,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray& samplers) {
SkString* code = &builder->fFSCode;
const char* func;
@@ -341,19 +342,16 @@ void GrGLMorphologyEffect::emitFS(GrGLShaderBuilder* builder,
GrGLSLMulVarBy4f(code, 2, outputColor, inputColor);
}
-GrGLEffect::EffectKey GrGLMorphologyEffect::GenKey(const GrEffect& s,
- const GrGLCaps& caps) {
- const GrMorphologyEffect& m = static_cast<const GrMorphologyEffect&>(s);
+GrGLEffect::EffectKey GrGLMorphologyEffect::GenKey(const GrEffectStage& s, const GrGLCaps&) {
+ const GrMorphologyEffect& m = static_cast<const GrMorphologyEffect&>(*s.getEffect());
EffectKey key = static_cast<EffectKey>(m.radius());
key |= (m.type() << 8);
return key;
}
-void GrGLMorphologyEffect::setData(const GrGLUniformManager& uman, const GrEffect& data) {
- const Gr1DKernelEffect& kern =
- static_cast<const Gr1DKernelEffect&>(data);
- GrGLTexture& texture =
- *static_cast<GrGLTexture*>(data.texture(0));
+void GrGLMorphologyEffect::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
+ const Gr1DKernelEffect& kern = static_cast<const Gr1DKernelEffect&>(*stage.getEffect());
+ GrTexture& texture = *kern.texture(0);
// the code we generated was for a specific kernel radius
GrAssert(kern.radius() == fRadius);
float imageIncrement[2] = { 0 };
diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp
index 16678c49cc..0ae7e1950b 100644
--- a/src/effects/SkTableColorFilter.cpp
+++ b/src/effects/SkTableColorFilter.cpp
@@ -217,6 +217,7 @@ bool SkTable_ColorFilter::asComponentTable(SkBitmap* table) const {
#if SK_SUPPORT_GPU
#include "GrEffect.h"
+#include "GrTBackendEffectFactory.h"
#include "gl/GrGLEffect.h"
#include "SkGr.h"
@@ -244,26 +245,26 @@ private:
typedef GrEffect INHERITED;
};
-class GLColorTableEffect : public GrGLLegacyEffect {
+class GLColorTableEffect : public GrGLEffect {
public:
GLColorTableEffect(const GrBackendEffectFactory& factory,
const GrEffect& effect);
- virtual void setupVariables(GrGLShaderBuilder* state) SK_OVERRIDE {}
- virtual void emitVS(GrGLShaderBuilder* state,
- const char* vertexCoords) SK_OVERRIDE {}
- virtual void emitFS(GrGLShaderBuilder* state,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray&) SK_OVERRIDE;
+ virtual void emitCode(GrGLShaderBuilder*,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray&) SK_OVERRIDE;
- virtual void setData(const GrGLUniformManager&, const GrEffect&) SK_OVERRIDE {}
+ virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE {}
- static EffectKey GenKey(const GrEffect&, const GrGLCaps&);
+ static EffectKey GenKey(const GrEffectStage&, const GrGLCaps&);
private:
- typedef GrGLLegacyEffect INHERITED;
+ typedef GrGLEffect INHERITED;
};
GLColorTableEffect::GLColorTableEffect(
@@ -271,10 +272,14 @@ GLColorTableEffect::GLColorTableEffect(
: INHERITED(factory) {
}
-void GLColorTableEffect::emitFS(GrGLShaderBuilder* builder,
+void GLColorTableEffect::emitCode(GrGLShaderBuilder* builder,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
const char* outputColor,
const char* inputColor,
const TextureSamplerArray& samplers) {
+
static const float kColorScaleFactor = 255.0f / 256.0f;
static const float kColorOffsetFactor = 1.0f / 512.0f;
SkString* code = &builder->fFSCode;
@@ -312,8 +317,7 @@ void GLColorTableEffect::emitFS(GrGLShaderBuilder* builder,
code->appendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
}
-GrGLEffect::EffectKey GLColorTableEffect::GenKey(const GrEffect& s,
- const GrGLCaps& caps) {
+GrGLEffect::EffectKey GLColorTableEffect::GenKey(const GrEffectStage&, const GrGLCaps&) {
return 0;
}
diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp
index 3920026b75..60eff91d65 100644
--- a/src/effects/gradients/SkGradientShader.cpp
+++ b/src/effects/gradients/SkGradientShader.cpp
@@ -682,13 +682,13 @@ GrGLGradientEffect::GrGLGradientEffect(const GrBackendEffectFactory& factory)
GrGLGradientEffect::~GrGLGradientEffect() { }
-void GrGLGradientEffect::setupVariables(GrGLShaderBuilder* builder) {
+void GrGLGradientEffect::emitYCoordUniform(GrGLShaderBuilder* builder) {
fFSYUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
kFloat_GrSLType, "GradientYCoordFS");
}
-void GrGLGradientEffect::setData(const GrGLUniformManager& uman, const GrEffect& effect) {
- GrScalar yCoord = static_cast<const GrGradientEffect&>(effect).getYCoord();
+void GrGLGradientEffect::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
+ GrScalar yCoord = static_cast<const GrGradientEffect&>(*stage.getEffect()).getYCoord();
if (yCoord != fCachedYCoord) {
uman.set1f(fFSYUni, yCoord);
fCachedYCoord = yCoord;
diff --git a/src/effects/gradients/SkGradientShaderPriv.h b/src/effects/gradients/SkGradientShaderPriv.h
index 194ff8c6d8..9f14e7f727 100644
--- a/src/effects/gradients/SkGradientShaderPriv.h
+++ b/src/effects/gradients/SkGradientShaderPriv.h
@@ -271,17 +271,21 @@ private:
///////////////////////////////////////////////////////////////////////////////
// Base class for GL gradient effects
-class GrGLGradientEffect : public GrGLLegacyEffect {
+class GrGLGradientEffect : public GrGLEffect {
public:
-
GrGLGradientEffect(const GrBackendEffectFactory& factory);
virtual ~GrGLGradientEffect();
- virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE;
- virtual void setData(const GrGLUniformManager&, const GrEffect&) SK_OVERRIDE;
+ virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE;
+
+protected:
+ // Emits the uniform used as the y-coord to texture samples in derived classes. Subclasses
+ // should call this method from their emitCode().
+ void emitYCoordUniform(GrGLShaderBuilder* builder);
- // emit code that gets a fragment's color from an expression for t; for now
- // this always uses the texture, but for simpler cases we'll be able to lerp
+ // emit code that gets a fragment's color from an expression for t; for now this always uses the
+ // texture, but for simpler cases we'll be able to lerp. Subclasses should call this method from
+ // their emitCode().
void emitColorLookup(GrGLShaderBuilder* builder,
const char* gradientTValue,
const char* outputColor,
@@ -289,11 +293,10 @@ public:
const GrGLShaderBuilder::TextureSampler&);
private:
-
GrScalar fCachedYCoord;
GrGLUniformManager::UniformHandle fFSYUni;
- typedef GrGLLegacyEffect INHERITED;
+ typedef GrGLEffect INHERITED;
};
#endif
diff --git a/src/effects/gradients/SkLinearGradient.cpp b/src/effects/gradients/SkLinearGradient.cpp
index 61824a042e..524db76966 100644
--- a/src/effects/gradients/SkLinearGradient.cpp
+++ b/src/effects/gradients/SkLinearGradient.cpp
@@ -474,6 +474,8 @@ void SkLinearGradient::shadeSpan16(int x, int y,
#if SK_SUPPORT_GPU
+#include "GrTBackendEffectFactory.h"
+
/////////////////////////////////////////////////////////////////////
class GrGLLinearGradient : public GrGLGradientEffect {
@@ -485,13 +487,15 @@ public:
virtual ~GrGLLinearGradient() { }
- virtual void emitVS(GrGLShaderBuilder* builder,
- const char* vertexCoords) SK_OVERRIDE { }
- virtual void emitFS(GrGLShaderBuilder* builder,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray&) SK_OVERRIDE;
- static EffectKey GenKey(const GrEffect& s, const GrGLCaps& caps) { return 0; }
+ virtual void emitCode(GrGLShaderBuilder*,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray&) SK_OVERRIDE;
+
+ static EffectKey GenKey(const GrEffectStage&, const GrGLCaps& caps) { return 0; }
private:
@@ -548,10 +552,14 @@ GrEffect* GrLinearGradient::TestCreate(SkRandom* random,
/////////////////////////////////////////////////////////////////////
-void GrGLLinearGradient::emitFS(GrGLShaderBuilder* builder,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray& samplers) {
+void GrGLLinearGradient::emitCode(GrGLShaderBuilder* builder,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray& samplers) {
+ this->emitYCoordUniform(builder);
SkString t;
t.printf("%s.x", builder->defaultTexCoordsName());
this->emitColorLookup(builder, t.c_str(), outputColor, inputColor, samplers[0]);
diff --git a/src/effects/gradients/SkRadialGradient.cpp b/src/effects/gradients/SkRadialGradient.cpp
index 6b9a678df7..4766af604b 100644
--- a/src/effects/gradients/SkRadialGradient.cpp
+++ b/src/effects/gradients/SkRadialGradient.cpp
@@ -473,6 +473,8 @@ void SkRadialGradient::shadeSpan(int x, int y,
#if SK_SUPPORT_GPU
+#include "GrTBackendEffectFactory.h"
+
class GrGLRadialGradient : public GrGLGradientEffect {
public:
@@ -480,14 +482,15 @@ public:
const GrEffect&) : INHERITED (factory) { }
virtual ~GrGLRadialGradient() { }
- virtual void emitVS(GrGLShaderBuilder* builder,
- const char* vertexCoords) SK_OVERRIDE { }
- virtual void emitFS(GrGLShaderBuilder* builder,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray&) SK_OVERRIDE;
+ virtual void emitCode(GrGLShaderBuilder*,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray&) SK_OVERRIDE;
- static EffectKey GenKey(const GrEffect& s, const GrGLCaps& caps) { return 0; }
+ static EffectKey GenKey(const GrEffectStage&, const GrGLCaps& caps) { return 0; }
private:
@@ -547,10 +550,14 @@ GrEffect* GrRadialGradient::TestCreate(SkRandom* random,
/////////////////////////////////////////////////////////////////////
-void GrGLRadialGradient::emitFS(GrGLShaderBuilder* builder,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray& samplers) {
+void GrGLRadialGradient::emitCode(GrGLShaderBuilder* builder,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray& samplers) {
+ this->emitYCoordUniform(builder);
SkString t;
t.printf("length(%s.xy)", builder->defaultTexCoordsName());
this->emitColorLookup(builder, t.c_str(), outputColor, inputColor, samplers[0]);
diff --git a/src/effects/gradients/SkSweepGradient.cpp b/src/effects/gradients/SkSweepGradient.cpp
index c606bbaca6..b64e15d0c1 100644
--- a/src/effects/gradients/SkSweepGradient.cpp
+++ b/src/effects/gradients/SkSweepGradient.cpp
@@ -382,6 +382,8 @@ void SkSweepGradient::shadeSpan16(int x, int y, uint16_t* SK_RESTRICT dstC,
#if SK_SUPPORT_GPU
+#include "GrTBackendEffectFactory.h"
+
class GrGLSweepGradient : public GrGLGradientEffect {
public:
@@ -389,14 +391,15 @@ public:
const GrEffect&) : INHERITED (factory) { }
virtual ~GrGLSweepGradient() { }
- virtual void emitVS(GrGLShaderBuilder* builder,
- const char* vertexCoords) SK_OVERRIDE { }
- virtual void emitFS(GrGLShaderBuilder* builder,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray&) SK_OVERRIDE;
+ virtual void emitCode(GrGLShaderBuilder*,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray&) SK_OVERRIDE;
- static EffectKey GenKey(const GrEffect& s, const GrGLCaps& caps) { return 0; }
+ static EffectKey GenKey(const GrEffectStage&, const GrGLCaps& caps) { return 0; }
private:
@@ -453,10 +456,14 @@ GrEffect* GrSweepGradient::TestCreate(SkRandom* random,
/////////////////////////////////////////////////////////////////////
-void GrGLSweepGradient::emitFS(GrGLShaderBuilder* builder,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray& samplers) {
+void GrGLSweepGradient::emitCode(GrGLShaderBuilder* builder,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray& samplers) {
+ this->emitYCoordUniform(builder);
SkString t;
t.printf("atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5",
builder->defaultTexCoordsName(), builder->defaultTexCoordsName());
diff --git a/src/effects/gradients/SkTwoPointConicalGradient.cpp b/src/effects/gradients/SkTwoPointConicalGradient.cpp
index 3c4560c909..acd0eeedfb 100644
--- a/src/effects/gradients/SkTwoPointConicalGradient.cpp
+++ b/src/effects/gradients/SkTwoPointConicalGradient.cpp
@@ -315,6 +315,8 @@ void SkTwoPointConicalGradient::flatten(
#if SK_SUPPORT_GPU
+#include "GrTBackendEffectFactory.h"
+
// For brevity
typedef GrGLUniformManager::UniformHandle UniformHandle;
static const UniformHandle kInvalidUniformHandle = GrGLUniformManager::kInvalidUniformHandle;
@@ -326,16 +328,16 @@ public:
const GrEffect&);
virtual ~GrGLConical2Gradient() { }
- virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE;
- virtual void emitVS(GrGLShaderBuilder* builder,
- const char* vertexCoords) SK_OVERRIDE;
- virtual void emitFS(GrGLShaderBuilder* builder,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray&) SK_OVERRIDE;
- virtual void setData(const GrGLUniformManager&, const GrEffect&) SK_OVERRIDE;
+ virtual void emitCode(GrGLShaderBuilder*,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray&) SK_OVERRIDE;
+ virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE;
- static EffectKey GenKey(const GrEffect& s, const GrGLCaps& caps);
+ static EffectKey GenKey(const GrEffectStage&, const GrGLCaps& caps);
protected:
@@ -465,8 +467,14 @@ GrGLConical2Gradient::GrGLConical2Gradient(
fIsDegenerate = data.isDegenerate();
}
-void GrGLConical2Gradient::setupVariables(GrGLShaderBuilder* builder) {
- INHERITED::setupVariables(builder);
+void GrGLConical2Gradient::emitCode(GrGLShaderBuilder* builder,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray& samplers) {
+ this->emitYCoordUniform(builder);
// 2 copies of uniform array, 1 for each of vertex & fragment shader,
// to work around Xoom bug. Doesn't seem to cause performance decrease
// in test apps, but need to keep an eye on it.
@@ -481,155 +489,152 @@ void GrGLConical2Gradient::setupVariables(GrGLShaderBuilder* builder) {
builder->addVarying(kFloat_GrSLType, "Conical2BCoeff",
&fVSVaryingName, &fFSVaryingName);
}
-}
-
-void GrGLConical2Gradient::emitVS(GrGLShaderBuilder* builder,
- const char* vertexCoords) {
- SkString* code = &builder->fVSCode;
- SkString p2; // distance between centers
- SkString p3; // start radius
- SkString p5; // difference in radii (r1 - r0)
- builder->getUniformVariable(fVSParamUni).appendArrayAccess(2, &p2);
- builder->getUniformVariable(fVSParamUni).appendArrayAccess(3, &p3);
- builder->getUniformVariable(fVSParamUni).appendArrayAccess(5, &p5);
- // For radial gradients without perspective we can pass the linear
- // part of the quadratic as a varying.
- if (!builder->defaultTextureMatrixIsPerspective()) {
- // r2Var = -2 * (r2Parm[2] * varCoord.x - r2Param[3] * r2Param[5])
- code->appendf("\t%s = -2.0 * (%s * %s.x + %s * %s);\n",
- fVSVaryingName, p2.c_str(),
- vertexCoords, p3.c_str(), p5.c_str());
+ // VS
+ {
+ SkString* code = &builder->fVSCode;
+ SkString p2; // distance between centers
+ SkString p3; // start radius
+ SkString p5; // difference in radii (r1 - r0)
+ builder->getUniformVariable(fVSParamUni).appendArrayAccess(2, &p2);
+ builder->getUniformVariable(fVSParamUni).appendArrayAccess(3, &p3);
+ builder->getUniformVariable(fVSParamUni).appendArrayAccess(5, &p5);
+
+ // For radial gradients without perspective we can pass the linear
+ // part of the quadratic as a varying.
+ if (!builder->defaultTextureMatrixIsPerspective()) {
+ // r2Var = -2 * (r2Parm[2] * varCoord.x - r2Param[3] * r2Param[5])
+ code->appendf("\t%s = -2.0 * (%s * %s.x + %s * %s);\n",
+ fVSVaryingName, p2.c_str(),
+ vertexCoords, p3.c_str(), p5.c_str());
+ }
}
-}
-void GrGLConical2Gradient::emitFS(GrGLShaderBuilder* builder,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray& samplers) {
- SkString* code = &builder->fFSCode;
-
- SkString cName("c");
- SkString ac4Name("ac4");
- SkString dName("d");
- SkString qName("q");
- SkString r0Name("r0");
- SkString r1Name("r1");
- SkString tName("t");
- SkString p0; // 4a
- SkString p1; // 1/a
- SkString p2; // distance between centers
- SkString p3; // start radius
- SkString p4; // start radius squared
- SkString p5; // difference in radii (r1 - r0)
-
- builder->getUniformVariable(fFSParamUni).appendArrayAccess(0, &p0);
- builder->getUniformVariable(fFSParamUni).appendArrayAccess(1, &p1);
- builder->getUniformVariable(fFSParamUni).appendArrayAccess(2, &p2);
- builder->getUniformVariable(fFSParamUni).appendArrayAccess(3, &p3);
- builder->getUniformVariable(fFSParamUni).appendArrayAccess(4, &p4);
- builder->getUniformVariable(fFSParamUni).appendArrayAccess(5, &p5);
-
- // If we we're able to interpolate the linear component,
- // bVar is the varying; otherwise compute it
- SkString bVar;
- if (!builder->defaultTextureMatrixIsPerspective()) {
- bVar = fFSVaryingName;
- } else {
- bVar = "b";
- code->appendf("\tfloat %s = -2.0 * (%s * %s.x + %s * %s);\n",
- bVar.c_str(), p2.c_str(), builder->defaultTexCoordsName(),
- p3.c_str(), p5.c_str());
- }
+ // FS
+ {
+ SkString* code = &builder->fFSCode;
+
+ SkString cName("c");
+ SkString ac4Name("ac4");
+ SkString dName("d");
+ SkString qName("q");
+ SkString r0Name("r0");
+ SkString r1Name("r1");
+ SkString tName("t");
+ SkString p0; // 4a
+ SkString p1; // 1/a
+ SkString p2; // distance between centers
+ SkString p3; // start radius
+ SkString p4; // start radius squared
+ SkString p5; // difference in radii (r1 - r0)
+
+ builder->getUniformVariable(fFSParamUni).appendArrayAccess(0, &p0);
+ builder->getUniformVariable(fFSParamUni).appendArrayAccess(1, &p1);
+ builder->getUniformVariable(fFSParamUni).appendArrayAccess(2, &p2);
+ builder->getUniformVariable(fFSParamUni).appendArrayAccess(3, &p3);
+ builder->getUniformVariable(fFSParamUni).appendArrayAccess(4, &p4);
+ builder->getUniformVariable(fFSParamUni).appendArrayAccess(5, &p5);
+
+ // If we we're able to interpolate the linear component,
+ // bVar is the varying; otherwise compute it
+ SkString bVar;
+ if (!builder->defaultTextureMatrixIsPerspective()) {
+ bVar = fFSVaryingName;
+ } else {
+ bVar = "b";
+ code->appendf("\tfloat %s = -2.0 * (%s * %s.x + %s * %s);\n",
+ bVar.c_str(), p2.c_str(), builder->defaultTexCoordsName(),
+ p3.c_str(), p5.c_str());
+ }
- // output will default to transparent black (we simply won't write anything
- // else to it if invalid, instead of discarding or returning prematurely)
- code->appendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", outputColor);
-
- // c = (x^2)+(y^2) - params[4]
- code->appendf("\tfloat %s = dot(%s, %s) - %s;\n", cName.c_str(),
- builder->defaultTexCoordsName(), builder->defaultTexCoordsName(),
- p4.c_str());
-
- // Non-degenerate case (quadratic)
- if (!fIsDegenerate) {
-
- // ac4 = params[0] * c
- code->appendf("\tfloat %s = %s * %s;\n", ac4Name.c_str(), p0.c_str(),
- cName.c_str());
-
- // d = b^2 - ac4
- code->appendf("\tfloat %s = %s * %s - %s;\n", dName.c_str(),
- bVar.c_str(), bVar.c_str(), ac4Name.c_str());
-
- // only proceed if discriminant is >= 0
- code->appendf("\tif (%s >= 0.0) {\n", dName.c_str());
-
- // intermediate value we'll use to compute the roots
- // q = -0.5 * (b +/- sqrt(d))
- code->appendf("\t\tfloat %s = -0.5 * (%s + (%s < 0.0 ? -1.0 : 1.0)"
- " * sqrt(%s));\n", qName.c_str(), bVar.c_str(),
- bVar.c_str(), dName.c_str());
-
- // compute both roots
- // r0 = q * params[1]
- code->appendf("\t\tfloat %s = %s * %s;\n", r0Name.c_str(),
- qName.c_str(), p1.c_str());
- // r1 = c / q
- code->appendf("\t\tfloat %s = %s / %s;\n", r1Name.c_str(),
- cName.c_str(), qName.c_str());
-
- // Note: If there are two roots that both generate radius(t) > 0, the
- // Canvas spec says to choose the larger t.
-
- // so we'll look at the larger one first:
- code->appendf("\t\tfloat %s = max(%s, %s);\n", tName.c_str(),
- r0Name.c_str(), r1Name.c_str());
-
- // if r(t) > 0, then we're done; t will be our x coordinate
- code->appendf("\t\tif (%s * %s + %s > 0.0) {\n", tName.c_str(),
- p5.c_str(), p3.c_str());
-
- code->appendf("\t\t");
- this->emitColorLookup(builder, tName.c_str(), outputColor, inputColor, samplers[0]);
-
- // otherwise, if r(t) for the larger root was <= 0, try the other root
- code->appendf("\t\t} else {\n");
- code->appendf("\t\t\t%s = min(%s, %s);\n", tName.c_str(),
- r0Name.c_str(), r1Name.c_str());
-
- // if r(t) > 0 for the smaller root, then t will be our x coordinate
- code->appendf("\t\t\tif (%s * %s + %s > 0.0) {\n",
- tName.c_str(), p5.c_str(), p3.c_str());
-
- code->appendf("\t\t\t");
- this->emitColorLookup(builder, tName.c_str(), outputColor, inputColor, samplers[0]);
-
- // end if (r(t) > 0) for smaller root
- code->appendf("\t\t\t}\n");
- // end if (r(t) > 0), else, for larger root
- code->appendf("\t\t}\n");
- // end if (discriminant >= 0)
- code->appendf("\t}\n");
- } else {
+ // output will default to transparent black (we simply won't write anything
+ // else to it if invalid, instead of discarding or returning prematurely)
+ code->appendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", outputColor);
+
+ // c = (x^2)+(y^2) - params[4]
+ code->appendf("\tfloat %s = dot(%s, %s) - %s;\n", cName.c_str(),
+ builder->defaultTexCoordsName(), builder->defaultTexCoordsName(),
+ p4.c_str());
+
+ // Non-degenerate case (quadratic)
+ if (!fIsDegenerate) {
+
+ // ac4 = params[0] * c
+ code->appendf("\tfloat %s = %s * %s;\n", ac4Name.c_str(), p0.c_str(),
+ cName.c_str());
+
+ // d = b^2 - ac4
+ code->appendf("\tfloat %s = %s * %s - %s;\n", dName.c_str(),
+ bVar.c_str(), bVar.c_str(), ac4Name.c_str());
+
+ // only proceed if discriminant is >= 0
+ code->appendf("\tif (%s >= 0.0) {\n", dName.c_str());
+
+ // intermediate value we'll use to compute the roots
+ // q = -0.5 * (b +/- sqrt(d))
+ code->appendf("\t\tfloat %s = -0.5 * (%s + (%s < 0.0 ? -1.0 : 1.0)"
+ " * sqrt(%s));\n", qName.c_str(), bVar.c_str(),
+ bVar.c_str(), dName.c_str());
+
+ // compute both roots
+ // r0 = q * params[1]
+ code->appendf("\t\tfloat %s = %s * %s;\n", r0Name.c_str(),
+ qName.c_str(), p1.c_str());
+ // r1 = c / q
+ code->appendf("\t\tfloat %s = %s / %s;\n", r1Name.c_str(),
+ cName.c_str(), qName.c_str());
+
+ // Note: If there are two roots that both generate radius(t) > 0, the
+ // Canvas spec says to choose the larger t.
+
+ // so we'll look at the larger one first:
+ code->appendf("\t\tfloat %s = max(%s, %s);\n", tName.c_str(),
+ r0Name.c_str(), r1Name.c_str());
+
+ // if r(t) > 0, then we're done; t will be our x coordinate
+ code->appendf("\t\tif (%s * %s + %s > 0.0) {\n", tName.c_str(),
+ p5.c_str(), p3.c_str());
+
+ code->appendf("\t\t");
+ this->emitColorLookup(builder, tName.c_str(), outputColor, inputColor, samplers[0]);
+
+ // otherwise, if r(t) for the larger root was <= 0, try the other root
+ code->appendf("\t\t} else {\n");
+ code->appendf("\t\t\t%s = min(%s, %s);\n", tName.c_str(),
+ r0Name.c_str(), r1Name.c_str());
+
+ // if r(t) > 0 for the smaller root, then t will be our x coordinate
+ code->appendf("\t\t\tif (%s * %s + %s > 0.0) {\n",
+ tName.c_str(), p5.c_str(), p3.c_str());
+
+ code->appendf("\t\t\t");
+ this->emitColorLookup(builder, tName.c_str(), outputColor, inputColor, samplers[0]);
+
+ // end if (r(t) > 0) for smaller root
+ code->appendf("\t\t\t}\n");
+ // end if (r(t) > 0), else, for larger root
+ code->appendf("\t\t}\n");
+ // end if (discriminant >= 0)
+ code->appendf("\t}\n");
+ } else {
- // linear case: t = -c/b
- code->appendf("\tfloat %s = -(%s / %s);\n", tName.c_str(),
- cName.c_str(), bVar.c_str());
+ // linear case: t = -c/b
+ code->appendf("\tfloat %s = -(%s / %s);\n", tName.c_str(),
+ cName.c_str(), bVar.c_str());
- // if r(t) > 0, then t will be the x coordinate
- code->appendf("\tif (%s * %s + %s > 0.0) {\n", tName.c_str(),
- p5.c_str(), p3.c_str());
- code->appendf("\t");
- this->emitColorLookup(builder, tName.c_str(), outputColor, inputColor, samplers[0]);
- code->appendf("\t}\n");
+ // if r(t) > 0, then t will be the x coordinate
+ code->appendf("\tif (%s * %s + %s > 0.0) {\n", tName.c_str(),
+ p5.c_str(), p3.c_str());
+ code->appendf("\t");
+ this->emitColorLookup(builder, tName.c_str(), outputColor, inputColor, samplers[0]);
+ code->appendf("\t}\n");
+ }
}
}
-void GrGLConical2Gradient::setData(const GrGLUniformManager& uman, const GrEffect& baseData) {
- INHERITED::setData(uman, baseData);
- const GrConical2Gradient& data =
- static_cast<const GrConical2Gradient&>(baseData);
+void GrGLConical2Gradient::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
+ INHERITED::setData(uman, stage);
+ const GrConical2Gradient& data = static_cast<const GrConical2Gradient&>(*stage.getEffect());
GrAssert(data.isDegenerate() == fIsDegenerate);
GrScalar centerX1 = data.center();
GrScalar radius0 = data.radius();
@@ -663,8 +668,8 @@ void GrGLConical2Gradient::setData(const GrGLUniformManager& uman, const GrEffec
}
}
-GrEffect::EffectKey GrGLConical2Gradient::GenKey(const GrEffect& s, const GrGLCaps& caps) {
- return (static_cast<const GrConical2Gradient&>(s).isDegenerate());
+GrGLEffect::EffectKey GrGLConical2Gradient::GenKey(const GrEffectStage& s, const GrGLCaps&) {
+ return (static_cast<const GrConical2Gradient&>(*s.getEffect()).isDegenerate());
}
/////////////////////////////////////////////////////////////////////
diff --git a/src/effects/gradients/SkTwoPointRadialGradient.cpp b/src/effects/gradients/SkTwoPointRadialGradient.cpp
index b37b568ad7..9357b11685 100644
--- a/src/effects/gradients/SkTwoPointRadialGradient.cpp
+++ b/src/effects/gradients/SkTwoPointRadialGradient.cpp
@@ -349,6 +349,8 @@ void SkTwoPointRadialGradient::init() {
#if SK_SUPPORT_GPU
+#include "GrTBackendEffectFactory.h"
+
// For brevity
typedef GrGLUniformManager::UniformHandle UniformHandle;
static const UniformHandle kInvalidUniformHandle = GrGLUniformManager::kInvalidUniformHandle;
@@ -361,16 +363,16 @@ public:
const GrEffect&);
virtual ~GrGLRadial2Gradient() { }
- virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE;
- virtual void emitVS(GrGLShaderBuilder* builder,
- const char* vertexCoords) SK_OVERRIDE;
- virtual void emitFS(GrGLShaderBuilder* builder,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray&) SK_OVERRIDE;
- virtual void setData(const GrGLUniformManager&, const GrEffect&) SK_OVERRIDE;
+ virtual void emitCode(GrGLShaderBuilder*,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray&) SK_OVERRIDE;
+ virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE;
- static EffectKey GenKey(const GrEffect& s, const GrGLCaps& caps);
+ static EffectKey GenKey(const GrEffectStage&, const GrGLCaps& caps);
protected:
@@ -498,8 +500,15 @@ GrGLRadial2Gradient::GrGLRadial2Gradient(
fIsDegenerate = data.isDegenerate();
}
-void GrGLRadial2Gradient::setupVariables(GrGLShaderBuilder* builder) {
- INHERITED::setupVariables(builder);
+void GrGLRadial2Gradient::emitCode(GrGLShaderBuilder* builder,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray& samplers) {
+
+ this->emitYCoordUniform(builder);
// 2 copies of uniform array, 1 for each of vertex & fragment shader,
// to work around Xoom bug. Doesn't seem to cause performance decrease
// in test apps, but need to keep an eye on it.
@@ -514,97 +523,94 @@ void GrGLRadial2Gradient::setupVariables(GrGLShaderBuilder* builder) {
builder->addVarying(kFloat_GrSLType, "Radial2BCoeff",
&fVSVaryingName, &fFSVaryingName);
}
-}
-void GrGLRadial2Gradient::emitVS(GrGLShaderBuilder* builder,
- const char* vertexCoords) {
- SkString* code = &builder->fVSCode;
- SkString p2;
- SkString p3;
- builder->getUniformVariable(fVSParamUni).appendArrayAccess(2, &p2);
- builder->getUniformVariable(fVSParamUni).appendArrayAccess(3, &p3);
-
- // For radial gradients without perspective we can pass the linear
- // part of the quadratic as a varying.
- if (!builder->defaultTextureMatrixIsPerspective()) {
- // r2Var = 2 * (r2Parm[2] * varCoord.x - r2Param[3])
- code->appendf("\t%s = 2.0 *(%s * %s.x - %s);\n",
- fVSVaryingName, p2.c_str(),
- vertexCoords, p3.c_str());
+ // VS
+ {
+ SkString* code = &builder->fVSCode;
+ SkString p2;
+ SkString p3;
+ builder->getUniformVariable(fVSParamUni).appendArrayAccess(2, &p2);
+ builder->getUniformVariable(fVSParamUni).appendArrayAccess(3, &p3);
+
+ // For radial gradients without perspective we can pass the linear
+ // part of the quadratic as a varying.
+ if (!builder->defaultTextureMatrixIsPerspective()) {
+ // r2Var = 2 * (r2Parm[2] * varCoord.x - r2Param[3])
+ code->appendf("\t%s = 2.0 *(%s * %s.x - %s);\n",
+ fVSVaryingName, p2.c_str(),
+ vertexCoords, p3.c_str());
+ }
}
-}
-void GrGLRadial2Gradient::emitFS(GrGLShaderBuilder* builder,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray& samplers) {
- SkString* code = &builder->fFSCode;
- SkString cName("c");
- SkString ac4Name("ac4");
- SkString rootName("root");
- SkString t;
- SkString p0;
- SkString p1;
- SkString p2;
- SkString p3;
- SkString p4;
- SkString p5;
- builder->getUniformVariable(fFSParamUni).appendArrayAccess(0, &p0);
- builder->getUniformVariable(fFSParamUni).appendArrayAccess(1, &p1);
- builder->getUniformVariable(fFSParamUni).appendArrayAccess(2, &p2);
- builder->getUniformVariable(fFSParamUni).appendArrayAccess(3, &p3);
- builder->getUniformVariable(fFSParamUni).appendArrayAccess(4, &p4);
- builder->getUniformVariable(fFSParamUni).appendArrayAccess(5, &p5);
-
- // If we we're able to interpolate the linear component,
- // bVar is the varying; otherwise compute it
- SkString bVar;
- if (!builder->defaultTextureMatrixIsPerspective()) {
- bVar = fFSVaryingName;
- } else {
- bVar = "b";
- code->appendf("\tfloat %s = 2.0 * (%s * %s.x - %s);\n",
- bVar.c_str(), p2.c_str(),
- builder->defaultTexCoordsName(), p3.c_str());
- }
+ // FS
+ {
+ SkString* code = &builder->fFSCode;
+ SkString cName("c");
+ SkString ac4Name("ac4");
+ SkString rootName("root");
+ SkString t;
+ SkString p0;
+ SkString p1;
+ SkString p2;
+ SkString p3;
+ SkString p4;
+ SkString p5;
+ builder->getUniformVariable(fFSParamUni).appendArrayAccess(0, &p0);
+ builder->getUniformVariable(fFSParamUni).appendArrayAccess(1, &p1);
+ builder->getUniformVariable(fFSParamUni).appendArrayAccess(2, &p2);
+ builder->getUniformVariable(fFSParamUni).appendArrayAccess(3, &p3);
+ builder->getUniformVariable(fFSParamUni).appendArrayAccess(4, &p4);
+ builder->getUniformVariable(fFSParamUni).appendArrayAccess(5, &p5);
+
+ // If we we're able to interpolate the linear component,
+ // bVar is the varying; otherwise compute it
+ SkString bVar;
+ if (!builder->defaultTextureMatrixIsPerspective()) {
+ bVar = fFSVaryingName;
+ } else {
+ bVar = "b";
+ code->appendf("\tfloat %s = 2.0 * (%s * %s.x - %s);\n",
+ bVar.c_str(), p2.c_str(),
+ builder->defaultTexCoordsName(), p3.c_str());
+ }
- // c = (x^2)+(y^2) - params[4]
- code->appendf("\tfloat %s = dot(%s, %s) - %s;\n",
- cName.c_str(),
- builder->defaultTexCoordsName(),
- builder->defaultTexCoordsName(),
- p4.c_str());
-
- // If we aren't degenerate, emit some extra code, and accept a slightly
- // more complex coord.
- if (!fIsDegenerate) {
-
- // ac4 = 4.0 * params[0] * c
- code->appendf("\tfloat %s = %s * 4.0 * %s;\n",
- ac4Name.c_str(), p0.c_str(),
- cName.c_str());
-
- // root = sqrt(b^2-4ac)
- // (abs to avoid exception due to fp precision)
- code->appendf("\tfloat %s = sqrt(abs(%s*%s - %s));\n",
- rootName.c_str(), bVar.c_str(), bVar.c_str(),
- ac4Name.c_str());
-
- // t is: (-b + params[5] * sqrt(b^2-4ac)) * params[1]
- t.printf("(-%s + %s * %s) * %s", bVar.c_str(), p5.c_str(),
- rootName.c_str(), p1.c_str());
- } else {
- // t is: -c/b
- t.printf("-%s / %s", cName.c_str(), bVar.c_str());
- }
+ // c = (x^2)+(y^2) - params[4]
+ code->appendf("\tfloat %s = dot(%s, %s) - %s;\n",
+ cName.c_str(),
+ builder->defaultTexCoordsName(),
+ builder->defaultTexCoordsName(),
+ p4.c_str());
+
+ // If we aren't degenerate, emit some extra code, and accept a slightly
+ // more complex coord.
+ if (!fIsDegenerate) {
+
+ // ac4 = 4.0 * params[0] * c
+ code->appendf("\tfloat %s = %s * 4.0 * %s;\n",
+ ac4Name.c_str(), p0.c_str(),
+ cName.c_str());
+
+ // root = sqrt(b^2-4ac)
+ // (abs to avoid exception due to fp precision)
+ code->appendf("\tfloat %s = sqrt(abs(%s*%s - %s));\n",
+ rootName.c_str(), bVar.c_str(), bVar.c_str(),
+ ac4Name.c_str());
+
+ // t is: (-b + params[5] * sqrt(b^2-4ac)) * params[1]
+ t.printf("(-%s + %s * %s) * %s", bVar.c_str(), p5.c_str(),
+ rootName.c_str(), p1.c_str());
+ } else {
+ // t is: -c/b
+ t.printf("-%s / %s", cName.c_str(), bVar.c_str());
+ }
- this->emitColorLookup(builder, t.c_str(), outputColor, inputColor, samplers[0]);
+ this->emitColorLookup(builder, t.c_str(), outputColor, inputColor, samplers[0]);
+ }
}
-void GrGLRadial2Gradient::setData(const GrGLUniformManager& uman, const GrEffect& baseData) {
- INHERITED::setData(uman, baseData);
- const GrRadial2Gradient& data =
- static_cast<const GrRadial2Gradient&>(baseData);
+void GrGLRadial2Gradient::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
+ INHERITED::setData(uman, stage);
+ const GrRadial2Gradient& data = static_cast<const GrRadial2Gradient&>(*stage.getEffect());
GrAssert(data.isDegenerate() == fIsDegenerate);
GrScalar centerX1 = data.center();
GrScalar radius0 = data.radius();
@@ -636,8 +642,8 @@ void GrGLRadial2Gradient::setData(const GrGLUniformManager& uman, const GrEffect
}
}
-GrEffect::EffectKey GrGLRadial2Gradient::GenKey(const GrEffect& s, const GrGLCaps& caps) {
- return (static_cast<const GrRadial2Gradient&>(s).isDegenerate());
+GrGLEffect::EffectKey GrGLRadial2Gradient::GenKey(const GrEffectStage& s, const GrGLCaps&) {
+ return (static_cast<const GrRadial2Gradient&>(*s.getEffect()).isDegenerate());
}
/////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
index 54372ce836..3c6c3a371a 100644
--- a/src/gpu/GrDrawState.h
+++ b/src/gpu/GrDrawState.h
@@ -8,6 +8,7 @@
#ifndef GrDrawState_DEFINED
#define GrDrawState_DEFINED
+#include "GrBackendEffectFactory.h"
#include "GrColor.h"
#include "GrMatrix.h"
#include "GrRefCnt.h"
diff --git a/src/gpu/GrEffect.cpp b/src/gpu/GrEffect.cpp
index 6423aef5dc..09032bf0f9 100644
--- a/src/gpu/GrEffect.cpp
+++ b/src/gpu/GrEffect.cpp
@@ -5,8 +5,9 @@
* found in the LICENSE file.
*/
-#include "GrContext.h"
#include "GrEffect.h"
+#include "GrBackendEffectFactory.h"
+#include "GrContext.h"
#include "GrMemoryPool.h"
#include "SkTLS.h"
@@ -49,6 +50,11 @@ bool GrEffect::isOpaque(bool inputTextureIsOpaque) const {
return false;
}
+const char* GrEffect::name() const {
+ return this->getFactory().name();
+}
+
+
bool GrEffect::isEqual(const GrEffect& s) const {
if (this->numTextures() != s.numTextures()) {
return false;
diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp
index cb4cb24a02..086064545e 100644
--- a/src/gpu/effects/GrConfigConversionEffect.cpp
+++ b/src/gpu/effects/GrConfigConversionEffect.cpp
@@ -6,9 +6,10 @@
*/
#include "GrConfigConversionEffect.h"
+#include "GrTBackendEffectFactory.h"
#include "gl/GrGLEffect.h"
-class GrGLConfigConversionEffect : public GrGLLegacyEffect {
+class GrGLConfigConversionEffect : public GrGLEffect {
public:
GrGLConfigConversionEffect(const GrBackendEffectFactory& factory,
const GrEffect& s) : INHERITED (factory) {
@@ -17,12 +18,13 @@ public:
fPMConversion = effect.pmConversion();
}
- virtual void emitVS(GrGLShaderBuilder* builder,
- const char* vertexCoords) SK_OVERRIDE { }
- virtual void emitFS(GrGLShaderBuilder* builder,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray& samplers) SK_OVERRIDE {
+ virtual void emitCode(GrGLShaderBuilder* builder,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray& samplers) SK_OVERRIDE {
builder->fFSCode.appendf("\t\t%s = ", outputColor);
builder->appendTextureLookup(&builder->fFSCode, samplers[0]);
builder->fFSCode.append(";\n");
@@ -58,8 +60,9 @@ public:
GrGLSLMulVarBy4f(&builder->fFSCode, 2, outputColor, inputColor);
}
- static inline EffectKey GenKey(const GrEffect& s, const GrGLCaps&) {
- const GrConfigConversionEffect& effect = static_cast<const GrConfigConversionEffect&>(s);
+ static inline EffectKey GenKey(const GrEffectStage& s, const GrGLCaps&) {
+ const GrConfigConversionEffect& effect =
+ static_cast<const GrConfigConversionEffect&>(*s.getEffect());
return static_cast<int>(effect.swapsRedAndBlue()) | (effect.pmConversion() << 1);
}
@@ -67,7 +70,7 @@ private:
bool fSwapRedAndBlue;
GrConfigConversionEffect::PMConversion fPMConversion;
- typedef GrGLLegacyEffect INHERITED;
+ typedef GrGLEffect INHERITED;
};
diff --git a/src/gpu/effects/GrConvolutionEffect.cpp b/src/gpu/effects/GrConvolutionEffect.cpp
index 6930bec34c..d0d9f5d68b 100644
--- a/src/gpu/effects/GrConvolutionEffect.cpp
+++ b/src/gpu/effects/GrConvolutionEffect.cpp
@@ -9,27 +9,27 @@
#include "gl/GrGLEffect.h"
#include "gl/GrGLSL.h"
#include "gl/GrGLTexture.h"
-#include "GrBackendEffectFactory.h"
+#include "GrTBackendEffectFactory.h"
// For brevity
typedef GrGLUniformManager::UniformHandle UniformHandle;
static const UniformHandle kInvalidUniformHandle = GrGLUniformManager::kInvalidUniformHandle;
-class GrGLConvolutionEffect : public GrGLLegacyEffect {
+class GrGLConvolutionEffect : public GrGLEffect {
public:
GrGLConvolutionEffect(const GrBackendEffectFactory&, const GrEffect&);
- virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE;
- virtual void emitVS(GrGLShaderBuilder* builder,
- const char* vertexCoords) SK_OVERRIDE {};
- virtual void emitFS(GrGLShaderBuilder* builder,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray&) SK_OVERRIDE;
+ virtual void emitCode(GrGLShaderBuilder*,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray&) SK_OVERRIDE;
- virtual void setData(const GrGLUniformManager& uman, const GrEffect&) SK_OVERRIDE;
+ virtual void setData(const GrGLUniformManager& uman, const GrEffectStage&) SK_OVERRIDE;
- static inline EffectKey GenKey(const GrEffect&, const GrGLCaps&);
+ static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&);
private:
int width() const { return Gr1DKernelEffect::WidthFromRadius(fRadius); }
@@ -38,7 +38,7 @@ private:
UniformHandle fKernelUni;
UniformHandle fImageIncrementUni;
- typedef GrGLLegacyEffect INHERITED;
+ typedef GrGLEffect INHERITED;
};
GrGLConvolutionEffect::GrGLConvolutionEffect(const GrBackendEffectFactory& factory,
@@ -51,17 +51,17 @@ GrGLConvolutionEffect::GrGLConvolutionEffect(const GrBackendEffectFactory& facto
fRadius = c.radius();
}
-void GrGLConvolutionEffect::setupVariables(GrGLShaderBuilder* builder) {
+void GrGLConvolutionEffect::emitCode(GrGLShaderBuilder* builder,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray& samplers) {
fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
kVec2f_GrSLType, "ImageIncrement");
fKernelUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_ShaderType,
kFloat_GrSLType, "Kernel", this->width());
-}
-
-void GrGLConvolutionEffect::emitFS(GrGLShaderBuilder* builder,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray& samplers) {
SkString* code = &builder->fFSCode;
code->appendf("\t\t%s = vec4(0, 0, 0, 0);\n", outputColor);
@@ -87,10 +87,9 @@ void GrGLConvolutionEffect::emitFS(GrGLShaderBuilder* builder,
GrGLSLMulVarBy4f(&builder->fFSCode, 2, outputColor, inputColor);
}
-void GrGLConvolutionEffect::setData(const GrGLUniformManager& uman, const GrEffect& data) {
- const GrConvolutionEffect& conv =
- static_cast<const GrConvolutionEffect&>(data);
- GrTexture& texture = *data.texture(0);
+void GrGLConvolutionEffect::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
+ const GrConvolutionEffect& conv = static_cast<const GrConvolutionEffect&>(*stage.getEffect());
+ GrTexture& texture = *conv.texture(0);
// the code we generated was for a specific kernel radius
GrAssert(conv.radius() == fRadius);
float imageIncrement[2] = { 0 };
@@ -108,9 +107,8 @@ void GrGLConvolutionEffect::setData(const GrGLUniformManager& uman, const GrEffe
uman.set1fv(fKernelUni, 0, this->width(), conv.kernel());
}
-GrGLEffect::EffectKey GrGLConvolutionEffect::GenKey(const GrEffect& s,
- const GrGLCaps& caps) {
- return static_cast<const GrConvolutionEffect&>(s).radius();
+GrGLEffect::EffectKey GrGLConvolutionEffect::GenKey(const GrEffectStage& s, const GrGLCaps&) {
+ return static_cast<const GrConvolutionEffect&>(*s.getEffect()).radius();
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/effects/GrSingleTextureEffect.cpp b/src/gpu/effects/GrSingleTextureEffect.cpp
index 844bff7693..8866153962 100644
--- a/src/gpu/effects/GrSingleTextureEffect.cpp
+++ b/src/gpu/effects/GrSingleTextureEffect.cpp
@@ -9,31 +9,33 @@
#include "gl/GrGLEffect.h"
#include "gl/GrGLSL.h"
#include "gl/GrGLTexture.h"
-#include "GrBackendEffectFactory.h"
+#include "GrTBackendEffectFactory.h"
#include "GrTexture.h"
-class GrGLSingleTextureEffect : public GrGLLegacyEffect {
+class GrGLSingleTextureEffect : public GrGLEffect {
public:
GrGLSingleTextureEffect(const GrBackendEffectFactory& factory, const GrEffect&)
: INHERITED (factory) {
}
- virtual void emitVS(GrGLShaderBuilder* builder,
- const char* vertexCoords) SK_OVERRIDE { }
- virtual void emitFS(GrGLShaderBuilder* builder,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray& samplers) SK_OVERRIDE {
+ virtual void emitCode(GrGLShaderBuilder* builder,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray& samplers) SK_OVERRIDE {
+
builder->fFSCode.appendf("\t%s = ", outputColor);
builder->appendTextureLookupAndModulate(&builder->fFSCode, inputColor, samplers[0]);
builder->fFSCode.append(";\n");
}
- static inline EffectKey GenKey(const GrEffect&, const GrGLCaps&) { return 0; }
+ static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&) { return 0; }
private:
- typedef GrGLLegacyEffect INHERITED;
+ typedef GrGLEffect INHERITED;
};
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/effects/GrTextureDomainEffect.cpp b/src/gpu/effects/GrTextureDomainEffect.cpp
index 1c2ad33cff..fcfae14907 100644
--- a/src/gpu/effects/GrTextureDomainEffect.cpp
+++ b/src/gpu/effects/GrTextureDomainEffect.cpp
@@ -6,29 +6,29 @@
*/
#include "GrTextureDomainEffect.h"
+#include "GrTBackendEffectFactory.h"
#include "gl/GrGLEffect.h"
-#include "GrBackendEffectFactory.h"
-class GrGLTextureDomainEffect : public GrGLLegacyEffect {
+class GrGLTextureDomainEffect : public GrGLEffect {
public:
GrGLTextureDomainEffect(const GrBackendEffectFactory&, const GrEffect&);
- virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE;
- virtual void emitVS(GrGLShaderBuilder* builder,
- const char* vertexCoords) SK_OVERRIDE { }
- virtual void emitFS(GrGLShaderBuilder* builder,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray&) SK_OVERRIDE;
+ virtual void emitCode(GrGLShaderBuilder*,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray&) SK_OVERRIDE;
- virtual void setData(const GrGLUniformManager&, const GrEffect&) SK_OVERRIDE;
+ virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE;
- static inline EffectKey GenKey(const GrEffect&, const GrGLCaps&) { return 0; }
+ static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&) { return 0; }
private:
GrGLUniformManager::UniformHandle fNameUni;
- typedef GrGLLegacyEffect INHERITED;
+ typedef GrGLEffect INHERITED;
};
GrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrBackendEffectFactory& factory,
@@ -37,15 +37,17 @@ GrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrBackendEffectFactory& f
, fNameUni(GrGLUniformManager::kInvalidUniformHandle) {
}
-void GrGLTextureDomainEffect::setupVariables(GrGLShaderBuilder* builder) {
+void GrGLTextureDomainEffect::emitCode(GrGLShaderBuilder* builder,
+ const GrEffectStage&,
+ EffectKey,
+ const char* vertexCoords,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplerArray& samplers) {
+
fNameUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
kVec4f_GrSLType, "TexDom");
-};
-void GrGLTextureDomainEffect::emitFS(GrGLShaderBuilder* builder,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray& samplers) {
builder->fFSCode.appendf("\tvec2 clampCoord = clamp(%s, %s.xy, %s.zw);\n",
builder->defaultTexCoordsName(),
builder->getUniformCStr(fNameUni),
@@ -59,8 +61,9 @@ void GrGLTextureDomainEffect::emitFS(GrGLShaderBuilder* builder,
builder->fFSCode.append(";\n");
}
-void GrGLTextureDomainEffect::setData(const GrGLUniformManager& uman, const GrEffect& data) {
- const GrTextureDomainEffect& effect = static_cast<const GrTextureDomainEffect&>(data);
+void GrGLTextureDomainEffect::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
+ const GrTextureDomainEffect& effect =
+ static_cast<const GrTextureDomainEffect&>(*stage.getEffect());
const GrRect& domain = effect.domain();
float values[4] = {
@@ -70,8 +73,7 @@ void GrGLTextureDomainEffect::setData(const GrGLUniformManager& uman, const GrEf
GrScalarToFloat(domain.bottom())
};
// vertical flip if necessary
- const GrGLTexture* texture = static_cast<const GrGLTexture*>(effect.texture(0));
- if (GrGLTexture::kBottomUp_Orientation == texture->orientation()) {
+ if (GrSurface::kBottomLeft_Origin == effect.texture(0)->origin()) {
values[1] = 1.0f - values[1];
values[3] = 1.0f - values[3];
// The top and bottom were just flipped, so correct the ordering
diff --git a/src/gpu/gl/GrGLEffect.cpp b/src/gpu/gl/GrGLEffect.cpp
index b53a1cf9bb..0bbf1f7ccb 100644
--- a/src/gpu/gl/GrGLEffect.cpp
+++ b/src/gpu/gl/GrGLEffect.cpp
@@ -17,11 +17,11 @@ GrGLEffect::~GrGLEffect() {
///////////////////////////////////////////////////////////////////////////////
-void GrGLEffect::setData(const GrGLUniformManager&, const GrEffect&) {
+void GrGLEffect::setData(const GrGLUniformManager&, const GrEffectStage&) {
}
GrGLEffect::EffectKey GrGLEffect::GenTextureKey(const GrEffect& effect,
- const GrGLCaps& caps) {
+ const GrGLCaps& caps) {
EffectKey key = 0;
for (int index = 0; index < effect.numTextures(); ++index) {
const GrTextureAccess& access = effect.textureAccess(index);
diff --git a/src/gpu/gl/GrGLEffect.h b/src/gpu/gl/GrGLEffect.h
index 132c3d78de..30b8455a68 100644
--- a/src/gpu/gl/GrGLEffect.h
+++ b/src/gpu/gl/GrGLEffect.h
@@ -8,14 +8,13 @@
#ifndef GrGLEffect_DEFINED
#define GrGLEffect_DEFINED
-#include "GrAllocator.h"
-#include "GrEffect.h"
+#include "GrBackendEffectFactory.h"
#include "GrGLProgram.h"
#include "GrGLShaderBuilder.h"
#include "GrGLShaderVar.h"
#include "GrGLSL.h"
-struct GrGLInterface;
+class GrEffectStage;
class GrGLTexture;
/** @file
@@ -23,7 +22,7 @@ class GrGLTexture;
include/gpu/GrEffect.h. Objects of type GrGLEffect are responsible for emitting the
GLSL code that implements a GrEffect and for uploading uniforms at draw time. They also
must have a function:
- static inline EffectKey GenKey(const GrEffect&, const GrGLCaps&)
+ static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&)
that is used to implement a program cache. When two GrEffects produce the same key this means
that their GrGLEffects would emit the same GLSL code.
@@ -33,7 +32,8 @@ class GrGLTexture;
class GrGLEffect {
public:
- typedef GrEffect::EffectKey EffectKey;
+ typedef GrBackendEffectFactory::EffectKey EffectKey;
+
enum {
// the number of bits in EffectKey available to GenKey
kEffectKeyBits = GrBackendEffectFactory::kEffectKeyBits,
@@ -50,7 +50,7 @@ public:
stages.
@param builder Interface used to emit code in the shaders.
- @param effect The effect that generated this program stage.
+ @param stage The effect stage that generated this program stage.
@param key The key that was computed by EffectKey() from the generating GrEffect.
@param vertexCoords A vec2 of texture coordinates in the VS, which may be altered. This will
be removed soon and stages will be responsible for computing their own
@@ -67,7 +67,7 @@ public:
reads in the generated code.
*/
virtual void emitCode(GrGLShaderBuilder* builder,
- const GrEffect& effect,
+ const GrEffectStage& stage,
EffectKey key,
const char* vertexCoords,
const char* outputColor,
@@ -76,8 +76,10 @@ public:
/** A GrGLEffect instance can be reused with any GrEffect that produces the same stage
key; this function reads data from a stage and uploads any uniform variables required
- by the shaders created in emitCode(). */
- virtual void setData(const GrGLUniformManager&, const GrEffect&);
+ by the shaders created in emitCode(). The GrEffect installed in the GrEffectStage is
+ guaranteed to be of the same type that created this GrGLEffect and to have an identical
+ EffectKey as the one that created this GrGLEffect. */
+ virtual void setData(const GrGLUniformManager&, const GrEffectStage&);
const char* name() const { return fFactory.name(); }
@@ -88,34 +90,4 @@ protected:
const GrBackendEffectFactory& fFactory;
};
-/**
- * This allows program stages that implemented an older set of virtual functions on GrGLEffect
- * to continue to work by change their parent class to this class. New program stages should not use
- * this interface. It will be removed once older stages are modified to implement emitCode().
- */
-class GrGLLegacyEffect : public GrGLEffect {
-public:
- GrGLLegacyEffect(const GrBackendEffectFactory& factory) : GrGLEffect(factory) {}
-
- virtual void setupVariables(GrGLShaderBuilder* builder) {};
- virtual void emitVS(GrGLShaderBuilder* builder,
- const char* vertexCoords) = 0;
- virtual void emitFS(GrGLShaderBuilder* builder,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray&) = 0;
-
- virtual void emitCode(GrGLShaderBuilder* builder,
- const GrEffect&,
- EffectKey,
- const char* vertexCoords,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray& samplers) {
- this->setupVariables(builder);
- this->emitVS(builder, vertexCoords);
- this->emitFS(builder, outputColor, inputColor, samplers);
- }
-};
-
#endif
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 5634e2aa83..44502095d1 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -25,7 +25,6 @@ SK_DEFINE_INST_COUNT(GrGLProgram)
typedef GrGLProgram::Desc::StageDesc StageDesc;
-#define POS_ATTR_NAME "aPosition"
#define COL_ATTR_NAME "aColor"
#define COV_ATTR_NAME "aCoverage"
#define EDGE_ATTR_NAME "aEdge"
@@ -53,8 +52,8 @@ inline const char* dual_source_output_name() { return "dualSourceOut"; }
GrGLProgram* GrGLProgram::Create(const GrGLContextInfo& gl,
const Desc& desc,
- const GrEffect** effects) {
- GrGLProgram* program = SkNEW_ARGS(GrGLProgram, (gl, desc, effects));
+ const GrEffectStage* stages[]) {
+ GrGLProgram* program = SkNEW_ARGS(GrGLProgram, (gl, desc, stages));
if (!program->succeeded()) {
delete program;
program = NULL;
@@ -64,7 +63,7 @@ GrGLProgram* GrGLProgram::Create(const GrGLContextInfo& gl,
GrGLProgram::GrGLProgram(const GrGLContextInfo& gl,
const Desc& desc,
- const GrEffect** effects)
+ const GrEffectStage* stages[])
: fContextInfo(gl)
, fUniformManager(gl) {
fDesc = desc;
@@ -83,10 +82,10 @@ GrGLProgram::GrGLProgram(const GrGLContextInfo& gl,
fEffects[s] = NULL;
fTextureMatrices[s] = GrMatrix::InvalidMatrix();
// this is arbitrary, just initialize to something
- fTextureOrientation[s] = GrGLTexture::kBottomUp_Orientation;
+ fTextureOrigin[s] = GrSurface::kBottomLeft_Origin;
}
- this->genProgram(effects);
+ this->genProgram(stages);
}
GrGLProgram::~GrGLProgram() {
@@ -500,7 +499,7 @@ bool GrGLProgram::compileShaders(const GrGLShaderBuilder& builder) {
return true;
}
-bool GrGLProgram::genProgram(const GrEffect** effects) {
+bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
GrAssert(0 == fProgramID);
GrGLShaderBuilder builder(fContextInfo, fUniformManager);
@@ -567,13 +566,10 @@ bool GrGLProgram::genProgram(const GrEffect** effects) {
fUniforms.fViewMatrixUni = builder.addUniform(GrGLShaderBuilder::kVertex_ShaderType,
kMat33f_GrSLType, "ViewM", &viewMName);
- builder.fVSAttrs.push_back().set(kVec2f_GrSLType,
- GrGLShaderVar::kAttribute_TypeModifier,
- POS_ATTR_NAME);
-
- builder.fVSCode.appendf("\tvec3 pos3 = %s * vec3("POS_ATTR_NAME", 1);\n"
+
+ builder.fVSCode.appendf("\tvec3 pos3 = %s * vec3(%s, 1);\n"
"\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n",
- viewMName);
+ viewMName, builder.positionAttribute().getName().c_str());
// incoming color to current stage being processed.
SkString inColor;
@@ -616,7 +612,7 @@ bool GrGLProgram::genProgram(const GrEffect** effects) {
// figure out what our input coords are
int tcIdx = GrDrawTarget::VertexTexCoordsForStage(s, layout);
if (tcIdx < 0) {
- inCoords = POS_ATTR_NAME;
+ inCoords = builder.positionAttribute().c_str();
} else {
// must have input tex coordinates if stage is enabled.
GrAssert(texCoordAttrs[tcIdx].size());
@@ -624,7 +620,7 @@ bool GrGLProgram::genProgram(const GrEffect** effects) {
}
builder.setCurrentStage(s);
- fEffects[s] = GenStageCode(effects[s],
+ fEffects[s] = GenStageCode(*stages[s],
fDesc.fStages[s],
&fUniforms.fStages[s],
inColor.size() ? inColor.c_str() : NULL,
@@ -713,7 +709,7 @@ bool GrGLProgram::genProgram(const GrEffect** effects) {
int tcIdx =
GrDrawTarget::VertexTexCoordsForStage(s, layout);
if (tcIdx < 0) {
- inCoords = POS_ATTR_NAME;
+ inCoords = builder.positionAttribute().c_str();
} else {
// must have input tex coordinates if stage is
// enabled.
@@ -729,7 +725,7 @@ bool GrGLProgram::genProgram(const GrEffect** effects) {
inCoverage.append("4");
}
builder.setCurrentStage(s);
- fEffects[s] = GenStageCode(effects[s],
+ fEffects[s] = GenStageCode(*stages[s],
fDesc.fStages[s],
&fUniforms.fStages[s],
inCoverage.size() ? inCoverage.c_str() : NULL,
@@ -801,7 +797,8 @@ bool GrGLProgram::genProgram(const GrEffect** effects) {
return false;
}
- if (!this->bindOutputsAttribsAndLinkProgram(texCoordAttrs,
+ if (!this->bindOutputsAttribsAndLinkProgram(builder,
+ texCoordAttrs,
isColorDeclared,
dualSourceOutputWritten)) {
return false;
@@ -814,7 +811,8 @@ bool GrGLProgram::genProgram(const GrEffect** effects) {
return true;
}
-bool GrGLProgram::bindOutputsAttribsAndLinkProgram(SkString texCoordAttrNames[],
+bool GrGLProgram::bindOutputsAttribsAndLinkProgram(const GrGLShaderBuilder& builder,
+ SkString texCoordAttrNames[],
bool bindColorOut,
bool bindDualSrcOut) {
GL_CALL_RET(fProgramID, CreateProgram());
@@ -836,7 +834,9 @@ bool GrGLProgram::bindOutputsAttribsAndLinkProgram(SkString texCoordAttrNames[],
}
// Bind the attrib locations to same values for all shaders
- GL_CALL(BindAttribLocation(fProgramID, PositionAttributeIdx(), POS_ATTR_NAME));
+ GL_CALL(BindAttribLocation(fProgramID,
+ PositionAttributeIdx(),
+ builder.positionAttribute().c_str()));
for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
if (texCoordAttrNames[t].size()) {
GL_CALL(BindAttribLocation(fProgramID,
@@ -896,14 +896,15 @@ void GrGLProgram::initSamplerUniforms() {
// Stage code generation
// TODO: Move this function to GrGLShaderBuilder
-GrGLEffect* GrGLProgram::GenStageCode(const GrEffect* effect,
- const StageDesc& desc,
- StageUniforms* uniforms,
- const char* fsInColor, // NULL means no incoming color
- const char* fsOutColor,
- const char* vsInCoord,
- GrGLShaderBuilder* builder) {
-
+GrGLEffect* GrGLProgram::GenStageCode(const GrEffectStage& stage,
+ const StageDesc& desc,
+ StageUniforms* uniforms,
+ const char* fsInColor, // NULL means no incoming color
+ const char* fsOutColor,
+ const char* vsInCoord,
+ GrGLShaderBuilder* builder) {
+
+ const GrEffect* effect = stage.getEffect();
GrGLEffect* glEffect = effect->getFactory().createGLInstance(*effect);
/// Vertex Shader Stuff
@@ -956,7 +957,7 @@ GrGLEffect* GrGLProgram::GenStageCode(const GrEffect* effect,
builder->fVSCode.appendf("\t{ // %s\n", glEffect->name());
builder->fFSCode.appendf("\t{ // %s \n", glEffect->name());
glEffect->emitCode(builder,
- *effect,
+ stage,
desc.fEffectKey,
varyingVSName,
fsOutColor,
@@ -978,7 +979,7 @@ void GrGLProgram::setData(const GrDrawState& drawState) {
if (NULL != fEffects[s]) {
const GrEffectStage& stage = drawState.getStage(s);
GrAssert(NULL != stage.getEffect());
- fEffects[s]->setData(fUniformManager, *stage.getEffect());
+ fEffects[s]->setData(fUniformManager, stage);
}
}
}
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index 8adcd6278d..a023de79d1 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -43,7 +43,7 @@ public:
static GrGLProgram* Create(const GrGLContextInfo& gl,
const Desc& desc,
- const GrEffect** effects);
+ const GrEffectStage* stages[]);
virtual ~GrGLProgram();
@@ -163,24 +163,24 @@ private:
GrGLProgram(const GrGLContextInfo& gl,
const Desc& desc,
- const GrEffect** effects);
+ const GrEffectStage* stages[]);
bool succeeded() const { return 0 != fProgramID; }
/**
* This is the heavy initialization routine for building a GLProgram.
*/
- bool genProgram(const GrEffect** effects);
+ bool genProgram(const GrEffectStage* stages[]);
void genInputColor(GrGLShaderBuilder* builder, SkString* inColor);
- static GrGLEffect* GenStageCode(const GrEffect* effect,
- const StageDesc& desc, // TODO: Eliminate this
- StageUniforms* stageUniforms, // TODO: Eliminate this
- const char* fsInColor, // NULL means no incoming color
- const char* fsOutColor,
- const char* vsInCoord,
- GrGLShaderBuilder* builder);
+ static GrGLEffect* GenStageCode(const GrEffectStage& stage,
+ const StageDesc& desc, // TODO: Eliminate this
+ StageUniforms* stageUniforms, // TODO: Eliminate this
+ const char* fsInColor, // NULL means no incoming color
+ const char* fsOutColor,
+ const char* vsInCoord,
+ GrGLShaderBuilder* builder);
void genGeometryShader(GrGLShaderBuilder* segments) const;
@@ -194,7 +194,8 @@ private:
bool genEdgeCoverage(SkString* coverageVar, GrGLShaderBuilder* builder) const;
// Creates a GL program ID, binds shader attributes to GL vertex attrs, and links the program
- bool bindOutputsAttribsAndLinkProgram(SkString texCoordAttrNames[GrDrawState::kMaxTexCoords],
+ bool bindOutputsAttribsAndLinkProgram(const GrGLShaderBuilder& builder,
+ SkString texCoordAttrNames[GrDrawState::kMaxTexCoords],
bool bindColorOut,
bool bindDualSrcOut);
@@ -248,10 +249,9 @@ private:
GrColor fCoverage;
GrColor fColorFilterColor;
int fRTHeight;
- /// When it is sent to GL, the texture matrix will be flipped if the texture orientation
- /// (below) requires.
+ /// When it is sent to GL, the texture matrix will be flipped if the texture origin requires.
GrMatrix fTextureMatrices[GrDrawState::kNumStages];
- GrGLTexture::Orientation fTextureOrientation[GrDrawState::kNumStages];
+ GrSurface::Origin fTextureOrigin[GrDrawState::kNumStages];
GrGLEffect* fEffects[GrDrawState::kNumStages];
diff --git a/src/gpu/gl/GrGLRenderTarget.cpp b/src/gpu/gl/GrGLRenderTarget.cpp
index 3e72757811..9bbc842e72 100644
--- a/src/gpu/gl/GrGLRenderTarget.cpp
+++ b/src/gpu/gl/GrGLRenderTarget.cpp
@@ -49,7 +49,9 @@ GrGLRenderTarget::GrGLRenderTarget(GrGpuGL* gpu,
texture,
MakeDesc(kNone_GrTextureFlags,
viewport.fWidth, viewport.fHeight,
- desc.fConfig, desc.fSampleCnt)) {
+ desc.fConfig, desc.fSampleCnt),
+ texture->origin()) {
+ GrAssert(kBottomLeft_Origin == texture->origin());
GrAssert(NULL != texID);
GrAssert(NULL != texture);
// FBO 0 can't also be a texture, right?
@@ -70,7 +72,8 @@ GrGLRenderTarget::GrGLRenderTarget(GrGpuGL* gpu,
NULL,
MakeDesc(kNone_GrTextureFlags,
viewport.fWidth, viewport.fHeight,
- desc.fConfig, desc.fSampleCnt)) {
+ desc.fConfig, desc.fSampleCnt),
+ kBottomLeft_Origin) {
this->init(desc, viewport, NULL);
}
diff --git a/src/gpu/gl/GrGLRenderTarget.h b/src/gpu/gl/GrGLRenderTarget.h
index 64b0d21902..11a877f292 100644
--- a/src/gpu/gl/GrGLRenderTarget.h
+++ b/src/gpu/gl/GrGLRenderTarget.h
@@ -51,7 +51,7 @@ public:
const GrGLIRect& getViewport() const { return fViewport; }
// The following two functions return the same ID when a
- // texture-rendertarget is multisampled, and different IDs when
+ // texture/render target is multisampled, and different IDs when
// it is.
// FBO ID used to render into
GrGLuint renderFBOID() const { return fRTFBOID; }
@@ -93,7 +93,7 @@ private:
// else own them.
bool fOwnIDs;
- // when we switch to this rendertarget we want to set the viewport to
+ // when we switch to this render target we want to set the viewport to
// only render to to content area (as opposed to the whole allocation) and
// we want the rendering to be at top left (GL has origin in bottom left)
GrGLIRect fViewport;
diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp
index d659cf7eca..463c0363eb 100644
--- a/src/gpu/gl/GrGLShaderBuilder.cpp
+++ b/src/gpu/gl/GrGLShaderBuilder.cpp
@@ -96,6 +96,9 @@ GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctx, GrGLUniformMana
, fSetupFragPosition(false)
, fRTHeightUniform(GrGLUniformManager::kInvalidUniformHandle)
, fTexCoordVaryingType(kVoid_GrSLType) {
+
+ fPositionVar = &fVSAttrs.push_back();
+ fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "aPosition");
}
void GrGLShaderBuilder::setupTextureAccess(const char* varyingFSName, GrSLType varyingType) {
@@ -153,9 +156,10 @@ void GrGLShaderBuilder::appendTextureLookupAndModulate(
GrGLSLModulate4f(out, modulation, lookup.c_str());
}
-GrEffect::EffectKey GrGLShaderBuilder::KeyForTextureAccess(const GrTextureAccess& access,
- const GrGLCaps& caps) {
- GrEffect::EffectKey key = 0;
+GrBackendEffectFactory::EffectKey GrGLShaderBuilder::KeyForTextureAccess(
+ const GrTextureAccess& access,
+ const GrGLCaps& caps) {
+ GrBackendEffectFactory::EffectKey key = 0;
// Assume that swizzle support implies that we never have to modify a shader to adjust
// for texture format/swizzle settings.
diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/GrGLShaderBuilder.h
index b67f2f00b2..6fdec63e36 100644
--- a/src/gpu/gl/GrGLShaderBuilder.h
+++ b/src/gpu/gl/GrGLShaderBuilder.h
@@ -9,6 +9,7 @@
#define GrGLShaderBuilder_DEFINED
#include "GrAllocator.h"
+#include "GrBackendEffectFactory.h"
#include "GrEffect.h"
#include "gl/GrGLShaderVar.h"
#include "gl/GrGLSL.h"
@@ -122,8 +123,8 @@ public:
/** Generates a EffectKey for the shader code based on the texture access parameters and the
capabilities of the GL context. This is useful for keying the shader programs that may
have multiple representations, based on the type/format of textures used. */
- static GrEffect::EffectKey KeyForTextureAccess(const GrTextureAccess& access,
- const GrGLCaps& caps);
+ static GrBackendEffectFactory::EffectKey KeyForTextureAccess(const GrTextureAccess&,
+ const GrGLCaps&);
/** If texture swizzling is available using tex parameters then it is preferred over mangling
the generated shader code. This potentially allows greater reuse of cached shaders. */
@@ -169,6 +170,11 @@ public:
is in device space (e.g. 0,0 is the top left and pixel centers are at half-integers). */
const char* fragmentPosition();
+ /** Returns a vertex attribute that represents the vertex position in the VS. This is the
+ pre-matrix position and is commonly used by effects to compute texture coords via a matrix.
+ */
+ const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
+
/** Called after building is complete to get the final shader string. */
void getShader(ShaderType, SkString*) const;
@@ -226,6 +232,8 @@ private:
bool fSetupFragPosition;
GrGLUniformManager::UniformHandle fRTHeightUniform;
+ GrGLShaderVar* fPositionVar;
+
/// Per-stage settings - only valid while we're inside GrGLProgram::genStageCode().
//@{
GrSLType fTexCoordVaryingType; // the type, either Vec2f or Vec3f, of the coords passed
diff --git a/src/gpu/gl/GrGLTexture.cpp b/src/gpu/gl/GrGLTexture.cpp
index 0aa488418a..c1821b2997 100644
--- a/src/gpu/gl/GrGLTexture.cpp
+++ b/src/gpu/gl/GrGLTexture.cpp
@@ -26,10 +26,9 @@ void GrGLTexture::init(GrGpuGL* gpu,
(GPUGL->glInterface(),
textureDesc.fTextureID,
textureDesc.fOwnsID));
- fOrientation = textureDesc.fOrientation;
-
+
if (NULL != rtDesc) {
- // we render to the top left
+ GrAssert(kBottomLeft_Origin == textureDesc.fOrigin);
GrGLIRect vp;
vp.fLeft = 0;
vp.fWidth = textureDesc.fWidth;
@@ -43,14 +42,14 @@ void GrGLTexture::init(GrGpuGL* gpu,
GrGLTexture::GrGLTexture(GrGpuGL* gpu,
const Desc& textureDesc)
- : INHERITED(gpu, textureDesc) {
+ : INHERITED(gpu, textureDesc, textureDesc.fOrigin) {
this->init(gpu, textureDesc, NULL);
}
GrGLTexture::GrGLTexture(GrGpuGL* gpu,
const Desc& textureDesc,
const GrGLRenderTarget::Desc& rtDesc)
- : INHERITED(gpu, textureDesc) {
+ : INHERITED(gpu, textureDesc, textureDesc.fOrigin) {
this->init(gpu, textureDesc, &rtDesc);
}
diff --git a/src/gpu/gl/GrGLTexture.h b/src/gpu/gl/GrGLTexture.h
index a2e4af2554..4666bfbdf8 100644
--- a/src/gpu/gl/GrGLTexture.h
+++ b/src/gpu/gl/GrGLTexture.h
@@ -48,11 +48,6 @@ private:
class GrGLTexture : public GrTexture {
public:
- enum Orientation {
- kBottomUp_Orientation,
- kTopDown_Orientation,
- };
-
struct TexParams {
GrGLenum fFilter;
GrGLenum fWrapS;
@@ -64,7 +59,7 @@ public:
struct Desc : public GrTextureDesc {
GrGLuint fTextureID;
bool fOwnsID;
- Orientation fOrientation;
+ Origin fOrigin;
};
// creates a texture that is also an RT
@@ -95,16 +90,6 @@ public:
}
GrGLuint textureID() const { return fTexIDObj->id(); }
- // Ganesh assumes texture coordinates have their origin
- // in the top-left corner of the image. OpenGL, however,
- // has the origin in the lower-left corner. For content that
- // is loaded by Ganesh we just push the content "upside down"
- // (by GL's understanding of the world) in glTex*Image and the
- // addressing just works out. However, content generated by GL
- // (FBO or externally imported texture) will be updside down
- // and it is up to the GrGpuGL derivative to handle y-mirroing.
- Orientation orientation() const { return fOrientation; }
-
protected:
// overrides of GrTexture
@@ -115,7 +100,6 @@ private:
TexParams fTexParams;
GrGpu::ResetTimestamp fTexParamsTimestamp;
GrGLTexID* fTexIDObj;
- Orientation fOrientation;
void init(GrGpuGL* gpu,
const Desc& textureDesc,
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 1d622bf027..eb60539fbf 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -499,7 +499,7 @@ GrTexture* GrGpuGL::onWrapBackendTexture(const GrBackendTextureDesc& desc) {
glTexDesc.fSampleCnt = desc.fSampleCnt;
glTexDesc.fTextureID = static_cast<GrGLuint>(desc.fTextureHandle);
glTexDesc.fOwnsID = false;
- glTexDesc.fOrientation = GrGLTexture::kBottomUp_Orientation;
+ glTexDesc.fOrigin = GrSurface::kBottomLeft_Origin;
GrGLTexture* texture = NULL;
if (desc.fFlags & kRenderTarget_GrBackendTextureFlag) {
@@ -583,7 +583,7 @@ void GrGpuGL::onWriteTexturePixels(GrTexture* texture,
desc.fConfig = glTex->config();
desc.fSampleCnt = glTex->desc().fSampleCnt;
desc.fTextureID = glTex->textureID();
- desc.fOrientation = glTex->orientation();
+ desc.fOrigin = glTex->origin();
this->uploadTexData(desc, false,
left, top, width, height,
@@ -674,7 +674,7 @@ bool GrGpuGL::uploadTexData(const GrGLTexture::Desc& desc,
bool swFlipY = false;
bool glFlipY = false;
if (NULL != data) {
- if (GrGLTexture::kBottomUp_Orientation == desc.fOrientation) {
+ if (GrSurface::kBottomLeft_Origin == desc.fOrigin) {
if (this->glCaps().unpackFlipYSupport()) {
glFlipY = true;
} else {
@@ -957,8 +957,7 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
// We keep GrRenderTargets in GL's normal orientation so that they
// can be drawn to by the outside world without the client having
// to render upside down.
- glTexDesc.fOrientation = renderTarget ? GrGLTexture::kBottomUp_Orientation :
- GrGLTexture::kTopDown_Orientation;
+ glTexDesc.fOrigin = renderTarget ? GrSurface::kBottomLeft_Origin : GrSurface::kTopLeft_Origin;
glRTDesc.fSampleCnt = desc.fSampleCnt;
if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() &&
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index 4985d99a12..f56d783199 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -146,8 +146,7 @@ private:
const GrGLContextInfo& glContextInfo() const { return fGLContextInfo; }
// adjusts texture matrix to account for orientation
- static void AdjustTextureMatrix(const GrGLTexture* texture,
- GrMatrix* matrix);
+ static void AdjustTextureMatrix(const GrTexture* texture, GrMatrix* matrix);
// This helper determines if what optimizations can be applied to the matrix after any coord
// adjustments are applied. The return is a bitfield of GrGLProgram::StageDesc::OptFlags.
@@ -164,7 +163,7 @@ private:
ProgramCache(const GrGLContextInfo& gl);
void abandon();
- GrGLProgram* getProgram(const GrGLProgram::Desc& desc, const GrEffect** stages);
+ GrGLProgram* getProgram(const GrGLProgram::Desc& desc, const GrEffectStage* stages[]);
private:
enum {
kKeySize = sizeof(ProgramDesc),
@@ -238,7 +237,6 @@ private:
void buildProgram(bool isPoints,
BlendOptFlags blendOpts,
GrBlendCoeff dstCoeff,
- const GrEffect** effects,
ProgramDesc* desc);
// Inits GrDrawTarget::Caps, subclass may enable additional caps.
diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp
index 3be5afcfc0..6d6110da8f 100644
--- a/src/gpu/gl/GrGpuGL_program.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -33,7 +33,7 @@ void GrGpuGL::ProgramCache::abandon() {
}
GrGLProgram* GrGpuGL::ProgramCache::getProgram(const ProgramDesc& desc,
- const GrEffect** stages) {
+ const GrEffectStage* stages[]) {
Entry newEntry;
newEntry.fKey.setKeyData(desc.asKey());
@@ -161,19 +161,15 @@ void GrGpuGL::flushViewMatrix(DrawType type) {
// helpers for texture matrices
-void GrGpuGL::AdjustTextureMatrix(const GrGLTexture* texture,
- GrMatrix* matrix) {
+void GrGpuGL::AdjustTextureMatrix(const GrTexture* texture, GrMatrix* matrix) {
GrAssert(NULL != texture);
GrAssert(NULL != matrix);
- GrGLTexture::Orientation orientation = texture->orientation();
- if (GrGLTexture::kBottomUp_Orientation == orientation) {
+ if (GrSurface::kBottomLeft_Origin == texture->origin()) {
GrMatrix invY;
invY.setAll(GR_Scalar1, 0, 0,
0, -GR_Scalar1, GR_Scalar1,
0, 0, GrMatrix::I()[8]);
matrix->postConcat(invY);
- } else {
- GrAssert(GrGLTexture::kTopDown_Orientation == orientation);
}
}
@@ -183,7 +179,7 @@ int GrGpuGL::TextureMatrixOptFlags(const GrGLTexture* texture,
GrMatrix matrix;
stage.getTotalMatrix(&matrix);
- bool canBeIndentity = GrGLTexture::kTopDown_Orientation == texture->orientation();
+ bool canBeIndentity = GrSurface::kTopLeft_Origin == texture->origin();
if (canBeIndentity && matrix.isIdentity()) {
return GrGLProgram::StageDesc::kIdentityMatrix_OptFlagBit;
@@ -206,8 +202,7 @@ void GrGpuGL::flushTextureMatrix(int s) {
const GrGLTexture* texture = static_cast<const GrGLTexture*>(effect->texture(0));
if (NULL != texture) {
- bool orientationChange = fCurrentProgram->fTextureOrientation[s] !=
- texture->orientation();
+ bool originChange = fCurrentProgram->fTextureOrigin[s] != texture->origin();
UniformHandle matrixUni = fCurrentProgram->fUniforms.fStages[s].fTextureMatrixUni;
@@ -216,7 +211,7 @@ void GrGpuGL::flushTextureMatrix(int s) {
drawState.getStage(s).getTotalMatrix(&samplerMatrix);
if (kInvalidUniformHandle != matrixUni &&
- (orientationChange || !hwMatrix.cheapEqualTo(samplerMatrix))) {
+ (originChange || !hwMatrix.cheapEqualTo(samplerMatrix))) {
GrMatrix m = samplerMatrix;
AdjustTextureMatrix(texture, &m);
@@ -239,7 +234,7 @@ void GrGpuGL::flushTextureMatrix(int s) {
fCurrentProgram->fTextureMatrices[s] = samplerMatrix;
}
- fCurrentProgram->fTextureOrientation[s] = texture->orientation();
+ fCurrentProgram->fTextureOrigin[s] = texture->origin();
}
}
@@ -350,11 +345,14 @@ bool GrGpuGL::flushGraphicsState(DrawType type) {
return false;
}
- const GrEffect* effects[GrDrawState::kNumStages];
+ const GrEffectStage* stages[GrDrawState::kNumStages];
+ for (int i = 0; i < GrDrawState::kNumStages; ++i) {
+ stages[i] = drawState.isStageEnabled(i) ? &drawState.getStage(i) : NULL;
+ }
GrGLProgram::Desc desc;
- this->buildProgram(kDrawPoints_DrawType == type, blendOpts, dstCoeff, effects, &desc);
+ this->buildProgram(kDrawPoints_DrawType == type, blendOpts, dstCoeff, &desc);
- fCurrentProgram.reset(fProgramCache->getProgram(desc, effects));
+ fCurrentProgram.reset(fProgramCache->getProgram(desc, stages));
if (NULL == fCurrentProgram.get()) {
GrAssert(!"Failed to create program!");
return false;
@@ -563,30 +561,9 @@ void GrGpuGL::setupGeometry(int* startVertex,
fHWGeometryState.fArrayPtrsDirty = false;
}
-namespace {
-
-void setup_effect(GrGLProgram::Desc::StageDesc* stageDesc,
- const GrEffectStage& stage,
- const GrGLCaps& caps,
- const GrEffect** effects,
- GrGLProgram* program, int index) {
- const GrEffect* effect = stage.getEffect();
- if (effect) {
- const GrBackendEffectFactory& factory = effect->getFactory();
- stageDesc->fEffectKey = factory.glEffectKey(*effect, caps);
- effects[index] = effect;
- } else {
- stageDesc->fEffectKey = 0;
- effects[index] = NULL;
- }
-}
-
-}
-
void GrGpuGL::buildProgram(bool isPoints,
BlendOptFlags blendOpts,
GrBlendCoeff dstCoeff,
- const GrEffect** effects,
ProgramDesc* desc) {
const GrDrawState& drawState = this->getDrawState();
@@ -692,12 +669,11 @@ void GrGpuGL::buildProgram(bool isPoints,
// This will go away when effects manage their own texture matrix.
stageDesc.fOptFlags |= StageDesc::kIdentityMatrix_OptFlagBit;
}
- setup_effect(&stageDesc, stage, this->glCaps(), effects, fCurrentProgram.get(), s);
-
+ const GrBackendEffectFactory& factory = effect->getFactory();
+ stageDesc.fEffectKey = factory.glEffectKey(stage, this->glCaps());
} else {
stageDesc.fOptFlags = 0;
stageDesc.fEffectKey = 0;
- effects[s] = NULL;
}
}
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index c77c67070b..9c001fbbd8 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -32,13 +32,10 @@ bool random_bool(GrRandom* r) {
}
typedef GrGLProgram::StageDesc StageDesc;
-// TODO: Effects should be able to register themselves for inclusion in the
-// randomly generated shaders. They should be able to configure themselves
-// randomly.
-const GrEffect* create_random_effect(StageDesc* stageDesc,
- GrRandom* random,
- GrContext* context,
- GrTexture* dummyTextures[]) {
+
+const GrEffect* create_random_effect(GrRandom* random,
+ GrContext* context,
+ GrTexture* dummyTextures[]) {
// The new code uses SkRandom not GrRandom.
// TODO: Remove GrRandom.
@@ -118,7 +115,7 @@ bool GrGpuGL::programUnitTest() {
pdesc.fDualSrcOutput = ProgramDesc::kNone_DualSrcOutput;
}
- SkAutoTUnref<const GrEffect> effects[GrDrawState::kNumStages];
+ GrEffectStage stages[GrDrawState::kNumStages];
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
StageDesc& stageDesc = pdesc.fStages[s];
@@ -141,22 +138,23 @@ bool GrGpuGL::programUnitTest() {
if (stageDesc.isEnabled()) {
GrTexture* dummyTextures[] = {dummyTexture1.get(), dummyTexture2.get()};
- effects[s].reset(create_random_effect(&stageDesc,
- &random,
- getContext(),
- dummyTextures));
- if (NULL != effects[s]) {
+ SkAutoTUnref<const GrEffect> effect(create_random_effect(&random,
+ getContext(),
+ dummyTextures));
+ stages[s].setEffect(effect.get());
+ if (NULL != stages[s].getEffect()) {
stageDesc.fEffectKey =
- effects[s]->getFactory().glEffectKey(*effects[s], this->glCaps());
+ stages[s].getEffect()->getFactory().glEffectKey(stages[s], this->glCaps());
}
}
}
- GR_STATIC_ASSERT(sizeof(effects) ==
- GrDrawState::kNumStages * sizeof(GrEffect*));
- const GrEffect** stages = reinterpret_cast<const GrEffect**>(&effects);
+ const GrEffectStage* stagePtrs[GrDrawState::kNumStages];
+ for (int s = 0; s < GrDrawState::kNumStages; ++s) {
+ stagePtrs[s] = &stages[s];
+ }
SkAutoTUnref<GrGLProgram> program(GrGLProgram::Create(this->glContextInfo(),
pdesc,
- stages));
+ stagePtrs));
if (NULL == program.get()) {
return false;
}