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"
12b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "gl/GrGLProcessor.h"
13907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
1430ba436f04e61d4505fb854d5fc56079636e0788joshualittclass GrGLProgramBuilder;
15907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgclass GrGLShaderBuilder;
16907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgstruct SkRect;
17907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
18907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org/**
19907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org * Limits a texture's lookup coordinates to a domain. Samples outside the domain are either clamped
20907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org * the edge of the domain or result in a vec4 of zeros (decal mode). The domain is clipped to
21907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org * normalized texture coords ([0,1]x[0,1] square). Bilinear filtering can cause texels outside the
22907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org * domain to affect the read value unless the caller considers this when calculating the domain.
23907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org */
24907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgclass GrTextureDomain {
25907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgpublic:
26907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    enum Mode {
275ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt        // Ignore the texture domain rectangle.
285ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt        kIgnore_Mode,
295ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt        // Clamp texture coords to the domain rectangle.
305ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt        kClamp_Mode,
315ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt        // Treat the area outside the domain rectangle as fully transparent.
325ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt        kDecal_Mode,
335ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt        // Wrap texture coordinates.  NOTE: filtering may not work as expected because Bilerp will
345ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt        // read texels outside of the domain.  We could perform additional texture reads and filter
355ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt        // in the shader, but are not currently doing this for performance reasons
365ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt        kRepeat_Mode,
37907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
385ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt        kLastMode = kRepeat_Mode
39907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    };
40907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    static const int kModeCount = kLastMode + 1;
41907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
427d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org    static const GrTextureDomain& IgnoredDomain() {
437d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org        static const SkRect gDummyRect = {0, 0, 0, 0};
447d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org        static const GrTextureDomain gDomain(gDummyRect, kIgnore_Mode);
457d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org        return gDomain;
467d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org    }
477d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org
48907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    /**
49907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     * @param index     Pass a value >= 0 if using multiple texture domains in the same effect.
50907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     *                  It is used to keep inserted variables from causing name collisions.
51907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     */
52907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    GrTextureDomain(const SkRect& domain, Mode, int index = -1);
53907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
54907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    const SkRect& domain() const { return fDomain; }
55907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    Mode mode() const { return fMode; }
56907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
57907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    /* Computes a domain that bounds all the texels in texelRect. Note that with bilerp enabled
58907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org       texels neighboring the domain may be read. */
59907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    static const SkRect MakeTexelDomain(const GrTexture* texture, const SkIRect& texelRect) {
60907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        SkScalar wInv = SK_Scalar1 / texture->width();
61907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        SkScalar hInv = SK_Scalar1 / texture->height();
62907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        SkRect result = {
63907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            texelRect.fLeft * wInv,
64907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            texelRect.fTop * hInv,
65907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            texelRect.fRight * wInv,
66907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            texelRect.fBottom * hInv
67907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        };
68907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        return result;
69907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    }
70907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
71907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    bool operator== (const GrTextureDomain& that) const {
7201a492f959e886f89995c6d1bbcd9f7bb7639726egdaniel        return fMode == that.fMode && (kIgnore_Mode == fMode || fDomain == that.fDomain);
73907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    }
74907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
75907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    /**
76b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt     * A GrGLProcessor subclass that corresponds to a GrProcessor subclass that uses GrTextureDomain
77907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     * should include this helper. It generates the texture domain GLSL, produces the part of the
78907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     * effect key that reflects the texture domain code, and performs the uniform uploads necessary
79907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     * for texture domains.
80907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org     */
81907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    class GLDomain {
82907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    public:
83907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        GLDomain() {
84907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            fPrevDomain[0] = SK_FloatNaN;
85907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            SkDEBUGCODE(fMode = (Mode) -1;)
86907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        }
87907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
88907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        /**
89b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt         * Call this from GrGLProcessor::emitCode() to sample the texture W.R.T. the domain and
90b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt         * mode.
91907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org         *
92907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org         * @param outcolor  name of vec4 variable to hold the sampled color.
93907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org         * @param inCoords  name of vec2 variable containing the coords to be used with the domain.
94907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org         *                  It is assumed that this is a variable and not an expression.
95907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org         * @param inModulateColor   if non-NULL the sampled color will be modulated with this
96907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org         *                          expression before being written to outColor.
97907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org         */
98907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        void sampleTexture(GrGLShaderBuilder* builder,
99907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                           const GrTextureDomain& textureDomain,
100907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                           const char* outColor,
101907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                           const SkString& inCoords,
102b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                           const GrGLProcessor::TextureSampler sampler,
103907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                           const char* inModulateColor = NULL);
104907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
105907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        /**
106b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt         * Call this from GrGLProcessor::setData() to upload uniforms necessary for the texture
107b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt         * domain. The rectangle is automatically adjusted to account for the texture's origin.
108907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org         */
1097510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen        void setData(const GrGLProgramDataManager& pdman, const GrTextureDomain& textureDomain,
110907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                     GrSurfaceOrigin textureOrigin);
111907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
112907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        enum {
113907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            kDomainKeyBits = 2, // See DomainKey().
114907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        };
115907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
116907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        /**
117b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt         * GrGLProcessor::GenKey() must call this and include the returned value in it's computed
118b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt         * key. The returned will be limited to the lower kDomainKeyBits bits.
119907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org         */
12063e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon        static uint32_t DomainKey(const GrTextureDomain& domain) {
121907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            GR_STATIC_ASSERT(kModeCount <= 4);
122907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            return domain.mode();
123907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        }
124907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
125907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    private:
1267510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen        SkDEBUGCODE(Mode                      fMode;)
1277510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen        GrGLProgramDataManager::UniformHandle fDomainUni;
1287510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen        SkString                              fDomainName;
1297510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen        GrGLfloat                             fPrevDomain[4];
130907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    };
131907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
132907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgprotected:
133907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    Mode    fMode;
134907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    SkRect  fDomain;
135907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    int     fIndex;
136907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
137907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    typedef GrSingleTextureEffect INHERITED;
138907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org};
139907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
140907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgclass GrGLTextureDomainEffect;
141907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
142907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org/**
143907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org * A basic texture effect that uses GrTextureDomain.
144907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org */
145907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgclass GrTextureDomainEffect : public GrSingleTextureEffect {
146907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
147907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgpublic:
148b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    static GrFragmentProcessor* Create(GrTexture*,
149b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const SkMatrix&,
150b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const SkRect& domain,
151b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       GrTextureDomain::Mode,
152b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       GrTextureParams::FilterMode filterMode,
153b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       GrCoordSet = kLocal_GrCoordSet);
154907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
155907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    virtual ~GrTextureDomainEffect();
156907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
157907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    static const char* Name() { return "TextureDomain"; }
158907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
159b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    typedef GrGLTextureDomainEffect GLProcessor;
160907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
161b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
162907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
163907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
164907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    const GrTextureDomain& textureDomain() const { return fTextureDomain; }
165907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
166907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgprotected:
167907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    GrTextureDomain fTextureDomain;
168907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
169907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgprivate:
170907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    GrTextureDomainEffect(GrTexture*,
171907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                          const SkMatrix&,
172907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                          const SkRect& domain,
173907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                          GrTextureDomain::Mode,
174907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                          GrTextureParams::FilterMode,
175907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                          GrCoordSet);
176907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
177b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
178907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
179b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
180907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
181907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    typedef GrSingleTextureEffect INHERITED;
182907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org};
183907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
184907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#endif
185