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"
940fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips
101afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips#include "GrProxyProvider.h"
1194efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon#include "GrShaderCaps.h"
1268b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com#include "GrSimpleTextureEffect.h"
1340fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips#include "GrSurfaceProxyPriv.h"
14646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips#include "GrTexture.h"
1592b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.com#include "SkFloatingPoint.h"
1664c4728c70001ed074fecf5c4e083781987b12e9egdaniel#include "glsl/GrGLSLFragmentProcessor.h"
177ea439b2203855db97330b25945b87dd4b170b8begdaniel#include "glsl/GrGLSLFragmentShaderBuilder.h"
18018fb62d12d1febf121fe265da5b6117b86a6541egdaniel#include "glsl/GrGLSLProgramDataManager.h"
197ea439b2203855db97330b25945b87dd4b170b8begdaniel#include "glsl/GrGLSLShaderBuilder.h"
207ea439b2203855db97330b25945b87dd4b170b8begdaniel#include "glsl/GrGLSLUniformHandler.h"
21907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
22b66b42f1749a7a23fd610d90605978537bf4fbb7Robert Phillipsstatic bool can_ignore_rect(GrTextureProxy* proxy, const SkRect& domain) {
231afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips    if (GrProxyProvider::IsFunctionallyExact(proxy)) {
2440fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips        const SkIRect kFullRect = SkIRect::MakeWH(proxy->width(), proxy->height());
2540fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips
2640fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips        return domain.contains(kFullRect);
2740fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    }
2840fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips
2940fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    return false;
3040fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips}
3140fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips
3240fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert PhillipsGrTextureDomain::GrTextureDomain(GrTextureProxy* proxy, const SkRect& domain, Mode mode, int index)
3340fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    : fMode(mode)
3440fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    , fIndex(index) {
3540fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips
3640fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    if (kIgnore_Mode == fMode) {
3740fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips        return;
3840fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    }
3940fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips
4040fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    if (kClamp_Mode == mode && can_ignore_rect(proxy, domain)) {
4140fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips        fMode = kIgnore_Mode;
4240fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips        return;
4340fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    }
4440fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips
4540fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    const SkRect kFullRect = SkRect::MakeIWH(proxy->width(), proxy->height());
4640fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips
4740fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    // We don't currently handle domains that are empty or don't intersect the texture.
4840fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    // It is OK if the domain rect is a line or point, but it should not be inverted. We do not
4940fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    // handle rects that do not intersect the [0..1]x[0..1] rect.
5040fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    SkASSERT(domain.fLeft <= domain.fRight);
5140fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    SkASSERT(domain.fTop <= domain.fBottom);
5240fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    fDomain.fLeft = SkScalarPin(domain.fLeft, 0.0f, kFullRect.fRight);
5340fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    fDomain.fRight = SkScalarPin(domain.fRight, fDomain.fLeft, kFullRect.fRight);
5440fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    fDomain.fTop = SkScalarPin(domain.fTop, 0.0f, kFullRect.fBottom);
5540fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    fDomain.fBottom = SkScalarPin(domain.fBottom, fDomain.fTop, kFullRect.fBottom);
5640fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    SkASSERT(fDomain.fLeft <= fDomain.fRight);
5740fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    SkASSERT(fDomain.fTop <= fDomain.fBottom);
5840fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips}
5940fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips
60907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
61907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
622d721d33aad192cc8a7a1321504b39bdca2a57ceegdanielvoid GrTextureDomain::GLDomain::sampleTexture(GrGLSLShaderBuilder* builder,
637ea439b2203855db97330b25945b87dd4b170b8begdaniel                                              GrGLSLUniformHandler* uniformHandler,
641edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon                                              const GrShaderCaps* shaderCaps,
65907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                                              const GrTextureDomain& textureDomain,
66907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                                              const char* outColor,
67907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                                              const SkString& inCoords,
6809aa1fce69b214714171db12c341aebd78dd29eaegdaniel                                              GrGLSLFragmentProcessor::SamplerHandle sampler,
692240be96d97b5ac0886381d74a21f1e2a0928f55Brian Osman                                              const char* inModulateColor) {
70c63ec5ca64074dcc264a43bd1c1fdfb26e009410Hans Wennborg    SkASSERT(!fHasMode || textureDomain.mode() == fMode);
71907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    SkDEBUGCODE(fMode = textureDomain.mode();)
72c63ec5ca64074dcc264a43bd1c1fdfb26e009410Hans Wennborg    SkDEBUGCODE(fHasMode = true;)
73907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
745ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt    if (textureDomain.mode() != kIgnore_Mode && !fDomainUni.isValid()) {
75907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        const char* name;
76907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        SkString uniName("TexDom");
77907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        if (textureDomain.fIndex >= 0) {
78907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            uniName.appendS32(textureDomain.fIndex);
79907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        }
80f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas        fDomainUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType,
817ea439b2203855db97330b25945b87dd4b170b8begdaniel                                                uniName.c_str(), &name);
82907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        fDomainName = name;
83907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    }
84907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
855ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt    switch (textureDomain.mode()) {
865ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt        case kIgnore_Mode: {
873fc656006c8bcbdca069b1b0f500f3c7311e5e5ajvanverth            builder->codeAppendf("%s = ", outColor);
88c468963b967b5e8cde4ed320f7130a9d703c2a4eBrian Osman            builder->appendTextureLookupAndModulate(inModulateColor, sampler, inCoords.c_str(),
892240be96d97b5ac0886381d74a21f1e2a0928f55Brian Osman                                                    kFloat2_GrSLType);
903fc656006c8bcbdca069b1b0f500f3c7311e5e5ajvanverth            builder->codeAppend(";");
915ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt            break;
925ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt        }
935ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt        case kClamp_Mode: {
945ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt            SkString clampedCoords;
953fc656006c8bcbdca069b1b0f500f3c7311e5e5ajvanverth            clampedCoords.appendf("clamp(%s, %s.xy, %s.zw)",
965ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                                  inCoords.c_str(), fDomainName.c_str(), fDomainName.c_str());
975ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt
983fc656006c8bcbdca069b1b0f500f3c7311e5e5ajvanverth            builder->codeAppendf("%s = ", outColor);
99c468963b967b5e8cde4ed320f7130a9d703c2a4eBrian Osman            builder->appendTextureLookupAndModulate(inModulateColor, sampler, clampedCoords.c_str(),
1002240be96d97b5ac0886381d74a21f1e2a0928f55Brian Osman                                                    kFloat2_GrSLType);
1013fc656006c8bcbdca069b1b0f500f3c7311e5e5ajvanverth            builder->codeAppend(";");
1025ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt            break;
1035ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt        }
1045ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt        case kDecal_Mode: {
1055ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt            // Add a block since we're going to declare variables.
1062d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel            GrGLSLShaderBuilder::ShaderBlock block(builder);
1075ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt
1085ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt            const char* domain = fDomainName.c_str();
1091edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon            if (!shaderCaps->canUseAnyFunctionInShader()) {
1105ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                // On the NexusS and GalaxyNexus, the other path (with the 'any'
1115ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                // call) causes the compilation error "Calls to any function that
1125ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                // may require a gradient calculation inside a conditional block
1135ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                // may return undefined results". This appears to be an issue with
1145ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                // the 'any' call since even the simple "result=black; if (any())
1155ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                // result=white;" code fails to compile.
116f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas                builder->codeAppend("half4 outside = half4(0.0, 0.0, 0.0, 0.0);");
117f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas                builder->codeAppend("half4 inside = ");
118c468963b967b5e8cde4ed320f7130a9d703c2a4eBrian Osman                builder->appendTextureLookupAndModulate(inModulateColor, sampler, inCoords.c_str(),
1192240be96d97b5ac0886381d74a21f1e2a0928f55Brian Osman                                                        kFloat2_GrSLType);
1203fc656006c8bcbdca069b1b0f500f3c7311e5e5ajvanverth                builder->codeAppend(";");
1219d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
1228aa4569c139a7a7ac38c62b25e3af40309cc2ee2Ethan Nicholas                builder->codeAppendf("float x = (%s).x;", inCoords.c_str());
1238aa4569c139a7a7ac38c62b25e3af40309cc2ee2Ethan Nicholas                builder->codeAppendf("float y = (%s).y;", inCoords.c_str());
1245ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt
1253fc656006c8bcbdca069b1b0f500f3c7311e5e5ajvanverth                builder->codeAppendf("x = abs(2.0*(x - %s.x)/(%s.z - %s.x) - 1.0);",
1263fc656006c8bcbdca069b1b0f500f3c7311e5e5ajvanverth                                     domain, domain, domain);
1273fc656006c8bcbdca069b1b0f500f3c7311e5e5ajvanverth                builder->codeAppendf("y = abs(2.0*(y - %s.y)/(%s.w - %s.y) - 1.0);",
1283fc656006c8bcbdca069b1b0f500f3c7311e5e5ajvanverth                                     domain, domain, domain);
129f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas                builder->codeAppend("half blend = step(1.0, max(x, y));");
1303fc656006c8bcbdca069b1b0f500f3c7311e5e5ajvanverth                builder->codeAppendf("%s = mix(inside, outside, blend);", outColor);
1315ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt            } else {
1325af9ea399d5e0344cc4b7da4e97b5dc5b3c74f64Ethan Nicholas                builder->codeAppend("bool4 outside;\n");
1333fc656006c8bcbdca069b1b0f500f3c7311e5e5ajvanverth                builder->codeAppendf("outside.xy = lessThan(%s, %s.xy);", inCoords.c_str(),
1345ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                                       domain);
1353fc656006c8bcbdca069b1b0f500f3c7311e5e5ajvanverth                builder->codeAppendf("outside.zw = greaterThan(%s, %s.zw);", inCoords.c_str(),
1365ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                                       domain);
137f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas                builder->codeAppendf("%s = any(outside) ? half4(0.0, 0.0, 0.0, 0.0) : ",
1385ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                                       outColor);
139c468963b967b5e8cde4ed320f7130a9d703c2a4eBrian Osman                builder->appendTextureLookupAndModulate(inModulateColor, sampler, inCoords.c_str(),
1402240be96d97b5ac0886381d74a21f1e2a0928f55Brian Osman                                                        kFloat2_GrSLType);
1413fc656006c8bcbdca069b1b0f500f3c7311e5e5ajvanverth                builder->codeAppend(";");
1425ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt            }
1435ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt            break;
1445ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt        }
1455ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt        case kRepeat_Mode: {
1465ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt            SkString clampedCoords;
1473fc656006c8bcbdca069b1b0f500f3c7311e5e5ajvanverth            clampedCoords.printf("mod(%s - %s.xy, %s.zw - %s.xy) + %s.xy",
1485ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                                 inCoords.c_str(), fDomainName.c_str(), fDomainName.c_str(),
1495ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt                                 fDomainName.c_str(), fDomainName.c_str());
1505ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt
1513fc656006c8bcbdca069b1b0f500f3c7311e5e5ajvanverth            builder->codeAppendf("%s = ", outColor);
152c468963b967b5e8cde4ed320f7130a9d703c2a4eBrian Osman            builder->appendTextureLookupAndModulate(inModulateColor, sampler, clampedCoords.c_str(),
1532240be96d97b5ac0886381d74a21f1e2a0928f55Brian Osman                                                    kFloat2_GrSLType);
1543fc656006c8bcbdca069b1b0f500f3c7311e5e5ajvanverth            builder->codeAppend(";");
1555ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt            break;
156907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        }
157907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    }
158907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org}
159907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
160018fb62d12d1febf121fe265da5b6117b86a6541egdanielvoid GrTextureDomain::GLDomain::setData(const GrGLSLProgramDataManager& pdman,
161907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                                        const GrTextureDomain& textureDomain,
162c686ce39f06d556d55befd290e0eb82851c7d33bRobert Phillips                                        GrSurfaceProxy* proxy) {
163c686ce39f06d556d55befd290e0eb82851c7d33bRobert Phillips    GrTexture* tex = proxy->priv().peekTexture();
164c63ec5ca64074dcc264a43bd1c1fdfb26e009410Hans Wennborg    SkASSERT(fHasMode && textureDomain.mode() == fMode);
165907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    if (kIgnore_Mode != textureDomain.mode()) {
166e98234f231d66848e149db683c11b6388e10b233Robert Phillips        SkScalar wInv = SK_Scalar1 / tex->width();
167e98234f231d66848e149db683c11b6388e10b233Robert Phillips        SkScalar hInv = SK_Scalar1 / tex->height();
168e98234f231d66848e149db683c11b6388e10b233Robert Phillips
169018fb62d12d1febf121fe265da5b6117b86a6541egdaniel        float values[kPrevDomainCount] = {
170e98234f231d66848e149db683c11b6388e10b233Robert Phillips            SkScalarToFloat(textureDomain.domain().fLeft * wInv),
171e98234f231d66848e149db683c11b6388e10b233Robert Phillips            SkScalarToFloat(textureDomain.domain().fTop * hInv),
172e98234f231d66848e149db683c11b6388e10b233Robert Phillips            SkScalarToFloat(textureDomain.domain().fRight * wInv),
173e98234f231d66848e149db683c11b6388e10b233Robert Phillips            SkScalarToFloat(textureDomain.domain().fBottom * hInv)
174907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        };
175e98234f231d66848e149db683c11b6388e10b233Robert Phillips
176e98234f231d66848e149db683c11b6388e10b233Robert Phillips        SkASSERT(values[0] >= 0.0f && values[0] <= 1.0f);
177e98234f231d66848e149db683c11b6388e10b233Robert Phillips        SkASSERT(values[1] >= 0.0f && values[1] <= 1.0f);
178e98234f231d66848e149db683c11b6388e10b233Robert Phillips        SkASSERT(values[2] >= 0.0f && values[2] <= 1.0f);
179e98234f231d66848e149db683c11b6388e10b233Robert Phillips        SkASSERT(values[3] >= 0.0f && values[3] <= 1.0f);
180e98234f231d66848e149db683c11b6388e10b233Robert Phillips
181907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        // vertical flip if necessary
182c686ce39f06d556d55befd290e0eb82851c7d33bRobert Phillips        if (kBottomLeft_GrSurfaceOrigin == proxy->origin()) {
183907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            values[1] = 1.0f - values[1];
184907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            values[3] = 1.0f - values[3];
185907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            // The top and bottom were just flipped, so correct the ordering
186907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            // of elements so that values = (l, t, r, b).
187907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org            SkTSwap(values[1], values[3]);
188907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        }
189018fb62d12d1febf121fe265da5b6117b86a6541egdaniel        if (0 != memcmp(values, fPrevDomain, kPrevDomainCount * sizeof(float))) {
1907510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen            pdman.set4fv(fDomainUni, 1, values);
191018fb62d12d1febf121fe265da5b6117b86a6541egdaniel            memcpy(fPrevDomain, values, kPrevDomainCount * sizeof(float));
192907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        }
193907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    }
194907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org}
195907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
1962f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com///////////////////////////////////////////////////////////////////////////////
197587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomoninline GrFragmentProcessor::OptimizationFlags GrTextureDomainEffect::OptFlags(
19840fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips        GrPixelConfig config, GrTextureDomain::Mode mode) {
19940fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    if (mode == GrTextureDomain::kDecal_Mode || !GrPixelConfigIsOpaque(config)) {
200f3b995b628ef76bff28b9721dd1e182336156086Brian Salomon        return GrFragmentProcessor::kCompatibleWithCoverageAsAlpha_OptimizationFlag;
201587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon    } else {
202f3b995b628ef76bff28b9721dd1e182336156086Brian Salomon        return GrFragmentProcessor::kCompatibleWithCoverageAsAlpha_OptimizationFlag |
203587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon               GrFragmentProcessor::kPreservesOpaqueInput_OptimizationFlag;
204587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon    }
205587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon}
206587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon
207aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomonstd::unique_ptr<GrFragmentProcessor> GrTextureDomainEffect::Make(
208aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon        sk_sp<GrTextureProxy> proxy,
209aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon        const SkMatrix& matrix,
210aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon        const SkRect& domain,
211aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon        GrTextureDomain::Mode mode,
2122bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon        GrSamplerState::Filter filterMode) {
21340fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    if (GrTextureDomain::kIgnore_Mode == mode ||
21440fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips        (GrTextureDomain::kClamp_Mode == mode && can_ignore_rect(proxy.get(), domain))) {
2152240be96d97b5ac0886381d74a21f1e2a0928f55Brian Osman        return GrSimpleTextureEffect::Make(std::move(proxy), matrix, filterMode);
21640fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    } else {
217aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon        return std::unique_ptr<GrFragmentProcessor>(new GrTextureDomainEffect(
2182240be96d97b5ac0886381d74a21f1e2a0928f55Brian Osman                std::move(proxy), matrix, domain, mode, filterMode));
21940fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    }
22040fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips}
22140fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips
222fbcef6eb8abad142daf45418516550f7635b4a52Robert PhillipsGrTextureDomainEffect::GrTextureDomainEffect(sk_sp<GrTextureProxy> proxy,
22340fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips                                             const SkMatrix& matrix,
22440fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips                                             const SkRect& domain,
22540fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips                                             GrTextureDomain::Mode mode,
2262bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon                                             GrSamplerState::Filter filterMode)
227abff956455637b12eab374fd44b99e1338799113Ethan Nicholas        : INHERITED(kGrTextureDomainEffect_ClassID, OptFlags(proxy->config(), mode))
2286cd51b51d6603a3100b147c45f38697f2f199fc6Brian Salomon        , fCoordTransform(matrix, proxy.get())
2296cd51b51d6603a3100b147c45f38697f2f199fc6Brian Salomon        , fTextureDomain(proxy.get(), domain, mode)
2302240be96d97b5ac0886381d74a21f1e2a0928f55Brian Osman        , fTextureSampler(std::move(proxy), filterMode) {
23140fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    SkASSERT(mode != GrTextureDomain::kRepeat_Mode ||
2322bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon             filterMode == GrSamplerState::Filter::kNearest);
2336cd51b51d6603a3100b147c45f38697f2f199fc6Brian Salomon    this->addCoordTransform(&fCoordTransform);
2346cd51b51d6603a3100b147c45f38697f2f199fc6Brian Salomon    this->addTextureSampler(&fTextureSampler);
23540fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips}
23640fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips
2373f6f965a5a65415c65fe9e64eb41896c66da771dBrian SalomonGrTextureDomainEffect::GrTextureDomainEffect(const GrTextureDomainEffect& that)
238abff956455637b12eab374fd44b99e1338799113Ethan Nicholas        : INHERITED(kGrTextureDomainEffect_ClassID, that.optimizationFlags())
2393f6f965a5a65415c65fe9e64eb41896c66da771dBrian Salomon        , fCoordTransform(that.fCoordTransform)
2403f6f965a5a65415c65fe9e64eb41896c66da771dBrian Salomon        , fTextureDomain(that.fTextureDomain)
2412240be96d97b5ac0886381d74a21f1e2a0928f55Brian Osman        , fTextureSampler(that.fTextureSampler) {
2423f6f965a5a65415c65fe9e64eb41896c66da771dBrian Salomon    this->addCoordTransform(&fCoordTransform);
2433f6f965a5a65415c65fe9e64eb41896c66da771dBrian Salomon    this->addTextureSampler(&fTextureSampler);
2443f6f965a5a65415c65fe9e64eb41896c66da771dBrian Salomon}
2453f6f965a5a65415c65fe9e64eb41896c66da771dBrian Salomon
24694efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomonvoid GrTextureDomainEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
24757d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel                                                  GrProcessorKeyBuilder* b) const {
2482ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon    b->add32(GrTextureDomain::GLDomain::DomainKey(fTextureDomain));
249eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt}
250eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
25157d3b039c635945e1dc2fcbac3462ed8bfedb068egdanielGrGLSLFragmentProcessor* GrTextureDomainEffect::onCreateGLSLInstance() const  {
2522ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon    class GLSLProcessor : public GrGLSLFragmentProcessor {
2532ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon    public:
2542ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon        void emitCode(EmitArgs& args) override {
2552ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon            const GrTextureDomainEffect& tde = args.fFp.cast<GrTextureDomainEffect>();
2562ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon            const GrTextureDomain& domain = tde.fTextureDomain;
2572ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon
2582ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon            GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
2592ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon            SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
260c468963b967b5e8cde4ed320f7130a9d703c2a4eBrian Osman
2612ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon            fGLDomain.sampleTexture(fragBuilder,
2622ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon                                    args.fUniformHandler,
2631edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon                                    args.fShaderCaps,
2642ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon                                    domain,
2652ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon                                    args.fOutputColor,
2662ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon                                    coords2D,
2672ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon                                    args.fTexSamplers[0],
2682240be96d97b5ac0886381d74a21f1e2a0928f55Brian Osman                                    args.fInputColor);
2692ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon        }
2702ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon
2712ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon    protected:
272ab015efc48c462ffdffebb45c02cd19efb254983Brian Salomon        void onSetData(const GrGLSLProgramDataManager& pdman,
273ab015efc48c462ffdffebb45c02cd19efb254983Brian Salomon                       const GrFragmentProcessor& fp) override {
2742ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon            const GrTextureDomainEffect& tde = fp.cast<GrTextureDomainEffect>();
2752ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon            const GrTextureDomain& domain = tde.fTextureDomain;
276c686ce39f06d556d55befd290e0eb82851c7d33bRobert Phillips            GrSurfaceProxy* proxy = tde.textureSampler(0).proxy();
2779bee2e5894bb8dd374392f238bc429e16f239583Robert Phillips
278c686ce39f06d556d55befd290e0eb82851c7d33bRobert Phillips            fGLDomain.setData(pdman, domain, proxy);
2792ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon        }
2802ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon
2812ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon    private:
2822ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon        GrTextureDomain::GLDomain         fGLDomain;
2832ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon    };
2842ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon
2852ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon    return new GLSLProcessor;
2862f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com}
2872f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
2880e08fc17e4718f7ce4e38f793695896473e96948bsalomonbool GrTextureDomainEffect::onIsEqual(const GrFragmentProcessor& sBase) const {
28949586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt    const GrTextureDomainEffect& s = sBase.cast<GrTextureDomainEffect>();
290a7c4c29abfee3b17f1ba0e6c6b1f98b6fb9cd2b8Brian Salomon    return this->fTextureDomain == s.fTextureDomain;
29168b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com}
29268b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com
2930a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com///////////////////////////////////////////////////////////////////////////////
2940a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com
295b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrTextureDomainEffect);
2960a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com
2976f6961ebad65c582318564b3688e78e5c99f3935Hal Canary#if GR_TEST_UTILS
298aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomonstd::unique_ptr<GrFragmentProcessor> GrTextureDomainEffect::TestCreate(GrProcessorTestData* d) {
29940fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx
30040fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips                                        : GrProcessorUnitTest::kAlphaTextureIdx;
30140fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    sk_sp<GrTextureProxy> proxy = d->textureProxy(texIdx);
302fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org    SkRect domain;
30340fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    domain.fLeft = d->fRandom->nextRangeScalar(0, proxy->width());
30440fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    domain.fRight = d->fRandom->nextRangeScalar(domain.fLeft, proxy->width());
30540fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    domain.fTop = d->fRandom->nextRangeScalar(0, proxy->height());
30640fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    domain.fBottom = d->fRandom->nextRangeScalar(domain.fTop, proxy->height());
307907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    GrTextureDomain::Mode mode =
3080067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt        (GrTextureDomain::Mode) d->fRandom->nextULessThan(GrTextureDomain::kModeCount);
3090067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    const SkMatrix& matrix = GrTest::TestMatrix(d->fRandom);
3100067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    bool bilerp = mode != GrTextureDomain::kRepeat_Mode ? d->fRandom->nextBool() : false;
3112bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon    return GrTextureDomainEffect::Make(
3122bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon            std::move(proxy),
3132bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon            matrix,
3142bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon            domain,
3152bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon            mode,
3162bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon            bilerp ? GrSamplerState::Filter::kBilerp : GrSamplerState::Filter::kNearest);
3172ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon}
3186f6961ebad65c582318564b3688e78e5c99f3935Hal Canary#endif
3192ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon
3202ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon///////////////////////////////////////////////////////////////////////////////
321aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomonstd::unique_ptr<GrFragmentProcessor> GrDeviceSpaceTextureDecalFragmentProcessor::Make(
322aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon        sk_sp<GrTextureProxy> proxy, const SkIRect& subset, const SkIPoint& deviceSpaceOffset) {
323aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon    return std::unique_ptr<GrFragmentProcessor>(new GrDeviceSpaceTextureDecalFragmentProcessor(
324fbcef6eb8abad142daf45418516550f7635b4a52Robert Phillips            std::move(proxy), subset, deviceSpaceOffset));
32540fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips}
32640fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips
32740fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert PhillipsGrDeviceSpaceTextureDecalFragmentProcessor::GrDeviceSpaceTextureDecalFragmentProcessor(
3282bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon        sk_sp<GrTextureProxy> proxy, const SkIRect& subset, const SkIPoint& deviceSpaceOffset)
329abff956455637b12eab374fd44b99e1338799113Ethan Nicholas        : INHERITED(kGrDeviceSpaceTextureDecalFragmentProcessor_ClassID,
330abff956455637b12eab374fd44b99e1338799113Ethan Nicholas                    kCompatibleWithCoverageAsAlpha_OptimizationFlag)
3312bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon        , fTextureSampler(proxy, GrSamplerState::ClampNearest())
33240fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips        , fTextureDomain(proxy.get(), GrTextureDomain::MakeTexelDomain(subset),
33340fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips                         GrTextureDomain::kDecal_Mode) {
33440fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    this->addTextureSampler(&fTextureSampler);
33540fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    fDeviceSpaceOffset.fX = deviceSpaceOffset.fX - subset.fLeft;
33640fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    fDeviceSpaceOffset.fY = deviceSpaceOffset.fY - subset.fTop;
33740fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips}
33840fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips
3391a2a7abe96d258399cca111ea55594599b461c33Brian SalomonGrDeviceSpaceTextureDecalFragmentProcessor::GrDeviceSpaceTextureDecalFragmentProcessor(
3401a2a7abe96d258399cca111ea55594599b461c33Brian Salomon        const GrDeviceSpaceTextureDecalFragmentProcessor& that)
341abff956455637b12eab374fd44b99e1338799113Ethan Nicholas        : INHERITED(kGrDeviceSpaceTextureDecalFragmentProcessor_ClassID,
342abff956455637b12eab374fd44b99e1338799113Ethan Nicholas                    kCompatibleWithCoverageAsAlpha_OptimizationFlag)
3431a2a7abe96d258399cca111ea55594599b461c33Brian Salomon        , fTextureSampler(that.fTextureSampler)
3441a2a7abe96d258399cca111ea55594599b461c33Brian Salomon        , fTextureDomain(that.fTextureDomain)
3451a2a7abe96d258399cca111ea55594599b461c33Brian Salomon        , fDeviceSpaceOffset(that.fDeviceSpaceOffset) {
3461a2a7abe96d258399cca111ea55594599b461c33Brian Salomon    this->addTextureSampler(&fTextureSampler);
3471a2a7abe96d258399cca111ea55594599b461c33Brian Salomon}
3481a2a7abe96d258399cca111ea55594599b461c33Brian Salomon
349aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomonstd::unique_ptr<GrFragmentProcessor> GrDeviceSpaceTextureDecalFragmentProcessor::clone() const {
350aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon    return std::unique_ptr<GrFragmentProcessor>(
351aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon            new GrDeviceSpaceTextureDecalFragmentProcessor(*this));
3521a2a7abe96d258399cca111ea55594599b461c33Brian Salomon}
3531a2a7abe96d258399cca111ea55594599b461c33Brian Salomon
3542ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian SalomonGrGLSLFragmentProcessor* GrDeviceSpaceTextureDecalFragmentProcessor::onCreateGLSLInstance() const  {
3552ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon    class GLSLProcessor : public GrGLSLFragmentProcessor {
3562ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon    public:
3572ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon        void emitCode(EmitArgs& args) override {
3582ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon            const GrDeviceSpaceTextureDecalFragmentProcessor& dstdfp =
3592ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon                    args.fFp.cast<GrDeviceSpaceTextureDecalFragmentProcessor>();
3602ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon            const char* scaleAndTranslateName;
3612ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon            fScaleAndTranslateUni = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
362f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas                                                                     kHalf4_GrSLType,
3632ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon                                                                     "scaleAndTranslate",
3642ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon                                                                     &scaleAndTranslateName);
365f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas            args.fFragBuilder->codeAppendf("half2 coords = sk_FragCoord.xy * %s.xy + %s.zw;",
3662ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon                                           scaleAndTranslateName, scaleAndTranslateName);
3672ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon            fGLDomain.sampleTexture(args.fFragBuilder,
3682ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon                                    args.fUniformHandler,
3691edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon                                    args.fShaderCaps,
3702ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon                                    dstdfp.fTextureDomain,
3712ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon                                    args.fOutputColor,
3722ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon                                    SkString("coords"),
3732ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon                                    args.fTexSamplers[0],
3742ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon                                    args.fInputColor);
3752ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon        }
3762ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon
3772ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon    protected:
378ab015efc48c462ffdffebb45c02cd19efb254983Brian Salomon        void onSetData(const GrGLSLProgramDataManager& pdman,
379ab015efc48c462ffdffebb45c02cd19efb254983Brian Salomon                       const GrFragmentProcessor& fp) override {
3802ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon            const GrDeviceSpaceTextureDecalFragmentProcessor& dstdfp =
3812ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon                    fp.cast<GrDeviceSpaceTextureDecalFragmentProcessor>();
382c686ce39f06d556d55befd290e0eb82851c7d33bRobert Phillips            GrSurfaceProxy* proxy = dstdfp.textureSampler(0).proxy();
383c686ce39f06d556d55befd290e0eb82851c7d33bRobert Phillips            GrTexture* texture = proxy->priv().peekTexture();
3849bee2e5894bb8dd374392f238bc429e16f239583Robert Phillips
385c686ce39f06d556d55befd290e0eb82851c7d33bRobert Phillips            fGLDomain.setData(pdman, dstdfp.fTextureDomain, proxy);
3860bbecb21ab82b3d742c491780bcc2e74be03efedBrian Salomon            float iw = 1.f / texture->width();
3870bbecb21ab82b3d742c491780bcc2e74be03efedBrian Salomon            float ih = 1.f / texture->height();
3882ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon            float scaleAndTransData[4] = {
3892ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon                iw, ih,
3902ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon                -dstdfp.fDeviceSpaceOffset.fX * iw, -dstdfp.fDeviceSpaceOffset.fY * ih
3912ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon            };
392c686ce39f06d556d55befd290e0eb82851c7d33bRobert Phillips            if (proxy->origin() == kBottomLeft_GrSurfaceOrigin) {
3932ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon                scaleAndTransData[1] = -scaleAndTransData[1];
3942ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon                scaleAndTransData[3] = 1 - scaleAndTransData[3];
3952ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon            }
3962ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon            pdman.set4fv(fScaleAndTranslateUni, 1, scaleAndTransData);
3972ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon        }
3982ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon
3992ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon    private:
4002ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon        GrTextureDomain::GLDomain   fGLDomain;
4012ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon        UniformHandle               fScaleAndTranslateUni;
4022ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon    };
4032ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon
4042ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon    return new GLSLProcessor;
4052ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon}
4062ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon
4072ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomonbool GrDeviceSpaceTextureDecalFragmentProcessor::onIsEqual(const GrFragmentProcessor& fp) const {
4082ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon    const GrDeviceSpaceTextureDecalFragmentProcessor& dstdfp =
4092ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon            fp.cast<GrDeviceSpaceTextureDecalFragmentProcessor>();
4101a2a7abe96d258399cca111ea55594599b461c33Brian Salomon    return dstdfp.fTextureSampler.proxy()->underlyingUniqueID() ==
4111a2a7abe96d258399cca111ea55594599b461c33Brian Salomon                   fTextureSampler.proxy()->underlyingUniqueID() &&
4122ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon           dstdfp.fDeviceSpaceOffset == fDeviceSpaceOffset &&
4132ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon           dstdfp.fTextureDomain == fTextureDomain;
4142ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon}
4152ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon
4162ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon///////////////////////////////////////////////////////////////////////////////
4172ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon
4182ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian SalomonGR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrDeviceSpaceTextureDecalFragmentProcessor);
4192ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon
4206f6961ebad65c582318564b3688e78e5c99f3935Hal Canary#if GR_TEST_UTILS
421aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomonstd::unique_ptr<GrFragmentProcessor> GrDeviceSpaceTextureDecalFragmentProcessor::TestCreate(
4222ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon        GrProcessorTestData* d) {
4232ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon    int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx
4242ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon                                        : GrProcessorUnitTest::kAlphaTextureIdx;
42540fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    sk_sp<GrTextureProxy> proxy = d->textureProxy(texIdx);
4262ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon    SkIRect subset;
42740fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    subset.fLeft = d->fRandom->nextULessThan(proxy->width() - 1);
42840fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    subset.fRight = d->fRandom->nextRangeU(subset.fLeft, proxy->width());
42940fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    subset.fTop = d->fRandom->nextULessThan(proxy->height() - 1);
43040fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips    subset.fBottom = d->fRandom->nextRangeU(subset.fTop, proxy->height());
4312ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon    SkIPoint pt;
4322ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon    pt.fX = d->fRandom->nextULessThan(2048);
4332ebd0c80a2a9d90a2c2c653f40a2a7205bd2d31bBrian Salomon    pt.fY = d->fRandom->nextULessThan(2048);
434fbcef6eb8abad142daf45418516550f7635b4a52Robert Phillips    return GrDeviceSpaceTextureDecalFragmentProcessor::Make(std::move(proxy), subset, pt);
4350a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com}
4366f6961ebad65c582318564b3688e78e5c99f3935Hal Canary#endif
437