180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2012 Google Inc.
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrTextureDomainEffect.h"
9d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#include "GrSimpleTextureEffect.h"
10363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "GrTBackendEffectFactory.h"
11363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "gl/GrGLEffect.h"
12363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "gl/GrGLEffectMatrix.h"
13363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "SkFloatingPoint.h"
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerclass GrGLTextureDomainEffect : public GrGLEffect {
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
17e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    GrGLTextureDomainEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    virtual void emitCode(GrGLShaderBuilder*,
20e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger                          const GrDrawEffect&,
21363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                          EffectKey,
22363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                          const char* outputColor,
23363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                          const char* inputColor,
24363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                          const TextureSamplerArray&) SK_OVERRIDE;
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
28e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrGLUniformManager::UniformHandle fNameUni;
32363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    GrGLEffectMatrix                  fEffectMatrix;
33363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    GrGLfloat                         fPrevDomain[4];
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
35363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    typedef GrGLEffect INHERITED;
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
38363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek SollenbergerGrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrBackendEffectFactory& factory,
39e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger                                                 const GrDrawEffect& drawEffect)
40363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    : INHERITED(factory)
41e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    , fNameUni(GrGLUniformManager::kInvalidUniformHandle)
42e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    , fEffectMatrix(drawEffect.castEffect<GrTextureDomainEffect>().coordsType()) {
43363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    fPrevDomain[0] = SK_FloatNaN;
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
46363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid GrGLTextureDomainEffect::emitCode(GrGLShaderBuilder* builder,
47e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger                                       const GrDrawEffect& drawEffect,
48363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                       EffectKey key,
49363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                       const char* outputColor,
50363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                       const char* inputColor,
51363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                       const TextureSamplerArray& samplers) {
52e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    const GrTextureDomainEffect& texDom = drawEffect.castEffect<GrTextureDomainEffect>();
53363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
54363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    const char* coords;
55e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, &coords);
56363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    const char* domain;
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fNameUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
58363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                    kVec4f_GrSLType, "TexDom", &domain);
59e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    if (GrTextureDomainEffect::kClamp_WrapMode == texDom.wrapMode()) {
60363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
61096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        builder->fsCodeAppendf("\tvec2 clampCoord = clamp(%s, %s.xy, %s.zw);\n",
62096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                                coords, domain, domain);
63363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
64096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        builder->fsCodeAppendf("\t%s = ", outputColor);
65096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        builder->appendTextureLookupAndModulate(GrGLShaderBuilder::kFragment_ShaderType,
66363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                                inputColor,
67363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                                samplers[0],
68363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                                "clampCoord");
69096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        builder->fsCodeAppend(";\n");
70363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    } else {
71e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger        GrAssert(GrTextureDomainEffect::kDecal_WrapMode == texDom.wrapMode());
72096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
73096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        if (kImagination_GrGLVendor == builder->ctxInfo().vendor()) {
74096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            // On the NexusS and GalaxyNexus, the other path (with the 'any'
75096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            // call) causes the compilation error "Calls to any function that
76096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            // may require a gradient calculation inside a conditional block
77096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            // may return undefined results". This appears to be an issue with
78096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            // the 'any' call since even the simple "result=black; if (any())
79096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            // result=white;" code fails to compile.
80096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            builder->fsCodeAppend("\tvec4 outside = vec4(0.0, 0.0, 0.0, 0.0);\n");
81096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            builder->fsCodeAppend("\tvec4 inside = ");
82096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            builder->appendTextureLookupAndModulate(GrGLShaderBuilder::kFragment_ShaderType,
83096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                                                    inputColor,
84096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                                                    samplers[0],
85096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                                                    coords);
86096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            builder->fsCodeAppend(";\n");
87096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
88096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            builder->fsCodeAppendf("\tfloat x = abs(2.0*(%s.x - %s.x)/(%s.z - %s.x) - 1.0);\n",
89096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                                   coords, domain, domain, domain);
90096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            builder->fsCodeAppendf("\tfloat y = abs(2.0*(%s.y - %s.y)/(%s.w - %s.y) - 1.0);\n",
91096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                                   coords, domain, domain, domain);
92096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            builder->fsCodeAppend("\tfloat blend = step(1.0, max(x, y));\n");
93096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            builder->fsCodeAppendf("\t%s = mix(inside, outside, blend);\n", outputColor);
94096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        } else {
95096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            builder->fsCodeAppend("\tbvec4 outside;\n");
96096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            builder->fsCodeAppendf("\toutside.xy = lessThan(%s, %s.xy);\n", coords, domain);
97096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            builder->fsCodeAppendf("\toutside.zw = greaterThan(%s, %s.zw);\n", coords, domain);
98096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            builder->fsCodeAppendf("\t%s = any(outside) ? vec4(0.0, 0.0, 0.0, 0.0) : ", outputColor);
99096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            builder->appendTextureLookupAndModulate(GrGLShaderBuilder::kFragment_ShaderType,
100096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                                                    inputColor,
101096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                                                    samplers[0],
102096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                                                    coords);
103096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            builder->fsCodeAppend(";\n");
104096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        }
105363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    }
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
108e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenbergervoid GrGLTextureDomainEffect::setData(const GrGLUniformManager& uman,
109e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger                                      const GrDrawEffect& drawEffect) {
110e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    const GrTextureDomainEffect& texDom = drawEffect.castEffect<GrTextureDomainEffect>();
11158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    const SkRect& domain = texDom.domain();
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    float values[4] = {
114363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        SkScalarToFloat(domain.left()),
115363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        SkScalarToFloat(domain.top()),
116363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        SkScalarToFloat(domain.right()),
117363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        SkScalarToFloat(domain.bottom())
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // vertical flip if necessary
120e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    if (kBottomLeft_GrSurfaceOrigin == texDom.texture(0)->origin()) {
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        values[1] = 1.0f - values[1];
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        values[3] = 1.0f - values[3];
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // The top and bottom were just flipped, so correct the ordering
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // of elements so that values = (l, t, r, b).
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkTSwap(values[1], values[3]);
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
127363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    if (0 != memcmp(values, fPrevDomain, 4 * sizeof(GrGLfloat))) {
128363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        uman.set4fv(fNameUni, 0, 1, values);
1297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        memcpy(fPrevDomain, values, 4 * sizeof(GrGLfloat));
130363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    }
131363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    fEffectMatrix.setData(uman,
132e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger                          texDom.getMatrix(),
133e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger                          drawEffect,
134e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger                          texDom.texture(0));
135363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger}
136363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
137e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek SollenbergerGrGLEffect::EffectKey GrGLTextureDomainEffect::GenKey(const GrDrawEffect& drawEffect,
138e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger                                                      const GrGLCaps&) {
139e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    const GrTextureDomainEffect& texDom = drawEffect.castEffect<GrTextureDomainEffect>();
140e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    EffectKey key = texDom.wrapMode();
141363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    key <<= GrGLEffectMatrix::kKeyBits;
142e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    EffectKey matrixKey = GrGLEffectMatrix::GenKey(texDom.getMatrix(),
143e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger                                                   drawEffect,
144e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger                                                   texDom.coordsType(),
145e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger                                                   texDom.texture(0));
146363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    return key | matrixKey;
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
152d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek SollenbergerGrEffectRef* GrTextureDomainEffect::Create(GrTexture* texture,
153d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                           const SkMatrix& matrix,
15458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                                           const SkRect& domain,
155d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                           WrapMode wrapMode,
15658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                                           GrTextureParams::FilterMode filterMode,
157e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger                                           CoordsType coordsType) {
158363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    static const SkRect kFullRect = {0, 0, SK_Scalar1, SK_Scalar1};
159363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    if (kClamp_WrapMode == wrapMode && domain.contains(kFullRect)) {
16058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        return GrSimpleTextureEffect::Create(texture, matrix, filterMode);
161363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    } else {
162363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        SkRect clippedDomain;
163363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        // We don't currently handle domains that are empty or don't intersect the texture.
164363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        // It is OK if the domain rect is a line or point, but it should not be inverted. We do not
165363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        // handle rects that do not intersect the [0..1]x[0..1] rect.
166363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        GrAssert(domain.fLeft <= domain.fRight);
167363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        GrAssert(domain.fTop <= domain.fBottom);
168363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        clippedDomain.fLeft = SkMaxScalar(domain.fLeft, kFullRect.fLeft);
169363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        clippedDomain.fRight = SkMinScalar(domain.fRight, kFullRect.fRight);
170363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        clippedDomain.fTop = SkMaxScalar(domain.fTop, kFullRect.fTop);
171363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        clippedDomain.fBottom = SkMinScalar(domain.fBottom, kFullRect.fBottom);
172363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        GrAssert(clippedDomain.fLeft <= clippedDomain.fRight);
173363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        GrAssert(clippedDomain.fTop <= clippedDomain.fBottom);
174d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
175d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        AutoEffectUnref effect(SkNEW_ARGS(GrTextureDomainEffect, (texture,
176d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                                                  matrix,
177d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                                                  clippedDomain,
178d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                                                  wrapMode,
17958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                                                                  filterMode,
180e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger                                                                  coordsType)));
181d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        return CreateEffectRef(effect);
182d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
183363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    }
18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture,
187363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                             const SkMatrix& matrix,
18858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                                             const SkRect& domain,
189363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                             WrapMode wrapMode,
19058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                                             GrTextureParams::FilterMode filterMode,
191e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger                                             CoordsType coordsType)
19258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    : GrSingleTextureEffect(texture, matrix, filterMode, coordsType)
193363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    , fWrapMode(wrapMode)
19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    , fTextureDomain(domain) {
19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrTextureDomainEffect::~GrTextureDomainEffect() {
19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
201363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerconst GrBackendEffectFactory& GrTextureDomainEffect::getFactory() const {
202363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    return GrTBackendEffectFactory<GrTextureDomainEffect>::getInstance();
20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
205d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerbool GrTextureDomainEffect::onIsEqual(const GrEffect& sBase) const {
206d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    const GrTextureDomainEffect& s = CastEffect<GrTextureDomainEffect>(sBase);
207e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    return this->hasSameTextureParamsMatrixAndCoordsType(s) &&
208e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger           this->fTextureDomain == s.fTextureDomain;
209d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger}
210d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
211d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergervoid GrTextureDomainEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
212d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    if (kDecal_WrapMode == fWrapMode) {
213d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        *validFlags = 0;
214d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    } else {
215d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        this->updateConstantColorComponentsForModulation(color, validFlags);
216d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    }
21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
221363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek SollenbergerGR_DEFINE_EFFECT_TEST(GrTextureDomainEffect);
22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
223096defe64d408e54474fe19f418c95bf1a554fc7Derek SollenbergerGrEffectRef* GrTextureDomainEffect::TestCreate(SkMWCRandom* random,
224096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                                               GrContext*,
2257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                               const GrDrawTargetCaps&,
226d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                               GrTexture* textures[]) {
227363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
228363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                      GrEffectUnitTest::kAlphaTextureIdx;
22958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkRect domain;
23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    domain.fLeft = random->nextUScalar1();
23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    domain.fRight = random->nextRangeScalar(domain.fLeft, SK_Scalar1);
23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    domain.fTop = random->nextUScalar1();
23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    domain.fBottom = random->nextRangeScalar(domain.fTop, SK_Scalar1);
234363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    WrapMode wrapMode = random->nextBool() ? kClamp_WrapMode : kDecal_WrapMode;
235363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random);
236e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    bool bilerp = random->nextBool();
237e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    CoordsType coords = random->nextBool() ? kLocal_CoordsType : kPosition_CoordsType;
238e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    return GrTextureDomainEffect::Create(textures[texIdx],
239e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger                                         matrix,
240e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger                                         domain,
241e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger                                         wrapMode,
24258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                                         bilerp ? GrTextureParams::kBilerp_FilterMode : GrTextureParams::kNone_FilterMode,
243e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger                                         coords);
24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
245