SkGr.cpp revision 55f2d2d57f4dd4109aa0c9dab6023373e3b928ec
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
8b5d32635345d6a974ad2ceb826c3bfb98107ab79reed
9ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "SkGr.h"
10378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel
11762286309545c8a1e4bbc05dcd1fe3085d2a1f47bsalomon#include "GrCaps.h"
12f276ac5c16d39a2b877300d760041f0291bb5ec9bsalomon#include "GrContext.h"
13045802dbb7202b52f5fd2758d725f39c156a6165bsalomon#include "GrGpuResourcePriv.h"
14c55271f2551533b37043aa2e37f754832a43073cbsalomon#include "GrImageIDTextureAdjuster.h"
1555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume#include "GrTextureParamsAdjuster.h"
1655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume#include "GrTypes.h"
17378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel#include "GrXferProcessor.h"
1843fe6185c5043247c47daa450b015e26d86728fereed#include "GrYUVProvider.h"
1943fe6185c5043247c47daa450b015e26d86728fereed
208dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org#include "SkColorFilter.h"
21ea476e1725f38688b79aadf4c5e36c10c3141927commit-bot@chromium.org#include "SkConfig8888.h"
22b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon#include "SkCanvas.h"
239c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski#include "SkData.h"
245f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt#include "SkErrorInternals.h"
258b26b99c97473f020df4b9d4ba789e074e06ceddreed#include "SkGrPixelRef.h"
2650a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org#include "SkMessageBus.h"
2755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume#include "SkMipMap.h"
2850a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org#include "SkPixelRef.h"
29692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi#include "SkResourceCache.h"
3055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume#include "SkTemplates.h"
3140a1e11ebebe81586f3fec96408fdfd4b51123d2krajcevski#include "SkTextureCompressor.h"
32692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi#include "SkYUVPlanesCache.h"
339bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt#include "effects/GrBicubicEffect.h"
34f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon#include "effects/GrConstColorProcessor.h"
35f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#include "effects/GrDitherEffect.h"
36378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel#include "effects/GrPorterDuffXferProcessor.h"
37f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon#include "effects/GrXfermodeFragmentProcessor.h"
38f267c1efe7de7a8e71404afde6cbf93c3808d267bsalomon#include "effects/GrYUVEffect.h"
399c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
408c111f783f40470e697310244426362132979ad9krajcevski#ifndef SK_IGNORE_ETC1_SUPPORT
4199ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski#  include "ktx.h"
429c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski#  include "etc1.h"
439c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski#endif
44ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
45466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomonGrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo& info) {
46466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    GrSurfaceDesc desc;
47466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    desc.fFlags = kNone_GrSurfaceFlags;
48466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    desc.fWidth = info.width();
49466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    desc.fHeight = info.height();
50466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    desc.fConfig = SkImageInfo2GrPixelConfig(info);
51466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    desc.fSampleCnt = 0;
52466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    return desc;
53466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon}
54466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon
55045802dbb7202b52f5fd2758d725f39c156a6165bsalomonvoid GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID, const SkIRect& imageBounds) {
56045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    SkASSERT(key);
57045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    SkASSERT(imageID);
58045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    SkASSERT(!imageBounds.isEmpty());
59045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    static const GrUniqueKey::Domain kImageIDDomain = GrUniqueKey::GenerateDomain();
60045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    GrUniqueKey::Builder builder(key, kImageIDDomain, 5);
61466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    builder[0] = imageID;
62045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    builder[1] = imageBounds.fLeft;
63045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    builder[2] = imageBounds.fTop;
64045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    builder[3] = imageBounds.fRight;
65045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    builder[4] = imageBounds.fBottom;
66466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon}
67466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon
68466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomonGrPixelConfig GrIsCompressedTextureDataSupported(GrContext* ctx, SkData* data,
69466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon                                                 int expectedW, int expectedH,
70466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon                                                 const void** outStartOfDataToUpload) {
71466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    *outStartOfDataToUpload = nullptr;
72466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon#ifndef SK_IGNORE_ETC1_SUPPORT
73466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    if (!ctx->caps()->isConfigTexturable(kETC1_GrPixelConfig)) {
74466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon        return kUnknown_GrPixelConfig;
75466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    }
76466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon
77466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    const uint8_t* bytes = data->bytes();
78466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    if (data->size() > ETC_PKM_HEADER_SIZE && etc1_pkm_is_valid(bytes)) {
79466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon        // Does the data match the dimensions of the bitmap? If not,
80466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon        // then we don't know how to scale the image to match it...
81466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon        if (etc1_pkm_get_width(bytes) != (unsigned)expectedW ||
82466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon            etc1_pkm_get_height(bytes) != (unsigned)expectedH)
83466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon        {
84466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon            return kUnknown_GrPixelConfig;
85466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon        }
86466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon
87466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon        *outStartOfDataToUpload = bytes + ETC_PKM_HEADER_SIZE;
88466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon        return kETC1_GrPixelConfig;
89466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    } else if (SkKTXFile::is_ktx(bytes)) {
90466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon        SkKTXFile ktx(data);
91466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon
92466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon        // Is it actually an ETC1 texture?
93466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon        if (!ktx.isCompressedFormat(SkTextureCompressor::kETC1_Format)) {
94466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon            return kUnknown_GrPixelConfig;
95466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon        }
96466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon
97466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon        // Does the data match the dimensions of the bitmap? If not,
98466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon        // then we don't know how to scale the image to match it...
99466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon        if (ktx.width() != expectedW || ktx.height() != expectedH) {
100466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon            return kUnknown_GrPixelConfig;
101466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon        }
102466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon
103466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon        *outStartOfDataToUpload = ktx.pixelData();
104466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon        return kETC1_GrPixelConfig;
105466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    }
106466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon#endif
107466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    return kUnknown_GrPixelConfig;
108466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon}
109466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon
110045802dbb7202b52f5fd2758d725f39c156a6165bsalomon//////////////////////////////////////////////////////////////////////////////
111bc0bcc08b390e430f66710ddfbc47da39ab841d9Brian Salomon
112045802dbb7202b52f5fd2758d725f39c156a6165bsalomon/**
113045802dbb7202b52f5fd2758d725f39c156a6165bsalomon * Fill out buffer with the compressed format Ganesh expects from a colortable
114045802dbb7202b52f5fd2758d725f39c156a6165bsalomon * based bitmap. [palette (colortable) + indices].
115045802dbb7202b52f5fd2758d725f39c156a6165bsalomon *
116045802dbb7202b52f5fd2758d725f39c156a6165bsalomon * At the moment Ganesh only supports 8bit version. If Ganesh allowed we others
117045802dbb7202b52f5fd2758d725f39c156a6165bsalomon * we could detect that the colortable.count is <= 16, and then repack the
118045802dbb7202b52f5fd2758d725f39c156a6165bsalomon * indices as nibbles to save RAM, but it would take more time (i.e. a lot
119045802dbb7202b52f5fd2758d725f39c156a6165bsalomon * slower than memcpy), so skipping that for now.
120045802dbb7202b52f5fd2758d725f39c156a6165bsalomon *
121045802dbb7202b52f5fd2758d725f39c156a6165bsalomon * Ganesh wants a full 256 palette entry, even though Skia's ctable is only as big
122045802dbb7202b52f5fd2758d725f39c156a6165bsalomon * as the colortable.count says it is.
123ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */
124e79a2dab91a90e26b13bc1ec9b8c6264a1ab22e4bsalomonstatic void build_index8_data(void* buffer, const SkBitmap& bitmap) {
1250689d7b12e7c427a077b003d3d8ae759d86f798freed    SkASSERT(kIndex_8_SkColorType == bitmap.colorType());
1265782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
1277f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com    SkAutoLockPixels alp(bitmap);
128ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (!bitmap.readyToDraw()) {
1290c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com        SkDEBUGFAIL("bitmap not ready to draw!");
130ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return;
131ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
132ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
133ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    SkColorTable* ctable = bitmap.getColorTable();
134ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    char* dst = (char*)buffer;
1355782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
1367111d463cee893a479280c7af41757e709e33ef5reed@google.com    const int count = ctable->count();
1377111d463cee893a479280c7af41757e709e33ef5reed@google.com
1387111d463cee893a479280c7af41757e709e33ef5reed@google.com    SkDstPixelInfo dstPI;
1397111d463cee893a479280c7af41757e709e33ef5reed@google.com    dstPI.fColorType = kRGBA_8888_SkColorType;
1407111d463cee893a479280c7af41757e709e33ef5reed@google.com    dstPI.fAlphaType = kPremul_SkAlphaType;
1417111d463cee893a479280c7af41757e709e33ef5reed@google.com    dstPI.fPixels = buffer;
1427111d463cee893a479280c7af41757e709e33ef5reed@google.com    dstPI.fRowBytes = count * sizeof(SkPMColor);
1437111d463cee893a479280c7af41757e709e33ef5reed@google.com
1447111d463cee893a479280c7af41757e709e33ef5reed@google.com    SkSrcPixelInfo srcPI;
14528fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org    srcPI.fColorType = kN32_SkColorType;
1467111d463cee893a479280c7af41757e709e33ef5reed@google.com    srcPI.fAlphaType = kPremul_SkAlphaType;
147775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein    srcPI.fPixels = ctable->readColors();
1487111d463cee893a479280c7af41757e709e33ef5reed@google.com    srcPI.fRowBytes = count * sizeof(SkPMColor);
1497111d463cee893a479280c7af41757e709e33ef5reed@google.com
1507111d463cee893a479280c7af41757e709e33ef5reed@google.com    srcPI.convertPixelsTo(&dstPI, count, 1);
1517111d463cee893a479280c7af41757e709e33ef5reed@google.com
152ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    // always skip a full 256 number of entries, even if we memcpy'd fewer
153d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon    dst += 256 * sizeof(GrColor);
154ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
1550ba4bf427acbd7707d04192a98c77ef194a0f25ascroggo@google.com    if ((unsigned)bitmap.width() == bitmap.rowBytes()) {
156ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        memcpy(dst, bitmap.getPixels(), bitmap.getSize());
157ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    } else {
158ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        // need to trim off the extra bytes per row
159ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        size_t width = bitmap.width();
160ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        size_t rowBytes = bitmap.rowBytes();
161ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        const char* src = (const char*)bitmap.getPixels();
162ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        for (int y = 0; y < bitmap.height(); y++) {
163ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            memcpy(dst, src, width);
164ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            src += rowBytes;
165ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            dst += width;
166ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
167ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
168ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
169ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
170045802dbb7202b52f5fd2758d725f39c156a6165bsalomon/**
17143fe6185c5043247c47daa450b015e26d86728fereed *  Once we have made SkImages handle all lazy/deferred/generated content, the YUV apis will
17243fe6185c5043247c47daa450b015e26d86728fereed *  be gone from SkPixelRef, and we can remove this subclass entirely.
17343fe6185c5043247c47daa450b015e26d86728fereed */
17443fe6185c5043247c47daa450b015e26d86728fereedclass PixelRef_GrYUVProvider : public GrYUVProvider {
17543fe6185c5043247c47daa450b015e26d86728fereed    SkPixelRef* fPR;
176692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi
17743fe6185c5043247c47daa450b015e26d86728fereedpublic:
17843fe6185c5043247c47daa450b015e26d86728fereed    PixelRef_GrYUVProvider(SkPixelRef* pr) : fPR(pr) {}
179abaef86f2b37d8a939506a2076da07f6db456951rileya
18043fe6185c5043247c47daa450b015e26d86728fereed    uint32_t onGetID() override { return fPR->getGenerationID(); }
18143fe6185c5043247c47daa450b015e26d86728fereed    bool onGetYUVSizes(SkISize sizes[3]) override {
18243fe6185c5043247c47daa450b015e26d86728fereed        return fPR->getYUV8Planes(sizes, nullptr, nullptr, nullptr);
183518d83dbc1c899e316e8c896af5defb58b83120fsugoi    }
18443fe6185c5043247c47daa450b015e26d86728fereed    bool onGetYUVPlanes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
18543fe6185c5043247c47daa450b015e26d86728fereed                        SkYUVColorSpace* space) override {
18643fe6185c5043247c47daa450b015e26d86728fereed        return fPR->getYUV8Planes(sizes, planes, rowBytes, space);
187518d83dbc1c899e316e8c896af5defb58b83120fsugoi    }
18843fe6185c5043247c47daa450b015e26d86728fereed};
189518d83dbc1c899e316e8c896af5defb58b83120fsugoi
190045802dbb7202b52f5fd2758d725f39c156a6165bsalomonstatic GrTexture* create_texture_from_yuv(GrContext* ctx, const SkBitmap& bm,
191045802dbb7202b52f5fd2758d725f39c156a6165bsalomon                                          const GrSurfaceDesc& desc) {
19243fe6185c5043247c47daa450b015e26d86728fereed    // Subsets are not supported, the whole pixelRef is loaded when using YUV decoding
19343fe6185c5043247c47daa450b015e26d86728fereed    SkPixelRef* pixelRef = bm.pixelRef();
19443fe6185c5043247c47daa450b015e26d86728fereed    if ((nullptr == pixelRef) ||
195045802dbb7202b52f5fd2758d725f39c156a6165bsalomon        (pixelRef->info().width() != bm.info().width()) ||
19643fe6185c5043247c47daa450b015e26d86728fereed        (pixelRef->info().height() != bm.info().height())) {
19796fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
198518d83dbc1c899e316e8c896af5defb58b83120fsugoi    }
199518d83dbc1c899e316e8c896af5defb58b83120fsugoi
20043fe6185c5043247c47daa450b015e26d86728fereed    PixelRef_GrYUVProvider provider(pixelRef);
201ea4615034498aca2f9ca1753fb9a1ef10508d8ccrobertphillips
202045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    return provider.refAsTexture(ctx, desc, !bm.isVolatile());
203518d83dbc1c899e316e8c896af5defb58b83120fsugoi}
204518d83dbc1c899e316e8c896af5defb58b83120fsugoi
205045802dbb7202b52f5fd2758d725f39c156a6165bsalomonstatic GrTexture* load_etc1_texture(GrContext* ctx, const SkBitmap &bm, GrSurfaceDesc desc) {
206466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    SkAutoTUnref<SkData> data(bm.pixelRef()->refEncodedData());
207466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    if (!data) {
208466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon        return nullptr;
209466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    }
210466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon
211466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    const void* startOfTexData;
212466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    desc.fConfig = GrIsCompressedTextureDataSupported(ctx, data, bm.width(), bm.height(),
213466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon                                                      &startOfTexData);
214466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    if (kUnknown_GrPixelConfig == desc.fConfig) {
215466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon        return nullptr;
216466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon    }
217466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon
2185ec26ae9bfca635ccc98283aad5deda11519d826bsalomon    return ctx->textureProvider()->createTexture(desc, SkBudgeted::kYes, startOfTexData, 0);
219466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon}
220466c2c48b9f78b974becbc6834970b6f6cdfa5f5bsalomon
221045802dbb7202b52f5fd2758d725f39c156a6165bsalomonGrTexture* GrUploadBitmapToTexture(GrContext* ctx, const SkBitmap& bmp) {
222045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    SkASSERT(!bmp.getTexture());
223045802dbb7202b52f5fd2758d725f39c156a6165bsalomon
224045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    SkBitmap tmpBitmap;
225045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    const SkBitmap* bitmap = &bmp;
2265782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
2273322a8137d12255258a937897389ea90ca1ee6fareed    GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(bitmap->info());
228762286309545c8a1e4bbc05dcd1fe3085d2a1f47bsalomon    const GrCaps* caps = ctx->caps();
2295782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
2300689d7b12e7c427a077b003d3d8ae759d86f798freed    if (kIndex_8_SkColorType == bitmap->colorType()) {
231762286309545c8a1e4bbc05dcd1fe3085d2a1f47bsalomon        if (caps->isConfigTexturable(kIndex_8_GrPixelConfig)) {
232d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon            size_t imageSize = GrCompressedFormatDataSize(kIndex_8_GrPixelConfig,
233d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon                                                          bitmap->width(), bitmap->height());
234d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon            SkAutoMalloc storage(imageSize);
235045802dbb7202b52f5fd2758d725f39c156a6165bsalomon            build_index8_data(storage.get(), bmp);
236ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
237ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            // our compressed data will be trimmed, so pass width() for its
238ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            // "rowBytes", since they are the same now.
2395ec26ae9bfca635ccc98283aad5deda11519d826bsalomon            return ctx->textureProvider()->createTexture(desc, SkBudgeted::kYes, storage.get(),
240045802dbb7202b52f5fd2758d725f39c156a6165bsalomon                                                         bitmap->width());
241ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        } else {
242045802dbb7202b52f5fd2758d725f39c156a6165bsalomon            bmp.copyTo(&tmpBitmap, kN32_SkColorType);
243ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            // now bitmap points to our temp, which has been promoted to 32bits
244ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            bitmap = &tmpBitmap;
2453adcc3403377c0b9a7afde6db8e0432325413a10commit-bot@chromium.org            desc.fConfig = SkImageInfo2GrPixelConfig(bitmap->info());
246ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
24743fe6185c5043247c47daa450b015e26d86728fereed    } else if (!bitmap->readyToDraw()) {
24843fe6185c5043247c47daa450b015e26d86728fereed        // If the bitmap had compressed data and was then uncompressed, it'll still return
24943fe6185c5043247c47daa450b015e26d86728fereed        // compressed data on 'refEncodedData' and upload it. Probably not good, since if
25043fe6185c5043247c47daa450b015e26d86728fereed        // the bitmap has available pixels, then they might not be what the decompressed
25143fe6185c5043247c47daa450b015e26d86728fereed        // data is.
252045802dbb7202b52f5fd2758d725f39c156a6165bsalomon
253045802dbb7202b52f5fd2758d725f39c156a6165bsalomon        // Really?? We aren't doing this with YUV.
254045802dbb7202b52f5fd2758d725f39c156a6165bsalomon
255045802dbb7202b52f5fd2758d725f39c156a6165bsalomon        GrTexture *texture = load_etc1_texture(ctx, *bitmap, desc);
25649f085dddff10473b6ebf832a974288300224e60bsalomon        if (texture) {
2579c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski            return texture;
2589c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski        }
2595782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    }
260ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
261045802dbb7202b52f5fd2758d725f39c156a6165bsalomon    GrTexture *texture = create_texture_from_yuv(ctx, *bitmap, desc);
262d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon    if (texture) {
263d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon        return texture;
264518d83dbc1c899e316e8c896af5defb58b83120fsugoi    }
265d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon
2667f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com    SkAutoLockPixels alp(*bitmap);
2677f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com    if (!bitmap->readyToDraw()) {
26896fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
2697f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com    }
27050a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
2715ec26ae9bfca635ccc98283aad5deda11519d826bsalomon    return ctx->textureProvider()->createTexture(desc, SkBudgeted::kYes, bitmap->getPixels(),
272045802dbb7202b52f5fd2758d725f39c156a6165bsalomon                                                 bitmap->rowBytes());
27337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon}
27437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
275b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon
276045802dbb7202b52f5fd2758d725f39c156a6165bsalomon////////////////////////////////////////////////////////////////////////////////
277045802dbb7202b52f5fd2758d725f39c156a6165bsalomon
278c55271f2551533b37043aa2e37f754832a43073cbsalomonvoid GrInstallBitmapUniqueKeyInvalidator(const GrUniqueKey& key, SkPixelRef* pixelRef) {
27989fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon    class Invalidator : public SkPixelRef::GenIDChangeListener {
28089fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon    public:
28189fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon        explicit Invalidator(const GrUniqueKey& key) : fMsg(key) {}
28289fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon    private:
28389fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon        GrUniqueKeyInvalidatedMessage fMsg;
28489fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon
28589fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon        void onChange() override { SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(fMsg); }
28689fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon    };
28789fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon
28889fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon    pixelRef->addGenIDChangeListener(new Invalidator(key));
28989fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon}
29089fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon
29155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblumeGrTexture* GrGenerateMipMapsAndUploadToTexture(GrContext* ctx, const SkBitmap& bitmap)
29255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume{
29355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(bitmap.info());
29455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    if (kIndex_8_SkColorType != bitmap.colorType() && !bitmap.readyToDraw()) {
29555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        GrTexture* texture = load_etc1_texture(ctx, bitmap, desc);
29655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        if (texture) {
29755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume            return texture;
29855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        }
29955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    }
30055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
30155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    GrTexture* texture = create_texture_from_yuv(ctx, bitmap, desc);
30255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    if (texture) {
30355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        return texture;
30455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    }
30555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
30655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    SkASSERT(sizeof(int) <= sizeof(uint32_t));
30755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    if (bitmap.width() < 0 || bitmap.height() < 0) {
30855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        return nullptr;
30955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    }
31055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
31155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    SkAutoPixmapUnlock srcUnlocker;
31255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    if (!bitmap.requestLock(&srcUnlocker)) {
31355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        return nullptr;
31455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    }
31555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    const SkPixmap& pixmap = srcUnlocker.pixmap();
31655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    // Try to catch where we might have returned nullptr for src crbug.com/492818
31755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    if (nullptr == pixmap.addr()) {
31855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        sk_throw();
31955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    }
32055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
32155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    SkAutoTDelete<SkMipMap> mipmaps(SkMipMap::Build(pixmap, nullptr));
32255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    if (!mipmaps) {
32355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        return nullptr;
32455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    }
32555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
32655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    const int mipLevelCount = mipmaps->countLevels() + 1;
32755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    if (mipLevelCount < 1) {
32855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        return nullptr;
32955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    }
33055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
33155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    const bool isMipMapped = mipLevelCount > 1;
33255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    desc.fIsMipMapped = isMipMapped;
33355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
33455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    SkAutoTDeleteArray<GrMipLevel> texels(new GrMipLevel[mipLevelCount]);
33555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
33655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    texels[0].fPixels = pixmap.addr();
33755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    texels[0].fRowBytes = pixmap.rowBytes();
33855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
33955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    for (int i = 1; i < mipLevelCount; ++i) {
34055f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        SkMipMap::Level generatedMipLevel;
34155f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        mipmaps->getLevel(i - 1, &generatedMipLevel);
34255f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        texels[i].fPixels = generatedMipLevel.fPixmap.addr();
34355f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume        texels[i].fRowBytes = generatedMipLevel.fPixmap.rowBytes();
34455f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    }
34555f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
34655f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume    return ctx->textureProvider()->createMipMappedTexture(desc, SkBudgeted::kYes, texels.get(),
34755f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume                                                          mipLevelCount);
34855f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume}
34955f2d2d57f4dd4109aa0c9dab6023373e3b928eccblume
350b5d32635345d6a974ad2ceb826c3bfb98107ab79reedGrTexture* GrRefCachedBitmapTexture(GrContext* ctx, const SkBitmap& bitmap,
351afa95e270c64c9777647b6c58b796750ced57c39bsalomon                                    const GrTextureParams& params) {
35289fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon    if (bitmap.getTexture()) {
353c55271f2551533b37043aa2e37f754832a43073cbsalomon        return GrBitmapTextureAdjuster(&bitmap).refTextureSafeForParams(params, nullptr);
35489fe56bb98de55c7bd2b547c875b74a98bd5a1cabsalomon    }
355b1b019985bee2bcbf35c2fbb4281904d0d3465bbbsalomon    return GrBitmapTextureMaker(ctx, bitmap).refTextureForParams(params);
35637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon}
3578f34372f7e97482e5e61ab298b7edaa008ba2f4creed
35824f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com///////////////////////////////////////////////////////////////////////////////
35924f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com
36015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org// alphatype is ignore for now, but if GrPixelConfig is expanded to encompass
36115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org// alpha info, that will be considered.
362fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverthGrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType, SkColorProfileType pt) {
36315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    switch (ct) {
36415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        case kUnknown_SkColorType:
36515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            return kUnknown_GrPixelConfig;
36615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        case kAlpha_8_SkColorType:
36715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            return kAlpha_8_GrPixelConfig;
36815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        case kRGB_565_SkColorType:
36915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            return kRGB_565_GrPixelConfig;
37015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        case kARGB_4444_SkColorType:
37115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            return kRGBA_4444_GrPixelConfig;
37215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        case kRGBA_8888_SkColorType:
37399babf2848095febfc5f98b47f3a6c232411147fjvanverth            //if (kSRGB_SkColorProfileType == pt) {
37499babf2848095febfc5f98b47f3a6c232411147fjvanverth            //    return kSRGBA_8888_GrPixelConfig;
37599babf2848095febfc5f98b47f3a6c232411147fjvanverth            //}
37615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            return kRGBA_8888_GrPixelConfig;
37715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        case kBGRA_8888_SkColorType:
37815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            return kBGRA_8888_GrPixelConfig;
37915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        case kIndex_8_SkColorType:
38015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            return kIndex_8_GrPixelConfig;
3810c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed        case kGray_8_SkColorType:
3820c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed            return kAlpha_8_GrPixelConfig; // TODO: gray8 support on gpu
3833601f280dc400cb75167393b0a2b6670b5f25ea4reed        case kRGBA_F16_SkColorType:
3843601f280dc400cb75167393b0a2b6670b5f25ea4reed            return kRGBA_half_GrPixelConfig;
38515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    }
38615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    SkASSERT(0);    // shouldn't get here
38715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    return kUnknown_GrPixelConfig;
38815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org}
38915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org
390fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverthbool GrPixelConfig2ColorAndProfileType(GrPixelConfig config, SkColorType* ctOut,
391fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth                                       SkColorProfileType* ptOut) {
392bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    SkColorType ct;
393fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth    SkColorProfileType pt = kLinear_SkColorProfileType;
394bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    switch (config) {
395bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kAlpha_8_GrPixelConfig:
396bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kAlpha_8_SkColorType;
397bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
398bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kIndex_8_GrPixelConfig:
399bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kIndex_8_SkColorType;
400bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
401bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kRGB_565_GrPixelConfig:
402bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kRGB_565_SkColorType;
403bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
404bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kRGBA_4444_GrPixelConfig:
405bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kARGB_4444_SkColorType;
406bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
407bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kRGBA_8888_GrPixelConfig:
408bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kRGBA_8888_SkColorType;
409bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
410bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kBGRA_8888_GrPixelConfig:
411bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kBGRA_8888_SkColorType;
412bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
413fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth        case kSRGBA_8888_GrPixelConfig:
414fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth            ct = kRGBA_8888_SkColorType;
415fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth            pt = kSRGB_SkColorProfileType;
416fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth            break;
417bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        default:
418bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            return false;
419bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    }
420bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    if (ctOut) {
421bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        *ctOut = ct;
422bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    }
423fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth    if (ptOut) {
424fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth        *ptOut = pt;
425fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth    }
426bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    return true;
427bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com}
4288dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
429f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon////////////////////////////////////////////////////////////////////////////////////////////////
4308dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
431aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomonstatic inline bool blend_requires_shader(const SkXfermode::Mode mode, bool primitiveIsSrc) {
432aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon    if (primitiveIsSrc) {
433aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon        return SkXfermode::kSrc_Mode != mode;
434aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon    } else {
435aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon        return SkXfermode::kDst_Mode != mode;
436aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon    }
437aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon}
438aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon
439f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomonstatic inline bool skpaint_to_grpaint_impl(GrContext* context,
440f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                           const SkPaint& skPaint,
441f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                           const SkMatrix& viewM,
442f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                           const GrFragmentProcessor** shaderProcessor,
443f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                           SkXfermode::Mode* primColorMode,
444f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                           bool primitiveIsSrc,
445f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                           GrPaint* grPaint) {
4468dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    grPaint->setAntiAlias(skPaint.isAntiAlias());
4478dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
448f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    // Setup the initial color considering the shader, the SkPaint color, and the presence or not
449f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    // of per-vertex colors.
450f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    SkAutoTUnref<const GrFragmentProcessor> aufp;
451aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon    const GrFragmentProcessor* shaderFP = nullptr;
452aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon    if (!primColorMode || blend_requires_shader(*primColorMode, primitiveIsSrc)) {
453aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon        if (shaderProcessor) {
454aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon            shaderFP = *shaderProcessor;
455aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon        } else if (const SkShader* shader = skPaint.getShader()) {
456aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon            aufp.reset(shader->asFragmentProcessor(context, viewM, nullptr,
4574a339529612a43871d021877e58698e067d6c4cdbsalomon                                                   skPaint.getFilterQuality()));
458aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon            shaderFP = aufp;
459aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon            if (!shaderFP) {
460aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon                return false;
461aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon            }
462f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        }
4638dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    }
464775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein
465f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    // Set this in below cases if the output of the shader/paint-color/paint-alpha/primXfermode is
466f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    // a known constant value. In that case we can simply apply a color filter during this
467f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    // conversion without converting the color filter to a GrFragmentProcessor.
468f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    bool applyColorFilterToPaintColor = false;
469f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    if (shaderFP) {
470f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        if (primColorMode) {
471f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // There is a blend between the primitive color and the shader color. The shader sees
472f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // the opaque paint color. The shader's output is blended using the provided mode by
473f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // the primitive color. The blended color is then modulated by the paint's alpha.
474f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
475f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // The geometry processor will insert the primitive color to start the color chain, so
476f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // the GrPaint color will be ignored.
477f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
478f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            GrColor shaderInput = SkColorToOpaqueGrColor(skPaint.getColor());
479f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
480f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            shaderFP = GrFragmentProcessor::OverrideInput(shaderFP, shaderInput);
481f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            aufp.reset(shaderFP);
482f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
483f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            if (primitiveIsSrc) {
484f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                shaderFP = GrXfermodeFragmentProcessor::CreateFromDstProcessor(shaderFP,
485f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                                                               *primColorMode);
486f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            } else {
487f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                shaderFP = GrXfermodeFragmentProcessor::CreateFromSrcProcessor(shaderFP,
488f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                                                               *primColorMode);
489f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            }
490f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            aufp.reset(shaderFP);
491f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // The above may return null if compose results in a pass through of the prim color.
492f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            if (shaderFP) {
493f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                grPaint->addColorFragmentProcessor(shaderFP);
494f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            }
495f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
496f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor());
497f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            if (GrColor_WHITE != paintAlpha) {
498f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                grPaint->addColorFragmentProcessor(GrConstColorProcessor::Create(
499f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                    paintAlpha, GrConstColorProcessor::kModulateRGBA_InputMode))->unref();
500f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            }
501f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        } else {
502f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // The shader's FP sees the paint unpremul color
503f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            grPaint->setColor(SkColorToUnpremulGrColor(skPaint.getColor()));
504f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            grPaint->addColorFragmentProcessor(shaderFP);
505f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        }
506f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    } else {
507f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        if (primColorMode) {
508f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // There is a blend between the primitive color and the paint color. The blend considers
509f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // the opaque paint color. The paint's alpha is applied to the post-blended color.
510f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            SkAutoTUnref<const GrFragmentProcessor> processor(
511f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                GrConstColorProcessor::Create(SkColorToOpaqueGrColor(skPaint.getColor()),
512f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                              GrConstColorProcessor::kIgnore_InputMode));
513f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            if (primitiveIsSrc) {
514f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                processor.reset(GrXfermodeFragmentProcessor::CreateFromDstProcessor(processor,
515f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                                                                *primColorMode));
516f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            } else {
517f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                processor.reset(GrXfermodeFragmentProcessor::CreateFromSrcProcessor(processor,
518f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                                                                *primColorMode));
519f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
520f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            }
521f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            if (processor) {
522f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                grPaint->addColorFragmentProcessor(processor);
523f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            }
524f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
525aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon            grPaint->setColor(SkColorToOpaqueGrColor(skPaint.getColor()));
526f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
527f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor());
528aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon            if (GrColor_WHITE != paintAlpha) {
529aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon                grPaint->addColorFragmentProcessor(GrConstColorProcessor::Create(
530aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon                    paintAlpha, GrConstColorProcessor::kModulateRGBA_InputMode))->unref();
531aa48d36397f8464dafd38c3f42fbdfb1419e8778bsalomon            }
532f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        } else {
533f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            // No shader, no primitive color.
534f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            grPaint->setColor(SkColorToPremulGrColor(skPaint.getColor()));
535f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            applyColorFilterToPaintColor = true;
536f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        }
537f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    }
5388dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
5398dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    SkColorFilter* colorFilter = skPaint.getColorFilter();
54049f085dddff10473b6ebf832a974288300224e60bsalomon    if (colorFilter) {
541f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon        if (applyColorFilterToPaintColor) {
542f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            grPaint->setColor(SkColorToPremulGrColor(colorFilter->filterColor(skPaint.getColor())));
5438dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org        } else {
544e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon            SkAutoTUnref<const GrFragmentProcessor> cfFP(
5454a339529612a43871d021877e58698e067d6c4cdbsalomon                colorFilter->asFragmentProcessor(context));
546e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon            if (cfFP) {
547e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon                grPaint->addColorFragmentProcessor(cfFP);
548f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon            } else {
549f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                return false;
5508dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org            }
5518dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org        }
5528dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    }
553f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
5544f0379444db31421894d2fce7c85889fe5eaa01arobertphillips    // When the xfermode is null on the SkPaint (meaning kSrcOver) we need the XPFactory field on
5554f0379444db31421894d2fce7c85889fe5eaa01arobertphillips    // the GrPaint to also be null (also kSrcOver).
5564f0379444db31421894d2fce7c85889fe5eaa01arobertphillips    SkASSERT(!grPaint->getXPFactory());
5574f0379444db31421894d2fce7c85889fe5eaa01arobertphillips    SkXfermode* xfermode = skPaint.getXfermode();
5584f0379444db31421894d2fce7c85889fe5eaa01arobertphillips    if (xfermode) {
5594f0379444db31421894d2fce7c85889fe5eaa01arobertphillips        // SafeUnref in case a new xfermode is added that returns null.
5604f0379444db31421894d2fce7c85889fe5eaa01arobertphillips        // In such cases we will fall back to kSrcOver_Mode.
5614f0379444db31421894d2fce7c85889fe5eaa01arobertphillips        SkSafeUnref(grPaint->setXPFactory(xfermode->asXPFactory()));
5624f0379444db31421894d2fce7c85889fe5eaa01arobertphillips    }
563f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
564f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#ifndef SK_IGNORE_GPU_DITHER
565ac856c97acc84dcb54d9cdb068ec8a02b8869647bsalomon    if (skPaint.isDither() && grPaint->numColorFragmentProcessors() > 0) {
566aca31fea8ca620bfdb2887641b7ba56e401a72d7bsalomon        grPaint->addColorFragmentProcessor(GrDitherEffect::Create())->unref();
567f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    }
568f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#endif
569bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    return true;
5708dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org}
5718dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
572f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomonbool SkPaintToGrPaint(GrContext* context, const SkPaint& skPaint, const SkMatrix& viewM,
573f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                      GrPaint* grPaint) {
574f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    return skpaint_to_grpaint_impl(context, skPaint, viewM, nullptr, nullptr, false, grPaint);
575f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon}
576f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
577f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon/** Replaces the SkShader (if any) on skPaint with the passed in GrFragmentProcessor. */
578f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomonbool SkPaintToGrPaintReplaceShader(GrContext* context,
579f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                   const SkPaint& skPaint,
580f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                   const GrFragmentProcessor* shaderFP,
581f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                   GrPaint* grPaint) {
582f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    if (!shaderFP) {
583c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon        return false;
5848dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    }
585f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    return skpaint_to_grpaint_impl(context, skPaint, SkMatrix::I(), &shaderFP, nullptr, false,
586f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                   grPaint);
587f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon}
588f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
589f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon/** Ignores the SkShader (if any) on skPaint. */
590f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomonbool SkPaintToGrPaintNoShader(GrContext* context,
591f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                              const SkPaint& skPaint,
592f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                              GrPaint* grPaint) {
593f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    // Use a ptr to a nullptr to to indicate that the SkShader is ignored and not replaced.
594f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    static const GrFragmentProcessor* kNullShaderFP = nullptr;
595f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    static const GrFragmentProcessor** kIgnoreShader = &kNullShaderFP;
596f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    return skpaint_to_grpaint_impl(context, skPaint, SkMatrix::I(), kIgnoreShader, nullptr, false,
597f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                   grPaint);
598f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon}
599f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
600f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon/** Blends the SkPaint's shader (or color if no shader) with a per-primitive color which must
601f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomonbe setup as a vertex attribute using the specified SkXfermode::Mode. */
602f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomonbool SkPaintToGrPaintWithXfermode(GrContext* context,
603f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                  const SkPaint& skPaint,
604f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                  const SkMatrix& viewM,
605f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                  SkXfermode::Mode primColorMode,
606f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                  bool primitiveIsSrc,
607f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                  GrPaint* grPaint) {
608f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon    return skpaint_to_grpaint_impl(context, skPaint, viewM, nullptr, &primColorMode, primitiveIsSrc,
609f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon                                   grPaint);
6108dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org}
6118b26b99c97473f020df4b9d4ba789e074e06ceddreed
61233a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualittbool SkPaintToGrPaintWithTexture(GrContext* context,
61333a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                                 const SkPaint& paint,
61433a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                                 const SkMatrix& viewM,
61533a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                                 const GrFragmentProcessor* fp,
61633a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                                 bool textureIsAlphaOnly,
61733a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                                 GrPaint* grPaint) {
61833a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt    SkAutoTUnref<const GrFragmentProcessor> shaderFP;
61933a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt    if (textureIsAlphaOnly) {
62033a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt        if (const SkShader* shader = paint.getShader()) {
62133a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt            shaderFP.reset(shader->asFragmentProcessor(context,
62233a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                                                       viewM,
62333a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                                                       nullptr,
62433a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                                                       paint.getFilterQuality()));
62533a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt            if (!shaderFP) {
62633a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                return false;
62733a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt            }
62833a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt            const GrFragmentProcessor* fpSeries[] = { shaderFP.get(), fp };
62933a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt            shaderFP.reset(GrFragmentProcessor::RunInSeries(fpSeries, 2));
63033a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt        } else {
63133a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt            shaderFP.reset(GrFragmentProcessor::MulOutputByInputUnpremulColor(fp));
63233a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt        }
63333a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt    } else {
63433a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt        shaderFP.reset(GrFragmentProcessor::MulOutputByInputAlpha(fp));
63533a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt    }
63633a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt
63733a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt    return SkPaintToGrPaintReplaceShader(context, paint, shaderFP.get(), grPaint);
63833a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt}
63933a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt
640f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
641f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon////////////////////////////////////////////////////////////////////////////////////////////////
642f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon
6438b26b99c97473f020df4b9d4ba789e074e06ceddreedSkImageInfo GrMakeInfoFromTexture(GrTexture* tex, int w, int h, bool isOpaque) {
6448b26b99c97473f020df4b9d4ba789e074e06ceddreed#ifdef SK_DEBUG
6458b26b99c97473f020df4b9d4ba789e074e06ceddreed    const GrSurfaceDesc& desc = tex->desc();
6468b26b99c97473f020df4b9d4ba789e074e06ceddreed    SkASSERT(w <= desc.fWidth);
6478b26b99c97473f020df4b9d4ba789e074e06ceddreed    SkASSERT(h <= desc.fHeight);
6488b26b99c97473f020df4b9d4ba789e074e06ceddreed#endif
6498b26b99c97473f020df4b9d4ba789e074e06ceddreed    const GrPixelConfig config = tex->config();
6508b26b99c97473f020df4b9d4ba789e074e06ceddreed    SkColorType ct;
6518b26b99c97473f020df4b9d4ba789e074e06ceddreed    SkAlphaType at = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
65296fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (!GrPixelConfig2ColorAndProfileType(config, &ct, nullptr)) {
6538b26b99c97473f020df4b9d4ba789e074e06ceddreed        ct = kUnknown_SkColorType;
6548b26b99c97473f020df4b9d4ba789e074e06ceddreed    }
6558b26b99c97473f020df4b9d4ba789e074e06ceddreed    return SkImageInfo::Make(w, h, ct, at);
6568b26b99c97473f020df4b9d4ba789e074e06ceddreed}
6578b26b99c97473f020df4b9d4ba789e074e06ceddreed
6588b26b99c97473f020df4b9d4ba789e074e06ceddreed
6598b26b99c97473f020df4b9d4ba789e074e06ceddreedvoid GrWrapTextureInBitmap(GrTexture* src, int w, int h, bool isOpaque, SkBitmap* dst) {
6608b26b99c97473f020df4b9d4ba789e074e06ceddreed    const SkImageInfo info = GrMakeInfoFromTexture(src, w, h, isOpaque);
6618b26b99c97473f020df4b9d4ba789e074e06ceddreed    dst->setInfo(info);
662385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    dst->setPixelRef(new SkGrPixelRef(info, src))->unref();
6638b26b99c97473f020df4b9d4ba789e074e06ceddreed}
6649bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt
6659bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualittGrTextureParams::FilterMode GrSkFilterQualityToGrFilterMode(SkFilterQuality paintFilterQuality,
6669bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt                                                            const SkMatrix& viewM,
6679bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt                                                            const SkMatrix& localM,
6689bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt                                                            bool* doBicubic) {
6699bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt    *doBicubic = false;
6709bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt    GrTextureParams::FilterMode textureFilterMode;
6719bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt    switch (paintFilterQuality) {
6729bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        case kNone_SkFilterQuality:
6739bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            textureFilterMode = GrTextureParams::kNone_FilterMode;
6749bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            break;
6759bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        case kLow_SkFilterQuality:
6769bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            textureFilterMode = GrTextureParams::kBilerp_FilterMode;
6779bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            break;
6789bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        case kMedium_SkFilterQuality: {
6799bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            SkMatrix matrix;
6809bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            matrix.setConcat(viewM, localM);
6819bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            if (matrix.getMinScale() < SK_Scalar1) {
6829bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt                textureFilterMode = GrTextureParams::kMipMap_FilterMode;
6839bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            } else {
6849bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt                // Don't trigger MIP level generation unnecessarily.
6859bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt                textureFilterMode = GrTextureParams::kBilerp_FilterMode;
6869bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            }
6879bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            break;
6889bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        }
6899bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        case kHigh_SkFilterQuality: {
6909bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            SkMatrix matrix;
6919bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            matrix.setConcat(viewM, localM);
6929bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            *doBicubic = GrBicubicEffect::ShouldUseBicubic(matrix, &textureFilterMode);
6939bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            break;
6949bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        }
6959bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        default:
6969bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            SkErrorInternals::SetError( kInvalidPaint_SkError,
6979bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt                                        "Sorry, I don't understand the filtering "
6989bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt                                        "mode you asked for.  Falling back to "
6999bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt                                        "MIPMaps.");
7009bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            textureFilterMode = GrTextureParams::kMipMap_FilterMode;
7019bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            break;
7029bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt
7039bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt    }
7049bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt    return textureFilterMode;
7059bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt}
706