SkGr.cpp revision 23e619cf462b2a8a500f3ca750e099f79601f508
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
10378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel#include "GrXferProcessor.h"
118dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org#include "SkColorFilter.h"
12ea476e1725f38688b79aadf4c5e36c10c3141927commit-bot@chromium.org#include "SkConfig8888.h"
139c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski#include "SkData.h"
1450a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org#include "SkMessageBus.h"
1550a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org#include "SkPixelRef.h"
16692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi#include "SkResourceCache.h"
1740a1e11ebebe81586f3fec96408fdfd4b51123d2krajcevski#include "SkTextureCompressor.h"
18692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi#include "SkYUVPlanesCache.h"
19f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#include "effects/GrDitherEffect.h"
20378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel#include "effects/GrPorterDuffXferProcessor.h"
21518d83dbc1c899e316e8c896af5defb58b83120fsugoi#include "effects/GrYUVtoRGBEffect.h"
229c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
238c111f783f40470e697310244426362132979ad9krajcevski#ifndef SK_IGNORE_ETC1_SUPPORT
2499ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski#  include "ktx.h"
259c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski#  include "etc1.h"
269c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski#endif
27ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
28ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com/*  Fill out buffer with the compressed format Ganesh expects from a colortable
29ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com based bitmap. [palette (colortable) + indices].
305782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
315782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com At the moment Ganesh only supports 8bit version. If Ganesh allowed we others
32ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com we could detect that the colortable.count is <= 16, and then repack the
33ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com indices as nibbles to save RAM, but it would take more time (i.e. a lot
34ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com slower than memcpy), so skipping that for now.
355782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
36ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com Ganesh wants a full 256 palette entry, even though Skia's ctable is only as big
37ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com as the colortable.count says it is.
38ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */
39e79a2dab91a90e26b13bc1ec9b8c6264a1ab22e4bsalomonstatic void build_index8_data(void* buffer, const SkBitmap& bitmap) {
400689d7b12e7c427a077b003d3d8ae759d86f798freed    SkASSERT(kIndex_8_SkColorType == bitmap.colorType());
415782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
427f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com    SkAutoLockPixels alp(bitmap);
43ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (!bitmap.readyToDraw()) {
440c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com        SkDEBUGFAIL("bitmap not ready to draw!");
45ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return;
46ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
47ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
48ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    SkColorTable* ctable = bitmap.getColorTable();
49ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    char* dst = (char*)buffer;
505782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
517111d463cee893a479280c7af41757e709e33ef5reed@google.com    const int count = ctable->count();
527111d463cee893a479280c7af41757e709e33ef5reed@google.com
537111d463cee893a479280c7af41757e709e33ef5reed@google.com    SkDstPixelInfo dstPI;
547111d463cee893a479280c7af41757e709e33ef5reed@google.com    dstPI.fColorType = kRGBA_8888_SkColorType;
557111d463cee893a479280c7af41757e709e33ef5reed@google.com    dstPI.fAlphaType = kPremul_SkAlphaType;
567111d463cee893a479280c7af41757e709e33ef5reed@google.com    dstPI.fPixels = buffer;
577111d463cee893a479280c7af41757e709e33ef5reed@google.com    dstPI.fRowBytes = count * sizeof(SkPMColor);
587111d463cee893a479280c7af41757e709e33ef5reed@google.com
597111d463cee893a479280c7af41757e709e33ef5reed@google.com    SkSrcPixelInfo srcPI;
6028fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org    srcPI.fColorType = kN32_SkColorType;
617111d463cee893a479280c7af41757e709e33ef5reed@google.com    srcPI.fAlphaType = kPremul_SkAlphaType;
62775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein    srcPI.fPixels = ctable->readColors();
637111d463cee893a479280c7af41757e709e33ef5reed@google.com    srcPI.fRowBytes = count * sizeof(SkPMColor);
647111d463cee893a479280c7af41757e709e33ef5reed@google.com
657111d463cee893a479280c7af41757e709e33ef5reed@google.com    srcPI.convertPixelsTo(&dstPI, count, 1);
667111d463cee893a479280c7af41757e709e33ef5reed@google.com
67ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    // always skip a full 256 number of entries, even if we memcpy'd fewer
68d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon    dst += 256 * sizeof(GrColor);
69ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
700ba4bf427acbd7707d04192a98c77ef194a0f25ascroggo@google.com    if ((unsigned)bitmap.width() == bitmap.rowBytes()) {
71ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        memcpy(dst, bitmap.getPixels(), bitmap.getSize());
72ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    } else {
73ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        // need to trim off the extra bytes per row
74ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        size_t width = bitmap.width();
75ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        size_t rowBytes = bitmap.rowBytes();
76ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        const char* src = (const char*)bitmap.getPixels();
77ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        for (int y = 0; y < bitmap.height(); y++) {
78ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            memcpy(dst, src, width);
79ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            src += rowBytes;
80ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            dst += width;
81ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
82ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
83ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
84ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
85ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com////////////////////////////////////////////////////////////////////////////////
86ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
8737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomonenum Stretch {
8837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    kNo_Stretch,
8937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    kBilerp_Stretch,
9037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    kNearest_Stretch
9137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon};
9237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
9337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomonstatic Stretch get_stretch_type(const GrContext* ctx, int width, int height,
9437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                                const GrTextureParams* params) {
9537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    if (params && params->isTiled()) {
96d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon        if (!ctx->npotTextureTileSupport() && (!SkIsPow2(width) || !SkIsPow2(height))) {
9737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon            switch(params->filterMode()) {
9837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                case GrTextureParams::kNone_FilterMode:
9937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                    return kNearest_Stretch;
10037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                case GrTextureParams::kBilerp_FilterMode:
10137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                case GrTextureParams::kMipMap_FilterMode:
10237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                    return kBilerp_Stretch;
10337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon            }
10437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        }
10537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    }
10637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    return kNo_Stretch;
10737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon}
10837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
10923e619cf462b2a8a500f3ca750e099f79601f508bsalomonstatic bool make_stretched_key(const GrContentKey& origKey, Stretch stretch,
11023e619cf462b2a8a500f3ca750e099f79601f508bsalomon                               GrContentKey* stretchedKey) {
11137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    if (origKey.isValid() && kNo_Stretch != stretch) {
11237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        static const GrContentKey::Domain kDomain = GrContentKey::GenerateDomain();
11323e619cf462b2a8a500f3ca750e099f79601f508bsalomon        GrContentKey::Builder builder(stretchedKey, origKey, kDomain, 1);
11437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        builder[0] = stretch;
11537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        builder.finish();
11637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        return true;
11737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    }
11823e619cf462b2a8a500f3ca750e099f79601f508bsalomon    SkASSERT(!stretchedKey->isValid());
11937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    return false;
12037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon}
12137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
12223e619cf462b2a8a500f3ca750e099f79601f508bsalomonstatic void make_unstretched_key(const SkBitmap& bitmap, GrContentKey* key) {
1230797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    // Our id includes the offset, width, and height so that bitmaps created by extractSubset()
1240797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    // are unique.
1250797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    uint32_t genID = bitmap.getGenerationID();
126672588b684d484dce6ae251e9e163e4a46924322reed@google.com    SkIPoint origin = bitmap.pixelRefOrigin();
12724db3b1c35fb935660229da164fc5ad31977387fbsalomon    uint32_t width = SkToU16(bitmap.width());
12824db3b1c35fb935660229da164fc5ad31977387fbsalomon    uint32_t height = SkToU16(bitmap.height());
12924db3b1c35fb935660229da164fc5ad31977387fbsalomon
13024db3b1c35fb935660229da164fc5ad31977387fbsalomon    static const GrContentKey::Domain kDomain = GrContentKey::GenerateDomain();
13124db3b1c35fb935660229da164fc5ad31977387fbsalomon    GrContentKey::Builder builder(key, kDomain, 4);
13224db3b1c35fb935660229da164fc5ad31977387fbsalomon    builder[0] = genID;
13324db3b1c35fb935660229da164fc5ad31977387fbsalomon    builder[1] = origin.fX;
13424db3b1c35fb935660229da164fc5ad31977387fbsalomon    builder[2] = origin.fY;
13524db3b1c35fb935660229da164fc5ad31977387fbsalomon    builder[3] = width | (height << 16);
13623e619cf462b2a8a500f3ca750e099f79601f508bsalomon}
13737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
13823e619cf462b2a8a500f3ca750e099f79601f508bsalomonstatic void make_bitmap_keys(const SkBitmap& bitmap,
13923e619cf462b2a8a500f3ca750e099f79601f508bsalomon                             Stretch stretch,
14023e619cf462b2a8a500f3ca750e099f79601f508bsalomon                             GrContentKey* key,
14123e619cf462b2a8a500f3ca750e099f79601f508bsalomon                             GrContentKey* stretchedKey) {
14223e619cf462b2a8a500f3ca750e099f79601f508bsalomon    make_unstretched_key(bitmap, key);
14337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    if (kNo_Stretch != stretch) {
14423e619cf462b2a8a500f3ca750e099f79601f508bsalomon        make_stretched_key(*key, stretch, stretchedKey);
14537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    }
1460797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com}
1470797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com
148f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomonstatic void generate_bitmap_texture_desc(const SkBitmap& bitmap, GrSurfaceDesc* desc) {
149f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon    desc->fFlags = kNone_GrSurfaceFlags;
1500797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    desc->fWidth = bitmap.width();
1510797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    desc->fHeight = bitmap.height();
1523adcc3403377c0b9a7afde6db8e0432325413a10commit-bot@chromium.org    desc->fConfig = SkImageInfo2GrPixelConfig(bitmap.info());
1530797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    desc->fSampleCnt = 0;
1540797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com}
1550797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com
15650a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgnamespace {
15750a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
15850a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org// When the SkPixelRef genID changes, invalidate a corresponding GrResource described by key.
15923e619cf462b2a8a500f3ca750e099f79601f508bsalomonclass BitmapInvalidator : public SkPixelRef::GenIDChangeListener {
16050a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgpublic:
16123e619cf462b2a8a500f3ca750e099f79601f508bsalomon    explicit BitmapInvalidator(const GrContentKey& key) : fMsg(key) {}
16250a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgprivate:
16323e619cf462b2a8a500f3ca750e099f79601f508bsalomon    GrContentKeyInvalidatedMessage fMsg;
16450a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
16572c9faab45124e08c85f70ca38536914862d947cmtklein    void onChange() SK_OVERRIDE {
16623e619cf462b2a8a500f3ca750e099f79601f508bsalomon        SkMessageBus<GrContentKeyInvalidatedMessage>::Post(fMsg);
16750a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    }
16850a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org};
16950a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
17050a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org}  // namespace
17150a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
17250a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
17337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomonstatic GrTexture* create_texture_for_bmp(GrContext* ctx,
17437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                                         const GrContentKey& optionalKey,
175f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon                                         GrSurfaceDesc desc,
17623e619cf462b2a8a500f3ca750e099f79601f508bsalomon                                         SkPixelRef* pixelRefForInvalidationNotification,
1770249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi                                         const void* pixels,
1780249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi                                         size_t rowBytes) {
179d0423587ac56ae84d3f1eb796d5c1e2dfba9646ebsalomon    GrTexture* result = ctx->createTexture(desc, true, pixels, rowBytes);
180d0423587ac56ae84d3f1eb796d5c1e2dfba9646ebsalomon    if (result && optionalKey.isValid()) {
18123e619cf462b2a8a500f3ca750e099f79601f508bsalomon        BitmapInvalidator* listener = SkNEW_ARGS(BitmapInvalidator, (optionalKey));
18223e619cf462b2a8a500f3ca750e099f79601f508bsalomon        pixelRefForInvalidationNotification->addGenIDChangeListener(listener);
183d0423587ac56ae84d3f1eb796d5c1e2dfba9646ebsalomon        SkAssertResult(ctx->addResourceToCache(optionalKey, result));
1840249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi    }
1850249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi    return result;
1860249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi}
1870249ec267a7c4f31b1f19668c176c2e3e33b7e19sugoi
18837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon// creates a new texture that is the input texture scaled up to the next power of two in
18937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon// width or height. If optionalKey is valid it will be set on the new texture. stretch
19037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon// controls whether the scaling is done using nearest or bilerp filtering.
19123e619cf462b2a8a500f3ca750e099f79601f508bsalomonGrTexture* stretch_texture_to_next_pot(GrTexture* inputTexture, Stretch stretch,
19223e619cf462b2a8a500f3ca750e099f79601f508bsalomon                                       SkPixelRef* pixelRef,
19323e619cf462b2a8a500f3ca750e099f79601f508bsalomon                                       const GrContentKey& optionalKey) {
19437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    SkASSERT(kNo_Stretch != stretch);
19537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
19637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    GrContext* context = inputTexture->getContext();
19737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    SkASSERT(context);
19837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
19937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    // Either it's a cache miss or the original wasn't cached to begin with.
20037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    GrSurfaceDesc rtDesc = inputTexture->desc();
20137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    rtDesc.fFlags =  rtDesc.fFlags |
20237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                     kRenderTarget_GrSurfaceFlag |
20337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                     kNoStencil_GrSurfaceFlag;
20437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    rtDesc.fWidth  = GrNextPow2(rtDesc.fWidth);
20537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    rtDesc.fHeight = GrNextPow2(rtDesc.fHeight);
20637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    rtDesc.fConfig = GrMakePixelConfigUncompressed(rtDesc.fConfig);
20737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
20837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    // If the config isn't renderable try converting to either A8 or an 32 bit config. Otherwise,
20937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    // fail.
21037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    if (!context->isConfigRenderable(rtDesc.fConfig, false)) {
21137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        if (GrPixelConfigIsAlphaOnly(rtDesc.fConfig)) {
21237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon            if (context->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
21337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                rtDesc.fConfig = kAlpha_8_GrPixelConfig;
21437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon            } else if (context->isConfigRenderable(kSkia8888_GrPixelConfig, false)) {
21537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                rtDesc.fConfig = kSkia8888_GrPixelConfig;
21637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon            } else {
21737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                return NULL;
21837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon            }
21937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        } else if (kRGB_GrColorComponentFlags ==
22037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                   (kRGB_GrColorComponentFlags & GrPixelConfigComponentMask(rtDesc.fConfig))) {
22137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon            if (context->isConfigRenderable(kSkia8888_GrPixelConfig, false)) {
22237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                rtDesc.fConfig = kSkia8888_GrPixelConfig;
22337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon            } else {
22437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                return NULL;
22537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon            }
22637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        } else {
22737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon            return NULL;
22837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        }
22937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    }
23037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
23123e619cf462b2a8a500f3ca750e099f79601f508bsalomon    GrTexture* stretched = create_texture_for_bmp(context, optionalKey, rtDesc, pixelRef, NULL, 0);
23237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
23323e619cf462b2a8a500f3ca750e099f79601f508bsalomon    if (!stretched) {
23437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        return NULL;
23537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    }
23637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    GrPaint paint;
23737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
23837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    // If filtering is not desired then we want to ensure all texels in the resampled image are
23937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    // copies of texels from the original.
24037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    GrTextureParams params(SkShader::kClamp_TileMode,
24137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                           kBilerp_Stretch == stretch ? GrTextureParams::kBilerp_FilterMode :
24237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                                                        GrTextureParams::kNone_FilterMode);
24337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    paint.addColorTextureProcessor(inputTexture, SkMatrix::I(), params);
24437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
24537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    SkRect rect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtDesc.fHeight));
24637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    SkRect localRect = SkRect::MakeWH(1.f, 1.f);
24737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
24823e619cf462b2a8a500f3ca750e099f79601f508bsalomon    GrContext::AutoRenderTarget autoRT(context, stretched->asRenderTarget());
24937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    GrContext::AutoClip ac(context, GrContext::AutoClip::kWideOpen_InitialClip);
25037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    context->drawNonAARectToRect(paint, SkMatrix::I(), rect, localRect);
25137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
25223e619cf462b2a8a500f3ca750e099f79601f508bsalomon    return stretched;
25337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon}
25437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
2558c111f783f40470e697310244426362132979ad9krajcevski#ifndef SK_IGNORE_ETC1_SUPPORT
25637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomonstatic GrTexture *load_etc1_texture(GrContext* ctx, const GrContentKey& optionalKey,
257f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon                                    const SkBitmap &bm, GrSurfaceDesc desc) {
25899ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski    SkAutoTUnref<SkData> data(bm.pixelRef()->refEncodedData());
2599c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
2609c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski    // Is this even encoded data?
2619c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski    if (NULL == data) {
2629c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski        return NULL;
2639c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski    }
2649c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
2659c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski    // Is this a valid PKM encoded data?
2669c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski    const uint8_t *bytes = data->bytes();
26799ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski    if (etc1_pkm_is_valid(bytes)) {
26899ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        uint32_t encodedWidth = etc1_pkm_get_width(bytes);
26999ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        uint32_t encodedHeight = etc1_pkm_get_height(bytes);
27099ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski
27199ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        // Does the data match the dimensions of the bitmap? If not,
27299ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        // then we don't know how to scale the image to match it...
27399ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        if (encodedWidth != static_cast<uint32_t>(bm.width()) ||
27499ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski            encodedHeight != static_cast<uint32_t>(bm.height())) {
27599ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski            return NULL;
27699ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        }
27799ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski
27899ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        // Everything seems good... skip ahead to the data.
27999ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        bytes += ETC_PKM_HEADER_SIZE;
28099ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        desc.fConfig = kETC1_GrPixelConfig;
28199ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski    } else if (SkKTXFile::is_ktx(bytes)) {
28299ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        SkKTXFile ktx(data);
2839c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
28499ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        // Is it actually an ETC1 texture?
28540a1e11ebebe81586f3fec96408fdfd4b51123d2krajcevski        if (!ktx.isCompressedFormat(SkTextureCompressor::kETC1_Format)) {
28699ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski            return NULL;
28799ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        }
28899ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski
28999ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        // Does the data match the dimensions of the bitmap? If not,
29099ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        // then we don't know how to scale the image to match it...
29199ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        if (ktx.width() != bm.width() || ktx.height() != bm.height()) {
29299ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski            return NULL;
293775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein        }
2949c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
29599ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        bytes = ktx.pixelData();
29699ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski        desc.fConfig = kETC1_GrPixelConfig;
29799ffe24200d8940ceba20f6fbf8c460f994d3cd1krajcevski    } else {
2989c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski        return NULL;
2999c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski    }
3009c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
30123e619cf462b2a8a500f3ca750e099f79601f508bsalomon    return create_texture_for_bmp(ctx, optionalKey, desc, bm.pixelRef(), bytes, 0);
3029c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski}
3038c111f783f40470e697310244426362132979ad9krajcevski#endif   // SK_IGNORE_ETC1_SUPPORT
3049c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
30537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomonstatic GrTexture* load_yuv_texture(GrContext* ctx, const GrContentKey& optionalKey,
306f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon                                   const SkBitmap& bm, const GrSurfaceDesc& desc) {
307ff58e4679b9473ce19abb81a3e50fc6a18f0981dsugoi    // Subsets are not supported, the whole pixelRef is loaded when using YUV decoding
308518d83dbc1c899e316e8c896af5defb58b83120fsugoi    SkPixelRef* pixelRef = bm.pixelRef();
309692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi    if ((NULL == pixelRef) ||
310692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi        (pixelRef->info().width()  != bm.info().width()) ||
311692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi        (pixelRef->info().height() != bm.info().height())) {
312518d83dbc1c899e316e8c896af5defb58b83120fsugoi        return NULL;
313518d83dbc1c899e316e8c896af5defb58b83120fsugoi    }
314518d83dbc1c899e316e8c896af5defb58b83120fsugoi
315ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi    const bool useCache = optionalKey.isValid();
316692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi    SkYUVPlanesCache::Info yuvInfo;
317ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi    SkAutoTUnref<SkCachedData> cachedData;
318ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi    SkAutoMalloc storage;
319ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi    if (useCache) {
320ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi        cachedData.reset(SkYUVPlanesCache::FindAndRef(pixelRef->getGenerationID(), &yuvInfo));
321ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi    }
322692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi
323518d83dbc1c899e316e8c896af5defb58b83120fsugoi    void* planes[3];
324ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi    if (cachedData.get()) {
325692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi        planes[0] = (void*)cachedData->data();
326692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi        planes[1] = (uint8_t*)planes[0] + yuvInfo.fSizeInMemory[0];
327692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi        planes[2] = (uint8_t*)planes[1] + yuvInfo.fSizeInMemory[1];
328692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi    } else {
329692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi        // Fetch yuv plane sizes for memory allocation. Here, width and height can be
330692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi        // rounded up to JPEG block size and be larger than the image's width and height.
331692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi        if (!pixelRef->getYUV8Planes(yuvInfo.fSize, NULL, NULL, NULL)) {
332692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi            return NULL;
333692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi        }
334518d83dbc1c899e316e8c896af5defb58b83120fsugoi
335692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi        // Allocate the memory for YUV
336692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi        size_t totalSize(0);
337692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi        for (int i = 0; i < 3; ++i) {
338692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi            yuvInfo.fRowBytes[i] = yuvInfo.fSize[i].fWidth;
339692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi            yuvInfo.fSizeInMemory[i] = yuvInfo.fRowBytes[i] * yuvInfo.fSize[i].fHeight;
340692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi            totalSize += yuvInfo.fSizeInMemory[i];
341692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi        }
342ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi        if (useCache) {
343ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi            cachedData.reset(SkResourceCache::NewCachedData(totalSize));
344ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi            planes[0] = cachedData->writable_data();
345ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi        } else {
346ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi            storage.reset(totalSize);
347ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi            planes[0] = storage.get();
348ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi        }
349692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi        planes[1] = (uint8_t*)planes[0] + yuvInfo.fSizeInMemory[0];
350692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi        planes[2] = (uint8_t*)planes[1] + yuvInfo.fSizeInMemory[1];
351692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi
352692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi        // Get the YUV planes and update plane sizes to actual image size
353692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi        if (!pixelRef->getYUV8Planes(yuvInfo.fSize, planes, yuvInfo.fRowBytes,
354692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi                                     &yuvInfo.fColorSpace)) {
355692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi            return NULL;
356692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi        }
357abaef86f2b37d8a939506a2076da07f6db456951rileya
358ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi        if (useCache) {
359ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi            // Decoding is done, cache the resulting YUV planes
360ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi            SkYUVPlanesCache::Add(pixelRef->getGenerationID(), cachedData, &yuvInfo);
361ba18f91b9f025dc53ab3cb19ea1407c55ad85937sugoi        }
362518d83dbc1c899e316e8c896af5defb58b83120fsugoi    }
363518d83dbc1c899e316e8c896af5defb58b83120fsugoi
364f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon    GrSurfaceDesc yuvDesc;
365518d83dbc1c899e316e8c896af5defb58b83120fsugoi    yuvDesc.fConfig = kAlpha_8_GrPixelConfig;
366e30597375c19dfb5197fd065a3d1768401eb00fabsalomon    SkAutoTUnref<GrTexture> yuvTextures[3];
367518d83dbc1c899e316e8c896af5defb58b83120fsugoi    for (int i = 0; i < 3; ++i) {
368692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi        yuvDesc.fWidth  = yuvInfo.fSize[i].fWidth;
369692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi        yuvDesc.fHeight = yuvInfo.fSize[i].fHeight;
370e30597375c19dfb5197fd065a3d1768401eb00fabsalomon        yuvTextures[i].reset(
371e30597375c19dfb5197fd065a3d1768401eb00fabsalomon            ctx->refScratchTexture(yuvDesc, GrContext::kApprox_ScratchTexMatch));
372e30597375c19dfb5197fd065a3d1768401eb00fabsalomon        if (!yuvTextures[i] ||
373e30597375c19dfb5197fd065a3d1768401eb00fabsalomon            !yuvTextures[i]->writePixels(0, 0, yuvDesc.fWidth, yuvDesc.fHeight,
374692135f9689d4dcb5ba91ff8f4899e268c0bfe11sugoi                                         yuvDesc.fConfig, planes[i], yuvInfo.fRowBytes[i])) {
375518d83dbc1c899e316e8c896af5defb58b83120fsugoi            return NULL;
376518d83dbc1c899e316e8c896af5defb58b83120fsugoi        }
377518d83dbc1c899e316e8c896af5defb58b83120fsugoi    }
378518d83dbc1c899e316e8c896af5defb58b83120fsugoi
379f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon    GrSurfaceDesc rtDesc = desc;
380518d83dbc1c899e316e8c896af5defb58b83120fsugoi    rtDesc.fFlags = rtDesc.fFlags |
381f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon                    kRenderTarget_GrSurfaceFlag |
382f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon                    kNoStencil_GrSurfaceFlag;
383518d83dbc1c899e316e8c896af5defb58b83120fsugoi
38423e619cf462b2a8a500f3ca750e099f79601f508bsalomon    GrTexture* result = create_texture_for_bmp(ctx, optionalKey, rtDesc, pixelRef, NULL, 0);
38537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    if (!result) {
38637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        return NULL;
387518d83dbc1c899e316e8c896af5defb58b83120fsugoi    }
388518d83dbc1c899e316e8c896af5defb58b83120fsugoi
38937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    GrRenderTarget* renderTarget = result->asRenderTarget();
39037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    SkASSERT(renderTarget);
39137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
39237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    SkAutoTUnref<GrFragmentProcessor>
39337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        yuvToRgbProcessor(GrYUVtoRGBEffect::Create(yuvTextures[0], yuvTextures[1], yuvTextures[2],
39437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                                                   yuvInfo.fColorSpace));
39537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    GrPaint paint;
39637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    paint.addColorProcessor(yuvToRgbProcessor);
39737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    SkRect r = SkRect::MakeWH(SkIntToScalar(yuvInfo.fSize[0].fWidth),
39837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                              SkIntToScalar(yuvInfo.fSize[0].fHeight));
39937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    GrContext::AutoRenderTarget autoRT(ctx, renderTarget);
40037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    GrContext::AutoClip ac(ctx, GrContext::AutoClip::kWideOpen_InitialClip);
40137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    ctx->drawRect(paint, SkMatrix::I(), r);
40237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
403518d83dbc1c899e316e8c896af5defb58b83120fsugoi    return result;
404518d83dbc1c899e316e8c896af5defb58b83120fsugoi}
405518d83dbc1c899e316e8c896af5defb58b83120fsugoi
40637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomonstatic GrTexture* create_unstretched_bitmap_texture(GrContext* ctx,
40737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                                                    const SkBitmap& origBitmap,
40837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                                                    const GrContentKey& optionalKey) {
409ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    SkBitmap tmpBitmap;
410ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
411ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    const SkBitmap* bitmap = &origBitmap;
4125782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
413f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon    GrSurfaceDesc desc;
4140797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    generate_bitmap_texture_desc(*bitmap, &desc);
4155782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
4160689d7b12e7c427a077b003d3d8ae759d86f798freed    if (kIndex_8_SkColorType == bitmap->colorType()) {
417d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon        if (ctx->isConfigTexturable(kIndex_8_GrPixelConfig)) {
418d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon            size_t imageSize = GrCompressedFormatDataSize(kIndex_8_GrPixelConfig,
419d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon                                                          bitmap->width(), bitmap->height());
420d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon            SkAutoMalloc storage(imageSize);
421e79a2dab91a90e26b13bc1ec9b8c6264a1ab22e4bsalomon            build_index8_data(storage.get(), origBitmap);
422ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
423ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            // our compressed data will be trimmed, so pass width() for its
424ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            // "rowBytes", since they are the same now.
42523e619cf462b2a8a500f3ca750e099f79601f508bsalomon            return create_texture_for_bmp(ctx, optionalKey, desc, origBitmap.pixelRef(),
42623e619cf462b2a8a500f3ca750e099f79601f508bsalomon                                          storage.get(), bitmap->width());
427ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        } else {
42828fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org            origBitmap.copyTo(&tmpBitmap, kN32_SkColorType);
429ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            // now bitmap points to our temp, which has been promoted to 32bits
430ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            bitmap = &tmpBitmap;
4313adcc3403377c0b9a7afde6db8e0432325413a10commit-bot@chromium.org            desc.fConfig = SkImageInfo2GrPixelConfig(bitmap->info());
432ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
433309e86912445879651d52ebbedb67b4ff3f1516ckrajcevski    }
4349c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
4359c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski    // Is this an ETC1 encoded texture?
4368c111f783f40470e697310244426362132979ad9krajcevski#ifndef SK_IGNORE_ETC1_SUPPORT
437d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon    // Make sure that the underlying device supports ETC1 textures before we go ahead
438d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon    // and check the data.
439d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon    else if (ctx->isConfigTexturable(kETC1_GrPixelConfig)
440d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon            // If the bitmap had compressed data and was then uncompressed, it'll still return
441d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon            // compressed data on 'refEncodedData' and upload it. Probably not good, since if
442d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon            // the bitmap has available pixels, then they might not be what the decompressed
443d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon            // data is.
444d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon            && !(bitmap->readyToDraw())) {
44537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        GrTexture *texture = load_etc1_texture(ctx, optionalKey, *bitmap, desc);
44649f085dddff10473b6ebf832a974288300224e60bsalomon        if (texture) {
4479c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski            return texture;
4489c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski        }
4495782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    }
4508c111f783f40470e697310244426362132979ad9krajcevski#endif   // SK_IGNORE_ETC1_SUPPORT
451ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
452d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon    GrTexture *texture = load_yuv_texture(ctx, optionalKey, *bitmap, desc);
453d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon    if (texture) {
454d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon        return texture;
455518d83dbc1c899e316e8c896af5defb58b83120fsugoi    }
456d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon
4577f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com    SkAutoLockPixels alp(*bitmap);
4587f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com    if (!bitmap->readyToDraw()) {
4597f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com        return NULL;
4607f4ad5a30ff745e666579d2b518dfd0c1aa49596bsalomon@google.com    }
46150a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
46223e619cf462b2a8a500f3ca750e099f79601f508bsalomon    return create_texture_for_bmp(ctx, optionalKey, desc, origBitmap.pixelRef(),
46323e619cf462b2a8a500f3ca750e099f79601f508bsalomon                                  bitmap->getPixels(), bitmap->rowBytes());
46437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon}
46537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
46637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomonstatic GrTexture* create_bitmap_texture(GrContext* ctx,
46737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                                        const SkBitmap& bmp,
46837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                                        Stretch stretch,
46937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                                        const GrContentKey& unstretchedKey,
47037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                                        const GrContentKey& stretchedKey) {
47137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    if (kNo_Stretch != stretch) {
47237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        SkAutoTUnref<GrTexture> unstretched;
47337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        // Check if we have the unstretched version in the cache, if not create it.
47437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        if (unstretchedKey.isValid()) {
47537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon            unstretched.reset(ctx->findAndRefCachedTexture(unstretchedKey));
47637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        }
47737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        if (!unstretched) {
47837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon            unstretched.reset(create_unstretched_bitmap_texture(ctx, bmp, unstretchedKey));
47937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon            if (!unstretched) {
48037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                return NULL;
48137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon            }
48237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        }
48323e619cf462b2a8a500f3ca750e099f79601f508bsalomon        GrTexture* stretched = stretch_texture_to_next_pot(unstretched, stretch, bmp.pixelRef(),
48423e619cf462b2a8a500f3ca750e099f79601f508bsalomon                                                           stretchedKey);
48523e619cf462b2a8a500f3ca750e099f79601f508bsalomon        return stretched;
48637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    }
48737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
48837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    return create_unstretched_bitmap_texture(ctx, bmp, unstretchedKey);
48937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
490ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
491ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
4920797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.combool GrIsBitmapInCache(const GrContext* ctx,
4930797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com                       const SkBitmap& bitmap,
4940797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com                       const GrTextureParams* params) {
49588425565259809bc1b0aac116d87f3fc8d212f43bsalomon    Stretch stretch = get_stretch_type(ctx, bitmap.width(), bitmap.height(), params);
49688425565259809bc1b0aac116d87f3fc8d212f43bsalomon
49788425565259809bc1b0aac116d87f3fc8d212f43bsalomon    // Handle the case where the bitmap is explicitly texture backed.
49888425565259809bc1b0aac116d87f3fc8d212f43bsalomon    GrTexture* texture = bitmap.getTexture();
49988425565259809bc1b0aac116d87f3fc8d212f43bsalomon    if (texture) {
50088425565259809bc1b0aac116d87f3fc8d212f43bsalomon        if (kNo_Stretch == stretch) {
50188425565259809bc1b0aac116d87f3fc8d212f43bsalomon            return true;
50288425565259809bc1b0aac116d87f3fc8d212f43bsalomon        }
50388425565259809bc1b0aac116d87f3fc8d212f43bsalomon        // No keys for volatile bitmaps.
50488425565259809bc1b0aac116d87f3fc8d212f43bsalomon        if (bitmap.isVolatile()) {
50588425565259809bc1b0aac116d87f3fc8d212f43bsalomon            return false;
50688425565259809bc1b0aac116d87f3fc8d212f43bsalomon        }
50788425565259809bc1b0aac116d87f3fc8d212f43bsalomon        const GrContentKey& key = texture->getContentKey();
50888425565259809bc1b0aac116d87f3fc8d212f43bsalomon        if (!key.isValid()) {
50988425565259809bc1b0aac116d87f3fc8d212f43bsalomon            return false;
51088425565259809bc1b0aac116d87f3fc8d212f43bsalomon        }
51123e619cf462b2a8a500f3ca750e099f79601f508bsalomon        GrContentKey stretchedKey;
51223e619cf462b2a8a500f3ca750e099f79601f508bsalomon        make_stretched_key(key, stretch, &stretchedKey);
51323e619cf462b2a8a500f3ca750e099f79601f508bsalomon        return ctx->isResourceInCache(stretchedKey);
5149ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon    }
5159ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon
51637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    // We don't cache volatile bitmaps
51737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    if (bitmap.isVolatile()) {
51837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        return false;
51937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    }
52037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
52123e619cf462b2a8a500f3ca750e099f79601f508bsalomon    GrContentKey key, stretchedKey;
52223e619cf462b2a8a500f3ca750e099f79601f508bsalomon    make_bitmap_keys(bitmap, stretch, &key, &stretchedKey);
52323e619cf462b2a8a500f3ca750e099f79601f508bsalomon    return ctx->isResourceInCache((kNo_Stretch == stretch) ? key : stretchedKey);
5240797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com}
525ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
526bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomonGrTexture* GrRefCachedBitmapTexture(GrContext* ctx,
527bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon                                    const SkBitmap& bitmap,
528bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon                                    const GrTextureParams* params) {
52988425565259809bc1b0aac116d87f3fc8d212f43bsalomon
53088425565259809bc1b0aac116d87f3fc8d212f43bsalomon    Stretch stretch = get_stretch_type(ctx, bitmap.width(), bitmap.height(), params);
53188425565259809bc1b0aac116d87f3fc8d212f43bsalomon
53288425565259809bc1b0aac116d87f3fc8d212f43bsalomon    GrTexture* result = bitmap.getTexture();
5339ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon    if (result) {
53488425565259809bc1b0aac116d87f3fc8d212f43bsalomon        if (kNo_Stretch == stretch) {
53588425565259809bc1b0aac116d87f3fc8d212f43bsalomon            return SkRef(result);
53688425565259809bc1b0aac116d87f3fc8d212f43bsalomon        }
53723e619cf462b2a8a500f3ca750e099f79601f508bsalomon        GrContentKey stretchedKey;
53888425565259809bc1b0aac116d87f3fc8d212f43bsalomon        // Don't create a key for the resized version if the bmp is volatile.
53988425565259809bc1b0aac116d87f3fc8d212f43bsalomon        if (!bitmap.isVolatile()) {
54088425565259809bc1b0aac116d87f3fc8d212f43bsalomon            const GrContentKey& key = result->getContentKey();
54188425565259809bc1b0aac116d87f3fc8d212f43bsalomon            if (key.isValid()) {
54223e619cf462b2a8a500f3ca750e099f79601f508bsalomon                make_stretched_key(key, stretch, &stretchedKey);
54323e619cf462b2a8a500f3ca750e099f79601f508bsalomon                GrTexture* stretched = ctx->findAndRefCachedTexture(stretchedKey);
54488425565259809bc1b0aac116d87f3fc8d212f43bsalomon                if (stretched) {
54588425565259809bc1b0aac116d87f3fc8d212f43bsalomon                    return stretched;
54688425565259809bc1b0aac116d87f3fc8d212f43bsalomon                }
54788425565259809bc1b0aac116d87f3fc8d212f43bsalomon            }
54888425565259809bc1b0aac116d87f3fc8d212f43bsalomon        }
54923e619cf462b2a8a500f3ca750e099f79601f508bsalomon        return stretch_texture_to_next_pot(result, stretch, bitmap.pixelRef(), stretchedKey);
5509ed7f573491217079cccf1d81792cf4520a3c0d0bsalomon    }
55124f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com
55237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    GrContentKey key, resizedKey;
5539c2ea846351a29208cb4a36301ee611e7fb384earobertphillips@google.com
55437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    if (!bitmap.isVolatile()) {
5550797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com        // If the bitmap isn't changing try to find a cached copy first.
55623e619cf462b2a8a500f3ca750e099f79601f508bsalomon        make_bitmap_keys(bitmap, stretch, &key, &resizedKey);
5574b86e3428b115202e82d49a0914ea8ab6dc25940bsalomon@google.com
55837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        result = ctx->findAndRefCachedTexture(resizedKey.isValid() ? resizedKey : key);
55937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        if (result) {
56037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon            return result;
56137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        }
562e137db8569e7a10d809980609688b3acfaec612absalomon    }
56337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
56437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    result = create_bitmap_texture(ctx, bitmap, stretch, key, resizedKey);
56537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    if (result) {
56637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon        return result;
567e137db8569e7a10d809980609688b3acfaec612absalomon    }
568e137db8569e7a10d809980609688b3acfaec612absalomon
56937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    SkDebugf("---- failed to create texture for cache [%d %d]\n",
57037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon                bitmap.width(), bitmap.height());
57137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
57237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    return NULL;
57337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon}
57424f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com///////////////////////////////////////////////////////////////////////////////
57524f3ad1bbb44916cae33f5d3cf2a20af4bbc381frileya@google.com
57615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org// alphatype is ignore for now, but if GrPixelConfig is expanded to encompass
57715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org// alpha info, that will be considered.
578fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverthGrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType, SkColorProfileType pt) {
57915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    switch (ct) {
58015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        case kUnknown_SkColorType:
58115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            return kUnknown_GrPixelConfig;
58215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        case kAlpha_8_SkColorType:
58315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            return kAlpha_8_GrPixelConfig;
58415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        case kRGB_565_SkColorType:
58515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            return kRGB_565_GrPixelConfig;
58615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        case kARGB_4444_SkColorType:
58715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            return kRGBA_4444_GrPixelConfig;
58815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        case kRGBA_8888_SkColorType:
589fe43c40d5dbfff6c3726404e4bb31e2f84a95c5cjvanverth//            if (kSRGB_SkColorProfileType == pt) {
590fe43c40d5dbfff6c3726404e4bb31e2f84a95c5cjvanverth//                return kSRGBA_8888_GrPixelConfig;
591fe43c40d5dbfff6c3726404e4bb31e2f84a95c5cjvanverth//            }
59215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            return kRGBA_8888_GrPixelConfig;
59315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        case kBGRA_8888_SkColorType:
59415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            return kBGRA_8888_GrPixelConfig;
59515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        case kIndex_8_SkColorType:
59615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            return kIndex_8_GrPixelConfig;
59715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    }
59815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    SkASSERT(0);    // shouldn't get here
59915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    return kUnknown_GrPixelConfig;
60015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org}
60115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org
602fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverthbool GrPixelConfig2ColorAndProfileType(GrPixelConfig config, SkColorType* ctOut,
603fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth                                       SkColorProfileType* ptOut) {
604bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    SkColorType ct;
605fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth    SkColorProfileType pt = kLinear_SkColorProfileType;
606bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    switch (config) {
607bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kAlpha_8_GrPixelConfig:
608bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kAlpha_8_SkColorType;
609bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
610bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kIndex_8_GrPixelConfig:
611bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kIndex_8_SkColorType;
612bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
613bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kRGB_565_GrPixelConfig:
614bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kRGB_565_SkColorType;
615bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
616bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kRGBA_4444_GrPixelConfig:
617bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kARGB_4444_SkColorType;
618bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
619bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kRGBA_8888_GrPixelConfig:
620bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kRGBA_8888_SkColorType;
621bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
622bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        case kBGRA_8888_GrPixelConfig:
623bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            ct = kBGRA_8888_SkColorType;
624bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            break;
625fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth        case kSRGBA_8888_GrPixelConfig:
626fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth            ct = kRGBA_8888_SkColorType;
627fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth            pt = kSRGB_SkColorProfileType;
628fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth            break;
629bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        default:
630bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com            return false;
631bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    }
632bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    if (ctOut) {
633bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        *ctOut = ct;
634bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    }
635fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth    if (ptOut) {
636fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth        *ptOut = pt;
637fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth    }
638bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    return true;
639bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com}
6408dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
6418dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////////
6428dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
64383d081ae1d731b5039e99823620f5e287542ee39bsalomonvoid SkPaint2GrPaintNoShader(GrContext* context, const SkPaint& skPaint, GrColor paintColor,
6448dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org                             bool constantColor, GrPaint* grPaint) {
6458dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
6468dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    grPaint->setDither(skPaint.isDither());
6478dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    grPaint->setAntiAlias(skPaint.isAntiAlias());
6488dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
6498dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    SkXfermode* mode = skPaint.getXfermode();
650378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel    GrXPFactory* xpFactory = NULL;
65158136167fc596fb945b58b34f500cf370c0dec7cegdaniel    if (!SkXfermode::AsXPFactory(mode, &xpFactory)) {
6528dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org        // Fall back to src-over
653c016fb8f9fb53dd8d4936c5e9e16a9dc99ab392eegdaniel        xpFactory = GrPorterDuffXPFactory::Create(SkXfermode::kSrcOver_Mode);
6548dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    }
655378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel    SkASSERT(xpFactory);
656378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel    grPaint->setXPFactory(xpFactory)->unref();
657775b8199a214af57c3ea7969e9d456f5f3eb137fmtklein
6589de5b514d38c5b36066bcdc14fba2f7e5196d372dandov    //set the color of the paint to the one of the parameter
65983d081ae1d731b5039e99823620f5e287542ee39bsalomon    grPaint->setColor(paintColor);
6608dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
6618dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    SkColorFilter* colorFilter = skPaint.getColorFilter();
66249f085dddff10473b6ebf832a974288300224e60bsalomon    if (colorFilter) {
6638dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org        // if the source color is a constant then apply the filter here once rather than per pixel
6648dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org        // in a shader.
6658dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org        if (constantColor) {
6668dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org            SkColor filtered = colorFilter->filterColor(skPaint.getColor());
6678dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org            grPaint->setColor(SkColor2GrColor(filtered));
6688dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org        } else {
669b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt            SkAutoTUnref<GrFragmentProcessor> fp(colorFilter->asFragmentProcessor(context));
670b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt            if (fp.get()) {
671b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                grPaint->addColorProcessor(fp);
6728dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org            }
6738dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org        }
6748dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    }
675f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
676f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#ifndef SK_IGNORE_GPU_DITHER
677f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    // If the dither flag is set, then we need to see if the underlying context
678f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    // supports it. If not, then install a dither effect.
679f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    if (skPaint.isDither() && grPaint->numColorStages() > 0) {
680f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        // What are we rendering into?
681f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        const GrRenderTarget *target = context->getRenderTarget();
68249f085dddff10473b6ebf832a974288300224e60bsalomon        SkASSERT(target);
683f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
684f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        // Suspect the dithering flag has no effect on these configs, otherwise
685f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        // fall back on setting the appropriate state.
686f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        if (target->config() == kRGBA_8888_GrPixelConfig ||
687f461a8fdf642ba713dcdfb217534652df1eac278krajcevski            target->config() == kBGRA_8888_GrPixelConfig) {
688f461a8fdf642ba713dcdfb217534652df1eac278krajcevski            // The dither flag is set and the target is likely
689f461a8fdf642ba713dcdfb217534652df1eac278krajcevski            // not going to be dithered by the GPU.
690b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt            SkAutoTUnref<GrFragmentProcessor> fp(GrDitherEffect::Create());
691b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt            if (fp.get()) {
692b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                grPaint->addColorProcessor(fp);
693f461a8fdf642ba713dcdfb217534652df1eac278krajcevski                grPaint->setDither(false);
694f461a8fdf642ba713dcdfb217534652df1eac278krajcevski            }
695f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        }
696f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    }
697f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#endif
6988dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org}
6998dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
7005531d51ce7426bdae7563547326fcf0bf926a083joshualittvoid SkPaint2GrPaintShader(GrContext* context, const SkPaint& skPaint, const SkMatrix& viewM,
7018dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org                           bool constantColor, GrPaint* grPaint) {
7028dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    SkShader* shader = skPaint.getShader();
7038dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    if (NULL == shader) {
7049de5b514d38c5b36066bcdc14fba2f7e5196d372dandov        SkPaint2GrPaintNoShader(context, skPaint, SkColor2GrColor(skPaint.getColor()),
7059de5b514d38c5b36066bcdc14fba2f7e5196d372dandov                                constantColor, grPaint);
7068dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org        return;
7078dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    }
7088dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org
70983d081ae1d731b5039e99823620f5e287542ee39bsalomon    GrColor paintColor = SkColor2GrColor(skPaint.getColor());
710f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
711f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    // Start a new block here in order to preserve our context state after calling
712b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    // asFragmentProcessor(). Since these calls get passed back to the client, we don't really
713f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    // want them messing around with the context.
714f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    {
715b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        // SkShader::asFragmentProcessor() may do offscreen rendering. Save off the current RT,
7165531d51ce7426bdae7563547326fcf0bf926a083joshualitt        // and clip
717f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        GrContext::AutoRenderTarget art(context, NULL);
718f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        GrContext::AutoClip ac(context, GrContext::AutoClip::kWideOpen_InitialClip);
719f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
72083d081ae1d731b5039e99823620f5e287542ee39bsalomon        // Allow the shader to modify paintColor and also create an effect to be installed as
72183d081ae1d731b5039e99823620f5e287542ee39bsalomon        // the first color effect on the GrPaint.
722b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        GrFragmentProcessor* fp = NULL;
7235531d51ce7426bdae7563547326fcf0bf926a083joshualitt        if (shader->asFragmentProcessor(context, skPaint, viewM, NULL, &paintColor, &fp) && fp) {
724b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt            grPaint->addColorProcessor(fp)->unref();
725f461a8fdf642ba713dcdfb217534652df1eac278krajcevski            constantColor = false;
726f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        }
7278dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org    }
728f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
729b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    // The grcolor is automatically set when calling asFragmentProcessor.
7309de5b514d38c5b36066bcdc14fba2f7e5196d372dandov    // If the shader can be seen as an effect it returns true and adds its effect to the grpaint.
73183d081ae1d731b5039e99823620f5e287542ee39bsalomon    SkPaint2GrPaintNoShader(context, skPaint, paintColor, constantColor, grPaint);
7328dcff6416969708952d663a47993f73957a00badcommit-bot@chromium.org}
733