1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/gpu/effects/GrTextureDomain.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,175 @@ 1.4 +/* 1.5 + * Copyright 2012 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#ifndef GrTextureDomainEffect_DEFINED 1.12 +#define GrTextureDomainEffect_DEFINED 1.13 + 1.14 +#include "GrSingleTextureEffect.h" 1.15 +#include "gl/GrGLEffect.h" 1.16 + 1.17 +class GrGLShaderBuilder; 1.18 +struct SkRect; 1.19 + 1.20 +/** 1.21 + * Limits a texture's lookup coordinates to a domain. Samples outside the domain are either clamped 1.22 + * the edge of the domain or result in a vec4 of zeros (decal mode). The domain is clipped to 1.23 + * normalized texture coords ([0,1]x[0,1] square). Bilinear filtering can cause texels outside the 1.24 + * domain to affect the read value unless the caller considers this when calculating the domain. 1.25 + */ 1.26 +class GrTextureDomain { 1.27 +public: 1.28 + enum Mode { 1.29 + kIgnore_Mode, // Ignore the texture domain rectangle. 1.30 + kClamp_Mode, // Clamp texture coords to the domain rectangle. 1.31 + kDecal_Mode, // Treat the area outside the domain rectangle as fully transparent. 1.32 + 1.33 + kLastMode = kDecal_Mode 1.34 + }; 1.35 + static const int kModeCount = kLastMode + 1; 1.36 + 1.37 + static const GrTextureDomain& IgnoredDomain() { 1.38 + static const SkRect gDummyRect = {0, 0, 0, 0}; 1.39 + static const GrTextureDomain gDomain(gDummyRect, kIgnore_Mode); 1.40 + return gDomain; 1.41 + } 1.42 + 1.43 + /** 1.44 + * @param index Pass a value >= 0 if using multiple texture domains in the same effect. 1.45 + * It is used to keep inserted variables from causing name collisions. 1.46 + */ 1.47 + GrTextureDomain(const SkRect& domain, Mode, int index = -1); 1.48 + 1.49 + const SkRect& domain() const { return fDomain; } 1.50 + Mode mode() const { return fMode; } 1.51 + 1.52 + /* Computes a domain that bounds all the texels in texelRect. Note that with bilerp enabled 1.53 + texels neighboring the domain may be read. */ 1.54 + static const SkRect MakeTexelDomain(const GrTexture* texture, const SkIRect& texelRect) { 1.55 + SkScalar wInv = SK_Scalar1 / texture->width(); 1.56 + SkScalar hInv = SK_Scalar1 / texture->height(); 1.57 + SkRect result = { 1.58 + texelRect.fLeft * wInv, 1.59 + texelRect.fTop * hInv, 1.60 + texelRect.fRight * wInv, 1.61 + texelRect.fBottom * hInv 1.62 + }; 1.63 + return result; 1.64 + } 1.65 + 1.66 + bool operator== (const GrTextureDomain& that) const { 1.67 + return fMode == that.fMode && fDomain == that.fDomain; 1.68 + } 1.69 + 1.70 + /** 1.71 + * A GrGLEffect subclass that corresponds to a GrEffect subclass that uses GrTextureDomain 1.72 + * should include this helper. It generates the texture domain GLSL, produces the part of the 1.73 + * effect key that reflects the texture domain code, and performs the uniform uploads necessary 1.74 + * for texture domains. 1.75 + */ 1.76 + class GLDomain { 1.77 + public: 1.78 + GLDomain() { 1.79 + fPrevDomain[0] = SK_FloatNaN; 1.80 + SkDEBUGCODE(fMode = (Mode) -1;) 1.81 + } 1.82 + 1.83 + /** 1.84 + * Call this from GrGLEffect::emitCode() to sample the texture W.R.T. the domain and mode. 1.85 + * 1.86 + * @param outcolor name of vec4 variable to hold the sampled color. 1.87 + * @param inCoords name of vec2 variable containing the coords to be used with the domain. 1.88 + * It is assumed that this is a variable and not an expression. 1.89 + * @param inModulateColor if non-NULL the sampled color will be modulated with this 1.90 + * expression before being written to outColor. 1.91 + */ 1.92 + void sampleTexture(GrGLShaderBuilder* builder, 1.93 + const GrTextureDomain& textureDomain, 1.94 + const char* outColor, 1.95 + const SkString& inCoords, 1.96 + const GrGLEffect::TextureSampler sampler, 1.97 + const char* inModulateColor = NULL); 1.98 + 1.99 + /** 1.100 + * Call this from GrGLEffect::setData() to upload uniforms necessary for the texture domain. 1.101 + * The rectangle is automatically adjusted to account for the texture's origin. 1.102 + */ 1.103 + void setData(const GrGLUniformManager& uman, const GrTextureDomain& textureDomain, 1.104 + GrSurfaceOrigin textureOrigin); 1.105 + 1.106 + enum { 1.107 + kDomainKeyBits = 2, // See DomainKey(). 1.108 + }; 1.109 + 1.110 + /** 1.111 + * GrGLEffect::GenKey() must call this and include the returned value in it's computed key. 1.112 + * The returned will be limited to the lower kDomainKeyBits bits. 1.113 + */ 1.114 + static GrGLEffect::EffectKey DomainKey(const GrTextureDomain& domain) { 1.115 + GR_STATIC_ASSERT(kModeCount <= 4); 1.116 + return domain.mode(); 1.117 + } 1.118 + 1.119 + private: 1.120 + SkDEBUGCODE(Mode fMode;) 1.121 + GrGLUniformManager::UniformHandle fDomainUni; 1.122 + SkString fDomainName; 1.123 + GrGLfloat fPrevDomain[4]; 1.124 + }; 1.125 + 1.126 +protected: 1.127 + Mode fMode; 1.128 + SkRect fDomain; 1.129 + int fIndex; 1.130 + 1.131 + typedef GrSingleTextureEffect INHERITED; 1.132 +}; 1.133 + 1.134 +class GrGLTextureDomainEffect; 1.135 + 1.136 +/** 1.137 + * A basic texture effect that uses GrTextureDomain. 1.138 + */ 1.139 +class GrTextureDomainEffect : public GrSingleTextureEffect { 1.140 + 1.141 +public: 1.142 + static GrEffectRef* Create(GrTexture*, 1.143 + const SkMatrix&, 1.144 + const SkRect& domain, 1.145 + GrTextureDomain::Mode, 1.146 + GrTextureParams::FilterMode filterMode, 1.147 + GrCoordSet = kLocal_GrCoordSet); 1.148 + 1.149 + virtual ~GrTextureDomainEffect(); 1.150 + 1.151 + static const char* Name() { return "TextureDomain"; } 1.152 + 1.153 + typedef GrGLTextureDomainEffect GLEffect; 1.154 + 1.155 + virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; 1.156 + virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; 1.157 + 1.158 + const GrTextureDomain& textureDomain() const { return fTextureDomain; } 1.159 + 1.160 +protected: 1.161 + GrTextureDomain fTextureDomain; 1.162 + 1.163 +private: 1.164 + GrTextureDomainEffect(GrTexture*, 1.165 + const SkMatrix&, 1.166 + const SkRect& domain, 1.167 + GrTextureDomain::Mode, 1.168 + GrTextureParams::FilterMode, 1.169 + GrCoordSet); 1.170 + 1.171 + virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; 1.172 + 1.173 + GR_DECLARE_EFFECT_TEST; 1.174 + 1.175 + typedef GrSingleTextureEffect INHERITED; 1.176 +}; 1.177 + 1.178 +#endif