105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc.
41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger */
805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#include "GrContext.h"
1205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#include "GrTextContext.h"
1305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
1405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#include "SkGpuDevice.h"
1505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#include "SkGrTexturePixelRef.h"
1605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
1735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#include "SkColorFilter.h"
1805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#include "SkDrawProcs.h"
1905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#include "SkGlyphCache.h"
201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkImageFilter.h"
211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkTLazy.h"
2287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#include "SkUtils.h"
2305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
2405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#define CACHE_LAYER_TEXTURES 1
2505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
2605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#if 0
2705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    extern bool (*gShouldDrawProc)();
2805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    #define CHECK_SHOULD_DRAW(draw)                             \
2905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        do {                                                    \
3005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            if (gShouldDrawProc && !gShouldDrawProc()) return;  \
3105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            this->prepareRenderTarget(draw);                    \
3205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        } while (0)
3305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#else
3405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    #define CHECK_SHOULD_DRAW(draw) this->prepareRenderTarget(draw)
3505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#endif
3605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
370b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger// we use the same texture slot on GrPaint for bitmaps and shaders
380b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger// (since drawBitmap, drawSprite, and drawDevice ignore skia's shader)
390b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerenum {
400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    kBitmapTextureIdx = 0,
410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    kShaderTextureIdx = 0
420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger};
430b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define MAX_BLUR_SIGMA 4.0f
461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// FIXME:  This value comes from from SkBlurMaskFilter.cpp.
471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// Should probably be put in a common header someplace.
481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define MAX_BLUR_RADIUS SkIntToScalar(128)
491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// This constant approximates the scaling done in the software path's
501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// "high quality" mode, in SkBlurMask::Blur() (1 / sqrt(3)).
511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// IMHO, it actually should be 1:  we blur "less" than we should do
521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// according to the CSS and canvas specs, simply because Safari does the same.
531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// Firefox used to do the same too, until 4.0 where they fixed it.  So at some
541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// point we should probably get rid of these scaling constants and rebaseline
551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// all the blur tests.
561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define BLUR_SIGMA_SCALE 0.6f
5705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
5805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
5905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek SollenbergerSkGpuDevice::SkAutoCachedTexture::
6005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger             SkAutoCachedTexture(SkGpuDevice* device,
6105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                 const SkBitmap& bitmap,
621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 const GrSamplerState* sampler,
6305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                 GrTexture** texture) {
6405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrAssert(texture);
6505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    *texture = this->set(device, bitmap, sampler);
6605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
6705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
6805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek SollenbergerSkGpuDevice::SkAutoCachedTexture::SkAutoCachedTexture() {
6905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
7005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
7105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek SollenbergerGrTexture* SkGpuDevice::SkAutoCachedTexture::set(SkGpuDevice* device,
7205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                                 const SkBitmap& bitmap,
731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                 const GrSamplerState* sampler) {
741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (fTex.texture()) {
7505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        fDevice->unlockCachedTexture(fTex);
7605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
7705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fDevice = device;
7805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrTexture* texture = (GrTexture*)bitmap.getTexture();
7905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (texture) {
8005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        // return the native texture
811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fTex.reset();
8205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    } else {
8305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        // look it up in our cache
841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fTex = device->lockCachedTexture(bitmap, sampler);
851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        texture = fTex.texture();
8605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
8705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    return texture;
8805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
8905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
9005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek SollenbergerSkGpuDevice::SkAutoCachedTexture::~SkAutoCachedTexture() {
911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (fTex.texture()) {
9205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        fDevice->unlockCachedTexture(fTex);
9305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
9405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
9505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
9605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
9705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
9805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerbool gDoTraceDraw;
9905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
10005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerstruct GrSkDrawProcs : public SkDrawProcs {
10105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerpublic:
10205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrContext* fContext;
10305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrTextContext* fTextContext;
10405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrFontScaler* fFontScaler;  // cached in the skia glyphcache
10505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger};
10605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
10705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
10805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
1091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkBitmap::Config grConfig2skConfig(GrPixelConfig config, bool* isOpaque) {
1101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    switch (config) {
1111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        case kAlpha_8_GrPixelConfig:
1121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            *isOpaque = false;
1131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return SkBitmap::kA8_Config;
1141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        case kRGB_565_GrPixelConfig:
1151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            *isOpaque = true;
1161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return SkBitmap::kRGB_565_Config;
1171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        case kRGBA_4444_GrPixelConfig:
1181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            *isOpaque = false;
1191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return SkBitmap::kARGB_4444_Config;
1201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        case kSkia8888_PM_GrPixelConfig:
1211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // we don't currently have a way of knowing whether
1221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // a 8888 is opaque based on the config.
1231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            *isOpaque = false;
1241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return SkBitmap::kARGB_8888_Config;
1251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        default:
1261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            *isOpaque = false;
1271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return SkBitmap::kNo_Config;
1281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
12905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
13005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
1311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkBitmap make_bitmap(GrContext* context, GrRenderTarget* renderTarget) {
1321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrPixelConfig config = renderTarget->config();
1331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool isOpaque;
1351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkBitmap bitmap;
1361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bitmap.setConfig(grConfig2skConfig(config, &isOpaque),
1371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                     renderTarget->width(), renderTarget->height());
1381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bitmap.setIsOpaque(isOpaque);
1391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return bitmap;
1401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1421cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkGpuDevice::SkGpuDevice(GrContext* context, GrTexture* texture)
1431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger: SkDevice(make_bitmap(context, texture->asRenderTarget())) {
1441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->initFromRenderTarget(context, texture->asRenderTarget());
1451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1471cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkGpuDevice::SkGpuDevice(GrContext* context, GrRenderTarget* renderTarget)
1481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger: SkDevice(make_bitmap(context, renderTarget)) {
1491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->initFromRenderTarget(context, renderTarget);
1501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1524f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkGpuDevice::initFromRenderTarget(GrContext* context,
1531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                       GrRenderTarget* renderTarget) {
1541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fNeedPrepareRenderTarget = false;
1551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fDrawProcs = NULL;
1564f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
1571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fContext = context;
1581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fContext->ref();
1594f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
1601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fTexture = NULL;
1611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fRenderTarget = NULL;
1621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fNeedClear = false;
1634f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
1641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAssert(NULL != renderTarget);
1651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fRenderTarget = renderTarget;
1661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fRenderTarget->ref();
1671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // if this RT is also a texture, hold a ref on it
1681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fTexture = fRenderTarget->asTexture();
1691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkSafeRef(fTexture);
1704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
1714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    // Create a pixel ref for the underlying SkBitmap. We prefer a texture pixel
1724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    // ref to a render target pixel reft. The pixel ref may get ref'ed outside
1734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    // the device via accessBitmap. This external ref may outlive the device.
1744f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    // Since textures own their render targets (but not vice-versa) we
1754f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    // are ensuring that both objects will live as long as the pixel ref.
1764f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    SkPixelRef* pr;
1774f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (fTexture) {
1784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        pr = new SkGrTexturePixelRef(fTexture);
1794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    } else {
1804f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        pr = new SkGrRenderTargetPixelRef(fRenderTarget);
1814f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    }
1821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->setPixelRef(pr, 0)->unref();
1831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
18405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
1851cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkGpuDevice::SkGpuDevice(GrContext* context, SkBitmap::Config config, int width,
1861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         int height, Usage usage)
1871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger: SkDevice(config, width, height, false /*isOpaque*/) {
18805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fNeedPrepareRenderTarget = false;
18905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fDrawProcs = NULL;
19005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
19105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fContext = context;
19205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fContext->ref();
19305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
19405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fTexture = NULL;
19505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fRenderTarget = NULL;
19605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fNeedClear = false;
19705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
1981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (config != SkBitmap::kRGB_565_Config) {
1991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        config = SkBitmap::kARGB_8888_Config;
2001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
2011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkBitmap bm;
2021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bm.setConfig(config, width, height);
20305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
20405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#if CACHE_LAYER_TEXTURES
2054f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    TexType type = (kSaveLayer_Usage == usage) ?
2061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            kSaveLayerDeviceRenderTarget_TexType :
2071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            kDeviceRenderTarget_TexType;
2081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fCache = this->lockCachedTexture(bm, NULL, type);
2091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fTexture = fCache.texture();
2101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (fTexture) {
2111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkASSERT(NULL != fTexture->asRenderTarget());
2121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // hold a ref directly on fTexture (even though fCache has one) to match
2131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // other constructor paths. Simplifies cleanup.
2141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fTexture->ref();
2151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
21605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#else
2171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrTextureDesc desc = {
2181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        kRenderTarget_GrTextureFlagBit,
2191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        width,
2201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        height,
2214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        SkGr::Bitmap2PixelConfig(bm),
2224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        {0} // samples
2231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
22405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
2251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fTexture = fContext->createUncachedTexture(desc, NULL, 0);
22605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#endif
2271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL != fTexture) {
2281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fRenderTarget = fTexture->asRenderTarget();
2291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fRenderTarget->ref();
23005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
2311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrAssert(NULL != fRenderTarget);
23205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
2331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // we defer the actual clear until our gainFocus()
2341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fNeedClear = true;
23505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
2361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // wrap the bitmap with a pixelref to expose our texture
2371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkGrTexturePixelRef* pr = new SkGrTexturePixelRef(fTexture);
23887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        this->setPixelRef(pr, 0)->unref();
2391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
2401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrPrintf("--- failed to create gpu-offscreen [%d %d]\n",
2411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                 width, height);
2421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrAssert(false);
24305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
24405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
24505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
24605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek SollenbergerSkGpuDevice::~SkGpuDevice() {
24705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (fDrawProcs) {
24805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        delete fDrawProcs;
24905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
25005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
2511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkSafeUnref(fTexture);
2521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkSafeUnref(fRenderTarget);
2531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (fCache.texture()) {
25405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        GrAssert(NULL != fTexture);
25505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        GrAssert(fRenderTarget == fTexture->asRenderTarget());
2561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fContext->unlockTexture(fCache);
2574f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    }
25805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fContext->unref();
25905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
26005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
26105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
26205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
26305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid SkGpuDevice::makeRenderTargetCurrent() {
26405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fContext->setRenderTarget(fRenderTarget);
26505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fContext->flush(true);
26605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fNeedPrepareRenderTarget = true;
26705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
26805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
26905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
27005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
2711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergernamespace {
2721cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrPixelConfig config8888_to_gr_config(SkCanvas::Config8888 config8888) {
2731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    switch (config8888) {
2741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        case SkCanvas::kNative_Premul_Config8888:
2751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return kSkia8888_PM_GrPixelConfig;
2761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        case SkCanvas::kNative_Unpremul_Config8888:
2771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return kSkia8888_UPM_GrPixelConfig;
2781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        case SkCanvas::kBGRA_Premul_Config8888:
2791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return kBGRA_8888_PM_GrPixelConfig;
2801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        case SkCanvas::kBGRA_Unpremul_Config8888:
2811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return kBGRA_8888_UPM_GrPixelConfig;
2821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        case SkCanvas::kRGBA_Premul_Config8888:
2831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return kRGBA_8888_PM_GrPixelConfig;
2841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        case SkCanvas::kRGBA_Unpremul_Config8888:
2851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return kRGBA_8888_UPM_GrPixelConfig;
2861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        default:
2871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrCrash("Unexpected Config8888.");
2881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return kSkia8888_PM_GrPixelConfig;
28905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
2901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
2911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
29205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
2931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkGpuDevice::onReadPixels(const SkBitmap& bitmap,
2941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                               int x, int y,
2951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                               SkCanvas::Config8888 config8888) {
2961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkASSERT(SkBitmap::kARGB_8888_Config == bitmap.config());
2971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkASSERT(!bitmap.isNull());
2981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkASSERT(SkIRect::MakeWH(this->width(), this->height()).contains(SkIRect::MakeXYWH(x, y, bitmap.width(), bitmap.height())));
29905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
3001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkAutoLockPixels alp(bitmap);
3011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrPixelConfig config;
3021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    config = config8888_to_gr_config(config8888);
3031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return fContext->readRenderTargetPixels(fRenderTarget,
3041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            x, y,
3051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            bitmap.width(),
3061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            bitmap.height(),
3071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            config,
3081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            bitmap.getPixels(),
3091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            bitmap.rowBytes());
31005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
31105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
3121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkGpuDevice::writePixels(const SkBitmap& bitmap, int x, int y,
3131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                              SkCanvas::Config8888 config8888) {
31405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkAutoLockPixels alp(bitmap);
31505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (!bitmap.readyToDraw()) {
31605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return;
31705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
31805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
3191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrPixelConfig config;
3201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (SkBitmap::kARGB_8888_Config == bitmap.config()) {
3211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        config = config8888_to_gr_config(config8888);
3221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
3231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        config= SkGr::BitmapConfig2PixelConfig(bitmap.config(),
3241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                               bitmap.isOpaque());
3251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
3261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fRenderTarget->writePixels(x, y, bitmap.width(), bitmap.height(),
3281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                               config, bitmap.getPixels(), bitmap.rowBytes());
32905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
33005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
33105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
33205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
33305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerstatic void convert_matrixclip(GrContext* context, const SkMatrix& matrix,
33405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                               const SkClipStack& clipStack,
33505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                               const SkRegion& clipRegion,
33605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                               const SkIPoint& origin) {
33735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    context->setMatrix(matrix);
33805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
33905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkGrClipIterator iter;
34005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    iter.reset(clipStack);
34105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    const SkIRect& skBounds = clipRegion.getBounds();
34205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrRect bounds;
34305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    bounds.setLTRB(GrIntToScalar(skBounds.fLeft),
34405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                   GrIntToScalar(skBounds.fTop),
34505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                   GrIntToScalar(skBounds.fRight),
34605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                   GrIntToScalar(skBounds.fBottom));
34705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrClip grc(&iter, GrIntToScalar(-origin.x()), GrIntToScalar(-origin.y()),
34805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger               &bounds);
34905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    context->setClip(grc);
35005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
35105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
35205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// call this ever each draw call, to ensure that the context reflects our state,
35305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// and not the state from some other canvas/device
35405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid SkGpuDevice::prepareRenderTarget(const SkDraw& draw) {
35505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (fNeedPrepareRenderTarget ||
35605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        fContext->getRenderTarget() != fRenderTarget) {
35705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
35805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        fContext->setRenderTarget(fRenderTarget);
35905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        SkASSERT(draw.fClipStack);
36005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        convert_matrixclip(fContext, *draw.fMatrix,
36105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                           *draw.fClipStack, *draw.fClip, this->getOrigin());
36205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        fNeedPrepareRenderTarget = false;
36305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
36405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
36505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
36605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid SkGpuDevice::setMatrixClip(const SkMatrix& matrix, const SkRegion& clip,
36705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                const SkClipStack& clipStack) {
36805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    this->INHERITED::setMatrixClip(matrix, clip, clipStack);
36987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    // We don't need to set them now because the context may not reflect this device.
37087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    fNeedPrepareRenderTarget = true;
37105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
37205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
37305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid SkGpuDevice::gainFocus(SkCanvas* canvas, const SkMatrix& matrix,
37405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                            const SkRegion& clip, const SkClipStack& clipStack) {
37505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
37605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fContext->setRenderTarget(fRenderTarget);
37705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
37805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    this->INHERITED::gainFocus(canvas, matrix, clip, clipStack);
37905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
38005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    convert_matrixclip(fContext, matrix, clipStack, clip, this->getOrigin());
38105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
38205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (fNeedClear) {
38335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        fContext->clear(NULL, 0x0);
38405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        fNeedClear = false;
38505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
38605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
38705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
3884f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerSkGpuRenderTarget* SkGpuDevice::accessRenderTarget() {
3894f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    return (SkGpuRenderTarget*)fRenderTarget;
3901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
3911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
39205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerbool SkGpuDevice::bindDeviceAsTexture(GrPaint* paint) {
39305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (NULL != fTexture) {
3940b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        paint->setTexture(kBitmapTextureIdx, fTexture);
39505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return true;
39605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
39705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    return false;
39805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
39905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
40005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
40105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
40205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek SollenbergerSK_COMPILE_ASSERT(SkShader::kNone_BitmapType == 0, shader_type_mismatch);
40305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek SollenbergerSK_COMPILE_ASSERT(SkShader::kDefault_BitmapType == 1, shader_type_mismatch);
40405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek SollenbergerSK_COMPILE_ASSERT(SkShader::kRadial_BitmapType == 2, shader_type_mismatch);
40505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek SollenbergerSK_COMPILE_ASSERT(SkShader::kSweep_BitmapType == 3, shader_type_mismatch);
40605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek SollenbergerSK_COMPILE_ASSERT(SkShader::kTwoPointRadial_BitmapType == 4,
40705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                  shader_type_mismatch);
40805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek SollenbergerSK_COMPILE_ASSERT(SkShader::kLast_BitmapType == 4, shader_type_mismatch);
40905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
41005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerstatic const GrSamplerState::SampleMode sk_bmp_type_to_sample_mode[] = {
41105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    (GrSamplerState::SampleMode) -1,                    // kNone_BitmapType
41205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrSamplerState::kNormal_SampleMode,                 // kDefault_BitmapType
41305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrSamplerState::kRadial_SampleMode,                 // kRadial_BitmapType
41405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrSamplerState::kSweep_SampleMode,                  // kSweep_BitmapType
41505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrSamplerState::kRadial2_SampleMode,                // kTwoPointRadial_BitmapType
41605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger};
41705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
41805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerbool SkGpuDevice::skPaint2GrPaintNoShader(const SkPaint& skPaint,
41905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                          bool justAlpha,
4200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                          GrPaint* grPaint,
4210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                          bool constantColor) {
42205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
42305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    grPaint->fDither    = skPaint.isDither();
42405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    grPaint->fAntiAlias = skPaint.isAntiAlias();
4254f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    grPaint->fCoverage = 0xFF;
42605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
42705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkXfermode::Coeff sm = SkXfermode::kOne_Coeff;
42805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkXfermode::Coeff dm = SkXfermode::kISA_Coeff;
42905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
43005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkXfermode* mode = skPaint.getXfermode();
43105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (mode) {
43205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        if (!mode->asCoeff(&sm, &dm)) {
4331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            //SkDEBUGCODE(SkDebugf("Unsupported xfer mode.\n");)
43405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#if 0
43505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            return false;
43605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#endif
43705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        }
43805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
43905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    grPaint->fSrcBlendCoeff = sk_blend_to_grblend(sm);
44005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    grPaint->fDstBlendCoeff = sk_blend_to_grblend(dm);
44105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
44205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (justAlpha) {
44305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        uint8_t alpha = skPaint.getAlpha();
44405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        grPaint->fColor = GrColorPackRGBA(alpha, alpha, alpha, alpha);
4450b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        // justAlpha is currently set to true only if there is a texture,
4460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        // so constantColor should not also be true.
4470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        GrAssert(!constantColor);
44805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    } else {
44905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        grPaint->fColor = SkGr::SkColor2GrColor(skPaint.getColor());
4500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        grPaint->setTexture(kShaderTextureIdx, NULL);
45105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
45235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkColorFilter* colorFilter = skPaint.getColorFilter();
45335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkColor color;
45435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkXfermode::Mode filterMode;
4551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkScalar matrix[20];
45635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    if (colorFilter != NULL && colorFilter->asColorMode(&color, &filterMode)) {
4571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        grPaint->fColorMatrixEnabled = false;
4580b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (!constantColor) {
4590b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            grPaint->fColorFilterColor = SkGr::SkColor2GrColor(color);
4600b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            grPaint->fColorFilterXfermode = filterMode;
4611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else {
4621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            SkColor filtered = colorFilter->filterColor(skPaint.getColor());
4631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            grPaint->fColor = SkGr::SkColor2GrColor(filtered);
4641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            grPaint->resetColorFilter();
4650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
4661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else if (colorFilter != NULL && colorFilter->asColorMatrix(matrix)) {
4671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        grPaint->fColorMatrixEnabled = true;
4681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        memcpy(grPaint->fColorMatrix, matrix, sizeof(matrix));
4691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        grPaint->fColorFilterXfermode = SkXfermode::kDst_Mode;
4701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
4711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        grPaint->resetColorFilter();
47235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    }
47305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    return true;
47405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
47505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
47605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerbool SkGpuDevice::skPaint2GrPaintShader(const SkPaint& skPaint,
47705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                        SkAutoCachedTexture* act,
47805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                        const SkMatrix& ctm,
4790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                        GrPaint* grPaint,
4800b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                        bool constantColor) {
48105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
48205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkASSERT(NULL != act);
48305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
48405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkShader* shader = skPaint.getShader();
48505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (NULL == shader) {
4860b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        return this->skPaint2GrPaintNoShader(skPaint,
4870b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                             false,
4880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                             grPaint,
4890b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                             constantColor);
4900b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    } else if (!this->skPaint2GrPaintNoShader(skPaint, true, grPaint, false)) {
49105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return false;
49205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
49305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
49405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkBitmap bitmap;
4951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkMatrix* matrix = grPaint->textureSampler(kShaderTextureIdx)->matrix();
49605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkShader::TileMode tileModes[2];
49705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkScalar twoPointParams[3];
4981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkShader::BitmapType bmptype = shader->asABitmap(&bitmap, matrix,
49905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                                     tileModes, twoPointParams);
50005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
50105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrSamplerState::SampleMode sampleMode = sk_bmp_type_to_sample_mode[bmptype];
50205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (-1 == sampleMode) {
5031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkShader::GradientInfo info;
5041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkColor                color;
5051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        info.fColors = &color;
5071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        info.fColorOffsets = NULL;
5081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        info.fColorCount = 1;
5091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (SkShader::kColor_GradientType == shader->asAGradient(&info)) {
5101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            SkPaint copy(skPaint);
5111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            copy.setShader(NULL);
5121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // modulate the paint alpha by the shader's solid color alpha
5131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            U8CPU newA = SkMulDiv255Round(SkColorGetA(color), copy.getAlpha());
5141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            copy.setColor(SkColorSetA(color, newA));
5151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return this->skPaint2GrPaintNoShader(copy,
5161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                 false,
5171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                 grPaint,
5181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                 constantColor);
5191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
52005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return false;
52105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
5221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrSamplerState* sampler = grPaint->textureSampler(kShaderTextureIdx);
5230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    sampler->setSampleMode(sampleMode);
52435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    if (skPaint.isFilterBitmap()) {
5250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        sampler->setFilter(GrSamplerState::kBilinear_Filter);
52635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    } else {
5270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        sampler->setFilter(GrSamplerState::kNearest_Filter);
52835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    }
5290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    sampler->setWrapX(sk_tile_mode_to_grwrap(tileModes[0]));
5300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    sampler->setWrapY(sk_tile_mode_to_grwrap(tileModes[1]));
53105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (GrSamplerState::kRadial2_SampleMode == sampleMode) {
5320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        sampler->setRadial2Params(twoPointParams[0],
5330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                  twoPointParams[1],
5340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                  twoPointParams[2] < 0);
53505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
53605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
5371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrTexture* texture = act->set(this, bitmap, sampler);
53805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (NULL == texture) {
53905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        SkDebugf("Couldn't convert bitmap to texture.\n");
54005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return false;
54105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
5420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    grPaint->setTexture(kShaderTextureIdx, texture);
54305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
54405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    // since our texture coords will be in local space, we wack the texture
54505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    // matrix to map them back into 0...1 before we load it
54605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkMatrix localM;
54705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (shader->getLocalMatrix(&localM)) {
54805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        SkMatrix inverse;
54905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        if (localM.invert(&inverse)) {
5501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            matrix->preConcat(inverse);
55105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        }
55205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
55305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (SkShader::kDefault_BitmapType == bmptype) {
55405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        GrScalar sx = GrFixedToScalar(GR_Fixed1 / bitmap.width());
55505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        GrScalar sy = GrFixedToScalar(GR_Fixed1 / bitmap.height());
5561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        matrix->postScale(sx, sy);
55705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    } else if (SkShader::kRadial_BitmapType == bmptype) {
55805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        GrScalar s = GrFixedToScalar(GR_Fixed1 / bitmap.width());
5591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        matrix->postScale(s, s);
56005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
56105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
56205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    return true;
56305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
56405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
56505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
56605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
56735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergervoid SkGpuDevice::clear(SkColor color) {
56835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    fContext->clear(NULL, color);
56935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger}
57035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
57105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
57205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    CHECK_SHOULD_DRAW(draw);
57305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
57405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrPaint grPaint;
57505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkAutoCachedTexture act;
5760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (!this->skPaint2GrPaintShader(paint,
5770b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                     &act,
5780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                     *draw.fMatrix,
5790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                     &grPaint,
5800b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                     true)) {
58105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return;
58205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
58305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
58405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fContext->drawPaint(grPaint);
58505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
58605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
58705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// must be in SkCanvas::PointMode order
58805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerstatic const GrPrimitiveType gPointMode2PrimtiveType[] = {
58905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    kPoints_PrimitiveType,
59005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    kLines_PrimitiveType,
59105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    kLineStrip_PrimitiveType
59205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger};
59305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
59405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
59505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                             size_t count, const SkPoint pts[], const SkPaint& paint) {
59605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    CHECK_SHOULD_DRAW(draw);
59705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
59805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkScalar width = paint.getStrokeWidth();
59905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (width < 0) {
60005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return;
60105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
60205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
60305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    // we only handle hairlines here, else we let the SkDraw call our drawPath()
60405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (width > 0) {
60505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        draw.drawPoints(mode, count, pts, paint, true);
60605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return;
60705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
60805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
60905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrPaint grPaint;
61005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkAutoCachedTexture act;
6110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (!this->skPaint2GrPaintShader(paint,
6120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                     &act,
6130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                     *draw.fMatrix,
6140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                     &grPaint,
6150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                     true)) {
61605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return;
61705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
61805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
61905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fContext->drawVertices(grPaint,
62005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                           gPointMode2PrimtiveType[mode],
62105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                           count,
62205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                           (GrPoint*)pts,
62305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                           NULL,
62405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                           NULL,
62505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                           NULL,
62605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                           0);
62705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
62805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
62987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
63087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
63105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect,
63205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                          const SkPaint& paint) {
63305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    CHECK_SHOULD_DRAW(draw);
63405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
6351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool doStroke = paint.getStyle() != SkPaint::kFill_Style;
63635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkScalar width = paint.getStrokeWidth();
63735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
63835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    /*
63935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        We have special code for hairline strokes, miter-strokes, and fills.
64035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        Anything else we just call our path code.
64135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger     */
64235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    bool usePath = doStroke && width > 0 &&
64335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger                    paint.getStrokeJoin() != SkPaint::kMiter_Join;
64435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    // another reason we might need to call drawPath...
64535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    if (paint.getMaskFilter()) {
64635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        usePath = true;
64735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    }
6480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    // until we aa rotated rects...
6490b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (!usePath && paint.isAntiAlias() && !draw.fMatrix->rectStaysRect()) {
6500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        usePath = true;
6510b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
6521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // small miter limit means right angles show bevel...
6531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (SkPaint::kMiter_Join == paint.getStrokeJoin() &&
6541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        paint.getStrokeMiter() < SK_ScalarSqrt2)
6551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    {
6561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        usePath = true;
6571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
6581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // until we can both stroke and fill rectangles
6591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (paint.getStyle() == SkPaint::kStrokeAndFill_Style) {
6601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        usePath = true;
6611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
66205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
66335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    if (usePath) {
66405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        SkPath path;
66505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        path.addRect(rect);
66605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        this->drawPath(draw, path, paint, NULL, true);
66735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        return;
66835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    }
66987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
67035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    GrPaint grPaint;
67135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkAutoCachedTexture act;
6720b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (!this->skPaint2GrPaintShader(paint,
6730b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                     &act,
6740b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                     *draw.fMatrix,
6750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                     &grPaint,
6760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                     true)) {
67735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        return;
67805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
67935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    fContext->drawRect(grPaint, rect, doStroke ? width : -1);
68005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
68105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
68205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#include "SkMaskFilter.h"
68305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#include "SkBounder.h"
68405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
6851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic GrPathFill skToGrFillType(SkPath::FillType fillType) {
6861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    switch (fillType) {
6871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        case SkPath::kWinding_FillType:
6881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return kWinding_PathFill;
6891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        case SkPath::kEvenOdd_FillType:
6901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return kEvenOdd_PathFill;
6911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        case SkPath::kInverseWinding_FillType:
6921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return kInverseWinding_PathFill;
6931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        case SkPath::kInverseEvenOdd_FillType:
6941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return kInverseEvenOdd_PathFill;
6951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        default:
6961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            SkDebugf("Unsupported path fill type\n");
6971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return kHairLine_PathFill;
6981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
6991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
7001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerstatic GrTexture* applyMorphology(GrContext* context, GrTexture* texture,
7024f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                  const GrRect& srcRect,
7034f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                  GrTexture* temp1, GrTexture* temp2,
7044f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                  GrSamplerState::Filter filter,
7054f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                  SkISize radius) {
7064f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    GrRenderTarget* oldRenderTarget = context->getRenderTarget();
7074f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    GrAutoMatrix avm(context, GrMatrix::I());
7084f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    GrClip oldClip = context->getClip();
7094f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    context->setClip(GrRect::MakeWH(texture->width(), texture->height()));
7104f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (radius.fWidth > 0) {
7114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        context->setRenderTarget(temp1->asRenderTarget());
7124f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        context->applyMorphology(texture, srcRect, radius.fWidth, filter,
7134f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                 GrSamplerState::kX_FilterDirection);
7144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        SkIRect clearRect = SkIRect::MakeXYWH(
7154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            srcRect.fLeft, srcRect.fBottom,
7164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            srcRect.width(), radius.fHeight);
7174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        context->clear(&clearRect, 0x0);
7184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        texture = temp1;
7194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    }
7204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (radius.fHeight > 0) {
7214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        context->setRenderTarget(temp2->asRenderTarget());
7224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        context->applyMorphology(texture, srcRect, radius.fHeight, filter,
7234f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                 GrSamplerState::kY_FilterDirection);
7244f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        texture = temp2;
7254f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    }
7264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    context->setRenderTarget(oldRenderTarget);
7274f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    context->setClip(oldClip);
7284f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    return texture;
7294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger}
7304f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
7311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void buildKernel(float sigma, float* kernel, int kernelWidth) {
7321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int halfWidth = (kernelWidth - 1) / 2;
7331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    float sum = 0.0f;
7341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    float denom = 1.0f / (2.0f * sigma * sigma);
7351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (int i = 0; i < kernelWidth; ++i) {
7361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        float x = static_cast<float>(i - halfWidth);
7371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // Note that the constant term (1/(sqrt(2*pi*sigma^2)) of the Gaussian
7381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // is dropped here, since we renormalize the kernel below.
7391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        kernel[i] = sk_float_exp(- x * x * denom);
7401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        sum += kernel[i];
7411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
7421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Normalize the kernel
7431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    float scale = 1.0f / sum;
7441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (int i = 0; i < kernelWidth; ++i)
7451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        kernel[i] *= scale;
7461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
7471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void scaleRect(SkRect* rect, float xScale, float yScale) {
7491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    rect->fLeft *= xScale;
7501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    rect->fTop *= yScale;
7511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    rect->fRight *= xScale;
7521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    rect->fBottom *= yScale;
7531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
7541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic float adjustSigma(float sigma, int *scaleFactor, int *halfWidth,
7561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         int *kernelWidth) {
7571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    *scaleFactor = 1;
7581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    while (sigma > MAX_BLUR_SIGMA) {
7591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        *scaleFactor *= 2;
7601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        sigma *= 0.5f;
7611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
7621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    *halfWidth = static_cast<int>(ceilf(sigma * 3.0f));
7631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    *kernelWidth = *halfWidth * 2 + 1;
7641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return sigma;
7651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
7661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// Apply a Gaussian blur to srcTexture by sigmaX and sigmaY, within the given
7681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// rect.
7691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// temp1 and temp2 are used for allocation of intermediate textures.
7704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger// If temp2 is non-NULL, srcTexture will be untouched, and the return
7711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// value will be either temp1 or temp2.
7721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// If temp2 is NULL, srcTexture will be overwritten with intermediate
7731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// results, and the return value will either be temp1 or srcTexture.
7741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic GrTexture* gaussianBlur(GrContext* context, GrTexture* srcTexture,
7751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                               GrAutoScratchTexture* temp1,
7761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                               GrAutoScratchTexture* temp2,
7771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                               const SkRect& rect,
7781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                               float sigmaX, float sigmaY) {
7791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrRenderTarget* oldRenderTarget = context->getRenderTarget();
7811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrClip oldClip = context->getClip();
7821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrTexture* origTexture = srcTexture;
7831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAutoMatrix avm(context, GrMatrix::I());
7841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkIRect clearRect;
7851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int scaleFactorX, halfWidthX, kernelWidthX;
7861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int scaleFactorY, halfWidthY, kernelWidthY;
7871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    sigmaX = adjustSigma(sigmaX, &scaleFactorX, &halfWidthX, &kernelWidthX);
7881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    sigmaY = adjustSigma(sigmaY, &scaleFactorY, &halfWidthY, &kernelWidthY);
7891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkRect srcRect(rect);
7911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    scaleRect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY);
7921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    srcRect.roundOut();
7931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    scaleRect(&srcRect, scaleFactorX, scaleFactorY);
7941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    context->setClip(srcRect);
7951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrTextureDesc desc = {
7971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit,
7981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        srcRect.width(),
7991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        srcRect.height(),
8004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        kRGBA_8888_GrPixelConfig,
8014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        {0} // samples
8021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
8031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    temp1->set(context, desc);
8051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (temp2) temp2->set(context, desc);
8061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrTexture* dstTexture = temp1->texture();
8081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrPaint paint;
8091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    paint.reset();
8101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    paint.textureSampler(0)->setFilter(GrSamplerState::kBilinear_Filter);
8111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) {
8131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        paint.textureSampler(0)->matrix()->setIDiv(srcTexture->width(),
8141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                   srcTexture->height());
8151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        context->setRenderTarget(dstTexture->asRenderTarget());
8161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkRect dstRect(srcRect);
8174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        scaleRect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f,
8181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            i < scaleFactorY ? 0.5f : 1.0f);
8191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        paint.setTexture(0, srcTexture);
8201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        context->drawRectToRect(paint, dstRect, srcRect);
8211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        srcRect = dstRect;
8221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkTSwap(srcTexture, dstTexture);
8231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // If temp2 is non-NULL, don't render back to origTexture
8241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (temp2 && dstTexture == origTexture) dstTexture = temp2->texture();
8251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
8261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (sigmaX > 0.0f) {
8281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkAutoTMalloc<float> kernelStorageX(kernelWidthX);
8291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        float* kernelX = kernelStorageX.get();
8301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        buildKernel(sigmaX, kernelX, kernelWidthX);
8311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (scaleFactorX > 1) {
8331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // Clear out a halfWidth to the right of the srcRect to prevent the
8341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // X convolution from reading garbage.
8351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            clearRect = SkIRect::MakeXYWH(
8361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                srcRect.fRight, srcRect.fTop, halfWidthX, srcRect.height());
8371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            context->clear(&clearRect, 0x0);
8381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
8391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        context->setRenderTarget(dstTexture->asRenderTarget());
8414f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        context->convolve(srcTexture, srcRect, kernelX, kernelWidthX,
8424f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                          GrSamplerState::kX_FilterDirection);
8431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkTSwap(srcTexture, dstTexture);
8441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (temp2 && dstTexture == origTexture) dstTexture = temp2->texture();
8451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
8461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (sigmaY > 0.0f) {
8481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkAutoTMalloc<float> kernelStorageY(kernelWidthY);
8491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        float* kernelY = kernelStorageY.get();
8501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        buildKernel(sigmaY, kernelY, kernelWidthY);
8511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (scaleFactorY > 1 || sigmaX > 0.0f) {
8531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // Clear out a halfWidth below the srcRect to prevent the Y
8541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // convolution from reading garbage.
8551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            clearRect = SkIRect::MakeXYWH(
8561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                srcRect.fLeft, srcRect.fBottom, srcRect.width(), halfWidthY);
8571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            context->clear(&clearRect, 0x0);
8581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
8591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        context->setRenderTarget(dstTexture->asRenderTarget());
8614f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        context->convolve(srcTexture, srcRect, kernelY, kernelWidthY,
8624f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                          GrSamplerState::kY_FilterDirection);
8631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkTSwap(srcTexture, dstTexture);
8641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (temp2 && dstTexture == origTexture) dstTexture = temp2->texture();
8651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
8661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (scaleFactorX > 1 || scaleFactorY > 1) {
8681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // Clear one pixel to the right and below, to accommodate bilinear
8691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // upsampling.
8701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        clearRect = SkIRect::MakeXYWH(
8711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            srcRect.fLeft, srcRect.fBottom, srcRect.width() + 1, 1);
8721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        context->clear(&clearRect, 0x0);
8731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        clearRect = SkIRect::MakeXYWH(
8741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            srcRect.fRight, srcRect.fTop, 1, srcRect.height());
8751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        context->clear(&clearRect, 0x0);
8761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // FIXME:  This should be mitchell, not bilinear.
8771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        paint.textureSampler(0)->setFilter(GrSamplerState::kBilinear_Filter);
8781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        paint.textureSampler(0)->matrix()->setIDiv(srcTexture->width(),
8791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                   srcTexture->height());
8801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        context->setRenderTarget(dstTexture->asRenderTarget());
8811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        paint.setTexture(0, srcTexture);
8821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkRect dstRect(srcRect);
8831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        scaleRect(&dstRect, scaleFactorX, scaleFactorY);
8841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        context->drawRectToRect(paint, dstRect, srcRect);
8851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        srcRect = dstRect;
8861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkTSwap(srcTexture, dstTexture);
8871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
8881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    context->setRenderTarget(oldRenderTarget);
8891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    context->setClip(oldClip);
8901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return srcTexture;
8911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
8921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path,
8941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                  SkMaskFilter* filter, const SkMatrix& matrix,
8951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                  const SkRegion& clip, SkBounder* bounder,
8961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                  GrPaint* grp) {
8971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_DISABLE_GPU_BLUR
8981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return false;
8991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
9001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkMaskFilter::BlurInfo info;
9011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkMaskFilter::BlurType blurType = filter->asABlur(&info);
9021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (SkMaskFilter::kNone_BlurType == blurType) {
9031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
9041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
9051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkScalar radius = info.fIgnoreTransform ? info.fRadius
9061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            : matrix.mapRadius(info.fRadius);
9071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    radius = SkMinScalar(radius, MAX_BLUR_RADIUS);
9081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (radius <= 0) {
9091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
9101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
9111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    float sigma = SkScalarToFloat(radius) * BLUR_SIGMA_SCALE;
9121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    float sigma3 = sigma * 3.0f;
9131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkRect srcRect = path.getBounds();
9151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkRect clipRect;
9161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    clipRect.set(clip.getBounds());
9171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Outset srcRect and clipRect by 3 * sigma, to compute affected blur area.
9191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    srcRect.inset(-sigma3, -sigma3);
9201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    clipRect.inset(-sigma3, -sigma3);
9211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    srcRect.intersect(clipRect);
9221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkRect finalRect = srcRect;
9231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkIRect finalIRect;
9241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    finalRect.roundOut(&finalIRect);
9251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (clip.quickReject(finalIRect)) {
9261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return true;
9271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
9281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (bounder && !bounder->doIRect(finalIRect)) {
9291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return true;
9301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
9311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrPoint offset = GrPoint::Make(-srcRect.fLeft, -srcRect.fTop);
9321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    srcRect.offset(offset);
9331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrTextureDesc desc = {
9341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        kRenderTarget_GrTextureFlagBit,
9351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        srcRect.width(),
9361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        srcRect.height(),
9371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // We actually only need A8, but it often isn't supported as a
9381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // render target
9394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        kRGBA_8888_PM_GrPixelConfig,
9404f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        {0} // samples
9411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
9421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAutoScratchTexture pathEntry(context, desc);
9441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrTexture* pathTexture = pathEntry.texture();
9451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL == pathTexture) {
9461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
9471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
9481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrRenderTarget* oldRenderTarget = context->getRenderTarget();
9491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Once this code moves into GrContext, this should be changed to use
9501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // an AutoClipRestore.
9511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrClip oldClip = context->getClip();
9521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    context->setRenderTarget(pathTexture->asRenderTarget());
9531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    context->setClip(srcRect);
9541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    context->clear(NULL, 0);
9551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrPaint tempPaint;
9561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    tempPaint.reset();
9571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAutoMatrix avm(context, GrMatrix::I());
9591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    tempPaint.fAntiAlias = grp->fAntiAlias;
9601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (tempPaint.fAntiAlias) {
9611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // AA uses the "coverage" stages on GrDrawTarget. Coverage with a dst
9621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // blend coeff of zero requires dual source blending support in order
9631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // to properly blend partially covered pixels. This means the AA
9641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // code path may not be taken. So we use a dst blend coeff of ISA. We
9651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // could special case AA draws to a dst surface with known alpha=0 to
9661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // use a zero dst coeff when dual source blending isn't available.
9671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        tempPaint.fSrcBlendCoeff = kOne_BlendCoeff;
9681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        tempPaint.fDstBlendCoeff = kISC_BlendCoeff;
9691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
9701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Draw hard shadow to pathTexture with path topleft at origin 0,0.
9711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    context->drawPath(tempPaint, path, skToGrFillType(path.getFillType()), &offset);
9721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAutoScratchTexture temp1, temp2;
9741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // If we're doing a normal blur, we can clobber the pathTexture in the
9751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // gaussianBlur.  Otherwise, we need to save it for later compositing.
9761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool isNormalBlur = blurType == SkMaskFilter::kNormal_BlurType;
9771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrTexture* blurTexture = gaussianBlur(context, pathTexture,
9781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                          &temp1, isNormalBlur ? NULL : &temp2,
9791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                          srcRect, sigma, sigma);
9801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (!isNormalBlur) {
9821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrPaint paint;
9831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        paint.reset();
9841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        paint.textureSampler(0)->setFilter(GrSamplerState::kNearest_Filter);
9851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        paint.textureSampler(0)->matrix()->setIDiv(pathTexture->width(),
9861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                   pathTexture->height());
9871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // Blend pathTexture over blurTexture.
9881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        context->setRenderTarget(blurTexture->asRenderTarget());
9891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        paint.setTexture(0, pathTexture);
9901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (SkMaskFilter::kInner_BlurType == blurType) {
9911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // inner:  dst = dst * src
9921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            paint.fSrcBlendCoeff = kDC_BlendCoeff;
9931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            paint.fDstBlendCoeff = kZero_BlendCoeff;
9941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else if (SkMaskFilter::kSolid_BlurType == blurType) {
9951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // solid:  dst = src + dst - src * dst
9961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            //             = (1 - dst) * src + 1 * dst
9971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            paint.fSrcBlendCoeff = kIDC_BlendCoeff;
9981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            paint.fDstBlendCoeff = kOne_BlendCoeff;
9991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else if (SkMaskFilter::kOuter_BlurType == blurType) {
10001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // outer:  dst = dst * (1 - src)
10011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            //             = 0 * src + (1 - src) * dst
10021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            paint.fSrcBlendCoeff = kZero_BlendCoeff;
10031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            paint.fDstBlendCoeff = kISC_BlendCoeff;
10041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
10051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        context->drawRect(paint, srcRect);
10061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
10071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    context->setRenderTarget(oldRenderTarget);
10081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    context->setClip(oldClip);
10094f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
10101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (grp->hasTextureOrMask()) {
10111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrMatrix inverse;
10121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (!matrix.invert(&inverse)) {
10131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return false;
10141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
10151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        grp->preConcatActiveSamplerMatrices(inverse);
10161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
10171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static const int MASK_IDX = GrPaint::kMaxMasks - 1;
10191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // we assume the last mask index is available for use
10201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAssert(NULL == grp->getMask(MASK_IDX));
10211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    grp->setMask(MASK_IDX, blurTexture);
10221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    grp->maskSampler(MASK_IDX)->reset();
10231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    grp->maskSampler(MASK_IDX)->matrix()->setTranslate(-finalRect.fLeft,
10251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                       -finalRect.fTop);
10261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    grp->maskSampler(MASK_IDX)->matrix()->postIDiv(blurTexture->width(),
10271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                   blurTexture->height());
10281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    context->drawRect(*grp, finalRect);
10291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return true;
10301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
10311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
103205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerstatic bool drawWithMaskFilter(GrContext* context, const SkPath& path,
103305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                               SkMaskFilter* filter, const SkMatrix& matrix,
103405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                               const SkRegion& clip, SkBounder* bounder,
103505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                               GrPaint* grp) {
103605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkMask  srcM, dstM;
103705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
103805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (!SkDraw::DrawToMask(path, &clip.getBounds(), filter, &matrix, &srcM,
103905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                            SkMask::kComputeBoundsAndRenderImage_CreateMode)) {
104005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return false;
104105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
10421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkAutoMaskFreeImage autoSrc(srcM.fImage);
104305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
104405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (!filter->filterMask(&dstM, srcM, matrix, NULL)) {
104505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return false;
104605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
104705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    // this will free-up dstM when we're done (allocated in filterMask())
10481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkAutoMaskFreeImage autoDst(dstM.fImage);
104905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
105005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (clip.quickReject(dstM.fBounds)) {
105105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return false;
105205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
105305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (bounder && !bounder->doIRect(dstM.fBounds)) {
105405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return false;
105505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
105605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
105705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    // we now have a device-aligned 8bit mask in dstM, ready to be drawn using
105805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    // the current clip (and identity matrix) and grpaint settings
105905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
10600b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    // used to compute inverse view, if necessary
10610b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    GrMatrix ivm = context->getMatrix();
10620b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
106305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrAutoMatrix avm(context, GrMatrix::I());
106405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
106535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    const GrTextureDesc desc = {
106635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        kNone_GrTextureFlags,
106705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        dstM.fBounds.width(),
106805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        dstM.fBounds.height(),
10694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        kAlpha_8_GrPixelConfig,
10704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        {0}, // samples
107105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    };
107205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
10731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAutoScratchTexture ast(context, desc);
10741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrTexture* texture = ast.texture();
10751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
107605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (NULL == texture) {
107705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return false;
107805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
10791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
10801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                               dstM.fImage, dstM.fRowBytes);
108105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
10820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (grp->hasTextureOrMask() && ivm.invert(&ivm)) {
10830b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        grp->preConcatActiveSamplerMatrices(ivm);
10840b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
10850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
10860b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    static const int MASK_IDX = GrPaint::kMaxMasks - 1;
10870b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    // we assume the last mask index is available for use
10880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    GrAssert(NULL == grp->getMask(MASK_IDX));
10890b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    grp->setMask(MASK_IDX, texture);
10901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    grp->maskSampler(MASK_IDX)->reset();
109105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
109205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrRect d;
109305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    d.setLTRB(GrIntToScalar(dstM.fBounds.fLeft),
109405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger              GrIntToScalar(dstM.fBounds.fTop),
109505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger              GrIntToScalar(dstM.fBounds.fRight),
109605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger              GrIntToScalar(dstM.fBounds.fBottom));
10970b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
10981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrMatrix* m = grp->maskSampler(MASK_IDX)->matrix();
10991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    m->setTranslate(-dstM.fBounds.fLeft*SK_Scalar1,
11001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         -dstM.fBounds.fTop*SK_Scalar1);
11011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    m->postIDiv(texture->width(), texture->height());
11020b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    context->drawRect(*grp, d);
110305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    return true;
110405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
110505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
110605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
11074f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                           const SkPaint& paint, const SkMatrix* prePathMatrix,
110805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                           bool pathIsMutable) {
110905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    CHECK_SHOULD_DRAW(draw);
111005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
11111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool             doFill = true;
11124f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
11134f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    SkScalar coverage = SK_Scalar1;
11144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    // can we cheat, and threat a thin stroke as a hairline w/ coverage
11151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // if we can, we draw lots faster (raster device does this same test)
11164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (SkDrawTreatAsHairline(paint, *draw.fMatrix, &coverage)) {
11174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        doFill = false;
11181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
11194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
112005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrPaint grPaint;
112105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkAutoCachedTexture act;
11224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (!this->skPaint2GrPaintShader(paint,
11230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                     &act,
11240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                     *draw.fMatrix,
11250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                     &grPaint,
11260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                     true)) {
112705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return;
112805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
112905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
11304f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    grPaint.fCoverage = SkScalarRoundToInt(coverage * grPaint.fCoverage);
11314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
11321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // If we have a prematrix, apply it to the path, optimizing for the case
11331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // where the original path can in fact be modified in place (even though
11341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // its parameter type is const).
11351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath* pathPtr = const_cast<SkPath*>(&origSrcPath);
11361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath  tmpPath;
113705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
113805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (prePathMatrix) {
113905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        SkPath* result = pathPtr;
114005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
114105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        if (!pathIsMutable) {
114205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            result = &tmpPath;
114305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            pathIsMutable = true;
114405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        }
114505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        // should I push prePathMatrix on our MV stack temporarily, instead
114605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        // of applying it here? See SkDraw.cpp
114705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        pathPtr->transform(*prePathMatrix, result);
114805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        pathPtr = result;
114905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
115005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    // at this point we're done with prePathMatrix
115105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;)
115205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
11534f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (paint.getPathEffect() ||
11544f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        (doFill && paint.getStyle() != SkPaint::kFill_Style)) {
11551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // it is safe to use tmpPath here, even if we already used it for the
11561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // prepathmatrix, since getFillPath can take the same object for its
11571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // input and output safely.
11584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        doFill = paint.getFillPath(*pathPtr, &tmpPath);
115905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        pathPtr = &tmpPath;
116005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
116105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
11624f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (paint.getMaskFilter()) {
116305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        // avoid possibly allocating a new path in transform if we can
116405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        SkPath* devPathPtr = pathIsMutable ? pathPtr : &tmpPath;
116505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
116605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        // transform the path into device space
116705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        pathPtr->transform(*draw.fMatrix, devPathPtr);
11684f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        if (!drawWithGPUMaskFilter(fContext, *devPathPtr, paint.getMaskFilter(),
11691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                   *draw.fMatrix, *draw.fClip, draw.fBounder,
11701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                   &grPaint)) {
11714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            drawWithMaskFilter(fContext, *devPathPtr, paint.getMaskFilter(),
11721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                               *draw.fMatrix, *draw.fClip, draw.fBounder,
11731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                               &grPaint);
11741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
117505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return;
117605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
117705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
117805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrPathFill fill = kHairLine_PathFill;
117905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
118005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (doFill) {
118105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        switch (pathPtr->getFillType()) {
118205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            case SkPath::kWinding_FillType:
118305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                fill = kWinding_PathFill;
118405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                break;
118505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            case SkPath::kEvenOdd_FillType:
118605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                fill = kEvenOdd_PathFill;
118705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                break;
118805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            case SkPath::kInverseWinding_FillType:
118905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                fill = kInverseWinding_PathFill;
119005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                break;
119105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            case SkPath::kInverseEvenOdd_FillType:
119205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                fill = kInverseEvenOdd_PathFill;
119305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                break;
119405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            default:
119505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                SkDebugf("Unsupported path fill type\n");
119605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                return;
119705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        }
119805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
119905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
12000b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    fContext->drawPath(grPaint, *pathPtr, fill);
120105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
120205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
12031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergernamespace {
12041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
12051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerinline int get_tile_count(int l, int t, int r, int b, int tileSize)  {
12061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int tilesX = (r / tileSize) - (l / tileSize) + 1;
12071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int tilesY = (b / tileSize) - (t / tileSize) + 1;
12081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return tilesX * tilesY;
12091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
12101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
12114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerinline int determine_tile_size(const SkBitmap& bitmap,
12121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                               const SkIRect* srcRectPtr,
12131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                               int maxTextureSize) {
12141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static const int kSmallTileSize = 1 << 10;
12151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (maxTextureSize <= kSmallTileSize) {
12161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return maxTextureSize;
12171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
12181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
12191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    size_t maxTexTotalTileSize;
12201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    size_t smallTotalTileSize;
12211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
12221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL == srcRectPtr) {
12231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int w = bitmap.width();
12241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int h = bitmap.height();
12251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        maxTexTotalTileSize = get_tile_count(0, 0, w, h, maxTextureSize);
12261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        smallTotalTileSize = get_tile_count(0, 0, w, h, kSmallTileSize);
12271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
12281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        maxTexTotalTileSize = get_tile_count(srcRectPtr->fLeft,
12291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                             srcRectPtr->fTop,
12301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                             srcRectPtr->fRight,
12311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                             srcRectPtr->fBottom,
12321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                             maxTextureSize);
12331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        smallTotalTileSize = get_tile_count(srcRectPtr->fLeft,
12341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            srcRectPtr->fTop,
12351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            srcRectPtr->fRight,
12361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            srcRectPtr->fBottom,
12371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            kSmallTileSize);
12381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
12391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    maxTexTotalTileSize *= maxTextureSize * maxTextureSize;
12401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    smallTotalTileSize *= kSmallTileSize * kSmallTileSize;
12411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
12421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (maxTexTotalTileSize > 2 * smallTotalTileSize) {
12431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return kSmallTileSize;
12441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
12451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return maxTextureSize;
12461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
12471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
12481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
12491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
12501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkGpuDevice::shouldTileBitmap(const SkBitmap& bitmap,
12511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                   const GrSamplerState& sampler,
12521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                   const SkIRect* srcRectPtr,
12531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                   int* tileSize) const {
12541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkASSERT(NULL != tileSize);
12551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
12561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // if bitmap is explictly texture backed then just use the texture
12571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL != bitmap.getTexture()) {
12581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
12591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
12601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // if it's larger than the max texture size, then we have no choice but
12611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // tiling
12621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const int maxTextureSize = fContext->getMaxTextureSize();
12631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (bitmap.width() > maxTextureSize ||
12641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        bitmap.height() > maxTextureSize) {
12651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        *tileSize = determine_tile_size(bitmap, srcRectPtr, maxTextureSize);
12661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return true;
12671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
12681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // if we are going to have to draw the whole thing, then don't tile
12691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL == srcRectPtr) {
12701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
12711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
12721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // if the entire texture is already in our cache then no reason to tile it
12731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (this->isBitmapInTextureCache(bitmap, sampler)) {
12741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
12751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
12761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
12771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // At this point we know we could do the draw by uploading the entire bitmap
12781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // as a texture. However, if the texture would be large compared to the
12791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // cache size and we don't require most of it for this draw then tile to
12801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // reduce the amount of upload and cache spill.
12811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
12821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // assumption here is that sw bitmap size is a good proxy for its size as
12831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // a texture
12841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    size_t bmpSize = bitmap.getSize();
12851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    size_t cacheSize;
12861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fContext->getTextureCacheLimits(NULL, &cacheSize);
12871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (bmpSize < cacheSize / 2) {
12881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
12891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
12901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
12911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkFixed fracUsed =
12921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkFixedMul((srcRectPtr->width() << 16) / bitmap.width(),
12931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                   (srcRectPtr->height() << 16) / bitmap.height());
12941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (fracUsed <= SK_FixedHalf) {
12951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        *tileSize = determine_tile_size(bitmap, srcRectPtr, maxTextureSize);
12961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return true;
12971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
12981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
12991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
13001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
13011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
130205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid SkGpuDevice::drawBitmap(const SkDraw& draw,
130305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                             const SkBitmap& bitmap,
130405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                             const SkIRect* srcRectPtr,
130505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                             const SkMatrix& m,
130605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                             const SkPaint& paint) {
130705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    CHECK_SHOULD_DRAW(draw);
130805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
130905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkIRect srcRect;
131005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (NULL == srcRectPtr) {
131105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        srcRect.set(0, 0, bitmap.width(), bitmap.height());
131205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    } else {
131305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        srcRect = *srcRectPtr;
131405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
131505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
13161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (paint.getMaskFilter()){
13171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // Convert the bitmap to a shader so that the rect can be drawn
13181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // through drawRect, which supports mask filters.
13191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkBitmap        tmp;    // subset of bitmap, if necessary
13201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const SkBitmap* bitmapPtr = &bitmap;
13211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (srcRectPtr) {
13221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (!bitmap.extractSubset(&tmp, srcRect)) {
13231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                return;     // extraction failed
13241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
13251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            bitmapPtr = &tmp;
13261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            srcRect.set(0,0, srcRect.width(), srcRect.height());
13271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
13281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPaint paintWithTexture(paint);
13291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        paintWithTexture.setShader(SkShader::CreateBitmapShader( *bitmapPtr,
13301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            SkShader::kClamp_TileMode, SkShader::kClamp_TileMode))->unref();
13311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkRect ScalarRect;
13321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        ScalarRect.set(srcRect);
13331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
13341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // Transform 'm' needs to be concatenated to the draw matrix,
13354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        // rather than transforming the primitive directly, so that 'm' will
13361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // also affect the behavior of the mask filter.
13371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkMatrix drawMatrix;
13381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawMatrix.setConcat(*draw.fMatrix, m);
13391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkDraw transformedDraw(draw);
13401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        transformedDraw.fMatrix = &drawMatrix;
13411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
13421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        this->drawRect(transformedDraw, ScalarRect, paintWithTexture);
13431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
13441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return;
13451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
13461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
134705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrPaint grPaint;
13480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (!this->skPaint2GrPaintNoShader(paint, true, &grPaint, false)) {
134905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return;
135005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
13511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrSamplerState* sampler = grPaint.textureSampler(kBitmapTextureIdx);
135235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    if (paint.isFilterBitmap()) {
13530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        sampler->setFilter(GrSamplerState::kBilinear_Filter);
135435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    } else {
13550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        sampler->setFilter(GrSamplerState::kNearest_Filter);
135635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    }
135705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
13581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int tileSize;
13591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (!this->shouldTileBitmap(bitmap, *sampler, srcRectPtr, &tileSize)) {
13601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // take the simple case
136105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        this->internalDrawBitmap(draw, bitmap, srcRect, m, &grPaint);
136205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return;
136305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
136405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
136505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    // undo the translate done by SkCanvas
136605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    int DX = SkMax32(0, srcRect.fLeft);
136705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    int DY = SkMax32(0, srcRect.fTop);
136805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    // compute clip bounds in local coordinates
136905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkIRect clipRect;
137005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    {
137105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        SkRect r;
137205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        r.set(draw.fClip->getBounds());
137305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        SkMatrix matrix, inverse;
137405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        matrix.setConcat(*draw.fMatrix, m);
137505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        if (!matrix.invert(&inverse)) {
137605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            return;
137705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        }
137805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        inverse.mapRect(&r);
137905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        r.roundOut(&clipRect);
138005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        // apply the canvas' translate to our local clip
138105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        clipRect.offset(DX, DY);
138205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
138305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
13841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int nx = bitmap.width() / tileSize;
13851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int ny = bitmap.height() / tileSize;
138605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    for (int x = 0; x <= nx; x++) {
138705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        for (int y = 0; y <= ny; y++) {
138805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            SkIRect tileR;
13891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            tileR.set(x * tileSize, y * tileSize,
13901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                      (x + 1) * tileSize, (y + 1) * tileSize);
139105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            if (!SkIRect::Intersects(tileR, clipRect)) {
139205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                continue;
139305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            }
139405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
139505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            SkIRect srcR = tileR;
139605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            if (!srcR.intersect(srcRect)) {
139705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                continue;
139805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            }
139905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
140005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            SkBitmap tmpB;
140105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            if (bitmap.extractSubset(&tmpB, tileR)) {
140205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                // now offset it to make it "local" to our tmp bitmap
140305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                srcR.offset(-tileR.fLeft, -tileR.fTop);
140405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
140505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                SkMatrix tmpM(m);
140605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                {
140705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                    int dx = tileR.fLeft - DX + SkMax32(0, srcR.fLeft);
140805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                    int dy = tileR.fTop -  DY + SkMax32(0, srcR.fTop);
140905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                    tmpM.preTranslate(SkIntToScalar(dx), SkIntToScalar(dy));
141005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                }
141105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                this->internalDrawBitmap(draw, tmpB, srcR, tmpM, &grPaint);
141205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            }
141305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        }
141405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
141505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
141605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
141705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger/*
141805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger *  This is called by drawBitmap(), which has to handle images that may be too
141905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger *  large to be represented by a single texture.
142005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger *
142105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger *  internalDrawBitmap assumes that the specified bitmap will fit in a texture
142205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger *  and that non-texture portion of the GrPaint has already been setup.
142305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger */
142405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid SkGpuDevice::internalDrawBitmap(const SkDraw& draw,
142505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                     const SkBitmap& bitmap,
142605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                     const SkIRect& srcRect,
142705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                     const SkMatrix& m,
142805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                     GrPaint* grPaint) {
14291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkASSERT(bitmap.width() <= fContext->getMaxTextureSize() &&
14301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger             bitmap.height() <= fContext->getMaxTextureSize());
143105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
14321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkAutoLockPixels alp(bitmap, !bitmap.getTexture());
143305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (!bitmap.getTexture() && !bitmap.readyToDraw()) {
14341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkDebugf("nothing to draw\n");
143505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return;
143605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
143705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
14381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrSamplerState* sampler = grPaint->textureSampler(kBitmapTextureIdx);
14390b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
14400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    sampler->setWrapX(GrSamplerState::kClamp_WrapMode);
14410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    sampler->setWrapY(GrSamplerState::kClamp_WrapMode);
14420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    sampler->setSampleMode(GrSamplerState::kNormal_SampleMode);
14431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    sampler->matrix()->reset();
144405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
144505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrTexture* texture;
14461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkAutoCachedTexture act(this, bitmap, sampler, &texture);
144705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (NULL == texture) {
144805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return;
144905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
145005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
14511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    grPaint->setTexture(kBitmapTextureIdx, texture);
145205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
145335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    GrRect dstRect = SkRect::MakeWH(GrIntToScalar(srcRect.width()),
145435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger                                    GrIntToScalar(srcRect.height()));
145505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrRect paintRect;
14560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    paintRect.setLTRB(GrFixedToScalar((srcRect.fLeft << 16) / bitmap.width()),
14570b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                      GrFixedToScalar((srcRect.fTop << 16) / bitmap.height()),
14580b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                      GrFixedToScalar((srcRect.fRight << 16) / bitmap.width()),
145905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                      GrFixedToScalar((srcRect.fBottom << 16) / bitmap.height()));
146005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
14610b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (GrSamplerState::kNearest_Filter != sampler->getFilter() &&
14624f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        (srcRect.width() < bitmap.width() ||
14630b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger         srcRect.height() < bitmap.height())) {
14640b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        // If drawing a subrect of the bitmap and filtering is enabled,
14650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        // use a constrained texture domain to avoid color bleeding
14660b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        GrScalar left, top, right, bottom;
14670b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (srcRect.width() > 1) {
14680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            GrScalar border = GR_ScalarHalf / bitmap.width();
14690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            left = paintRect.left() + border;
14700b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            right = paintRect.right() - border;
14710b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        } else {
14720b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            left = right = GrScalarHalf(paintRect.left() + paintRect.right());
14730b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
14740b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (srcRect.height() > 1) {
14750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            GrScalar border = GR_ScalarHalf / bitmap.height();
14760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            top = paintRect.top() + border;
14770b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            bottom = paintRect.bottom() - border;
14780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        } else {
14790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            top = bottom = GrScalarHalf(paintRect.top() + paintRect.bottom());
14800b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
14810b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        GrRect textureDomain;
14820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        textureDomain.setLTRB(left, top, right, bottom);
14830b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        sampler->setTextureDomain(textureDomain);
14840b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
14850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
148635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    fContext->drawRectToRect(*grPaint, dstRect, paintRect, &m);
148705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
148805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
148905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
149005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                            int left, int top, const SkPaint& paint) {
149105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    CHECK_SHOULD_DRAW(draw);
149205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
149305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkAutoLockPixels alp(bitmap);
149405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (!bitmap.getTexture() && !bitmap.readyToDraw()) {
149505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return;
149605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
149705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
14981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int w = bitmap.width();
14991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int h = bitmap.height();
15001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
150105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrPaint grPaint;
15020b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if(!this->skPaint2GrPaintNoShader(paint, true, &grPaint, false)) {
150305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return;
150405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
150505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
150605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrAutoMatrix avm(fContext, GrMatrix::I());
150705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
15081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrSamplerState* sampler = grPaint.textureSampler(kBitmapTextureIdx);
15090b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
151005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrTexture* texture;
15111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    sampler->reset();
15121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkAutoCachedTexture act(this, bitmap, sampler, &texture);
15131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
15141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkImageFilter* imageFilter = paint.getImageFilter();
15151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkSize blurSize;
15164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    SkISize radius;
15171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL != imageFilter && imageFilter->asABlur(&blurSize)) {
15181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrAutoScratchTexture temp1, temp2;
15191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrTexture* blurTexture = gaussianBlur(fContext,
15201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                              texture, &temp1, &temp2,
15211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                              GrRect::MakeWH(w, h),
15221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                              blurSize.width(),
15231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                              blurSize.height());
15241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        texture = blurTexture;
15251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        grPaint.setTexture(kBitmapTextureIdx, texture);
15264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    } else if (NULL != imageFilter && imageFilter->asADilate(&radius)) {
15274f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        const GrTextureDesc desc = {
15284f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            kRenderTarget_GrTextureFlagBit,
15294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            w,
15304f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            h,
15314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            kRGBA_8888_PM_GrPixelConfig,
15324f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            {0} // samples
15334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        };
15344f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        GrAutoScratchTexture temp1(fContext, desc), temp2(fContext, desc);
15354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        texture = applyMorphology(fContext, texture, GrRect::MakeWH(w, h),
15364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                  temp1.texture(), temp2.texture(),
15374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                  GrSamplerState::kDilate_Filter, radius);
15384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        grPaint.setTexture(kBitmapTextureIdx, texture);
15394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    } else if (NULL != imageFilter && imageFilter->asAnErode(&radius)) {
15404f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        const GrTextureDesc desc = {
15414f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            kRenderTarget_GrTextureFlagBit,
15424f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            w,
15434f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            h,
15444f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            kRGBA_8888_PM_GrPixelConfig,
15454f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            {0} // samples
15464f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        };
15474f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        GrAutoScratchTexture temp1(fContext, desc), temp2(fContext, desc);
15484f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        texture = applyMorphology(fContext, texture, GrRect::MakeWH(w, h),
15494f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                  temp1.texture(), temp2.texture(),
15504f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                  GrSamplerState::kErode_Filter, radius);
15514f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        grPaint.setTexture(kBitmapTextureIdx, texture);
15521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
15531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        grPaint.setTexture(kBitmapTextureIdx, texture);
15541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
155505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
155605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fContext->drawRectToRect(grPaint,
15571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            GrRect::MakeXYWH(GrIntToScalar(left),
15581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            GrIntToScalar(top),
15591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            GrIntToScalar(w),
15601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            GrIntToScalar(h)),
15611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            GrRect::MakeWH(GR_Scalar1 * w / texture->width(),
15621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                        GR_Scalar1 * h / texture->height()));
156305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
156405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
156505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* dev,
156605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                            int x, int y, const SkPaint& paint) {
156705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    CHECK_SHOULD_DRAW(draw);
156805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
156905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrPaint grPaint;
157005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (!((SkGpuDevice*)dev)->bindDeviceAsTexture(&grPaint) ||
15710b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        !this->skPaint2GrPaintNoShader(paint, true, &grPaint, false)) {
157205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return;
157305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
157405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
15751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrTexture* devTex = grPaint.getTexture(0);
15761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkASSERT(NULL != devTex);
157705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
157805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    const SkBitmap& bm = dev->accessBitmap(false);
157905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    int w = bm.width();
158005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    int h = bm.height();
158105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
158205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrAutoMatrix avm(fContext, GrMatrix::I());
158305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
15841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    grPaint.textureSampler(kBitmapTextureIdx)->reset();
158505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
15861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrRect dstRect = GrRect::MakeXYWH(GrIntToScalar(x),
15871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                      GrIntToScalar(y),
15881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                      GrIntToScalar(w),
15891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                      GrIntToScalar(h));
15901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
15911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // The device being drawn may not fill up its texture (saveLayer uses
15921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // the approximate ).
15931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrRect srcRect = GrRect::MakeWH(GR_Scalar1 * w / devTex->width(),
15941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                    GR_Scalar1 * h / devTex->height());
15951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
15961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fContext->drawRectToRect(grPaint, dstRect, srcRect);
15971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
15981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
15991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkGpuDevice::filterImage(SkImageFilter* filter, const SkBitmap& src,
16001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                              const SkMatrix& ctm,
16011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                              SkBitmap* result, SkIPoint* offset) {
16021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkSize size;
16034f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    SkISize radius;
16044f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (!filter->asABlur(&size) && !filter->asADilate(&radius) && !filter->asAnErode(&radius)) {
16051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
16061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
16071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkDevice* dev = this->createCompatibleDevice(SkBitmap::kARGB_8888_Config,
16081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                 src.width(),
16091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                 src.height(),
16101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                 false);
16111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL == dev) {
16121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
16131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
16141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkAutoUnref aur(dev);
16151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkCanvas canvas(dev);
16161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPaint paint;
16171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    paint.setImageFilter(filter);
16181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    canvas.drawSprite(src, 0, 0, &paint);
16191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    *result = dev->accessBitmap(false);
16201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return true;
162105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
162205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
162305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
162405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
162505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger// must be in SkCanvas::VertexMode order
162605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerstatic const GrPrimitiveType gVertexMode2PrimitiveType[] = {
162705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    kTriangles_PrimitiveType,
162805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    kTriangleStrip_PrimitiveType,
162905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    kTriangleFan_PrimitiveType,
163005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger};
163105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
163205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
163305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                              int vertexCount, const SkPoint vertices[],
163405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                              const SkPoint texs[], const SkColor colors[],
163505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                              SkXfermode* xmode,
163605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                              const uint16_t indices[], int indexCount,
163705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                              const SkPaint& paint) {
163805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    CHECK_SHOULD_DRAW(draw);
163905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
164005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrPaint grPaint;
164105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkAutoCachedTexture act;
164205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    // we ignore the shader if texs is null.
164305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (NULL == texs) {
16440b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (!this->skPaint2GrPaintNoShader(paint,
16450b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                           false,
16464f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                           &grPaint,
16470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                           NULL == colors)) {
164805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            return;
164905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        }
165005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    } else {
165105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        if (!this->skPaint2GrPaintShader(paint, &act,
165205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                         *draw.fMatrix,
16530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                         &grPaint,
16540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                         NULL == colors)) {
165505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            return;
165605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        }
165705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
165805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
165905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (NULL != xmode && NULL != texs && NULL != colors) {
16601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (!SkXfermode::IsMode(xmode, SkXfermode::kMultiply_Mode)) {
166105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            SkDebugf("Unsupported vertex-color/texture xfer mode.\n");
166205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#if 0
166305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            return
166405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#endif
166505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        }
166605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
166705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
16681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkAutoSTMalloc<128, GrColor> convertedColors(0);
16691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL != colors) {
16701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // need to convert byte order and from non-PM to PM
16711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        convertedColors.reset(vertexCount);
16721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        for (int i = 0; i < vertexCount; ++i) {
16731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            convertedColors[i] = SkGr::SkColor2GrColor(colors[i]);
16741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
16751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        colors = convertedColors.get();
167605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
16771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fContext->drawVertices(grPaint,
16781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                           gVertexMode2PrimitiveType[vmode],
16791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                           vertexCount,
16801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                           (GrPoint*) vertices,
16811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                           (GrPoint*) texs,
16821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                           colors,
16831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                           indices,
16841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                           indexCount);
168505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
168605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
168705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
168805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
168905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerstatic void GlyphCacheAuxProc(void* data) {
169005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    delete (GrFontScaler*)data;
169105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
169205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
169305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerstatic GrFontScaler* get_gr_font_scaler(SkGlyphCache* cache) {
169405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    void* auxData;
169505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrFontScaler* scaler = NULL;
169605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (cache->getAuxProcData(GlyphCacheAuxProc, &auxData)) {
169705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        scaler = (GrFontScaler*)auxData;
169805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
169905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (NULL == scaler) {
170005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        scaler = new SkGrFontScaler(cache);
170105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        cache->setAuxProc(GlyphCacheAuxProc, scaler);
170205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
170305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    return scaler;
170405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
170505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
170605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerstatic void SkGPU_Draw1Glyph(const SkDraw1Glyph& state,
170705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                             SkFixed fx, SkFixed fy,
170805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                             const SkGlyph& glyph) {
170905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkASSERT(glyph.fWidth > 0 && glyph.fHeight > 0);
171005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
17111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrSkDrawProcs* procs = static_cast<GrSkDrawProcs*>(state.fDraw->fProcs);
171205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
171305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (NULL == procs->fFontScaler) {
171405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        procs->fFontScaler = get_gr_font_scaler(state.fCache);
171505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
171687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
17171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    procs->fTextContext->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(),
17181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                       glyph.getSubXFixed(),
17191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                       glyph.getSubYFixed()),
17201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                         SkFixedFloorToFixed(fx),
17211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                         SkFixedFloorToFixed(fy),
172205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                         procs->fFontScaler);
172305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
172405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
172505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek SollenbergerSkDrawProcs* SkGpuDevice::initDrawForText(GrTextContext* context) {
172605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
172705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    // deferred allocation
172805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (NULL == fDrawProcs) {
172905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        fDrawProcs = new GrSkDrawProcs;
173005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        fDrawProcs->fD1GProc = SkGPU_Draw1Glyph;
173105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        fDrawProcs->fContext = fContext;
173205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
173305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
173405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    // init our (and GL's) state
173505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fDrawProcs->fTextContext = context;
173605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fDrawProcs->fFontScaler = NULL;
173705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    return fDrawProcs;
173805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
173905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
174005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid SkGpuDevice::drawText(const SkDraw& draw, const void* text,
174105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                          size_t byteLength, SkScalar x, SkScalar y,
174205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                          const SkPaint& paint) {
174305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    CHECK_SHOULD_DRAW(draw);
174405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
17451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (draw.fMatrix->hasPerspective()) {
174605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        // this guy will just call our drawPath()
174705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        draw.drawText((const char*)text, byteLength, x, y, paint);
174805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    } else {
174905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        SkDraw myDraw(draw);
175005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
175105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        GrPaint grPaint;
175205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        SkAutoCachedTexture act;
175305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
17540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (!this->skPaint2GrPaintShader(paint,
17550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                         &act,
17560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                         *draw.fMatrix,
17570b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                         &grPaint,
17580b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                         true)) {
175905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            return;
176005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        }
176135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        GrTextContext context(fContext, grPaint, draw.fExtMatrix);
176205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        myDraw.fProcs = this->initDrawForText(&context);
176305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        this->INHERITED::drawText(myDraw, text, byteLength, x, y, paint);
176405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
176505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
176605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
176705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid SkGpuDevice::drawPosText(const SkDraw& draw, const void* text,
176805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                             size_t byteLength, const SkScalar pos[],
176905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                             SkScalar constY, int scalarsPerPos,
177005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                             const SkPaint& paint) {
177105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    CHECK_SHOULD_DRAW(draw);
177205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
17731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (draw.fMatrix->hasPerspective()) {
177405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        // this guy will just call our drawPath()
177505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        draw.drawPosText((const char*)text, byteLength, pos, constY,
177605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                         scalarsPerPos, paint);
177705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    } else {
177805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        SkDraw myDraw(draw);
177905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
178005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        GrPaint grPaint;
178105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        SkAutoCachedTexture act;
17820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (!this->skPaint2GrPaintShader(paint,
17830b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                         &act,
17840b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                         *draw.fMatrix,
17850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                         &grPaint,
17860b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                         true)) {
178705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            return;
178805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        }
178905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
179035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        GrTextContext context(fContext, grPaint, draw.fExtMatrix);
179105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        myDraw.fProcs = this->initDrawForText(&context);
179205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        this->INHERITED::drawPosText(myDraw, text, byteLength, pos, constY,
179305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                     scalarsPerPos, paint);
179405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
179505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
179605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
179705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergervoid SkGpuDevice::drawTextOnPath(const SkDraw& draw, const void* text,
179805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                size_t len, const SkPath& path,
179905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                const SkMatrix* m, const SkPaint& paint) {
180005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    CHECK_SHOULD_DRAW(draw);
180105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
180205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkASSERT(draw.fDevice == this);
180305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    draw.drawTextOnPath((const char*)text, len, path, m, paint);
180405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
180505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
180605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
180705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
1808137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenbergerbool SkGpuDevice::filterTextFlags(const SkPaint& paint, TextFlags* flags) {
1809137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger    if (!paint.isLCDRenderText()) {
1810137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger        // we're cool with the paint as is
1811137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger        return false;
1812137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger    }
1813137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger
1814137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger    if (paint.getShader() ||
1815137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger        paint.getXfermode() || // unless its srcover
1816137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger        paint.getMaskFilter() ||
1817137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger        paint.getRasterizer() ||
1818137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger        paint.getColorFilter() ||
1819137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger        paint.getPathEffect() ||
1820137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger        paint.isFakeBoldText() ||
1821137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger        paint.getStyle() != SkPaint::kFill_Style) {
1822137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger        // turn off lcd
1823137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger        flags->fFlags = paint.getFlags() & ~SkPaint::kLCDRenderText_Flag;
1824137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger        flags->fHinting = paint.getHinting();
1825137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger        return true;
1826137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger    }
1827137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger    // we're cool with the paint as is
1828137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger    return false;
1829137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger}
1830137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger
18311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkGpuDevice::flush() {
18324f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    fContext->resolveRenderTarget(fRenderTarget);
18331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
18341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1835137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
1836137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger
18371cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkGpuDevice::TexCache SkGpuDevice::lockCachedTexture(const SkBitmap& bitmap,
18381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            const GrSamplerState* sampler,
18391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            TexType type) {
18401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrContext::TextureCacheEntry entry;
184105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrContext* ctx = this->context();
184235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
18431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (kBitmap_TexType != type) {
184435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        const GrTextureDesc desc = {
184535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            kRenderTarget_GrTextureFlagBit,
184635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            bitmap.width(),
184735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            bitmap.height(),
18484f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            SkGr::Bitmap2PixelConfig(bitmap),
18494f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            {0} // samples
185035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        };
18511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrContext::ScratchTexMatch match;
18521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (kSaveLayerDeviceRenderTarget_TexType == type) {
18531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // we know layers will only be drawn through drawDevice.
18541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // drawDevice has been made to work with content embedded in a
18551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // larger texture so its okay to use the approximate version.
18561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            match = GrContext::kApprox_ScratchTexMatch;
18571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else {
18581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            SkASSERT(kDeviceRenderTarget_TexType == type);
18591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            match = GrContext::kExact_ScratchTexMatch;
18601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
18611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        entry = ctx->lockScratchTexture(desc, match);
186205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    } else {
18631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (!bitmap.isVolatile()) {
18641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrContext::TextureKey key = bitmap.getGenerationID();
18651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            key |= ((uint64_t) bitmap.pixelRefOffset()) << 32;
18664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
18671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            entry = ctx->findAndLockTexture(key, bitmap.width(),
18681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            bitmap.height(), sampler);
18691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (NULL == entry.texture()) {
18701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                entry = sk_gr_create_bitmap_texture(ctx, key, sampler,
18711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                    bitmap);
187235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            }
18731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else {
18741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            entry = sk_gr_create_bitmap_texture(ctx, gUNCACHED_KEY,
18751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                sampler, bitmap);
187605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        }
18771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (NULL == entry.texture()) {
18781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrPrintf("---- failed to create texture for cache [%d %d]\n",
18791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                     bitmap.width(), bitmap.height());
188005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        }
188105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
18821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return entry;
188305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
188405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
18851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkGpuDevice::unlockCachedTexture(TexCache cache) {
18861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->context()->unlockTexture(cache);
188705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
188805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
18891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkGpuDevice::isBitmapInTextureCache(const SkBitmap& bitmap,
18901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                         const GrSamplerState& sampler) const {
18911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrContext::TextureKey key = bitmap.getGenerationID();
18921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    key |= ((uint64_t) bitmap.pixelRefOffset()) << 32;
18931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return this->context()->isTextureInCache(key, bitmap.width(),
18941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                             bitmap.height(), &sampler);
189505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
189687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger}
189787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
189887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
18994f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerSkDevice* SkGpuDevice::onCreateCompatibleDevice(SkBitmap::Config config,
19004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                                int width, int height,
19011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                bool isOpaque,
19021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                Usage usage) {
19034f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    return SkNEW_ARGS(SkGpuDevice,(this->context(), config,
19041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                   width, height, usage));
190505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
190605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
1907