SkGr.cpp revision 43fe6185c5043247c47daa450b015e26d86728fe
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"
9378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel
10762286309545c8a1e4bbc05dcd1fe3085d2a1f47bsalomon#include "GrCaps.h"
11ea4615034498aca2f9ca1753fb9a1ef10508d8ccrobertphillips#include "GrDrawContext.h"
12378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel#include "GrXferProcessor.h"
1343fe6185c5043247c47daa450b015e26d86728fereed#include "GrYUVProvider.h"
1443fe6185c5043247c47daa450b015e26d86728fereed
158dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org#include "SkColorFilter.h"
16ea476e1725f38688b79aadf4c5e36c10c3141927commit-bot@chromium.org#include "SkConfig8888.h"
17b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon#include "SkCanvas.h"
189c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski#include "SkData.h"
195f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt#include "SkErrorInternals.h"
208b26b99c97473f020df4b9d4ba789e074e06ceddreed#include "SkGrPixelRef.h"
2150a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org#include "SkMessageBus.h"
2250a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org#include "SkPixelRef.h"
23692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi#include "SkResourceCache.h"
2440a1e11ebebe81586f3fec96408fdfd4b51123d2krajcevski#include "SkTextureCompressor.h"
25692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi#include "SkYUVPlanesCache.h"
269bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt#include "effects/GrBicubicEffect.h"
27f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#include "effects/GrDitherEffect.h"
28378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel#include "effects/GrPorterDuffXferProcessor.h"
29518d83dbc1c899e316e8c896af5defb58b83120fsugoi#include "effects/GrYUVtoRGBEffect.h"
309c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
318c111f783f40470e697310244426362132979ad9krajcevski#ifndef SK_IGNORE_ETC1_SUPPORT
3299ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski#  include "ktx.h"
339c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski#  include "etc1.h"
349c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski#endif
35ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
36ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com/*  Fill out buffer with the compressed format Ganesh expects from a colortable
37ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com based bitmap. [palette (colortable) + indices].
385782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
395782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com At the moment Ganesh only supports 8bit version. If Ganesh allowed we others
40ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com we could detect that the colortable.count is <= 16, and then repack the
41ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com indices as nibbles to save RAM, but it would take more time (i.e. a lot
42ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com slower than memcpy), so skipping that for now.
435782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
44ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com Ganesh wants a full 256 palette entry, even though Skia's ctable is only as big
45ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com as the colortable.count says it is.
46ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */
47e79a2dab91a90e26b13bc1ec9b8c6264a1ab22e4bsalomonstatic void build_index8_data(void* buffer, const SkBitmap& bitmap) {
480689d7b12e7c427a077b003d3d8ae759d86f798freed    SkASSERT(kIndex_8_SkColorType == bitmap.colorType());
495782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
507f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com    SkAutoLockPixels alp(bitmap);
51ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (!bitmap.readyToDraw()) {
520c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com        SkDEBUGFAIL("bitmap not ready to draw!");
53ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return;
54ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
55ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
56ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    SkColorTable* ctable = bitmap.getColorTable();
57ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    char* dst = (char*)buffer;
585782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
597111d463cee893a479280c7af41757e709e33ef5reed@google.com    const int count = ctable->count();
607111d463cee893a479280c7af41757e709e33ef5reed@google.com
617111d463cee893a479280c7af41757e709e33ef5reed@google.com    SkDstPixelInfo dstPI;
627111d463cee893a479280c7af41757e709e33ef5reed@google.com    dstPI.fColorType = kRGBA_8888_SkColorType;
637111d463cee893a479280c7af41757e709e33ef5reed@google.com    dstPI.fAlphaType = kPremul_SkAlphaType;
647111d463cee893a479280c7af41757e709e33ef5reed@google.com    dstPI.fPixels = buffer;
657111d463cee893a479280c7af41757e709e33ef5reed@google.com    dstPI.fRowBytes = count * sizeof(SkPMColor);
667111d463cee893a479280c7af41757e709e33ef5reed@google.com
677111d463cee893a479280c7af41757e709e33ef5reed@google.com    SkSrcPixelInfo srcPI;
6828fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org    srcPI.fColorType = kN32_SkColorType;
697111d463cee893a479280c7af41757e709e33ef5reed@google.com    srcPI.fAlphaType = kPremul_SkAlphaType;
70775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein    srcPI.fPixels = ctable->readColors();
717111d463cee893a479280c7af41757e709e33ef5reed@google.com    srcPI.fRowBytes = count * sizeof(SkPMColor);
727111d463cee893a479280c7af41757e709e33ef5reed@google.com
737111d463cee893a479280c7af41757e709e33ef5reed@google.com    srcPI.convertPixelsTo(&dstPI, count, 1);
747111d463cee893a479280c7af41757e709e33ef5reed@google.com
75ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    // always skip a full 256 number of entries, even if we memcpy'd fewer
76d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon    dst += 256 * sizeof(GrColor);
77ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
780ba4bf427acbd7707d04192a98c77ef194a0f25ascroggo@google.com    if ((unsigned)bitmap.width() == bitmap.rowBytes()) {
79ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        memcpy(dst, bitmap.getPixels(), bitmap.getSize());
80ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    } else {
81ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        // need to trim off the extra bytes per row
82ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        size_t width = bitmap.width();
83ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        size_t rowBytes = bitmap.rowBytes();
84ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        const char* src = (const char*)bitmap.getPixels();
85ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        for (int y = 0; y < bitmap.height(); y++) {
86ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            memcpy(dst, src, width);
87ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            src += rowBytes;
88ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            dst += width;
89ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
90ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
91ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
92ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
93ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com////////////////////////////////////////////////////////////////////////////////
94ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
95c59a1df65516eb60f9d41823d52e7ebffa900e9absalomonstruct Stretch {
96c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon    enum Type {
97c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon        kNone_Type,
98c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon        kBilerp_Type,
99c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon        kNearest_Type
100c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon    } fType;
101c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon    int fWidth;
102c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon    int fHeight;
10337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon};
10437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
105c59a1df65516eb60f9d41823d52e7ebffa900e9absalomonstatic void get_stretch(const GrContext* ctx, int width, int height,
106c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon                        const GrTextureParams* params, Stretch* stretch) {
107c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon    stretch->fType = Stretch::kNone_Type;
108c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon    bool doStretch = false;
109c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon    if (params && params->isTiled() && !ctx->caps()->npotTextureTileSupport() &&
110c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon        (!SkIsPow2(width) || !SkIsPow2(height))) {
111c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon        doStretch = true;
112b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon        stretch->fWidth  = GrNextPow2(SkTMax(width, ctx->caps()->minTextureSize()));
113b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon        stretch->fHeight = GrNextPow2(SkTMax(height, ctx->caps()->minTextureSize()));
114b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon    } else if (width < ctx->caps()->minTextureSize() || height < ctx->caps()->minTextureSize()) {
115c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon        // The small texture issues appear to be with tiling. Hence it seems ok to scale them
116c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon        // up using the GPU. If issues persist we may need to CPU-stretch.
117c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon        doStretch = true;
118c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon        stretch->fWidth = SkTMax(width, ctx->caps()->minTextureSize());
119c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon        stretch->fHeight = SkTMax(height, ctx->caps()->minTextureSize());
120c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon    }
121c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon    if (doStretch) {
1220513c83e0f6bffa566c7d1b93fb2ba52bacc10fcbsalomon        if (params) {
1230513c83e0f6bffa566c7d1b93fb2ba52bacc10fcbsalomon            switch(params->filterMode()) {
1240513c83e0f6bffa566c7d1b93fb2ba52bacc10fcbsalomon                case GrTextureParams::kNone_FilterMode:
1250513c83e0f6bffa566c7d1b93fb2ba52bacc10fcbsalomon                    stretch->fType = Stretch::kNearest_Type;
1260513c83e0f6bffa566c7d1b93fb2ba52bacc10fcbsalomon                    break;
1270513c83e0f6bffa566c7d1b93fb2ba52bacc10fcbsalomon                case GrTextureParams::kBilerp_FilterMode:
1280513c83e0f6bffa566c7d1b93fb2ba52bacc10fcbsalomon                case GrTextureParams::kMipMap_FilterMode:
1290513c83e0f6bffa566c7d1b93fb2ba52bacc10fcbsalomon                    stretch->fType = Stretch::kBilerp_Type;
1300513c83e0f6bffa566c7d1b93fb2ba52bacc10fcbsalomon                    break;
1310513c83e0f6bffa566c7d1b93fb2ba52bacc10fcbsalomon            }
1320513c83e0f6bffa566c7d1b93fb2ba52bacc10fcbsalomon        } else {
1330513c83e0f6bffa566c7d1b93fb2ba52bacc10fcbsalomon            stretch->fType = Stretch::kBilerp_Type;
13437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        }
135c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon    } else {
136c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon        stretch->fWidth  = -1;
137c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon        stretch->fHeight = -1;
138c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon        stretch->fType = Stretch::kNone_Type;
13937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    }
14037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon}
14137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
142c59a1df65516eb60f9d41823d52e7ebffa900e9absalomonstatic bool make_stretched_key(const GrUniqueKey& origKey, const Stretch& stretch,
1438718aafec239c93485e45bbe8fed19d9a8def079bsalomon                               GrUniqueKey* stretchedKey) {
144c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon    if (origKey.isValid() && Stretch::kNone_Type != stretch.fType) {
145c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon        uint32_t width = SkToU16(stretch.fWidth);
146c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon        uint32_t height = SkToU16(stretch.fHeight);
1478718aafec239c93485e45bbe8fed19d9a8def079bsalomon        static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
1488f34372f7e97482e5e61ab298b7edaa008ba2f4creed        GrUniqueKey::Builder builder(stretchedKey, origKey, kDomain, 2);
149c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon        builder[0] = stretch.fType;
150c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon        builder[1] = width | (height << 16);
15137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        builder.finish();
15237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        return true;
15337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    }
15423e619cf462b2a8a500f3ca750e099f79601f508bsalomon    SkASSERT(!stretchedKey->isValid());
15537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    return false;
15637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon}
15737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
1588f34372f7e97482e5e61ab298b7edaa008ba2f4creedstatic void make_unstretched_key(GrUniqueKey* key, uint32_t imageID,
1598f34372f7e97482e5e61ab298b7edaa008ba2f4creed                                 U16CPU width, U16CPU height, SkIPoint origin) {
1608f34372f7e97482e5e61ab298b7edaa008ba2f4creed    SkASSERT((uint16_t)width == width);
1618f34372f7e97482e5e61ab298b7edaa008ba2f4creed    SkASSERT((uint16_t)height == height);
16224db3b1c35fb935660229da164fc5ad31977387fbsalomon
1638718aafec239c93485e45bbe8fed19d9a8def079bsalomon    static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
1648718aafec239c93485e45bbe8fed19d9a8def079bsalomon    GrUniqueKey::Builder builder(key, kDomain, 4);
1658f34372f7e97482e5e61ab298b7edaa008ba2f4creed    builder[0] = imageID;
16624db3b1c35fb935660229da164fc5ad31977387fbsalomon    builder[1] = origin.fX;
16724db3b1c35fb935660229da164fc5ad31977387fbsalomon    builder[2] = origin.fY;
16824db3b1c35fb935660229da164fc5ad31977387fbsalomon    builder[3] = width | (height << 16);
16923e619cf462b2a8a500f3ca750e099f79601f508bsalomon}
17037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
1718f34372f7e97482e5e61ab298b7edaa008ba2f4creedvoid GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID,
1728f34372f7e97482e5e61ab298b7edaa008ba2f4creed                          U16CPU width, U16CPU height, SkIPoint origin,
1738f34372f7e97482e5e61ab298b7edaa008ba2f4creed                          const GrCaps& caps, SkImageUsageType usage) {
1748f34372f7e97482e5e61ab298b7edaa008ba2f4creed    const Stretch::Type stretches[] = {
1758f34372f7e97482e5e61ab298b7edaa008ba2f4creed        Stretch::kNone_Type,        // kUntiled_SkImageUsageType
1768f34372f7e97482e5e61ab298b7edaa008ba2f4creed        Stretch::kNearest_Type,     // kTiled_Unfiltered_SkImageUsageType
1778f34372f7e97482e5e61ab298b7edaa008ba2f4creed        Stretch::kBilerp_Type,      // kTiled_Filtered_SkImageUsageType
1788f34372f7e97482e5e61ab298b7edaa008ba2f4creed    };
1798f34372f7e97482e5e61ab298b7edaa008ba2f4creed
1808f34372f7e97482e5e61ab298b7edaa008ba2f4creed    const bool isPow2 = SkIsPow2(width) && SkIsPow2(height);
1818f34372f7e97482e5e61ab298b7edaa008ba2f4creed    const bool needToStretch = !isPow2 &&
1828f34372f7e97482e5e61ab298b7edaa008ba2f4creed                               usage != kUntiled_SkImageUsageType &&
1838f34372f7e97482e5e61ab298b7edaa008ba2f4creed                               !caps.npotTextureTileSupport();
1848f34372f7e97482e5e61ab298b7edaa008ba2f4creed
1858f34372f7e97482e5e61ab298b7edaa008ba2f4creed    if (needToStretch) {
1868f34372f7e97482e5e61ab298b7edaa008ba2f4creed        GrUniqueKey tmpKey;
1878f34372f7e97482e5e61ab298b7edaa008ba2f4creed        make_unstretched_key(&tmpKey, imageID, width, height, origin);
1888f34372f7e97482e5e61ab298b7edaa008ba2f4creed
1898f34372f7e97482e5e61ab298b7edaa008ba2f4creed        Stretch stretch;
1908f34372f7e97482e5e61ab298b7edaa008ba2f4creed        stretch.fType = stretches[usage];
1918f34372f7e97482e5e61ab298b7edaa008ba2f4creed        stretch.fWidth = SkNextPow2(width);
1928f34372f7e97482e5e61ab298b7edaa008ba2f4creed        stretch.fHeight = SkNextPow2(height);
1938f34372f7e97482e5e61ab298b7edaa008ba2f4creed        if (!make_stretched_key(tmpKey, stretch, key)) {
1948f34372f7e97482e5e61ab298b7edaa008ba2f4creed            goto UNSTRETCHED;
1958f34372f7e97482e5e61ab298b7edaa008ba2f4creed        }
1968f34372f7e97482e5e61ab298b7edaa008ba2f4creed    } else {
1978f34372f7e97482e5e61ab298b7edaa008ba2f4creed        UNSTRETCHED:
1988f34372f7e97482e5e61ab298b7edaa008ba2f4creed        make_unstretched_key(key, imageID, width, height, origin);
1998f34372f7e97482e5e61ab298b7edaa008ba2f4creed    }
2008f34372f7e97482e5e61ab298b7edaa008ba2f4creed}
2018f34372f7e97482e5e61ab298b7edaa008ba2f4creed
2028f34372f7e97482e5e61ab298b7edaa008ba2f4creedstatic void make_unstretched_key(const SkBitmap& bitmap, GrUniqueKey* key) {
2038f34372f7e97482e5e61ab298b7edaa008ba2f4creed    make_unstretched_key(key, bitmap.getGenerationID(), bitmap.width(), bitmap.height(),
2048f34372f7e97482e5e61ab298b7edaa008ba2f4creed                         bitmap.pixelRefOrigin());
2058f34372f7e97482e5e61ab298b7edaa008ba2f4creed}
2068f34372f7e97482e5e61ab298b7edaa008ba2f4creed
20723e619cf462b2a8a500f3ca750e099f79601f508bsalomonstatic void make_bitmap_keys(const SkBitmap& bitmap,
208c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon                             const Stretch& stretch,
2098718aafec239c93485e45bbe8fed19d9a8def079bsalomon                             GrUniqueKey* key,
2108718aafec239c93485e45bbe8fed19d9a8def079bsalomon                             GrUniqueKey* stretchedKey) {
21123e619cf462b2a8a500f3ca750e099f79601f508bsalomon    make_unstretched_key(bitmap, key);
212c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon    if (Stretch::kNone_Type != stretch.fType) {
21323e619cf462b2a8a500f3ca750e099f79601f508bsalomon        make_stretched_key(*key, stretch, stretchedKey);
21437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    }
2150797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com}
2160797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com
217f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomonstatic void generate_bitmap_texture_desc(const SkBitmap& bitmap, GrSurfaceDesc* desc) {
218f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon    desc->fFlags = kNone_GrSurfaceFlags;
2190797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    desc->fWidth = bitmap.width();
2200797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    desc->fHeight = bitmap.height();
2213adcc3403377c0b9a7afde6db8e0432325413a10commit-bot@chromium.org    desc->fConfig = SkImageInfo2GrPixelConfig(bitmap.info());
2220797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    desc->fSampleCnt = 0;
2230797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com}
2240797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com
22550a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgnamespace {
22650a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
22750a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org// When the SkPixelRef genID changes, invalidate a corresponding GrResource described by key.
22823e619cf462b2a8a500f3ca750e099f79601f508bsalomonclass BitmapInvalidator : public SkPixelRef::GenIDChangeListener {
22950a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgpublic:
2308718aafec239c93485e45bbe8fed19d9a8def079bsalomon    explicit BitmapInvalidator(const GrUniqueKey& key) : fMsg(key) {}
23150a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgprivate:
2328718aafec239c93485e45bbe8fed19d9a8def079bsalomon    GrUniqueKeyInvalidatedMessage fMsg;
23350a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
23436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onChange() override {
2358718aafec239c93485e45bbe8fed19d9a8def079bsalomon        SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(fMsg);
23650a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    }
23750a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org};
23850a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
23950a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org}  // namespace
24050a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
24150a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
24243fe6185c5043247c47daa450b015e26d86728fereedGrTexture* GrCreateTextureForPixels(GrContext* ctx,
24343fe6185c5043247c47daa450b015e26d86728fereed                                    const GrUniqueKey& optionalKey,
24443fe6185c5043247c47daa450b015e26d86728fereed                                    GrSurfaceDesc desc,
24543fe6185c5043247c47daa450b015e26d86728fereed                                    SkPixelRef* pixelRefForInvalidationNotification,
24643fe6185c5043247c47daa450b015e26d86728fereed                                    const void* pixels,
24743fe6185c5043247c47daa450b015e26d86728fereed                                    size_t rowBytes) {
248d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon    GrTexture* result = ctx->textureProvider()->createTexture(desc, true, pixels, rowBytes);
249d0423587ac56ae84d3f1eb796d5c1e2dfba9646ebsalomon    if (result && optionalKey.isValid()) {
25043fe6185c5043247c47daa450b015e26d86728fereed        if (pixelRefForInvalidationNotification) {
25143fe6185c5043247c47daa450b015e26d86728fereed            BitmapInvalidator* listener = new BitmapInvalidator(optionalKey);
25243fe6185c5043247c47daa450b015e26d86728fereed            pixelRefForInvalidationNotification->addGenIDChangeListener(listener);
25343fe6185c5043247c47daa450b015e26d86728fereed        }
254d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon        ctx->textureProvider()->assignUniqueKeyToTexture(optionalKey, result);
2550249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi    }
2560249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi    return result;
2570249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi}
2580249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi
259c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon// creates a new texture that is the input texture scaled up. If optionalKey is valid it will be
260c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon// set on the new texture. stretch controls whether the scaling is done using nearest or bilerp
261c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon// filtering and the size to stretch the texture to.
262c59a1df65516eb60f9d41823d52e7ebffa900e9absalomonGrTexture* stretch_texture(GrTexture* inputTexture, const Stretch& stretch,
263c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon                           SkPixelRef* pixelRef,
264c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon                           const GrUniqueKey& optionalKey) {
265c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon    SkASSERT(Stretch::kNone_Type != stretch.fType);
26637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
26737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    GrContext* context = inputTexture->getContext();
26837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    SkASSERT(context);
269762286309545c8a1e4bbc05dcd1fe3085d2a1f47bsalomon    const GrCaps* caps = context->caps();
27037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
27137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    // Either it's a cache miss or the original wasn't cached to begin with.
27237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    GrSurfaceDesc rtDesc = inputTexture->desc();
2736bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon    rtDesc.fFlags =  rtDesc.fFlags | kRenderTarget_GrSurfaceFlag;
274c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon    rtDesc.fWidth  = stretch.fWidth;
275c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon    rtDesc.fHeight = stretch.fHeight;
27637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    rtDesc.fConfig = GrMakePixelConfigUncompressed(rtDesc.fConfig);
27737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
27837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    // If the config isn't renderable try converting to either A8 or an 32 bit config. Otherwise,
27937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    // fail.
280762286309545c8a1e4bbc05dcd1fe3085d2a1f47bsalomon    if (!caps->isConfigRenderable(rtDesc.fConfig, false)) {
28137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        if (GrPixelConfigIsAlphaOnly(rtDesc.fConfig)) {
282762286309545c8a1e4bbc05dcd1fe3085d2a1f47bsalomon            if (caps->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
28337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                rtDesc.fConfig = kAlpha_8_GrPixelConfig;
284762286309545c8a1e4bbc05dcd1fe3085d2a1f47bsalomon            } else if (caps->isConfigRenderable(kSkia8888_GrPixelConfig, false)) {
28537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                rtDesc.fConfig = kSkia8888_GrPixelConfig;
28637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon            } else {
28796fcdcc219d2a0d3579719b84b28bede76efba64halcanary                return nullptr;
28837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon            }
28937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        } else if (kRGB_GrColorComponentFlags ==
29037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                   (kRGB_GrColorComponentFlags & GrPixelConfigComponentMask(rtDesc.fConfig))) {
291762286309545c8a1e4bbc05dcd1fe3085d2a1f47bsalomon            if (caps->isConfigRenderable(kSkia8888_GrPixelConfig, false)) {
29237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                rtDesc.fConfig = kSkia8888_GrPixelConfig;
29337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon            } else {
29496fcdcc219d2a0d3579719b84b28bede76efba64halcanary                return nullptr;
29537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon            }
29637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        } else {
29796fcdcc219d2a0d3579719b84b28bede76efba64halcanary            return nullptr;
29837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        }
29937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    }
30037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
30143fe6185c5043247c47daa450b015e26d86728fereed    SkAutoTUnref<GrTexture> stretched(GrCreateTextureForPixels(context, optionalKey, rtDesc,
30243fe6185c5043247c47daa450b015e26d86728fereed                                                               pixelRef, nullptr,0));
30323e619cf462b2a8a500f3ca750e099f79601f508bsalomon    if (!stretched) {
30496fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
30537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    }
30637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    GrPaint paint;
30737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
30837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    // If filtering is not desired then we want to ensure all texels in the resampled image are
30937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    // copies of texels from the original.
31037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    GrTextureParams params(SkShader::kClamp_TileMode,
311c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon                           Stretch::kBilerp_Type == stretch.fType ?
312c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon                              GrTextureParams::kBilerp_FilterMode :
313c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon                              GrTextureParams::kNone_FilterMode);
31437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    paint.addColorTextureProcessor(inputTexture, SkMatrix::I(), params);
31537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
31637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    SkRect rect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtDesc.fHeight));
31737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    SkRect localRect = SkRect::MakeWH(1.f, 1.f);
31837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
319c9a3706f1ee38c331610ec1e872d9a658566c397robertphillips    SkAutoTUnref<GrDrawContext> drawContext(context->drawContext());
320ea4615034498aca2f9ca1753fb9a1ef10508d8ccrobertphillips    if (!drawContext) {
32196fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
322ea4615034498aca2f9ca1753fb9a1ef10508d8ccrobertphillips    }
323ea4615034498aca2f9ca1753fb9a1ef10508d8ccrobertphillips
324ea4615034498aca2f9ca1753fb9a1ef10508d8ccrobertphillips    drawContext->drawNonAARectToRect(stretched->asRenderTarget(), GrClip::WideOpen(), paint,
325ea4615034498aca2f9ca1753fb9a1ef10508d8ccrobertphillips                                     SkMatrix::I(), rect, localRect);
32637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
32743fe6185c5043247c47daa450b015e26d86728fereed    return stretched.detach();
32837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon}
32937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
33043fe6185c5043247c47daa450b015e26d86728fereedGrPixelConfig GrIsCompressedTextureDataSupported(GrContext* ctx, SkData* data,
33143fe6185c5043247c47daa450b015e26d86728fereed                                                 int expectedW, int expectedH,
33243fe6185c5043247c47daa450b015e26d86728fereed                                                 const void** outStartOfDataToUpload) {
33343fe6185c5043247c47daa450b015e26d86728fereed    *outStartOfDataToUpload = nullptr;
3348c111f783f40470e697310244426362132979ad9krajcevski#ifndef SK_IGNORE_ETC1_SUPPORT
33543fe6185c5043247c47daa450b015e26d86728fereed    if (!ctx->caps()->isConfigTexturable(kETC1_GrPixelConfig)) {
33643fe6185c5043247c47daa450b015e26d86728fereed        return kUnknown_GrPixelConfig;
3379c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski    }
3389c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
33943fe6185c5043247c47daa450b015e26d86728fereed    const uint8_t* bytes = data->bytes();
34043fe6185c5043247c47daa450b015e26d86728fereed    if (data->size() > ETC_PKM_HEADER_SIZE && etc1_pkm_is_valid(bytes)) {
34199ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        // Does the data match the dimensions of the bitmap? If not,
34299ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        // then we don't know how to scale the image to match it...
34343fe6185c5043247c47daa450b015e26d86728fereed        if (etc1_pkm_get_width(bytes) != (unsigned)expectedW ||
34443fe6185c5043247c47daa450b015e26d86728fereed            etc1_pkm_get_height(bytes) != (unsigned)expectedH)
34543fe6185c5043247c47daa450b015e26d86728fereed        {
34643fe6185c5043247c47daa450b015e26d86728fereed            return kUnknown_GrPixelConfig;
34799ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        }
34899ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski
34943fe6185c5043247c47daa450b015e26d86728fereed        *outStartOfDataToUpload = bytes + ETC_PKM_HEADER_SIZE;
35043fe6185c5043247c47daa450b015e26d86728fereed        return kETC1_GrPixelConfig;
35199ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski    } else if (SkKTXFile::is_ktx(bytes)) {
35299ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        SkKTXFile ktx(data);
3539c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
35499ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        // Is it actually an ETC1 texture?
35540a1e11ebebe81586f3fec96408fdfd4b51123d2krajcevski        if (!ktx.isCompressedFormat(SkTextureCompressor::kETC1_Format)) {
35643fe6185c5043247c47daa450b015e26d86728fereed            return kUnknown_GrPixelConfig;
35799ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        }
35899ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski
35999ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        // Does the data match the dimensions of the bitmap? If not,
36099ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        // then we don't know how to scale the image to match it...
36143fe6185c5043247c47daa450b015e26d86728fereed        if (ktx.width() != expectedW || ktx.height() != expectedH) {
36243fe6185c5043247c47daa450b015e26d86728fereed            return kUnknown_GrPixelConfig;
363775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein        }
3649c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
36543fe6185c5043247c47daa450b015e26d86728fereed        *outStartOfDataToUpload = ktx.pixelData();
36643fe6185c5043247c47daa450b015e26d86728fereed        return kETC1_GrPixelConfig;
3679c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski    }
36843fe6185c5043247c47daa450b015e26d86728fereed#endif
36943fe6185c5043247c47daa450b015e26d86728fereed    return kUnknown_GrPixelConfig;
3709c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski}
3719c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
37243fe6185c5043247c47daa450b015e26d86728fereedstatic GrTexture* load_etc1_texture(GrContext* ctx, const GrUniqueKey& optionalKey,
37343fe6185c5043247c47daa450b015e26d86728fereed                                    const SkBitmap &bm, GrSurfaceDesc desc) {
37443fe6185c5043247c47daa450b015e26d86728fereed    SkAutoTUnref<SkData> data(bm.pixelRef()->refEncodedData());
37543fe6185c5043247c47daa450b015e26d86728fereed    if (!data) {
37696fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
377518d83dbc1c899e316e8c896af5defb58b83120fsugoi    }
378518d83dbc1c899e316e8c896af5defb58b83120fsugoi
37943fe6185c5043247c47daa450b015e26d86728fereed    const void* startOfTexData;
38043fe6185c5043247c47daa450b015e26d86728fereed    desc.fConfig = GrIsCompressedTextureDataSupported(ctx, data, bm.width(), bm.height(),
38143fe6185c5043247c47daa450b015e26d86728fereed                                                      &startOfTexData);
38243fe6185c5043247c47daa450b015e26d86728fereed    if (kUnknown_GrPixelConfig == desc.fConfig) {
38343fe6185c5043247c47daa450b015e26d86728fereed        return nullptr;
384ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi    }
385692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi
38643fe6185c5043247c47daa450b015e26d86728fereed    return GrCreateTextureForPixels(ctx, optionalKey, desc, bm.pixelRef(), startOfTexData, 0);
38743fe6185c5043247c47daa450b015e26d86728fereed}
388518d83dbc1c899e316e8c896af5defb58b83120fsugoi
38943fe6185c5043247c47daa450b015e26d86728fereed/*
39043fe6185c5043247c47daa450b015e26d86728fereed *  Once we have made SkImages handle all lazy/deferred/generated content, the YUV apis will
39143fe6185c5043247c47daa450b015e26d86728fereed *  be gone from SkPixelRef, and we can remove this subclass entirely.
39243fe6185c5043247c47daa450b015e26d86728fereed */
39343fe6185c5043247c47daa450b015e26d86728fereedclass PixelRef_GrYUVProvider : public GrYUVProvider {
39443fe6185c5043247c47daa450b015e26d86728fereed    SkPixelRef* fPR;
395692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi
39643fe6185c5043247c47daa450b015e26d86728fereedpublic:
39743fe6185c5043247c47daa450b015e26d86728fereed    PixelRef_GrYUVProvider(SkPixelRef* pr) : fPR(pr) {}
398abaef86f2b37d8a939506a2076da07f6db456951rileya
39943fe6185c5043247c47daa450b015e26d86728fereed    uint32_t onGetID() override { return fPR->getGenerationID(); }
40043fe6185c5043247c47daa450b015e26d86728fereed    bool onGetYUVSizes(SkISize sizes[3]) override {
40143fe6185c5043247c47daa450b015e26d86728fereed        return fPR->getYUV8Planes(sizes, nullptr, nullptr, nullptr);
402518d83dbc1c899e316e8c896af5defb58b83120fsugoi    }
40343fe6185c5043247c47daa450b015e26d86728fereed    bool onGetYUVPlanes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
40443fe6185c5043247c47daa450b015e26d86728fereed                        SkYUVColorSpace* space) override {
40543fe6185c5043247c47daa450b015e26d86728fereed        return fPR->getYUV8Planes(sizes, planes, rowBytes, space);
406518d83dbc1c899e316e8c896af5defb58b83120fsugoi    }
40743fe6185c5043247c47daa450b015e26d86728fereed};
408518d83dbc1c899e316e8c896af5defb58b83120fsugoi
40943fe6185c5043247c47daa450b015e26d86728fereedstatic GrTexture* load_yuv_texture(GrContext* ctx, const GrUniqueKey& optionalKey,
41043fe6185c5043247c47daa450b015e26d86728fereed                                   const SkBitmap& bm, const GrSurfaceDesc& desc) {
41143fe6185c5043247c47daa450b015e26d86728fereed    // Subsets are not supported, the whole pixelRef is loaded when using YUV decoding
41243fe6185c5043247c47daa450b015e26d86728fereed    SkPixelRef* pixelRef = bm.pixelRef();
41343fe6185c5043247c47daa450b015e26d86728fereed    if ((nullptr == pixelRef) ||
41443fe6185c5043247c47daa450b015e26d86728fereed        (pixelRef->info().width()  != bm.info().width()) ||
41543fe6185c5043247c47daa450b015e26d86728fereed        (pixelRef->info().height() != bm.info().height())) {
41696fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
417518d83dbc1c899e316e8c896af5defb58b83120fsugoi    }
418518d83dbc1c899e316e8c896af5defb58b83120fsugoi
41943fe6185c5043247c47daa450b015e26d86728fereed    const bool useCache = optionalKey.isValid();
42043fe6185c5043247c47daa450b015e26d86728fereed    PixelRef_GrYUVProvider provider(pixelRef);
42143fe6185c5043247c47daa450b015e26d86728fereed    GrTexture* texture = provider.refAsTexture(ctx, desc, useCache);
42243fe6185c5043247c47daa450b015e26d86728fereed    if (!texture) {
42396fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
424ea4615034498aca2f9ca1753fb9a1ef10508d8ccrobertphillips    }
425ea4615034498aca2f9ca1753fb9a1ef10508d8ccrobertphillips
42643fe6185c5043247c47daa450b015e26d86728fereed    if (useCache) {
42743fe6185c5043247c47daa450b015e26d86728fereed        BitmapInvalidator* listener = new BitmapInvalidator(optionalKey);
42843fe6185c5043247c47daa450b015e26d86728fereed        pixelRef->addGenIDChangeListener(listener);
42943fe6185c5043247c47daa450b015e26d86728fereed        ctx->textureProvider()->assignUniqueKeyToTexture(optionalKey, texture);
43043fe6185c5043247c47daa450b015e26d86728fereed    }
43143fe6185c5043247c47daa450b015e26d86728fereed    return texture;
432518d83dbc1c899e316e8c896af5defb58b83120fsugoi}
433518d83dbc1c899e316e8c896af5defb58b83120fsugoi
43437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomonstatic GrTexture* create_unstretched_bitmap_texture(GrContext* ctx,
43537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                                                    const SkBitmap& origBitmap,
4368718aafec239c93485e45bbe8fed19d9a8def079bsalomon                                                    const GrUniqueKey& optionalKey) {
437b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon    if (origBitmap.width() < ctx->caps()->minTextureSize() ||
438b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon        origBitmap.height() < ctx->caps()->minTextureSize()) {
43996fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
440b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon    }
441ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    SkBitmap tmpBitmap;
442ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
443ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    const SkBitmap* bitmap = &origBitmap;
4445782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
445f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon    GrSurfaceDesc desc;
4460797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    generate_bitmap_texture_desc(*bitmap, &desc);
447762286309545c8a1e4bbc05dcd1fe3085d2a1f47bsalomon    const GrCaps* caps = ctx->caps();
4485782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
4490689d7b12e7c427a077b003d3d8ae759d86f798freed    if (kIndex_8_SkColorType == bitmap->colorType()) {
450762286309545c8a1e4bbc05dcd1fe3085d2a1f47bsalomon        if (caps->isConfigTexturable(kIndex_8_GrPixelConfig)) {
451d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon            size_t imageSize = GrCompressedFormatDataSize(kIndex_8_GrPixelConfig,
452d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon                                                          bitmap->width(), bitmap->height());
453d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon            SkAutoMalloc storage(imageSize);
454e79a2dab91a90e26b13bc1ec9b8c6264a1ab22e4bsalomon            build_index8_data(storage.get(), origBitmap);
455ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
456ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            // our compressed data will be trimmed, so pass width() for its
457ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            // "rowBytes", since they are the same now.
45843fe6185c5043247c47daa450b015e26d86728fereed            return GrCreateTextureForPixels(ctx, optionalKey, desc, origBitmap.pixelRef(),
45943fe6185c5043247c47daa450b015e26d86728fereed                                            storage.get(), bitmap->width());
460ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        } else {
46128fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org            origBitmap.copyTo(&tmpBitmap, kN32_SkColorType);
462ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            // now bitmap points to our temp, which has been promoted to 32bits
463ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            bitmap = &tmpBitmap;
4643adcc3403377c0b9a7afde6db8e0432325413a10commit-bot@chromium.org            desc.fConfig = SkImageInfo2GrPixelConfig(bitmap->info());
465ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
46643fe6185c5043247c47daa450b015e26d86728fereed    } else if (!bitmap->readyToDraw()) {
46743fe6185c5043247c47daa450b015e26d86728fereed        // If the bitmap had compressed data and was then uncompressed, it'll still return
46843fe6185c5043247c47daa450b015e26d86728fereed        // compressed data on 'refEncodedData' and upload it. Probably not good, since if
46943fe6185c5043247c47daa450b015e26d86728fereed        // the bitmap has available pixels, then they might not be what the decompressed
47043fe6185c5043247c47daa450b015e26d86728fereed        // data is.
47137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        GrTexture *texture = load_etc1_texture(ctx, optionalKey, *bitmap, desc);
47249f085dddff10473b6ebf832a974288300224e60bsalomon        if (texture) {
4739c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski            return texture;
4749c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski        }
4755782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    }
476ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
477d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon    GrTexture *texture = load_yuv_texture(ctx, optionalKey, *bitmap, desc);
478d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon    if (texture) {
479d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon        return texture;
480518d83dbc1c899e316e8c896af5defb58b83120fsugoi    }
481d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon
4827f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com    SkAutoLockPixels alp(*bitmap);
4837f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com    if (!bitmap->readyToDraw()) {
48496fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
4857f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com    }
48650a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
48743fe6185c5043247c47daa450b015e26d86728fereed    return GrCreateTextureForPixels(ctx, optionalKey, desc, origBitmap.pixelRef(),
48843fe6185c5043247c47daa450b015e26d86728fereed                                    bitmap->getPixels(), bitmap->rowBytes());
48937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon}
49037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
491b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomonstatic SkBitmap stretch_on_cpu(const SkBitmap& bmp, const Stretch& stretch) {
492b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon    SkBitmap stretched;
493b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon    stretched.allocN32Pixels(stretch.fWidth, stretch.fHeight);
494b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon    SkCanvas canvas(stretched);
495b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon    SkPaint paint;
496b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon    switch (stretch.fType) {
497b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon        case Stretch::kNearest_Type:
498b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon            paint.setFilterQuality(kNone_SkFilterQuality);
499b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon            break;
500b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon        case Stretch::kBilerp_Type:
501b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon            paint.setFilterQuality(kLow_SkFilterQuality);
502b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon            break;
503b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon        case Stretch::kNone_Type:
504b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon            SkDEBUGFAIL("Shouldn't get here.");
505b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon            break;
506b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon    }
507b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon    SkRect dstRect = SkRect::MakeWH(SkIntToScalar(stretch.fWidth), SkIntToScalar(stretch.fHeight));
50884984efeb64787b88c5f8bd6929cfe2d58a3ba06reed    canvas.drawBitmapRect(bmp, dstRect, &paint);
509b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon    return stretched;
510b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon}
511b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon
51237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomonstatic GrTexture* create_bitmap_texture(GrContext* ctx,
51337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                                        const SkBitmap& bmp,
514c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon                                        const Stretch& stretch,
5158718aafec239c93485e45bbe8fed19d9a8def079bsalomon                                        const GrUniqueKey& unstretchedKey,
5168718aafec239c93485e45bbe8fed19d9a8def079bsalomon                                        const GrUniqueKey& stretchedKey) {
517c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon    if (Stretch::kNone_Type != stretch.fType) {
51837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        SkAutoTUnref<GrTexture> unstretched;
51937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        // Check if we have the unstretched version in the cache, if not create it.
52037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        if (unstretchedKey.isValid()) {
521d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon            unstretched.reset(ctx->textureProvider()->findAndRefTextureByUniqueKey(unstretchedKey));
52237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        }
52337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        if (!unstretched) {
52437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon            unstretched.reset(create_unstretched_bitmap_texture(ctx, bmp, unstretchedKey));
52537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon            if (!unstretched) {
526b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon                // We might not have been able to create a unstrecthed texture because it is smaller
527b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon                // than the min texture size. In that case do cpu stretching.
528b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon                SkBitmap stretchedBmp = stretch_on_cpu(bmp, stretch);
529b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon                return create_unstretched_bitmap_texture(ctx, stretchedBmp, stretchedKey);
53037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon            }
53137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        }
532b4d40ef72432429d22c6be2e228b7f73e5c3a91dbsalomon        return stretch_texture(unstretched, stretch, bmp.pixelRef(), stretchedKey);
53337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    }
53437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    return create_unstretched_bitmap_texture(ctx, bmp, unstretchedKey);
535ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
536ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
5370797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.combool GrIsBitmapInCache(const GrContext* ctx,
5380797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com                       const SkBitmap& bitmap,
5390797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com                       const GrTextureParams* params) {
540c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon    Stretch stretch;
541c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon    get_stretch(ctx, bitmap.width(), bitmap.height(), params, &stretch);
54288425565259809bc1b0aac116d87f3fc8d212f43bsalomon
54388425565259809bc1b0aac116d87f3fc8d212f43bsalomon    // Handle the case where the bitmap is explicitly texture backed.
54488425565259809bc1b0aac116d87f3fc8d212f43bsalomon    GrTexture* texture = bitmap.getTexture();
54588425565259809bc1b0aac116d87f3fc8d212f43bsalomon    if (texture) {
546c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon        if (Stretch::kNone_Type == stretch.fType) {
54788425565259809bc1b0aac116d87f3fc8d212f43bsalomon            return true;
54888425565259809bc1b0aac116d87f3fc8d212f43bsalomon        }
54988425565259809bc1b0aac116d87f3fc8d212f43bsalomon        // No keys for volatile bitmaps.
55088425565259809bc1b0aac116d87f3fc8d212f43bsalomon        if (bitmap.isVolatile()) {
55188425565259809bc1b0aac116d87f3fc8d212f43bsalomon            return false;
55288425565259809bc1b0aac116d87f3fc8d212f43bsalomon        }
5538718aafec239c93485e45bbe8fed19d9a8def079bsalomon        const GrUniqueKey& key = texture->getUniqueKey();
55488425565259809bc1b0aac116d87f3fc8d212f43bsalomon        if (!key.isValid()) {
55588425565259809bc1b0aac116d87f3fc8d212f43bsalomon            return false;
55688425565259809bc1b0aac116d87f3fc8d212f43bsalomon        }
5578718aafec239c93485e45bbe8fed19d9a8def079bsalomon        GrUniqueKey stretchedKey;
55823e619cf462b2a8a500f3ca750e099f79601f508bsalomon        make_stretched_key(key, stretch, &stretchedKey);
559d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon        return ctx->textureProvider()->existsTextureWithUniqueKey(stretchedKey);
5609ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon    }
5619ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon
56237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    // We don't cache volatile bitmaps
56337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    if (bitmap.isVolatile()) {
56437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        return false;
56537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    }
56637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
5678718aafec239c93485e45bbe8fed19d9a8def079bsalomon    GrUniqueKey key, stretchedKey;
56823e619cf462b2a8a500f3ca750e099f79601f508bsalomon    make_bitmap_keys(bitmap, stretch, &key, &stretchedKey);
569d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon    return ctx->textureProvider()->existsTextureWithUniqueKey(
570c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon        (Stretch::kNone_Type == stretch.fType) ? key : stretchedKey);
5710797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com}
572ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
573bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomonGrTexture* GrRefCachedBitmapTexture(GrContext* ctx,
574bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon                                    const SkBitmap& bitmap,
575bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon                                    const GrTextureParams* params) {
57688425565259809bc1b0aac116d87f3fc8d212f43bsalomon
577c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon    Stretch stretch;
578c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon    get_stretch(ctx, bitmap.width(), bitmap.height(), params, &stretch);
57988425565259809bc1b0aac116d87f3fc8d212f43bsalomon
58088425565259809bc1b0aac116d87f3fc8d212f43bsalomon    GrTexture* result = bitmap.getTexture();
5819ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon    if (result) {
582c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon        if (Stretch::kNone_Type == stretch.fType) {
58388425565259809bc1b0aac116d87f3fc8d212f43bsalomon            return SkRef(result);
58488425565259809bc1b0aac116d87f3fc8d212f43bsalomon        }
5858718aafec239c93485e45bbe8fed19d9a8def079bsalomon        GrUniqueKey stretchedKey;
58688425565259809bc1b0aac116d87f3fc8d212f43bsalomon        // Don't create a key for the resized version if the bmp is volatile.
58788425565259809bc1b0aac116d87f3fc8d212f43bsalomon        if (!bitmap.isVolatile()) {
5888718aafec239c93485e45bbe8fed19d9a8def079bsalomon            const GrUniqueKey& key = result->getUniqueKey();
58988425565259809bc1b0aac116d87f3fc8d212f43bsalomon            if (key.isValid()) {
59023e619cf462b2a8a500f3ca750e099f79601f508bsalomon                make_stretched_key(key, stretch, &stretchedKey);
591d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon                GrTexture* stretched =
592d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon                    ctx->textureProvider()->findAndRefTextureByUniqueKey(stretchedKey);
59388425565259809bc1b0aac116d87f3fc8d212f43bsalomon                if (stretched) {
59488425565259809bc1b0aac116d87f3fc8d212f43bsalomon                    return stretched;
59588425565259809bc1b0aac116d87f3fc8d212f43bsalomon                }
59688425565259809bc1b0aac116d87f3fc8d212f43bsalomon            }
59788425565259809bc1b0aac116d87f3fc8d212f43bsalomon        }
598c59a1df65516eb60f9d41823d52e7ebffa900e9absalomon        return stretch_texture(result, stretch, bitmap.pixelRef(), stretchedKey);
5999ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon    }
60024f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com
6018718aafec239c93485e45bbe8fed19d9a8def079bsalomon    GrUniqueKey key, resizedKey;
6029c2ea846351a29208cb4a36301ee611e7fb384earobertphillips@google.com
60337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    if (!bitmap.isVolatile()) {
6040797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com        // If the bitmap isn't changing try to find a cached copy first.
60523e619cf462b2a8a500f3ca750e099f79601f508bsalomon        make_bitmap_keys(bitmap, stretch, &key, &resizedKey);
6064b86e3428b115202e82d49a0914ea8ab6dc25940bsalomon@google.com
607d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon        result = ctx->textureProvider()->findAndRefTextureByUniqueKey(
608d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon            resizedKey.isValid() ? resizedKey : key);
60937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        if (result) {
61037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon            return result;
61137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        }
612e137db8569e7a10d809980609688b3acfaec612absalomon    }
61337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
61437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    result = create_bitmap_texture(ctx, bitmap, stretch, key, resizedKey);
61537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    if (result) {
61637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        return result;
617e137db8569e7a10d809980609688b3acfaec612absalomon    }
618e137db8569e7a10d809980609688b3acfaec612absalomon
6195f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt    SkErrorInternals::SetError( kInternalError_SkError,
6205f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt                                "---- failed to create texture for cache [%d %d]\n",
6215f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt                                bitmap.width(), bitmap.height());
62237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
62396fcdcc219d2a0d3579719b84b28bede76efba64halcanary    return nullptr;
62437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon}
6258f34372f7e97482e5e61ab298b7edaa008ba2f4creed
6268f34372f7e97482e5e61ab298b7edaa008ba2f4creed// TODO: make this be the canonical signature, and turn the version that takes GrTextureParams*
6278f34372f7e97482e5e61ab298b7edaa008ba2f4creed//       into a wrapper that contains the inverse of these tables.
6288f34372f7e97482e5e61ab298b7edaa008ba2f4creedGrTexture* GrRefCachedBitmapTexture(GrContext* ctx,
6298f34372f7e97482e5e61ab298b7edaa008ba2f4creed                                    const SkBitmap& bitmap,
6308f34372f7e97482e5e61ab298b7edaa008ba2f4creed                                    SkImageUsageType usage) {
6318f34372f7e97482e5e61ab298b7edaa008ba2f4creed    // Just need a params that will trigger the correct cache key / etc, since the usage doesn't
6328f34372f7e97482e5e61ab298b7edaa008ba2f4creed    // tell us the specifics about filter level or specific tiling.
6338f34372f7e97482e5e61ab298b7edaa008ba2f4creed
6348f34372f7e97482e5e61ab298b7edaa008ba2f4creed    const SkShader::TileMode tiles[] = {
6358f34372f7e97482e5e61ab298b7edaa008ba2f4creed        SkShader::kClamp_TileMode,      // kUntiled_SkImageUsageType
6368f34372f7e97482e5e61ab298b7edaa008ba2f4creed        SkShader::kRepeat_TileMode,     // kTiled_Unfiltered_SkImageUsageType
6378f34372f7e97482e5e61ab298b7edaa008ba2f4creed        SkShader::kRepeat_TileMode,     // kTiled_Filtered_SkImageUsageType
6388f34372f7e97482e5e61ab298b7edaa008ba2f4creed    };
6398f34372f7e97482e5e61ab298b7edaa008ba2f4creed
6408f34372f7e97482e5e61ab298b7edaa008ba2f4creed    const GrTextureParams::FilterMode filters[] = {
6418f34372f7e97482e5e61ab298b7edaa008ba2f4creed        GrTextureParams::kNone_FilterMode,      // kUntiled_SkImageUsageType
6428f34372f7e97482e5e61ab298b7edaa008ba2f4creed        GrTextureParams::kNone_FilterMode,      // kTiled_Unfiltered_SkImageUsageType
6438f34372f7e97482e5e61ab298b7edaa008ba2f4creed        GrTextureParams::kBilerp_FilterMode,    // kTiled_Filtered_SkImageUsageType
6448f34372f7e97482e5e61ab298b7edaa008ba2f4creed    };
6458f34372f7e97482e5e61ab298b7edaa008ba2f4creed
6468f34372f7e97482e5e61ab298b7edaa008ba2f4creed    GrTextureParams params(tiles[usage], filters[usage]);
6478f34372f7e97482e5e61ab298b7edaa008ba2f4creed    return GrRefCachedBitmapTexture(ctx, bitmap, &params);
6488f34372f7e97482e5e61ab298b7edaa008ba2f4creed}
6498f34372f7e97482e5e61ab298b7edaa008ba2f4creed
65024f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com///////////////////////////////////////////////////////////////////////////////
65124f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com
65215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org// alphatype is ignore for now, but if GrPixelConfig is expanded to encompass
65315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org// alpha info, that will be considered.
654fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverthGrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType, SkColorProfileType pt) {
65515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    switch (ct) {
65615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        case kUnknown_SkColorType:
65715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            return kUnknown_GrPixelConfig;
65815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        case kAlpha_8_SkColorType:
65915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            return kAlpha_8_GrPixelConfig;
66015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        case kRGB_565_SkColorType:
66115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            return kRGB_565_GrPixelConfig;
66215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        case kARGB_4444_SkColorType:
66315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            return kRGBA_4444_GrPixelConfig;
66415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        case kRGBA_8888_SkColorType:
66599babf2848095febfc5f98b47f3a6c232411147fjvanverth            //if (kSRGB_SkColorProfileType == pt) {
66699babf2848095febfc5f98b47f3a6c232411147fjvanverth            //    return kSRGBA_8888_GrPixelConfig;
66799babf2848095febfc5f98b47f3a6c232411147fjvanverth            //}
66815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            return kRGBA_8888_GrPixelConfig;
66915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        case kBGRA_8888_SkColorType:
67015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            return kBGRA_8888_GrPixelConfig;
67115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        case kIndex_8_SkColorType:
67215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            return kIndex_8_GrPixelConfig;
6730c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed        case kGray_8_SkColorType:
6740c9b1a8d05ea6ec5dfae0ead854304673d94d2c2reed            return kAlpha_8_GrPixelConfig; // TODO: gray8 support on gpu
67515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    }
67615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    SkASSERT(0);    // shouldn't get here
67715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    return kUnknown_GrPixelConfig;
67815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org}
67915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org
680fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverthbool GrPixelConfig2ColorAndProfileType(GrPixelConfig config, SkColorType* ctOut,
681fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth                                       SkColorProfileType* ptOut) {
682bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    SkColorType ct;
683fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth    SkColorProfileType pt = kLinear_SkColorProfileType;
684bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    switch (config) {
685bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kAlpha_8_GrPixelConfig:
686bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kAlpha_8_SkColorType;
687bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
688bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kIndex_8_GrPixelConfig:
689bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kIndex_8_SkColorType;
690bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
691bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kRGB_565_GrPixelConfig:
692bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kRGB_565_SkColorType;
693bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
694bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kRGBA_4444_GrPixelConfig:
695bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kARGB_4444_SkColorType;
696bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
697bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kRGBA_8888_GrPixelConfig:
698bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kRGBA_8888_SkColorType;
699bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
700bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kBGRA_8888_GrPixelConfig:
701bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kBGRA_8888_SkColorType;
702bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
703fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth        case kSRGBA_8888_GrPixelConfig:
704fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth            ct = kRGBA_8888_SkColorType;
705fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth            pt = kSRGB_SkColorProfileType;
706fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth            break;
707bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        default:
708bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            return false;
709bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    }
710bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    if (ctOut) {
711bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        *ctOut = ct;
712bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    }
713fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth    if (ptOut) {
714fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth        *ptOut = pt;
715fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth    }
716bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    return true;
717bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com}
7188dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
7198dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////////
7208dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
721bed83a66f5fa5821a3a08da32157a6155960b15ebsalomonbool SkPaint2GrPaintNoShader(GrContext* context, GrRenderTarget* rt, const SkPaint& skPaint,
72225d9c154087d2132a51d1ca74a104726f60ef380joshualitt                             GrColor paintColor, bool constantColor, GrPaint* grPaint) {
7238dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
7248dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    grPaint->setDither(skPaint.isDither());
7258dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    grPaint->setAntiAlias(skPaint.isAntiAlias());
7268dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
7278dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    SkXfermode* mode = skPaint.getXfermode();
72896fcdcc219d2a0d3579719b84b28bede76efba64halcanary    GrXPFactory* xpFactory = nullptr;
72958136167fc596fb945b58b34f500cf370c0dec7cegdaniel    if (!SkXfermode::AsXPFactory(mode, &xpFactory)) {
7308dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org        // Fall back to src-over
731bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon        // return false here?
732c016fb8f9fb53dd8d4936c5e9e16a9dc99ab392eegdaniel        xpFactory = GrPorterDuffXPFactory::Create(SkXfermode::kSrcOver_Mode);
7338dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    }
734378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel    SkASSERT(xpFactory);
735378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel    grPaint->setXPFactory(xpFactory)->unref();
736775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein
7379de5b514d38c5b36066bcdc14fba2f7e5196d372dandov    //set the color of the paint to the one of the parameter
73883d081ae1d731b5039e99823620f5e287542ee39bsalomon    grPaint->setColor(paintColor);
7398dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
7408dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    SkColorFilter* colorFilter = skPaint.getColorFilter();
74149f085dddff10473b6ebf832a974288300224e60bsalomon    if (colorFilter) {
7428dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org        // if the source color is a constant then apply the filter here once rather than per pixel
7438dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org        // in a shader.
7448dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org        if (constantColor) {
7458dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org            SkColor filtered = colorFilter->filterColor(skPaint.getColor());
7468dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org            grPaint->setColor(SkColor2GrColor(filtered));
7478dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org        } else {
748cff10b21a9934afc540d121b493b204335829589reed            SkTDArray<GrFragmentProcessor*> array;
749bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon            // return false if failed?
7509cc1775e7230579ad15345bdcb59fa517c17f870joshualitt            if (colorFilter->asFragmentProcessors(context, grPaint->getProcessorDataManager(),
7512cff176fa25e962f7ae53ebeefa833f0eed276ccjoshualitt                                                  &array)) {
752cff10b21a9934afc540d121b493b204335829589reed                for (int i = 0; i < array.count(); ++i) {
753ac856c97acc84dcb54d9cdb068ec8a02b8869647bsalomon                    grPaint->addColorFragmentProcessor(array[i]);
754cff10b21a9934afc540d121b493b204335829589reed                    array[i]->unref();
755cff10b21a9934afc540d121b493b204335829589reed                }
7568dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org            }
7578dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org        }
7588dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    }
759f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
760f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#ifndef SK_IGNORE_GPU_DITHER
761f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    // If the dither flag is set, then we need to see if the underlying context
762f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    // supports it. If not, then install a dither effect.
763ac856c97acc84dcb54d9cdb068ec8a02b8869647bsalomon    if (skPaint.isDither() && grPaint->numColorFragmentProcessors() > 0) {
764f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        // What are we rendering into?
76525d9c154087d2132a51d1ca74a104726f60ef380joshualitt        SkASSERT(rt);
766f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
767f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        // Suspect the dithering flag has no effect on these configs, otherwise
768f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        // fall back on setting the appropriate state.
76925d9c154087d2132a51d1ca74a104726f60ef380joshualitt        if (GrPixelConfigIs8888(rt->config()) ||
77025d9c154087d2132a51d1ca74a104726f60ef380joshualitt            GrPixelConfigIs8888(rt->config())) {
771f461a8fdf642ba713dcdfb217534652df1eac278krajcevski            // The dither flag is set and the target is likely
772f461a8fdf642ba713dcdfb217534652df1eac278krajcevski            // not going to be dithered by the GPU.
773b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt            SkAutoTUnref<GrFragmentProcessor> fp(GrDitherEffect::Create());
774b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt            if (fp.get()) {
775ac856c97acc84dcb54d9cdb068ec8a02b8869647bsalomon                grPaint->addColorFragmentProcessor(fp);
776f461a8fdf642ba713dcdfb217534652df1eac278krajcevski                grPaint->setDither(false);
777f461a8fdf642ba713dcdfb217534652df1eac278krajcevski            }
778f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        }
779f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    }
780f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#endif
781bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    return true;
7828dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org}
7838dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
784bed83a66f5fa5821a3a08da32157a6155960b15ebsalomonbool SkPaint2GrPaint(GrContext* context, GrRenderTarget* rt, const SkPaint& skPaint,
785bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon                     const SkMatrix& viewM, bool constantColor, GrPaint* grPaint) {
7868dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    SkShader* shader = skPaint.getShader();
78796fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (nullptr == shader) {
788bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon        return SkPaint2GrPaintNoShader(context, rt, skPaint, SkColor2GrColor(skPaint.getColor()),
789bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon                                       constantColor, grPaint);
7908dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    }
7918dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
79283d081ae1d731b5039e99823620f5e287542ee39bsalomon    GrColor paintColor = SkColor2GrColor(skPaint.getColor());
793f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
794c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon    const GrFragmentProcessor* fp = shader->asFragmentProcessor(context, viewM, NULL,
795c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon        skPaint.getFilterQuality(), grPaint->getProcessorDataManager());
796c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon    if (!fp) {
797c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon        return false;
7988dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    }
799c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon    grPaint->addColorFragmentProcessor(fp)->unref();
800c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon    constantColor = false;
801f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
802b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    // The grcolor is automatically set when calling asFragmentProcessor.
8039de5b514d38c5b36066bcdc14fba2f7e5196d372dandov    // If the shader can be seen as an effect it returns true and adds its effect to the grpaint.
804bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    return SkPaint2GrPaintNoShader(context, rt, skPaint, paintColor, constantColor, grPaint);
8058dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org}
8068b26b99c97473f020df4b9d4ba789e074e06ceddreed
8078b26b99c97473f020df4b9d4ba789e074e06ceddreedSkImageInfo GrMakeInfoFromTexture(GrTexture* tex, int w, int h, bool isOpaque) {
8088b26b99c97473f020df4b9d4ba789e074e06ceddreed#ifdef SK_DEBUG
8098b26b99c97473f020df4b9d4ba789e074e06ceddreed    const GrSurfaceDesc& desc = tex->desc();
8108b26b99c97473f020df4b9d4ba789e074e06ceddreed    SkASSERT(w <= desc.fWidth);
8118b26b99c97473f020df4b9d4ba789e074e06ceddreed    SkASSERT(h <= desc.fHeight);
8128b26b99c97473f020df4b9d4ba789e074e06ceddreed#endif
8138b26b99c97473f020df4b9d4ba789e074e06ceddreed    const GrPixelConfig config = tex->config();
8148b26b99c97473f020df4b9d4ba789e074e06ceddreed    SkColorType ct;
8158b26b99c97473f020df4b9d4ba789e074e06ceddreed    SkAlphaType at = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
81696fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (!GrPixelConfig2ColorAndProfileType(config, &ct, nullptr)) {
8178b26b99c97473f020df4b9d4ba789e074e06ceddreed        ct = kUnknown_SkColorType;
8188b26b99c97473f020df4b9d4ba789e074e06ceddreed    }
8198b26b99c97473f020df4b9d4ba789e074e06ceddreed    return SkImageInfo::Make(w, h, ct, at);
8208b26b99c97473f020df4b9d4ba789e074e06ceddreed}
8218b26b99c97473f020df4b9d4ba789e074e06ceddreed
8228b26b99c97473f020df4b9d4ba789e074e06ceddreed
8238b26b99c97473f020df4b9d4ba789e074e06ceddreedvoid GrWrapTextureInBitmap(GrTexture* src, int w, int h, bool isOpaque, SkBitmap* dst) {
8248b26b99c97473f020df4b9d4ba789e074e06ceddreed    const SkImageInfo info = GrMakeInfoFromTexture(src, w, h, isOpaque);
8258b26b99c97473f020df4b9d4ba789e074e06ceddreed    dst->setInfo(info);
826385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    dst->setPixelRef(new SkGrPixelRef(info, src))->unref();
8278b26b99c97473f020df4b9d4ba789e074e06ceddreed}
8289bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt
8299bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualittGrTextureParams::FilterMode GrSkFilterQualityToGrFilterMode(SkFilterQuality paintFilterQuality,
8309bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt                                                            const SkMatrix& viewM,
8319bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt                                                            const SkMatrix& localM,
8329bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt                                                            bool* doBicubic) {
8339bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt    *doBicubic = false;
8349bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt    GrTextureParams::FilterMode textureFilterMode;
8359bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt    switch (paintFilterQuality) {
8369bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        case kNone_SkFilterQuality:
8379bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            textureFilterMode = GrTextureParams::kNone_FilterMode;
8389bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            break;
8399bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        case kLow_SkFilterQuality:
8409bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            textureFilterMode = GrTextureParams::kBilerp_FilterMode;
8419bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            break;
8429bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        case kMedium_SkFilterQuality: {
8439bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            SkMatrix matrix;
8449bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            matrix.setConcat(viewM, localM);
8459bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            if (matrix.getMinScale() < SK_Scalar1) {
8469bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt                textureFilterMode = GrTextureParams::kMipMap_FilterMode;
8479bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            } else {
8489bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt                // Don't trigger MIP level generation unnecessarily.
8499bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt                textureFilterMode = GrTextureParams::kBilerp_FilterMode;
8509bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            }
8519bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            break;
8529bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        }
8539bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        case kHigh_SkFilterQuality: {
8549bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            SkMatrix matrix;
8559bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            matrix.setConcat(viewM, localM);
8569bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            *doBicubic = GrBicubicEffect::ShouldUseBicubic(matrix, &textureFilterMode);
8579bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            break;
8589bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        }
8599bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt        default:
8609bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            SkErrorInternals::SetError( kInvalidPaint_SkError,
8619bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt                                        "Sorry, I don't understand the filtering "
8629bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt                                        "mode you asked for.  Falling back to "
8639bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt                                        "MIPMaps.");
8649bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            textureFilterMode = GrTextureParams::kMipMap_FilterMode;
8659bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt            break;
8669bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt
8679bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt    }
8689bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt    return textureFilterMode;
8699bc3954fc1b6c3fb609cbb10d42f659b9d762eb0joshualitt}
870