SkGr.cpp revision 4cbb6e6d551e8bea2c040b1aa9dce253cffb9af0
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"
1632342f032e1dfd133040324f851f0365f9d4cb51Brian Osman#include "GrResourceProvider.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"
27a29a956d0e27819b97592404ae1ec6cc8e7b1045Robert Phillips#include "SkMaskFilter.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//////////////////////////////////////////////////////////////////////////////
6826c90e04797e15c37ec00e0f836292b8a207d294Robert Phillipssk_sp<GrTextureProxy> GrUploadBitmapToTextureProxy(GrResourceProvider* resourceProvider,
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    }
78dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett    return GrUploadPixmapToTextureProxy(resourceProvider, pixmap, SkBudgeted::kYes, dstColorSpace);
79d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips}
804075ec80e1c36e414e57746c772298be3b49a74eBrian Osman
81d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillipsstatic const SkPixmap* compute_desc(const GrCaps& caps, const SkPixmap& pixmap,
82d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips                                    GrSurfaceDesc* desc,
83d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips                                    SkBitmap* tmpBitmap, SkPixmap* tmpPixmap) {
84d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips    const SkPixmap* pmap = &pixmap;
85d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips
86d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips    *desc = GrImageInfoToSurfaceDesc(pixmap.info(), caps);
87a6359365887048ef055196de75591311d7a015f0brianosman
88d0be1ef36c64c2a420cbd82f4c033704d4c54a07Brian Osman    // TODO: We're checking for srgbSupport, but we can then end up picking sBGRA as our pixel
89d0be1ef36c64c2a420cbd82f4c033704d4c54a07Brian Osman    // config (which may not be supported). We need better fallback management here.
90472991481bf1aaf6e966d9e8d3c64208cfc84247Brian Osman    SkColorSpace* colorSpace = pixmap.colorSpace();
91d0be1ef36c64c2a420cbd82f4c033704d4c54a07Brian Osman
92d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips    if (caps.srgbSupport() &&
93f3880933092c3226cd7ffd1690fe72c9c0cc376cMatt Sarett        colorSpace && colorSpace->gammaCloseToSRGB() && !GrPixelConfigIsSRGB(desc->fConfig)) {
94b109b8c5ec40a7dd85a0a2951a1f98fa63b805aabrianosman        // We were supplied an sRGB-like color space, but we don't have a suitable pixel config.
95a6359365887048ef055196de75591311d7a015f0brianosman        // Convert to 8888 sRGB so we can handle the data correctly. The raster backend doesn't
96a6359365887048ef055196de75591311d7a015f0brianosman        // handle sRGB Index8 -> sRGB 8888 correctly (yet), so lie about both the source and
97a6359365887048ef055196de75591311d7a015f0brianosman        // destination (claim they're linear):
98a6359365887048ef055196de75591311d7a015f0brianosman        SkImageInfo linSrcInfo = SkImageInfo::Make(pixmap.width(), pixmap.height(),
99a6359365887048ef055196de75591311d7a015f0brianosman                                                   pixmap.colorType(), pixmap.alphaType());
100086a427b0cee3862f25c492fc5082ff24105dc53Mike Reed        SkPixmap linSrcPixmap(linSrcInfo, pixmap.addr(), pixmap.rowBytes());
101a6359365887048ef055196de75591311d7a015f0brianosman
102b109b8c5ec40a7dd85a0a2951a1f98fa63b805aabrianosman        SkImageInfo dstInfo = SkImageInfo::Make(pixmap.width(), pixmap.height(),
103b109b8c5ec40a7dd85a0a2951a1f98fa63b805aabrianosman                                                kN32_SkColorType, kPremul_SkAlphaType,
10470b49fd063171a78d3c664ca8af3988f5426319bRobert Phillips                                                pixmap.info().refColorSpace());
105b109b8c5ec40a7dd85a0a2951a1f98fa63b805aabrianosman
106d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips        tmpBitmap->allocPixels(dstInfo);
107a6359365887048ef055196de75591311d7a015f0brianosman
108a6359365887048ef055196de75591311d7a015f0brianosman        SkImageInfo linDstInfo = SkImageInfo::MakeN32Premul(pixmap.width(), pixmap.height());
109d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips        if (!linSrcPixmap.readPixels(linDstInfo, tmpBitmap->getPixels(), tmpBitmap->rowBytes())) {
110a6359365887048ef055196de75591311d7a015f0brianosman            return nullptr;
111a6359365887048ef055196de75591311d7a015f0brianosman        }
112d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips        if (!tmpBitmap->peekPixels(tmpPixmap)) {
113a6359365887048ef055196de75591311d7a015f0brianosman            return nullptr;
114a6359365887048ef055196de75591311d7a015f0brianosman        }
115d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips        pmap = tmpPixmap;
116a6359365887048ef055196de75591311d7a015f0brianosman        // must rebuild desc, since we've forced the info to be N32
117d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips        *desc = GrImageInfoToSurfaceDesc(pmap->info(), caps);
1185782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    }
119ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
120d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips    return pmap;
12137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon}
12237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
123dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarettsk_sp<GrTextureProxy> GrUploadPixmapToTextureProxy(GrResourceProvider* resourceProvider,
124dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett                                                   const SkPixmap& pixmap,
125dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett                                                   SkBudgeted budgeted,
126dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett                                                   SkColorSpace* dstColorSpace) {
127dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett    SkDestinationSurfaceColorMode colorMode = dstColorSpace
128dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett        ? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware
129dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett        : SkDestinationSurfaceColorMode::kLegacy;
130dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett
131dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett    if (!SkImageInfoIsValid(pixmap.info(), colorMode)) {
132dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett        return nullptr;
133dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett    }
134dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett
135d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips    SkBitmap tmpBitmap;
136d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips    SkPixmap tmpPixmap;
137d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips    GrSurfaceDesc desc;
138d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips
139559f534759f616f1d9a173e0045acead5ee4cae1Derek Sollenberger    ATRACE_ANDROID_FRAMEWORK("Upload Texture [%ux%u]", pixmap.width(), pixmap.height());
14026c90e04797e15c37ec00e0f836292b8a207d294Robert Phillips    if (const SkPixmap* pmap = compute_desc(*resourceProvider->caps(), pixmap, &desc,
14126c90e04797e15c37ec00e0f836292b8a207d294Robert Phillips                                            &tmpBitmap, &tmpPixmap)) {
14226c90e04797e15c37ec00e0f836292b8a207d294Robert Phillips        return GrSurfaceProxy::MakeDeferred(resourceProvider, desc,
143d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips                                            budgeted, pmap->addr(), pmap->rowBytes());
144d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips    }
145d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips
146d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips    return nullptr;
147d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips}
148b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon
149045802dbb7202b52f5fd2758d725f39c156a6165bsalomon////////////////////////////////////////////////////////////////////////////////
150045802dbb7202b52f5fd2758d725f39c156a6165bsalomon
151c55271f2551533b37043aa2e37f754832a43073cbsalomonvoid GrInstallBitmapUniqueKeyInvalidator(const GrUniqueKey& key, SkPixelRef* pixelRef) {
15289fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon    class Invalidator : public SkPixelRef::GenIDChangeListener {
15389fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon    public:
15489fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon        explicit Invalidator(const GrUniqueKey& key) : fMsg(key) {}
15589fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon    private:
15689fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon        GrUniqueKeyInvalidatedMessage fMsg;
15789fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon
15889fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon        void onChange() override { SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(fMsg); }
15989fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon    };
16089fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon
16189fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon    pixelRef->addGenIDChangeListener(new Invalidator(key));
16289fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon}
16389fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon
16478075804c1e43ca32f3d8eb75d2a8b6c91e74b9bRobert Phillipssk_sp<GrTextureProxy> GrGenerateMipMapsAndUploadToTextureProxy(GrContext* ctx,
16578075804c1e43ca32f3d8eb75d2a8b6c91e74b9bRobert Phillips                                                               const SkBitmap& bitmap,
16678075804c1e43ca32f3d8eb75d2a8b6c91e74b9bRobert Phillips                                                               SkColorSpace* dstColorSpace) {
16761624f0c716b576706659750d87b6956f4c15722Brian Osman    SkDestinationSurfaceColorMode colorMode = dstColorSpace
16861624f0c716b576706659750d87b6956f4c15722Brian Osman        ? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware
16961624f0c716b576706659750d87b6956f4c15722Brian Osman        : SkDestinationSurfaceColorMode::kLegacy;
17061624f0c716b576706659750d87b6956f4c15722Brian Osman
171dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett    if (!SkImageInfoIsValid(bitmap.info(), colorMode)) {
1724075ec80e1c36e414e57746c772298be3b49a74eBrian Osman        return nullptr;
1734075ec80e1c36e414e57746c772298be3b49a74eBrian Osman    }
1744075ec80e1c36e414e57746c772298be3b49a74eBrian Osman
1754edb5d219eb99aa1e8fbe5e37260d3b34314e54bMike Reed    SkPixmap pixmap;
1764edb5d219eb99aa1e8fbe5e37260d3b34314e54bMike Reed    if (!bitmap.peekPixels(&pixmap)) {
17755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        return nullptr;
17855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    }
17955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
180faa5329b9be0042c95e219f9ceec7a09c4caa7caGreg Daniel    SkBitmap tmpBitmap;
181faa5329b9be0042c95e219f9ceec7a09c4caa7caGreg Daniel    SkPixmap tmpPixmap;
182faa5329b9be0042c95e219f9ceec7a09c4caa7caGreg Daniel    GrSurfaceDesc desc;
183faa5329b9be0042c95e219f9ceec7a09c4caa7caGreg Daniel    const SkPixmap* pmap = compute_desc(*ctx->resourceProvider()->caps(), pixmap, &desc,
184faa5329b9be0042c95e219f9ceec7a09c4caa7caGreg Daniel                                        &tmpBitmap, &tmpPixmap);
185faa5329b9be0042c95e219f9ceec7a09c4caa7caGreg Daniel    if (!pmap) {
186faa5329b9be0042c95e219f9ceec7a09c4caa7caGreg Daniel        return nullptr;
187faa5329b9be0042c95e219f9ceec7a09c4caa7caGreg Daniel    }
188faa5329b9be0042c95e219f9ceec7a09c4caa7caGreg Daniel
189faa5329b9be0042c95e219f9ceec7a09c4caa7caGreg Daniel    ATRACE_ANDROID_FRAMEWORK("Upload MipMap Texture [%ux%u]", pmap->width(), pmap->height());
190faa5329b9be0042c95e219f9ceec7a09c4caa7caGreg Daniel    std::unique_ptr<SkMipMap> mipmaps(SkMipMap::Build(*pmap, colorMode, nullptr));
19155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    if (!mipmaps) {
19255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        return nullptr;
19355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    }
19455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
19555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    const int mipLevelCount = mipmaps->countLevels() + 1;
19655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    if (mipLevelCount < 1) {
19755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        return nullptr;
19855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    }
19955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
2007ecc59610de72043e9b7ebaf1ef45c43425e54fcBen Wagner    std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipLevelCount]);
20155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
202faa5329b9be0042c95e219f9ceec7a09c4caa7caGreg Daniel    texels[0].fPixels = pmap->addr();
203faa5329b9be0042c95e219f9ceec7a09c4caa7caGreg Daniel    texels[0].fRowBytes = pmap->rowBytes();
20455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
20555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    for (int i = 1; i < mipLevelCount; ++i) {
20655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        SkMipMap::Level generatedMipLevel;
20755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        mipmaps->getLevel(i - 1, &generatedMipLevel);
20855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        texels[i].fPixels = generatedMipLevel.fPixmap.addr();
20955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        texels[i].fRowBytes = generatedMipLevel.fPixmap.rowBytes();
21055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    }
21155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
2128e8c755f56e5dbaf0f87d88a775632010b32e974Robert Phillips    return GrSurfaceProxy::MakeDeferredMipMap(ctx->resourceProvider(),
2138e8c755f56e5dbaf0f87d88a775632010b32e974Robert Phillips                                              desc,
2148e8c755f56e5dbaf0f87d88a775632010b32e974Robert Phillips                                              SkBudgeted::kYes,
2158e8c755f56e5dbaf0f87d88a775632010b32e974Robert Phillips                                              texels.get(),
2168e8c755f56e5dbaf0f87d88a775632010b32e974Robert Phillips                                              mipLevelCount,
2178e8c755f56e5dbaf0f87d88a775632010b32e974Robert Phillips                                              colorMode);
2180c984a0af30989fe20b1f8af18867983a88c48b6Robert Phillips}
2190c984a0af30989fe20b1f8af18867983a88c48b6Robert Phillips
22055afd6dcee62b403ab888bb8a333c538a79041d3Greg Danielsk_sp<GrTextureProxy> GrCopyBaseMipMapToTextureProxy(GrContext* ctx,
221e1da1d9a7dfa6c9ebdcbd2845acebd045edd2a6fGreg Daniel                                                     GrTextureProxy* baseProxy) {
22255afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    SkASSERT(baseProxy);
22355afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel
224bb76ace72bee5d44189b6ee6c81cda174ce9ea30Greg Daniel    if (!ctx->caps()->isConfigCopyable(baseProxy->config())) {
225bb76ace72bee5d44189b6ee6c81cda174ce9ea30Greg Daniel        return nullptr;
226bb76ace72bee5d44189b6ee6c81cda174ce9ea30Greg Daniel    }
227bb76ace72bee5d44189b6ee6c81cda174ce9ea30Greg Daniel
22855afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    GrSurfaceDesc desc;
22955afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    desc.fFlags = kNone_GrSurfaceFlags;
23055afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    desc.fOrigin = baseProxy->origin();
23155afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    desc.fWidth = baseProxy->width();
23255afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    desc.fHeight = baseProxy->height();
23355afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    desc.fConfig = baseProxy->config();
23455afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    desc.fSampleCnt = 0;
23555afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel
23655afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeDeferredMipMap(ctx->resourceProvider(),
23755afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel                                                                     desc,
238e1da1d9a7dfa6c9ebdcbd2845acebd045edd2a6fGreg Daniel                                                                     SkBudgeted::kYes);
23955afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    if (!proxy) {
24055afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel        return nullptr;
24155afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    }
24255afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel
24355afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    // Copy the base layer to our proxy
24455afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    sk_sp<GrSurfaceContext> sContext = ctx->contextPriv().makeWrappedSurfaceContext(proxy, nullptr);
24555afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    SkASSERT(sContext);
24655afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    SkAssertResult(sContext->copy(baseProxy));
24755afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel
24855afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel    return proxy;
24955afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel}
25055afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel
25155afd6dcee62b403ab888bb8a333c538a79041d3Greg Daniel
25278075804c1e43ca32f3d8eb75d2a8b6c91e74b9bRobert Phillipssk_sp<GrTextureProxy> GrUploadMipMapToTextureProxy(GrContext* ctx, const SkImageInfo& info,
253590533f066035a48df9f78395a80314b559f4714Robert Phillips                                                   const GrMipLevel texels[],
25478075804c1e43ca32f3d8eb75d2a8b6c91e74b9bRobert Phillips                                                   int mipLevelCount,
25578075804c1e43ca32f3d8eb75d2a8b6c91e74b9bRobert Phillips                                                   SkDestinationSurfaceColorMode colorMode) {
256dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett    if (!SkImageInfoIsValid(info, colorMode)) {
2574075ec80e1c36e414e57746c772298be3b49a74eBrian Osman        return nullptr;
2584075ec80e1c36e414e57746c772298be3b49a74eBrian Osman    }
2594075ec80e1c36e414e57746c772298be3b49a74eBrian Osman
2608e8c755f56e5dbaf0f87d88a775632010b32e974Robert Phillips    return GrSurfaceProxy::MakeDeferredMipMap(ctx->resourceProvider(),
2618e8c755f56e5dbaf0f87d88a775632010b32e974Robert Phillips                                              GrImageInfoToSurfaceDesc(info, *ctx->caps()),
2628e8c755f56e5dbaf0f87d88a775632010b32e974Robert Phillips                                              SkBudgeted::kYes, texels,
2638e8c755f56e5dbaf0f87d88a775632010b32e974Robert Phillips                                              mipLevelCount, colorMode);
2640ae6faa34d73ffc7ebec3d13f0473703bade821bRobert Phillips}
2650ae6faa34d73ffc7ebec3d13f0473703bade821bRobert Phillips
266bbd7a3be407ce94fcc4f8b1eb475de8b6f49026eRobert Phillipssk_sp<GrTextureProxy> GrRefCachedBitmapTextureProxy(GrContext* ctx,
267bbd7a3be407ce94fcc4f8b1eb475de8b6f49026eRobert Phillips                                                    const SkBitmap& bitmap,
2682bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon                                                    const GrSamplerState& params,
269bbd7a3be407ce94fcc4f8b1eb475de8b6f49026eRobert Phillips                                                    SkScalar scaleAdjust[2]) {
270bbd7a3be407ce94fcc4f8b1eb475de8b6f49026eRobert Phillips    // Caller doesn't care about the texture's color space (they can always get it from the bitmap)
2713798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips    return GrBitmapTextureMaker(ctx, bitmap).refTextureProxyForParams(params, nullptr,
2723798c86f6885f0b47fb2e659a43b48a4468a97efRobert Phillips                                                                      nullptr, scaleAdjust);
273bbd7a3be407ce94fcc4f8b1eb475de8b6f49026eRobert Phillips}
274bbd7a3be407ce94fcc4f8b1eb475de8b6f49026eRobert Phillips
27526c90e04797e15c37ec00e0f836292b8a207d294Robert Phillipssk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrResourceProvider* resourceProvider,
27626c90e04797e15c37ec00e0f836292b8a207d294Robert Phillips                                              const SkBitmap& bitmap) {
277e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips    GrUniqueKey originalKey;
278e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips
279e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips    if (!bitmap.isVolatile()) {
280e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips        SkIPoint origin = bitmap.pixelRefOrigin();
281e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips        SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, bitmap.width(), bitmap.height());
282e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips        GrMakeKeyFromImageID(&originalKey, bitmap.pixelRef()->getGenerationID(), subset);
283e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips    }
284e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips
285d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips    sk_sp<GrTextureProxy> proxy;
286e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips
287e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips    if (originalKey.isValid()) {
288cd871401114f402e72420ccd49edecee2532b0e6Greg Daniel        proxy = resourceProvider->findOrCreateProxyByUniqueKey(originalKey,
289cd871401114f402e72420ccd49edecee2532b0e6Greg Daniel                                                               kTopLeft_GrSurfaceOrigin);
290e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips    }
291d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips    if (!proxy) {
292dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett        // Pass nullptr for |dstColorSpace|.  This is lenient - we allow a wider range of
293dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett        // color spaces in legacy mode.  Unfortunately, we have to be lenient here, since
294dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett        // we can't necessarily know the |dstColorSpace| at this time.
295dedac85b4f08546e92143d96c13b753cb1b80e23Matt Sarett        proxy = GrUploadBitmapToTextureProxy(resourceProvider, bitmap, nullptr);
296d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips        if (proxy && originalKey.isValid()) {
297019ff27ac0167026f9f8f4aaec8fb6461d8ba21eRobert Phillips            SkASSERT(proxy->origin() == kTopLeft_GrSurfaceOrigin);
29826c90e04797e15c37ec00e0f836292b8a207d294Robert Phillips            resourceProvider->assignUniqueKeyToProxy(originalKey, proxy.get());
299e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips            GrInstallBitmapUniqueKeyInvalidator(originalKey, bitmap.pixelRef());
300e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips        }
301e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips    }
302e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips
303d3749485db2de966a80e39669a49192fc7c0bd9dRobert Phillips    return proxy;
304e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips}
305e14d3053f329c97e1bd0519e9b358a887988dcb8Robert Phillips
30624f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com///////////////////////////////////////////////////////////////////////////////
30724f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com
3084cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian SalomonGrColor4f SkColorToPremulGrColor4f(SkColor c, const GrColorSpaceInfo& colorSpaceInfo) {
30972ae431e4032985999dc0990bfbbf4acf127a74eBrian Osman    // We want to premultiply after linearizing, so this is easy:
3104cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon    return SkColorToUnpremulGrColor4f(c, colorSpaceInfo).premul();
31172ae431e4032985999dc0990bfbbf4acf127a74eBrian Osman}
31272ae431e4032985999dc0990bfbbf4acf127a74eBrian Osman
3134cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian SalomonGrColor4f SkColorToPremulGrColor4fLegacy(SkColor c) {
3144cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon    return GrColor4f::FromGrColor(SkColorToUnpremulGrColor(c)).premul();
31572ae431e4032985999dc0990bfbbf4acf127a74eBrian Osman}
31672ae431e4032985999dc0990bfbbf4acf127a74eBrian Osman
3174cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian SalomonGrColor4f SkColorToUnpremulGrColor4f(SkColor c, const GrColorSpaceInfo& colorSpaceInfo) {
318c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman    GrColor4f color;
3194cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon    if (colorSpaceInfo.colorSpace()) {
320c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman        // SkColor4f::FromColor does sRGB -> Linear
321c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman        color = GrColor4f::FromSkColor4f(SkColor4f::FromColor(c));
322c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman    } else {
323c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman        // GrColor4f::FromGrColor just multiplies by 1/255
324c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman        color = GrColor4f::FromGrColor(SkColorToUnpremulGrColor(c));
325c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman    }
326c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman
3274cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon    if (auto* xform = colorSpaceInfo.colorSpaceXformFromSRGB()) {
3284cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon        color = xform->clampedXform(color);
329c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman    }
330c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman
331c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman    return color;
332c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman}
333c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman
334c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman///////////////////////////////////////////////////////////////////////////////
335c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman
33681e7bf8d6d338d944f3c5075b14c21580398aeb6Greg DanielGrPixelConfig SkImageInfo2GrPixelConfig(const SkColorType type, SkColorSpace* cs,
33781e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel                                        const GrCaps& caps) {
338a6359365887048ef055196de75591311d7a015f0brianosman    // We intentionally ignore profile type for non-8888 formats. Anything we can't support
339a6359365887048ef055196de75591311d7a015f0brianosman    // in hardware will be expanded to sRGB 8888 in GrUploadPixmapToTexture.
34081e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel    switch (type) {
341c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman        case kUnknown_SkColorType:
342c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman            return kUnknown_GrPixelConfig;
343c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman        case kAlpha_8_SkColorType:
344c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman            return kAlpha_8_GrPixelConfig;
345c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman        case kRGB_565_SkColorType:
346c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman            return kRGB_565_GrPixelConfig;
347c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman        case kARGB_4444_SkColorType:
348c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman            return kRGBA_4444_GrPixelConfig;
349c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman        case kRGBA_8888_SkColorType:
350f3880933092c3226cd7ffd1690fe72c9c0cc376cMatt Sarett            return (caps.srgbSupport() && cs && cs->gammaCloseToSRGB())
351a6359365887048ef055196de75591311d7a015f0brianosman                   ? kSRGBA_8888_GrPixelConfig : kRGBA_8888_GrPixelConfig;
352c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman        case kBGRA_8888_SkColorType:
353f3880933092c3226cd7ffd1690fe72c9c0cc376cMatt Sarett            return (caps.srgbSupport() && cs && cs->gammaCloseToSRGB())
354a6359365887048ef055196de75591311d7a015f0brianosman                   ? kSBGRA_8888_GrPixelConfig : kBGRA_8888_GrPixelConfig;
355c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman        case kGray_8_SkColorType:
356986563bcff26300ea4317b4dd84917d5240bb723Brian Osman            return kGray_8_GrPixelConfig;
357c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman        case kRGBA_F16_SkColorType:
358c571c001cee4e0dfacd7bd17d5cd0a2900a853a9brianosman            return kRGBA_half_GrPixelConfig;
35915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    }
36015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    SkASSERT(0);    // shouldn't get here
36115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    return kUnknown_GrPixelConfig;
36215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org}
36315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org
36481e7bf8d6d338d944f3c5075b14c21580398aeb6Greg DanielGrPixelConfig SkImageInfo2GrPixelConfig(const SkImageInfo& info, const GrCaps& caps) {
36581e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel    return SkImageInfo2GrPixelConfig(info.colorType(), info.colorSpace(), caps);
36681e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel}
36781e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel
368396fcdba14a0101ed43dcc3863585bf50c4ed6ccbrianosmanbool GrPixelConfigToColorType(GrPixelConfig config, SkColorType* ctOut) {
369bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    SkColorType ct;
370bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    switch (config) {
371bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kAlpha_8_GrPixelConfig:
372bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kAlpha_8_SkColorType;
373bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
374986563bcff26300ea4317b4dd84917d5240bb723Brian Osman        case kGray_8_GrPixelConfig:
375986563bcff26300ea4317b4dd84917d5240bb723Brian Osman            ct = kGray_8_SkColorType;
376986563bcff26300ea4317b4dd84917d5240bb723Brian Osman            break;
377bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kRGB_565_GrPixelConfig:
378bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kRGB_565_SkColorType;
379bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
380bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kRGBA_4444_GrPixelConfig:
381bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kARGB_4444_SkColorType;
382bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
383bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kRGBA_8888_GrPixelConfig:
384bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kRGBA_8888_SkColorType;
385bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
386bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kBGRA_8888_GrPixelConfig:
387bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kBGRA_8888_SkColorType;
388bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
389fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth        case kSRGBA_8888_GrPixelConfig:
390fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth            ct = kRGBA_8888_SkColorType;
391fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth            break;
392a6359365887048ef055196de75591311d7a015f0brianosman        case kSBGRA_8888_GrPixelConfig:
393a6359365887048ef055196de75591311d7a015f0brianosman            ct = kBGRA_8888_SkColorType;
394a6359365887048ef055196de75591311d7a015f0brianosman            break;
3959ac5b91957e59eeddebfae9630204f217c20cd4ebrianosman        case kRGBA_half_GrPixelConfig:
3969ac5b91957e59eeddebfae9630204f217c20cd4ebrianosman            ct = kRGBA_F16_SkColorType;
3979ac5b91957e59eeddebfae9630204f217c20cd4ebrianosman            break;
398bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        default:
399bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            return false;
400bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    }
401bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    if (ctOut) {
402bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        *ctOut = ct;
403bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    }
404bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    return true;
405bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com}
4068dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
40727a3aa5921b2aaf95314f955285c3cba91e4c19abrianosmanGrPixelConfig GrRenderableConfigForColorSpace(const SkColorSpace* colorSpace) {
408f3880933092c3226cd7ffd1690fe72c9c0cc376cMatt Sarett    if (!colorSpace) {
4092695eaa41fbd208dcee9e134e180c6609856f0acbrianosman        return kRGBA_8888_GrPixelConfig;
4102695eaa41fbd208dcee9e134e180c6609856f0acbrianosman    } else if (colorSpace->gammaIsLinear()) {
4112695eaa41fbd208dcee9e134e180c6609856f0acbrianosman        return kRGBA_half_GrPixelConfig;
4122695eaa41fbd208dcee9e134e180c6609856f0acbrianosman    } else if (colorSpace->gammaCloseToSRGB()) {
4132695eaa41fbd208dcee9e134e180c6609856f0acbrianosman        return kSRGBA_8888_GrPixelConfig;
4142695eaa41fbd208dcee9e134e180c6609856f0acbrianosman    } else {
4152695eaa41fbd208dcee9e134e180c6609856f0acbrianosman        SkDEBUGFAIL("No renderable config exists for color space with strange gamma");
4162695eaa41fbd208dcee9e134e180c6609856f0acbrianosman        return kUnknown_GrPixelConfig;
4172695eaa41fbd208dcee9e134e180c6609856f0acbrianosman    }
4182695eaa41fbd208dcee9e134e180c6609856f0acbrianosman}
4192695eaa41fbd208dcee9e134e180c6609856f0acbrianosman
420f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon////////////////////////////////////////////////////////////////////////////////////////////////
4218dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
422185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reedstatic inline bool blend_requires_shader(const SkBlendMode mode) {
423185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reed    return SkBlendMode::kDst != mode;
424aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon}
425aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon
426f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomonstatic inline bool skpaint_to_grpaint_impl(GrContext* context,
427f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                                           const GrColorSpaceInfo& colorSpaceInfo,
428f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                           const SkPaint& skPaint,
429f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                           const SkMatrix& viewM,
430aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon                                           std::unique_ptr<GrFragmentProcessor>* shaderProcessor,
4317d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed                                           SkBlendMode* primColorMode,
432f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                           GrPaint* grPaint) {
433f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon    grPaint->setAllowSRGBInputs(colorSpaceInfo.isGammaCorrect());
4348dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
435c68d4aa4ead74e7c89f0d638f56234f4103e19e7Brian Osman    // Convert SkPaint color to 4f format, including optional linearizing and gamut conversion.
4364cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon    GrColor4f origColor = SkColorToUnpremulGrColor4f(skPaint.getColor(), colorSpaceInfo);
437a4535a34d1b317543307df6901debfefe7132569brianosman
438f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    // Setup the initial color considering the shader, the SkPaint color, and the presence or not
439f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    // of per-vertex colors.
440aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon    std::unique_ptr<GrFragmentProcessor> shaderFP;
441185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reed    if (!primColorMode || blend_requires_shader(*primColorMode)) {
442aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon        if (shaderProcessor) {
443aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon            shaderFP = std::move(*shaderProcessor);
4444aed13889bd9085337e0d4c20df28686687b833bFlorin Malita        } else if (const auto* shader = as_SB(skPaint.getShader())) {
4454cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon            shaderFP = shader->asFragmentProcessor(SkShaderBase::AsFPArgs(
4464cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon                    context, &viewM, nullptr, skPaint.getFilterQuality(), &colorSpaceInfo));
447aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon            if (!shaderFP) {
448aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon                return false;
449aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon            }
450f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        }
4518dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    }
452775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein
453f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    // Set this in below cases if the output of the shader/paint-color/paint-alpha/primXfermode is
454f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    // a known constant value. In that case we can simply apply a color filter during this
455f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    // conversion without converting the color filter to a GrFragmentProcessor.
456f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    bool applyColorFilterToPaintColor = false;
457f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    if (shaderFP) {
458f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        if (primColorMode) {
459f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // There is a blend between the primitive color and the shader color. The shader sees
460f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // the opaque paint color. The shader's output is blended using the provided mode by
461f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // the primitive color. The blended color is then modulated by the paint's alpha.
462f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
463f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // The geometry processor will insert the primitive color to start the color chain, so
464f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // the GrPaint color will be ignored.
465f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
4664cea3b9e9d9836c926a8feb55d050993d40b4b5ebrianosman            GrColor4f shaderInput = origColor.opaque();
467aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon            shaderFP = GrFragmentProcessor::OverrideInput(std::move(shaderFP), shaderInput);
468185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reed            shaderFP = GrXfermodeFragmentProcessor::MakeFromSrcProcessor(std::move(shaderFP),
469185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reed                                                                         *primColorMode);
470185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reed
471f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // The above may return null if compose results in a pass through of the prim color.
472f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            if (shaderFP) {
4731c9686bfa5e2de3e06f1d1b9691105afb6659e85Robert Phillips                grPaint->addColorFragmentProcessor(std::move(shaderFP));
474f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            }
475f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
476a4535a34d1b317543307df6901debfefe7132569brianosman            // We can ignore origColor here - alpha is unchanged by gamma
477f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor());
478f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            if (GrColor_WHITE != paintAlpha) {
479618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman                // No gamut conversion - paintAlpha is a (linear) alpha value, splatted to all
480618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman                // color channels. It's value should be treated as the same in ANY color space.
48106ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                grPaint->addColorFragmentProcessor(GrConstColorProcessor::Make(
482618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman                    GrColor4f::FromGrColor(paintAlpha),
483618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman                    GrConstColorProcessor::kModulateRGBA_InputMode));
484f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            }
485f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        } else {
486f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // The shader's FP sees the paint unpremul color
487a4535a34d1b317543307df6901debfefe7132569brianosman            grPaint->setColor4f(origColor);
48806ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman            grPaint->addColorFragmentProcessor(std::move(shaderFP));
489f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        }
490f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    } else {
491f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        if (primColorMode) {
492f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // There is a blend between the primitive color and the paint color. The blend considers
493f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // the opaque paint color. The paint's alpha is applied to the post-blended color.
494aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon            auto processor = GrConstColorProcessor::Make(origColor.opaque(),
495aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon                                                         GrConstColorProcessor::kIgnore_InputMode);
496185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reed            processor = GrXfermodeFragmentProcessor::MakeFromSrcProcessor(std::move(processor),
497185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reed                                                                          *primColorMode);
498f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            if (processor) {
49906ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                grPaint->addColorFragmentProcessor(std::move(processor));
500f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            }
501f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
502a4535a34d1b317543307df6901debfefe7132569brianosman            grPaint->setColor4f(origColor.opaque());
503f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
504a4535a34d1b317543307df6901debfefe7132569brianosman            // We can ignore origColor here - alpha is unchanged by gamma
505f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor());
506aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon            if (GrColor_WHITE != paintAlpha) {
507618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman                // No gamut conversion - paintAlpha is a (linear) alpha value, splatted to all
508618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman                // color channels. It's value should be treated as the same in ANY color space.
50906ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                grPaint->addColorFragmentProcessor(GrConstColorProcessor::Make(
510618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman                    GrColor4f::FromGrColor(paintAlpha),
511618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman                    GrConstColorProcessor::kModulateRGBA_InputMode));
512aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon            }
513f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        } else {
514f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // No shader, no primitive color.
515a4535a34d1b317543307df6901debfefe7132569brianosman            grPaint->setColor4f(origColor.premul());
516f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            applyColorFilterToPaintColor = true;
517f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        }
518f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    }
5198dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
5208dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    SkColorFilter* colorFilter = skPaint.getColorFilter();
52149f085dddff10473b6ebf832a974288300224e60bsalomon    if (colorFilter) {
522f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        if (applyColorFilterToPaintColor) {
5238bf4e672f2c40ef313274f8b79c2c9304f9fff3fBrian Osman            // If we're in legacy mode, we *must* avoid using the 4f version of the color filter,
5248bf4e672f2c40ef313274f8b79c2c9304f9fff3fBrian Osman            // because that will combine with the linearized version of the stored color.
525f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon            if (colorSpaceInfo.isGammaCorrect()) {
5268bf4e672f2c40ef313274f8b79c2c9304f9fff3fBrian Osman                grPaint->setColor4f(GrColor4f::FromSkColor4f(
5278bf4e672f2c40ef313274f8b79c2c9304f9fff3fBrian Osman                    colorFilter->filterColor4f(origColor.toSkColor4f())).premul());
5288bf4e672f2c40ef313274f8b79c2c9304f9fff3fBrian Osman            } else {
5294cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon                grPaint->setColor4f(SkColorToPremulGrColor4fLegacy(
5304cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon                        colorFilter->filterColor(skPaint.getColor())));
5318bf4e672f2c40ef313274f8b79c2c9304f9fff3fBrian Osman            }
5328dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org        } else {
5334cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon            auto cfFP = colorFilter->asFragmentProcessor(context, colorSpaceInfo);
534e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon            if (cfFP) {
53506ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                grPaint->addColorFragmentProcessor(std::move(cfFP));
536f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            } else {
537f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                return false;
5388dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org            }
5398dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org        }
5408dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    }
541f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
542a29a956d0e27819b97592404ae1ec6cc8e7b1045Robert Phillips    SkMaskFilter* maskFilter = skPaint.getMaskFilter();
543a29a956d0e27819b97592404ae1ec6cc8e7b1045Robert Phillips    if (maskFilter) {
544a29a956d0e27819b97592404ae1ec6cc8e7b1045Robert Phillips        GrFragmentProcessor* mfFP;
545d9d84858bf0efa6fccd093aeafc29dd5f0b0356cRobert Phillips        if (maskFilter->asFragmentProcessor(&mfFP)) {
546aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon            grPaint->addCoverageFragmentProcessor(std::unique_ptr<GrFragmentProcessor>(mfFP));
547a29a956d0e27819b97592404ae1ec6cc8e7b1045Robert Phillips        }
548a29a956d0e27819b97592404ae1ec6cc8e7b1045Robert Phillips    }
549a29a956d0e27819b97592404ae1ec6cc8e7b1045Robert Phillips
5504f0379444db31421894d2fce7c85889fe5eaa01arobertphillips    // When the xfermode is null on the SkPaint (meaning kSrcOver) we need the XPFactory field on
5514f0379444db31421894d2fce7c85889fe5eaa01arobertphillips    // the GrPaint to also be null (also kSrcOver).
5524f0379444db31421894d2fce7c85889fe5eaa01arobertphillips    SkASSERT(!grPaint->getXPFactory());
553374772bd61951f01bf84fe17bf53d8867681c9aereed    if (!skPaint.isSrcOver()) {
554374772bd61951f01bf84fe17bf53d8867681c9aereed        grPaint->setXPFactory(SkBlendMode_AsXPFactory(skPaint.getBlendMode()));
5554f0379444db31421894d2fce7c85889fe5eaa01arobertphillips    }
556f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
557f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#ifndef SK_IGNORE_GPU_DITHER
558d4a70ee36717493cc071f878b16b037463e6ce9aFlorin Malita    // Conservative default, in case GrPixelConfigToColorType() fails.
559d4a70ee36717493cc071f878b16b037463e6ce9aFlorin Malita    SkColorType ct = SkColorType::kRGB_565_SkColorType;
560f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon    GrPixelConfigToColorType(colorSpaceInfo.config(), &ct);
561f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon    if (SkPaintPriv::ShouldDither(skPaint, ct) && grPaint->numColorFragmentProcessors() > 0 &&
562f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon        !colorSpaceInfo.isGammaCorrect()) {
563f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon        auto ditherFP = GrDitherEffect::Make(colorSpaceInfo.config());
5640c15ae82f0d5b5356f7650b78d749c09b3bc0403Brian Salomon        if (ditherFP) {
5650c15ae82f0d5b5356f7650b78d749c09b3bc0403Brian Salomon            grPaint->addColorFragmentProcessor(std::move(ditherFP));
5660c15ae82f0d5b5356f7650b78d749c09b3bc0403Brian Salomon        }
567f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    }
568f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#endif
569bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    return true;
5708dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org}
5718dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
572f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomonbool SkPaintToGrPaint(GrContext* context, const GrColorSpaceInfo& colorSpaceInfo,
573f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                      const SkPaint& skPaint, const SkMatrix& viewM, GrPaint* grPaint) {
574f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon    return skpaint_to_grpaint_impl(context, colorSpaceInfo, skPaint, viewM, nullptr, nullptr,
575f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                                   grPaint);
576f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon}
577f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
578f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon/** Replaces the SkShader (if any) on skPaint with the passed in GrFragmentProcessor. */
579f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomonbool SkPaintToGrPaintReplaceShader(GrContext* context,
580f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                                   const GrColorSpaceInfo& colorSpaceInfo,
581f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                   const SkPaint& skPaint,
582aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon                                   std::unique_ptr<GrFragmentProcessor> shaderFP,
583f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                   GrPaint* grPaint) {
584f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    if (!shaderFP) {
585c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon        return false;
5868dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    }
587f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon    return skpaint_to_grpaint_impl(context, colorSpaceInfo, skPaint, SkMatrix::I(), &shaderFP,
588f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                                   nullptr, grPaint);
589f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon}
590f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
591f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon/** Ignores the SkShader (if any) on skPaint. */
592f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomonbool SkPaintToGrPaintNoShader(GrContext* context,
593f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                              const GrColorSpaceInfo& colorSpaceInfo,
594f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                              const SkPaint& skPaint,
595f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                              GrPaint* grPaint) {
596f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    // Use a ptr to a nullptr to to indicate that the SkShader is ignored and not replaced.
597aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon    static std::unique_ptr<GrFragmentProcessor> kNullShaderFP(nullptr);
598aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon    static std::unique_ptr<GrFragmentProcessor>* kIgnoreShader = &kNullShaderFP;
599f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon    return skpaint_to_grpaint_impl(context, colorSpaceInfo, skPaint, SkMatrix::I(), kIgnoreShader,
600f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                                   nullptr, grPaint);
601f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon}
602f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
603f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon/** Blends the SkPaint's shader (or color if no shader) with a per-primitive color which must
6047d954ad797176afedb9262fdea4507d0fc60eb9dMike Reedbe setup as a vertex attribute using the specified SkBlendMode. */
605f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomonbool SkPaintToGrPaintWithXfermode(GrContext* context,
606f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                                  const GrColorSpaceInfo& colorSpaceInfo,
607f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                  const SkPaint& skPaint,
608f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                  const SkMatrix& viewM,
6097d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed                                  SkBlendMode primColorMode,
610f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                  GrPaint* grPaint) {
611f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon    return skpaint_to_grpaint_impl(context, colorSpaceInfo, skPaint, viewM, nullptr, &primColorMode,
612185ba21bffc2df9ddfc1e351505a7a622821df1fMike Reed                                   grPaint);
6138dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org}
6148b26b99c97473f020df4b9d4ba789e074e06ceddreed
61533a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualittbool SkPaintToGrPaintWithTexture(GrContext* context,
616f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                                 const GrColorSpaceInfo& colorSpaceInfo,
61733a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                                 const SkPaint& paint,
61833a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                                 const SkMatrix& viewM,
619aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon                                 std::unique_ptr<GrFragmentProcessor> fp,
62033a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                                 bool textureIsAlphaOnly,
62133a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                                 GrPaint* grPaint) {
622aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon    std::unique_ptr<GrFragmentProcessor> shaderFP;
62333a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt    if (textureIsAlphaOnly) {
6244aed13889bd9085337e0d4c20df28686687b833bFlorin Malita        if (const auto* shader = as_SB(paint.getShader())) {
6254cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon            shaderFP = shader->asFragmentProcessor(SkShaderBase::AsFPArgs(
6264cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon                    context, &viewM, nullptr, paint.getFilterQuality(), &colorSpaceInfo));
62733a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt            if (!shaderFP) {
62833a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                return false;
62933a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt            }
630aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon            std::unique_ptr<GrFragmentProcessor> fpSeries[] = { std::move(shaderFP), std::move(fp) };
63106ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman            shaderFP = GrFragmentProcessor::RunInSeries(fpSeries, 2);
63233a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt        } else {
633aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon            shaderFP = GrFragmentProcessor::MakeInputPremulAndMulByOutput(std::move(fp));
63433a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt        }
63533a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt    } else {
636aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon        shaderFP = GrFragmentProcessor::MulOutputByInputAlpha(std::move(fp));
63733a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt    }
63833a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt
639f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon    return SkPaintToGrPaintReplaceShader(context, colorSpaceInfo, paint, std::move(shaderFP),
640f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon                                         grPaint);
64133a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt}
64233a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt
643f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
644f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon////////////////////////////////////////////////////////////////////////////////////////////////
645f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
6462bbdcc44c63974f29f3743bb58d929601a3f65c6Brian SalomonGrSamplerState::Filter GrSkFilterQualityToGrFilterMode(SkFilterQuality paintFilterQuality,
6472bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon                                                       const SkMatrix& viewM,
6482bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon                                                       const SkMatrix& localM,
6492bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon                                                       bool* doBicubic) {
6509bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt    *doBicubic = false;
6512bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon    GrSamplerState::Filter textureFilterMode;
6529bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt    switch (paintFilterQuality) {
6539bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        case kNone_SkFilterQuality:
6542bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon            textureFilterMode = GrSamplerState::Filter::kNearest;
6559bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            break;
6569bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        case kLow_SkFilterQuality:
6572bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon            textureFilterMode = GrSamplerState::Filter::kBilerp;
6589bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            break;
6599bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        case kMedium_SkFilterQuality: {
6609bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            SkMatrix matrix;
6619bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            matrix.setConcat(viewM, localM);
6629bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            if (matrix.getMinScale() < SK_Scalar1) {
6632bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon                textureFilterMode = GrSamplerState::Filter::kMipMap;
6649bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            } else {
6659bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt                // Don't trigger MIP level generation unnecessarily.
6662bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon                textureFilterMode = GrSamplerState::Filter::kBilerp;
6679bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            }
6689bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            break;
6699bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        }
6709bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        case kHigh_SkFilterQuality: {
6719bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            SkMatrix matrix;
6729bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            matrix.setConcat(viewM, localM);
6739bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            *doBicubic = GrBicubicEffect::ShouldUseBicubic(matrix, &textureFilterMode);
6749bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            break;
6759bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        }
6769bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        default:
677e54c75f351c775201049743c506d7a508d0fef91Mike Klein            // Should be unreachable.  If not, fall back to mipmaps.
6782bbdcc44c63974f29f3743bb58d929601a3f65c6Brian Salomon            textureFilterMode = GrSamplerState::Filter::kMipMap;
6799bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            break;
6809bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt
6819bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt    }
6829bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt    return textureFilterMode;
6839bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt}
684