Home | History | Annotate | Download | only in effects
      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 
     13 class GrGLTextureDomainEffect;
     14 struct SkRect;
     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                                GrTextureParams::FilterMode filterMode,
     42                                CoordsType = kLocal_CoordsType);
     43 
     44     virtual ~GrTextureDomainEffect();
     45 
     46     static const char* Name() { return "TextureDomain"; }
     47 
     48     typedef GrGLTextureDomainEffect GLEffect;
     49 
     50     virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
     51     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
     52 
     53     const SkRect& domain() const { return fTextureDomain; }
     54     WrapMode wrapMode() const { return fWrapMode; }
     55 
     56     /* Computes a domain that bounds all the texels in texelRect. Note that with bilerp enabled
     57        texels neighboring the domain may be read. */
     58     static const SkRect MakeTexelDomain(const GrTexture* texture, const SkIRect& texelRect) {
     59         SkScalar wInv = SK_Scalar1 / texture->width();
     60         SkScalar hInv = SK_Scalar1 / texture->height();
     61         SkRect result = {
     62             texelRect.fLeft * wInv,
     63             texelRect.fTop * hInv,
     64             texelRect.fRight * wInv,
     65             texelRect.fBottom * hInv
     66         };
     67         return result;
     68     }
     69 
     70 protected:
     71     WrapMode fWrapMode;
     72     SkRect   fTextureDomain;
     73 
     74 private:
     75     GrTextureDomainEffect(GrTexture*,
     76                           const SkMatrix&,
     77                           const SkRect& domain,
     78                           WrapMode,
     79                           GrTextureParams::FilterMode filterMode,
     80                           CoordsType type);
     81 
     82     virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
     83 
     84     GR_DECLARE_EFFECT_TEST;
     85 
     86     typedef GrSingleTextureEffect INHERITED;
     87 };
     88 
     89 #endif
     90