1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h"
98b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h"
108b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h"
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPixelRef.h"
12b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com#include "SkErrorInternals.h"
133aad3b01afc77993ff051c02e49186294e312980humper@google.com#include "SkBitmapProcShader.h"
143aad3b01afc77993ff051c02e49186294e312980humper@google.com
1530df03ce784868b5920ed385e6e516b132606f37humper@google.com#if SK_SUPPORT_GPU
163aad3b01afc77993ff051c02e49186294e312980humper@google.com#include "effects/GrSimpleTextureEffect.h"
173aad3b01afc77993ff051c02e49186294e312980humper@google.com#include "effects/GrBicubicEffect.h"
1830df03ce784868b5920ed385e6e516b132606f37humper@google.com#endif
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkBitmapProcShader::CanDo(const SkBitmap& bm, TileMode tx, TileMode ty) {
21900ecf2f1579d42c9d2959831787af0346320f86reed@google.com    switch (bm.colorType()) {
22900ecf2f1579d42c9d2959831787af0346320f86reed@google.com        case kAlpha_8_SkColorType:
23900ecf2f1579d42c9d2959831787af0346320f86reed@google.com        case kRGB_565_SkColorType:
24900ecf2f1579d42c9d2959831787af0346320f86reed@google.com        case kIndex_8_SkColorType:
2528fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org        case kN32_SkColorType:
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    //        if (tx == ty && (kClamp_TileMode == tx || kRepeat_TileMode == tx))
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                return true;
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        default:
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return false;
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
349c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.orgSkBitmapProcShader::SkBitmapProcShader(const SkBitmap& src, TileMode tmx, TileMode tmy,
359c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org                                       const SkMatrix* localMatrix)
369c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org        : INHERITED(localMatrix) {
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fRawBitmap = src;
3887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    fTileModeX = (uint8_t)tmx;
3987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    fTileModeY = (uint8_t)tmy;
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
427c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.comSkShader::BitmapType SkBitmapProcShader::asABitmap(SkBitmap* texture,
437c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com                                                   SkMatrix* texM,
4491f319c5dc4493384f0a52aaeef3dcc311ef6ed0rileya@google.com                                                   TileMode xy[]) const {
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (texture) {
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *texture = fRawBitmap;
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (texM) {
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        texM->reset();
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (xy) {
5287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        xy[0] = (TileMode)fTileModeX;
5387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        xy[1] = (TileMode)fTileModeY;
548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
55f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    return kDefault_BitmapType;
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
589fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedSkFlattenable* SkBitmapProcShader::CreateProc(SkReadBuffer& buffer) {
599fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    SkMatrix lm;
609fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    buffer.readMatrix(&lm);
619fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    SkBitmap bm;
629fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    if (!buffer.readBitmap(&bm)) {
639fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed        return NULL;
649fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    }
659fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    bm.setImmutable();
669fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    TileMode mx = (TileMode)buffer.readUInt();
679fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    TileMode my = (TileMode)buffer.readUInt();
689fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    return SkShader::CreateBitmapShader(bm, mx, my, &lm);
699fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed}
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
719fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedvoid SkBitmapProcShader::flatten(SkWriteBuffer& buffer) const {
729fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed    buffer.writeMatrix(this->getLocalMatrix());
73c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com    buffer.writeBitmap(fRawBitmap);
7487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    buffer.writeUInt(fTileModeX);
7587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    buffer.writeUInt(fTileModeY);
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
785119bdb952025a30f115b9c6a187173956e55097reed@android.comstatic bool only_scale_and_translate(const SkMatrix& matrix) {
795119bdb952025a30f115b9c6a187173956e55097reed@android.com    unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask;
805119bdb952025a30f115b9c6a187173956e55097reed@android.com    return (matrix.getType() & ~mask) == 0;
815119bdb952025a30f115b9c6a187173956e55097reed@android.com}
825119bdb952025a30f115b9c6a187173956e55097reed@android.com
83b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.orgbool SkBitmapProcShader::isOpaque() const {
84b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.org    return fRawBitmap.isOpaque();
85b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.org}
86b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.org
87ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.orgSkShader::Context* SkBitmapProcShader::onCreateContext(const ContextRec& rec, void* storage) const {
88ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org    SkMatrix totalInverse;
8987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    // Do this first, so we know the matrix can be inverted.
90ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org    if (!this->computeTotalInverse(rec, &totalInverse)) {
91ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org        return NULL;
92bc2f1dc85e458af7bdb87873e60207f9f7299e4acommit-bot@chromium.org    }
93edda70e020630103270c815b7499e8b02271875dskia.committer@gmail.com
94ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org    void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext);
95ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org    SkBitmapProcState* state = SkNEW_PLACEMENT(stateStorage, SkBitmapProcState);
96bc2f1dc85e458af7bdb87873e60207f9f7299e4acommit-bot@chromium.org
9787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    SkASSERT(state);
9887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    state->fTileModeX = fTileModeX;
9987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    state->fTileModeY = fTileModeY;
10087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    state->fOrigBitmap = fRawBitmap;
101ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org    if (!state->chooseProcs(totalInverse, *rec.fPaint)) {
10287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        state->~SkBitmapProcState();
10387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        return NULL;
10487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    }
10587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org
106e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org    return SkNEW_PLACEMENT_ARGS(storage, BitmapProcShaderContext, (*this, rec, state));
10787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org}
10887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org
10987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgsize_t SkBitmapProcShader::contextSize() const {
11087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    // The SkBitmapProcState is stored outside of the context object, with the context holding
11187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    // a pointer to it.
11287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    return sizeof(BitmapProcShaderContext) + sizeof(SkBitmapProcState);
11387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org}
11487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org
11587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkBitmapProcShader::BitmapProcShaderContext::BitmapProcShaderContext(
116e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org        const SkBitmapProcShader& shader, const ContextRec& rec, SkBitmapProcState* state)
117e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org    : INHERITED(shader, rec)
11887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    , fState(state)
11987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org{
12087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    const SkBitmap& bitmap = *fState->fBitmap;
1217f6e1e9caa4ced154c23701768e6c618dfe6ad48reed@android.com    bool bitmapIsOpaque = bitmap.isOpaque();
1227c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com
1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // update fFlags
124cafc9f9e80e30fa75ad8a952e7a290e72f211ce7reed@android.com    uint32_t flags = 0;
1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (bitmapIsOpaque && (255 == this->getPaintAlpha())) {
126cafc9f9e80e30fa75ad8a952e7a290e72f211ce7reed@android.com        flags |= kOpaqueAlpha_Flag;
1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
129900ecf2f1579d42c9d2959831787af0346320f86reed@google.com    switch (bitmap.colorType()) {
130900ecf2f1579d42c9d2959831787af0346320f86reed@google.com        case kRGB_565_SkColorType:
131cafc9f9e80e30fa75ad8a952e7a290e72f211ce7reed@android.com            flags |= (kHasSpan16_Flag | kIntrinsicly16_Flag);
1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
133900ecf2f1579d42c9d2959831787af0346320f86reed@google.com        case kIndex_8_SkColorType:
13428fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org        case kN32_SkColorType:
1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (bitmapIsOpaque) {
136cafc9f9e80e30fa75ad8a952e7a290e72f211ce7reed@android.com                flags |= kHasSpan16_Flag;
1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
139900ecf2f1579d42c9d2959831787af0346320f86reed@google.com        case kAlpha_8_SkColorType:
1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;  // never set kHasSpan16_Flag
1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        default:
1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1445119bdb952025a30f115b9c6a187173956e55097reed@android.com
145e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org    if (rec.fPaint->isDither() && bitmap.colorType() != kRGB_565_SkColorType) {
146cafc9f9e80e30fa75ad8a952e7a290e72f211ce7reed@android.com        // gradients can auto-dither in their 16bit sampler, but we don't so
1477f6e1e9caa4ced154c23701768e6c618dfe6ad48reed@android.com        // we clear the flag here.
148cafc9f9e80e30fa75ad8a952e7a290e72f211ce7reed@android.com        flags &= ~kHasSpan16_Flag;
149cafc9f9e80e30fa75ad8a952e7a290e72f211ce7reed@android.com    }
150cafc9f9e80e30fa75ad8a952e7a290e72f211ce7reed@android.com
15176f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com    // if we're only 1-pixel high, and we don't rotate, then we can claim this
1527f6e1e9caa4ced154c23701768e6c618dfe6ad48reed@android.com    if (1 == bitmap.height() &&
1535119bdb952025a30f115b9c6a187173956e55097reed@android.com            only_scale_and_translate(this->getTotalInverse())) {
1543c9b2a4a0e4f57db23640e85959ee78b86634628reed@android.com        flags |= kConstInY32_Flag;
1553c9b2a4a0e4f57db23640e85959ee78b86634628reed@android.com        if (flags & kHasSpan16_Flag) {
1563c9b2a4a0e4f57db23640e85959ee78b86634628reed@android.com            flags |= kConstInY16_Flag;
1573c9b2a4a0e4f57db23640e85959ee78b86634628reed@android.com        }
1585119bdb952025a30f115b9c6a187173956e55097reed@android.com    }
159cafc9f9e80e30fa75ad8a952e7a290e72f211ce7reed@android.com
160cafc9f9e80e30fa75ad8a952e7a290e72f211ce7reed@android.com    fFlags = flags;
1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
16387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkBitmapProcShader::BitmapProcShaderContext::~BitmapProcShaderContext() {
16487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    // The bitmap proc state has been created outside of the context on memory that will be freed
16587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    // elsewhere. Only call the destructor but leave the freeing of the memory to the caller.
16687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    fState->~SkBitmapProcState();
167a641f3f18e5319773989812a888f3fad49e4f2adreed@google.com}
168a641f3f18e5319773989812a888f3fad49e4f2adreed@google.com
169f21991b1046a0e8cb0ed263d06bc48f3c05c944bcommit-bot@chromium.org#define BUF_MAX     128
1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
171258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com#define TEST_BUFFER_OVERRITEx
172258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com
173258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com#ifdef TEST_BUFFER_OVERRITE
174258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com    #define TEST_BUFFER_EXTRA   32
175f21991b1046a0e8cb0ed263d06bc48f3c05c944bcommit-bot@chromium.org    #define TEST_PATTERN    0x88888888
176258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com#else
177258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com    #define TEST_BUFFER_EXTRA   0
178258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com#endif
179258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com
18087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgvoid SkBitmapProcShader::BitmapProcShaderContext::shadeSpan(int x, int y, SkPMColor dstC[],
18187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org                                                            int count) {
18287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    const SkBitmapProcState& state = *fState;
1839fe287bd07baa6d9e890b627c102bba562954f7dreed@google.com    if (state.getShaderProc32()) {
1849fe287bd07baa6d9e890b627c102bba562954f7dreed@google.com        state.getShaderProc32()(state, x, y, dstC, count);
1857a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com        return;
1867a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com    }
1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
188f21991b1046a0e8cb0ed263d06bc48f3c05c944bcommit-bot@chromium.org    uint32_t buffer[BUF_MAX + TEST_BUFFER_EXTRA];
1899fe287bd07baa6d9e890b627c102bba562954f7dreed@google.com    SkBitmapProcState::MatrixProc   mproc = state.getMatrixProc();
1909fe287bd07baa6d9e890b627c102bba562954f7dreed@google.com    SkBitmapProcState::SampleProc32 sproc = state.getSampleProc32();
19187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    int max = state.maxCountForBufferSize(sizeof(buffer[0]) * BUF_MAX);
1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(state.fBitmap->getPixels());
1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(state.fBitmap->pixelRef() == NULL ||
195ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com             state.fBitmap->pixelRef()->isLocked());
1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (;;) {
1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int n = count;
1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (n > max) {
2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            n = max;
2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
202258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com        SkASSERT(n > 0 && n < BUF_MAX*2);
203258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com#ifdef TEST_BUFFER_OVERRITE
204258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com        for (int i = 0; i < TEST_BUFFER_EXTRA; i++) {
205258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com            buffer[BUF_MAX + i] = TEST_PATTERN;
206258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com        }
207258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com#endif
2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        mproc(state, buffer, n, x, y);
209258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com#ifdef TEST_BUFFER_OVERRITE
210258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com        for (int j = 0; j < TEST_BUFFER_EXTRA; j++) {
211258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com            SkASSERT(buffer[BUF_MAX + j] == TEST_PATTERN);
212258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com        }
213258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com#endif
2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        sproc(state, buffer, n, dstC);
2157c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com
2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if ((count -= n) == 0) {
2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
219258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com        SkASSERT(count > 0);
2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        x += n;
2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        dstC += n;
2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
22587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkShader::Context::ShadeProc SkBitmapProcShader::BitmapProcShaderContext::asAShadeProc(void** ctx) {
22687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    if (fState->getShaderProc32()) {
22787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        *ctx = fState;
22887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        return (ShadeProc)fState->getShaderProc32();
2293bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com    }
2303bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com    return NULL;
2313bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com}
2323bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com
23387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgvoid SkBitmapProcShader::BitmapProcShaderContext::shadeSpan16(int x, int y, uint16_t dstC[],
23487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org                                                              int count) {
23587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    const SkBitmapProcState& state = *fState;
2369fe287bd07baa6d9e890b627c102bba562954f7dreed@google.com    if (state.getShaderProc16()) {
2379fe287bd07baa6d9e890b627c102bba562954f7dreed@google.com        state.getShaderProc16()(state, x, y, dstC, count);
2387a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com        return;
2397a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com    }
2407c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com
241f21991b1046a0e8cb0ed263d06bc48f3c05c944bcommit-bot@chromium.org    uint32_t buffer[BUF_MAX];
2429fe287bd07baa6d9e890b627c102bba562954f7dreed@google.com    SkBitmapProcState::MatrixProc   mproc = state.getMatrixProc();
2439fe287bd07baa6d9e890b627c102bba562954f7dreed@google.com    SkBitmapProcState::SampleProc16 sproc = state.getSampleProc16();
24487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    int max = state.maxCountForBufferSize(sizeof(buffer));
2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(state.fBitmap->getPixels());
2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(state.fBitmap->pixelRef() == NULL ||
248ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com             state.fBitmap->pixelRef()->isLocked());
2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (;;) {
2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int n = count;
2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (n > max) {
2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            n = max;
2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        mproc(state, buffer, n, x, y);
2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        sproc(state, buffer, n, dstC);
2577c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com
2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if ((count -= n) == 0) {
2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        x += n;
2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        dstC += n;
2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
268c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com#include "SkUnPreMultiply.h"
269c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com#include "SkColorShader.h"
27037a201231b8f6381938282675eb9abb50ab3b389reed@google.com#include "SkEmptyShader.h"
271c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com
272c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com// returns true and set color if the bitmap can be drawn as a single color
273c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com// (for efficiency)
274c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.comstatic bool canUseColorShader(const SkBitmap& bm, SkColor* color) {
27548c55fe972572c0331ecf6b3d9e8f1a49108bd7eChris Craik#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
27648c55fe972572c0331ecf6b3d9e8f1a49108bd7eChris Craik    // Android expects SkShaders constructed from a Bitmap to always be queryable with
27748c55fe972572c0331ecf6b3d9e8f1a49108bd7eChris Craik    // SkShader::asABitmap()
27848c55fe972572c0331ecf6b3d9e8f1a49108bd7eChris Craik    return false;
27948c55fe972572c0331ecf6b3d9e8f1a49108bd7eChris Craik#endif
28048c55fe972572c0331ecf6b3d9e8f1a49108bd7eChris Craik
281c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com    if (1 != bm.width() || 1 != bm.height()) {
282c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com        return false;
283c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com    }
284c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com
285c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com    SkAutoLockPixels alp(bm);
286c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com    if (!bm.readyToDraw()) {
287c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com        return false;
288c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com    }
289c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com
290900ecf2f1579d42c9d2959831787af0346320f86reed@google.com    switch (bm.colorType()) {
29128fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org        case kN32_SkColorType:
292c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com            *color = SkUnPreMultiply::PMColorToColor(*bm.getAddr32(0, 0));
293c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com            return true;
294900ecf2f1579d42c9d2959831787af0346320f86reed@google.com        case kRGB_565_SkColorType:
295c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com            *color = SkPixel16ToColor(*bm.getAddr16(0, 0));
296c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com            return true;
297900ecf2f1579d42c9d2959831787af0346320f86reed@google.com        case kIndex_8_SkColorType:
298c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com            *color = SkUnPreMultiply::PMColorToColor(bm.getIndex8Color(0, 0));
299c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com            return true;
300c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com        default: // just skip the other configs for now
301c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com            break;
302c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com    }
303c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com    return false;
304c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com}
305c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com
30699c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.comstatic bool bitmapIsTooBig(const SkBitmap& bm) {
30799c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.com    // SkBitmapProcShader stores bitmap coordinates in a 16bit buffer, as it
30899c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.com    // communicates between its matrix-proc and its sampler-proc. Until we can
30999c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.com    // widen that, we have to reject bitmaps that are larger.
31099c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.com    //
31199c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.com    const int maxSize = 65535;
31299c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.com
31399c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.com    return bm.width() > maxSize || bm.height() > maxSize;
31499c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.com}
31599c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.com
3167ef849d45a4de02697697ea213bfae7c215a0c38mtkleinSkShader* SkCreateBitmapShader(const SkBitmap& src, SkShader::TileMode tmx,
3177ef849d45a4de02697697ea213bfae7c215a0c38mtklein                               SkShader::TileMode tmy, const SkMatrix* localMatrix,
3187ef849d45a4de02697697ea213bfae7c215a0c38mtklein                               SkTBlitterAllocator* allocator) {
3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkShader* shader;
320c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com    SkColor color;
32199c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.com    if (src.isNull() || bitmapIsTooBig(src)) {
322a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org        if (NULL == allocator) {
323a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org            shader = SkNEW(SkEmptyShader);
324a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org        } else {
325a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org            shader = allocator->createT<SkEmptyShader>();
326a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org        }
32737a201231b8f6381938282675eb9abb50ab3b389reed@google.com    }
32837a201231b8f6381938282675eb9abb50ab3b389reed@google.com    else if (canUseColorShader(src, &color)) {
329a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org        if (NULL == allocator) {
330a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org            shader = SkNEW_ARGS(SkColorShader, (color));
331a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org        } else {
332a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org            shader = allocator->createT<SkColorShader>(color);
333a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org        }
334c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com    } else {
335a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org        if (NULL == allocator) {
3369c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org            shader = SkNEW_ARGS(SkBitmapProcShader, (src, tmx, tmy, localMatrix));
337a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org        } else {
3389c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org            shader = allocator->createT<SkBitmapProcShader>(src, tmx, tmy, localMatrix);
339a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org        }
340c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com    }
3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return shader;
3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3460f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING
34776f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.comvoid SkBitmapProcShader::toString(SkString* str) const {
34876f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com    static const char* gTileModeName[SkShader::kTileModeCount] = {
34976f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com        "clamp", "repeat", "mirror"
35076f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com    };
3517c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com
35276f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com    str->append("BitmapShader: (");
3537c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com
35476f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com    str->appendf("(%s, %s)",
35587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org                 gTileModeName[fTileModeX],
35687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org                 gTileModeName[fTileModeY]);
35776f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com
35876f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com    str->append(" ");
35976f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com    fRawBitmap.toString(str);
36076f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com
36176f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com    this->INHERITED::toString(str);
36276f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com
36376f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com    str->append(")");
3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
36576f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com#endif
36676f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com
367e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com///////////////////////////////////////////////////////////////////////////////
368e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com
369e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com#if SK_SUPPORT_GPU
370e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com
371e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com#include "GrTextureAccess.h"
37268b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com#include "effects/GrSimpleTextureEffect.h"
373e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com#include "SkGr.h"
374e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com
375b0a8a377f832c59cee939ad721e1f87d378b7142joshualittbool SkBitmapProcShader::asFragmentProcessor(GrContext* context, const SkPaint& paint,
3765531d51ce7426bdae7563547326fcf0bf926a083joshualitt                                             const SkMatrix& viewM,
377b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                             const SkMatrix* localMatrix, GrColor* paintColor,
378b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                             GrFragmentProcessor** fp) const {
379e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com    SkMatrix matrix;
380e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com    matrix.setIDiv(fRawBitmap.width(), fRawBitmap.height());
381e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com
38279b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org    SkMatrix lmInverse;
38379b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org    if (!this->getLocalMatrix().invert(&lmInverse)) {
3849de5b514d38c5b36066bcdc14fba2f7e5196d372dandov        return false;
385e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com    }
38696fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org    if (localMatrix) {
38796fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org        SkMatrix inv;
38896fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org        if (!localMatrix->invert(&inv)) {
3899de5b514d38c5b36066bcdc14fba2f7e5196d372dandov            return false;
39096fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org        }
39196fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org        lmInverse.postConcat(inv);
39296fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org    }
39379b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org    matrix.preConcat(lmInverse);
394cea9abb001b07eaf4340a78db708bfac9e8c68c2commit-bot@chromium.org
395e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com    SkShader::TileMode tm[] = {
39687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        (TileMode)fTileModeX,
39787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        (TileMode)fTileModeY,
398e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com    };
399e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com
40079b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org    // Must set wrap and filter on the sampler before requesting a texture. In two places below
40179b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org    // we check the matrix scale factors to determine how to interpret the filter quality setting.
40279b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org    // This completely ignores the complexity of the drawVertices case where explicit local coords
40379b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org    // are provided by the caller.
4049927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org    bool useBicubic = false;
405b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com    GrTextureParams::FilterMode textureFilterMode;
40693a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed    switch(paint.getFilterQuality()) {
40793a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed        case kNone_SkFilterQuality:
408b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com            textureFilterMode = GrTextureParams::kNone_FilterMode;
409b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com            break;
41093a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed        case kLow_SkFilterQuality:
411b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com            textureFilterMode = GrTextureParams::kBilerp_FilterMode;
412b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com            break;
41393a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed        case kMedium_SkFilterQuality: {
4149927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org            SkMatrix matrix;
4155531d51ce7426bdae7563547326fcf0bf926a083joshualitt            matrix.setConcat(viewM, this->getLocalMatrix());
4169927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org            if (matrix.getMinScale() < SK_Scalar1) {
41779b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org                textureFilterMode = GrTextureParams::kMipMap_FilterMode;
41879b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org            } else {
41979b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org                // Don't trigger MIP level generation unnecessarily.
42079b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org                textureFilterMode = GrTextureParams::kBilerp_FilterMode;
42179b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org            }
422b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com            break;
4239927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org        }
42493a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed        case kHigh_SkFilterQuality: {
4259927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org            SkMatrix matrix;
4265531d51ce7426bdae7563547326fcf0bf926a083joshualitt            matrix.setConcat(viewM, this->getLocalMatrix());
4279927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org            useBicubic = GrBicubicEffect::ShouldUseBicubic(matrix, &textureFilterMode);
428b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com            break;
4299927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org        }
430f9ed6fe6c5a1d05d49925de3798397e2fbb1c185humper@google.com        default:
431f9ed6fe6c5a1d05d49925de3798397e2fbb1c185humper@google.com            SkErrorInternals::SetError( kInvalidPaint_SkError,
432f9ed6fe6c5a1d05d49925de3798397e2fbb1c185humper@google.com                                        "Sorry, I don't understand the filtering "
433f9ed6fe6c5a1d05d49925de3798397e2fbb1c185humper@google.com                                        "mode you asked for.  Falling back to "
434f9ed6fe6c5a1d05d49925de3798397e2fbb1c185humper@google.com                                        "MIPMaps.");
435f9ed6fe6c5a1d05d49925de3798397e2fbb1c185humper@google.com            textureFilterMode = GrTextureParams::kMipMap_FilterMode;
436f9ed6fe6c5a1d05d49925de3798397e2fbb1c185humper@google.com            break;
437956b310f13c7412c035406c658ff16ca85eac656skia.committer@gmail.com
438b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com    }
439b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com    GrTextureParams params(tm, textureFilterMode);
440bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon    SkAutoTUnref<GrTexture> texture(GrRefCachedBitmapTexture(context, fRawBitmap, &params));
441e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com
442bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon    if (!texture) {
4433aad3b01afc77993ff051c02e49186294e312980humper@google.com        SkErrorInternals::SetError( kInternalError_SkError,
4443aad3b01afc77993ff051c02e49186294e312980humper@google.com                                    "Couldn't convert bitmap to texture.");
4459de5b514d38c5b36066bcdc14fba2f7e5196d372dandov        return false;
446e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com    }
4477ef849d45a4de02697697ea213bfae7c215a0c38mtklein
44883d081ae1d731b5039e99823620f5e287542ee39bsalomon    *paintColor = (kAlpha_8_SkColorType == fRawBitmap.colorType()) ?
44983d081ae1d731b5039e99823620f5e287542ee39bsalomon                                                SkColor2GrColor(paint.getColor()) :
45083d081ae1d731b5039e99823620f5e287542ee39bsalomon                                                SkColor2GrColorJustAlpha(paint.getColor());
4518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4529927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org    if (useBicubic) {
453b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        *fp = GrBicubicEffect::Create(texture, matrix, tm);
4543aad3b01afc77993ff051c02e49186294e312980humper@google.com    } else {
455b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        *fp = GrSimpleTextureEffect::Create(texture, matrix, params);
4563aad3b01afc77993ff051c02e49186294e312980humper@google.com    }
4579de5b514d38c5b36066bcdc14fba2f7e5196d372dandov
4589de5b514d38c5b36066bcdc14fba2f7e5196d372dandov    return true;
4599de5b514d38c5b36066bcdc14fba2f7e5196d372dandov}
4609de5b514d38c5b36066bcdc14fba2f7e5196d372dandov
4617ef849d45a4de02697697ea213bfae7c215a0c38mtklein#else
4629de5b514d38c5b36066bcdc14fba2f7e5196d372dandov
4635531d51ce7426bdae7563547326fcf0bf926a083joshualittbool SkBitmapProcShader::asFragmentProcessor(GrContext*, const SkPaint&, const SkMatrix&,
4645531d51ce7426bdae7563547326fcf0bf926a083joshualitt                                             const SkMatrix*, GrColor*,
465b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                             GrFragmentProcessor**) const {
4669de5b514d38c5b36066bcdc14fba2f7e5196d372dandov    SkDEBUGFAIL("Should not call in GPU-less build");
4679de5b514d38c5b36066bcdc14fba2f7e5196d372dandov    return false;
468e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com}
4699de5b514d38c5b36066bcdc14fba2f7e5196d372dandov
470e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com#endif
471