| /* |
| * 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 GrTextureDomainEffect_DEFINED |
| #define GrTextureDomainEffect_DEFINED |
| |
| #include "GrSingleTextureEffect.h" |
| #include "GrRect.h" |
| |
| class GrGLTextureDomainEffect; |
| |
| /** |
| * Limits a texture's lookup coordinates to a domain. Samples outside the domain are either clamped |
| * the edge of the domain or result in a vec4 of zeros. The domain is clipped to normalized texture |
| * coords ([0,1]x[0,1] square). Bilinear filtering can cause texels outside the domain to affect the |
| * read value unless the caller considers this when calculating the domain. TODO: This should be a |
| * helper that can assist an effect rather than effect unto itself. |
| */ |
| class GrTextureDomainEffect : public GrSingleTextureEffect { |
| |
| public: |
| /** |
| * If SkShader::kDecal_TileMode sticks then this enum could be replaced by SkShader::TileMode. |
| * We could also consider replacing/augmenting Decal mode with Border mode where the color |
| * outside of the domain is user-specifiable. Decal mode currently has a hard (non-lerped) |
| * transition between the border and the interior. |
| */ |
| enum WrapMode { |
| kClamp_WrapMode, |
| kDecal_WrapMode, |
| }; |
| |
| static GrEffectRef* Create(GrTexture*, |
| const SkMatrix&, |
| const SkRect& domain, |
| WrapMode, |
| bool bilerp = false); |
| |
| virtual ~GrTextureDomainEffect(); |
| |
| static const char* Name() { return "TextureDomain"; } |
| |
| typedef GrGLTextureDomainEffect GLEffect; |
| |
| virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; |
| virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; |
| |
| const SkRect& domain() const { return fTextureDomain; } |
| WrapMode wrapMode() const { return fWrapMode; } |
| |
| /* Computes a domain that bounds all the texels in texelRect. Note that with bilerp enabled |
| texels neighboring the domain may be read. */ |
| static const SkRect MakeTexelDomain(const GrTexture* texture, const SkIRect& texelRect) { |
| SkScalar wInv = SK_Scalar1 / texture->width(); |
| SkScalar hInv = SK_Scalar1 / texture->height(); |
| SkRect result = { |
| texelRect.fLeft * wInv, |
| texelRect.fTop * hInv, |
| texelRect.fRight * wInv, |
| texelRect.fBottom * hInv |
| }; |
| return result; |
| } |
| |
| protected: |
| WrapMode fWrapMode; |
| SkRect fTextureDomain; |
| |
| private: |
| GrTextureDomainEffect(GrTexture*, |
| const SkMatrix&, |
| const GrRect& domain, |
| WrapMode, |
| bool bilerp); |
| |
| virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; |
| |
| GR_DECLARE_EFFECT_TEST; |
| |
| typedef GrSingleTextureEffect INHERITED; |
| }; |
| |
| #endif |