12f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com/*
22f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com * Copyright 2012 Google Inc.
32f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com *
42f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com * Use of this source code is governed by a BSD-style license that can be
52f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com * found in the LICENSE file.
62f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com */
72f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
8907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#include "GrTextureDomain.h"
9605dd0fbce9dbb2a0d3313e13e161f2bd54870d7egdaniel#include "GrInvariantOutput.h"
1068b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com#include "GrSimpleTextureEffect.h"
1192b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.com#include "SkFloatingPoint.h"
12eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "gl/GrGLProcessor.h"
13eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "gl/builders/GrGLProgramBuilder.h"
14907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
15907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgGrTextureDomain::GrTextureDomain(const SkRect& domain, Mode mode, int index)
16907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    : fIndex(index) {
17907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
18907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    static const SkRect kFullRect = {0, 0, SK_Scalar1, SK_Scalar1};
1926632630fdf17f5a11d9aed6d8766e22842fec14commit-bot@chromium.org    if (domain.contains(kFullRect) && kClamp_Mode == mode) {
20907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        fMode = kIgnore_Mode;
21907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    } else {
22907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        fMode = mode;
23907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    }
24907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
25907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    if (fMode != kIgnore_Mode) {
26907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        // We don't currently handle domains that are empty or don't intersect the texture.
27907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        // It is OK if the domain rect is a line or point, but it should not be inverted. We do not
28907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        // handle rects that do not intersect the [0..1]x[0..1] rect.
29907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        SkASSERT(domain.fLeft <= domain.fRight);
30907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        SkASSERT(domain.fTop <= domain.fBottom);
31d0d37cace08f12abf8d316e6949e947551d418e6senorblanco        fDomain.fLeft = SkScalarPin(domain.fLeft, kFullRect.fLeft, kFullRect.fRight);
32d0d37cace08f12abf8d316e6949e947551d418e6senorblanco        fDomain.fRight = SkScalarPin(domain.fRight, kFullRect.fLeft, kFullRect.fRight);
33d0d37cace08f12abf8d316e6949e947551d418e6senorblanco        fDomain.fTop = SkScalarPin(domain.fTop, kFullRect.fTop, kFullRect.fBottom);
34d0d37cace08f12abf8d316e6949e947551d418e6senorblanco        fDomain.fBottom = SkScalarPin(domain.fBottom, kFullRect.fTop, kFullRect.fBottom);
35907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        SkASSERT(fDomain.fLeft <= fDomain.fRight);
36907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        SkASSERT(fDomain.fTop <= fDomain.fBottom);
37907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    }
38907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org}
39907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
40907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
41907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
42907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgvoid GrTextureDomain::GLDomain::sampleTexture(GrGLShaderBuilder* builder,
43907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                                              const GrTextureDomain& textureDomain,
44907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                                              const char* outColor,
45907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                                              const SkString& inCoords,
46b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                              const GrGLProcessor::TextureSampler sampler,
47907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                                              const char* inModulateColor) {
48d7b1af68deefe6e4ca5fa635625154c1e4f2eae6reed@google.com    SkASSERT((Mode)-1 == fMode || textureDomain.mode() == fMode);
49907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    SkDEBUGCODE(fMode = textureDomain.mode();)
50907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
5130ba436f04e61d4505fb854d5fc56079636e0788joshualitt    GrGLProgramBuilder* program = builder->getProgramBuilder();
5230ba436f04e61d4505fb854d5fc56079636e0788joshualitt
535ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt    if (textureDomain.mode() != kIgnore_Mode && !fDomainUni.isValid()) {
54907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        const char* name;
55907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        SkString uniName("TexDom");
56907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        if (textureDomain.fIndex >= 0) {
57907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            uniName.appendS32(textureDomain.fIndex);
58907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        }
59422f56f6e51c2f6a6ab425573b4d790f0157f883bsalomon        fDomainUni = program->addUniform(GrGLProgramBuilder::kFragment_Visibility,
60422f56f6e51c2f6a6ab425573b4d790f0157f883bsalomon                                         kVec4f_GrSLType, kDefault_GrSLPrecision,
61422f56f6e51c2f6a6ab425573b4d790f0157f883bsalomon                                         uniName.c_str(), &name);
62907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        fDomainName = name;
63907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    }
64907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
655ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt    switch (textureDomain.mode()) {
665ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt        case kIgnore_Mode: {
6730ba436f04e61d4505fb854d5fc56079636e0788joshualitt            builder->codeAppendf("\t%s = ", outColor);
6830ba436f04e61d4505fb854d5fc56079636e0788joshualitt            builder->appendTextureLookupAndModulate(inModulateColor, sampler,
695ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                                                      inCoords.c_str());
7030ba436f04e61d4505fb854d5fc56079636e0788joshualitt            builder->codeAppend(";\n");
715ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt            break;
725ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt        }
735ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt        case kClamp_Mode: {
745ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt            SkString clampedCoords;
755ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt            clampedCoords.appendf("\tclamp(%s, %s.xy, %s.zw)",
765ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                                  inCoords.c_str(), fDomainName.c_str(), fDomainName.c_str());
775ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt
7830ba436f04e61d4505fb854d5fc56079636e0788joshualitt            builder->codeAppendf("\t%s = ", outColor);
7930ba436f04e61d4505fb854d5fc56079636e0788joshualitt            builder->appendTextureLookupAndModulate(inModulateColor, sampler,
805ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                                                      clampedCoords.c_str());
8130ba436f04e61d4505fb854d5fc56079636e0788joshualitt            builder->codeAppend(";\n");
825ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt            break;
835ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt        }
845ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt        case kDecal_Mode: {
855ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt            // Add a block since we're going to declare variables.
8630ba436f04e61d4505fb854d5fc56079636e0788joshualitt            GrGLShaderBuilder::ShaderBlock block(builder);
875ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt
885ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt            const char* domain = fDomainName.c_str();
8930ba436f04e61d4505fb854d5fc56079636e0788joshualitt            if (kImagination_GrGLVendor == program->ctxInfo().vendor()) {
905ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                // On the NexusS and GalaxyNexus, the other path (with the 'any'
915ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                // call) causes the compilation error "Calls to any function that
925ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                // may require a gradient calculation inside a conditional block
935ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                // may return undefined results". This appears to be an issue with
945ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                // the 'any' call since even the simple "result=black; if (any())
955ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                // result=white;" code fails to compile.
9630ba436f04e61d4505fb854d5fc56079636e0788joshualitt                builder->codeAppend("\tvec4 outside = vec4(0.0, 0.0, 0.0, 0.0);\n");
9730ba436f04e61d4505fb854d5fc56079636e0788joshualitt                builder->codeAppend("\tvec4 inside = ");
9830ba436f04e61d4505fb854d5fc56079636e0788joshualitt                builder->appendTextureLookupAndModulate(inModulateColor, sampler,
995ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                                                          inCoords.c_str());
10030ba436f04e61d4505fb854d5fc56079636e0788joshualitt                builder->codeAppend(";\n");
10130ba436f04e61d4505fb854d5fc56079636e0788joshualitt                builder->codeAppendf("\tfloat x = (%s).x;\n", inCoords.c_str());
10230ba436f04e61d4505fb854d5fc56079636e0788joshualitt                builder->codeAppendf("\tfloat y = (%s).y;\n", inCoords.c_str());
1035ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt
10430ba436f04e61d4505fb854d5fc56079636e0788joshualitt                builder->codeAppendf("\tx = abs(2.0*(x - %s.x)/(%s.z - %s.x) - 1.0);\n",
105d9e183fce58061daf316dfb3ce0c7744232b17f9joshualitt                                       domain, domain, domain);
10630ba436f04e61d4505fb854d5fc56079636e0788joshualitt                builder->codeAppendf("\ty = abs(2.0*(y - %s.y)/(%s.w - %s.y) - 1.0);\n",
107d9e183fce58061daf316dfb3ce0c7744232b17f9joshualitt                                       domain, domain, domain);
10830ba436f04e61d4505fb854d5fc56079636e0788joshualitt                builder->codeAppend("\tfloat blend = step(1.0, max(x, y));\n");
10930ba436f04e61d4505fb854d5fc56079636e0788joshualitt                builder->codeAppendf("\t%s = mix(inside, outside, blend);\n", outColor);
1105ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt            } else {
11130ba436f04e61d4505fb854d5fc56079636e0788joshualitt                builder->codeAppend("\tbvec4 outside;\n");
11230ba436f04e61d4505fb854d5fc56079636e0788joshualitt                builder->codeAppendf("\toutside.xy = lessThan(%s, %s.xy);\n", inCoords.c_str(),
1135ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                                       domain);
11430ba436f04e61d4505fb854d5fc56079636e0788joshualitt                builder->codeAppendf("\toutside.zw = greaterThan(%s, %s.zw);\n", inCoords.c_str(),
1155ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                                       domain);
11630ba436f04e61d4505fb854d5fc56079636e0788joshualitt                builder->codeAppendf("\t%s = any(outside) ? vec4(0.0, 0.0, 0.0, 0.0) : ",
1175ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                                       outColor);
11830ba436f04e61d4505fb854d5fc56079636e0788joshualitt                builder->appendTextureLookupAndModulate(inModulateColor, sampler,
1195ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                                                          inCoords.c_str());
12030ba436f04e61d4505fb854d5fc56079636e0788joshualitt                builder->codeAppend(";\n");
1215ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt            }
1225ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt            break;
1235ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt        }
1245ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt        case kRepeat_Mode: {
1255ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt            SkString clampedCoords;
1265ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt            clampedCoords.printf("\tmod(%s - %s.xy, %s.zw - %s.xy) + %s.xy",
1275ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                                 inCoords.c_str(), fDomainName.c_str(), fDomainName.c_str(),
1285ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                                 fDomainName.c_str(), fDomainName.c_str());
1295ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt
13030ba436f04e61d4505fb854d5fc56079636e0788joshualitt            builder->codeAppendf("\t%s = ", outColor);
13130ba436f04e61d4505fb854d5fc56079636e0788joshualitt            builder->appendTextureLookupAndModulate(inModulateColor, sampler,
1325ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                                                      clampedCoords.c_str());
13330ba436f04e61d4505fb854d5fc56079636e0788joshualitt            builder->codeAppend(";\n");
1345ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt            break;
135907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        }
136907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    }
137907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org}
138907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
1397510b224e52b9518a8ddf7418db0e9c258f79539kkinnunenvoid GrTextureDomain::GLDomain::setData(const GrGLProgramDataManager& pdman,
140907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                                        const GrTextureDomain& textureDomain,
141907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                                        GrSurfaceOrigin textureOrigin) {
142907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    SkASSERT(textureDomain.mode() == fMode);
143907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    if (kIgnore_Mode != textureDomain.mode()) {
144907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        GrGLfloat values[4] = {
145907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            SkScalarToFloat(textureDomain.domain().left()),
146907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            SkScalarToFloat(textureDomain.domain().top()),
147907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            SkScalarToFloat(textureDomain.domain().right()),
148907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            SkScalarToFloat(textureDomain.domain().bottom())
149907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        };
150907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        // vertical flip if necessary
151907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        if (kBottomLeft_GrSurfaceOrigin == textureOrigin) {
152907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            values[1] = 1.0f - values[1];
153907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            values[3] = 1.0f - values[3];
154907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            // The top and bottom were just flipped, so correct the ordering
155907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            // of elements so that values = (l, t, r, b).
156907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            SkTSwap(values[1], values[3]);
157907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        }
158907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        if (0 != memcmp(values, fPrevDomain, 4 * sizeof(GrGLfloat))) {
1597510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen            pdman.set4fv(fDomainUni, 1, values);
160907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            memcpy(fPrevDomain, values, 4 * sizeof(GrGLfloat));
161907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        }
162907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    }
163907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org}
164907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
165907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
166907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
167907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
168b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrGLTextureDomainEffect : public GrGLFragmentProcessor {
1692f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.compublic:
170eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    GrGLTextureDomainEffect(const GrProcessor&);
1712f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
1721598899975ecc85b003a59740b588d1ddbcedb09joshualitt    virtual void emitCode(GrGLFPBuilder*,
173b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                          const GrFragmentProcessor&,
17422a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com                          const char* outputColor,
17522a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com                          const char* inputColor,
17677af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com                          const TransformedCoordsArray&,
17736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein                          const TextureSamplerArray&) override;
1782f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
17936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
1802f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
181cfc18867d982119d9dc2888bf09f1093012daaddjvanverth    static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*);
1822f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
1832f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.comprivate:
184907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    GrTextureDomain::GLDomain         fGLDomain;
185b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    typedef GrGLFragmentProcessor INHERITED;
1862f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com};
1872f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
188eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittGrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrProcessor&) {
1892f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com}
1902f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
1911598899975ecc85b003a59740b588d1ddbcedb09joshualittvoid GrGLTextureDomainEffect::emitCode(GrGLFPBuilder* builder,
192b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       const GrFragmentProcessor& fp,
19322a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com                                       const char* outputColor,
19422a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com                                       const char* inputColor,
19577af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com                                       const TransformedCoordsArray& coords,
19622a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com                                       const TextureSamplerArray& samplers) {
197b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    const GrTextureDomainEffect& textureDomainEffect = fp.cast<GrTextureDomainEffect>();
19849586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt    const GrTextureDomain& domain = textureDomainEffect.textureDomain();
1997b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com
20029bee0fe657fabf7c396502b69c9167fba13eaaaegdaniel    GrGLFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
20130ba436f04e61d4505fb854d5fc56079636e0788joshualitt    SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0);
20230ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fGLDomain.sampleTexture(fsBuilder, domain, outputColor, coords2D, samplers[0], inputColor);
2032f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com}
2042f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
2057510b224e52b9518a8ddf7418db0e9c258f79539kkinnunenvoid GrGLTextureDomainEffect::setData(const GrGLProgramDataManager& pdman,
206b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                      const GrProcessor& processor) {
207b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    const GrTextureDomainEffect& textureDomainEffect = processor.cast<GrTextureDomainEffect>();
20849586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt    const GrTextureDomain& domain = textureDomainEffect.textureDomain();
209b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    fGLDomain.setData(pdman, domain, processor.texture(0)->origin());
2101aa90cf11e136a722bce71dd77f4bb03cc2b56f8skia.committer@gmail.com}
21192b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.com
212cfc18867d982119d9dc2888bf09f1093012daaddjvanverthvoid GrGLTextureDomainEffect::GenKey(const GrProcessor& processor, const GrGLSLCaps&,
213b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                     GrProcessorKeyBuilder* b) {
214b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    const GrTextureDomain& domain = processor.cast<GrTextureDomainEffect>().textureDomain();
21563e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon    b->add32(GrTextureDomain::GLDomain::DomainKey(domain));
2162f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com}
2172f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
2182f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
2192f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com///////////////////////////////////////////////////////////////////////////////
2202f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
221b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* GrTextureDomainEffect::Create(GrTexture* texture,
222b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                   const SkMatrix& matrix,
223b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                   const SkRect& domain,
224b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                   GrTextureDomain::Mode mode,
225b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                   GrTextureParams::FilterMode filterMode,
226b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                   GrCoordSet coordSet) {
2277b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com    static const SkRect kFullRect = {0, 0, SK_Scalar1, SK_Scalar1};
228907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    if (GrTextureDomain::kIgnore_Mode == mode ||
229907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        (GrTextureDomain::kClamp_Mode == mode && domain.contains(kFullRect))) {
230b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com        return GrSimpleTextureEffect::Create(texture, matrix, filterMode);
2317b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com    } else {
2320ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com
23355fad7af61c21d502acb9891d631e8aa29e3628cbsalomon        return SkNEW_ARGS(GrTextureDomainEffect, (texture,
23455fad7af61c21d502acb9891d631e8aa29e3628cbsalomon                                                  matrix,
23555fad7af61c21d502acb9891d631e8aa29e3628cbsalomon                                                  domain,
23655fad7af61c21d502acb9891d631e8aa29e3628cbsalomon                                                  mode,
23755fad7af61c21d502acb9891d631e8aa29e3628cbsalomon                                                  filterMode,
23855fad7af61c21d502acb9891d631e8aa29e3628cbsalomon                                                  coordSet));
2397b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com    }
2402f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com}
2412f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
2421ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.comGrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture,
2437b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com                                             const SkMatrix& matrix,
244fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org                                             const SkRect& domain,
245907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                                             GrTextureDomain::Mode mode,
246b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com                                             GrTextureParams::FilterMode filterMode,
24777af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com                                             GrCoordSet coordSet)
24877af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com    : GrSingleTextureEffect(texture, matrix, filterMode, coordSet)
249907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    , fTextureDomain(domain, mode) {
2505ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt    SkASSERT(mode != GrTextureDomain::kRepeat_Mode ||
2515ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt            filterMode == GrTextureParams::kNone_FilterMode);
252eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    this->initClassID<GrTextureDomainEffect>();
2531ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com}
2541ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com
2552f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.comGrTextureDomainEffect::~GrTextureDomainEffect() {
2562f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
2572f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com}
2582f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
259cfc18867d982119d9dc2888bf09f1093012daaddjvanverthvoid GrTextureDomainEffect::getGLProcessorKey(const GrGLSLCaps& caps,
260eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt                                              GrProcessorKeyBuilder* b) const {
261eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    GrGLTextureDomainEffect::GenKey(*this, caps, b);
262eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt}
263eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
264eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittGrGLFragmentProcessor* GrTextureDomainEffect::createGLInstance() const  {
265eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    return SkNEW_ARGS(GrGLTextureDomainEffect, (*this));
2662f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com}
2672f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
2680e08fc17e4718f7ce4e38f793695896473e96948bsalomonbool GrTextureDomainEffect::onIsEqual(const GrFragmentProcessor& sBase) const {
26949586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt    const GrTextureDomainEffect& s = sBase.cast<GrTextureDomainEffect>();
270420d7e9a79358908850c74192b4949375563449absalomon    return this->fTextureDomain == s.fTextureDomain;
27168b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com}
27268b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com
273605dd0fbce9dbb2a0d3313e13e161f2bd54870d7egdanielvoid GrTextureDomainEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
274907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    if (GrTextureDomain::kDecal_Mode == fTextureDomain.mode()) { // TODO: helper
275f8449babdc430bb522c0eb87ce18f05c54d83714egdaniel        if (GrPixelConfigIsAlphaOnly(this->texture(0)->config())) {
27656995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt            inout->mulByUnknownSingleComponent();
277f8449babdc430bb522c0eb87ce18f05c54d83714egdaniel        } else {
27856995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt            inout->mulByUnknownFourComponents();
279f8449babdc430bb522c0eb87ce18f05c54d83714egdaniel        }
28068b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com    } else {
2811a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel        this->updateInvariantOutputForModulation(inout);
28268b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com    }
2832f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com}
2840a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com
2850a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com///////////////////////////////////////////////////////////////////////////////
2860a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com
287b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrTextureDomainEffect);
2880a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com
289b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* GrTextureDomainEffect::TestCreate(SkRandom* random,
290b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                       GrContext*,
291b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                       const GrDrawTargetCaps&,
292b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                       GrTexture* textures[]) {
293b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
294b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                      GrProcessorUnitTest::kAlphaTextureIdx;
295fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org    SkRect domain;
2960a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com    domain.fLeft = random->nextUScalar1();
2970a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com    domain.fRight = random->nextRangeScalar(domain.fLeft, SK_Scalar1);
2980a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com    domain.fTop = random->nextUScalar1();
2990a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com    domain.fBottom = random->nextRangeScalar(domain.fTop, SK_Scalar1);
300907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    GrTextureDomain::Mode mode =
301907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        (GrTextureDomain::Mode) random->nextULessThan(GrTextureDomain::kModeCount);
3024eaf9cef5a76098f78efac30beb966ac833d32c2joshualitt    const SkMatrix& matrix = GrTest::TestMatrix(random);
3035ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt    bool bilerp = mode != GrTextureDomain::kRepeat_Mode ? random->nextBool() : false;
304309d4d590964fbf7443c5bc892c132faa61a9abbbsalomon    GrCoordSet coords = random->nextBool() ? kLocal_GrCoordSet : kDevice_GrCoordSet;
305c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    return GrTextureDomainEffect::Create(textures[texIdx],
306c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com                                         matrix,
307c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com                                         domain,
308907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                                         mode,
309b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com                                         bilerp ? GrTextureParams::kBilerp_FilterMode : GrTextureParams::kNone_FilterMode,
310c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com                                         coords);
3110a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com}
312