1 /* 2 * Copyright 2012 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef GrTextureDomainEffect_DEFINED 9 #define GrTextureDomainEffect_DEFINED 10 11 #include "GrSingleTextureEffect.h" 12 #include "GrRect.h" 13 14 class GrGLTextureDomainEffect; 15 16 /** 17 * Limits a texture's lookup coordinates to a domain. Samples outside the domain are either clamped 18 * the edge of the domain or result in a vec4 of zeros. The domain is clipped to normalized texture 19 * coords ([0,1]x[0,1] square). Bilinear filtering can cause texels outside the domain to affect the 20 * read value unless the caller considers this when calculating the domain. TODO: This should be a 21 * helper that can assist an effect rather than effect unto itself. 22 */ 23 class GrTextureDomainEffect : public GrSingleTextureEffect { 24 25 public: 26 /** 27 * If SkShader::kDecal_TileMode sticks then this enum could be replaced by SkShader::TileMode. 28 * We could also consider replacing/augmenting Decal mode with Border mode where the color 29 * outside of the domain is user-specifiable. Decal mode currently has a hard (non-lerped) 30 * transition between the border and the interior. 31 */ 32 enum WrapMode { 33 kClamp_WrapMode, 34 kDecal_WrapMode, 35 }; 36 37 static GrEffectRef* Create(GrTexture*, 38 const SkMatrix&, 39 const SkRect& domain, 40 WrapMode, 41 bool bilerp = false); 42 43 virtual ~GrTextureDomainEffect(); 44 45 static const char* Name() { return "TextureDomain"; } 46 47 typedef GrGLTextureDomainEffect GLEffect; 48 49 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; 50 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; 51 52 const SkRect& domain() const { return fTextureDomain; } 53 WrapMode wrapMode() const { return fWrapMode; } 54 55 /* Computes a domain that bounds all the texels in texelRect. Note that with bilerp enabled 56 texels neighboring the domain may be read. */ 57 static const SkRect MakeTexelDomain(const GrTexture* texture, const SkIRect& texelRect) { 58 SkScalar wInv = SK_Scalar1 / texture->width(); 59 SkScalar hInv = SK_Scalar1 / texture->height(); 60 SkRect result = { 61 texelRect.fLeft * wInv, 62 texelRect.fTop * hInv, 63 texelRect.fRight * wInv, 64 texelRect.fBottom * hInv 65 }; 66 return result; 67 } 68 69 protected: 70 WrapMode fWrapMode; 71 SkRect fTextureDomain; 72 73 private: 74 GrTextureDomainEffect(GrTexture*, 75 const SkMatrix&, 76 const GrRect& domain, 77 WrapMode, 78 bool bilerp); 79 80 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; 81 82 GR_DECLARE_EFFECT_TEST; 83 84 typedef GrSingleTextureEffect INHERITED; 85 }; 86 87 #endif 88