SkGr.cpp revision e41e1769e76dcce573038d04d90d62043ece7e4f
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2010 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */
7ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
8ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "SkGr.h"
93b66ab6f9fdc6eacdf0ee1921da28751de30c018Brian Osman#include "GrBitmapTextureMaker.h"
10762286309545c8a1e4bbc05dcd1fe3085d2a1f47bsalomon#include "GrCaps.h"
111cb41717bc4a44272eab48bd47ca7579425dc22eBrian Osman#include "GrColorSpaceXform.h"
12f276ac5c16d39a2b877300d760041f0291bb5ec9bsalomon#include "GrContext.h"
1355afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel#include "GrContextPriv.h"
14045802dbb7202b52f5fd2758d725f39c156a6165bsalomon#include "GrGpuResourcePriv.h"
15f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon#include "GrPaint.h"
161afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips#include "GrProxyProvider.h"
176f6961ebad65c582318564b3688e78e5c99f3935Hal Canary#include "GrTextureProxy.h"
1855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume#include "GrTypes.h"
19378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel#include "GrXferProcessor.h"
2095e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary#include "SkAutoMalloc.h"
21374772bd61951f01bf84fe17bf53d8867681c9aereed#include "SkBlendModePriv.h"
2295e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary#include "SkCanvas.h"
238dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org#include "SkColorFilter.h"
24485c499a2797c1eb0e750fa4aaec57192799b424Matt Sarett#include "SkConvertPixels.h"
259c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski#include "SkData.h"
264075ec80e1c36e414e57746c772298be3b49a74eBrian Osman#include "SkImageInfoPriv.h"
2780747ef591ff3c09c2b610eb21258132d1ff4ef5Mike Reed#include "SkMaskFilterBase.h"
2850a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org#include "SkMessageBus.h"
2955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume#include "SkMipMap.h"
30c456b73fef9589bbdc5eb83eaa83e53c357bb3daKevin Lubick#include "SkPM4fPriv.h"
31d4a70ee36717493cc071f878b16b037463e6ce9aFlorin Malita#include "SkPaintPriv.h"
3295e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary#include "SkPixelRef.h"
33692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi#include "SkResourceCache.h"
344aed13889bd9085337e0d4c20df28686687b833bFlorin Malita#include "SkShaderBase.h"
3555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume#include "SkTemplates.h"
36559f534759f616f1d9a173e0045acead5ee4cae1Derek Sollenberger#include "SkTraceEvent.h"
379bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt#include "effects/GrBicubicEffect.h"
38f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon#include "effects/GrConstColorProcessor.h"
39f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#include "effects/GrDitherEffect.h"
40378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel#include "effects/GrPorterDuffXferProcessor.h"
41f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon#include "effects/GrXfermodeFragmentProcessor.h"
429c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
43a6359365887048ef055196de75591311d7a015f0brianosmanGrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo& info, const GrCaps& caps) {
44466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    GrSurfaceDesc desc;
45466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    desc.fFlags = kNone_GrSurfaceFlags;
46019ff27ac0167026f9f8f4aaec8fb6461d8ba21eRobert Phillips    desc.fOrigin = kTopLeft_GrSurfaceOrigin;
47466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    desc.fWidth = info.width();
48466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    desc.fHeight = info.height();
49a6359365887048ef055196de75591311d7a015f0brianosman    desc.fConfig = SkImageInfo2GrPixelConfig(info, caps);
50466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    desc.fSampleCnt = 0;
51466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    return desc;
52466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon}
53466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon
54045802dbb7202b52f5fd2758d725f39c156a6165bsalomonvoid GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID, const SkIRect& imageBounds) {
55045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    SkASSERT(key);
56045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    SkASSERT(imageID);
57045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    SkASSERT(!imageBounds.isEmpty());
58045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    static const GrUniqueKey::Domain kImageIDDomain = GrUniqueKey::GenerateDomain();
59045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    GrUniqueKey::Builder builder(key, kImageIDDomain, 5);
60466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    builder[0] = imageID;
61045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    builder[1] = imageBounds.fLeft;
62045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    builder[2] = imageBounds.fTop;
63045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    builder[3] = imageBounds.fRight;
64045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    builder[4] = imageBounds.fBottom;
65466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon}
66466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon
67045802dbb7202b52f5fd2758d725f39c156a6165bsalomon//////////////////////////////////////////////////////////////////////////////
681afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillipssk_sp<GrTextureProxy> GrUploadBitmapToTextureProxy(GrProxyProvider* proxyProvider,
69dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett                                                   const SkBitmap& bitmap,
70dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett                                                   SkColorSpace* dstColorSpace) {
71d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips    if (!bitmap.readyToDraw()) {
72d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips        return nullptr;
73d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips    }
74d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips    SkPixmap pixmap;
75d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips    if (!bitmap.peekPixels(&pixmap)) {
764075ec80e1c36e414e57746c772298be3b49a74eBrian Osman        return nullptr;
774075ec80e1c36e414e57746c772298be3b49a74eBrian Osman    }
781afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips    return GrUploadPixmapToTextureProxy(proxyProvider, pixmap, SkBudgeted::kYes, dstColorSpace);
79d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips}
804075ec80e1c36e414e57746c772298be3b49a74eBrian Osman
811afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillipssk_sp<GrTextureProxy> GrUploadPixmapToTextureProxy(GrProxyProvider* proxyProvider,
82dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett                                                   const SkPixmap& pixmap,
83dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett                                                   SkBudgeted budgeted,
84dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett                                                   SkColorSpace* dstColorSpace) {
85dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett    SkDestinationSurfaceColorMode colorMode = dstColorSpace
86dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett        ? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware
87dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett        : SkDestinationSurfaceColorMode::kLegacy;
88dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett
89dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett    if (!SkImageInfoIsValid(pixmap.info(), colorMode)) {
90dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett        return nullptr;
91dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett    }
92dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett
93559f534759f616f1d9a173e0045acead5ee4cae1Derek Sollenberger    ATRACE_ANDROID_FRAMEWORK("Upload Texture [%ux%u]", pixmap.width(), pixmap.height());
941afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips    GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(pixmap.info(), *proxyProvider->caps());
950bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips
960bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips    return proxyProvider->createTextureProxy(desc, budgeted, pixmap.addr(), pixmap.rowBytes());
97d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips}
98b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon
99045802dbb7202b52f5fd2758d725f39c156a6165bsalomon////////////////////////////////////////////////////////////////////////////////
100045802dbb7202b52f5fd2758d725f39c156a6165bsalomon
101c55271f2551533b37043aa2e37f754832a43073cbsalomonvoid GrInstallBitmapUniqueKeyInvalidator(const GrUniqueKey& key, SkPixelRef* pixelRef) {
10289fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon    class Invalidator : public SkPixelRef::GenIDChangeListener {
10389fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon    public:
10489fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon        explicit Invalidator(const GrUniqueKey& key) : fMsg(key) {}
10589fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon    private:
10689fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon        GrUniqueKeyInvalidatedMessage fMsg;
10789fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon
10889fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon        void onChange() override { SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(fMsg); }
10989fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon    };
11089fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon
11189fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon    pixelRef->addGenIDChangeListener(new Invalidator(key));
11289fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon}
11389fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon
1140bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillipssk_sp<GrTextureProxy> GrGenerateMipMapsAndUploadToTextureProxy(GrProxyProvider* proxyProvider,
11578075804c1e43ca32f3d8eb75d2a8b6c91e74b9bRobert Phillips                                                               const SkBitmap& bitmap,
11678075804c1e43ca32f3d8eb75d2a8b6c91e74b9bRobert Phillips                                                               SkColorSpace* dstColorSpace) {
11761624f0c716b576706659750d87b6956f4c15722Brian Osman    SkDestinationSurfaceColorMode colorMode = dstColorSpace
11861624f0c716b576706659750d87b6956f4c15722Brian Osman        ? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware
11961624f0c716b576706659750d87b6956f4c15722Brian Osman        : SkDestinationSurfaceColorMode::kLegacy;
12061624f0c716b576706659750d87b6956f4c15722Brian Osman
121dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett    if (!SkImageInfoIsValid(bitmap.info(), colorMode)) {
1224075ec80e1c36e414e57746c772298be3b49a74eBrian Osman        return nullptr;
1234075ec80e1c36e414e57746c772298be3b49a74eBrian Osman    }
1244075ec80e1c36e414e57746c772298be3b49a74eBrian Osman
1254edb5d219eb99aa1e8fbe5e37260d3b34314e54bMike Reed    SkPixmap pixmap;
1264edb5d219eb99aa1e8fbe5e37260d3b34314e54bMike Reed    if (!bitmap.peekPixels(&pixmap)) {
12755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        return nullptr;
12855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    }
12955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
130243f605ce9fb3d7c91a1c49e8f052dd4d00db8a0Brian Osman    ATRACE_ANDROID_FRAMEWORK("Upload MipMap Texture [%ux%u]", pixmap.width(), pixmap.height());
1310bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips    GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(pixmap.info(), *proxyProvider->caps());
1329d44081e00f67361414935b82332df5754bddcafBrian Osman    std::unique_ptr<SkMipMap> mipmaps(SkMipMap::Build(pixmap, colorMode, nullptr));
13355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    if (!mipmaps) {
13455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        return nullptr;
13555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    }
13655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
13755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    const int mipLevelCount = mipmaps->countLevels() + 1;
13855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    if (mipLevelCount < 1) {
13955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        return nullptr;
14055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    }
14155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
1427ecc59610de72043e9b7ebaf1ef45c43425e54fcBen Wagner    std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipLevelCount]);
14355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
1449d44081e00f67361414935b82332df5754bddcafBrian Osman    texels[0].fPixels = pixmap.addr();
1459d44081e00f67361414935b82332df5754bddcafBrian Osman    texels[0].fRowBytes = pixmap.rowBytes();
14655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
14755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    for (int i = 1; i < mipLevelCount; ++i) {
14855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        SkMipMap::Level generatedMipLevel;
14955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        mipmaps->getLevel(i - 1, &generatedMipLevel);
15055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        texels[i].fPixels = generatedMipLevel.fPixmap.addr();
15155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        texels[i].fRowBytes = generatedMipLevel.fPixmap.rowBytes();
15255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    }
15355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
1540bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips    return proxyProvider->createMipMapProxy(desc, SkBudgeted::kYes, texels.get(), mipLevelCount,
1550bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips                                            colorMode);
1560c984a0af30989fe20b1f8af18867983a88c48b6Robert Phillips}
1570c984a0af30989fe20b1f8af18867983a88c48b6Robert Phillips
1580bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillipssk_sp<GrTextureProxy> GrCopyBaseMipMapToTextureProxy(GrContext* ctx, GrTextureProxy* baseProxy) {
15955afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    SkASSERT(baseProxy);
16055afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel
161bb76ace72bee5d44189b6ee6c81cda174ce9ea30Greg Daniel    if (!ctx->caps()->isConfigCopyable(baseProxy->config())) {
162bb76ace72bee5d44189b6ee6c81cda174ce9ea30Greg Daniel        return nullptr;
163bb76ace72bee5d44189b6ee6c81cda174ce9ea30Greg Daniel    }
164bb76ace72bee5d44189b6ee6c81cda174ce9ea30Greg Daniel
1650bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips    GrProxyProvider* proxyProvider = ctx->contextPriv().proxyProvider();
16655afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    GrSurfaceDesc desc;
16755afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    desc.fFlags = kNone_GrSurfaceFlags;
16855afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    desc.fOrigin = baseProxy->origin();
16955afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    desc.fWidth = baseProxy->width();
17055afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    desc.fHeight = baseProxy->height();
17155afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    desc.fConfig = baseProxy->config();
17255afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    desc.fSampleCnt = 0;
17355afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel
1740bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips    sk_sp<GrTextureProxy> proxy = proxyProvider->createMipMapProxy(desc, SkBudgeted::kYes);
17555afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    if (!proxy) {
17655afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel        return nullptr;
17755afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    }
17855afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel
17955afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    // Copy the base layer to our proxy
18055afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    sk_sp<GrSurfaceContext> sContext = ctx->contextPriv().makeWrappedSurfaceContext(proxy, nullptr);
18155afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    SkASSERT(sContext);
18255afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    SkAssertResult(sContext->copy(baseProxy));
18355afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel
18455afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    return proxy;
18555afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel}
18655afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel
18755afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel
1880bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillipssk_sp<GrTextureProxy> GrUploadMipMapToTextureProxy(GrProxyProvider* proxyProvider,
1890bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips                                                   const SkImageInfo& info,
190590533f066035a48df9f78395a80314b559f4714Robert Phillips                                                   const GrMipLevel texels[],
19178075804c1e43ca32f3d8eb75d2a8b6c91e74b9bRobert Phillips                                                   int mipLevelCount,
19278075804c1e43ca32f3d8eb75d2a8b6c91e74b9bRobert Phillips                                                   SkDestinationSurfaceColorMode colorMode) {
193dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett    if (!SkImageInfoIsValid(info, colorMode)) {
1944075ec80e1c36e414e57746c772298be3b49a74eBrian Osman        return nullptr;
1954075ec80e1c36e414e57746c772298be3b49a74eBrian Osman    }
1964075ec80e1c36e414e57746c772298be3b49a74eBrian Osman
1970bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips    GrSurfaceDesc desc(GrImageInfoToSurfaceDesc(info, *proxyProvider->caps()));
1980bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips
1990bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips    return proxyProvider->createMipMapProxy(desc, SkBudgeted::kYes,
2000bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips                                            texels, mipLevelCount, colorMode);
2010ae6faa34d73ffc7ebec3d13f0473703bade821bRobert Phillips}
2020ae6faa34d73ffc7ebec3d13f0473703bade821bRobert Phillips
203bbd7a3be407ce94fcc4f8b1eb475de8b6f49026eRobert Phillipssk_sp<GrTextureProxy> GrRefCachedBitmapTextureProxy(GrContext* ctx,
204bbd7a3be407ce94fcc4f8b1eb475de8b6f49026eRobert Phillips                                                    const SkBitmap& bitmap,
2052bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon                                                    const GrSamplerState& params,
206bbd7a3be407ce94fcc4f8b1eb475de8b6f49026eRobert Phillips                                                    SkScalar scaleAdjust[2]) {
207bbd7a3be407ce94fcc4f8b1eb475de8b6f49026eRobert Phillips    // Caller doesn't care about the texture's color space (they can always get it from the bitmap)
2083798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips    return GrBitmapTextureMaker(ctx, bitmap).refTextureProxyForParams(params, nullptr,
2093798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips                                                                      nullptr, scaleAdjust);
210bbd7a3be407ce94fcc4f8b1eb475de8b6f49026eRobert Phillips}
211bbd7a3be407ce94fcc4f8b1eb475de8b6f49026eRobert Phillips
2121afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillipssk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrProxyProvider* proxyProvider,
21326c90e04797e15c37ec00e0f836292b8a207d294Robert Phillips                                              const SkBitmap& bitmap) {
214e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips    GrUniqueKey originalKey;
215e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips
216e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips    if (!bitmap.isVolatile()) {
217e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips        SkIPoint origin = bitmap.pixelRefOrigin();
218e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips        SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, bitmap.width(), bitmap.height());
219e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips        GrMakeKeyFromImageID(&originalKey, bitmap.pixelRef()->getGenerationID(), subset);
220e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips    }
221e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips
222d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips    sk_sp<GrTextureProxy> proxy;
223e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips
224e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips    if (originalKey.isValid()) {
2251afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips        proxy = proxyProvider->findOrCreateProxyByUniqueKey(originalKey, kTopLeft_GrSurfaceOrigin);
226e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips    }
227d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips    if (!proxy) {
228dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett        // Pass nullptr for |dstColorSpace|.  This is lenient - we allow a wider range of
229dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett        // color spaces in legacy mode.  Unfortunately, we have to be lenient here, since
230dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett        // we can't necessarily know the |dstColorSpace| at this time.
2311afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips        proxy = GrUploadBitmapToTextureProxy(proxyProvider, bitmap, nullptr);
232d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips        if (proxy && originalKey.isValid()) {
233019ff27ac0167026f9f8f4aaec8fb6461d8ba21eRobert Phillips            SkASSERT(proxy->origin() == kTopLeft_GrSurfaceOrigin);
2341afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips            proxyProvider->assignUniqueKeyToProxy(originalKey, proxy.get());
235e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips            GrInstallBitmapUniqueKeyInvalidator(originalKey, bitmap.pixelRef());
236e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips        }
237e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips    }
238e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips
239d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips    return proxy;
240e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips}
241e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips
24224f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com///////////////////////////////////////////////////////////////////////////////
24324f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com
2444cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian SalomonGrColor4f SkColorToPremulGrColor4f(SkColor c, const GrColorSpaceInfo& colorSpaceInfo) {
24572ae431e4032985999dc0990bfbbf4acf127a74eBrian Osman    // We want to premultiply after linearizing, so this is easy:
2464cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon    return SkColorToUnpremulGrColor4f(c, colorSpaceInfo).premul();
24772ae431e4032985999dc0990bfbbf4acf127a74eBrian Osman}
24872ae431e4032985999dc0990bfbbf4acf127a74eBrian Osman
2494cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian SalomonGrColor4f SkColorToPremulGrColor4fLegacy(SkColor c) {
2504cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon    return GrColor4f::FromGrColor(SkColorToUnpremulGrColor(c)).premul();
25172ae431e4032985999dc0990bfbbf4acf127a74eBrian Osman}
25272ae431e4032985999dc0990bfbbf4acf127a74eBrian Osman
2534cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian SalomonGrColor4f SkColorToUnpremulGrColor4f(SkColor c, const GrColorSpaceInfo& colorSpaceInfo) {
254c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman    GrColor4f color;
2554cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon    if (colorSpaceInfo.colorSpace()) {
256c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman        // SkColor4f::FromColor does sRGB -> Linear
257c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman        color = GrColor4f::FromSkColor4f(SkColor4f::FromColor(c));
258c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman    } else {
259c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman        // GrColor4f::FromGrColor just multiplies by 1/255
260c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman        color = GrColor4f::FromGrColor(SkColorToUnpremulGrColor(c));
261c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman    }
262c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman
2634cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon    if (auto* xform = colorSpaceInfo.colorSpaceXformFromSRGB()) {
2644cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon        color = xform->clampedXform(color);
265c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman    }
266c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman
267c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman    return color;
268c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman}
269c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman
270c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman///////////////////////////////////////////////////////////////////////////////
271c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman
27281e7bf8d6d338d944f3c5075b14c21580398aeb6Greg DanielGrPixelConfig SkImageInfo2GrPixelConfig(const SkColorType type, SkColorSpace* cs,
27381e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel                                        const GrCaps& caps) {
27481e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel    switch (type) {
275c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman        case kUnknown_SkColorType:
276c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman            return kUnknown_GrPixelConfig;
277c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman        case kAlpha_8_SkColorType:
278c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman            return kAlpha_8_GrPixelConfig;
279c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman        case kRGB_565_SkColorType:
280c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman            return kRGB_565_GrPixelConfig;
281c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman        case kARGB_4444_SkColorType:
282c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman            return kRGBA_4444_GrPixelConfig;
283c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman        case kRGBA_8888_SkColorType:
284f3880933092c3226cd7ffd1690fe72c9c0cc376cMatt Sarett            return (caps.srgbSupport() && cs && cs->gammaCloseToSRGB())
285a6359365887048ef055196de75591311d7a015f0brianosman                   ? kSRGBA_8888_GrPixelConfig : kRGBA_8888_GrPixelConfig;
2869d44081e00f67361414935b82332df5754bddcafBrian Osman        // TODO: We're checking for srgbSupport, but we can then end up picking sBGRA as our pixel
2879d44081e00f67361414935b82332df5754bddcafBrian Osman        // config (which may not be supported). We need a better test here.
288e41e1769e76dcce573038d04d90d62043ece7e4fBrian Salomon        case kRGB_888x_SkColorType:
289e41e1769e76dcce573038d04d90d62043ece7e4fBrian Salomon            return kUnknown_GrPixelConfig;
290c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman        case kBGRA_8888_SkColorType:
291f3880933092c3226cd7ffd1690fe72c9c0cc376cMatt Sarett            return (caps.srgbSupport() && cs && cs->gammaCloseToSRGB())
292a6359365887048ef055196de75591311d7a015f0brianosman                   ? kSBGRA_8888_GrPixelConfig : kBGRA_8888_GrPixelConfig;
293e41e1769e76dcce573038d04d90d62043ece7e4fBrian Salomon        case kRGBA_1010102_SkColorType:
294e41e1769e76dcce573038d04d90d62043ece7e4fBrian Salomon            return kUnknown_GrPixelConfig;
295e41e1769e76dcce573038d04d90d62043ece7e4fBrian Salomon        case kRGB_101010x_SkColorType:
296e41e1769e76dcce573038d04d90d62043ece7e4fBrian Salomon            return kUnknown_GrPixelConfig;
297c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman        case kGray_8_SkColorType:
298986563bcff26300ea4317b4dd84917d5240bb723Brian Osman            return kGray_8_GrPixelConfig;
299c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman        case kRGBA_F16_SkColorType:
300c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman            return kRGBA_half_GrPixelConfig;
30115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    }
30215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    SkASSERT(0);    // shouldn't get here
30315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    return kUnknown_GrPixelConfig;
30415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org}
30515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org
30681e7bf8d6d338d944f3c5075b14c21580398aeb6Greg DanielGrPixelConfig SkImageInfo2GrPixelConfig(const SkImageInfo& info, const GrCaps& caps) {
30781e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel    return SkImageInfo2GrPixelConfig(info.colorType(), info.colorSpace(), caps);
30881e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel}
30981e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel
310396fcdba14a0101ed43dcc3863585bf50c4ed6ccbrianosmanbool GrPixelConfigToColorType(GrPixelConfig config, SkColorType* ctOut) {
311bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    SkColorType ct;
312bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    switch (config) {
313ef59d87ae8cd998eede62e7dfd46882cdfcc1817Greg Daniel        case kAlpha_8_GrPixelConfig: // fall through
314ef59d87ae8cd998eede62e7dfd46882cdfcc1817Greg Daniel        case kAlpha_8_as_Alpha_GrPixelConfig: // fall through
315ef59d87ae8cd998eede62e7dfd46882cdfcc1817Greg Daniel        case kAlpha_8_as_Red_GrPixelConfig:
316bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kAlpha_8_SkColorType;
317bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
3187af060a8bcc250af00b0dadaf10d414765dc94f9Greg Daniel        case kGray_8_GrPixelConfig: // fall through
3197af060a8bcc250af00b0dadaf10d414765dc94f9Greg Daniel        case kGray_8_as_Lum_GrPixelConfig: // fall through
3207af060a8bcc250af00b0dadaf10d414765dc94f9Greg Daniel        case kGray_8_as_Red_GrPixelConfig:
321986563bcff26300ea4317b4dd84917d5240bb723Brian Osman            ct = kGray_8_SkColorType;
322986563bcff26300ea4317b4dd84917d5240bb723Brian Osman            break;
323bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kRGB_565_GrPixelConfig:
324bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kRGB_565_SkColorType;
325bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
326bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kRGBA_4444_GrPixelConfig:
327bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kARGB_4444_SkColorType;
328bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
329bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kRGBA_8888_GrPixelConfig:
330bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kRGBA_8888_SkColorType;
331bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
332bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kBGRA_8888_GrPixelConfig:
333bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kBGRA_8888_SkColorType;
334bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
335fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth        case kSRGBA_8888_GrPixelConfig:
336fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth            ct = kRGBA_8888_SkColorType;
337fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth            break;
338a6359365887048ef055196de75591311d7a015f0brianosman        case kSBGRA_8888_GrPixelConfig:
339a6359365887048ef055196de75591311d7a015f0brianosman            ct = kBGRA_8888_SkColorType;
340a6359365887048ef055196de75591311d7a015f0brianosman            break;
3419ac5b91957e59eeddebfae9630204f217c20cd4ebrianosman        case kRGBA_half_GrPixelConfig:
3429ac5b91957e59eeddebfae9630204f217c20cd4ebrianosman            ct = kRGBA_F16_SkColorType;
3439ac5b91957e59eeddebfae9630204f217c20cd4ebrianosman            break;
344bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        default:
345bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            return false;
346bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    }
347bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    if (ctOut) {
348bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        *ctOut = ct;
349bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    }
350bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    return true;
351bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com}
3528dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
35327a3aa5921b2aaf95314f955285c3cba91e4c19abrianosmanGrPixelConfig GrRenderableConfigForColorSpace(const SkColorSpace* colorSpace) {
354f3880933092c3226cd7ffd1690fe72c9c0cc376cMatt Sarett    if (!colorSpace) {
3552695eaa41fbd208dcee9e134e180c6609856f0acbrianosman        return kRGBA_8888_GrPixelConfig;
3562695eaa41fbd208dcee9e134e180c6609856f0acbrianosman    } else if (colorSpace->gammaIsLinear()) {
3572695eaa41fbd208dcee9e134e180c6609856f0acbrianosman        return kRGBA_half_GrPixelConfig;
3582695eaa41fbd208dcee9e134e180c6609856f0acbrianosman    } else if (colorSpace->gammaCloseToSRGB()) {
3592695eaa41fbd208dcee9e134e180c6609856f0acbrianosman        return kSRGBA_8888_GrPixelConfig;
3602695eaa41fbd208dcee9e134e180c6609856f0acbrianosman    } else {
3612695eaa41fbd208dcee9e134e180c6609856f0acbrianosman        SkDEBUGFAIL("No renderable config exists for color space with strange gamma");
3622695eaa41fbd208dcee9e134e180c6609856f0acbrianosman        return kUnknown_GrPixelConfig;
3632695eaa41fbd208dcee9e134e180c6609856f0acbrianosman    }
3642695eaa41fbd208dcee9e134e180c6609856f0acbrianosman}
3652695eaa41fbd208dcee9e134e180c6609856f0acbrianosman
366f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon////////////////////////////////////////////////////////////////////////////////////////////////
3678dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
368185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reedstatic inline bool blend_requires_shader(const SkBlendMode mode) {
369185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reed    return SkBlendMode::kDst != mode;
370aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon}
371aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon
372f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomonstatic inline bool skpaint_to_grpaint_impl(GrContext* context,
373f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                                           const GrColorSpaceInfo& colorSpaceInfo,
374f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                           const SkPaint& skPaint,
375f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                           const SkMatrix& viewM,
376aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon                                           std::unique_ptr<GrFragmentProcessor>* shaderProcessor,
3777d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed                                           SkBlendMode* primColorMode,
378f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                           GrPaint* grPaint) {
379f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon    grPaint->setAllowSRGBInputs(colorSpaceInfo.isGammaCorrect());
3808dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
381c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman    // Convert SkPaint color to 4f format, including optional linearizing and gamut conversion.
3824cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon    GrColor4f origColor = SkColorToUnpremulGrColor4f(skPaint.getColor(), colorSpaceInfo);
383a4535a34d1b317543307df6901debfefe7132569brianosman
3843bc266b33ad85299af06469a32ad9f6339424485Mike Reed    const GrFPArgs fpArgs(context, &viewM, skPaint.getFilterQuality(), &colorSpaceInfo);
385bfadcf0224cb22e2aec10592fa197ba7ab19b479Mike Reed
386f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    // Setup the initial color considering the shader, the SkPaint color, and the presence or not
387f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    // of per-vertex colors.
388aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon    std::unique_ptr<GrFragmentProcessor> shaderFP;
389185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reed    if (!primColorMode || blend_requires_shader(*primColorMode)) {
390aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon        if (shaderProcessor) {
391aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon            shaderFP = std::move(*shaderProcessor);
3924aed13889bd9085337e0d4c20df28686687b833bFlorin Malita        } else if (const auto* shader = as_SB(skPaint.getShader())) {
393bfadcf0224cb22e2aec10592fa197ba7ab19b479Mike Reed            shaderFP = shader->asFragmentProcessor(fpArgs);
394f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        }
3958dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    }
396775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein
397f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    // Set this in below cases if the output of the shader/paint-color/paint-alpha/primXfermode is
398f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    // a known constant value. In that case we can simply apply a color filter during this
399f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    // conversion without converting the color filter to a GrFragmentProcessor.
400f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    bool applyColorFilterToPaintColor = false;
401f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    if (shaderFP) {
402f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        if (primColorMode) {
403f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // There is a blend between the primitive color and the shader color. The shader sees
404f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // the opaque paint color. The shader's output is blended using the provided mode by
405f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // the primitive color. The blended color is then modulated by the paint's alpha.
406f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
407f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // The geometry processor will insert the primitive color to start the color chain, so
408f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // the GrPaint color will be ignored.
409f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
4104cea3b9e9d9836c926a8feb55d050993d40b4b5ebrianosman            GrColor4f shaderInput = origColor.opaque();
411aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon            shaderFP = GrFragmentProcessor::OverrideInput(std::move(shaderFP), shaderInput);
412185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reed            shaderFP = GrXfermodeFragmentProcessor::MakeFromSrcProcessor(std::move(shaderFP),
413185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reed                                                                         *primColorMode);
414185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reed
415f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // The above may return null if compose results in a pass through of the prim color.
416f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            if (shaderFP) {
4171c9686bfa5e2de3e06f1d1b9691105afb6659e85Robert Phillips                grPaint->addColorFragmentProcessor(std::move(shaderFP));
418f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            }
419f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
420a4535a34d1b317543307df6901debfefe7132569brianosman            // We can ignore origColor here - alpha is unchanged by gamma
421f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor());
422f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            if (GrColor_WHITE != paintAlpha) {
423618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman                // No gamut conversion - paintAlpha is a (linear) alpha value, splatted to all
424618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman                // color channels. It's value should be treated as the same in ANY color space.
42506ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                grPaint->addColorFragmentProcessor(GrConstColorProcessor::Make(
426618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman                    GrColor4f::FromGrColor(paintAlpha),
427e9d172af84fff5d76e19180a0c2b7b3cc51e90a2Ethan Nicholas                    GrConstColorProcessor::InputMode::kModulateRGBA));
428f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            }
429f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        } else {
430f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // The shader's FP sees the paint unpremul color
431a4535a34d1b317543307df6901debfefe7132569brianosman            grPaint->setColor4f(origColor);
43206ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman            grPaint->addColorFragmentProcessor(std::move(shaderFP));
433f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        }
434f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    } else {
435f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        if (primColorMode) {
436f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // There is a blend between the primitive color and the paint color. The blend considers
437f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // the opaque paint color. The paint's alpha is applied to the post-blended color.
438aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon            auto processor = GrConstColorProcessor::Make(origColor.opaque(),
439e9d172af84fff5d76e19180a0c2b7b3cc51e90a2Ethan Nicholas                                                         GrConstColorProcessor::InputMode::kIgnore);
440185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reed            processor = GrXfermodeFragmentProcessor::MakeFromSrcProcessor(std::move(processor),
441185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reed                                                                          *primColorMode);
442f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            if (processor) {
44306ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                grPaint->addColorFragmentProcessor(std::move(processor));
444f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            }
445f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
446a4535a34d1b317543307df6901debfefe7132569brianosman            grPaint->setColor4f(origColor.opaque());
447f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
448a4535a34d1b317543307df6901debfefe7132569brianosman            // We can ignore origColor here - alpha is unchanged by gamma
449f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor());
450aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon            if (GrColor_WHITE != paintAlpha) {
451618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman                // No gamut conversion - paintAlpha is a (linear) alpha value, splatted to all
452618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman                // color channels. It's value should be treated as the same in ANY color space.
45306ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                grPaint->addColorFragmentProcessor(GrConstColorProcessor::Make(
454618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman                    GrColor4f::FromGrColor(paintAlpha),
455e9d172af84fff5d76e19180a0c2b7b3cc51e90a2Ethan Nicholas                    GrConstColorProcessor::InputMode::kModulateRGBA));
456aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon            }
457f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        } else {
458f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // No shader, no primitive color.
459a4535a34d1b317543307df6901debfefe7132569brianosman            grPaint->setColor4f(origColor.premul());
460f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            applyColorFilterToPaintColor = true;
461f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        }
462f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    }
4638dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
4648dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    SkColorFilter* colorFilter = skPaint.getColorFilter();
46549f085dddff10473b6ebf832a974288300224e60bsalomon    if (colorFilter) {
466f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        if (applyColorFilterToPaintColor) {
4678bf4e672f2c40ef313274f8b79c2c9304f9fff3fBrian Osman            // If we're in legacy mode, we *must* avoid using the 4f version of the color filter,
4688bf4e672f2c40ef313274f8b79c2c9304f9fff3fBrian Osman            // because that will combine with the linearized version of the stored color.
469f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon            if (colorSpaceInfo.isGammaCorrect()) {
4708bf4e672f2c40ef313274f8b79c2c9304f9fff3fBrian Osman                grPaint->setColor4f(GrColor4f::FromSkColor4f(
4718bf4e672f2c40ef313274f8b79c2c9304f9fff3fBrian Osman                    colorFilter->filterColor4f(origColor.toSkColor4f())).premul());
4728bf4e672f2c40ef313274f8b79c2c9304f9fff3fBrian Osman            } else {
4734cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon                grPaint->setColor4f(SkColorToPremulGrColor4fLegacy(
4744cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon                        colorFilter->filterColor(skPaint.getColor())));
4758bf4e672f2c40ef313274f8b79c2c9304f9fff3fBrian Osman            }
4768dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org        } else {
4774cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon            auto cfFP = colorFilter->asFragmentProcessor(context, colorSpaceInfo);
478e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon            if (cfFP) {
47906ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                grPaint->addColorFragmentProcessor(std::move(cfFP));
480f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            } else {
481f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                return false;
4828dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org            }
4838dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org        }
4848dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    }
485f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
48680747ef591ff3c09c2b610eb21258132d1ff4ef5Mike Reed    SkMaskFilterBase* maskFilter = as_MFB(skPaint.getMaskFilter());
487a29a956d0e27819b97592404ae1ec6cc8e7b1045Robert Phillips    if (maskFilter) {
488bfadcf0224cb22e2aec10592fa197ba7ab19b479Mike Reed        if (auto mfFP = maskFilter->asFragmentProcessor(fpArgs)) {
489bfadcf0224cb22e2aec10592fa197ba7ab19b479Mike Reed            grPaint->addCoverageFragmentProcessor(std::move(mfFP));
490a29a956d0e27819b97592404ae1ec6cc8e7b1045Robert Phillips        }
491a29a956d0e27819b97592404ae1ec6cc8e7b1045Robert Phillips    }
492a29a956d0e27819b97592404ae1ec6cc8e7b1045Robert Phillips
4934f0379444db31421894d2fce7c85889fe5eaa01arobertphillips    // When the xfermode is null on the SkPaint (meaning kSrcOver) we need the XPFactory field on
4944f0379444db31421894d2fce7c85889fe5eaa01arobertphillips    // the GrPaint to also be null (also kSrcOver).
4954f0379444db31421894d2fce7c85889fe5eaa01arobertphillips    SkASSERT(!grPaint->getXPFactory());
496374772bd61951f01bf84fe17bf53d8867681c9aereed    if (!skPaint.isSrcOver()) {
497374772bd61951f01bf84fe17bf53d8867681c9aereed        grPaint->setXPFactory(SkBlendMode_AsXPFactory(skPaint.getBlendMode()));
4984f0379444db31421894d2fce7c85889fe5eaa01arobertphillips    }
499f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
500f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#ifndef SK_IGNORE_GPU_DITHER
501d4a70ee36717493cc071f878b16b037463e6ce9aFlorin Malita    // Conservative default, in case GrPixelConfigToColorType() fails.
502d4a70ee36717493cc071f878b16b037463e6ce9aFlorin Malita    SkColorType ct = SkColorType::kRGB_565_SkColorType;
503f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon    GrPixelConfigToColorType(colorSpaceInfo.config(), &ct);
504f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon    if (SkPaintPriv::ShouldDither(skPaint, ct) && grPaint->numColorFragmentProcessors() > 0 &&
505f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon        !colorSpaceInfo.isGammaCorrect()) {
506f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon        auto ditherFP = GrDitherEffect::Make(colorSpaceInfo.config());
5070c15ae82f0d5b5356f7650b78d749c09b3bc0403Brian Salomon        if (ditherFP) {
5080c15ae82f0d5b5356f7650b78d749c09b3bc0403Brian Salomon            grPaint->addColorFragmentProcessor(std::move(ditherFP));
5090c15ae82f0d5b5356f7650b78d749c09b3bc0403Brian Salomon        }
510f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    }
511f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#endif
512bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    return true;
5138dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org}
5148dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
515f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomonbool SkPaintToGrPaint(GrContext* context, const GrColorSpaceInfo& colorSpaceInfo,
516f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                      const SkPaint& skPaint, const SkMatrix& viewM, GrPaint* grPaint) {
517f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon    return skpaint_to_grpaint_impl(context, colorSpaceInfo, skPaint, viewM, nullptr, nullptr,
518f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                                   grPaint);
519f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon}
520f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
521f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon/** Replaces the SkShader (if any) on skPaint with the passed in GrFragmentProcessor. */
522f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomonbool SkPaintToGrPaintReplaceShader(GrContext* context,
523f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                                   const GrColorSpaceInfo& colorSpaceInfo,
524f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                   const SkPaint& skPaint,
525aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon                                   std::unique_ptr<GrFragmentProcessor> shaderFP,
526f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                   GrPaint* grPaint) {
527f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    if (!shaderFP) {
528c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon        return false;
5298dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    }
530f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon    return skpaint_to_grpaint_impl(context, colorSpaceInfo, skPaint, SkMatrix::I(), &shaderFP,
531f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                                   nullptr, grPaint);
532f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon}
533f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
534f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon/** Ignores the SkShader (if any) on skPaint. */
535f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomonbool SkPaintToGrPaintNoShader(GrContext* context,
536f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                              const GrColorSpaceInfo& colorSpaceInfo,
537f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                              const SkPaint& skPaint,
538f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                              GrPaint* grPaint) {
539f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    // Use a ptr to a nullptr to to indicate that the SkShader is ignored and not replaced.
540aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon    static std::unique_ptr<GrFragmentProcessor> kNullShaderFP(nullptr);
541aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon    static std::unique_ptr<GrFragmentProcessor>* kIgnoreShader = &kNullShaderFP;
542f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon    return skpaint_to_grpaint_impl(context, colorSpaceInfo, skPaint, SkMatrix::I(), kIgnoreShader,
543f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                                   nullptr, grPaint);
544f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon}
545f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
546f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon/** Blends the SkPaint's shader (or color if no shader) with a per-primitive color which must
5477d954ad797176afedb9262fdea4507d0fc60eb9dMike Reedbe setup as a vertex attribute using the specified SkBlendMode. */
548f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomonbool SkPaintToGrPaintWithXfermode(GrContext* context,
549f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                                  const GrColorSpaceInfo& colorSpaceInfo,
550f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                  const SkPaint& skPaint,
551f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                  const SkMatrix& viewM,
5527d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed                                  SkBlendMode primColorMode,
553f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                  GrPaint* grPaint) {
554f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon    return skpaint_to_grpaint_impl(context, colorSpaceInfo, skPaint, viewM, nullptr, &primColorMode,
555185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reed                                   grPaint);
5568dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org}
5578b26b99c97473f020df4b9d4ba789e074e06ceddreed
55833a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualittbool SkPaintToGrPaintWithTexture(GrContext* context,
559f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                                 const GrColorSpaceInfo& colorSpaceInfo,
56033a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                                 const SkPaint& paint,
56133a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                                 const SkMatrix& viewM,
562aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon                                 std::unique_ptr<GrFragmentProcessor> fp,
56333a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                                 bool textureIsAlphaOnly,
56433a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                                 GrPaint* grPaint) {
565aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon    std::unique_ptr<GrFragmentProcessor> shaderFP;
56633a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt    if (textureIsAlphaOnly) {
5674aed13889bd9085337e0d4c20df28686687b833bFlorin Malita        if (const auto* shader = as_SB(paint.getShader())) {
568e3429e62b0d020b27de3daa55893953eff581c4fMike Reed            shaderFP = shader->asFragmentProcessor(GrFPArgs(
5694cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon                    context, &viewM, nullptr, paint.getFilterQuality(), &colorSpaceInfo));
57033a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt            if (!shaderFP) {
57133a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                return false;
57233a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt            }
573aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon            std::unique_ptr<GrFragmentProcessor> fpSeries[] = { std::move(shaderFP), std::move(fp) };
57406ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman            shaderFP = GrFragmentProcessor::RunInSeries(fpSeries, 2);
57533a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt        } else {
576aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon            shaderFP = GrFragmentProcessor::MakeInputPremulAndMulByOutput(std::move(fp));
57733a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt        }
57833a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt    } else {
579aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon        shaderFP = GrFragmentProcessor::MulOutputByInputAlpha(std::move(fp));
58033a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt    }
58133a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt
582f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon    return SkPaintToGrPaintReplaceShader(context, colorSpaceInfo, paint, std::move(shaderFP),
583f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                                         grPaint);
58433a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt}
58533a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt
586f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
587f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon////////////////////////////////////////////////////////////////////////////////////////////////
588f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
5892bbdcc44c63974f29f3743bb58d929601a3f65c6Brian SalomonGrSamplerState::Filter GrSkFilterQualityToGrFilterMode(SkFilterQuality paintFilterQuality,
5902bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon                                                       const SkMatrix& viewM,
5912bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon                                                       const SkMatrix& localM,
5922bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon                                                       bool* doBicubic) {
5939bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt    *doBicubic = false;
5942bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon    GrSamplerState::Filter textureFilterMode;
5959bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt    switch (paintFilterQuality) {
5969bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        case kNone_SkFilterQuality:
5972bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon            textureFilterMode = GrSamplerState::Filter::kNearest;
5989bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            break;
5999bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        case kLow_SkFilterQuality:
6002bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon            textureFilterMode = GrSamplerState::Filter::kBilerp;
6019bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            break;
6029bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        case kMedium_SkFilterQuality: {
6039bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            SkMatrix matrix;
6049bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            matrix.setConcat(viewM, localM);
6059bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            if (matrix.getMinScale() < SK_Scalar1) {
6062bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon                textureFilterMode = GrSamplerState::Filter::kMipMap;
6079bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            } else {
6089bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt                // Don't trigger MIP level generation unnecessarily.
6092bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon                textureFilterMode = GrSamplerState::Filter::kBilerp;
6109bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            }
6119bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            break;
6129bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        }
6139bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        case kHigh_SkFilterQuality: {
6149bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            SkMatrix matrix;
6159bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            matrix.setConcat(viewM, localM);
6169bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            *doBicubic = GrBicubicEffect::ShouldUseBicubic(matrix, &textureFilterMode);
6179bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            break;
6189bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        }
6199bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        default:
620e54c75f351c775201049743c506d7a508d0fef91Mike Klein            // Should be unreachable.  If not, fall back to mipmaps.
6212bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon            textureFilterMode = GrSamplerState::Filter::kMipMap;
6229bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            break;
6239bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt
6249bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt    }
6259bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt    return textureFilterMode;
6269bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt}
627