aboutsummaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-03-29 19:22:36 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-03-29 19:22:36 +0000
commit26e18b593ab65e4d92dfbce92579d8bc180d4c2c (patch)
treeddc5eddf771019decfe6a3401ea9b2da79dbc68a /include
parente36f3baa78cbf4a7bab6e5f14702d6a4d259abde (diff)
Add support for reading the dst pixel value in an effect. Use in a new effect for the kDarken xfer mode.
The current implementation is to always make a copy of the entire dst before the draw. It will only succeed if the RT is also a texture. Obviously, there is lots of room for improvement. Review URL: https://codereview.chromium.org/13314002 git-svn-id: http://skia.googlecode.com/svn/trunk@8449 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'include')
-rw-r--r--include/core/SkXfermode.h16
-rw-r--r--include/gpu/GrEffect.h13
-rw-r--r--include/gpu/GrTexture.h39
3 files changed, 62 insertions, 6 deletions
diff --git a/include/core/SkXfermode.h b/include/core/SkXfermode.h
index 0a0099f3e2..92e240b6c2 100644
--- a/include/core/SkXfermode.h
+++ b/include/core/SkXfermode.h
@@ -188,16 +188,24 @@ public:
src, and dst must all be NULL or all non-NULL. If effect is non-NULL then the xfermode may
optionally allocate an effect to return and the caller as *effect. The caller will install
it and own a ref to it. Since the xfermode may or may not assign *effect, the caller should
- set *effect to NULL beforehand. If the function returns true then the src and dst coeffs
- will be applied to the draw regardless of whether an effect was returned.
+ set *effect to NULL beforehand. If the function returns true and *effect is NULL then the
+ src and dst coeffs will be applied to the draw. When *effect is non-NULL the coeffs are
+ ignored.
*/
- virtual bool asNewEffect(GrContext*, GrEffectRef** effect, Coeff* src, Coeff* dst) const;
+ virtual bool asNewEffectOrCoeff(GrContext*,
+ GrEffectRef** effect,
+ Coeff* src,
+ Coeff* dst) const;
/**
* The same as calling xfermode->asNewEffect(...), except that this also checks if the xfermode
* is NULL, and if so, treats it as kSrcOver_Mode.
*/
- static bool AsNewEffect(SkXfermode*, GrContext*, GrEffectRef** effect, Coeff* src, Coeff* dst);
+ static bool AsNewEffectOrCoeff(SkXfermode*,
+ GrContext*,
+ GrEffectRef** effect,
+ Coeff* src,
+ Coeff* dst);
SkDEVCODE(virtual void toString(SkString* str) const = 0;)
SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
diff --git a/include/gpu/GrEffect.h b/include/gpu/GrEffect.h
index de4b2a14fb..08f34e0364 100644
--- a/include/gpu/GrEffect.h
+++ b/include/gpu/GrEffect.h
@@ -138,6 +138,8 @@ public:
/** Shortcut for textureAccess(index).texture(); */
GrTexture* texture(int index) const { return this->textureAccess(index).getTexture(); }
+ /** Will this effect read the destination pixel value? */
+ bool willReadDst() const { return fWillReadDst; }
int numVertexAttribs() const { return fVertexAttribTypes.count(); }
@@ -145,7 +147,6 @@ public:
static const int kMaxVertexAttribs = 2;
-
/** Useful for effects that want to insert a texture matrix that is implied by the texture
dimensions */
static inline SkMatrix MakeDivByTextureWHMatrix(const GrTexture* texture) {
@@ -191,7 +192,7 @@ protected:
*/
void addVertexAttrib(GrSLType type);
- GrEffect() : fEffectRef(NULL) {};
+ GrEffect() : fWillReadDst(false), fEffectRef(NULL) {}
/** This should be called by GrEffect subclass factories. See the comment on AutoEffectUnref for
an example factory function. */
@@ -234,6 +235,13 @@ protected:
return *static_cast<const T*>(&effectRef);
}
+ /**
+ * If the effect subclass will read the destination pixel value then it must call this function
+ * from its constructor. Otherwise, when its generated backend-specific effect class attempts
+ * to generate code that reads the destination pixel it will fail.
+ */
+ void setWillReadDst() { fWillReadDst = true; }
+
private:
bool isEqual(const GrEffect& other) const {
if (&this->getFactory() != &other.getFactory()) {
@@ -265,6 +273,7 @@ private:
SkSTArray<4, const GrTextureAccess*, true> fTextureAccesses;
SkSTArray<kMaxVertexAttribs, GrSLType, true> fVertexAttribTypes;
+ bool fWillReadDst;
GrEffectRef* fEffectRef;
typedef GrRefCnt INHERITED;
diff --git a/include/gpu/GrTexture.h b/include/gpu/GrTexture.h
index c088bdd582..5d8ecaaaf2 100644
--- a/include/gpu/GrTexture.h
+++ b/include/gpu/GrTexture.h
@@ -10,6 +10,7 @@
#define GrTexture_DEFINED
#include "GrSurface.h"
+#include "SkPoint.h"
class GrRenderTarget;
class GrResourceKey;
@@ -166,4 +167,42 @@ private:
typedef GrSurface INHERITED;
};
+/**
+ * Represents a texture that is intended to be accessed in device coords with an offset.
+ */
+class GrDeviceCoordTexture {
+public:
+ GrDeviceCoordTexture() { fOffset.set(0, 0); }
+
+ GrDeviceCoordTexture(const GrDeviceCoordTexture& other) {
+ *this = other;
+ }
+
+ GrDeviceCoordTexture(GrTexture* texture, const SkIPoint& offset)
+ : fTexture(SkSafeRef(texture))
+ , fOffset(offset) {
+ }
+
+ GrDeviceCoordTexture& operator=(const GrDeviceCoordTexture& other) {
+ fTexture.reset(SkSafeRef(other.fTexture.get()));
+ fOffset = other.fOffset;
+ return *this;
+ }
+
+ const SkIPoint& offset() const { return fOffset; }
+
+ void setOffset(const SkIPoint& offset) { fOffset = offset; }
+ void setOffset(int ox, int oy) { fOffset.set(ox, oy); }
+
+ GrTexture* texture() const { return fTexture.get(); }
+
+ GrTexture* setTexture(GrTexture* texture) {
+ fTexture.reset(SkSafeRef(texture));
+ return texture;
+ }
+private:
+ SkAutoTUnref<GrTexture> fTexture;
+ SkIPoint fOffset;
+};
+
#endif