aboutsummaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-03-20 17:32:27 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-03-20 17:32:27 +0000
commitae81d5c4aa1716756b2cfb4c44f27f4dce2716ef (patch)
tree019b5c1b55da3c7da77943f8b93f5cc28da090c2 /include
parent723dd790fbef396cd5c6619d0a3656c641b0c3f5 (diff)
Adds local coords to GrEffect system.
Effects can ask the builder for local coords which may or may not be distinct from positions. GrEffectStage tracks changes to relationship between pos and local coords. GrGLEffectMatrix and GrSingleTextureEffect can use either pos or textures as intput coords GrSimpleTextureEffect now allows for an explicit texture coords attribute. Review URL: https://codereview.chromium.org/12531015 git-svn-id: http://skia.googlecode.com/svn/trunk@8264 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'include')
-rw-r--r--include/core/SkTLazy.h22
-rw-r--r--include/gpu/GrBackendEffectFactory.h8
-rw-r--r--include/gpu/GrContext.h28
-rw-r--r--include/gpu/GrDrawEffect.h51
-rw-r--r--include/gpu/GrEffect.h14
-rw-r--r--include/gpu/GrEffectStage.h7
-rw-r--r--include/gpu/GrPaint.h93
-rw-r--r--include/gpu/GrTBackendEffectFactory.h14
8 files changed, 159 insertions, 78 deletions
diff --git a/include/core/SkTLazy.h b/include/core/SkTLazy.h
index b9052f0d99..1934b5dff9 100644
--- a/include/core/SkTLazy.h
+++ b/include/core/SkTLazy.h
@@ -14,6 +14,9 @@
#include "SkTypes.h"
#include <new>
+template <typename T> class SkTLazy;
+template <typename T> void* operator new(size_t, SkTLazy<T>* lazy);
+
/**
* Efficient way to defer allocating/initializing a class until it is needed
* (if ever).
@@ -44,7 +47,7 @@ public:
/**
* Return a pointer to a default-initialized instance of the class. If a
- * previous instance had been initialzied (either from init() or set()) it
+ * previous instance had been initialized (either from init() or set()) it
* will first be destroyed, so that a freshly initialized instance is
* always returned.
*/
@@ -84,10 +87,27 @@ public:
T* get() const { SkASSERT(this->isValid()); return fPtr; }
private:
+ friend void* operator new<T>(size_t, SkTLazy* lazy);
+
T* fPtr; // NULL or fStorage
char fStorage[sizeof(T)];
};
+// Use the below macro (SkNEW_IN_TLAZY) rather than calling this directly
+template <typename T> void* operator new(size_t, SkTLazy<T>* lazy) {
+ SkASSERT(!lazy->isValid());
+ lazy->fPtr = reinterpret_cast<T*>(lazy->fStorage);
+ return lazy->fPtr;
+}
+
+// Skia doesn't use C++ exceptions but it may be compiled with them enabled. Having an op delete
+// to match the op new silences warnings about missing op delete when a constructor throws an
+// exception.
+template <typename T> void operator delete(void*, SkTLazy<T>) { SK_CRASH(); }
+
+// Use this to construct a T inside an SkTLazy using a non-default constructor.
+#define SkNEW_IN_TLAZY(tlazy_ptr, type_name, args) (new (tlazy_ptr) type_name args)
+
/**
* A helper built on top of SkTLazy to do copy-on-first-write. The object is initialized
* with a const pointer but provides a non-const pointer accessor. The first time the
diff --git a/include/gpu/GrBackendEffectFactory.h b/include/gpu/GrBackendEffectFactory.h
index 99d6a73a25..da296c9469 100644
--- a/include/gpu/GrBackendEffectFactory.h
+++ b/include/gpu/GrBackendEffectFactory.h
@@ -24,16 +24,16 @@
*/
class GrEffectRef;
-class GrEffectStage;
class GrGLEffect;
class GrGLCaps;
+class GrDrawEffect;
class GrBackendEffectFactory : public GrNoncopyable {
public:
typedef uint32_t EffectKey;
enum {
kNoEffectKey = 0,
- kEffectKeyBits = 12,
+ kEffectKeyBits = 16,
/**
* 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
@@ -44,8 +44,8 @@ public:
kAttribKeyBits = 6
};
- virtual EffectKey glEffectKey(const GrEffectStage&, const GrGLCaps&) const = 0;
- virtual GrGLEffect* createGLInstance(const GrEffectRef&) const = 0;
+ virtual EffectKey glEffectKey(const GrDrawEffect&, const GrGLCaps&) const = 0;
+ virtual GrGLEffect* createGLInstance(const GrDrawEffect&) const = 0;
bool operator ==(const GrBackendEffectFactory& b) const {
return fEffectClassID == b.fEffectClassID;
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index 79edd0b11b..2d5766056b 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -390,25 +390,23 @@ public:
const SkMatrix* matrix = NULL);
/**
- * Maps a rect of paint coordinates onto the a rect of destination
- * coordinates. Each rect can optionally be transformed. The srcRect
+ * Maps a rect of local coordinates onto the a rect of destination
+ * coordinates. Each rect can optionally be transformed. The localRect
* is stretched over the dstRect. The dstRect is transformed by the
- * context's matrix and the srcRect is transformed by the paint's matrix.
- * Additional optional matrices can be provided by parameters.
+ * context's matrix. Additional optional matrices for both rects can be
+ * provided by parameters.
*
- * @param paint describes how to color pixels.
- * @param dstRect the destination rect to draw.
- * @param srcRect rect of paint coordinates to be mapped onto dstRect
- * @param dstMatrix Optional matrix to transform dstRect. Applied before
- * context's matrix.
- * @param srcMatrix Optional matrix to transform srcRect Applied before
- * paint's matrix.
+ * @param paint describes how to color pixels.
+ * @param dstRect the destination rect to draw.
+ * @param localRect rect of local coordinates to be mapped onto dstRect
+ * @param dstMatrix Optional matrix to transform dstRect. Applied before context's matrix.
+ * @param localMatrix Optional matrix to transform localRect.
*/
void drawRectToRect(const GrPaint& paint,
const GrRect& dstRect,
- const GrRect& srcRect,
+ const GrRect& localRect,
const SkMatrix* dstMatrix = NULL,
- const SkMatrix* srcMatrix = NULL);
+ const SkMatrix* localMatrix = NULL);
/**
* Draws a path.
@@ -699,7 +697,7 @@ public:
this->restore();
if (NULL != paint) {
- if (!paint->sourceCoordChangeByInverse(context->getMatrix())) {
+ if (!paint->localCoordChangeInverse(context->getMatrix())) {
return false;
}
}
@@ -737,7 +735,7 @@ public:
*/
void preConcat(const SkMatrix& preConcat, GrPaint* paint = NULL) {
if (NULL != paint) {
- paint->sourceCoordChange(preConcat);
+ paint->localCoordChange(preConcat);
}
fContext->concatMatrix(preConcat);
}
diff --git a/include/gpu/GrDrawEffect.h b/include/gpu/GrDrawEffect.h
new file mode 100644
index 0000000000..005de417ee
--- /dev/null
+++ b/include/gpu/GrDrawEffect.h
@@ -0,0 +1,51 @@
+
+#ifndef GrDrawEffect_DEFINED
+#define GrDrawEffect_DEFINED
+
+#include "GrEffectStage.h"
+
+/**
+ * This class is used to communicate the particular GrEffect used in a draw to the backend-specific
+ * effect subclass (e.g. GrGLEffect). It is used to by the backend-specific class to generate a
+ * cache key for the effect, generate code on a program cache miss, and to upload uniform values to
+ * the program.
+ * In addition to the effect, it also communicates any changes between the relationship between
+ * the view matrix and local coordinate system since the effect was installed in its GrDrawState.
+ * 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.
+ */
+class GrDrawEffect {
+public:
+ GrDrawEffect(const GrEffectStage& stage, bool explicitLocalCoords)
+ : fEffectStage(&stage)
+ , fExplicitLocalCoords(explicitLocalCoords) {
+ GrAssert(NULL != fEffectStage);
+ GrAssert(NULL != fEffectStage->getEffect());
+ }
+ const GrEffectRef* effect() const { return fEffectStage->getEffect(); }
+
+ template <typename T>
+ const T& castEffect() const { return *static_cast<const T*>(this->effect()->get()); }
+
+ const SkMatrix& getCoordChangeMatrix() const {
+ if (fExplicitLocalCoords) {
+ return SkMatrix::I();
+ } else {
+ return fEffectStage->getCoordChangeMatrix();
+ }
+ }
+
+ bool programHasExplicitLocalCoords() const { return fExplicitLocalCoords; }
+
+ const int* getVertexAttribIndices() const { return fEffectStage->getVertexAttribIndices(); }
+ int getVertexAttribIndexCount() const { return fEffectStage->getVertexAttribIndexCount(); }
+
+private:
+ const GrEffectStage* fEffectStage;
+ bool fExplicitLocalCoords;
+};
+
+#endif
diff --git a/include/gpu/GrEffect.h b/include/gpu/GrEffect.h
index 1b2604114d..883438603d 100644
--- a/include/gpu/GrEffect.h
+++ b/include/gpu/GrEffect.h
@@ -70,6 +70,20 @@ class GrEffect : private GrRefCnt {
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. kCustom_CoordsType is provided to signify that an alternative set of coords
+ * is used (usually an explicit vertex attribute) but its meaning is determined by the effect
+ * subclass.
+ */
+ enum CoordsType {
+ kLocal_CoordsType,
+ kPosition_CoordsType,
+
+ kCustom_CoordsType,
+ };
+
virtual ~GrEffect();
/**
diff --git a/include/gpu/GrEffectStage.h b/include/gpu/GrEffectStage.h
index f4e46b0dea..94ff779a18 100644
--- a/include/gpu/GrEffectStage.h
+++ b/include/gpu/GrEffectStage.h
@@ -58,9 +58,10 @@ public:
/**
* This is called when the coordinate system in which the geometry is specified will change.
*
- * @param matrix The transformation from the old coord system to the new one.
+ * @param matrix The transformation from the old coord system in which geometry is specified
+ * to the new one from which it will actually be drawn.
*/
- void preConcatCoordChange(const SkMatrix& matrix) { fCoordChangeMatrix.preConcat(matrix); }
+ void localCoordChange(const SkMatrix& matrix) { fCoordChangeMatrix.preConcat(matrix); }
class SavedCoordChange {
private:
@@ -72,7 +73,7 @@ public:
/**
* This gets the current coordinate system change. It is the accumulation of
- * preConcatCoordChange calls since the effect was installed. It is used when then caller
+ * localCoordChange calls since the effect was installed. It is used when then caller
* wants to temporarily change the source geometry coord system, draw something, and then
* restore the previous coord system (e.g. temporarily draw in device coords).
*/
diff --git a/include/gpu/GrPaint.h b/include/gpu/GrPaint.h
index 0fd42f9f7f..8e2ebcdf07 100644
--- a/include/gpu/GrPaint.h
+++ b/include/gpu/GrPaint.h
@@ -169,54 +169,6 @@ public:
bool hasStage() const { return this->hasColorStage() || this->hasCoverageStage(); }
- /**
- * Called when the source coord system is changing. preConcatInverse is the inverse of the
- * transformation from the old coord system to the new coord system. Returns false if the matrix
- * cannot be inverted.
- */
- bool sourceCoordChangeByInverse(const SkMatrix& preConcatInverse) {
- SkMatrix inv;
- bool computed = false;
- for (int i = 0; i < kMaxColorStages; ++i) {
- if (this->isColorStageEnabled(i)) {
- if (!computed && !preConcatInverse.invert(&inv)) {
- return false;
- } else {
- computed = true;
- }
- fColorStages[i].preConcatCoordChange(inv);
- }
- }
- for (int i = 0; i < kMaxCoverageStages; ++i) {
- if (this->isCoverageStageEnabled(i)) {
- if (!computed && !preConcatInverse.invert(&inv)) {
- return false;
- } else {
- computed = true;
- }
- fCoverageStages[i].preConcatCoordChange(inv);
- }
- }
- return true;
- }
-
- /**
- * Called when the source coord system is changing. preConcat gives the transformation from the
- * old coord system to the new coord system.
- */
- void sourceCoordChange(const SkMatrix& preConcat) {
- for (int i = 0; i < kMaxColorStages; ++i) {
- if (this->isColorStageEnabled(i)) {
- fColorStages[i].preConcatCoordChange(preConcat);
- }
- }
- for (int i = 0; i < kMaxCoverageStages; ++i) {
- if (this->isCoverageStageEnabled(i)) {
- fCoverageStages[i].preConcatCoordChange(preConcat);
- }
- }
- }
-
GrPaint& operator=(const GrPaint& paint) {
fSrcBlendCoeff = paint.fSrcBlendCoeff;
fDstBlendCoeff = paint.fDstBlendCoeff;
@@ -264,6 +216,51 @@ public:
};
private:
+ /**
+ * Called when the source coord system from which geometry is rendered changes. It ensures that
+ * the local coordinates seen by effects remains unchanged. oldToNew gives the transformation
+ * from the previous coord system to the new coord system.
+ */
+ void localCoordChange(const SkMatrix& oldToNew) {
+ for (int i = 0; i < kMaxColorStages; ++i) {
+ if (this->isColorStageEnabled(i)) {
+ fColorStages[i].localCoordChange(oldToNew);
+ }
+ }
+ for (int i = 0; i < kMaxCoverageStages; ++i) {
+ if (this->isCoverageStageEnabled(i)) {
+ fCoverageStages[i].localCoordChange(oldToNew);
+ }
+ }
+ }
+
+ bool localCoordChangeInverse(const SkMatrix& newToOld) {
+ SkMatrix oldToNew;
+ bool computed = false;
+ for (int i = 0; i < kMaxColorStages; ++i) {
+ if (this->isColorStageEnabled(i)) {
+ if (!computed && !newToOld.invert(&oldToNew)) {
+ return false;
+ } else {
+ computed = true;
+ }
+ fColorStages[i].localCoordChange(oldToNew);
+ }
+ }
+ for (int i = 0; i < kMaxCoverageStages; ++i) {
+ if (this->isCoverageStageEnabled(i)) {
+ if (!computed && !newToOld.invert(&oldToNew)) {
+ return false;
+ } else {
+ computed = true;
+ }
+ fCoverageStages[i].localCoordChange(oldToNew);
+ }
+ }
+ return true;
+ }
+
+ friend GrContext; // To access above two functions
GrEffectStage fColorStages[kMaxColorStages];
GrEffectStage fCoverageStages[kMaxCoverageStages];
diff --git a/include/gpu/GrTBackendEffectFactory.h b/include/gpu/GrTBackendEffectFactory.h
index 1b6f8167bf..8697f8eb7a 100644
--- a/include/gpu/GrTBackendEffectFactory.h
+++ b/include/gpu/GrTBackendEffectFactory.h
@@ -9,7 +9,7 @@
#define GrTBackendEffectFactory_DEFINED
#include "GrBackendEffectFactory.h"
-#include "GrEffectStage.h"
+#include "GrDrawEffect.h"
/**
* Implements GrBackendEffectFactory for a GrEffect subclass as a singleton.
@@ -30,12 +30,12 @@ public:
id identifies the GrEffect subclass. The remainder is based
on the aspects of the GrEffect object's configuration that affect
GLSL code generation. */
- virtual EffectKey glEffectKey(const GrEffectStage& stage,
+ virtual EffectKey glEffectKey(const GrDrawEffect& drawEffect,
const GrGLCaps& caps) const SK_OVERRIDE {
GrAssert(kIllegalEffectClassID != fEffectClassID);
- EffectKey effectKey = GLEffect::GenKey(stage, caps);
- EffectKey textureKey = GLEffect::GenTextureKey(stage.getEffect(), caps);
- EffectKey attribKey = GLEffect::GenAttribKey(stage);
+ EffectKey effectKey = GLEffect::GenKey(drawEffect, caps);
+ EffectKey textureKey = GLEffect::GenTextureKey(drawEffect, caps);
+ EffectKey attribKey = GLEffect::GenAttribKey(drawEffect);
#if GR_DEBUG
static const EffectKey kIllegalIDMask = (uint16_t) (~((1U << kEffectKeyBits) - 1));
GrAssert(!(kIllegalIDMask & effectKey));
@@ -53,8 +53,8 @@ public:
/** Returns a new instance of the appropriate *GL* implementation class
for the given GrEffect; caller is responsible for deleting
the object. */
- virtual GLEffect* createGLInstance(const GrEffectRef& effect) const SK_OVERRIDE {
- return SkNEW_ARGS(GLEffect, (*this, effect));
+ virtual GLEffect* createGLInstance(const GrDrawEffect& drawEffect) const SK_OVERRIDE {
+ return SkNEW_ARGS(GLEffect, (*this, drawEffect));
}
/** This class is a singleton. This function returns the single instance.