1907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org/*
2907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org * Copyright 2012 Google Inc.
3907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org *
4907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be
5907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org * found in the LICENSE file.
6907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org */
7907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
8907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#ifndef GrTextureDomainEffect_DEFINED
9907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#define GrTextureDomainEffect_DEFINED
10907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
11907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#include "GrSingleTextureEffect.h"
12907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#include "gl/GrGLEffect.h"
13907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
14907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgclass GrGLShaderBuilder;
15907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgstruct SkRect;
16907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
17907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org/**
18907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org * Limits a texture's lookup coordinates to a domain. Samples outside the domain are either clamped
19907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org * the edge of the domain or result in a vec4 of zeros (decal mode). The domain is clipped to
20907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org * normalized texture coords ([0,1]x[0,1] square). Bilinear filtering can cause texels outside the
21907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org * domain to affect the read value unless the caller considers this when calculating the domain.
22907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org */
23907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgclass GrTextureDomain {
24907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgpublic:
25907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    enum Mode {
26907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        kIgnore_Mode,  // Ignore the texture domain rectangle.
27907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        kClamp_Mode,   // Clamp texture coords to the domain rectangle.
28907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        kDecal_Mode,   // Treat the area outside the domain rectangle as fully transparent.
29907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
30907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        kLastMode = kDecal_Mode
31907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    };
32907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    static const int kModeCount = kLastMode + 1;
33907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
347d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org    static const GrTextureDomain& IgnoredDomain() {
357d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org        static const SkRect gDummyRect = {0, 0, 0, 0};
367d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org        static const GrTextureDomain gDomain(gDummyRect, kIgnore_Mode);
377d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org        return gDomain;
387d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org    }
397d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org
40907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    /**
41907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     * @param index     Pass a value >= 0 if using multiple texture domains in the same effect.
42907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     *                  It is used to keep inserted variables from causing name collisions.
43907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     */
44907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    GrTextureDomain(const SkRect& domain, Mode, int index = -1);
45907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
46907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    const SkRect& domain() const { return fDomain; }
47907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    Mode mode() const { return fMode; }
48907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
49907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    /* Computes a domain that bounds all the texels in texelRect. Note that with bilerp enabled
50907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org       texels neighboring the domain may be read. */
51907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    static const SkRect MakeTexelDomain(const GrTexture* texture, const SkIRect& texelRect) {
52907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        SkScalar wInv = SK_Scalar1 / texture->width();
53907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        SkScalar hInv = SK_Scalar1 / texture->height();
54907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        SkRect result = {
55907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            texelRect.fLeft * wInv,
56907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            texelRect.fTop * hInv,
57907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            texelRect.fRight * wInv,
58907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            texelRect.fBottom * hInv
59907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        };
60907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        return result;
61907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    }
62907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
63907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    bool operator== (const GrTextureDomain& that) const {
64907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        return fMode == that.fMode && fDomain == that.fDomain;
65907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    }
66907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
67907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    /**
68907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     * A GrGLEffect subclass that corresponds to a GrEffect subclass that uses GrTextureDomain
69907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     * should include this helper. It generates the texture domain GLSL, produces the part of the
70907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     * effect key that reflects the texture domain code, and performs the uniform uploads necessary
71907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     * for texture domains.
72907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     */
73907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    class GLDomain {
74907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    public:
75907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        GLDomain() {
76907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            fPrevDomain[0] = SK_FloatNaN;
77907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            SkDEBUGCODE(fMode = (Mode) -1;)
78907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        }
79907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
80907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        /**
81907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org         * Call this from GrGLEffect::emitCode() to sample the texture W.R.T. the domain and mode.
82907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org         *
83907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org         * @param outcolor  name of vec4 variable to hold the sampled color.
84907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org         * @param inCoords  name of vec2 variable containing the coords to be used with the domain.
85907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org         *                  It is assumed that this is a variable and not an expression.
86907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org         * @param inModulateColor   if non-NULL the sampled color will be modulated with this
87907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org         *                          expression before being written to outColor.
88907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org         */
89907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        void sampleTexture(GrGLShaderBuilder* builder,
90907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                           const GrTextureDomain& textureDomain,
91907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                           const char* outColor,
92907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                           const SkString& inCoords,
93907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                           const GrGLEffect::TextureSampler sampler,
94907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                           const char* inModulateColor = NULL);
95907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
96907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        /**
97907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org         * Call this from GrGLEffect::setData() to upload uniforms necessary for the texture domain.
98907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org         * The rectangle is automatically adjusted to account for the texture's origin.
99907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org         */
100907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        void setData(const GrGLUniformManager& uman, const GrTextureDomain& textureDomain,
101907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                     GrSurfaceOrigin textureOrigin);
102907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
103907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        enum {
104907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            kDomainKeyBits = 2, // See DomainKey().
105907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        };
106907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
107907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        /**
108907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org         * GrGLEffect::GenKey() must call this and include the returned value in it's computed key.
109907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org         * The returned will be limited to the lower kDomainKeyBits bits.
110907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org         */
111907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        static GrGLEffect::EffectKey DomainKey(const GrTextureDomain& domain) {
112907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            GR_STATIC_ASSERT(kModeCount <= 4);
113907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            return domain.mode();
114907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        }
115907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
116907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    private:
117907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        SkDEBUGCODE(Mode                  fMode;)
118907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        GrGLUniformManager::UniformHandle fDomainUni;
119907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        SkString                          fDomainName;
120907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        GrGLfloat                         fPrevDomain[4];
121907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    };
122907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
123907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgprotected:
124907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    Mode    fMode;
125907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    SkRect  fDomain;
126907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    int     fIndex;
127907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
128907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    typedef GrSingleTextureEffect INHERITED;
129907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org};
130907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
131907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgclass GrGLTextureDomainEffect;
132907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
133907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org/**
134907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org * A basic texture effect that uses GrTextureDomain.
135907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org */
136907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgclass GrTextureDomainEffect : public GrSingleTextureEffect {
137907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
138907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgpublic:
139907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    static GrEffectRef* Create(GrTexture*,
140907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                               const SkMatrix&,
141907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                               const SkRect& domain,
142907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                               GrTextureDomain::Mode,
143907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                               GrTextureParams::FilterMode filterMode,
144907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                               GrCoordSet = kLocal_GrCoordSet);
145907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
146907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    virtual ~GrTextureDomainEffect();
147907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
148907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    static const char* Name() { return "TextureDomain"; }
149907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
150907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    typedef GrGLTextureDomainEffect GLEffect;
151907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
152907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
153907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
154907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
155907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    const GrTextureDomain& textureDomain() const { return fTextureDomain; }
156907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
157907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgprotected:
158907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    GrTextureDomain fTextureDomain;
159907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
160907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgprivate:
161907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    GrTextureDomainEffect(GrTexture*,
162907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                          const SkMatrix&,
163907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                          const SkRect& domain,
164907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                          GrTextureDomain::Mode,
165907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                          GrTextureParams::FilterMode,
166907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                          GrCoordSet);
167907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
168907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
169907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
170907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    GR_DECLARE_EFFECT_TEST;
171907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
172907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    typedef GrSingleTextureEffect INHERITED;
173907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org};
174907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
175907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#endif
176