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
428b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgSkBitmapProcShader::SkBitmapProcShader(SkReadBuffer& buffer)
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        : INHERITED(buffer) {
44c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com    buffer.readBitmap(&fRawBitmap);
4584239fb28d87b6fd62150f4f167c8e50f744d6cereed@google.com    fRawBitmap.setImmutable();
4687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    fTileModeX = buffer.readUInt();
4787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    fTileModeY = buffer.readUInt();
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
507c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.comSkShader::BitmapType SkBitmapProcShader::asABitmap(SkBitmap* texture,
517c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com                                                   SkMatrix* texM,
5291f319c5dc4493384f0a52aaeef3dcc311ef6ed0rileya@google.com                                                   TileMode xy[]) const {
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (texture) {
548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *texture = fRawBitmap;
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (texM) {
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        texM->reset();
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (xy) {
6087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        xy[0] = (TileMode)fTileModeX;
6187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        xy[1] = (TileMode)fTileModeY;
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
63f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    return kDefault_BitmapType;
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
668b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkBitmapProcShader::flatten(SkWriteBuffer& buffer) const {
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->INHERITED::flatten(buffer);
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
69c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com    buffer.writeBitmap(fRawBitmap);
7087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    buffer.writeUInt(fTileModeX);
7187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    buffer.writeUInt(fTileModeY);
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
745119bdb952025a30f115b9c6a187173956e55097reed@android.comstatic bool only_scale_and_translate(const SkMatrix& matrix) {
755119bdb952025a30f115b9c6a187173956e55097reed@android.com    unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask;
765119bdb952025a30f115b9c6a187173956e55097reed@android.com    return (matrix.getType() & ~mask) == 0;
775119bdb952025a30f115b9c6a187173956e55097reed@android.com}
785119bdb952025a30f115b9c6a187173956e55097reed@android.com
79b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.orgbool SkBitmapProcShader::isOpaque() const {
80b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.org    return fRawBitmap.isOpaque();
81b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.org}
82b6e161937bc890f0aa12ac5e27415d4d260ea6e0junov@chromium.org
83cee9dcb8377e1f85a7a232822a894464ea6ccddcreed@google.comstatic bool valid_for_drawing(const SkBitmap& bm) {
84cee9dcb8377e1f85a7a232822a894464ea6ccddcreed@google.com    if (0 == bm.width() || 0 == bm.height()) {
85cee9dcb8377e1f85a7a232822a894464ea6ccddcreed@google.com        return false;   // nothing to draw
86cee9dcb8377e1f85a7a232822a894464ea6ccddcreed@google.com    }
87cee9dcb8377e1f85a7a232822a894464ea6ccddcreed@google.com    if (NULL == bm.pixelRef()) {
88cee9dcb8377e1f85a7a232822a894464ea6ccddcreed@google.com        return false;   // no pixels to read
89cee9dcb8377e1f85a7a232822a894464ea6ccddcreed@google.com    }
90900ecf2f1579d42c9d2959831787af0346320f86reed@google.com    if (kIndex_8_SkColorType == bm.colorType()) {
91cee9dcb8377e1f85a7a232822a894464ea6ccddcreed@google.com        // ugh, I have to lock-pixels to inspect the colortable
92cee9dcb8377e1f85a7a232822a894464ea6ccddcreed@google.com        SkAutoLockPixels alp(bm);
93cee9dcb8377e1f85a7a232822a894464ea6ccddcreed@google.com        if (!bm.getColorTable()) {
94cee9dcb8377e1f85a7a232822a894464ea6ccddcreed@google.com            return false;
95cee9dcb8377e1f85a7a232822a894464ea6ccddcreed@google.com        }
96cee9dcb8377e1f85a7a232822a894464ea6ccddcreed@google.com    }
97cee9dcb8377e1f85a7a232822a894464ea6ccddcreed@google.com    return true;
98cee9dcb8377e1f85a7a232822a894464ea6ccddcreed@google.com}
99cee9dcb8377e1f85a7a232822a894464ea6ccddcreed@google.com
100ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.orgSkShader::Context* SkBitmapProcShader::onCreateContext(const ContextRec& rec, void* storage) const {
101cee9dcb8377e1f85a7a232822a894464ea6ccddcreed@google.com    if (!fRawBitmap.getTexture() && !valid_for_drawing(fRawBitmap)) {
102ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org        return NULL;
103001f4ed2fb62ecdc98ce2884d925de11b7516d23commit-bot@chromium.org    }
104edda70e020630103270c815b7499e8b02271875dskia.committer@gmail.com
105ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org    SkMatrix totalInverse;
10687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    // Do this first, so we know the matrix can be inverted.
107ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org    if (!this->computeTotalInverse(rec, &totalInverse)) {
108ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org        return NULL;
109bc2f1dc85e458af7bdb87873e60207f9f7299e4acommit-bot@chromium.org    }
110edda70e020630103270c815b7499e8b02271875dskia.committer@gmail.com
111ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org    void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext);
112ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org    SkBitmapProcState* state = SkNEW_PLACEMENT(stateStorage, SkBitmapProcState);
113bc2f1dc85e458af7bdb87873e60207f9f7299e4acommit-bot@chromium.org
11487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    SkASSERT(state);
11587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    state->fTileModeX = fTileModeX;
11687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    state->fTileModeY = fTileModeY;
11787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    state->fOrigBitmap = fRawBitmap;
118ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.org    if (!state->chooseProcs(totalInverse, *rec.fPaint)) {
11987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        state->~SkBitmapProcState();
12087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        return NULL;
12187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    }
12287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org
123e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org    return SkNEW_PLACEMENT_ARGS(storage, BitmapProcShaderContext, (*this, rec, state));
12487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org}
12587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org
12687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgsize_t SkBitmapProcShader::contextSize() const {
12787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    // The SkBitmapProcState is stored outside of the context object, with the context holding
12887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    // a pointer to it.
12987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    return sizeof(BitmapProcShaderContext) + sizeof(SkBitmapProcState);
13087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org}
13187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org
13287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkBitmapProcShader::BitmapProcShaderContext::BitmapProcShaderContext(
133e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org        const SkBitmapProcShader& shader, const ContextRec& rec, SkBitmapProcState* state)
134e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org    : INHERITED(shader, rec)
13587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    , fState(state)
13687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org{
13787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    const SkBitmap& bitmap = *fState->fBitmap;
1387f6e1e9caa4ced154c23701768e6c618dfe6ad48reed@android.com    bool bitmapIsOpaque = bitmap.isOpaque();
1397c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com
1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // update fFlags
141cafc9f9e80e30fa75ad8a952e7a290e72f211ce7reed@android.com    uint32_t flags = 0;
1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (bitmapIsOpaque && (255 == this->getPaintAlpha())) {
143cafc9f9e80e30fa75ad8a952e7a290e72f211ce7reed@android.com        flags |= kOpaqueAlpha_Flag;
1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
146900ecf2f1579d42c9d2959831787af0346320f86reed@google.com    switch (bitmap.colorType()) {
147900ecf2f1579d42c9d2959831787af0346320f86reed@google.com        case kRGB_565_SkColorType:
148cafc9f9e80e30fa75ad8a952e7a290e72f211ce7reed@android.com            flags |= (kHasSpan16_Flag | kIntrinsicly16_Flag);
1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
150900ecf2f1579d42c9d2959831787af0346320f86reed@google.com        case kIndex_8_SkColorType:
15128fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org        case kN32_SkColorType:
1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (bitmapIsOpaque) {
153cafc9f9e80e30fa75ad8a952e7a290e72f211ce7reed@android.com                flags |= kHasSpan16_Flag;
1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
156900ecf2f1579d42c9d2959831787af0346320f86reed@google.com        case kAlpha_8_SkColorType:
1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;  // never set kHasSpan16_Flag
1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        default:
1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1615119bdb952025a30f115b9c6a187173956e55097reed@android.com
162e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org    if (rec.fPaint->isDither() && bitmap.colorType() != kRGB_565_SkColorType) {
163cafc9f9e80e30fa75ad8a952e7a290e72f211ce7reed@android.com        // gradients can auto-dither in their 16bit sampler, but we don't so
1647f6e1e9caa4ced154c23701768e6c618dfe6ad48reed@android.com        // we clear the flag here.
165cafc9f9e80e30fa75ad8a952e7a290e72f211ce7reed@android.com        flags &= ~kHasSpan16_Flag;
166cafc9f9e80e30fa75ad8a952e7a290e72f211ce7reed@android.com    }
167cafc9f9e80e30fa75ad8a952e7a290e72f211ce7reed@android.com
16876f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com    // if we're only 1-pixel high, and we don't rotate, then we can claim this
1697f6e1e9caa4ced154c23701768e6c618dfe6ad48reed@android.com    if (1 == bitmap.height() &&
1705119bdb952025a30f115b9c6a187173956e55097reed@android.com            only_scale_and_translate(this->getTotalInverse())) {
1713c9b2a4a0e4f57db23640e85959ee78b86634628reed@android.com        flags |= kConstInY32_Flag;
1723c9b2a4a0e4f57db23640e85959ee78b86634628reed@android.com        if (flags & kHasSpan16_Flag) {
1733c9b2a4a0e4f57db23640e85959ee78b86634628reed@android.com            flags |= kConstInY16_Flag;
1743c9b2a4a0e4f57db23640e85959ee78b86634628reed@android.com        }
1755119bdb952025a30f115b9c6a187173956e55097reed@android.com    }
176cafc9f9e80e30fa75ad8a952e7a290e72f211ce7reed@android.com
177cafc9f9e80e30fa75ad8a952e7a290e72f211ce7reed@android.com    fFlags = flags;
1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
18087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkBitmapProcShader::BitmapProcShaderContext::~BitmapProcShaderContext() {
18187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    // The bitmap proc state has been created outside of the context on memory that will be freed
18287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    // elsewhere. Only call the destructor but leave the freeing of the memory to the caller.
18387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    fState->~SkBitmapProcState();
184a641f3f18e5319773989812a888f3fad49e4f2adreed@google.com}
185a641f3f18e5319773989812a888f3fad49e4f2adreed@google.com
186f21991b1046a0e8cb0ed263d06bc48f3c05c944bcommit-bot@chromium.org#define BUF_MAX     128
1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
188258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com#define TEST_BUFFER_OVERRITEx
189258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com
190258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com#ifdef TEST_BUFFER_OVERRITE
191258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com    #define TEST_BUFFER_EXTRA   32
192f21991b1046a0e8cb0ed263d06bc48f3c05c944bcommit-bot@chromium.org    #define TEST_PATTERN    0x88888888
193258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com#else
194258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com    #define TEST_BUFFER_EXTRA   0
195258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com#endif
196258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com
19787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgvoid SkBitmapProcShader::BitmapProcShaderContext::shadeSpan(int x, int y, SkPMColor dstC[],
19887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org                                                            int count) {
19987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    const SkBitmapProcState& state = *fState;
2009fe287bd07baa6d9e890b627c102bba562954f7dreed@google.com    if (state.getShaderProc32()) {
2019fe287bd07baa6d9e890b627c102bba562954f7dreed@google.com        state.getShaderProc32()(state, x, y, dstC, count);
2027a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com        return;
2037a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com    }
2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
205f21991b1046a0e8cb0ed263d06bc48f3c05c944bcommit-bot@chromium.org    uint32_t buffer[BUF_MAX + TEST_BUFFER_EXTRA];
2069fe287bd07baa6d9e890b627c102bba562954f7dreed@google.com    SkBitmapProcState::MatrixProc   mproc = state.getMatrixProc();
2079fe287bd07baa6d9e890b627c102bba562954f7dreed@google.com    SkBitmapProcState::SampleProc32 sproc = state.getSampleProc32();
20887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    int max = state.maxCountForBufferSize(sizeof(buffer[0]) * BUF_MAX);
2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(state.fBitmap->getPixels());
2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(state.fBitmap->pixelRef() == NULL ||
212ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com             state.fBitmap->pixelRef()->isLocked());
2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (;;) {
2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int n = count;
2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (n > max) {
2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            n = max;
2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
219258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com        SkASSERT(n > 0 && n < BUF_MAX*2);
220258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com#ifdef TEST_BUFFER_OVERRITE
221258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com        for (int i = 0; i < TEST_BUFFER_EXTRA; i++) {
222258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com            buffer[BUF_MAX + i] = TEST_PATTERN;
223258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com        }
224258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com#endif
2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        mproc(state, buffer, n, x, y);
226258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com#ifdef TEST_BUFFER_OVERRITE
227258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com        for (int j = 0; j < TEST_BUFFER_EXTRA; j++) {
228258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com            SkASSERT(buffer[BUF_MAX + j] == TEST_PATTERN);
229258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com        }
230258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com#endif
2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        sproc(state, buffer, n, dstC);
2327c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com
2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if ((count -= n) == 0) {
2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
236258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com        SkASSERT(count > 0);
2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        x += n;
2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        dstC += n;
2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
24287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkShader::Context::ShadeProc SkBitmapProcShader::BitmapProcShaderContext::asAShadeProc(void** ctx) {
24387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    if (fState->getShaderProc32()) {
24487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        *ctx = fState;
24587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        return (ShadeProc)fState->getShaderProc32();
2463bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com    }
2473bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com    return NULL;
2483bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com}
2493bafe74a29c37761082980ed4ee9b831256bd27ereed@google.com
25087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgvoid SkBitmapProcShader::BitmapProcShaderContext::shadeSpan16(int x, int y, uint16_t dstC[],
25187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org                                                              int count) {
25287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    const SkBitmapProcState& state = *fState;
2539fe287bd07baa6d9e890b627c102bba562954f7dreed@google.com    if (state.getShaderProc16()) {
2549fe287bd07baa6d9e890b627c102bba562954f7dreed@google.com        state.getShaderProc16()(state, x, y, dstC, count);
2557a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com        return;
2567a99eb1c63d4327d352af09ea59f039f014e4028reed@android.com    }
2577c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com
258f21991b1046a0e8cb0ed263d06bc48f3c05c944bcommit-bot@chromium.org    uint32_t buffer[BUF_MAX];
2599fe287bd07baa6d9e890b627c102bba562954f7dreed@google.com    SkBitmapProcState::MatrixProc   mproc = state.getMatrixProc();
2609fe287bd07baa6d9e890b627c102bba562954f7dreed@google.com    SkBitmapProcState::SampleProc16 sproc = state.getSampleProc16();
26187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org    int max = state.maxCountForBufferSize(sizeof(buffer));
2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(state.fBitmap->getPixels());
2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(state.fBitmap->pixelRef() == NULL ||
265ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com             state.fBitmap->pixelRef()->isLocked());
2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (;;) {
2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int n = count;
2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (n > max) {
2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            n = max;
2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        mproc(state, buffer, n, x, y);
2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        sproc(state, buffer, n, dstC);
2747c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com
2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if ((count -= n) == 0) {
2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        x += n;
2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        dstC += n;
2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
285c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com#include "SkUnPreMultiply.h"
286c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com#include "SkColorShader.h"
28737a201231b8f6381938282675eb9abb50ab3b389reed@google.com#include "SkEmptyShader.h"
288c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com
289c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com// returns true and set color if the bitmap can be drawn as a single color
290c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com// (for efficiency)
291c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.comstatic bool canUseColorShader(const SkBitmap& bm, SkColor* color) {
292c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com    if (1 != bm.width() || 1 != bm.height()) {
293c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com        return false;
294c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com    }
295c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com
296c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com    SkAutoLockPixels alp(bm);
297c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com    if (!bm.readyToDraw()) {
298c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com        return false;
299c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com    }
300c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com
301900ecf2f1579d42c9d2959831787af0346320f86reed@google.com    switch (bm.colorType()) {
30228fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org        case kN32_SkColorType:
303c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com            *color = SkUnPreMultiply::PMColorToColor(*bm.getAddr32(0, 0));
304c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com            return true;
305900ecf2f1579d42c9d2959831787af0346320f86reed@google.com        case kRGB_565_SkColorType:
306c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com            *color = SkPixel16ToColor(*bm.getAddr16(0, 0));
307c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com            return true;
308900ecf2f1579d42c9d2959831787af0346320f86reed@google.com        case kIndex_8_SkColorType:
309c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com            *color = SkUnPreMultiply::PMColorToColor(bm.getIndex8Color(0, 0));
310c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com            return true;
311c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com        default: // just skip the other configs for now
312c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com            break;
313c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com    }
314c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com    return false;
315c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com}
316c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com
31799c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.comstatic bool bitmapIsTooBig(const SkBitmap& bm) {
31899c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.com    // SkBitmapProcShader stores bitmap coordinates in a 16bit buffer, as it
31999c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.com    // communicates between its matrix-proc and its sampler-proc. Until we can
32099c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.com    // widen that, we have to reject bitmaps that are larger.
32199c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.com    //
32299c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.com    const int maxSize = 65535;
32399c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.com
32499c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.com    return bm.width() > maxSize || bm.height() > maxSize;
32599c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.com}
32699c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.com
327a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.orgSkShader* CreateBitmapShader(const SkBitmap& src, SkShader::TileMode tmx,
3289c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org        SkShader::TileMode tmy, const SkMatrix* localMatrix, SkTBlitterAllocator* allocator) {
3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkShader* shader;
330c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com    SkColor color;
33199c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.com    if (src.isNull() || bitmapIsTooBig(src)) {
332a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org        if (NULL == allocator) {
333a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org            shader = SkNEW(SkEmptyShader);
334a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org        } else {
335a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org            shader = allocator->createT<SkEmptyShader>();
336a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org        }
33737a201231b8f6381938282675eb9abb50ab3b389reed@google.com    }
33837a201231b8f6381938282675eb9abb50ab3b389reed@google.com    else if (canUseColorShader(src, &color)) {
339a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org        if (NULL == allocator) {
340a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org            shader = SkNEW_ARGS(SkColorShader, (color));
341a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org        } else {
342a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org            shader = allocator->createT<SkColorShader>(color);
343a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org        }
344c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com    } else {
345a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org        if (NULL == allocator) {
3469c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org            shader = SkNEW_ARGS(SkBitmapProcShader, (src, tmx, tmy, localMatrix));
347a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org        } else {
3489c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org            shader = allocator->createT<SkBitmapProcShader>(src, tmx, tmy, localMatrix);
349a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org        }
350c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com    }
3518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return shader;
3528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3560f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING
35776f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.comvoid SkBitmapProcShader::toString(SkString* str) const {
35876f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com    static const char* gTileModeName[SkShader::kTileModeCount] = {
35976f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com        "clamp", "repeat", "mirror"
36076f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com    };
3617c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com
36276f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com    str->append("BitmapShader: (");
3637c2f27d788fff9dbf66a6d52753e47f786a313c0reed@google.com
36476f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com    str->appendf("(%s, %s)",
36587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org                 gTileModeName[fTileModeX],
36687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org                 gTileModeName[fTileModeY]);
36776f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com
36876f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com    str->append(" ");
36976f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com    fRawBitmap.toString(str);
37076f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com
37176f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com    this->INHERITED::toString(str);
37276f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com
37376f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com    str->append(")");
3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
37576f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com#endif
37676f9e938df0b5826fd4c80b854ceafaf385cfbe1robertphillips@google.com
377e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com///////////////////////////////////////////////////////////////////////////////
378e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com
379e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com#if SK_SUPPORT_GPU
380e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com
381e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com#include "GrTextureAccess.h"
38268b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com#include "effects/GrSimpleTextureEffect.h"
383e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com#include "SkGr.h"
384e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com
3859de5b514d38c5b36066bcdc14fba2f7e5196d372dandovbool SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint& paint,
3869de5b514d38c5b36066bcdc14fba2f7e5196d372dandov                                     const SkMatrix* localMatrix, GrColor* grColor,
3879de5b514d38c5b36066bcdc14fba2f7e5196d372dandov                                     GrEffectRef** grEffect) const {
388e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com    SkMatrix matrix;
389e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com    matrix.setIDiv(fRawBitmap.width(), fRawBitmap.height());
390e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com
39179b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org    SkMatrix lmInverse;
39279b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org    if (!this->getLocalMatrix().invert(&lmInverse)) {
3939de5b514d38c5b36066bcdc14fba2f7e5196d372dandov        return false;
394e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com    }
39596fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org    if (localMatrix) {
39696fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org        SkMatrix inv;
39796fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org        if (!localMatrix->invert(&inv)) {
3989de5b514d38c5b36066bcdc14fba2f7e5196d372dandov            return false;
39996fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org        }
40096fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org        lmInverse.postConcat(inv);
40196fb7489ba46909c3f81bb2d94755e7d4ccb5fadcommit-bot@chromium.org    }
40279b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org    matrix.preConcat(lmInverse);
403cea9abb001b07eaf4340a78db708bfac9e8c68c2commit-bot@chromium.org
404e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com    SkShader::TileMode tm[] = {
40587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        (TileMode)fTileModeX,
40687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org        (TileMode)fTileModeY,
407e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com    };
408e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com
40979b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org    // Must set wrap and filter on the sampler before requesting a texture. In two places below
41079b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org    // we check the matrix scale factors to determine how to interpret the filter quality setting.
41179b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org    // This completely ignores the complexity of the drawVertices case where explicit local coords
41279b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org    // are provided by the caller.
4139927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org    bool useBicubic = false;
414b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com    GrTextureParams::FilterMode textureFilterMode;
4159927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org    switch(paint.getFilterLevel()) {
416b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com        case SkPaint::kNone_FilterLevel:
417b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com            textureFilterMode = GrTextureParams::kNone_FilterMode;
418b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com            break;
419b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com        case SkPaint::kLow_FilterLevel:
420b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com            textureFilterMode = GrTextureParams::kBilerp_FilterMode;
421b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com            break;
4229927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org        case SkPaint::kMedium_FilterLevel: {
4239927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org            SkMatrix matrix;
4249927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org            matrix.setConcat(context->getMatrix(), this->getLocalMatrix());
4259927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org            if (matrix.getMinScale() < SK_Scalar1) {
42679b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org                textureFilterMode = GrTextureParams::kMipMap_FilterMode;
42779b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org            } else {
42879b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org                // Don't trigger MIP level generation unnecessarily.
42979b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org                textureFilterMode = GrTextureParams::kBilerp_FilterMode;
43079b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org            }
431b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com            break;
4329927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org        }
4339927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org        case SkPaint::kHigh_FilterLevel: {
4349927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org            SkMatrix matrix;
4359927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org            matrix.setConcat(context->getMatrix(), this->getLocalMatrix());
4369927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org            useBicubic = GrBicubicEffect::ShouldUseBicubic(matrix, &textureFilterMode);
437b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com            break;
4389927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org        }
439f9ed6fe6c5a1d05d49925de3798397e2fbb1c185humper@google.com        default:
440f9ed6fe6c5a1d05d49925de3798397e2fbb1c185humper@google.com            SkErrorInternals::SetError( kInvalidPaint_SkError,
441f9ed6fe6c5a1d05d49925de3798397e2fbb1c185humper@google.com                                        "Sorry, I don't understand the filtering "
442f9ed6fe6c5a1d05d49925de3798397e2fbb1c185humper@google.com                                        "mode you asked for.  Falling back to "
443f9ed6fe6c5a1d05d49925de3798397e2fbb1c185humper@google.com                                        "MIPMaps.");
444f9ed6fe6c5a1d05d49925de3798397e2fbb1c185humper@google.com            textureFilterMode = GrTextureParams::kMipMap_FilterMode;
445f9ed6fe6c5a1d05d49925de3798397e2fbb1c185humper@google.com            break;
446956b310f13c7412c035406c658ff16ca85eac656skia.committer@gmail.com
447b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com    }
448b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com    GrTextureParams params(tm, textureFilterMode);
44995ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com    GrTexture* texture = GrLockAndRefCachedBitmapTexture(context, fRawBitmap, &params);
450e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com
451e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com    if (NULL == texture) {
4523aad3b01afc77993ff051c02e49186294e312980humper@google.com        SkErrorInternals::SetError( kInternalError_SkError,
4533aad3b01afc77993ff051c02e49186294e312980humper@google.com                                    "Couldn't convert bitmap to texture.");
4549de5b514d38c5b36066bcdc14fba2f7e5196d372dandov        return false;
455e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com    }
4569de5b514d38c5b36066bcdc14fba2f7e5196d372dandov
4579de5b514d38c5b36066bcdc14fba2f7e5196d372dandov    *grColor = (kAlpha_8_SkColorType == fRawBitmap.colorType()) ? SkColor2GrColor(paint.getColor())
4589de5b514d38c5b36066bcdc14fba2f7e5196d372dandov                                        : SkColor2GrColorJustAlpha(paint.getColor());
4598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4609927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org    if (useBicubic) {
4619de5b514d38c5b36066bcdc14fba2f7e5196d372dandov        *grEffect = GrBicubicEffect::Create(texture, matrix, tm);
4623aad3b01afc77993ff051c02e49186294e312980humper@google.com    } else {
4639de5b514d38c5b36066bcdc14fba2f7e5196d372dandov        *grEffect = GrSimpleTextureEffect::Create(texture, matrix, params);
4643aad3b01afc77993ff051c02e49186294e312980humper@google.com    }
46595ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com    GrUnlockAndUnrefCachedBitmapTexture(texture);
4669de5b514d38c5b36066bcdc14fba2f7e5196d372dandov
4679de5b514d38c5b36066bcdc14fba2f7e5196d372dandov    return true;
4689de5b514d38c5b36066bcdc14fba2f7e5196d372dandov}
4699de5b514d38c5b36066bcdc14fba2f7e5196d372dandov
4709de5b514d38c5b36066bcdc14fba2f7e5196d372dandov#else
4719de5b514d38c5b36066bcdc14fba2f7e5196d372dandov
4729de5b514d38c5b36066bcdc14fba2f7e5196d372dandovbool SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint& paint,
4739de5b514d38c5b36066bcdc14fba2f7e5196d372dandov                                     const SkMatrix* localMatrix, GrColor* grColor,
4749de5b514d38c5b36066bcdc14fba2f7e5196d372dandov                                     GrEffectRef** grEffect) const {
4759de5b514d38c5b36066bcdc14fba2f7e5196d372dandov    SkDEBUGFAIL("Should not call in GPU-less build");
4769de5b514d38c5b36066bcdc14fba2f7e5196d372dandov    return false;
477e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com}
4789de5b514d38c5b36066bcdc14fba2f7e5196d372dandov
479e197cbf9a3e66bab926bc5e51962752dad5221a0bsalomon@google.com#endif
480