diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-03-29 19:22:36 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-03-29 19:22:36 +0000 |
commit | 26e18b593ab65e4d92dfbce92579d8bc180d4c2c (patch) | |
tree | ddc5eddf771019decfe6a3401ea9b2da79dbc68a /include | |
parent | e36f3baa78cbf4a7bab6e5f14702d6a4d259abde (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.h | 16 | ||||
-rw-r--r-- | include/gpu/GrEffect.h | 13 | ||||
-rw-r--r-- | include/gpu/GrTexture.h | 39 |
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 |