Rebase gpu_dev up to r5182
git-svn-id: http://skia.googlecode.com/svn/branches/gpu_dev@6187 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi
index 8650f3c..c011747 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 89562d5..c496f5a 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 @@
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 @@
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 d7209ff..0adc00b 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 @@
public:
SK_DECLARE_INST_COUNT(GrEffect)
- typedef GrBackendEffectFactory::EffectKey EffectKey;
-
explicit GrEffect(int numTextures);
virtual ~GrEffect();
@@ -77,7 +75,7 @@
/** 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 6f8b23f..5cd0af3 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 @@
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 @@
* 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 @@
/**
* 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 @@
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 @@
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 58a3aa5..2a6e62a 100644
--- a/include/gpu/GrRenderTarget.h
+++ b/include/gpu/GrRenderTarget.h
@@ -40,7 +40,7 @@
// 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 @@
/**
* 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 @@
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 aa237ae..d7aa267 100644
--- a/include/gpu/GrSurface.h
+++ b/include/gpu/GrSurface.h
@@ -34,6 +34,22 @@
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 @@
* @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 @@
* @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 @@
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 0000000..52dbc64
--- /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 a8d67e7..65950a6 100644
--- a/include/gpu/GrTexture.h
+++ b/include/gpu/GrTexture.h
@@ -146,8 +146,8 @@
// 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 8bd1f2f..9723868 100644
--- a/include/gpu/GrTypes.h
+++ b/include/gpu/GrTypes.h
@@ -457,7 +457,7 @@
* 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 fdbf070..fb0e4d0 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 @@
///////////////////////////////////////////////////////////////////////////////
#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() {
}
-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 @@
}
}
-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 ca23452..58d2673 100644
--- a/src/effects/SkColorMatrixFilter.cpp
+++ b/src/effects/SkColorMatrixFilter.cpp
@@ -320,6 +320,7 @@
#if SK_SUPPORT_GPU
#include "GrEffect.h"
+#include "GrTBackendEffectFactory.h"
#include "gl/GrGLEffect.h"
class ColorMatrixEffect : public GrEffect {
@@ -339,10 +340,10 @@
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 @@
, 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 @@
}
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 @@
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 f17318c..82e1f22 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 @@
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;
+
+ /**
+ * 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;
-private:
- typedef SkRefCnt INHERITED;
-
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 @@
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 @@
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 @@
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 @@
}
-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;
+ static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&);
+
+ /**
+ * Subclasses of GrGLLightingEffect must call INHERITED::setData();
+ */
+ virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE;
+
+protected:
virtual void emitLightFunc(GrGLShaderBuilder*, SkString* funcName) = 0;
- static inline EffectKey GenKey(const GrEffect& s, const GrGLCaps& caps);
-
- virtual void setData(const GrGLUniformManager&, const GrEffect&) SK_OVERRIDE;
-
private:
- typedef GrGLLegacyEffect INHERITED;
+ typedef GrGLEffect INHERITED;
UniformHandle fImageIncrementUni;
UniformHandle fSurfaceScaleUni;
@@ -973,9 +980,8 @@
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 @@
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 @@
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 @@
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 @@
, 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 @@
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 @@
, fShininessUni(kInvalidUniformHandle) {
}
-void GrGLSpecularLightingEffect::setupVariables(GrGLShaderBuilder* builder) {
- INHERITED::setupVariables(builder);
- fKSUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
- kFloat_GrSLType, "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);
+ const char* ks;
+ const char* shininess;
+
+ fKSUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
+ kFloat_GrSLType, "KS", &ks);
+ fShininessUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
+ kFloat_GrSLType, "Shininess", &shininess);
static const GrGLShaderVar gLightArgs[] = {
GrGLShaderVar("normal", kVec3f_GrSLType),
@@ -1298,26 +1294,25 @@
}
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 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::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 @@
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 @@
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 @@
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 ea64e53..1097273 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 @@
// 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 @@
UniformHandle fZoomVar;
UniformHandle fInsetVar;
- typedef GrGLLegacyEffect INHERITED;
+ typedef GrGLEffect INHERITED;
};
GrGLMagnifierEffect::GrGLMagnifierEffect(const GrBackendEffectFactory& factory,
@@ -107,41 +106,37 @@
, 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) {
-}
+ SkString* code = &builder->fFSCode;
-void GrGLMagnifierEffect::emitFS(GrGLShaderBuilder* state,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray& samplers) {
- SkString* code = &state->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 @@
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::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 a1ece00..f8d1c09 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 @@
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 @@
UniformHandle fGainUni;
UniformHandle fBiasUni;
- typedef GrGLLegacyEffect INHERITED;
+ typedef GrGLEffect INHERITED;
};
GrGLMatrixConvolutionEffect::GrGLMatrixConvolutionEffect(const GrBackendEffectFactory& factory,
@@ -325,19 +326,6 @@
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 @@
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 @@
};
-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 @@
}
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 3273798..0e6a318 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 @@
///////////////////////////////////////////////////////////////////////////////
-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 @@
GrMorphologyEffect::MorphologyType fType;
GrGLUniformManager::UniformHandle fImageIncrementUni;
- typedef GrGLLegacyEffect INHERITED;
+ typedef GrGLEffect INHERITED;
};
GrGLMorphologyEffect::GrGLMorphologyEffect(const GrBackendEffectFactory& factory,
@@ -302,15 +302,16 @@
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 @@
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 16678c4..0ae7e19 100644
--- a/src/effects/SkTableColorFilter.cpp
+++ b/src/effects/SkTableColorFilter.cpp
@@ -217,6 +217,7 @@
#if SK_SUPPORT_GPU
#include "GrEffect.h"
+#include "GrTBackendEffectFactory.h"
#include "gl/GrGLEffect.h"
#include "SkGr.h"
@@ -244,26 +245,26 @@
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 @@
: 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 @@
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 f9bdf2f..d71195c 100644
--- a/src/effects/gradients/SkGradientShader.cpp
+++ b/src/effects/gradients/SkGradientShader.cpp
@@ -682,13 +682,13 @@
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 194ff8c..9f14e7f 100644
--- a/src/effects/gradients/SkGradientShaderPriv.h
+++ b/src/effects/gradients/SkGradientShaderPriv.h
@@ -271,17 +271,21 @@
///////////////////////////////////////////////////////////////////////////////
// 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;
- // 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
+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. Subclasses should call this method from
+ // their emitCode().
void emitColorLookup(GrGLShaderBuilder* builder,
const char* gradientTValue,
const char* outputColor,
@@ -289,11 +293,10 @@
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 61824a0..524db76 100644
--- a/src/effects/gradients/SkLinearGradient.cpp
+++ b/src/effects/gradients/SkLinearGradient.cpp
@@ -474,6 +474,8 @@
#if SK_SUPPORT_GPU
+#include "GrTBackendEffectFactory.h"
+
/////////////////////////////////////////////////////////////////////
class GrGLLinearGradient : public GrGLGradientEffect {
@@ -485,13 +487,15 @@
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 @@
/////////////////////////////////////////////////////////////////////
-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 6b9a678..4766af6 100644
--- a/src/effects/gradients/SkRadialGradient.cpp
+++ b/src/effects/gradients/SkRadialGradient.cpp
@@ -473,6 +473,8 @@
#if SK_SUPPORT_GPU
+#include "GrTBackendEffectFactory.h"
+
class GrGLRadialGradient : public GrGLGradientEffect {
public:
@@ -480,14 +482,15 @@
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 @@
/////////////////////////////////////////////////////////////////////
-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 c606bba..b64e15d 100644
--- a/src/effects/gradients/SkSweepGradient.cpp
+++ b/src/effects/gradients/SkSweepGradient.cpp
@@ -382,6 +382,8 @@
#if SK_SUPPORT_GPU
+#include "GrTBackendEffectFactory.h"
+
class GrGLSweepGradient : public GrGLGradientEffect {
public:
@@ -389,14 +391,15 @@
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 @@
/////////////////////////////////////////////////////////////////////
-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 3c4560c..acd0eee 100644
--- a/src/effects/gradients/SkTwoPointConicalGradient.cpp
+++ b/src/effects/gradients/SkTwoPointConicalGradient.cpp
@@ -315,6 +315,8 @@
#if SK_SUPPORT_GPU
+#include "GrTBackendEffectFactory.h"
+
// For brevity
typedef GrGLUniformManager::UniformHandle UniformHandle;
static const UniformHandle kInvalidUniformHandle = GrGLUniformManager::kInvalidUniformHandle;
@@ -326,16 +328,16 @@
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 @@
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 @@
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);
+ // 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());
+ // 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());
+ }
+ }
+
+ // 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 {
+
+ // 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");
+ }
}
}
-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());
- }
-
- // 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());
-
- // 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 @@
}
}
-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 b37b568..9357b11 100644
--- a/src/effects/gradients/SkTwoPointRadialGradient.cpp
+++ b/src/effects/gradients/SkTwoPointRadialGradient.cpp
@@ -349,6 +349,8 @@
#if SK_SUPPORT_GPU
+#include "GrTBackendEffectFactory.h"
+
// For brevity
typedef GrGLUniformManager::UniformHandle UniformHandle;
static const UniformHandle kInvalidUniformHandle = GrGLUniformManager::kInvalidUniformHandle;
@@ -361,16 +363,16 @@
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 @@
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 @@
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);
+ // 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());
+ // 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());
+ }
+ }
+
+ // 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());
+ }
+
+ this->emitColorLookup(builder, t.c_str(), outputColor, inputColor, samplers[0]);
}
}
-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());
- }
-
- // 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]);
-}
-
-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 @@
}
}
-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 54372ce..3c6c3a3 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 6423aef..09032bf 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 @@
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 cb4cb24..0860645 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 @@
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 @@
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 @@
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 6930bec..d0d9f5d 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 @@
UniformHandle fKernelUni;
UniformHandle fImageIncrementUni;
- typedef GrGLLegacyEffect INHERITED;
+ typedef GrGLEffect INHERITED;
};
GrGLConvolutionEffect::GrGLConvolutionEffect(const GrBackendEffectFactory& factory,
@@ -51,17 +51,17 @@
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 @@
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 @@
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 844bff7..8866153 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 1c2ad33..fcfae14 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 @@
, 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 @@
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 @@
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 b53a1cf..0bbf1f7 100644
--- a/src/gpu/gl/GrGLEffect.cpp
+++ b/src/gpu/gl/GrGLEffect.cpp
@@ -17,11 +17,11 @@
///////////////////////////////////////////////////////////////////////////////
-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 132c3d7..30b8455 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 @@
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 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 @@
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 @@
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 @@
/** 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 @@
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 5634e2a..f9912aa 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -53,8 +53,8 @@
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 +64,7 @@
GrGLProgram::GrGLProgram(const GrGLContextInfo& gl,
const Desc& desc,
- const GrEffect** effects)
+ const GrEffectStage* stages[])
: fContextInfo(gl)
, fUniformManager(gl) {
fDesc = desc;
@@ -83,10 +83,10 @@
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 +500,7 @@
return true;
}
-bool GrGLProgram::genProgram(const GrEffect** effects) {
+bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
GrAssert(0 == fProgramID);
GrGLShaderBuilder builder(fContextInfo, fUniformManager);
@@ -624,7 +624,7 @@
}
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,
@@ -729,7 +729,7 @@
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,
@@ -896,14 +896,15 @@
// 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 @@
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 @@
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 8adcd62..000ebe8 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -43,7 +43,7 @@
static GrGLProgram* Create(const GrGLContextInfo& gl,
const Desc& desc,
- const GrEffect** effects);
+ const GrEffectStage* stages[]);
virtual ~GrGLProgram();
@@ -163,24 +163,24 @@
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;
@@ -248,10 +248,9 @@
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 3e72757..9bbc842 100644
--- a/src/gpu/gl/GrGLRenderTarget.cpp
+++ b/src/gpu/gl/GrGLRenderTarget.cpp
@@ -49,7 +49,9 @@
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 @@
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 64b0d21..11a877f 100644
--- a/src/gpu/gl/GrGLRenderTarget.h
+++ b/src/gpu/gl/GrGLRenderTarget.h
@@ -51,7 +51,7 @@
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 @@
// 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 d659cf7..ec7199b 100644
--- a/src/gpu/gl/GrGLShaderBuilder.cpp
+++ b/src/gpu/gl/GrGLShaderBuilder.cpp
@@ -153,9 +153,10 @@
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 b67f2f0..8f5d695 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 @@
/** 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. */
diff --git a/src/gpu/gl/GrGLTexture.cpp b/src/gpu/gl/GrGLTexture.cpp
index 0aa4884..c1821b2 100644
--- a/src/gpu/gl/GrGLTexture.cpp
+++ b/src/gpu/gl/GrGLTexture.cpp
@@ -26,10 +26,9 @@
(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 @@
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 a2e4af2..4666bfb 100644
--- a/src/gpu/gl/GrGLTexture.h
+++ b/src/gpu/gl/GrGLTexture.h
@@ -48,11 +48,6 @@
class GrGLTexture : public GrTexture {
public:
- enum Orientation {
- kBottomUp_Orientation,
- kTopDown_Orientation,
- };
-
struct TexParams {
GrGLenum fFilter;
GrGLenum fWrapS;
@@ -64,7 +59,7 @@
struct Desc : public GrTextureDesc {
GrGLuint fTextureID;
bool fOwnsID;
- Orientation fOrientation;
+ Origin fOrigin;
};
// creates a texture that is also an RT
@@ -95,16 +90,6 @@
}
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 @@
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 04d0f8e..28963f1 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -490,7 +490,7 @@
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) {
@@ -574,7 +574,7 @@
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,
@@ -665,7 +665,7 @@
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 {
@@ -948,8 +948,7 @@
// 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 4985d99..f56d783 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -146,8 +146,7 @@
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 @@
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 @@
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 3be5afc..6d6110d 100644
--- a/src/gpu/gl/GrGpuGL_program.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -33,7 +33,7 @@
}
GrGLProgram* GrGpuGL::ProgramCache::getProgram(const ProgramDesc& desc,
- const GrEffect** stages) {
+ const GrEffectStage* stages[]) {
Entry newEntry;
newEntry.fKey.setKeyData(desc.asKey());
@@ -161,19 +161,15 @@
// 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 @@
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 @@
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 @@
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 @@
fCurrentProgram->fTextureMatrices[s] = samplerMatrix;
}
- fCurrentProgram->fTextureOrientation[s] = texture->orientation();
+ fCurrentProgram->fTextureOrigin[s] = texture->origin();
}
}
@@ -350,11 +345,14 @@
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 @@
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 @@
// 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 c77c670..9c001fb 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -32,13 +32,10 @@
}
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 @@
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 @@
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;
}