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"
267a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips#include "SkImage_Base.h"
274075ec80e1c36e414e57746c772298be3b49a74eBrian Osman#include "SkImageInfoPriv.h"
287e1912a8ab48134eb3a631f188ad8aa262e8eaa0Greg Daniel#include "SkImagePriv.h"
2980747ef591ff3c09c2b610eb21258132d1ff4ef5Mike Reed#include "SkMaskFilterBase.h"
3050a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org#include "SkMessageBus.h"
3155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume#include "SkMipMap.h"
32c456b73fef9589bbdc5eb83eaa83e53c357bb3daKevin Lubick#include "SkPM4fPriv.h"
33d4a70ee36717493cc071f878b16b037463e6ce9aFlorin Malita#include "SkPaintPriv.h"
3495e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary#include "SkPixelRef.h"
35692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi#include "SkResourceCache.h"
364aed13889bd9085337e0d4c20df28686687b833bFlorin Malita#include "SkShaderBase.h"
3755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume#include "SkTemplates.h"
38559f534759f616f1d9a173e0045acead5ee4cae1Derek Sollenberger#include "SkTraceEvent.h"
399bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt#include "effects/GrBicubicEffect.h"
40f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon#include "effects/GrConstColorProcessor.h"
41f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#include "effects/GrDitherEffect.h"
42378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel#include "effects/GrPorterDuffXferProcessor.h"
43f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon#include "effects/GrXfermodeFragmentProcessor.h"
449c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
45a6359365887048ef055196de75591311d7a015f0brianosmanGrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo& info, const GrCaps& caps) {
46466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    GrSurfaceDesc desc;
47466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    desc.fFlags = kNone_GrSurfaceFlags;
48019ff27ac0167026f9f8f4aaec8fb6461d8ba21eRobert Phillips    desc.fOrigin = kTopLeft_GrSurfaceOrigin;
49466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    desc.fWidth = info.width();
50466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    desc.fHeight = info.height();
51a6359365887048ef055196de75591311d7a015f0brianosman    desc.fConfig = SkImageInfo2GrPixelConfig(info, caps);
52bdecacfbe47bc7211336bb847bb33c00ef85ea3eBrian Salomon    desc.fSampleCnt = 1;
53466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    return desc;
54466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon}
55466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon
56045802dbb7202b52f5fd2758d725f39c156a6165bsalomonvoid GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID, const SkIRect& imageBounds) {
57045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    SkASSERT(key);
58045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    SkASSERT(imageID);
59045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    SkASSERT(!imageBounds.isEmpty());
60045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    static const GrUniqueKey::Domain kImageIDDomain = GrUniqueKey::GenerateDomain();
6167914ebddfc81b5f564dfa119eca3c8bad33db74Derek Sollenberger    GrUniqueKey::Builder builder(key, kImageIDDomain, 5, "Image");
62466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    builder[0] = imageID;
63045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    builder[1] = imageBounds.fLeft;
64045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    builder[2] = imageBounds.fTop;
65045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    builder[3] = imageBounds.fRight;
66045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    builder[4] = imageBounds.fBottom;
67466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon}
68466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon
69045802dbb7202b52f5fd2758d725f39c156a6165bsalomon//////////////////////////////////////////////////////////////////////////////
701afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillipssk_sp<GrTextureProxy> GrUploadBitmapToTextureProxy(GrProxyProvider* proxyProvider,
71dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett                                                   const SkBitmap& bitmap,
72dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett                                                   SkColorSpace* dstColorSpace) {
737619b646881c9a346a3c760d2ab9ab2f3fca0390Greg Daniel    if (!bitmap.peekPixels(nullptr)) {
74d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips        return nullptr;
75d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips    }
767619b646881c9a346a3c760d2ab9ab2f3fca0390Greg Daniel
777619b646881c9a346a3c760d2ab9ab2f3fca0390Greg Daniel    SkDestinationSurfaceColorMode colorMode = dstColorSpace
787619b646881c9a346a3c760d2ab9ab2f3fca0390Greg Daniel        ? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware
797619b646881c9a346a3c760d2ab9ab2f3fca0390Greg Daniel        : SkDestinationSurfaceColorMode::kLegacy;
807619b646881c9a346a3c760d2ab9ab2f3fca0390Greg Daniel
817619b646881c9a346a3c760d2ab9ab2f3fca0390Greg Daniel    if (!SkImageInfoIsValid(bitmap.info(), colorMode)) {
824075ec80e1c36e414e57746c772298be3b49a74eBrian Osman        return nullptr;
834075ec80e1c36e414e57746c772298be3b49a74eBrian Osman    }
847619b646881c9a346a3c760d2ab9ab2f3fca0390Greg Daniel
857619b646881c9a346a3c760d2ab9ab2f3fca0390Greg Daniel    // In non-ddl we will always instantiate right away. Thus we never want to copy the SkBitmap
867619b646881c9a346a3c760d2ab9ab2f3fca0390Greg Daniel    // even if it's mutable. In ddl, if the bitmap is mutable then we must make a copy since the
877619b646881c9a346a3c760d2ab9ab2f3fca0390Greg Daniel    // upload of the data to the gpu can happen at anytime and the bitmap may change by then.
887619b646881c9a346a3c760d2ab9ab2f3fca0390Greg Daniel    SkCopyPixelsMode cpyMode = proxyProvider->mutableBitmapsNeedCopy() ? kIfMutable_SkCopyPixelsMode
897619b646881c9a346a3c760d2ab9ab2f3fca0390Greg Daniel                                                                       : kNever_SkCopyPixelsMode;
907619b646881c9a346a3c760d2ab9ab2f3fca0390Greg Daniel    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, cpyMode);
917619b646881c9a346a3c760d2ab9ab2f3fca0390Greg Daniel
927619b646881c9a346a3c760d2ab9ab2f3fca0390Greg Daniel    return proxyProvider->createTextureProxy(std::move(image), kNone_GrSurfaceFlags,
937619b646881c9a346a3c760d2ab9ab2f3fca0390Greg Daniel                                             kTopLeft_GrSurfaceOrigin, 1, SkBudgeted::kYes,
947619b646881c9a346a3c760d2ab9ab2f3fca0390Greg Daniel                                             SkBackingFit::kExact);
95d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips}
964075ec80e1c36e414e57746c772298be3b49a74eBrian Osman
97045802dbb7202b52f5fd2758d725f39c156a6165bsalomon////////////////////////////////////////////////////////////////////////////////
98045802dbb7202b52f5fd2758d725f39c156a6165bsalomon
99c55271f2551533b37043aa2e37f754832a43073cbsalomonvoid GrInstallBitmapUniqueKeyInvalidator(const GrUniqueKey& key, SkPixelRef* pixelRef) {
10089fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon    class Invalidator : public SkPixelRef::GenIDChangeListener {
10189fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon    public:
10289fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon        explicit Invalidator(const GrUniqueKey& key) : fMsg(key) {}
10389fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon    private:
10489fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon        GrUniqueKeyInvalidatedMessage fMsg;
10589fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon
10689fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon        void onChange() override { SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(fMsg); }
10789fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon    };
10889fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon
10989fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon    pixelRef->addGenIDChangeListener(new Invalidator(key));
11089fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon}
11189fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon
1120bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillipssk_sp<GrTextureProxy> GrCopyBaseMipMapToTextureProxy(GrContext* ctx, GrTextureProxy* baseProxy) {
11355afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    SkASSERT(baseProxy);
11455afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel
115bb76ace72bee5d44189b6ee6c81cda174ce9ea30Greg Daniel    if (!ctx->caps()->isConfigCopyable(baseProxy->config())) {
116bb76ace72bee5d44189b6ee6c81cda174ce9ea30Greg Daniel        return nullptr;
117bb76ace72bee5d44189b6ee6c81cda174ce9ea30Greg Daniel    }
118bb76ace72bee5d44189b6ee6c81cda174ce9ea30Greg Daniel
1190bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips    GrProxyProvider* proxyProvider = ctx->contextPriv().proxyProvider();
12055afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    GrSurfaceDesc desc;
12155afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    desc.fFlags = kNone_GrSurfaceFlags;
12255afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    desc.fOrigin = baseProxy->origin();
12355afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    desc.fWidth = baseProxy->width();
12455afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    desc.fHeight = baseProxy->height();
12555afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    desc.fConfig = baseProxy->config();
126bdecacfbe47bc7211336bb847bb33c00ef85ea3eBrian Salomon    desc.fSampleCnt = 1;
12755afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel
1280bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips    sk_sp<GrTextureProxy> proxy = proxyProvider->createMipMapProxy(desc, SkBudgeted::kYes);
12955afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    if (!proxy) {
13055afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel        return nullptr;
13155afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    }
13255afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel
13355afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    // Copy the base layer to our proxy
134366093f2124c38fa5c590c9ed2d1811817fed8eeBrian Salomon    sk_sp<SkColorSpace> colorSpace;
135366093f2124c38fa5c590c9ed2d1811817fed8eeBrian Salomon    if (GrPixelConfigIsSRGB(proxy->config())) {
136366093f2124c38fa5c590c9ed2d1811817fed8eeBrian Salomon        colorSpace = SkColorSpace::MakeSRGB();
137366093f2124c38fa5c590c9ed2d1811817fed8eeBrian Salomon    }
138366093f2124c38fa5c590c9ed2d1811817fed8eeBrian Salomon    sk_sp<GrSurfaceContext> sContext =
139366093f2124c38fa5c590c9ed2d1811817fed8eeBrian Salomon            ctx->contextPriv().makeWrappedSurfaceContext(proxy, std::move(colorSpace));
14055afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    SkASSERT(sContext);
14155afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    SkAssertResult(sContext->copy(baseProxy));
14255afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel
14355afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    return proxy;
14455afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel}
14555afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel
146bbd7a3be407ce94fcc4f8b1eb475de8b6f49026eRobert Phillipssk_sp<GrTextureProxy> GrRefCachedBitmapTextureProxy(GrContext* ctx,
147bbd7a3be407ce94fcc4f8b1eb475de8b6f49026eRobert Phillips                                                    const SkBitmap& bitmap,
1482bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon                                                    const GrSamplerState& params,
149bbd7a3be407ce94fcc4f8b1eb475de8b6f49026eRobert Phillips                                                    SkScalar scaleAdjust[2]) {
150bbd7a3be407ce94fcc4f8b1eb475de8b6f49026eRobert Phillips    // Caller doesn't care about the texture's color space (they can always get it from the bitmap)
1513798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips    return GrBitmapTextureMaker(ctx, bitmap).refTextureProxyForParams(params, nullptr,
1523798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips                                                                      nullptr, scaleAdjust);
153bbd7a3be407ce94fcc4f8b1eb475de8b6f49026eRobert Phillips}
154bbd7a3be407ce94fcc4f8b1eb475de8b6f49026eRobert Phillips
1551afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillipssk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrProxyProvider* proxyProvider,
1567e1912a8ab48134eb3a631f188ad8aa262e8eaa0Greg Daniel                                              const SkBitmap& bitmap,
1577e1912a8ab48134eb3a631f188ad8aa262e8eaa0Greg Daniel                                              SkBackingFit fit) {
1587e1912a8ab48134eb3a631f188ad8aa262e8eaa0Greg Daniel    if (!bitmap.peekPixels(nullptr)) {
1597e1912a8ab48134eb3a631f188ad8aa262e8eaa0Greg Daniel        return nullptr;
160e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips    }
161e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips
1627e1912a8ab48134eb3a631f188ad8aa262e8eaa0Greg Daniel    // In non-ddl we will always instantiate right away. Thus we never want to copy the SkBitmap
1637e1912a8ab48134eb3a631f188ad8aa262e8eaa0Greg Daniel    // even if its mutable. In ddl, if the bitmap is mutable then we must make a copy since the
1647e1912a8ab48134eb3a631f188ad8aa262e8eaa0Greg Daniel    // upload of the data to the gpu can happen at anytime and the bitmap may change by then.
1657e1912a8ab48134eb3a631f188ad8aa262e8eaa0Greg Daniel    SkCopyPixelsMode cpyMode = proxyProvider->mutableBitmapsNeedCopy() ? kIfMutable_SkCopyPixelsMode
1667e1912a8ab48134eb3a631f188ad8aa262e8eaa0Greg Daniel                                                                       : kNever_SkCopyPixelsMode;
1677e1912a8ab48134eb3a631f188ad8aa262e8eaa0Greg Daniel    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, cpyMode);
168e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips
1697e1912a8ab48134eb3a631f188ad8aa262e8eaa0Greg Daniel    if (!image) {
1707e1912a8ab48134eb3a631f188ad8aa262e8eaa0Greg Daniel        return nullptr;
171e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips    }
172e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips
1737e1912a8ab48134eb3a631f188ad8aa262e8eaa0Greg Daniel    return GrMakeCachedImageProxy(proxyProvider, std::move(image), fit);
174e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips}
175e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips
1767a9263906c677c0fa5636521e3cc58ba60837720Robert Phillipsstatic void create_unique_key_for_image(const SkImage* image, GrUniqueKey* result) {
1777a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips    if (!image) {
1787a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips        result->reset(); // will be invalid
1797a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips        return;
1807a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips    }
1817a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips
1827a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips    if (const SkBitmap* bm = as_IB(image)->onPeekBitmap()) {
1837a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips        SkIPoint origin = bm->pixelRefOrigin();
1847a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips        SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, bm->width(), bm->height());
1857a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips        GrMakeKeyFromImageID(result, bm->getGenerationID(), subset);
1867a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips        return;
1877a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips    }
1887a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips
1897a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips    GrMakeKeyFromImageID(result, image->uniqueID(), image->bounds());
1907a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips}
1917a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips
1927a9263906c677c0fa5636521e3cc58ba60837720Robert Phillipssk_sp<GrTextureProxy> GrMakeCachedImageProxy(GrProxyProvider* proxyProvider,
193490695babbe0748ff33c9d23cf9b9f038db59afaGreg Daniel                                             sk_sp<SkImage> srcImage,
194490695babbe0748ff33c9d23cf9b9f038db59afaGreg Daniel                                             SkBackingFit fit) {
1957a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips    sk_sp<GrTextureProxy> proxy;
1967a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips    GrUniqueKey originalKey;
1977a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips
1987a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips    create_unique_key_for_image(srcImage.get(), &originalKey);
1997a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips
2007a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips    if (originalKey.isValid()) {
2017a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips        proxy = proxyProvider->findOrCreateProxyByUniqueKey(originalKey, kTopLeft_GrSurfaceOrigin);
2027a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips    }
2037a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips    if (!proxy) {
2047a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips        proxy = proxyProvider->createTextureProxy(std::move(srcImage), kNone_GrSurfaceFlags,
205bdecacfbe47bc7211336bb847bb33c00ef85ea3eBrian Salomon                                                  kTopLeft_GrSurfaceOrigin, 1, SkBudgeted::kYes,
206490695babbe0748ff33c9d23cf9b9f038db59afaGreg Daniel                                                  fit);
2077a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips        if (proxy && originalKey.isValid()) {
2087a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips            proxyProvider->assignUniqueKeyToProxy(originalKey, proxy.get());
2097a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips        }
2107a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips    }
2117a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips
2127a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips    return proxy;
2137a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips}
2147a9263906c677c0fa5636521e3cc58ba60837720Robert Phillips
21524f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com///////////////////////////////////////////////////////////////////////////////
21624f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com
2174cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian SalomonGrColor4f SkColorToPremulGrColor4f(SkColor c, const GrColorSpaceInfo& colorSpaceInfo) {
21872ae431e4032985999dc0990bfbbf4acf127a74eBrian Osman    // We want to premultiply after linearizing, so this is easy:
2194cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon    return SkColorToUnpremulGrColor4f(c, colorSpaceInfo).premul();
22072ae431e4032985999dc0990bfbbf4acf127a74eBrian Osman}
22172ae431e4032985999dc0990bfbbf4acf127a74eBrian Osman
2224cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian SalomonGrColor4f SkColorToPremulGrColor4fLegacy(SkColor c) {
2234cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon    return GrColor4f::FromGrColor(SkColorToUnpremulGrColor(c)).premul();
22472ae431e4032985999dc0990bfbbf4acf127a74eBrian Osman}
22572ae431e4032985999dc0990bfbbf4acf127a74eBrian Osman
2264cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian SalomonGrColor4f SkColorToUnpremulGrColor4f(SkColor c, const GrColorSpaceInfo& colorSpaceInfo) {
227c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman    GrColor4f color;
2284cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon    if (colorSpaceInfo.colorSpace()) {
229c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman        // SkColor4f::FromColor does sRGB -> Linear
230c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman        color = GrColor4f::FromSkColor4f(SkColor4f::FromColor(c));
231c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman    } else {
232c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman        // GrColor4f::FromGrColor just multiplies by 1/255
233c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman        color = GrColor4f::FromGrColor(SkColorToUnpremulGrColor(c));
234c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman    }
235c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman
2364cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon    if (auto* xform = colorSpaceInfo.colorSpaceXformFromSRGB()) {
2374cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon        color = xform->clampedXform(color);
238c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman    }
239c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman
240c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman    return color;
241c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman}
242c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman
243c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman///////////////////////////////////////////////////////////////////////////////
244c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman
24581e7bf8d6d338d944f3c5075b14c21580398aeb6Greg DanielGrPixelConfig SkImageInfo2GrPixelConfig(const SkColorType type, SkColorSpace* cs,
24681e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel                                        const GrCaps& caps) {
24781e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel    switch (type) {
248c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman        case kUnknown_SkColorType:
249c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman            return kUnknown_GrPixelConfig;
250c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman        case kAlpha_8_SkColorType:
251c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman            return kAlpha_8_GrPixelConfig;
252c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman        case kRGB_565_SkColorType:
253c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman            return kRGB_565_GrPixelConfig;
254c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman        case kARGB_4444_SkColorType:
255c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman            return kRGBA_4444_GrPixelConfig;
256c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman        case kRGBA_8888_SkColorType:
257f3880933092c3226cd7ffd1690fe72c9c0cc376cMatt Sarett            return (caps.srgbSupport() && cs && cs->gammaCloseToSRGB())
258a6359365887048ef055196de75591311d7a015f0brianosman                   ? kSRGBA_8888_GrPixelConfig : kRGBA_8888_GrPixelConfig;
2599d44081e00f67361414935b82332df5754bddcafBrian Osman        // TODO: We're checking for srgbSupport, but we can then end up picking sBGRA as our pixel
2609d44081e00f67361414935b82332df5754bddcafBrian Osman        // config (which may not be supported). We need a better test here.
261e41e1769e76dcce573038d04d90d62043ece7e4fBrian Salomon        case kRGB_888x_SkColorType:
262e41e1769e76dcce573038d04d90d62043ece7e4fBrian Salomon            return kUnknown_GrPixelConfig;
263c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman        case kBGRA_8888_SkColorType:
264f3880933092c3226cd7ffd1690fe72c9c0cc376cMatt Sarett            return (caps.srgbSupport() && cs && cs->gammaCloseToSRGB())
265a6359365887048ef055196de75591311d7a015f0brianosman                   ? kSBGRA_8888_GrPixelConfig : kBGRA_8888_GrPixelConfig;
266e41e1769e76dcce573038d04d90d62043ece7e4fBrian Salomon        case kRGBA_1010102_SkColorType:
26710fc6fddf24878f4f34e75c1bcc11e4499edfcc0Brian Osman            return kRGBA_1010102_GrPixelConfig;
268e41e1769e76dcce573038d04d90d62043ece7e4fBrian Salomon        case kRGB_101010x_SkColorType:
269e41e1769e76dcce573038d04d90d62043ece7e4fBrian Salomon            return kUnknown_GrPixelConfig;
270c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman        case kGray_8_SkColorType:
271986563bcff26300ea4317b4dd84917d5240bb723Brian Osman            return kGray_8_GrPixelConfig;
272c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman        case kRGBA_F16_SkColorType:
273c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman            return kRGBA_half_GrPixelConfig;
27415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    }
27515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    SkASSERT(0);    // shouldn't get here
27615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    return kUnknown_GrPixelConfig;
27715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org}
27815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org
27981e7bf8d6d338d944f3c5075b14c21580398aeb6Greg DanielGrPixelConfig SkImageInfo2GrPixelConfig(const SkImageInfo& info, const GrCaps& caps) {
28081e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel    return SkImageInfo2GrPixelConfig(info.colorType(), info.colorSpace(), caps);
28181e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel}
28281e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel
283396fcdba14a0101ed43dcc3863585bf50c4ed6ccbrianosmanbool GrPixelConfigToColorType(GrPixelConfig config, SkColorType* ctOut) {
284bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    SkColorType ct;
285bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    switch (config) {
286ef59d87ae8cd998eede62e7dfd46882cdfcc1817Greg Daniel        case kAlpha_8_GrPixelConfig: // fall through
287ef59d87ae8cd998eede62e7dfd46882cdfcc1817Greg Daniel        case kAlpha_8_as_Alpha_GrPixelConfig: // fall through
288ef59d87ae8cd998eede62e7dfd46882cdfcc1817Greg Daniel        case kAlpha_8_as_Red_GrPixelConfig:
289bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kAlpha_8_SkColorType;
290bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
2917af060a8bcc250af00b0dadaf10d414765dc94f9Greg Daniel        case kGray_8_GrPixelConfig: // fall through
2927af060a8bcc250af00b0dadaf10d414765dc94f9Greg Daniel        case kGray_8_as_Lum_GrPixelConfig: // fall through
2937af060a8bcc250af00b0dadaf10d414765dc94f9Greg Daniel        case kGray_8_as_Red_GrPixelConfig:
294986563bcff26300ea4317b4dd84917d5240bb723Brian Osman            ct = kGray_8_SkColorType;
295986563bcff26300ea4317b4dd84917d5240bb723Brian Osman            break;
296bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kRGB_565_GrPixelConfig:
297bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kRGB_565_SkColorType;
298bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
299bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kRGBA_4444_GrPixelConfig:
300bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kARGB_4444_SkColorType;
301bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
302bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kRGBA_8888_GrPixelConfig:
303bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kRGBA_8888_SkColorType;
304bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
305bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kBGRA_8888_GrPixelConfig:
306bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kBGRA_8888_SkColorType;
307bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
308fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth        case kSRGBA_8888_GrPixelConfig:
309fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth            ct = kRGBA_8888_SkColorType;
310fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth            break;
311a6359365887048ef055196de75591311d7a015f0brianosman        case kSBGRA_8888_GrPixelConfig:
312a6359365887048ef055196de75591311d7a015f0brianosman            ct = kBGRA_8888_SkColorType;
313a6359365887048ef055196de75591311d7a015f0brianosman            break;
31410fc6fddf24878f4f34e75c1bcc11e4499edfcc0Brian Osman        case kRGBA_1010102_GrPixelConfig:
31510fc6fddf24878f4f34e75c1bcc11e4499edfcc0Brian Osman            ct = kRGBA_1010102_SkColorType;
31610fc6fddf24878f4f34e75c1bcc11e4499edfcc0Brian Osman            break;
3179ac5b91957e59eeddebfae9630204f217c20cd4ebrianosman        case kRGBA_half_GrPixelConfig:
3189ac5b91957e59eeddebfae9630204f217c20cd4ebrianosman            ct = kRGBA_F16_SkColorType;
3199ac5b91957e59eeddebfae9630204f217c20cd4ebrianosman            break;
320bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        default:
321bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            return false;
322bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    }
323bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    if (ctOut) {
324bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        *ctOut = ct;
325bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    }
326bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    return true;
327bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com}
3288dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
32927a3aa5921b2aaf95314f955285c3cba91e4c19abrianosmanGrPixelConfig GrRenderableConfigForColorSpace(const SkColorSpace* colorSpace) {
330f3880933092c3226cd7ffd1690fe72c9c0cc376cMatt Sarett    if (!colorSpace) {
3312695eaa41fbd208dcee9e134e180c6609856f0acbrianosman        return kRGBA_8888_GrPixelConfig;
3322695eaa41fbd208dcee9e134e180c6609856f0acbrianosman    } else if (colorSpace->gammaIsLinear()) {
3332695eaa41fbd208dcee9e134e180c6609856f0acbrianosman        return kRGBA_half_GrPixelConfig;
3342695eaa41fbd208dcee9e134e180c6609856f0acbrianosman    } else if (colorSpace->gammaCloseToSRGB()) {
3352695eaa41fbd208dcee9e134e180c6609856f0acbrianosman        return kSRGBA_8888_GrPixelConfig;
3362695eaa41fbd208dcee9e134e180c6609856f0acbrianosman    } else {
3372695eaa41fbd208dcee9e134e180c6609856f0acbrianosman        SkDEBUGFAIL("No renderable config exists for color space with strange gamma");
3382695eaa41fbd208dcee9e134e180c6609856f0acbrianosman        return kUnknown_GrPixelConfig;
3392695eaa41fbd208dcee9e134e180c6609856f0acbrianosman    }
3402695eaa41fbd208dcee9e134e180c6609856f0acbrianosman}
3412695eaa41fbd208dcee9e134e180c6609856f0acbrianosman
342f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon////////////////////////////////////////////////////////////////////////////////////////////////
3438dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
344185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reedstatic inline bool blend_requires_shader(const SkBlendMode mode) {
345185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reed    return SkBlendMode::kDst != mode;
346aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon}
347aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon
348f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomonstatic inline bool skpaint_to_grpaint_impl(GrContext* context,
349f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                                           const GrColorSpaceInfo& colorSpaceInfo,
350f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                           const SkPaint& skPaint,
351f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                           const SkMatrix& viewM,
352aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon                                           std::unique_ptr<GrFragmentProcessor>* shaderProcessor,
3537d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed                                           SkBlendMode* primColorMode,
354f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                           GrPaint* grPaint) {
355f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon    grPaint->setAllowSRGBInputs(colorSpaceInfo.isGammaCorrect());
3568dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
357c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman    // Convert SkPaint color to 4f format, including optional linearizing and gamut conversion.
3584cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon    GrColor4f origColor = SkColorToUnpremulGrColor4f(skPaint.getColor(), colorSpaceInfo);
359a4535a34d1b317543307df6901debfefe7132569brianosman
3603bc266b33ad85299af06469a32ad9f6339424485Mike Reed    const GrFPArgs fpArgs(context, &viewM, skPaint.getFilterQuality(), &colorSpaceInfo);
361bfadcf0224cb22e2aec10592fa197ba7ab19b479Mike Reed
362f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    // Setup the initial color considering the shader, the SkPaint color, and the presence or not
363f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    // of per-vertex colors.
364aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon    std::unique_ptr<GrFragmentProcessor> shaderFP;
365185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reed    if (!primColorMode || blend_requires_shader(*primColorMode)) {
366aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon        if (shaderProcessor) {
367aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon            shaderFP = std::move(*shaderProcessor);
3684aed13889bd9085337e0d4c20df28686687b833bFlorin Malita        } else if (const auto* shader = as_SB(skPaint.getShader())) {
369bfadcf0224cb22e2aec10592fa197ba7ab19b479Mike Reed            shaderFP = shader->asFragmentProcessor(fpArgs);
370aad2ec69f32bad4eef0663600d606e4526488f16Yuqian Li            if (!shaderFP) {
371aad2ec69f32bad4eef0663600d606e4526488f16Yuqian Li                return false;
372aad2ec69f32bad4eef0663600d606e4526488f16Yuqian Li            }
373f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        }
3748dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    }
375775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein
376f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    // Set this in below cases if the output of the shader/paint-color/paint-alpha/primXfermode is
377f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    // a known constant value. In that case we can simply apply a color filter during this
378f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    // conversion without converting the color filter to a GrFragmentProcessor.
379f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    bool applyColorFilterToPaintColor = false;
380f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    if (shaderFP) {
381f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        if (primColorMode) {
382f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // There is a blend between the primitive color and the shader color. The shader sees
383f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // the opaque paint color. The shader's output is blended using the provided mode by
384f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // the primitive color. The blended color is then modulated by the paint's alpha.
385f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
386f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // The geometry processor will insert the primitive color to start the color chain, so
387f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // the GrPaint color will be ignored.
388f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
3894cea3b9e9d9836c926a8feb55d050993d40b4b5ebrianosman            GrColor4f shaderInput = origColor.opaque();
390aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon            shaderFP = GrFragmentProcessor::OverrideInput(std::move(shaderFP), shaderInput);
391185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reed            shaderFP = GrXfermodeFragmentProcessor::MakeFromSrcProcessor(std::move(shaderFP),
392185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reed                                                                         *primColorMode);
393185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reed
394f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // The above may return null if compose results in a pass through of the prim color.
395f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            if (shaderFP) {
3961c9686bfa5e2de3e06f1d1b9691105afb6659e85Robert Phillips                grPaint->addColorFragmentProcessor(std::move(shaderFP));
397f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            }
398f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
399a4535a34d1b317543307df6901debfefe7132569brianosman            // We can ignore origColor here - alpha is unchanged by gamma
400f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor());
401f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            if (GrColor_WHITE != paintAlpha) {
402618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman                // No gamut conversion - paintAlpha is a (linear) alpha value, splatted to all
403618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman                // color channels. It's value should be treated as the same in ANY color space.
40406ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                grPaint->addColorFragmentProcessor(GrConstColorProcessor::Make(
405618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman                    GrColor4f::FromGrColor(paintAlpha),
406e9d172af84fff5d76e19180a0c2b7b3cc51e90a2Ethan Nicholas                    GrConstColorProcessor::InputMode::kModulateRGBA));
407f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            }
408f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        } else {
409f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // The shader's FP sees the paint unpremul color
410a4535a34d1b317543307df6901debfefe7132569brianosman            grPaint->setColor4f(origColor);
41106ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman            grPaint->addColorFragmentProcessor(std::move(shaderFP));
412f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        }
413f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    } else {
414f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        if (primColorMode) {
415f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // There is a blend between the primitive color and the paint color. The blend considers
416f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // the opaque paint color. The paint's alpha is applied to the post-blended color.
417aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon            auto processor = GrConstColorProcessor::Make(origColor.opaque(),
418e9d172af84fff5d76e19180a0c2b7b3cc51e90a2Ethan Nicholas                                                         GrConstColorProcessor::InputMode::kIgnore);
419185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reed            processor = GrXfermodeFragmentProcessor::MakeFromSrcProcessor(std::move(processor),
420185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reed                                                                          *primColorMode);
421f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            if (processor) {
42206ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                grPaint->addColorFragmentProcessor(std::move(processor));
423f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            }
424f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
425a4535a34d1b317543307df6901debfefe7132569brianosman            grPaint->setColor4f(origColor.opaque());
426f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
427a4535a34d1b317543307df6901debfefe7132569brianosman            // We can ignore origColor here - alpha is unchanged by gamma
428f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor());
429aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon            if (GrColor_WHITE != paintAlpha) {
430618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman                // No gamut conversion - paintAlpha is a (linear) alpha value, splatted to all
431618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman                // color channels. It's value should be treated as the same in ANY color space.
43206ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                grPaint->addColorFragmentProcessor(GrConstColorProcessor::Make(
433618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman                    GrColor4f::FromGrColor(paintAlpha),
434e9d172af84fff5d76e19180a0c2b7b3cc51e90a2Ethan Nicholas                    GrConstColorProcessor::InputMode::kModulateRGBA));
435aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon            }
436f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        } else {
437f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // No shader, no primitive color.
438a4535a34d1b317543307df6901debfefe7132569brianosman            grPaint->setColor4f(origColor.premul());
439f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            applyColorFilterToPaintColor = true;
440f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        }
441f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    }
4428dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
4438dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    SkColorFilter* colorFilter = skPaint.getColorFilter();
44449f085dddff10473b6ebf832a974288300224e60bsalomon    if (colorFilter) {
445f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        if (applyColorFilterToPaintColor) {
4468bf4e672f2c40ef313274f8b79c2c9304f9fff3fBrian Osman            // If we're in legacy mode, we *must* avoid using the 4f version of the color filter,
4478bf4e672f2c40ef313274f8b79c2c9304f9fff3fBrian Osman            // because that will combine with the linearized version of the stored color.
448f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon            if (colorSpaceInfo.isGammaCorrect()) {
4498bf4e672f2c40ef313274f8b79c2c9304f9fff3fBrian Osman                grPaint->setColor4f(GrColor4f::FromSkColor4f(
4508bf4e672f2c40ef313274f8b79c2c9304f9fff3fBrian Osman                    colorFilter->filterColor4f(origColor.toSkColor4f())).premul());
4518bf4e672f2c40ef313274f8b79c2c9304f9fff3fBrian Osman            } else {
4524cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon                grPaint->setColor4f(SkColorToPremulGrColor4fLegacy(
4534cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon                        colorFilter->filterColor(skPaint.getColor())));
4548bf4e672f2c40ef313274f8b79c2c9304f9fff3fBrian Osman            }
4558dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org        } else {
4564cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon            auto cfFP = colorFilter->asFragmentProcessor(context, colorSpaceInfo);
457e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon            if (cfFP) {
45806ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                grPaint->addColorFragmentProcessor(std::move(cfFP));
459f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            } else {
460f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                return false;
4618dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org            }
4628dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org        }
4638dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    }
464f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
46580747ef591ff3c09c2b610eb21258132d1ff4ef5Mike Reed    SkMaskFilterBase* maskFilter = as_MFB(skPaint.getMaskFilter());
466a29a956d0e27819b97592404ae1ec6cc8e7b1045Robert Phillips    if (maskFilter) {
467bfadcf0224cb22e2aec10592fa197ba7ab19b479Mike Reed        if (auto mfFP = maskFilter->asFragmentProcessor(fpArgs)) {
468bfadcf0224cb22e2aec10592fa197ba7ab19b479Mike Reed            grPaint->addCoverageFragmentProcessor(std::move(mfFP));
469a29a956d0e27819b97592404ae1ec6cc8e7b1045Robert Phillips        }
470a29a956d0e27819b97592404ae1ec6cc8e7b1045Robert Phillips    }
471a29a956d0e27819b97592404ae1ec6cc8e7b1045Robert Phillips
4724f0379444db31421894d2fce7c85889fe5eaa01arobertphillips    // When the xfermode is null on the SkPaint (meaning kSrcOver) we need the XPFactory field on
4734f0379444db31421894d2fce7c85889fe5eaa01arobertphillips    // the GrPaint to also be null (also kSrcOver).
4744f0379444db31421894d2fce7c85889fe5eaa01arobertphillips    SkASSERT(!grPaint->getXPFactory());
475374772bd61951f01bf84fe17bf53d8867681c9aereed    if (!skPaint.isSrcOver()) {
476374772bd61951f01bf84fe17bf53d8867681c9aereed        grPaint->setXPFactory(SkBlendMode_AsXPFactory(skPaint.getBlendMode()));
4774f0379444db31421894d2fce7c85889fe5eaa01arobertphillips    }
478f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
479f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#ifndef SK_IGNORE_GPU_DITHER
480d4a70ee36717493cc071f878b16b037463e6ce9aFlorin Malita    // Conservative default, in case GrPixelConfigToColorType() fails.
481d4a70ee36717493cc071f878b16b037463e6ce9aFlorin Malita    SkColorType ct = SkColorType::kRGB_565_SkColorType;
482f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon    GrPixelConfigToColorType(colorSpaceInfo.config(), &ct);
483f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon    if (SkPaintPriv::ShouldDither(skPaint, ct) && grPaint->numColorFragmentProcessors() > 0 &&
484f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon        !colorSpaceInfo.isGammaCorrect()) {
485f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon        auto ditherFP = GrDitherEffect::Make(colorSpaceInfo.config());
4860c15ae82f0d5b5356f7650b78d749c09b3bc0403Brian Salomon        if (ditherFP) {
4870c15ae82f0d5b5356f7650b78d749c09b3bc0403Brian Salomon            grPaint->addColorFragmentProcessor(std::move(ditherFP));
4880c15ae82f0d5b5356f7650b78d749c09b3bc0403Brian Salomon        }
489f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    }
490f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#endif
491bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    return true;
4928dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org}
4938dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
494f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomonbool SkPaintToGrPaint(GrContext* context, const GrColorSpaceInfo& colorSpaceInfo,
495f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                      const SkPaint& skPaint, const SkMatrix& viewM, GrPaint* grPaint) {
496f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon    return skpaint_to_grpaint_impl(context, colorSpaceInfo, skPaint, viewM, nullptr, nullptr,
497f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                                   grPaint);
498f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon}
499f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
500f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon/** Replaces the SkShader (if any) on skPaint with the passed in GrFragmentProcessor. */
501f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomonbool SkPaintToGrPaintReplaceShader(GrContext* context,
502f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                                   const GrColorSpaceInfo& colorSpaceInfo,
503f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                   const SkPaint& skPaint,
504aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon                                   std::unique_ptr<GrFragmentProcessor> shaderFP,
505f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                   GrPaint* grPaint) {
506f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    if (!shaderFP) {
507c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon        return false;
5088dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    }
509f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon    return skpaint_to_grpaint_impl(context, colorSpaceInfo, skPaint, SkMatrix::I(), &shaderFP,
510f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                                   nullptr, grPaint);
511f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon}
512f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
513f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon/** Ignores the SkShader (if any) on skPaint. */
514f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomonbool SkPaintToGrPaintNoShader(GrContext* context,
515f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                              const GrColorSpaceInfo& colorSpaceInfo,
516f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                              const SkPaint& skPaint,
517f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                              GrPaint* grPaint) {
518f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    // Use a ptr to a nullptr to to indicate that the SkShader is ignored and not replaced.
519aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon    static std::unique_ptr<GrFragmentProcessor> kNullShaderFP(nullptr);
520aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon    static std::unique_ptr<GrFragmentProcessor>* kIgnoreShader = &kNullShaderFP;
521f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon    return skpaint_to_grpaint_impl(context, colorSpaceInfo, skPaint, SkMatrix::I(), kIgnoreShader,
522f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                                   nullptr, grPaint);
523f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon}
524f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
525f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon/** Blends the SkPaint's shader (or color if no shader) with a per-primitive color which must
5267d954ad797176afedb9262fdea4507d0fc60eb9dMike Reedbe setup as a vertex attribute using the specified SkBlendMode. */
527f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomonbool SkPaintToGrPaintWithXfermode(GrContext* context,
528f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                                  const GrColorSpaceInfo& colorSpaceInfo,
529f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                  const SkPaint& skPaint,
530f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                  const SkMatrix& viewM,
5317d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed                                  SkBlendMode primColorMode,
532f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                  GrPaint* grPaint) {
533f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon    return skpaint_to_grpaint_impl(context, colorSpaceInfo, skPaint, viewM, nullptr, &primColorMode,
534185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reed                                   grPaint);
5358dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org}
5368b26b99c97473f020df4b9d4ba789e074e06ceddreed
53733a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualittbool SkPaintToGrPaintWithTexture(GrContext* context,
538f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                                 const GrColorSpaceInfo& colorSpaceInfo,
53933a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                                 const SkPaint& paint,
54033a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                                 const SkMatrix& viewM,
541aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon                                 std::unique_ptr<GrFragmentProcessor> fp,
54233a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                                 bool textureIsAlphaOnly,
54333a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                                 GrPaint* grPaint) {
544aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon    std::unique_ptr<GrFragmentProcessor> shaderFP;
54533a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt    if (textureIsAlphaOnly) {
5464aed13889bd9085337e0d4c20df28686687b833bFlorin Malita        if (const auto* shader = as_SB(paint.getShader())) {
547e3429e62b0d020b27de3daa55893953eff581c4fMike Reed            shaderFP = shader->asFragmentProcessor(GrFPArgs(
5484cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon                    context, &viewM, nullptr, paint.getFilterQuality(), &colorSpaceInfo));
54933a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt            if (!shaderFP) {
55033a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                return false;
55133a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt            }
552aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon            std::unique_ptr<GrFragmentProcessor> fpSeries[] = { std::move(shaderFP), std::move(fp) };
55306ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman            shaderFP = GrFragmentProcessor::RunInSeries(fpSeries, 2);
55433a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt        } else {
555aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon            shaderFP = GrFragmentProcessor::MakeInputPremulAndMulByOutput(std::move(fp));
55633a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt        }
55733a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt    } else {
55828eaed254dcd73b42c15b73528f349cccd7797e5Mike Reed        shaderFP = GrFragmentProcessor::MulChildByInputAlpha(std::move(fp));
55933a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt    }
56033a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt
561f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon    return SkPaintToGrPaintReplaceShader(context, colorSpaceInfo, paint, std::move(shaderFP),
562f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                                         grPaint);
56333a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt}
56433a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt
565f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
566f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon////////////////////////////////////////////////////////////////////////////////////////////////
567f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
5682bbdcc44c63974f29f3743bb58d929601a3f65c6Brian SalomonGrSamplerState::Filter GrSkFilterQualityToGrFilterMode(SkFilterQuality paintFilterQuality,
5692bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon                                                       const SkMatrix& viewM,
5702bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon                                                       const SkMatrix& localM,
571db78cba957889285604aeacb75e47af4600880c4Brian Osman                                                       bool sharpenMipmappedTextures,
5722bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon                                                       bool* doBicubic) {
5739bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt    *doBicubic = false;
5742bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon    GrSamplerState::Filter textureFilterMode;
5759bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt    switch (paintFilterQuality) {
5769bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        case kNone_SkFilterQuality:
5772bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon            textureFilterMode = GrSamplerState::Filter::kNearest;
5789bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            break;
5799bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        case kLow_SkFilterQuality:
5802bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon            textureFilterMode = GrSamplerState::Filter::kBilerp;
5819bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            break;
5829bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        case kMedium_SkFilterQuality: {
5839bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            SkMatrix matrix;
5849bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            matrix.setConcat(viewM, localM);
585db78cba957889285604aeacb75e47af4600880c4Brian Osman            // With sharp mips, we bias lookups by -0.5. That means our final LOD is >= 0 until the
586db78cba957889285604aeacb75e47af4600880c4Brian Osman            // computed LOD is >= 0.5. At what scale factor does a texture get an LOD of 0.5?
587db78cba957889285604aeacb75e47af4600880c4Brian Osman            //
588db78cba957889285604aeacb75e47af4600880c4Brian Osman            // Want:  0       = log2(1/s) - 0.5
589db78cba957889285604aeacb75e47af4600880c4Brian Osman            //        0.5     = log2(1/s)
590db78cba957889285604aeacb75e47af4600880c4Brian Osman            //        2^0.5   = 1/s
591db78cba957889285604aeacb75e47af4600880c4Brian Osman            //        1/2^0.5 = s
592db78cba957889285604aeacb75e47af4600880c4Brian Osman            //        2^0.5/2 = s
593db78cba957889285604aeacb75e47af4600880c4Brian Osman            SkScalar mipScale = sharpenMipmappedTextures ? SK_ScalarRoot2Over2 : SK_Scalar1;
594db78cba957889285604aeacb75e47af4600880c4Brian Osman            if (matrix.getMinScale() < mipScale) {
5952bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon                textureFilterMode = GrSamplerState::Filter::kMipMap;
5969bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            } else {
5979bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt                // Don't trigger MIP level generation unnecessarily.
5982bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon                textureFilterMode = GrSamplerState::Filter::kBilerp;
5999bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            }
6009bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            break;
6019bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        }
6029bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        case kHigh_SkFilterQuality: {
6039bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            SkMatrix matrix;
6049bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            matrix.setConcat(viewM, localM);
6059bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            *doBicubic = GrBicubicEffect::ShouldUseBicubic(matrix, &textureFilterMode);
6069bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            break;
6079bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        }
6089bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        default:
609e54c75f351c775201049743c506d7a508d0fef91Mike Klein            // Should be unreachable.  If not, fall back to mipmaps.
6102bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon            textureFilterMode = GrSamplerState::Filter::kMipMap;
6119bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            break;
6129bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt
6139bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt    }
6149bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt    return textureFilterMode;
6159bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt}
616