'<(skia_src_path)/gpu/GrCacheID.cpp',
'<(skia_src_path)/gpu/GrClipData.cpp',
'<(skia_src_path)/gpu/GrContext.cpp',
+ '<(skia_src_path)/gpu/GrCoordTransform.h',
'<(skia_src_path)/gpu/GrDefaultPathRenderer.cpp',
'<(skia_src_path)/gpu/GrDefaultPathRenderer.h',
'<(skia_src_path)/gpu/GrDrawState.cpp',
'<(skia_src_path)/gpu/gl/GrGLCaps.h',
'<(skia_src_path)/gpu/gl/GrGLContext.cpp',
'<(skia_src_path)/gpu/gl/GrGLContext.h',
+ '<(skia_src_path)/gpu/gl/GrGLCoordTransform.cpp',
+ '<(skia_src_path)/gpu/gl/GrGLCoordTransform.h',
'<(skia_src_path)/gpu/gl/GrGLCreateNativeInterface_none.cpp',
'<(skia_src_path)/gpu/gl/GrGLDefaultInterface_none.cpp',
'<(skia_src_path)/gpu/gl/GrGLDefines.h',
'<(skia_src_path)/gpu/gl/GrGLEffect.cpp',
'<(skia_src_path)/gpu/gl/GrGLEffect.h',
'<(skia_src_path)/gpu/gl/GrGLExtensions.cpp',
- '<(skia_src_path)/gpu/gl/GrGLEffectMatrix.cpp',
- '<(skia_src_path)/gpu/gl/GrGLEffectMatrix.h',
'<(skia_src_path)/gpu/gl/GrGLIndexBuffer.cpp',
'<(skia_src_path)/gpu/gl/GrGLIndexBuffer.h',
'<(skia_src_path)/gpu/gl/GrGLInterface.cpp',
typedef uint32_t EffectKey;
enum {
kNoEffectKey = 0,
- kEffectKeyBits = 15,
+ kEffectKeyBits = 10,
/**
- * Some aspects of the generated code may be determined by the particular textures that are
- * associated with the effect. These manipulations are performed by GrGLShaderBuilder beyond
- * GrGLEffects' control. So there is a dedicated part of the key which is combined
- * automatically with the bits produced by GrGLEffect::GenKey().
+ * The framework automatically includes coord transforms and texture accesses in their
+ * effect's EffectKey, so effects don't need to account for them in GenKey().
*/
kTextureKeyBits = 4,
- kAttribKeyBits = 6
+ kTransformKeyBits = 6,
+ kAttribKeyBits = 6,
+ kClassIDBits = 6
};
virtual EffectKey glEffectKey(const GrDrawEffect&, const GrGLCaps&) const = 0;
virtual const char* name() const = 0;
+ static EffectKey GetTransformKey(EffectKey key) {
+ return key >> (kEffectKeyBits + kTextureKeyBits) & ((1U << kTransformKeyBits) - 1);
+ }
+
protected:
enum {
kIllegalEffectClassID = 0,
--- /dev/null
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrCoordTransform_DEFINED
+#define GrCoordTransform_DEFINED
+
+#include "GrEffect.h"
+#include "SkMatrix.h"
+#include "GrTexture.h"
+#include "GrTypes.h"
+
+/**
+ * Coordinates available to GrEffect subclasses for requesting transformations. Transformed
+ * coordinates are made available in the the portion of fragment shader emitted by the effect.
+ */
+enum GrCoordSet {
+ /**
+ * The user-space coordinates that map to the fragment being rendered. These coords account for
+ * any change of coordinate system done on the CPU by GrContext before rendering, and also are
+ * correct for draws that take explicit local coords rather than inferring them from the
+ * primitive's positions (e.g. drawVertices). These are usually the coords a GrEffect wants.
+ */
+ kLocal_GrCoordSet,
+
+ /**
+ * The actual vertex position. Note that GrContext may not draw using the original view matrix
+ * specified by the caller, as it may have transformed vertices into another space. These are
+ * usually not the coordinates a GrEffect wants.
+ */
+ kPosition_GrCoordSet
+};
+
+/**
+ * A class representing a linear transformation from one of the built-in coordinate sets (local or
+ * position). GrEffects just define these transformations, and the framework does the rest of the
+ * work to make the transformed coordinates available in their fragment shader.
+ */
+class GrCoordTransform : public SkNoncopyable {
+public:
+ GrCoordTransform() {}
+
+ /**
+ * Create a transformation that maps [0, 1] to a texture's boundaries.
+ */
+ GrCoordTransform(GrCoordSet sourceCoords, const GrTexture* texture) {
+ this->reset(sourceCoords, texture);
+ }
+
+ /**
+ * Create a transformation from a matrix. The optional texture parameter is used to infer if the
+ * framework should internally do a y reversal to account for it being upside down by Skia's
+ * coord convention.
+ */
+ GrCoordTransform(GrCoordSet sourceCoords, const SkMatrix& m, const GrTexture* texture = NULL) {
+ this->reset(sourceCoords, m, texture);
+ }
+
+ void reset(GrCoordSet sourceCoords, const GrTexture* texture) {
+ SkASSERT(NULL != texture);
+ this->reset(sourceCoords, GrEffect::MakeDivByTextureWHMatrix(texture), texture);
+ }
+
+ void reset(GrCoordSet sourceCoords, const SkMatrix& m, const GrTexture* texture = NULL) {
+ fSourceCoords = sourceCoords;
+ fMatrix = m;
+ fReverseY = NULL != texture && kBottomLeft_GrSurfaceOrigin == texture->origin();
+ }
+
+ bool operator== (const GrCoordTransform& other) const {
+ return fSourceCoords == other.fSourceCoords &&
+ fMatrix.cheapEqualTo(other.fMatrix) &&
+ fReverseY == other.fReverseY;
+ }
+
+ GrCoordSet sourceCoords() const { return fSourceCoords; }
+ const SkMatrix& getMatrix() const { return fMatrix; }
+ bool reverseY() const { return fReverseY; }
+
+private:
+ GrCoordSet fSourceCoords;
+ SkMatrix fMatrix;
+ bool fReverseY;
+
+ typedef SkNoncopyable INHERITED;
+};
+
+#endif
* The typical use case is that sometime after an effect was installed a decision was made to draw
* in device coordinates (i.e. use an identity view-matrix). In such a case the GrDrawEffect's
* coord-change-matrix would be the inverse of the view matrix that was set when the effect was
- * installed. GrGLEffectMatrix is a handy class that implements a local coordinate matrix that
- * automatically accounts for the coord-change matrix.
+ * installed.
*/
class GrDrawEffect {
public:
class GrBackendEffectFactory;
class GrContext;
+class GrCoordTransform;
class GrEffect;
class GrVertexEffect;
class SkString;
public:
SK_DECLARE_INST_COUNT(GrEffect)
- /**
- * The types of vertex coordinates available to an effect in the vertex shader. Effects can
- * require their own vertex attribute but these coordinates are made available by the framework
- * in all programs.
- */
- enum CoordsType {
- kLocal_CoordsType,
- kPosition_CoordsType,
- };
-
virtual ~GrEffect();
/**
in generated shader code. */
const char* name() const;
+ int numTransforms() const { return fCoordTransforms.count(); }
+
+ /** Returns the coordinate transformation at index. index must be valid according to
+ numTransforms(). */
+ const GrCoordTransform& coordTransform(int index) const { return *fCoordTransforms[index]; }
+
int numTextures() const { return fTextureAccesses.count(); }
/** Returns the access pattern for the texture at index. index must be valid according to
protected:
/**
+ * Subclasses call this from their constructor to register coordinate transformations. The
+ * effect subclass manages the lifetime of the transformations (this function only stores a
+ * pointer). The GrCoordTransform is typically a member field of the GrEffect subclass. When the
+ * matrix has perspective, the transformed coordinates will have 3 components. Otherwise they'll
+ * have 2. This must only be called from the constructor because GrEffects are immutable.
+ */
+ void addCoordTransform(const GrCoordTransform* coordTransform);
+
+ /**
* Subclasses call this from their constructor to register GrTextureAccesses. The effect
* subclass manages the lifetime of the accesses (this function only stores a pointer). The
- * GrTextureAccess is typically a member field of the GrEffet subclass. This must only be
+ * GrTextureAccess is typically a member field of the GrEffect subclass. This must only be
* called from the constructor because GrEffects are immutable.
*/
void addTextureAccess(const GrTextureAccess* textureAccess);
bool result = this->onIsEqual(other);
#ifdef SK_DEBUG
if (result) {
- SkASSERT(this->numTextures() == other.numTextures());
- for (int i = 0; i < this->numTextures(); ++i) {
- SkASSERT(*fTextureAccesses[i] == *other.fTextureAccesses[i]);
- }
+ this->assertEquality(other);
}
#endif
return result;
}
+ SkDEBUGCODE(void assertEquality(const GrEffect& other) const;)
+
/** Subclass implements this to support isEqual(). It will only be called if it is known that
the two effects are of the same subclass (i.e. they return the same object from
getFactory()).*/
// to inc/dec deferred ref counts.
friend class GrVertexEffect; // to set fHasVertexCode and build fVertexAttribTypes.
+ SkSTArray<4, const GrCoordTransform*, true> fCoordTransforms;
SkSTArray<4, const GrTextureAccess*, true> fTextureAccesses;
SkSTArray<kMaxVertexAttribs, GrSLType, true> fVertexAttribTypes;
bool fWillReadDstColor;
SkASSERT(kIllegalEffectClassID != fEffectClassID);
EffectKey effectKey = GLEffect::GenKey(drawEffect, caps);
EffectKey textureKey = GLEffect::GenTextureKey(drawEffect, caps);
+ EffectKey transformKey = GLEffect::GenTransformKey(drawEffect);
EffectKey attribKey = GLEffect::GenAttribKey(drawEffect);
#ifdef SK_DEBUG
- static const EffectKey kIllegalIDMask = (uint16_t) (~((1U << kEffectKeyBits) - 1));
- SkASSERT(!(kIllegalIDMask & effectKey));
+ static const EffectKey kIllegalEffectKeyMask = (uint16_t) (~((1U << kEffectKeyBits) - 1));
+ SkASSERT(!(kIllegalEffectKeyMask & effectKey));
static const EffectKey kIllegalTextureKeyMask = (uint16_t) (~((1U << kTextureKeyBits) - 1));
SkASSERT(!(kIllegalTextureKeyMask & textureKey));
+ static const EffectKey kIllegalTransformKeyMask = (uint16_t) (~((1U << kTransformKeyBits) - 1));
+ SkASSERT(!(kIllegalTransformKeyMask & transformKey));
+
static const EffectKey kIllegalAttribKeyMask = (uint16_t) (~((1U << kAttribKeyBits) - 1));
SkASSERT(!(kIllegalAttribKeyMask & textureKey));
+
+ static const EffectKey kIllegalClassIDMask = (uint16_t) (~((1U << kClassIDBits) - 1));
+ SkASSERT(!(kIllegalClassIDMask & fEffectClassID));
#endif
- return fEffectClassID | (attribKey << (kEffectKeyBits+kTextureKeyBits)) |
- (textureKey << kEffectKeyBits) | effectKey;
+ return (fEffectClassID << (kEffectKeyBits+kTextureKeyBits+kTransformKeyBits+kAttribKeyBits)) |
+ (attribKey << (kEffectKeyBits+kTextureKeyBits+kTransformKeyBits)) |
+ (transformKey << (kEffectKeyBits+kTextureKeyBits)) |
+ (textureKey << kEffectKeyBits) |
+ (effectKey);
}
/** Returns a new instance of the appropriate *GL* implementation class
protected:
GrTBackendEffectFactory() {
- fEffectClassID = GenID() << (kAttribKeyBits + kEffectKeyBits + kTextureKeyBits) ;
+ fEffectClassID = GenID();
}
};
#if SK_SUPPORT_GPU
#include "GrEffect.h"
+#include "GrCoordTransform.h"
#include "GrEffectUnitTest.h"
#include "GrTBackendEffectFactory.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLEffectMatrix.h"
/**
* GrEffect that implements the all the separable xfer modes that cannot be expressed as Coeffs.
class GLEffect : public GrGLEffect {
public:
GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
- : GrGLEffect(factory )
- , fBackgroundEffectMatrix(kCoordsType) {
+ : GrGLEffect(factory) {
}
virtual void emitCode(GrGLShaderBuilder* builder,
const GrDrawEffect& drawEffect,
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) SK_OVERRIDE {
SkXfermode::Mode mode = drawEffect.castEffect<XferEffect>().mode();
const GrTexture* backgroundTex = drawEffect.castEffect<XferEffect>().backgroundAccess().getTexture();
const char* dstColor;
if (backgroundTex) {
- SkString bgCoords;
- GrSLType bgCoordsType = fBackgroundEffectMatrix.emitCode(builder, key, &bgCoords, NULL, "BG");
dstColor = "bgColor";
builder->fsCodeAppendf("\t\tvec4 %s = ", dstColor);
- builder->fsAppendTextureLookup(samplers[0], bgCoords.c_str(), bgCoordsType);
+ builder->fsAppendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
builder->fsCodeAppendf(";\n");
} else {
dstColor = builder->dstColor();
}
static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
- const XferEffect& xfer = drawEffect.castEffect<XferEffect>();
- GrTexture* bgTex = xfer.backgroundAccess().getTexture();
- EffectKey bgKey = 0;
- if (bgTex) {
- bgKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMatrix(bgTex),
- drawEffect,
- GLEffect::kCoordsType,
- bgTex);
- }
- EffectKey modeKey = xfer.mode() << GrGLEffectMatrix::kKeyBits;
- return modeKey | bgKey;
- }
-
- virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) SK_OVERRIDE {
- const XferEffect& xfer = drawEffect.castEffect<XferEffect>();
- GrTexture* bgTex = xfer.backgroundAccess().getTexture();
- if (bgTex) {
- fBackgroundEffectMatrix.setData(uman,
- GrEffect::MakeDivByTextureWHMatrix(bgTex),
- drawEffect,
- bgTex);
- }
+ return drawEffect.castEffect<XferEffect>().mode();
}
private:
}
- static const GrEffect::CoordsType kCoordsType = GrEffect::kLocal_CoordsType;
- GrGLEffectMatrix fBackgroundEffectMatrix;
typedef GrGLEffect INHERITED;
};
XferEffect(SkXfermode::Mode mode, GrTexture* background)
: fMode(mode) {
if (background) {
+ fBackgroundTransform.reset(kLocal_GrCoordSet, background);
+ this->addCoordTransform(&fBackgroundTransform);
fBackgroundAccess.reset(background);
this->addTextureAccess(&fBackgroundAccess);
} else {
}
SkXfermode::Mode fMode;
+ GrCoordTransform fBackgroundTransform;
GrTextureAccess fBackgroundAccess;
typedef GrEffect INHERITED;
#include "SkUnPreMultiply.h"
#if SK_SUPPORT_GPU
#include "GrContext.h"
+#include "GrCoordTransform.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLEffectMatrix.h"
#include "GrTBackendEffectFactory.h"
#include "SkImageFilterUtils.h"
#endif
EffectKey,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray&) SK_OVERRIDE;
- static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
-
virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
private:
- static const GrEffect::CoordsType kCoordsType = GrEffect::kLocal_CoordsType;
- GrGLEffectMatrix fBackgroundEffectMatrix;
GrGLUniformManager::UniformHandle fKUni;
typedef GrGLEffect INHERITED;
GrArithmeticEffect(float k1, float k2, float k3, float k4, GrTexture* background);
float fK1, fK2, fK3, fK4;
+ GrCoordTransform fBackgroundTransform;
GrTextureAccess fBackgroundAccess;
GR_DECLARE_EFFECT_TEST;
GrTexture* background)
: fK1(k1), fK2(k2), fK3(k3), fK4(k4) {
if (background) {
+ fBackgroundTransform.reset(kLocal_GrCoordSet, background);
+ this->addCoordTransform(&fBackgroundTransform);
fBackgroundAccess.reset(background);
this->addTextureAccess(&fBackgroundAccess);
} else {
GrGLArithmeticEffect::GrGLArithmeticEffect(const GrBackendEffectFactory& factory,
const GrDrawEffect& drawEffect)
- : INHERITED(factory)
- , fBackgroundEffectMatrix(kCoordsType) {
+ : INHERITED(factory) {
}
GrGLArithmeticEffect::~GrGLArithmeticEffect() {
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) {
GrTexture* backgroundTex = drawEffect.castEffect<GrArithmeticEffect>().backgroundTexture();
const char* dstColor;
if (backgroundTex) {
- SkString bgCoords;
- GrSLType bgCoordsType = fBackgroundEffectMatrix.emitCode(builder, key, &bgCoords, NULL, "BG");
builder->fsCodeAppend("\t\tvec4 bgColor = ");
- builder->fsAppendTextureLookup(samplers[0], bgCoords.c_str(), bgCoordsType);
+ builder->fsAppendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
builder->fsCodeAppendf(";\n");
dstColor = "bgColor";
} else {
void GrGLArithmeticEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
const GrArithmeticEffect& arith = drawEffect.castEffect<GrArithmeticEffect>();
uman.set4f(fKUni, arith.k1(), arith.k2(), arith.k3(), arith.k4());
- GrTexture* bgTex = arith.backgroundTexture();
- if (bgTex) {
- fBackgroundEffectMatrix.setData(uman,
- GrEffect::MakeDivByTextureWHMatrix(bgTex),
- drawEffect,
- bgTex);
- }
-}
-
-GrGLEffect::EffectKey GrGLArithmeticEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
- const GrArithmeticEffect& effect = drawEffect.castEffect<GrArithmeticEffect>();
- GrTexture* bgTex = effect.backgroundTexture();
- EffectKey bgKey = 0;
- if (bgTex) {
- bgKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMatrix(bgTex),
- drawEffect,
- GrGLArithmeticEffect::kCoordsType,
- bgTex);
- }
- return bgKey;
}
GrEffectRef* GrArithmeticEffect::TestCreate(SkRandom* rand,
#if SK_SUPPORT_GPU
#include "GrContext.h"
+#include "GrCoordTransform.h"
#include "GrEffect.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLEffectMatrix.h"
#include "GrTBackendEffectFactory.h"
#include "GrTextureAccess.h"
GLEffect(const GrBackendEffectFactory& factory,
const GrDrawEffect& e)
: GrGLEffect(factory)
- , fBmpMatrix(GrEffect::kLocal_CoordsType)
- , fMaskMatrix(GrEffect::kLocal_CoordsType)
, fPrevThreshold(-SK_Scalar1) {
}
virtual void emitCode(GrGLShaderBuilder* builder,
- const GrDrawEffect& drawEffect,
- EffectKey key,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray& samplers) SK_OVERRIDE {
- SkString bmpCoord;
- SkString maskCoord;
-
- GrSLType bmpCoordType = fBmpMatrix.emitCode(builder, key, &bmpCoord, NULL, "Bmp");
- EffectKey maskMatrixKey = key >> GrGLEffectMatrix::kKeyBits;
- GrSLType maskCoordType = fMaskMatrix.emitCode(builder,
- maskMatrixKey,
- &maskCoord,
- NULL,
- "Mask");
-
+ const GrDrawEffect& drawEffect,
+ EffectKey key,
+ const char* outputColor,
+ const char* inputColor,
+ const TransformedCoordsArray& coords,
+ const TextureSamplerArray& samplers) SK_OVERRIDE {
// put bitmap color in "color"
builder->fsCodeAppend("\t\tvec4 color = ");
- builder->fsAppendTextureLookup(samplers[0], bmpCoord.c_str(), bmpCoordType);
+ builder->fsAppendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
builder->fsCodeAppend(";\n");
// put alpha from mask texture in "mask"
builder->fsCodeAppend("\t\tfloat mask = ");
- builder->fsAppendTextureLookup(samplers[1], maskCoord.c_str(), maskCoordType);
+ builder->fsAppendTextureLookup(samplers[1], coords[1].c_str(), coords[1].type());
builder->fsCodeAppend(".a;\n");
const char* threshold;
virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect& e) SK_OVERRIDE {
const ThresholdEffect& effect = e.castEffect<ThresholdEffect>();
- fBmpMatrix.setData(uman, effect.fBmpMatrix, e, effect.fBmpAccess.getTexture());
- fMaskMatrix.setData(uman, effect.fMaskMatrix, e, effect.fMaskAccess.getTexture());
if (fPrevThreshold != effect.fThreshold) {
uman.set1f(fThresholdUniHandle, effect.fThreshold);
}
}
- static inline EffectKey GenKey(const GrDrawEffect& e, const GrGLCaps&) {
- const ThresholdEffect& effect = e.castEffect<ThresholdEffect>();
-
- EffectKey bmpMKey = GrGLEffectMatrix::GenKey(effect.fBmpMatrix,
- e,
- GrEffect::kLocal_CoordsType,
- effect.fBmpAccess.getTexture());
- EffectKey maskMKey = GrGLEffectMatrix::GenKey(effect.fMaskMatrix,
- e,
- GrEffect::kLocal_CoordsType,
- effect.fMaskAccess.getTexture());
- return bmpMKey | (maskMKey << GrGLEffectMatrix::kKeyBits);
- }
-
private:
- GrGLEffectMatrix fBmpMatrix;
- GrGLEffectMatrix fMaskMatrix;
-
GrGLUniformManager::UniformHandle fThresholdUniHandle;
SkScalar fPrevThreshold;
};
ThresholdEffect(GrTexture* bmpTexture, const SkMatrix& bmpMatrix,
GrTexture* maskTexture, const SkMatrix& maskMatrix,
SkScalar threshold)
- : fBmpAccess(bmpTexture, GrTextureParams())
+ : fBmpTransform(kLocal_GrCoordSet, bmpMatrix, bmpTexture)
+ , fBmpAccess(bmpTexture, GrTextureParams())
+ , fMaskTransform(kLocal_GrCoordSet, maskMatrix, maskTexture)
, fMaskAccess(maskTexture, GrTextureParams())
- , fBmpMatrix(bmpMatrix)
- , fMaskMatrix(maskMatrix)
, fThreshold(threshold) {
+ this->addCoordTransform(&fBmpTransform);
this->addTextureAccess(&fBmpAccess);
+ this->addCoordTransform(&fMaskTransform);
this->addTextureAccess(&fMaskAccess);
}
const ThresholdEffect& e = CastEffect<ThresholdEffect>(other);
return e.fBmpAccess.getTexture() == fBmpAccess.getTexture() &&
e.fMaskAccess.getTexture() == fMaskAccess.getTexture() &&
- e.fBmpMatrix == fBmpMatrix &&
- e.fMaskMatrix == fMaskMatrix &&
+ e.fBmpTransform.getMatrix() == fBmpTransform.getMatrix() &&
+ e.fMaskTransform.getMatrix() == fMaskTransform.getMatrix() &&
e.fThreshold == fThreshold;
}
- GrTextureAccess fBmpAccess;
- GrTextureAccess fMaskAccess;
-
- SkMatrix fBmpMatrix;
- SkMatrix fMaskMatrix;
+ GrCoordTransform fBmpTransform;
+ GrTextureAccess fBmpAccess;
+ GrCoordTransform fMaskTransform;
+ GrTextureAccess fMaskAccess;
SkScalar fThreshold;
};
EffectKey,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray&) SK_OVERRIDE {
fMatrixHandle = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
kMat44f_GrSLType,
#include "SkColorPriv.h"
#if SK_SUPPORT_GPU
#include "GrContext.h"
+#include "GrCoordTransform.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLEffectMatrix.h"
#include "GrTBackendEffectFactory.h"
#include "SkImageFilterUtils.h"
#endif
EffectKey,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray&) SK_OVERRIDE;
static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
private:
- static const GrEffect::CoordsType kCoordsType = GrEffect::kLocal_CoordsType;
-
SkDisplacementMapEffect::ChannelSelectorType fXChannelSelector;
SkDisplacementMapEffect::ChannelSelectorType fYChannelSelector;
- GrGLEffectMatrix fDisplacementEffectMatrix;
- GrGLEffectMatrix fColorEffectMatrix;
GrGLUniformManager::UniformHandle fScaleUni;
typedef GrGLEffect INHERITED;
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
private:
-
virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
GrDisplacementMapEffect(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,
GR_DECLARE_EFFECT_TEST;
+ GrCoordTransform fDisplacementTransform;
GrTextureAccess fDisplacementAccess;
+ GrCoordTransform fColorTransform;
GrTextureAccess fColorAccess;
SkDisplacementMapEffect::ChannelSelectorType fXChannelSelector;
SkDisplacementMapEffect::ChannelSelectorType fYChannelSelector;
SkScalar scale,
GrTexture* displacement,
GrTexture* color)
- : fDisplacementAccess(displacement)
+ : fDisplacementTransform(kLocal_GrCoordSet, displacement)
+ , fDisplacementAccess(displacement)
+ , fColorTransform(kLocal_GrCoordSet, color)
, fColorAccess(color)
, fXChannelSelector(xChannelSelector)
, fYChannelSelector(yChannelSelector)
, fScale(scale) {
+ this->addCoordTransform(&fDisplacementTransform);
this->addTextureAccess(&fDisplacementAccess);
+ this->addCoordTransform(&fColorTransform);
this->addTextureAccess(&fColorAccess);
}
const GrDrawEffect& drawEffect)
: INHERITED(factory)
, fXChannelSelector(drawEffect.castEffect<GrDisplacementMapEffect>().xChannelSelector())
- , fYChannelSelector(drawEffect.castEffect<GrDisplacementMapEffect>().yChannelSelector())
- , fDisplacementEffectMatrix(kCoordsType)
- , fColorEffectMatrix(kCoordsType) {
+ , fYChannelSelector(drawEffect.castEffect<GrDisplacementMapEffect>().yChannelSelector()) {
}
GrGLDisplacementMapEffect::~GrGLDisplacementMapEffect() {
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) {
sk_ignore_unused_variable(inputColor);
fScaleUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
kVec2f_GrSLType, "Scale");
const char* scaleUni = builder->getUniformCStr(fScaleUni);
-
- SkString dCoordsIn;
- GrSLType dCoordsType = fDisplacementEffectMatrix.emitCode(
- builder, key, &dCoordsIn, NULL, "DISPL");
- SkString cCoordsIn;
- GrSLType cCoordsType = fColorEffectMatrix.emitCode(
- builder, key, &cCoordsIn, NULL, "COLOR");
-
const char* dColor = "dColor";
const char* cCoords = "cCoords";
const char* outOfBounds = "outOfBounds";
// leave room for 32-bit float GPU rounding errors.
builder->fsCodeAppendf("\t\tvec4 %s = ", dColor);
- builder->fsAppendTextureLookup(samplers[0], dCoordsIn.c_str(), dCoordsType);
+ builder->fsAppendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
builder->fsCodeAppend(";\n");
// Unpremultiply the displacement
dColor, dColor, nearZero, dColor, dColor);
builder->fsCodeAppendf("\t\tvec2 %s = %s + %s*(%s.",
- cCoords, cCoordsIn.c_str(), scaleUni, dColor);
+ cCoords, coords[1].c_str(), scaleUni, dColor);
switch (fXChannelSelector) {
case SkDisplacementMapEffect::kR_ChannelSelectorType:
"bool %s = (%s.x < 0.0) || (%s.y < 0.0) || (%s.x > 1.0) || (%s.y > 1.0);\t\t",
outOfBounds, cCoords, cCoords, cCoords, cCoords);
builder->fsCodeAppendf("%s = %s ? vec4(0.0) : ", outputColor, outOfBounds);
- builder->fsAppendTextureLookup(samplers[1], cCoords, cCoordsType);
+ builder->fsAppendTextureLookup(samplers[1], cCoords, coords[1].type());
builder->fsCodeAppend(";\n");
}
const GrDrawEffect& drawEffect) {
const GrDisplacementMapEffect& displacementMap =
drawEffect.castEffect<GrDisplacementMapEffect>();
- GrTexture* displTex = displacementMap.texture(0);
GrTexture* colorTex = displacementMap.texture(1);
- fDisplacementEffectMatrix.setData(uman,
- GrEffect::MakeDivByTextureWHMatrix(displTex),
- drawEffect,
- displTex);
- fColorEffectMatrix.setData(uman,
- GrEffect::MakeDivByTextureWHMatrix(colorTex),
- drawEffect,
- colorTex);
-
SkScalar scaleX = SkScalarDiv(displacementMap.scale(), SkIntToScalar(colorTex->width()));
SkScalar scaleY = SkScalarDiv(displacementMap.scale(), SkIntToScalar(colorTex->height()));
uman.set2f(fScaleUni, SkScalarToFloat(scaleX),
const GrDisplacementMapEffect& displacementMap =
drawEffect.castEffect<GrDisplacementMapEffect>();
- GrTexture* displTex = displacementMap.texture(0);
- GrTexture* colorTex = displacementMap.texture(1);
-
- EffectKey displKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMatrix(displTex),
- drawEffect,
- kCoordsType,
- displTex);
-
- EffectKey colorKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMatrix(colorTex),
- drawEffect,
- kCoordsType,
- colorTex);
-
- colorKey <<= GrGLEffectMatrix::kKeyBits;
- EffectKey xKey = displacementMap.xChannelSelector() << (2 * GrGLEffectMatrix::kKeyBits);
- EffectKey yKey = displacementMap.yChannelSelector() << (2 * GrGLEffectMatrix::kKeyBits +
- SkDisplacementMapEffect::kKeyBits);
+ EffectKey xKey = displacementMap.xChannelSelector();
+ EffectKey yKey = displacementMap.yChannelSelector() << SkDisplacementMapEffect::kKeyBits;
- return xKey | yKey | displKey | colorKey;
+ return xKey | yKey;
}
#endif
#if SK_SUPPORT_GPU
#include "effects/GrSingleTextureEffect.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLEffectMatrix.h"
#include "GrEffect.h"
#include "GrTBackendEffectFactory.h"
EffectKey,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray&) SK_OVERRIDE;
static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
UniformHandle fImageIncrementUni;
UniformHandle fSurfaceScaleUni;
GrGLLight* fLight;
- GrGLEffectMatrix fEffectMatrix;
};
///////////////////////////////////////////////////////////////////////////////
GrGLLightingEffect::GrGLLightingEffect(const GrBackendEffectFactory& factory,
const GrDrawEffect& drawEffect)
- : INHERITED(factory)
- , fEffectMatrix(drawEffect.castEffect<GrLightingEffect>().coordsType()) {
+ : INHERITED(factory) {
const GrLightingEffect& m = drawEffect.castEffect<GrLightingEffect>();
fLight = m.light()->createGLLight();
}
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) {
- SkString coords;
- fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, &coords);
+ SkString coords2D = builder->ensureFSCoords2D(coords, 0);
fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
kVec2f_GrSLType,
interiorNormalBody.c_str(),
&interiorNormalName);
- builder->fsCodeAppendf("\t\tvec2 coord = %s;\n", coords.c_str());
+ builder->fsCodeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
builder->fsCodeAppend("\t\tfloat m[9];\n");
const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
GrGLEffect::EffectKey GrGLLightingEffect::GenKey(const GrDrawEffect& drawEffect,
const GrGLCaps& caps) {
- const GrLightingEffect& lighting = drawEffect.castEffect<GrLightingEffect>();
- EffectKey key = lighting.light()->type();
- key <<= GrGLEffectMatrix::kKeyBits;
- EffectKey matrixKey = GrGLEffectMatrix::GenKey(lighting.getMatrix(),
- drawEffect,
- lighting.coordsType(),
- lighting.texture(0));
- return key | matrixKey;
+ return drawEffect.castEffect<GrLightingEffect>().light()->type();
}
void GrGLLightingEffect::setData(const GrGLUniformManager& uman,
uman.set1f(fSurfaceScaleUni, lighting.surfaceScale());
SkAutoTUnref<SkLight> transformedLight(lighting.light()->transform(lighting.filterMatrix()));
fLight->setData(uman, transformedLight);
- fEffectMatrix.setData(uman,
- lighting.getMatrix(),
- drawEffect,
- lighting.texture(0));
}
///////////////////////////////////////////////////////////////////////////////
#if SK_SUPPORT_GPU
#include "gl/GrGLEffect.h"
-#include "gl/GrGLEffectMatrix.h"
#include "GrContext.h"
#include "GrTBackendEffectFactory.h"
#endif
EffectKey,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray&) SK_OVERRIDE;
static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
}
void GrGLLumaMaskEffect::emitCode(GrGLShaderBuilder* builder,
- const GrDrawEffect& effect,
- EffectKey key,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplerArray& samplers) {
+ const GrDrawEffect& effect,
+ EffectKey key,
+ const char* outputColor,
+ const char* inputColor,
+ const TransformedCoordsArray&,
+ const TextureSamplerArray& samplers) {
const GrLumaMaskEffect& lumaEffect = effect.castEffect<GrLumaMaskEffect>();
const char* dstColor = builder->dstColor();
#if SK_SUPPORT_GPU
#include "effects/GrSingleTextureEffect.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLEffectMatrix.h"
#include "gl/GrGLSL.h"
#include "gl/GrGLTexture.h"
#include "GrTBackendEffectFactory.h"
EffectKey,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray&) SK_OVERRIDE;
virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
- static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
-
private:
UniformHandle fOffsetVar;
UniformHandle fZoomVar;
UniformHandle fInsetVar;
- GrGLEffectMatrix fEffectMatrix;
-
typedef GrGLEffect INHERITED;
};
-GrGLMagnifierEffect::GrGLMagnifierEffect(const GrBackendEffectFactory& factory,
- const GrDrawEffect& drawEffect)
- : INHERITED(factory)
- , fEffectMatrix(drawEffect.castEffect<GrMagnifierEffect>().coordsType()) {
+GrGLMagnifierEffect::GrGLMagnifierEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
+ : INHERITED(factory) {
}
void GrGLMagnifierEffect::emitCode(GrGLShaderBuilder* builder,
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) {
- SkString coords;
- fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, &coords);
+ SkString coords2D = builder->ensureFSCoords2D(coords, 0);
fOffsetVar = builder->addUniform(
GrGLShaderBuilder::kFragment_Visibility |
GrGLShaderBuilder::kVertex_Visibility,
GrGLShaderBuilder::kVertex_Visibility,
kVec2f_GrSLType, "uInset");
- builder->fsCodeAppendf("\t\tvec2 coord = %s;\n", coords.c_str());
+ builder->fsCodeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
builder->fsCodeAppendf("\t\tvec2 zoom_coord = %s + %s / %s;\n",
builder->getUniformCStr(fOffsetVar),
- coords.c_str(),
+ coords2D.c_str(),
builder->getUniformCStr(fZoomVar));
builder->fsCodeAppend("\t\tvec2 delta = min(coord, vec2(1.0, 1.0) - coord);\n");
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());
- fEffectMatrix.setData(uman, zoom.getMatrix(), drawEffect, zoom.texture(0));
-}
-
-GrGLEffect::EffectKey GrGLMagnifierEffect::GenKey(const GrDrawEffect& drawEffect,
- const GrGLCaps&) {
- const GrMagnifierEffect& zoom = drawEffect.castEffect<GrMagnifierEffect>();
- return GrGLEffectMatrix::GenKey(zoom.getMatrix(),
- drawEffect,
- zoom.coordsType(),
- zoom.texture(0));
}
/////////////////////////////////////////////////////////////////////
#if SK_SUPPORT_GPU
#include "gl/GrGLEffect.h"
-#include "gl/GrGLEffectMatrix.h"
#include "effects/GrSingleTextureEffect.h"
#include "GrTBackendEffectFactory.h"
#include "GrTexture.h"
EffectKey,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray&) SK_OVERRIDE;
static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
UniformHandle fGainUni;
UniformHandle fBiasUni;
- GrGLEffectMatrix fEffectMatrix;
-
typedef GrGLEffect INHERITED;
};
GrGLMatrixConvolutionEffect::GrGLMatrixConvolutionEffect(const GrBackendEffectFactory& factory,
const GrDrawEffect& drawEffect)
- : INHERITED(factory)
- , fEffectMatrix(drawEffect.castEffect<GrMatrixConvolutionEffect>().coordsType()) {
+ : INHERITED(factory) {
const GrMatrixConvolutionEffect& m = drawEffect.castEffect<GrMatrixConvolutionEffect>();
fKernelSize = m.kernelSize();
fTileMode = m.tileMode();
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) {
- SkString coords;
- fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, &coords);
+ SkString coords2D = builder->ensureFSCoords2D(coords, 0);
fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
kVec2f_GrSLType, "ImageIncrement");
fKernelUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibility,
int kHeight = fKernelSize.height();
builder->fsCodeAppend("\t\tvec4 sum = vec4(0, 0, 0, 0);\n");
- builder->fsCodeAppendf("\t\tvec2 coord = %s - %s * %s;\n", coords.c_str(), target, imgInc);
+ builder->fsCodeAppendf("\t\tvec2 coord = %s - %s * %s;\n", coords2D.c_str(), target, imgInc);
builder->fsCodeAppendf("\t\tfor (int y = 0; y < %d; y++) {\n", kHeight);
builder->fsCodeAppendf("\t\t\tfor (int x = 0; x < %d; x++) {\n", kWidth);
builder->fsCodeAppendf("\t\t\t\tfloat k = %s[y * %d + x];\n", kernel, kWidth);
builder->fsCodeAppendf("\t\t%s.rgb = clamp(%s.rgb, 0.0, %s.a);\n", outputColor, outputColor, outputColor);
} else {
builder->fsCodeAppend("\t\tvec4 c = ");
- appendTextureLookup(builder, samplers[0], coords.c_str(), fTileMode);
+ appendTextureLookup(builder, samplers[0], coords2D.c_str(), fTileMode);
builder->fsCodeAppend(";\n");
builder->fsCodeAppendf("\t\t%s.a = c.a;\n", outputColor);
builder->fsCodeAppendf("\t\t%s.rgb = sum.rgb * %s + %s;\n", outputColor, gain, bias);
EffectKey key = encodeXY(m.kernelSize().width(), m.kernelSize().height());
key |= m.tileMode() << 7;
key |= m.convolveAlpha() ? 1 << 9 : 0;
- key <<= GrGLEffectMatrix::kKeyBits;
- EffectKey matrixKey = GrGLEffectMatrix::GenKey(m.getMatrix(),
- drawEffect,
- m.coordsType(),
- m.texture(0));
- return key | matrixKey;
+ return key;
}
void GrGLMatrixConvolutionEffect::setData(const GrGLUniformManager& uman,
uman.set1fv(fKernelUni, 0, fKernelSize.width() * fKernelSize.height(), conv.kernel());
uman.set1f(fGainUni, conv.gain());
uman.set1f(fBiasUni, conv.bias());
- fEffectMatrix.setData(uman,
- conv.getMatrix(),
- drawEffect,
- conv.texture(0));
}
GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrTexture* texture,
#include "GrTexture.h"
#include "GrTBackendEffectFactory.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLEffectMatrix.h"
#include "effects/Gr1DKernelEffect.h"
#include "SkImageFilterUtils.h"
#endif
EffectKey,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray&) SK_OVERRIDE;
static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
int fRadius;
GrMorphologyEffect::MorphologyType fType;
GrGLUniformManager::UniformHandle fImageIncrementUni;
- GrGLEffectMatrix fEffectMatrix;
typedef GrGLEffect INHERITED;
};
GrGLMorphologyEffect::GrGLMorphologyEffect(const GrBackendEffectFactory& factory,
const GrDrawEffect& drawEffect)
- : INHERITED(factory)
- , fEffectMatrix(drawEffect.castEffect<GrMorphologyEffect>().coordsType()) {
+ : INHERITED(factory) {
const GrMorphologyEffect& m = drawEffect.castEffect<GrMorphologyEffect>();
fRadius = m.radius();
fType = m.type();
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) {
- SkString coords;
- fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, &coords);
+ SkString coords2D = builder->ensureFSCoords2D(coords, 0);
fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
kVec2f_GrSLType, "ImageIncrement");
}
const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
- builder->fsCodeAppendf("\t\tvec2 coord = %s - %d.0 * %s;\n", coords.c_str(), fRadius, imgInc);
+ builder->fsCodeAppendf("\t\tvec2 coord = %s - %d.0 * %s;\n", coords2D.c_str(), fRadius, imgInc);
builder->fsCodeAppendf("\t\tfor (int i = 0; i < %d; i++) {\n", this->width());
builder->fsCodeAppendf("\t\t\t%s = %s(%s, ", outputColor, func, outputColor);
builder->fsAppendTextureLookup(samplers[0], "coord");
const GrMorphologyEffect& m = drawEffect.castEffect<GrMorphologyEffect>();
EffectKey key = static_cast<EffectKey>(m.radius());
key |= (m.type() << 8);
- key <<= GrGLEffectMatrix::kKeyBits;
- EffectKey matrixKey = GrGLEffectMatrix::GenKey(m.getMatrix(),
- drawEffect,
- m.coordsType(),
- m.texture(0));
- return key | matrixKey;
+ return key;
}
void GrGLMorphologyEffect::setData(const GrGLUniformManager& uman,
GrCrash("Unknown filter direction.");
}
uman.set2fv(fImageIncrementUni, 0, 1, imageIncrement);
- fEffectMatrix.setData(uman, kern.getMatrix(), drawEffect, kern.texture(0));
}
///////////////////////////////////////////////////////////////////////////////
#if SK_SUPPORT_GPU
#include "GrContext.h"
+#include "GrCoordTransform.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLEffectMatrix.h"
#include "GrTBackendEffectFactory.h"
#include "SkGr.h"
#endif
GrGLUniformManager::UniformHandle fBaseFrequencyUni;
GrGLUniformManager::UniformHandle fAlphaUni;
GrGLUniformManager::UniformHandle fInvMatrixUni;
- GrGLEffectMatrix fEffectMatrix;
private:
typedef GrGLEffect INHERITED;
EffectKey,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray&) SK_OVERRIDE;
virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
EffectKey,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray&) SK_OVERRIDE;
virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
bool stitchTiles() const { return fStitchTiles; }
const SkVector& baseFrequency() const { return fBaseFrequency; }
int numOctaves() const { return fNumOctaves; }
- const SkMatrix& matrix() const { return fMatrix; }
+ const SkMatrix& matrix() const { return fCoordTransform.getMatrix(); }
uint8_t alpha() const { return fAlpha; }
- GrGLEffectMatrix::CoordsType coordsType() const { return GrEffect::kLocal_CoordsType; }
void getConstantColorComponents(GrColor*, uint32_t* validFlags) const SK_OVERRIDE {
*validFlags = 0; // This is noise. Nothing is constant.
fBaseFrequency == s.fBaseFrequency &&
fNumOctaves == s.fNumOctaves &&
fStitchTiles == s.fStitchTiles &&
- fMatrix == s.fMatrix &&
+ fCoordTransform.getMatrix() == s.fCoordTransform.getMatrix() &&
fAlpha == s.fAlpha;
}
, fStitchTiles(stitchTiles)
, fMatrix(matrix)
, fAlpha(alpha) {
+ // This (1,1) translation is due to WebKit's 1 based coordinates for the noise
+ // (as opposed to 0 based, usually). The same adjustment is in the shadeSpan() functions.
+ SkMatrix m = matrix;
+ m.postTranslate(SK_Scalar1, SK_Scalar1);
+ fCoordTransform.reset(kLocal_GrCoordSet, m);
+ this->addCoordTransform(&fCoordTransform);
}
SkPerlinNoiseShader::Type fType;
+ GrCoordTransform fCoordTransform;
SkVector fBaseFrequency;
int fNumOctaves;
bool fStitchTiles;
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray& coords,
const TextureSamplerArray&) {
sk_ignore_unused_variable(inputColor);
- SkString vCoords;
- fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, &vCoords);
+ SkString vCoords = builder->ensureFSCoords2D(coords, 0);
fSeedUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
kFloat_GrSLType, "seed");
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) {
sk_ignore_unused_variable(inputColor);
- SkString vCoords;
- fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, &vCoords);
+ SkString vCoords = builder->ensureFSCoords2D(coords, 0);
fInvMatrixUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
kMat33f_GrSLType, "invMatrix");
: INHERITED (factory)
, fType(drawEffect.castEffect<GrPerlinNoiseEffect>().type())
, fStitchTiles(drawEffect.castEffect<GrPerlinNoiseEffect>().stitchTiles())
- , fNumOctaves(drawEffect.castEffect<GrPerlinNoiseEffect>().numOctaves())
- , fEffectMatrix(drawEffect.castEffect<GrPerlinNoiseEffect>().coordsType()) {
+ , fNumOctaves(drawEffect.castEffect<GrPerlinNoiseEffect>().numOctaves()) {
}
GrGLEffect::EffectKey GrGLNoise::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
key |= 0x4; // Flip the 3rd bit if tile stitching is on
}
- key = key << GrGLEffectMatrix::kKeyBits;
-
- SkMatrix m = turbulence.matrix();
- m.postTranslate(SK_Scalar1, SK_Scalar1);
- return key | GrGLEffectMatrix::GenKey(m, drawEffect,
- drawEffect.castEffect<GrPerlinNoiseEffect>().coordsType(), NULL);
+ return key;
}
void GrGLNoise::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
uman.set1f(fAlphaUni, SkScalarDiv(SkIntToScalar(turbulence.alpha()), SkIntToScalar(255)));
SkMatrix m = turbulence.matrix();
+ m.postTranslate(-SK_Scalar1, -SK_Scalar1);
SkMatrix invM;
if (!m.invert(&invM)) {
invM.reset();
invM.postConcat(invM); // Square the matrix
}
uman.setSkMatrix(fInvMatrixUni, invM);
-
- // This (1,1) translation is due to WebKit's 1 based coordinates for the noise
- // (as opposed to 0 based, usually). The same adjustment is in the shadeSpan() functions.
- m.postTranslate(SK_Scalar1, SK_Scalar1);
- fEffectMatrix.setData(uman, m, drawEffect, NULL);
}
void GrGLPerlinNoise::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
EffectKey,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray&) SK_OVERRIDE;
virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
EffectKey,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray& samplers) {
static const float kColorScaleFactor = 255.0f / 256.0f;
GrGLGradientEffect::GrGLGradientEffect(const GrBackendEffectFactory& factory)
: INHERITED(factory)
- , fCachedYCoord(SK_ScalarMax)
- , fEffectMatrix(kCoordsType) {
+ , fCachedYCoord(SK_ScalarMax) {
}
GrGLGradientEffect::~GrGLGradientEffect() { }
if (GrGradientEffect::kTwo_ColorType == e.getColorType()){
- fEffectMatrix.setData(uman, e.getMatrix(), drawEffect, NULL);
if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) {
set_mul_color_uni(uman, fColorStartUni, e.getColors(0));
set_mul_color_uni(uman, fColorEndUni, e.getColors(1));
} else if (GrGradientEffect::kThree_ColorType == e.getColorType()){
- fEffectMatrix.setData(uman, e.getMatrix(), drawEffect, NULL);
if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) {
set_mul_color_uni(uman, fColorStartUni, e.getColors(0));
set_mul_color_uni(uman, fColorMidUni, e.getColors(1));
set_color_uni(uman, fColorEndUni, e.getColors(2));
}
} else {
- const GrTexture* texture = e.texture(0);
- fEffectMatrix.setData(uman, e.getMatrix(), drawEffect, texture);
SkScalar yCoord = e.getYCoord();
if (yCoord != fCachedYCoord) {
GrGLEffect::EffectKey GrGLGradientEffect::GenBaseGradientKey(const GrDrawEffect& drawEffect) {
const GrGradientEffect& e = drawEffect.castEffect<GrGradientEffect>();
- const GrTexture* texture = NULL;
- if (GrGradientEffect::kTexture_ColorType == e.getColorType()){
- texture = e.texture(0);
- }
-
- EffectKey key = GrGLEffectMatrix::GenKey(e.getMatrix(), drawEffect, kCoordsType, texture);
+ EffectKey key = 0;
if (GrGradientEffect::kTwo_ColorType == e.getColorType()) {
key |= kTwoColorKey;
return key;
}
-void GrGLGradientEffect::setupMatrix(GrGLShaderBuilder* builder,
- EffectKey key,
- SkString* fsCoordName,
- SkString* vsVaryingName,
- GrSLType* vsVaryingType) {
- fEffectMatrix.emitCodeMakeFSCoords2D(builder,
- key & kMatrixKeyMask,
- fsCoordName,
- vsVaryingName,
- vsVaryingType);
-}
-
void GrGLGradientEffect::emitColor(GrGLShaderBuilder* builder,
const char* gradientTValue,
EffectKey key,
const SkMatrix& matrix,
SkShader::TileMode tileMode) {
-
- fMatrix = matrix;
fIsOpaque = shader.isOpaque();
SkShader::GradientInfo info;
} else {
fPremulType = kAfterInterp_PremulType;
}
+ fCoordTransform.reset(kCoordSet, matrix);
} else {
// doesn't matter how this is set, just be consistent because it is part of the effect key.
fPremulType = kBeforeInterp_PremulType;
if (-1 != fRow) {
fYCoord = fAtlas->getYOffset(fRow) + SK_ScalarHalf *
fAtlas->getVerticalScaleFactor();
+ fCoordTransform.reset(kCoordSet, matrix, fAtlas->getTexture());
fTextureAccess.reset(fAtlas->getTexture(), params);
} else {
GrTexture* texture = GrLockAndRefCachedBitmapTexture(ctx, bitmap, ¶ms);
+ fCoordTransform.reset(kCoordSet, matrix, texture);
fTextureAccess.reset(texture, params);
fYCoord = SK_ScalarHalf;
}
this->addTextureAccess(&fTextureAccess);
}
+ this->addCoordTransform(&fCoordTransform);
}
GrGradientEffect::~GrGradientEffect() {
s.fTextureAccess.getParams().getTileModeX() &&
this->useAtlas() == s.useAtlas() &&
fYCoord == s.getYCoord() &&
- fMatrix.cheapEqualTo(s.getMatrix());
+ fCoordTransform.getMatrix().cheapEqualTo(s.fCoordTransform.getMatrix());
}
return false;
#if SK_SUPPORT_GPU
+#include "GrCoordTransform.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLEffectMatrix.h"
class GrEffectStage;
class GrBackendEffectFactory;
bool useAtlas() const { return SkToBool(-1 != fRow); }
SkScalar getYCoord() const { return fYCoord; };
- const SkMatrix& getMatrix() const { return fMatrix;}
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
virtual bool onIsEqual(const GrEffect& effect) const SK_OVERRIDE;
private:
+ static const GrCoordSet kCoordSet = kLocal_GrCoordSet;
enum {
kMaxAnalyticColors = 3 // if more colors use texture
};
+ GrCoordTransform fCoordTransform;
GrTextureAccess fTextureAccess;
SkScalar fYCoord;
GrTextureStripAtlas* fAtlas;
int fRow;
- SkMatrix fMatrix;
bool fIsOpaque;
ColorType fColorType;
SkColor fColors[kMaxAnalyticColors];
virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
protected:
- /**
- * Subclasses must reserve the lower kMatrixKeyBitCnt of their key for use by
- * GrGLGradientEffect.
- */
enum {
- kMatrixKeyBitCnt = GrGLEffectMatrix::kKeyBits,
- kMatrixKeyMask = (1 << kMatrixKeyBitCnt) - 1,
-
kPremulTypeKeyBitCnt = 1,
- kPremulTypeMask = 1 << kMatrixKeyBitCnt,
+ kPremulTypeMask = 1,
kPremulBeforeInterpKey = kPremulTypeMask,
- kTwoColorKey = 2 << (kMatrixKeyBitCnt + kPremulTypeKeyBitCnt),
- kThreeColorKey = 3 << (kMatrixKeyBitCnt + kPremulTypeKeyBitCnt),
+ kTwoColorKey = 2 << kPremulTypeKeyBitCnt,
+ kThreeColorKey = 3 << kPremulTypeKeyBitCnt,
kColorKeyMask = kTwoColorKey | kThreeColorKey,
kColorKeyBitCnt = 2,
// Subclasses must shift any key bits they produce up by this amount
// and combine with the result of GenBaseGradientKey.
- kBaseKeyBitCnt = (kMatrixKeyBitCnt + kPremulTypeKeyBitCnt + kColorKeyBitCnt)
+ kBaseKeyBitCnt = (kPremulTypeKeyBitCnt + kColorKeyBitCnt)
};
static GrGradientEffect::ColorType ColorTypeFromKey(EffectKey key){
*/
static EffectKey GenBaseGradientKey(const GrDrawEffect&);
- /**
- * Inserts code to implement the GrGradientEffect's matrix. This should be called before a
- * subclass emits its own code. The name of the 2D coords is output via fsCoordName and already
- * incorporates any perspective division. The caller can also optionally retrieve the name of
- * the varying inserted in the VS and its type, which may be either vec2f or vec3f depending
- * upon whether the matrix has perspective or not. It is not necessary to mask the key before
- * calling.
- */
- void setupMatrix(GrGLShaderBuilder* builder,
- EffectKey key,
- SkString* fsCoordName,
- SkString* vsVaryingName = NULL,
- GrSLType* vsVaryingType = NULL);
-
// Emits the uniform used as the y-coord to texture samples in derived classes. Subclasses
// should call this method from their emitCode().
void emitUniforms(GrGLShaderBuilder* builder, EffectKey key);
const GrGLShaderBuilder::TextureSamplerArray& samplers);
private:
- static const GrEffect::CoordsType kCoordsType = GrEffect::kLocal_CoordsType;
-
SkScalar fCachedYCoord;
GrGLUniformManager::UniformHandle fFSYUni;
GrGLUniformManager::UniformHandle fColorStartUni;
GrGLUniformManager::UniformHandle fColorMidUni;
GrGLUniformManager::UniformHandle fColorEndUni;
- GrGLEffectMatrix fEffectMatrix;
typedef GrGLEffect INHERITED;
};
EffectKey,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray&) SK_OVERRIDE;
static EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) {
this->emitUniforms(builder, key);
- SkString coords;
- this->setupMatrix(builder, key, &coords);
- SkString t;
- t.append(coords);
+ SkString t = builder->ensureFSCoords2D(coords, 0);
t.append(".x");
this->emitColor(builder, t.c_str(), key, outputColor, inputColor, samplers);
}
EffectKey,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray&) SK_OVERRIDE;
static EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) {
this->emitUniforms(builder, key);
- SkString coords;
- this->setupMatrix(builder, key, &coords);
SkString t("length(");
- t.append(coords);
+ t.append(builder->ensureFSCoords2D(coords, 0));
t.append(")");
this->emitColor(builder, t.c_str(), key, outputColor, inputColor, samplers);
}
EffectKey,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray&) SK_OVERRIDE;
static EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) {
this->emitUniforms(builder, key);
- SkString coords;
- this->setupMatrix(builder, key, &coords);
+ SkString coords2D = builder->ensureFSCoords2D(coords, 0);
SkString t;
- t.printf("atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5", coords.c_str(), coords.c_str());
+ t.printf("atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5", coords2D.c_str(), coords2D.c_str());
this->emitColor(builder, t.c_str(), key,
outputColor, inputColor, samplers);
}
EffectKey,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray&) SK_OVERRIDE;
virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) {
- SkString fsCoords;
- SkString vsCoordsVarying;
- GrSLType coordsVaryingType;
- this->setupMatrix(builder, key, &fsCoords, &vsCoordsVarying, &coordsVaryingType);
-
this->emitUniforms(builder, key);
// 2 copies of uniform array, 1 for each of vertex & fragment shader,
// to work around Xoom bug. Doesn't seem to cause performance decrease
// For radial gradients without perspective we can pass the linear
// part of the quadratic as a varying.
GrGLShaderBuilder::VertexBuilder* vertexBuilder =
- (kVec2f_GrSLType == coordsVaryingType) ? builder->getVertexBuilder() : NULL;
+ (kVec2f_GrSLType == coords[0].type()) ? builder->getVertexBuilder() : NULL;
if (NULL != vertexBuilder) {
vertexBuilder->addVarying(kFloat_GrSLType, "Conical2BCoeff",
&fVSVaryingName, &fFSVaryingName);
// r2Var = -2 * (r2Parm[2] * varCoord.x - r2Param[3] * r2Param[5])
vertexBuilder->vsCodeAppendf("\t%s = -2.0 * (%s * %s.x + %s * %s);\n",
fVSVaryingName, p2.c_str(),
- vsCoordsVarying.c_str(), p3.c_str(), p5.c_str());
+ coords[0].getVSName().c_str(), p3.c_str(), p5.c_str());
}
}
// FS
{
-
+ SkString coords2D = builder->ensureFSCoords2D(coords, 0);
SkString cName("c");
SkString ac4Name("ac4");
SkString dName("d");
} else {
bVar = "b";
builder->fsCodeAppendf("\tfloat %s = -2.0 * (%s * %s.x + %s * %s);\n",
- bVar.c_str(), p2.c_str(), fsCoords.c_str(),
+ bVar.c_str(), p2.c_str(), coords2D.c_str(),
p3.c_str(), p5.c_str());
}
// c = (x^2)+(y^2) - params[4]
builder->fsCodeAppendf("\tfloat %s = dot(%s, %s) - %s;\n", cName.c_str(),
- fsCoords.c_str(), fsCoords.c_str(),
+ coords2D.c_str(), coords2D.c_str(),
p4.c_str());
// Non-degenerate case (quadratic)
EffectKey,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray&) SK_OVERRIDE;
virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) {
this->emitUniforms(builder, key);
- SkString fsCoords;
- SkString vsCoordsVarying;
-
- GrSLType coordsVaryingType;
- this->setupMatrix(builder, key, &fsCoords, &vsCoordsVarying, &coordsVaryingType);
-
// 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.
// For radial gradients without perspective we can pass the linear
// part of the quadratic as a varying.
GrGLShaderBuilder::VertexBuilder* vertexBuilder =
- (kVec2f_GrSLType == coordsVaryingType) ? builder->getVertexBuilder() : NULL;
+ (kVec2f_GrSLType == coords[0].type()) ? builder->getVertexBuilder() : NULL;
if (NULL != vertexBuilder) {
vertexBuilder->addVarying(kFloat_GrSLType, "Radial2BCoeff",
&fVSVaryingName, &fFSVaryingName);
// r2Var = 2 * (r2Parm[2] * varCoord.x - r2Param[3])
vertexBuilder->vsCodeAppendf("\t%s = 2.0 *(%s * %s.x - %s);\n",
fVSVaryingName, p2.c_str(),
- vsCoordsVarying.c_str(), p3.c_str());
+ coords[0].getVSName().c_str(), p3.c_str());
}
}
// FS
{
+ SkString coords2D = builder->ensureFSCoords2D(coords, 0);
SkString cName("c");
SkString ac4Name("ac4");
SkString rootName("root");
} else {
bVar = "b";
builder->fsCodeAppendf("\tfloat %s = 2.0 * (%s * %s.x - %s);\n",
- bVar.c_str(), p2.c_str(), fsCoords.c_str(), p3.c_str());
+ bVar.c_str(), p2.c_str(), coords2D.c_str(), p3.c_str());
}
// c = (x^2)+(y^2) - params[4]
builder->fsCodeAppendf("\tfloat %s = dot(%s, %s) - %s;\n",
cName.c_str(),
- fsCoords.c_str(),
- fsCoords.c_str(),
+ coords2D.c_str(),
+ coords2D.c_str(),
p4.c_str());
// If we aren't degenerate, emit some extra code, and accept a slightly
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray& samplers) SK_OVERRIDE {
GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder();
SkASSERT(NULL != vertexBuilder);
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray& samplers) SK_OVERRIDE {
GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder();
SkASSERT(NULL != vertexBuilder);
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray& samplers) SK_OVERRIDE {
GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder();
SkASSERT(NULL != vertexBuilder);
GrTextureDomainEffect::MakeTexelDomain(result, domainTexels),
GrTextureDomainEffect::kDecal_WrapMode,
GrTextureParams::kNone_FilterMode,
- GrEffect::kPosition_CoordsType))->unref();
+ kPosition_GrCoordSet))->unref();
}
bool path_needs_SW_renderer(GrContext* context,
#include "GrEffect.h"
#include "GrBackendEffectFactory.h"
#include "GrContext.h"
+#include "GrCoordTransform.h"
#include "GrMemoryPool.h"
#include "SkTLS.h"
return this->getFactory().name();
}
+void GrEffect::addCoordTransform(const GrCoordTransform* transform) {
+ fCoordTransforms.push_back(transform);
+}
+
void GrEffect::addTextureAccess(const GrTextureAccess* access) {
fTextureAccesses.push_back(access);
}
void GrEffect::operator delete(void* target) {
GrEffect_Globals::GetTLS()->release(target);
}
+
+#ifdef SK_DEBUG
+void GrEffect::assertEquality(const GrEffect& other) const {
+ SkASSERT(this->numTransforms() == other.numTransforms());
+ for (int i = 0; i < this->numTransforms(); ++i) {
+ SkASSERT(this->coordTransform(i) == other.coordTransform(i));
+ }
+ SkASSERT(this->numTextures() == other.numTextures());
+ for (int i = 0; i < this->numTextures(); ++i) {
+ SkASSERT(this->textureAccess(i) == other.textureAccess(i));
+ }
+}
+#endif
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray& samplers) SK_OVERRIDE {
GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder();
SkASSERT(NULL != vertexBuilder);
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray& samplers) SK_OVERRIDE {
GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder();
SkASSERT(NULL != vertexBuilder);
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray& samplers) SK_OVERRIDE {
GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder();
SkASSERT(NULL != vertexBuilder);
GrSimpleTextureEffect::Create(texture,
maskMatrix,
GrTextureParams::kNone_FilterMode,
- GrEffect::kPosition_CoordsType))->unref();
+ kPosition_GrCoordSet))->unref();
target->drawSimpleRect(dstRect);
}
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray&) SK_OVERRIDE;
static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray& samplers) {
GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder();
SkASSERT(NULL != vertexBuilder);
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray&) SK_OVERRIDE;
static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray& samplers) {
GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder();
SkASSERT(NULL != vertexBuilder);
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray&) SK_OVERRIDE;
static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray& samplers) {
GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder();
SkASSERT(NULL != vertexBuilder);
EffectKey,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray&) SK_OVERRIDE;
- static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
-
virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
private:
UniformHandle fCoefficientsUni;
UniformHandle fImageIncrementUni;
- GrGLEffectMatrix fEffectMatrix;
-
typedef GrGLEffect INHERITED;
};
-GrGLBicubicEffect::GrGLBicubicEffect(const GrBackendEffectFactory& factory,
- const GrDrawEffect& drawEffect)
- : INHERITED(factory)
- , fEffectMatrix(drawEffect.castEffect<GrBicubicEffect>().coordsType()) {
+GrGLBicubicEffect::GrGLBicubicEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
+ : INHERITED(factory) {
}
void GrGLBicubicEffect::emitCode(GrGLShaderBuilder* builder,
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) {
- SkString coords;
- fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, &coords);
+ SkString coords2D = builder->ensureFSCoords2D(coords, 0);
fCoefficientsUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
kMat44f_GrSLType, "Coefficients");
fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
"\tvec4 c = coefficients * ts;\n"
"\treturn c.x * c0 + c.y * c1 + c.z * c2 + c.w * c3;\n",
&cubicBlendName);
- builder->fsCodeAppendf("\tvec2 coord = %s - %s * vec2(0.5, 0.5);\n", coords.c_str(), imgInc);
+ builder->fsCodeAppendf("\tvec2 coord = %s - %s * vec2(0.5, 0.5);\n", coords2D.c_str(), imgInc);
builder->fsCodeAppendf("\tvec2 f = fract(coord / %s);\n", imgInc);
for (int y = 0; y < 4; ++y) {
for (int x = 0; x < 4; ++x) {
builder->fsCodeAppendf("\t%s = %s(%s, f.y, s0, s1, s2, s3);\n", outputColor, cubicBlendName.c_str(), coeff);
}
-GrGLEffect::EffectKey GrGLBicubicEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
- const GrBicubicEffect& bicubic = drawEffect.castEffect<GrBicubicEffect>();
- EffectKey matrixKey = GrGLEffectMatrix::GenKey(bicubic.getMatrix(),
- drawEffect,
- bicubic.coordsType(),
- bicubic.texture(0));
- return matrixKey;
-}
-
void GrGLBicubicEffect::setData(const GrGLUniformManager& uman,
const GrDrawEffect& drawEffect) {
const GrBicubicEffect& effect = drawEffect.castEffect<GrBicubicEffect>();
imageIncrement[1] = 1.0f / texture.height();
uman.set2fv(fImageIncrementUni, 0, 1, imageIncrement);
uman.setMatrix4f(fCoefficientsUni, effect.coefficients());
- fEffectMatrix.setData(uman,
- effect.getMatrix(),
- drawEffect,
- effect.texture(0));
}
GrBicubicEffect::GrBicubicEffect(GrTexture* texture,
const SkScalar coefficients[16],
const SkMatrix &matrix,
const GrTextureParams ¶ms,
- CoordsType coordsType)
- : INHERITED(texture, MakeDivByTextureWHMatrix(texture), params, coordsType) {
+ GrCoordSet coordSet)
+ : INHERITED(texture, MakeDivByTextureWHMatrix(texture), params, coordSet) {
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
// Convert from row-major scalars to column-major floats.
#include "GrSingleTextureEffect.h"
#include "GrDrawEffect.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLEffectMatrix.h"
#include "GrTBackendEffectFactory.h"
class GrGLBicubicEffect;
static GrEffectRef* Create(GrTexture* tex, const SkScalar coefficients[16],
const SkMatrix& matrix,
const GrTextureParams& p,
- CoordsType coordsType = kLocal_CoordsType) {
- AutoEffectUnref effect(SkNEW_ARGS(GrBicubicEffect, (tex, coefficients, matrix, p, coordsType)));
+ GrCoordSet coordSet = kLocal_GrCoordSet) {
+ AutoEffectUnref effect(SkNEW_ARGS(GrBicubicEffect, (tex, coefficients, matrix, p, coordSet)));
return CreateEffectRef(effect);
}
static GrEffectRef* Create(GrTexture* tex,
const SkMatrix& matrix,
const GrTextureParams& p,
- CoordsType coordsType = kLocal_CoordsType) {
- return Create(tex, gMitchellCoefficients, matrix, p, coordsType);
+ GrCoordSet coordSet = kLocal_GrCoordSet) {
+ return Create(tex, gMitchellCoefficients, matrix, p, coordSet);
}
private:
GrBicubicEffect(GrTexture*, const SkScalar coefficients[16]);
GrBicubicEffect(GrTexture*, const SkScalar coefficients[16],
- const SkMatrix &matrix, const GrTextureParams &p, CoordsType coordsType);
+ const SkMatrix &matrix, const GrTextureParams &p, GrCoordSet coordSet);
virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
float fCoefficients[16];
#include "GrTBackendEffectFactory.h"
#include "GrSimpleTextureEffect.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLEffectMatrix.h"
#include "SkMatrix.h"
class GrGLConfigConversionEffect : public GrGLEffect {
public:
GrGLConfigConversionEffect(const GrBackendEffectFactory& factory,
const GrDrawEffect& drawEffect)
- : INHERITED (factory)
- , fEffectMatrix(drawEffect.castEffect<GrConfigConversionEffect>().coordsType()) {
+ : INHERITED (factory) {
const GrConfigConversionEffect& effect = drawEffect.castEffect<GrConfigConversionEffect>();
fSwapRedAndBlue = effect.swapsRedAndBlue();
fPMConversion = effect.pmConversion();
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) SK_OVERRIDE {
- SkString coords;
- GrSLType coordsType = fEffectMatrix.emitCode(builder, key, &coords);
builder->fsCodeAppendf("\t\t%s = ", outputColor);
- builder->fsAppendTextureLookup(samplers[0], coords.c_str(), coordsType);
+ builder->fsAppendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
builder->fsCodeAppend(";\n");
if (GrConfigConversionEffect::kNone_PMConversion == fPMConversion) {
SkASSERT(fSwapRedAndBlue);
builder->fsCodeAppend(modulate.c_str());
}
- void setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
- const GrConfigConversionEffect& conv = drawEffect.castEffect<GrConfigConversionEffect>();
- fEffectMatrix.setData(uman, conv.getMatrix(), drawEffect, conv.texture(0));
- }
-
static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
const GrConfigConversionEffect& conv = drawEffect.castEffect<GrConfigConversionEffect>();
- EffectKey key = static_cast<EffectKey>(conv.swapsRedAndBlue()) | (conv.pmConversion() << 1);
- key <<= GrGLEffectMatrix::kKeyBits;
- EffectKey matrixKey = GrGLEffectMatrix::GenKey(conv.getMatrix(),
- drawEffect,
- conv.coordsType(),
- conv.texture(0));
- SkASSERT(!(matrixKey & key));
- return matrixKey | key;
+ return static_cast<EffectKey>(conv.swapsRedAndBlue()) | (conv.pmConversion() << 1);
}
private:
bool fSwapRedAndBlue;
GrConfigConversionEffect::PMConversion fPMConversion;
- GrGLEffectMatrix fEffectMatrix;
typedef GrGLEffect INHERITED;
#include "GrConvolutionEffect.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLEffectMatrix.h"
#include "gl/GrGLSL.h"
#include "gl/GrGLTexture.h"
#include "GrTBackendEffectFactory.h"
EffectKey,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray&) SK_OVERRIDE;
virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect&) SK_OVERRIDE;
UniformHandle fKernelUni;
UniformHandle fImageIncrementUni;
UniformHandle fBoundsUni;
- GrGLEffectMatrix fEffectMatrix;
typedef GrGLEffect INHERITED;
};
GrGLConvolutionEffect::GrGLConvolutionEffect(const GrBackendEffectFactory& factory,
const GrDrawEffect& drawEffect)
- : INHERITED(factory)
- , fEffectMatrix(drawEffect.castEffect<GrConvolutionEffect>().coordsType()) {
+ : INHERITED(factory) {
const GrConvolutionEffect& c = drawEffect.castEffect<GrConvolutionEffect>();
fRadius = c.radius();
fUseBounds = c.useBounds();
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) {
- SkString coords;
- fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, &coords);
+ SkString coords2D = builder->ensureFSCoords2D(coords, 0);
fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
kVec2f_GrSLType, "ImageIncrement");
if (this->useBounds()) {
const GrGLShaderVar& kernel = builder->getUniformVariable(fKernelUni);
const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
- builder->fsCodeAppendf("\t\tvec2 coord = %s - %d.0 * %s;\n", coords.c_str(), fRadius, imgInc);
+ builder->fsCodeAppendf("\t\tvec2 coord = %s - %d.0 * %s;\n", coords2D.c_str(), fRadius, imgInc);
// Manually unroll loop because some drivers don't; yields 20-30% speedup.
for (int i = 0; i < width; i++) {
}
}
uman.set1fv(fKernelUni, 0, this->width(), conv.kernel());
- fEffectMatrix.setData(uman, conv.getMatrix(), drawEffect, conv.texture(0));
}
GrGLEffect::EffectKey GrGLConvolutionEffect::GenKey(const GrDrawEffect& drawEffect,
key |= 0x2;
key |= GrConvolutionEffect::kY_Direction == conv.direction() ? 0x1 : 0x0;
}
- key <<= GrGLEffectMatrix::kKeyBits;
- EffectKey matrixKey = GrGLEffectMatrix::GenKey(conv.getMatrix(),
- drawEffect,
- conv.coordsType(),
- conv.texture(0));
- return key | matrixKey;
+ return key;
}
///////////////////////////////////////////////////////////////////////////////
#include "GrCustomCoordsTextureEffect.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLEffectMatrix.h"
#include "gl/GrGLSL.h"
#include "gl/GrGLTexture.h"
#include "GrTBackendEffectFactory.h"
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray& samplers) SK_OVERRIDE {
GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder();
SkASSERT(NULL != vertexBuilder);
builder->fsCodeAppend(";\n");
}
- static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
- return 1 << GrGLEffectMatrix::kKeyBits;
- }
-
virtual void setData(const GrGLUniformManager& uman,
const GrDrawEffect& drawEffect) SK_OVERRIDE {}
#include "GrSimpleTextureEffect.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLEffectMatrix.h"
#include "gl/GrGLSL.h"
#include "gl/GrGLTexture.h"
#include "GrTBackendEffectFactory.h"
class GrGLSimpleTextureEffect : public GrGLEffect {
public:
- GrGLSimpleTextureEffect(const GrBackendEffectFactory& factory, const GrDrawEffect& drawEffect)
- : INHERITED (factory)
- , fEffectMatrix(drawEffect.castEffect<GrSimpleTextureEffect>().coordsType()) {
+ GrGLSimpleTextureEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
+ : INHERITED (factory) {
}
virtual void emitCode(GrGLShaderBuilder* builder,
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) SK_OVERRIDE {
- SkString fsCoordName;
- GrSLType fsCoordSLType;
- fsCoordSLType = fEffectMatrix.emitCode(builder, key, &fsCoordName);
-
builder->fsCodeAppendf("\t%s = ", outputColor);
builder->fsAppendTextureLookupAndModulate(inputColor,
samplers[0],
- fsCoordName.c_str(),
- fsCoordSLType);
+ coords[0].c_str(),
+ coords[0].type());
builder->fsCodeAppend(";\n");
}
- static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
- const GrSimpleTextureEffect& ste = drawEffect.castEffect<GrSimpleTextureEffect>();
- return GrGLEffectMatrix::GenKey(ste.getMatrix(),
- drawEffect,
- ste.coordsType(),
- ste.texture(0));
- }
-
- virtual void setData(const GrGLUniformManager& uman,
- const GrDrawEffect& drawEffect) SK_OVERRIDE {
- const GrSimpleTextureEffect& ste = drawEffect.castEffect<GrSimpleTextureEffect>();
- fEffectMatrix.setData(uman, ste.getMatrix(), drawEffect, ste.texture(0));
- }
-
private:
- GrGLEffectMatrix fEffectMatrix;
typedef GrGLEffect INHERITED;
};
GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode :
GrTextureParams::kNone_FilterMode);
- static const CoordsType kCoordsTypes[] = {
- kLocal_CoordsType,
- kPosition_CoordsType
+ static const GrCoordSet kCoordSets[] = {
+ kLocal_GrCoordSet,
+ kPosition_GrCoordSet
};
- CoordsType coordsType = kCoordsTypes[random->nextULessThan(GR_ARRAY_COUNT(kCoordsTypes))];
+ GrCoordSet coordSet = kCoordSets[random->nextULessThan(GR_ARRAY_COUNT(kCoordSets))];
const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random);
- return GrSimpleTextureEffect::Create(textures[texIdx], matrix, coordsType);
+ return GrSimpleTextureEffect::Create(textures[texIdx], matrix, coordSet);
}
/* unfiltered, clamp mode */
static GrEffectRef* Create(GrTexture* tex,
const SkMatrix& matrix,
- CoordsType coordsType = kLocal_CoordsType) {
- AutoEffectUnref effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, GrTextureParams::kNone_FilterMode, coordsType)));
+ GrCoordSet coordSet = kLocal_GrCoordSet) {
+ AutoEffectUnref effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, GrTextureParams::kNone_FilterMode, coordSet)));
return CreateEffectRef(effect);
}
static GrEffectRef* Create(GrTexture* tex,
const SkMatrix& matrix,
GrTextureParams::FilterMode filterMode,
- CoordsType coordsType = kLocal_CoordsType) {
+ GrCoordSet coordSet = kLocal_GrCoordSet) {
AutoEffectUnref effect(
- SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, filterMode, coordsType)));
+ SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, filterMode, coordSet)));
return CreateEffectRef(effect);
}
static GrEffectRef* Create(GrTexture* tex,
const SkMatrix& matrix,
const GrTextureParams& p,
- CoordsType coordsType = kLocal_CoordsType) {
- AutoEffectUnref effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, p, coordsType)));
+ GrCoordSet coordSet = kLocal_GrCoordSet) {
+ AutoEffectUnref effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, p, coordSet)));
return CreateEffectRef(effect);
}
GrSimpleTextureEffect(GrTexture* texture,
const SkMatrix& matrix,
GrTextureParams::FilterMode filterMode,
- CoordsType coordsType)
- : GrSingleTextureEffect(texture, matrix, filterMode, coordsType) {
+ GrCoordSet coordSet)
+ : GrSingleTextureEffect(texture, matrix, filterMode, coordSet) {
}
GrSimpleTextureEffect(GrTexture* texture,
const SkMatrix& matrix,
const GrTextureParams& params,
- CoordsType coordsType)
- : GrSingleTextureEffect(texture, matrix, params, coordsType) {
+ GrCoordSet coordSet)
+ : GrSingleTextureEffect(texture, matrix, params, coordSet) {
}
virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
const GrSimpleTextureEffect& ste = CastEffect<GrSimpleTextureEffect>(other);
- return this->hasSameTextureParamsMatrixAndCoordsType(ste);
+ return this->hasSameTextureParamsMatrixAndSourceCoords(ste);
}
GR_DECLARE_EFFECT_TEST;
GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture,
const SkMatrix& m,
- CoordsType coordsType)
- : fTextureAccess(texture)
- , fMatrix(m)
- , fCoordsType(coordsType) {
+ GrCoordSet coordSet)
+ : fCoordTransform(coordSet, m, texture)
+ , fTextureAccess(texture) {
+ this->addCoordTransform(&fCoordTransform);
this->addTextureAccess(&fTextureAccess);
}
GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture,
const SkMatrix& m,
GrTextureParams::FilterMode filterMode,
- CoordsType coordsType)
- : fTextureAccess(texture, filterMode)
- , fMatrix(m)
- , fCoordsType(coordsType) {
+ GrCoordSet coordSet)
+ : fCoordTransform(coordSet, m, texture)
+ , fTextureAccess(texture, filterMode) {
+ this->addCoordTransform(&fCoordTransform);
this->addTextureAccess(&fTextureAccess);
}
GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture,
const SkMatrix& m,
const GrTextureParams& params,
- CoordsType coordsType)
- : fTextureAccess(texture, params)
- , fMatrix(m)
- , fCoordsType(coordsType) {
+ GrCoordSet coordSet)
+ : fCoordTransform(coordSet, m, texture)
+ , fTextureAccess(texture, params) {
+ this->addCoordTransform(&fCoordTransform);
this->addTextureAccess(&fTextureAccess);
}
#include "GrEffect.h"
#include "SkMatrix.h"
+#include "GrCoordTransform.h"
class GrTexture;
public:
virtual ~GrSingleTextureEffect();
- const SkMatrix& getMatrix() const { return fMatrix; }
-
- /** Indicates whether the matrix operates on local coords or positions */
- CoordsType coordsType() const { return fCoordsType; }
-
protected:
/** unfiltered, clamp mode */
- GrSingleTextureEffect(GrTexture*, const SkMatrix&, CoordsType = kLocal_CoordsType);
+ GrSingleTextureEffect(GrTexture*, const SkMatrix&, GrCoordSet = kLocal_GrCoordSet);
/** clamp mode */
GrSingleTextureEffect(GrTexture*, const SkMatrix&, GrTextureParams::FilterMode filterMode,
- CoordsType = kLocal_CoordsType);
+ GrCoordSet = kLocal_GrCoordSet);
GrSingleTextureEffect(GrTexture*,
const SkMatrix&,
const GrTextureParams&,
- CoordsType = kLocal_CoordsType);
+ GrCoordSet = kLocal_GrCoordSet);
/**
* Helper for subclass onIsEqual() functions.
*/
- bool hasSameTextureParamsMatrixAndCoordsType(const GrSingleTextureEffect& other) const {
+ bool hasSameTextureParamsMatrixAndSourceCoords(const GrSingleTextureEffect& other) const {
// We don't have to check the accesses' swizzles because they are inferred from the texture.
return fTextureAccess == other.fTextureAccess &&
- this->getMatrix().cheapEqualTo(other.getMatrix()) &&
- fCoordsType == other.fCoordsType;
+ fCoordTransform.getMatrix().cheapEqualTo(other.fCoordTransform.getMatrix()) &&
+ fCoordTransform.sourceCoords() == other.fCoordTransform.sourceCoords();
}
/**
}
private:
- GrTextureAccess fTextureAccess;
- SkMatrix fMatrix;
- CoordsType fCoordsType;
+ GrCoordTransform fCoordTransform;
+ GrTextureAccess fTextureAccess;
typedef GrEffect INHERITED;
};
#include "GrSimpleTextureEffect.h"
#include "GrTBackendEffectFactory.h"
#include "gl/GrGLEffect.h"
-#include "gl/GrGLEffectMatrix.h"
#include "SkFloatingPoint.h"
class GrGLTextureDomainEffect : public GrGLEffect {
EffectKey,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray&,
const TextureSamplerArray&) SK_OVERRIDE;
virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
private:
GrGLUniformManager::UniformHandle fNameUni;
- GrGLEffectMatrix fEffectMatrix;
GrGLfloat fPrevDomain[4];
typedef GrGLEffect INHERITED;
};
GrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrBackendEffectFactory& factory,
- const GrDrawEffect& drawEffect)
- : INHERITED(factory)
- , fEffectMatrix(drawEffect.castEffect<GrTextureDomainEffect>().coordsType()) {
+ const GrDrawEffect&)
+ : INHERITED(factory) {
fPrevDomain[0] = SK_FloatNaN;
}
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) {
const GrTextureDomainEffect& texDom = drawEffect.castEffect<GrTextureDomainEffect>();
- SkString coords;
- fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, &coords);
+ SkString coords2D = builder->ensureFSCoords2D(coords, 0);
const char* domain;
fNameUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
kVec4f_GrSLType, "TexDom", &domain);
if (GrTextureDomainEffect::kClamp_WrapMode == texDom.wrapMode()) {
builder->fsCodeAppendf("\tvec2 clampCoord = clamp(%s, %s.xy, %s.zw);\n",
- coords.c_str(), domain, domain);
+ coords2D.c_str(), domain, domain);
builder->fsCodeAppendf("\t%s = ", outputColor);
builder->fsAppendTextureLookupAndModulate(inputColor, samplers[0], "clampCoord");
// result=white;" code fails to compile.
builder->fsCodeAppend("\tvec4 outside = vec4(0.0, 0.0, 0.0, 0.0);\n");
builder->fsCodeAppend("\tvec4 inside = ");
- builder->fsAppendTextureLookupAndModulate(inputColor, samplers[0], coords.c_str());
+ builder->fsAppendTextureLookupAndModulate(inputColor, samplers[0], coords2D.c_str());
builder->fsCodeAppend(";\n");
builder->fsCodeAppendf("\tfloat x = abs(2.0*(%s.x - %s.x)/(%s.z - %s.x) - 1.0);\n",
- coords.c_str(), domain, domain, domain);
+ coords2D.c_str(), domain, domain, domain);
builder->fsCodeAppendf("\tfloat y = abs(2.0*(%s.y - %s.y)/(%s.w - %s.y) - 1.0);\n",
- coords.c_str(), domain, domain, domain);
+ coords2D.c_str(), domain, domain, domain);
builder->fsCodeAppend("\tfloat blend = step(1.0, max(x, y));\n");
builder->fsCodeAppendf("\t%s = mix(inside, outside, blend);\n", outputColor);
} else {
builder->fsCodeAppend("\tbvec4 outside;\n");
- builder->fsCodeAppendf("\toutside.xy = lessThan(%s, %s.xy);\n", coords.c_str(), domain);
- builder->fsCodeAppendf("\toutside.zw = greaterThan(%s, %s.zw);\n", coords.c_str(), domain);
+ builder->fsCodeAppendf("\toutside.xy = lessThan(%s, %s.xy);\n", coords2D.c_str(), domain);
+ builder->fsCodeAppendf("\toutside.zw = greaterThan(%s, %s.zw);\n", coords2D.c_str(), domain);
builder->fsCodeAppendf("\t%s = any(outside) ? vec4(0.0, 0.0, 0.0, 0.0) : ", outputColor);
- builder->fsAppendTextureLookupAndModulate(inputColor, samplers[0], coords.c_str());
+ builder->fsAppendTextureLookupAndModulate(inputColor, samplers[0], coords2D.c_str());
builder->fsCodeAppend(";\n");
}
}
uman.set4fv(fNameUni, 0, 1, values);
memcpy(fPrevDomain, values, 4 * sizeof(GrGLfloat));
}
- fEffectMatrix.setData(uman,
- texDom.getMatrix(),
- drawEffect,
- texDom.texture(0));
}
GrGLEffect::EffectKey GrGLTextureDomainEffect::GenKey(const GrDrawEffect& drawEffect,
const GrGLCaps&) {
- const GrTextureDomainEffect& texDom = drawEffect.castEffect<GrTextureDomainEffect>();
- EffectKey key = texDom.wrapMode();
- key <<= GrGLEffectMatrix::kKeyBits;
- EffectKey matrixKey = GrGLEffectMatrix::GenKey(texDom.getMatrix(),
- drawEffect,
- texDom.coordsType(),
- texDom.texture(0));
- return key | matrixKey;
+ return drawEffect.castEffect<GrTextureDomainEffect>().wrapMode();
}
const SkRect& domain,
WrapMode wrapMode,
GrTextureParams::FilterMode filterMode,
- CoordsType coordsType) {
+ GrCoordSet coordSet) {
static const SkRect kFullRect = {0, 0, SK_Scalar1, SK_Scalar1};
if (kClamp_WrapMode == wrapMode && domain.contains(kFullRect)) {
return GrSimpleTextureEffect::Create(texture, matrix, filterMode);
clippedDomain,
wrapMode,
filterMode,
- coordsType)));
+ coordSet)));
return CreateEffectRef(effect);
}
const SkRect& domain,
WrapMode wrapMode,
GrTextureParams::FilterMode filterMode,
- CoordsType coordsType)
- : GrSingleTextureEffect(texture, matrix, filterMode, coordsType)
+ GrCoordSet coordSet)
+ : GrSingleTextureEffect(texture, matrix, filterMode, coordSet)
, fWrapMode(wrapMode)
, fTextureDomain(domain) {
}
bool GrTextureDomainEffect::onIsEqual(const GrEffect& sBase) const {
const GrTextureDomainEffect& s = CastEffect<GrTextureDomainEffect>(sBase);
- return this->hasSameTextureParamsMatrixAndCoordsType(s) &&
+ return this->hasSameTextureParamsMatrixAndSourceCoords(s) &&
this->fTextureDomain == s.fTextureDomain;
}
WrapMode wrapMode = random->nextBool() ? kClamp_WrapMode : kDecal_WrapMode;
const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random);
bool bilerp = random->nextBool();
- CoordsType coords = random->nextBool() ? kLocal_CoordsType : kPosition_CoordsType;
+ GrCoordSet coords = random->nextBool() ? kLocal_GrCoordSet : kPosition_GrCoordSet;
return GrTextureDomainEffect::Create(textures[texIdx],
matrix,
domain,
const SkRect& domain,
WrapMode,
GrTextureParams::FilterMode filterMode,
- CoordsType = kLocal_CoordsType);
+ GrCoordSet = kLocal_GrCoordSet);
virtual ~GrTextureDomainEffect();
const SkRect& domain,
WrapMode,
GrTextureParams::FilterMode filterMode,
- CoordsType type);
+ GrCoordSet);
virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
* found in the LICENSE file.
*/
-#include "GrGLEffectMatrix.h"
+#include "GrGLCoordTransform.h"
#include "GrDrawEffect.h"
#include "GrTexture.h"
+#include "GrGLShaderBuilder.h"
-GrGLEffect::EffectKey GrGLEffectMatrix::GenKey(const SkMatrix& effectMatrix,
- const GrDrawEffect& drawEffect,
- CoordsType coordsType,
- const GrTexture* texture) {
+GrGLCoordTransform::EffectKey GrGLCoordTransform::GenKey(const GrDrawEffect& drawEffect,
+ int transformIdx) {
+ const GrCoordTransform& transform = (*drawEffect.effect())->coordTransform(transformIdx);
EffectKey key = 0;
- SkMatrix::TypeMask type0 = effectMatrix.getType();
+ SkMatrix::TypeMask type0 = transform.getMatrix().getType();
SkMatrix::TypeMask type1;
- if (GrEffect::kLocal_CoordsType == coordsType) {
+ if (kLocal_GrCoordSet == transform.sourceCoords()) {
type1 = drawEffect.getCoordChangeMatrix().getType();
} else {
if (drawEffect.programHasExplicitLocalCoords()) {
// We only make the key indicate that device coords are referenced when the local coords
- // are not actually determined by positions.
+ // are not actually determined by positions. Otherwise the local coords var and position
+ // var are identical.
key |= kPositionCoords_Flag;
}
type1 = SkMatrix::kIdentity_Mask;
int combinedTypes = type0 | type1;
- bool reverseY = (NULL != texture) && kBottomLeft_GrSurfaceOrigin == texture->origin();
+ bool reverseY = transform.reverseY();
if (SkMatrix::kPerspective_Mask & combinedTypes) {
key |= kGeneral_MatrixType;
return key;
}
-GrSLType GrGLEffectMatrix::emitCode(GrGLShaderBuilder* builder,
- EffectKey key,
- SkString* fsCoordName,
- SkString* vsCoordName,
- const char* suffix) {
+void GrGLCoordTransform::emitCode(GrGLShaderBuilder* builder,
+ EffectKey key,
+ TransformedCoords* transformedCoords,
+ int suffix) {
GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder();
SkASSERT(NULL != vertexBuilder);
GrSLType varyingType = kVoid_GrSLType;
const char* uniName;
- key &= kKeyMask;
switch (key & kMatrixTypeKeyMask) {
case kIdentity_MatrixType:
fUniType = kVoid_GrSLType;
}
SkString suffixedUniName;
if (kVoid_GrSLType != fUniType) {
- if (NULL != suffix) {
+ if (0 != suffix) {
suffixedUniName.append(uniName);
- suffixedUniName.append(suffix);
+ suffixedUniName.appendf("_%i", suffix);
uniName = suffixedUniName.c_str();
}
fUni = builder->addUniform(GrGLShaderBuilder::kVertex_Visibility,
const char* varyingName = "MatrixCoord";
SkString suffixedVaryingName;
- if (NULL != suffix) {
+ if (0 != suffix) {
suffixedVaryingName.append(varyingName);
- suffixedVaryingName.append(suffix);
+ suffixedVaryingName.appendf("_%i", suffix);
varyingName = suffixedVaryingName.c_str();
}
const char* vsVaryingName;
const char* fsVaryingName;
vertexBuilder->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName);
- const GrGLShaderVar* coords;
- switch (fCoordsType) {
- case GrEffect::kLocal_CoordsType:
- SkASSERT(!(kPositionCoords_Flag & key));
- coords = &vertexBuilder->localCoordsAttribute();
- break;
- case GrEffect::kPosition_CoordsType:
- SkASSERT((kPositionCoords_Flag & key) || !vertexBuilder->hasExplicitLocalCoords());
- coords = &vertexBuilder->positionAttribute();
- break;
- default:
- coords = NULL; // prevents warning
- GrCrash("Unexpected coords type.");
- }
+ const GrGLShaderVar& coords = (kPositionCoords_Flag & key) ?
+ vertexBuilder->positionAttribute() :
+ vertexBuilder->localCoordsAttribute();
// varying = matrix * coords (logically)
switch (fUniType) {
case kVoid_GrSLType:
SkASSERT(kVec2f_GrSLType == varyingType);
- vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, coords->c_str());
+ vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, coords.c_str());
break;
case kVec2f_GrSLType:
SkASSERT(kVec2f_GrSLType == varyingType);
vertexBuilder->vsCodeAppendf("\t%s = %s + %s;\n",
- vsVaryingName, uniName, coords->c_str());
+ vsVaryingName, uniName, coords.c_str());
break;
case kMat33f_GrSLType: {
SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
if (kVec2f_GrSLType == varyingType) {
vertexBuilder->vsCodeAppendf("\t%s = (%s * vec3(%s, 1)).xy;\n",
- vsVaryingName, uniName, coords->c_str());
+ vsVaryingName, uniName, coords.c_str());
} else {
vertexBuilder->vsCodeAppendf("\t%s = %s * vec3(%s, 1);\n",
- vsVaryingName, uniName, coords->c_str());
+ vsVaryingName, uniName, coords.c_str());
}
break;
}
default:
GrCrash("Unexpected uniform type.");
}
- if (NULL != vsCoordName) {
- *vsCoordName = vsVaryingName;
- }
- if (NULL != fsCoordName) {
- *fsCoordName = fsVaryingName;
- }
- return varyingType;
-}
-
-/**
- * This is similar to emitCode except that it performs perspective division in the FS if the
- * texture coordinates have a w coordinate. The fsCoordName always refers to a vec2f.
- */
-void GrGLEffectMatrix::emitCodeMakeFSCoords2D(GrGLShaderBuilder* builder,
- EffectKey key,
- SkString* fsCoordName,
- SkString* vsVaryingName,
- GrSLType* vsVaryingType,
- const char* suffix) {
- SkString fsVaryingName;
-
- GrSLType varyingType = this->emitCode(builder,
- key,
- &fsVaryingName,
- vsVaryingName,
- suffix);
- if (kVec3f_GrSLType == varyingType) {
-
- const char* coordName = "coords2D";
- SkString suffixedCoordName;
- if (NULL != suffix) {
- suffixedCoordName.append(coordName);
- suffixedCoordName.append(suffix);
- coordName = suffixedCoordName.c_str();
- }
- builder->fsCodeAppendf("\tvec2 %s = %s.xy / %s.z;",
- coordName, fsVaryingName.c_str(), fsVaryingName.c_str());
- if (NULL != fsCoordName) {
- *fsCoordName = coordName;
- }
- } else if(NULL != fsCoordName) {
- *fsCoordName = fsVaryingName;
- }
- if (NULL != vsVaryingType) {
- *vsVaryingType = varyingType;
- }
+ SkASSERT(NULL != transformedCoords);
+ transformedCoords->fName = fsVaryingName;
+ transformedCoords->fType = varyingType;
+ transformedCoords->fVSName = vsVaryingName;
}
-void GrGLEffectMatrix::setData(const GrGLUniformManager& uniformManager,
- const SkMatrix& matrix,
- const GrDrawEffect& drawEffect,
- const GrTexture* texture) {
+void GrGLCoordTransform::setData(const GrGLUniformManager& uniformManager,
+ const GrDrawEffect& drawEffect,
+ int transformIdx) {
SkASSERT(fUni.isValid() != (kVoid_GrSLType == fUniType));
- const SkMatrix& coordChangeMatrix = GrEffect::kLocal_CoordsType == fCoordsType ?
+ const GrCoordTransform& transform = (*drawEffect.effect())->coordTransform(transformIdx);
+ const SkMatrix& matrix = transform.getMatrix();
+ const SkMatrix& coordChangeMatrix = kLocal_GrCoordSet == transform.sourceCoords() ?
drawEffect.getCoordChangeMatrix() :
SkMatrix::I();
switch (fUniType) {
case kVoid_GrSLType:
SkASSERT(matrix.isIdentity());
SkASSERT(coordChangeMatrix.isIdentity());
- SkASSERT(NULL == texture || kTopLeft_GrSurfaceOrigin == texture->origin());
+ SkASSERT(!transform.reverseY());
return;
case kVec2f_GrSLType: {
SkASSERT(SkMatrix::kTranslate_Mask == (matrix.getType() | coordChangeMatrix.getType()));
- SkASSERT(NULL == texture || kTopLeft_GrSurfaceOrigin == texture->origin());
+ SkASSERT(!transform.reverseY());
SkScalar tx = matrix[SkMatrix::kMTransX] + (coordChangeMatrix)[SkMatrix::kMTransX];
SkScalar ty = matrix[SkMatrix::kMTransY] + (coordChangeMatrix)[SkMatrix::kMTransY];
if (fPrevMatrix.get(SkMatrix::kMTransX) != tx ||
case kMat33f_GrSLType: {
SkMatrix combined;
combined.setConcat(matrix, coordChangeMatrix);
- if (NULL != texture && kBottomLeft_GrSurfaceOrigin == texture->origin()) {
+ if (transform.reverseY()) {
// combined.postScale(1,-1);
// combined.postTranslate(0,1);
combined.set(SkMatrix::kMSkewY,
--- /dev/null
+/*
+ * 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 GrGLCoordTransform_DEFINED
+#define GrGLCoordTransform_DEFINED
+
+#include "GrBackendEffectFactory.h"
+#include "GrCoordTransform.h"
+#include "GrGLUniformManager.h"
+
+class GrTexture;
+class GrGLShaderBuilder;
+
+/**
+ * This is a helper class used by the framework to implement a coordinate transform that operates on
+ * incoming coords in the vertex shader and writes them to a varying to be used in the fragment
+ * shader. Effects should not use this class directly, but instead call GrEffect::addCoordTransform.
+ * When the input coords are local coordinates this class accounts for the coord change matrix
+ * communicated via GrDrawEffect. The input coords may also be positions and in this case the coord
+ * change matrix is ignored. The GrGLCoordTransform may emit different code based on the type of
+ * matrix and thus must contribute to the effect's key.
+ *
+ * This class cannot be used to apply a matrix to coordinates that come in the form of custom vertex
+ * attributes.
+ */
+class GrGLCoordTransform {
+private:
+ // We specialize the generated code for each of these matrix types.
+ enum MatrixTypes {
+ kIdentity_MatrixType = 0,
+ kTrans_MatrixType = 1,
+ kNoPersp_MatrixType = 2,
+ kGeneral_MatrixType = 3,
+ };
+ // The key for is made up of a matrix type and a bit that indicates the source of the input
+ // coords.
+ enum {
+ kMatrixTypeKeyBits = 2,
+ kMatrixTypeKeyMask = (1 << kMatrixTypeKeyBits) - 1,
+ kPositionCoords_Flag = (1 << kMatrixTypeKeyBits),
+ kKeyBitsPrivate = kMatrixTypeKeyBits + 1,
+ };
+
+public:
+
+ typedef GrBackendEffectFactory::EffectKey EffectKey;
+
+ /**
+ * A GrGLCoordTransform key is kKeyBits long. The framework automatically generates and includes
+ * these in EffectKeys.
+ */
+ enum {
+ kKeyBits = kKeyBitsPrivate,
+ kKeyMask = (1 << kKeyBits) - 1,
+ };
+
+ GrGLCoordTransform() { fPrevMatrix = SkMatrix::InvalidMatrix(); }
+
+ /**
+ * Generates the key for the portion of the code emitted by this class's emitCode() function.
+ */
+ static EffectKey GenKey(const GrDrawEffect&, int transformIdx);
+
+ /**
+ * Stores the name and type of a transformed set of coordinates. This class is passed to
+ * GrGLEffect::emitCode.
+ */
+ class TransformedCoords {
+ public:
+ const char* c_str() const { return fName.c_str(); }
+ GrSLType type() const { return fType; }
+ const SkString& getName() const { return fName; }
+ // TODO: Remove the VS name when we have vertexless shaders, and gradients are reworked.
+ const SkString& getVSName() const { return fVSName; }
+
+ private:
+ friend class GrGLCoordTransform;
+
+ SkString fName;
+ GrSLType fType;
+ SkString fVSName;
+ };
+
+ /**
+ * Emits code to implement the matrix in the VS. A varying is added as an output of the VS and
+ * input to the FS. The varying may be either a vec2f or vec3f depending upon whether
+ * perspective interpolation is required or not. The names of the varying in the VS and FS as
+ * well as its type are written to the TransformedCoords* object. The suffix is an optional
+ * parameter that can be used to make all variables emitted by the object unique within a stage.
+ * It is only necessary if multiple GrGLCoordTransform objects are used by a single GrGLEffect.
+ */
+ void emitCode(GrGLShaderBuilder*, EffectKey, TransformedCoords*, int suffix = 0);
+
+ /**
+ * Call from a GrGLEffect's subclass to update the texture matrix. The matrix and reverseY value
+ * should match those used with GenKey.
+ */
+ void setData(const GrGLUniformManager&, const GrDrawEffect&, int transformIdx);
+
+ GrGLUniformManager::UniformHandle fUni;
+ GrSLType fUniType;
+ SkMatrix fPrevMatrix;
+};
+
+#endif
#include "GrGLSL.h"
#include "GrGLEffect.h"
+#include "GrCoordTransform.h"
#include "GrDrawEffect.h"
GrGLEffect::GrGLEffect(const GrBackendEffectFactory& factory)
return key;
}
+GrGLEffect::EffectKey GrGLEffect::GenTransformKey(const GrDrawEffect& drawEffect) {
+ EffectKey key = 0;
+ int numTransforms = (*drawEffect.effect())->numTransforms();
+ for (int index = 0; index < numTransforms; ++index) {
+ EffectKey value = GrGLCoordTransform::GenKey(drawEffect, index);
+ value <<= index * GrGLCoordTransform::kKeyBits;
+ SkASSERT(0 == (value & key)); // keys for each transform ought not to overlap
+ key |= value;
+ }
+ return key;
+}
+
GrGLEffect::EffectKey GrGLEffect::GenAttribKey(const GrDrawEffect& drawEffect) {
EffectKey key = 0;
/** @file
This file contains specializations for OpenGL of the shader stages declared in
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:
+ GLSL code that implements a GrEffect and for uploading uniforms at draw time. If they don't
+ always emit the same GLSL code, they must have a function:
static inline EffectKey GenKey(const GrDrawEffect&, 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.
kEffectKeyBits = GrBackendEffectFactory::kEffectKeyBits,
};
+ typedef GrGLShaderBuilder::TransformedCoordsArray TransformedCoordsArray;
typedef GrGLShaderBuilder::TextureSamplerArray TextureSamplerArray;
GrGLEffect(const GrBackendEffectFactory&);
EffectKey key,
const char* outputColor,
const char* inputColor,
+ const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) = 0;
/** A GrGLEffect instance can be reused with any GrEffect that produces the same stage
const char* name() const { return fFactory.name(); }
+ static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&) { return 0; }
+
static EffectKey GenTextureKey(const GrDrawEffect&, const GrGLCaps&);
+ static EffectKey GenTransformKey(const GrDrawEffect&);
static EffectKey GenAttribKey(const GrDrawEffect& stage);
protected:
+++ /dev/null
-/*
- * 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 GrGLEffectMatrix_DEFINED
-#define GrGLEffectMatrix_DEFINED
-
-#include "GrGLEffect.h"
-#include "SkMatrix.h"
-
-class GrTexture;
-
-/**
- * This is a helper to implement a matrix in a GrGLEffect that operates on incoming coords in the
- * vertex shader and writes them to an attribute to be used in the fragment shader. When the input
- * coords in the vertex shader are local coordinates this class accounts for the coord change matrix
- * communicated via GrDrawEffect. The input coords may also be positions and in this case the coord
- * change matrix is ignored. The GrGLEffectMatrix will emit different code based on the type of
- * matrix and thus must contribute to the effect's key.
- *
- * This class cannot be used to apply a matrix to coordinates that come in the form of custom vertex
- * attributes.
- */
-class GrGLEffectMatrix {
-private:
- // We specialize the generated code for each of these matrix types.
- enum MatrixTypes {
- kIdentity_MatrixType = 0,
- kTrans_MatrixType = 1,
- kNoPersp_MatrixType = 2,
- kGeneral_MatrixType = 3,
- };
- // The key for is made up of a matrix type and a bit that indicates the source of the input
- // coords.
- enum {
- kMatrixTypeKeyBits = 2,
- kMatrixTypeKeyMask = (1 << kMatrixTypeKeyBits) - 1,
- kPositionCoords_Flag = (1 << kMatrixTypeKeyBits),
- kKeyBitsPrivate = kMatrixTypeKeyBits + 1,
- };
-
-public:
-
- typedef GrEffect::CoordsType CoordsType;
-
- typedef GrGLEffect::EffectKey EffectKey;
-
- /**
- * The matrix uses kKeyBits of the effect's EffectKey. A GrGLEffect may place these bits at an
- * arbitrary shift in its final key. However, when GrGLEffectMatrix::emitCode*() code is called
- * the relevant bits must be in the lower kKeyBits of the key parameter.
- */
- enum {
- kKeyBits = kKeyBitsPrivate,
- kKeyMask = (1 << kKeyBits) - 1,
- };
-
- GrGLEffectMatrix(CoordsType coordsType)
- : fCoordsType(coordsType) {
- fPrevMatrix = SkMatrix::InvalidMatrix();
- }
-
- /**
- * Generates the key for the portion of the code emitted by this class's emitCode() function.
- * Pass a texture to make GrGLEffectMatrix automatically adjust for the texture's origin. Pass
- * NULL when not using the EffectMatrix for a texture lookup, or if the GrGLEffect subclass
- * wants to handle origin adjustments in some other manner. The coords type param must match the
- * param that would be used to initialize GrGLEffectMatrix for the generating GrEffect.
- */
- static EffectKey GenKey(const SkMatrix& effectMatrix,
- const GrDrawEffect&,
- CoordsType,
- const GrTexture*);
-
- /**
- * Emits code to implement the matrix in the VS. A varying is added as an output of the VS and
- * input to the FS. The varying may be either a vec2f or vec3f depending upon whether
- * perspective interpolation is required or not. The names of the varying in the VS and FS are
- * are returned as output parameters and the type of the varying is the return value. The suffix
- * is an optional parameter that can be used to make all variables emitted by the object
- * unique within a stage. It is only necessary if multiple GrGLEffectMatrix objects are used by
- * a single GrGLEffect.
- */
- GrSLType emitCode(GrGLShaderBuilder*,
- EffectKey,
- SkString* fsCoordName, /* optional */
- SkString* vsCoordName = NULL,
- const char* suffix = NULL);
-
- /**
- * This is similar to emitCode except that it performs perspective division in the FS if the
- * texture coordinates have a w coordinate. The fsCoordName always refers to a vec2f.
- */
- void emitCodeMakeFSCoords2D(GrGLShaderBuilder*,
- EffectKey,
- SkString* fsCoordName, /* optional */
- SkString* vsVaryingName = NULL,
- GrSLType* vsVaryingType = NULL,
- const char* suffix = NULL);
- /**
- * Call from a GrGLEffect's subclass to update the texture matrix. The effectMatrix and texture
- * params should match those used with GenKey.
- */
- void setData(const GrGLUniformManager& uniformManager,
- const SkMatrix& effectMatrix,
- const GrDrawEffect& drawEffect,
- const GrTexture*);
-
- GrGLUniformManager::UniformHandle fUni;
- GrSLType fUniType;
- SkMatrix fPrevMatrix;
- CoordsType fCoordsType;
-};
-
-#endif
#include "GrAllocator.h"
#include "GrEffect.h"
+#include "GrCoordTransform.h"
#include "GrDrawEffect.h"
#include "GrGLEffect.h"
#include "GrGpuGL.h"
need_blend_inputs(filterColorCoeff, colorCoeff, &needFilterColor, &needColor);
// used in order for builder to return the per-stage uniform handles.
+ typedef SkTArray<GrGLCoordTransform, false>* CoordTransformArrayPtr;
typedef SkTArray<GrGLUniformManager::UniformHandle, true>* UniHandleArrayPtr;
int maxColorOrCovEffectCnt = GrMax(fDesc.numColorEffects(), fDesc.numCoverageEffects());
+ SkAutoTArray<CoordTransformArrayPtr> effectCoordTransformArrays(maxColorOrCovEffectCnt);
SkAutoTArray<UniHandleArrayPtr> effectUniformArrays(maxColorOrCovEffectCnt);
SkAutoTArray<GrGLEffect*> glEffects(maxColorOrCovEffectCnt);
if (needColor) {
for (int e = 0; e < fDesc.numColorEffects(); ++e) {
+ effectCoordTransformArrays[e] = &fColorEffects[e].fCoordTransforms;
effectUniformArrays[e] = &fColorEffects[e].fSamplerUnis;
}
fDesc.numColorEffects(),
&inColor,
&knownColorValue,
+ effectCoordTransformArrays.get(),
effectUniformArrays.get(),
glEffects.get());
GrSLConstantVec knownCoverageValue = builder.getKnownCoverageValue();
for (int e = 0; e < fDesc.numCoverageEffects(); ++e) {
+ effectCoordTransformArrays[e] = &fCoverageEffects[e].fCoordTransforms;
effectUniformArrays[e] = &fCoverageEffects[e].fSamplerUnis;
}
fDesc.numCoverageEffects(),
&inCoverage,
&knownCoverageValue,
+ effectCoordTransformArrays.get(),
effectUniformArrays.get(),
glEffects.get());
for (int e = 0; e < fDesc.numCoverageEffects(); ++e) {
///////////////////////////////////////////////////////////////////////////////
void GrGLProgram::setEffectData(const GrEffectStage& stage,
- const EffectAndSamplers& effect) {
+ EffectAndSamplers& effect) {
// Let the GrGLEffect set its data.
bool explicitLocalCoords = -1 != fDesc.getHeader().fLocalCoordAttributeIndex;
GrDrawEffect drawEffect(stage, explicitLocalCoords);
effect.fGLEffect->setData(fUniformManager, drawEffect);
+ // Set the effect's coord transform matrices.
+ int numTransforms = effect.fCoordTransforms.count();
+ SkASSERT((*stage.getEffect())->numTransforms() == numTransforms);
+ for (int c = 0; c < numTransforms; ++c) {
+ effect.fCoordTransforms[c].setData(fUniformManager, drawEffect, c);
+ }
+
// Bind the texures for the effect.
int numSamplers = effect.fSamplerUnis.count();
SkASSERT((*stage.getEffect())->numTextures() == numSamplers);
#include "GrDrawState.h"
#include "GrGLContext.h"
+#include "GrGLCoordTransform.h"
#include "GrGLProgramDesc.h"
#include "GrGLShaderBuilder.h"
#include "GrGLSL.h"
UniformHandle fDstCopySamplerUni;
};
+ typedef SkSTArray<4, GrGLCoordTransform, false> CoordTransformSArray;
typedef SkSTArray<4, UniformHandle, true> SamplerUniSArray;
typedef SkSTArray<4, int, true> TextureUnitSArray;
struct EffectAndSamplers {
EffectAndSamplers() : fGLEffect(NULL) {}
~EffectAndSamplers() { delete fGLEffect; }
- GrGLEffect* fGLEffect;
- SamplerUniSArray fSamplerUnis; // sampler uni handles for effect's GrTextureAccess
- TextureUnitSArray fTextureUnits; // texture unit used for each entry of fSamplerUnis
+ GrGLEffect* fGLEffect;
+ CoordTransformSArray fCoordTransforms;
+ SamplerUniSArray fSamplerUnis; // sampler uni handles for effect's GrTextureAccess
+ TextureUnitSArray fTextureUnits; // texture unit used for each entry of fSamplerUnis
};
GrGLProgram(GrGpuGL* gpu,
void initEffectSamplerUniforms(EffectAndSamplers* effect, int* texUnitIdx);
// Helper for setData().
- void setEffectData(const GrEffectStage& stage, const EffectAndSamplers& effect);
+ void setEffectData(const GrEffectStage& stage, EffectAndSamplers& effect);
// Helper for setData(). Makes GL calls to specify the initial color when there is not
// per-vertex colors.
#include "gl/GrGLShaderBuilder.h"
#include "gl/GrGLProgram.h"
#include "gl/GrGLUniformHandle.h"
+#include "GrCoordTransform.h"
#include "GrDrawEffect.h"
#include "GrGpuGL.h"
#include "GrTexture.h"
GrGLSLModulatef<4>(&fFSCode, modulation, lookup.c_str());
}
-GrBackendEffectFactory::EffectKey GrGLShaderBuilder::KeyForTextureAccess(
- const GrTextureAccess& access,
- const GrGLCaps& caps) {
+GrGLShaderBuilder::EffectKey GrGLShaderBuilder::KeyForTextureAccess(const GrTextureAccess& access,
+ const GrGLCaps& caps) {
uint32_t configComponentMask = GrPixelConfigComponentMask(access.getTexture()->config());
if (swizzle_requires_alpha_remapping(caps, configComponentMask, access.swizzleMask())) {
return 1;
return h;
}
+SkString GrGLShaderBuilder::ensureFSCoords2D(const TransformedCoordsArray& coords, int index) {
+ if (kVec3f_GrSLType != coords[index].type()) {
+ SkASSERT(kVec2f_GrSLType == coords[index].type());
+ return coords[index].getName();
+ }
+
+ SkString coords2D("coords2D");
+ if (0 != index) {
+ coords2D.appendf("_%i", index);
+ }
+ this->fsCodeAppendf("\tvec2 %s = %s.xy / %s.z;",
+ coords2D.c_str(), coords[index].c_str(), coords[index].c_str());
+ return coords2D;
+}
+
const char* GrGLShaderBuilder::fragmentPosition() {
if (fCodeStage.inStageCode()) {
const GrEffectRef& effect = *fCodeStage.effectStage()->getEffect();
void GrGLShaderBuilder::emitEffects(
const GrEffectStage* effectStages[],
- const GrBackendEffectFactory::EffectKey effectKeys[],
+ const EffectKey effectKeys[],
int effectCnt,
SkString* fsInOutColor,
GrSLConstantVec* fsInOutColorKnownValue,
+ SkTArray<GrGLCoordTransform, false>* effectCoordTransformArrays[],
SkTArray<GrGLUniformManager::UniformHandle, true>* effectSamplerHandles[],
GrGLEffect* glEffects[]) {
bool effectEmitted = false;
CodeStage::AutoStageRestore csar(&fCodeStage, &stage);
+ int numTransforms = effect->numTransforms();
+ SkSTArray<8, GrGLCoordTransform::TransformedCoords> transformedCoords;
+ transformedCoords.push_back_n(numTransforms);
+ EffectKey transformKey = GrBackendEffectFactory::GetTransformKey(effectKeys[e]);
+ for (int c = 0; c < numTransforms; ++c) {
+ GrGLCoordTransform& ct = effectCoordTransformArrays[e]->push_back();
+ EffectKey key = (transformKey >> (c * GrGLCoordTransform::kKeyBits)) &
+ (GrGLCoordTransform::kKeyMask);
+ ct.emitCode(this, key, &transformedCoords[c], c);
+ }
+
int numTextures = effect->numTextures();
SkSTArray<8, GrGLShaderBuilder::TextureSampler> textureSamplers;
textureSamplers.push_back_n(numTextures);
textureSamplers[t].init(this, &effect->textureAccess(t), t);
effectSamplerHandles[e]->push_back(textureSamplers[t].fSamplerUniform);
}
+
GrDrawEffect drawEffect(stage, NULL != fVertexBuilder.get()
&& fVertexBuilder->hasExplicitLocalCoords());
effectKeys[e],
outColor.c_str(),
inColor.isEmpty() ? NULL : inColor.c_str(),
+ transformedCoords,
textureSamplers);
if (NULL != fVertexBuilder.get()) {
#include "GrColor.h"
#include "GrEffect.h"
#include "SkTypes.h"
+#include "gl/GrGLCoordTransform.h"
#include "gl/GrGLSL.h"
#include "gl/GrGLUniformManager.h"
friend class GrGLShaderBuilder; // to call init().
};
+ typedef SkTArray<GrGLCoordTransform::TransformedCoords> TransformedCoordsArray;
typedef SkTArray<TextureSampler> TextureSamplerArray;
typedef GrTAllocator<GrGLShaderVar> VarArray;
+ typedef GrBackendEffectFactory::EffectKey EffectKey;
enum ShaderVisibility {
kVertex_Visibility = 0x1,
/** 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 GrBackendEffectFactory::EffectKey KeyForTextureAccess(const GrTextureAccess&,
- const GrGLCaps&);
+ static EffectKey KeyForTextureAccess(const GrTextureAccess&, const GrGLCaps&);
typedef uint8_t DstReadKey;
typedef uint8_t FragPosKey;
return this->getUniformVariable(u).c_str();
}
+ /**
+ * This returns a variable name to access the 2D, perspective correct version of the coords in
+ * the fragment shader. If the coordinates at index are 3-dimensional, it immediately emits a
+ * perspective divide into the fragment shader (xy / z) to convert them to 2D.
+ */
+ SkString ensureFSCoords2D(const TransformedCoordsArray&, int index);
+
/** Returns a variable name that represents the position of the fragment in the FS. The position
is in device space (e.g. 0,0 is the top left and pixel centers are at half-integers). */
const char* fragmentPosition();
* effectStages.
*/
void emitEffects(const GrEffectStage* effectStages[],
- const GrBackendEffectFactory::EffectKey effectKeys[],
+ const EffectKey effectKeys[],
int effectCnt,
SkString* inOutFSColor,
GrSLConstantVec* fsInOutColorKnownValue,
+ SkTArray<GrGLCoordTransform, false>* effectCoordTransformArrays[],
SkTArray<GrGLUniformManager::UniformHandle, true>* effectSamplerHandles[],
GrGLEffect* glEffects[]);