111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com/*
211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com * Copyright 2011 Google Inc.
311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com *
411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com * Use of this source code is governed by a BSD-style license that can be
511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com * found in the LICENSE file.
611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com */
711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkGpuDevice.h"
911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
10dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org#include "effects/GrBicubicEffect.h"
11628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org#include "effects/GrDashingEffect.h"
12907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#include "effects/GrTextureDomain.h"
1311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "effects/GrSimpleTextureEffect.h"
1411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "GrContext.h"
1611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "GrBitmapTextContext.h"
1711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "GrDistanceFieldTextContext.h"
18e930a075625d3d90c023c2570a6a4cae1a4b484frobertphillips@google.com#include "GrLayerCache.h"
1998d709bc8d0761df8e0ad35e92c06e500f0be50drobertphillips#include "GrLayerHoister.h"
208ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org#include "GrPictureUtils.h"
21274b4ba6bde67bb8b6d8f1721ef5d6d4294f2aa8robertphillips#include "GrRecordReplaceDraw.h"
22d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel#include "GrStrokeInfo.h"
23bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel#include "GrTracing.h"
2411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
2511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkGrTexturePixelRef.h"
2611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
2711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkDeviceImageFilterProxy.h"
2811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkDrawProcs.h"
2911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkGlyphCache.h"
3011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkImageFilter.h"
31821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org#include "SkMaskFilter.h"
3211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkPathEffect.h"
33145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org#include "SkPicture.h"
34db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips#include "SkPictureData.h"
35274b4ba6bde67bb8b6d8f1721ef5d6d4294f2aa8robertphillips#include "SkRecord.h"
3611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkRRect.h"
3711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkStroke.h"
3876f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com#include "SkSurface.h"
39a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org#include "SkTLazy.h"
4011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkUtils.h"
41559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org#include "SkVertState.h"
42320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips#include "SkXfermode.h"
4311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkErrorInternals.h"
4411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
4555b6d8be997a447ef9ce0f029697677a940bfc24senorblancoenum { kDefaultImageFilterCacheSize = 32 * 1024 * 1024 };
4655b6d8be997a447ef9ce0f029697677a940bfc24senorblanco
4711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#define CACHE_COMPATIBLE_DEVICE_TEXTURES 1
4811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
4911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#if 0
5011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    extern bool (*gShouldDrawProc)();
5111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    #define CHECK_SHOULD_DRAW(draw, forceI)                     \
5211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        do {                                                    \
5311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            if (gShouldDrawProc && !gShouldDrawProc()) return;  \
5411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            this->prepareDraw(draw, forceI);                    \
5511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        } while (0)
5611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#else
5711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    #define CHECK_SHOULD_DRAW(draw, forceI) this->prepareDraw(draw, forceI)
5811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#endif
5911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
6011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// This constant represents the screen alignment criterion in texels for
6111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// requiring texture domain clamping to prevent color bleeding when drawing
6211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// a sub region of a larger source image.
634b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org#define COLOR_BLEED_TOLERANCE 0.001f
6411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
6511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#define DO_DEFERRED_CLEAR()             \
6611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    do {                                \
6711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (fNeedClear) {               \
6811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            this->clear(SK_ColorTRANSPARENT); \
6911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }                               \
7011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } while (false)                     \
7111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
7211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
7311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
7411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#define CHECK_FOR_ANNOTATION(paint) \
7511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    do { if (paint.getAnnotation()) { return; } } while (0)
7611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
7711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
7811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
7911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
8011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comclass SkGpuDevice::SkAutoCachedTexture : public ::SkNoncopyable {
8111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.compublic:
8211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoCachedTexture()
8311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        : fDevice(NULL)
8411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        , fTexture(NULL) {
8511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
8611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
8711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoCachedTexture(SkGpuDevice* device,
8811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                        const SkBitmap& bitmap,
8911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                        const GrTextureParams* params,
9011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                        GrTexture** texture)
9111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        : fDevice(NULL)
9211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        , fTexture(NULL) {
9349f085dddff10473b6ebf832a974288300224e60bsalomon        SkASSERT(texture);
9411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        *texture = this->set(device, bitmap, params);
9511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
9611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
9711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    ~SkAutoCachedTexture() {
9849f085dddff10473b6ebf832a974288300224e60bsalomon        if (fTexture) {
9911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            GrUnlockAndUnrefCachedBitmapTexture(fTexture);
10011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
10111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
10211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
10311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTexture* set(SkGpuDevice* device,
10411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                   const SkBitmap& bitmap,
10511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                   const GrTextureParams* params) {
10649f085dddff10473b6ebf832a974288300224e60bsalomon        if (fTexture) {
10711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            GrUnlockAndUnrefCachedBitmapTexture(fTexture);
10811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            fTexture = NULL;
10911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
11011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        fDevice = device;
11111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        GrTexture* result = (GrTexture*)bitmap.getTexture();
11211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (NULL == result) {
11311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            // Cannot return the native texture so look it up in our cache
11411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            fTexture = GrLockAndRefCachedBitmapTexture(device->context(), bitmap, params);
11511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            result = fTexture;
11611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
11711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return result;
11811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
11911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
12011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comprivate:
12111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkGpuDevice* fDevice;
12211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTexture*   fTexture;
12311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com};
12411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
12511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
12611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
12711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comstruct GrSkDrawProcs : public SkDrawProcs {
12811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.compublic:
12911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrContext* fContext;
13011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTextContext* fTextContext;
13111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrFontScaler* fFontScaler;  // cached in the skia glyphcache
13211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com};
13311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
13411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
13511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1364a8126e7f81384526629b1e21bf89b632ea13cd9reedSkGpuDevice* SkGpuDevice::Create(GrSurface* surface, const SkSurfaceProps& props, unsigned flags) {
13749f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(surface);
13832d0b3b5463c11032f12d03d993f11ea0af05959bsalomon    if (NULL == surface->asRenderTarget() || surface->wasDestroyed()) {
13911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return NULL;
14011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
1414a8126e7f81384526629b1e21bf89b632ea13cd9reed    return SkNEW_ARGS(SkGpuDevice, (surface, props, flags));
14211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
14311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1444a8126e7f81384526629b1e21bf89b632ea13cd9reedSkGpuDevice::SkGpuDevice(GrSurface* surface, const SkSurfaceProps& props, unsigned flags) {
14511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
14611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fDrawProcs = NULL;
14711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
14832d0b3b5463c11032f12d03d993f11ea0af05959bsalomon    fContext = SkRef(surface->getContext());
14911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
150d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org    fNeedClear = flags & kNeedClear_Flag;
15111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
15232d0b3b5463c11032f12d03d993f11ea0af05959bsalomon    fRenderTarget = SkRef(surface->asRenderTarget());
15311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1546c22573edb234ad14df947278cfed010669a39a7reed    SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef,
1556c22573edb234ad14df947278cfed010669a39a7reed                                (surface->info(), surface, SkToBool(flags & kCached_Flag)));
15689443aba5bfa2b040dc9fd24938b7d0b3decd737reed    fLegacyBitmap.setInfo(surface->info());
15789443aba5bfa2b040dc9fd24938b7d0b3decd737reed    fLegacyBitmap.setPixelRef(pr)->unref();
158c6cb56f36c4aad8ed45486a3bb4de614bb822f1bkkinnunen
1594a8126e7f81384526629b1e21bf89b632ea13cd9reed    this->setPixelGeometry(props.pixelGeometry());
1604a8126e7f81384526629b1e21bf89b632ea13cd9reed
161c6cb56f36c4aad8ed45486a3bb4de614bb822f1bkkinnunen    bool useDFFonts = !!(flags & kDFFonts_Flag);
162e010f1c2a0e6fe9cbaa73be01c7d878308b5166creed    fMainTextContext = fContext->createTextContext(fRenderTarget, this->getLeakyProperties(), useDFFonts);
163e010f1c2a0e6fe9cbaa73be01c7d878308b5166creed    fFallbackTextContext = SkNEW_ARGS(GrBitmapTextContext, (fContext, this->getLeakyProperties()));
16411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
16511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
16615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.orgSkGpuDevice* SkGpuDevice::Create(GrContext* context, const SkImageInfo& origInfo,
1674a8126e7f81384526629b1e21bf89b632ea13cd9reed                                 const SkSurfaceProps& props, int sampleCount) {
16815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    if (kUnknown_SkColorType == origInfo.colorType() ||
16915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        origInfo.width() < 0 || origInfo.height() < 0) {
17015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        return NULL;
17115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    }
17215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org
173e5ea500d4714a7d84de2bf913e81be3b65d2de68reed    SkColorType ct = origInfo.colorType();
174e5ea500d4714a7d84de2bf913e81be3b65d2de68reed    SkAlphaType at = origInfo.alphaType();
175a0537deca24abc2713e72f61e9cec14bdcc703d0robertphillips    // TODO: perhaps we can loosen this check now that colortype is more detailed
17615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    // e.g. can we support both RGBA and BGRA here?
177e5ea500d4714a7d84de2bf913e81be3b65d2de68reed    if (kRGB_565_SkColorType == ct) {
178e5ea500d4714a7d84de2bf913e81be3b65d2de68reed        at = kOpaque_SkAlphaType;  // force this setting
17915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    } else {
180e5ea500d4714a7d84de2bf913e81be3b65d2de68reed        ct = kN32_SkColorType;
181e5ea500d4714a7d84de2bf913e81be3b65d2de68reed        if (kOpaque_SkAlphaType != at) {
182e5ea500d4714a7d84de2bf913e81be3b65d2de68reed            at = kPremul_SkAlphaType;  // force this setting
18315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        }
18415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    }
185e5ea500d4714a7d84de2bf913e81be3b65d2de68reed    const SkImageInfo info = SkImageInfo::Make(origInfo.width(), origInfo.height(), ct, at);
18615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org
18715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    GrTextureDesc desc;
18815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    desc.fFlags = kRenderTarget_GrTextureFlagBit;
18915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    desc.fWidth = info.width();
19015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    desc.fHeight = info.height();
1913adcc3403377c0b9a7afde6db8e0432325413a10commit-bot@chromium.org    desc.fConfig = SkImageInfo2GrPixelConfig(info);
19215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    desc.fSampleCnt = sampleCount;
19315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org
19415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    SkAutoTUnref<GrTexture> texture(context->createUncachedTexture(desc, NULL, 0));
19515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    if (!texture.get()) {
19615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        return NULL;
19715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    }
198969588f0c9030d5a4942085a4b5a5ea7e8d2bc25skia.committer@gmail.com
1994a8126e7f81384526629b1e21bf89b632ea13cd9reed    return SkNEW_ARGS(SkGpuDevice, (texture.get(), props));
20015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org}
20115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org
20211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comSkGpuDevice::~SkGpuDevice() {
20311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (fDrawProcs) {
20411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        delete fDrawProcs;
20511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
206d2ac07b64b7d46e81d00d389781f9f83810f0095skia.committer@gmail.com
207cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    delete fMainTextContext;
208cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    delete fFallbackTextContext;
20911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
21011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // The GrContext takes a ref on the target. We don't want to cause the render
21111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // target to be unnecessarily kept alive.
21211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (fContext->getRenderTarget() == fRenderTarget) {
21311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        fContext->setRenderTarget(NULL);
21411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
21511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
21611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (fContext->getClip() == &fClipData) {
21711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        fContext->setClip(NULL);
21811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
21911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
22032d0b3b5463c11032f12d03d993f11ea0af05959bsalomon    fRenderTarget->unref();
22111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext->unref();
22211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
22311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
22411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
22511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
226a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.orgbool SkGpuDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
227a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org                               int x, int y) {
228a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    DO_DEFERRED_CLEAR();
229a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org
230a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    // TODO: teach fRenderTarget to take ImageInfo directly to specify the src pixels
2313adcc3403377c0b9a7afde6db8e0432325413a10commit-bot@chromium.org    GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo);
232a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    if (kUnknown_GrPixelConfig == config) {
233a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org        return false;
234a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    }
235a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org
236a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    uint32_t flags = 0;
237a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    if (kUnpremul_SkAlphaType == dstInfo.alphaType()) {
238a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org        flags = GrContext::kUnpremul_PixelOpsFlag;
239a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    }
240a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    return fContext->readRenderTargetPixels(fRenderTarget, x, y, dstInfo.width(), dstInfo.height(),
241a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org                                            config, dstPixels, dstRowBytes, flags);
242a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org}
24311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
2444cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkGpuDevice::onWritePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes,
2454cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org                                int x, int y) {
2464cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    // TODO: teach fRenderTarget to take ImageInfo directly to specify the src pixels
2473adcc3403377c0b9a7afde6db8e0432325413a10commit-bot@chromium.org    GrPixelConfig config = SkImageInfo2GrPixelConfig(info);
2484cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    if (kUnknown_GrPixelConfig == config) {
2494cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org        return false;
2504cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    }
2514cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    uint32_t flags = 0;
2524cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    if (kUnpremul_SkAlphaType == info.alphaType()) {
2534cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org        flags = GrContext::kUnpremul_PixelOpsFlag;
2544cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    }
2554cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    fRenderTarget->writePixels(x, y, info.width(), info.height(), config, pixels, rowBytes, flags);
2564cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org
2574cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    // need to bump our genID for compatibility with clients that "know" we have a bitmap
25889443aba5bfa2b040dc9fd24938b7d0b3decd737reed    fLegacyBitmap.notifyPixelsChanged();
2594cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org
2604cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    return true;
2614cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org}
26211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
263b7b7eb32f41729c136c939702b0c9a484accb541senorblanco@chromium.orgconst SkBitmap& SkGpuDevice::onAccessBitmap() {
264b7b7eb32f41729c136c939702b0c9a484accb541senorblanco@chromium.org    DO_DEFERRED_CLEAR();
26589443aba5bfa2b040dc9fd24938b7d0b3decd737reed    return fLegacyBitmap;
266b7b7eb32f41729c136c939702b0c9a484accb541senorblanco@chromium.org}
267b7b7eb32f41729c136c939702b0c9a484accb541senorblanco@chromium.org
26811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::onAttachToCanvas(SkCanvas* canvas) {
26911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    INHERITED::onAttachToCanvas(canvas);
27011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
27111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // Canvas promises that this ptr is valid until onDetachFromCanvas is called
27211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fClipData.fClipStack = canvas->getClipStack();
27311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
27411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
27511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::onDetachFromCanvas() {
27611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    INHERITED::onDetachFromCanvas();
27711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fClipData.fClipStack = NULL;
27811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
27911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
28011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// call this every draw call, to ensure that the context reflects our state,
28111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// and not the state from some other canvas/device
28211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::prepareDraw(const SkDraw& draw, bool forceIdentity) {
28349f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(fClipData.fClipStack);
28411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
28511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext->setRenderTarget(fRenderTarget);
28611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
28711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkASSERT(draw.fClipStack && draw.fClipStack == fClipData.fClipStack);
28811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
28911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (forceIdentity) {
29011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        fContext->setIdentityMatrix();
29111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
29211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        fContext->setMatrix(*draw.fMatrix);
29311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
29411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fClipData.fOrigin = this->getOrigin();
29511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
29611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext->setClip(&fClipData);
29711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
29811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    DO_DEFERRED_CLEAR();
29911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
30011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
30111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comGrRenderTarget* SkGpuDevice::accessRenderTarget() {
30211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    DO_DEFERRED_CLEAR();
30311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    return fRenderTarget;
30411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
30511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
30611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
30711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
30811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comSK_COMPILE_ASSERT(SkShader::kNone_BitmapType == 0, shader_type_mismatch);
30911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comSK_COMPILE_ASSERT(SkShader::kDefault_BitmapType == 1, shader_type_mismatch);
31011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comSK_COMPILE_ASSERT(SkShader::kRadial_BitmapType == 2, shader_type_mismatch);
31111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comSK_COMPILE_ASSERT(SkShader::kSweep_BitmapType == 3, shader_type_mismatch);
31211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comSK_COMPILE_ASSERT(SkShader::kTwoPointRadial_BitmapType == 4,
31311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                  shader_type_mismatch);
31411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comSK_COMPILE_ASSERT(SkShader::kTwoPointConical_BitmapType == 5,
31511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                  shader_type_mismatch);
31611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comSK_COMPILE_ASSERT(SkShader::kLinear_BitmapType == 6, shader_type_mismatch);
31711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comSK_COMPILE_ASSERT(SkShader::kLast_BitmapType == 6, shader_type_mismatch);
31811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
31911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
32011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
32111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::clear(SkColor color) {
322d78a168ec2ec2c07c0c1845e6a1781988e4a52d9egdaniel    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::clear", fContext);
32311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkIRect rect = SkIRect::MakeWH(this->width(), this->height());
32411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext->clear(&rect, SkColor2GrColor(color), true, fRenderTarget);
32511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fNeedClear = false;
32611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
32711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
32811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
32911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_SHOULD_DRAW(draw, false);
330d78a168ec2ec2c07c0c1845e6a1781988e4a52d9egdaniel    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPaint", fContext);
33111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
33211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint grPaint;
3333595f88aff0a1b490aa6661f0ba2d3534ee86353commit-bot@chromium.org    SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
33411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
33511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext->drawPaint(grPaint);
33611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
33711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
33811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// must be in SkCanvas::PointMode order
33911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comstatic const GrPrimitiveType gPointMode2PrimtiveType[] = {
34011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    kPoints_GrPrimitiveType,
34111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    kLines_GrPrimitiveType,
34211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    kLineStrip_GrPrimitiveType
34311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com};
34411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
34511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
34611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                             size_t count, const SkPoint pts[], const SkPaint& paint) {
34711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_FOR_ANNOTATION(paint);
34811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_SHOULD_DRAW(draw, false);
34911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
35011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkScalar width = paint.getStrokeWidth();
35111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (width < 0) {
35211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
35311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
35411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
355628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org    if (paint.getPathEffect() && 2 == count && SkCanvas::kLines_PointMode == mode) {
356e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel        GrStrokeInfo strokeInfo(paint, SkPaint::kStroke_Style);
357e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel        GrPaint grPaint;
358e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel        SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
359e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel        SkPath path;
360e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel        path.moveTo(pts[0]);
361e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel        path.lineTo(pts[1]);
362e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel        fContext->drawPath(grPaint, path, strokeInfo);
363e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel        return;
364628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org    }
365628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org
36611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // we only handle hairlines and paints without path effects or mask filters,
36711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // else we let the SkDraw call our drawPath()
36811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (width > 0 || paint.getPathEffect() || paint.getMaskFilter()) {
36911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        draw.drawPoints(mode, count, pts, paint, true);
37011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
37111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
37211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
37311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint grPaint;
3743595f88aff0a1b490aa6661f0ba2d3534ee86353commit-bot@chromium.org    SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
37511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
37611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext->drawVertices(grPaint,
37711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           gPointMode2PrimtiveType[mode],
378a4662865e37a2ca95b5e3379072f6a274acc8ac8robertphillips@google.com                           SkToS32(count),
379972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org                           (SkPoint*)pts,
38011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           NULL,
38111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           NULL,
38211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           NULL,
38311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           0);
38411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
38511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
38611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
38711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
38811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect,
38911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           const SkPaint& paint) {
390bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawRect", fContext);
391bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel
39211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_FOR_ANNOTATION(paint);
39311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_SHOULD_DRAW(draw, false);
39411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
39511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    bool doStroke = paint.getStyle() != SkPaint::kFill_Style;
39611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkScalar width = paint.getStrokeWidth();
39711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
39811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    /*
39911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        We have special code for hairline strokes, miter-strokes, bevel-stroke
40011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        and fills. Anything else we just call our path code.
40111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com     */
40211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    bool usePath = doStroke && width > 0 &&
40311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                   (paint.getStrokeJoin() == SkPaint::kRound_Join ||
40411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    (paint.getStrokeJoin() == SkPaint::kBevel_Join && rect.isEmpty()));
40511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // another two reasons we might need to call drawPath...
406d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
407d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    if (paint.getMaskFilter()) {
40811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        usePath = true;
40911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
410d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
41111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (!usePath && paint.isAntiAlias() && !fContext->getMatrix().rectStaysRect()) {
41211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT)
41311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (doStroke) {
41411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#endif
41511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            usePath = true;
41611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT)
41711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        } else {
41811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            usePath = !fContext->getMatrix().preservesRightAngles();
41911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
42011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#endif
42111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
42211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // until we can both stroke and fill rectangles
42311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (paint.getStyle() == SkPaint::kStrokeAndFill_Style) {
42411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        usePath = true;
42511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
42611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
427d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    GrStrokeInfo strokeInfo(paint);
428d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
429d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    const SkPathEffect* pe = paint.getPathEffect();
43049f085dddff10473b6ebf832a974288300224e60bsalomon    if (!usePath && pe && !strokeInfo.isDashed()) {
431d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        usePath = true;
432d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    }
433d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
43411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (usePath) {
43511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkPath path;
43611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        path.addRect(rect);
43711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        this->drawPath(draw, path, paint, NULL, true);
43811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
43911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
44011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
44111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint grPaint;
4423595f88aff0a1b490aa6661f0ba2d3534ee86353commit-bot@chromium.org    SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
443744fb7313f31069e9eceeca4c0ff33dbe2fe1737Mike Klein
444d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    fContext->drawRect(grPaint, rect, &strokeInfo);
44511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
44611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
44711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
44811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
44911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rect,
45011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           const SkPaint& paint) {
451d78a168ec2ec2c07c0c1845e6a1781988e4a52d9egdaniel    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawRRect", fContext);
45211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_FOR_ANNOTATION(paint);
45311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_SHOULD_DRAW(draw, false);
45411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
455821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org    GrPaint grPaint;
4563595f88aff0a1b490aa6661f0ba2d3534ee86353commit-bot@chromium.org    SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
457744fb7313f31069e9eceeca4c0ff33dbe2fe1737Mike Klein
458d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    GrStrokeInfo strokeInfo(paint);
459821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org    if (paint.getMaskFilter()) {
460821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org        // try to hit the fast path for drawing filtered round rects
461821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org
462821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org        SkRRect devRRect;
463821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org        if (rect.transform(fContext->getMatrix(), &devRRect)) {
464821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org            if (devRRect.allCornersCircular()) {
465821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                SkRect maskRect;
466821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                if (paint.getMaskFilter()->canFilterMaskGPU(devRRect.rect(),
467821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                                            draw.fClip->getBounds(),
468821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                                            fContext->getMatrix(),
469821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                                            &maskRect)) {
470821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                    SkIRect finalIRect;
471821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                    maskRect.roundOut(&finalIRect);
472821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                    if (draw.fClip->quickReject(finalIRect)) {
473821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                        // clipped out
474821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                        return;
475821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                    }
476821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                    if (paint.getMaskFilter()->directFilterRRectMaskGPU(fContext, &grPaint,
477d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel                                                                        strokeInfo.getStrokeRec(),
478d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel                                                                        devRRect)) {
479821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                        return;
480821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                    }
481821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                }
482821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org
483821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org            }
484821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org        }
485821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org
486821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org    }
487821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org
488d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    bool usePath = false;
489d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
490d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    if (paint.getMaskFilter()) {
491d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        usePath = true;
492d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    } else {
493d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        const SkPathEffect* pe = paint.getPathEffect();
49449f085dddff10473b6ebf832a974288300224e60bsalomon        if (pe && !strokeInfo.isDashed()) {
495d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel            usePath = true;
496d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        }
497d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    }
498d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
499d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
500d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    if (usePath) {
50111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkPath path;
50211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        path.addRRect(rect);
50311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        this->drawPath(draw, path, paint, NULL, true);
50411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
50511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
506744fb7313f31069e9eceeca4c0ff33dbe2fe1737Mike Klein
507d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    fContext->drawRRect(grPaint, rect, strokeInfo);
50811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
50911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
5100a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.orgvoid SkGpuDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
5110a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org                              const SkRRect& inner, const SkPaint& paint) {
5120a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    SkStrokeRec stroke(paint);
5130a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    if (stroke.isFillStyle()) {
5140a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
5150a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        CHECK_FOR_ANNOTATION(paint);
5160a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        CHECK_SHOULD_DRAW(draw, false);
5170a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
5180a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        GrPaint grPaint;
5193595f88aff0a1b490aa6661f0ba2d3534ee86353commit-bot@chromium.org        SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
5200a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
5210a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        if (NULL == paint.getMaskFilter() && NULL == paint.getPathEffect()) {
5220a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org            fContext->drawDRRect(grPaint, outer, inner);
5230a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org            return;
5240a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        }
5250a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    }
5260a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
5270a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    SkPath path;
5280a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    path.addRRect(outer);
5290a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    path.addRRect(inner);
5300a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    path.setFillType(SkPath::kEvenOdd_FillType);
5310a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
5320a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    this->drawPath(draw, path, paint, NULL, true);
5330a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org}
5340a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
5350a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
536821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////
53711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
53811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawOval(const SkDraw& draw, const SkRect& oval,
53911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           const SkPaint& paint) {
540d78a168ec2ec2c07c0c1845e6a1781988e4a52d9egdaniel    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawOval", fContext);
54111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_FOR_ANNOTATION(paint);
54211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_SHOULD_DRAW(draw, false);
54311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
544d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    GrStrokeInfo strokeInfo(paint);
545d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
54611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    bool usePath = false;
54711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // some basic reasons we might need to call drawPath...
548d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    if (paint.getMaskFilter()) {
54911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        usePath = true;
550d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    } else {
551d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        const SkPathEffect* pe = paint.getPathEffect();
55249f085dddff10473b6ebf832a974288300224e60bsalomon        if (pe && !strokeInfo.isDashed()) {
553d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel            usePath = true;
554d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        }
55511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
55611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
55711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (usePath) {
55811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkPath path;
55911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        path.addOval(oval);
56011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        this->drawPath(draw, path, paint, NULL, true);
56111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
56211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
56311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
56411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint grPaint;
5653595f88aff0a1b490aa6661f0ba2d3534ee86353commit-bot@chromium.org    SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
56611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
567d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    fContext->drawOval(grPaint, oval, strokeInfo);
56811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
56911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
57011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkMaskFilter.h"
57111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
57211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
57311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
57411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// helpers for applying mask filters
57511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comnamespace {
57611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
57711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// Draw a mask using the supplied paint. Since the coverage/geometry
57811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// is already burnt into the mask this boils down to a rect draw.
57911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// Return true if the mask was successfully drawn.
58011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.combool draw_mask(GrContext* context, const SkRect& maskRect,
58111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com               GrPaint* grp, GrTexture* mask) {
58211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrContext::AutoMatrix am;
58311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (!am.setIdentity(context, grp)) {
58411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
58511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
58611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
58711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkMatrix matrix;
58811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    matrix.setTranslate(-maskRect.fLeft, -maskRect.fTop);
58911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    matrix.postIDiv(mask->width(), mask->height());
59011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
591b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    grp->addCoverageProcessor(GrSimpleTextureEffect::Create(mask, matrix))->unref();
59211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    context->drawRect(*grp, maskRect);
59311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    return true;
59411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
59511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
59611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.combool draw_with_mask_filter(GrContext* context, const SkPath& devPath,
597868074b50b0fc3e460d2aa97c1096827fe0a1935reed                           SkMaskFilter* filter, const SkRegion& clip,
59811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           GrPaint* grp, SkPaint::Style style) {
59911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkMask  srcM, dstM;
60011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
60111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (!SkDraw::DrawToMask(devPath, &clip.getBounds(), filter, &context->getMatrix(), &srcM,
60211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                            SkMask::kComputeBoundsAndRenderImage_CreateMode, style)) {
60311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
60411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
60511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoMaskFreeImage autoSrc(srcM.fImage);
60611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
60711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (!filter->filterMask(&dstM, srcM, context->getMatrix(), NULL)) {
60811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
60911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
61011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // this will free-up dstM when we're done (allocated in filterMask())
61111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoMaskFreeImage autoDst(dstM.fImage);
61211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
61311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (clip.quickReject(dstM.fBounds)) {
61411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
61511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
61611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
61711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // we now have a device-aligned 8bit mask in dstM, ready to be drawn using
61811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // the current clip (and identity matrix) and GrPaint settings
61911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTextureDesc desc;
62011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fWidth = dstM.fBounds.width();
62111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fHeight = dstM.fBounds.height();
62211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fConfig = kAlpha_8_GrPixelConfig;
62311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
62411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrAutoScratchTexture ast(context, desc);
62511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTexture* texture = ast.texture();
62611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
62711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (NULL == texture) {
62811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
62911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
63011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
63111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                               dstM.fImage, dstM.fRowBytes);
63211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
63311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect maskRect = SkRect::Make(dstM.fBounds);
63411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
63511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    return draw_mask(context, maskRect, grp, texture);
63611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
63711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
63811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// Create a mask of 'devPath' and place the result in 'mask'. Return true on
63911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// success; false otherwise.
64011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.combool create_mask_GPU(GrContext* context,
64111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                     const SkRect& maskRect,
64211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                     const SkPath& devPath,
643d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel                     const GrStrokeInfo& strokeInfo,
64411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                     bool doAA,
64511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                     GrAutoScratchTexture* mask) {
64611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTextureDesc desc;
64711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fFlags = kRenderTarget_GrTextureFlagBit;
64811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fWidth = SkScalarCeilToInt(maskRect.width());
64911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fHeight = SkScalarCeilToInt(maskRect.height());
65011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // We actually only need A8, but it often isn't supported as a
65111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // render target so default to RGBA_8888
65211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fConfig = kRGBA_8888_GrPixelConfig;
65311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (context->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
65411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        desc.fConfig = kAlpha_8_GrPixelConfig;
65511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
65611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
65711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    mask->set(context, desc);
65811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (NULL == mask->texture()) {
65911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
66011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
66111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
66211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTexture* maskTexture = mask->texture();
66311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect clipRect = SkRect::MakeWH(maskRect.width(), maskRect.height());
66411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
66511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrContext::AutoRenderTarget art(context, maskTexture->asRenderTarget());
66611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrContext::AutoClip ac(context, clipRect);
66711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
66811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    context->clear(NULL, 0x0, true);
66911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
67011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint tempPaint;
67111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (doAA) {
67211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        tempPaint.setAntiAlias(true);
67311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // AA uses the "coverage" stages on GrDrawTarget. Coverage with a dst
67411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // blend coeff of zero requires dual source blending support in order
67511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // to properly blend partially covered pixels. This means the AA
67611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // code path may not be taken. So we use a dst blend coeff of ISA. We
67711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // could special case AA draws to a dst surface with known alpha=0 to
67811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // use a zero dst coeff when dual source blending isn't available.
67911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        tempPaint.setBlendFunc(kOne_GrBlendCoeff, kISC_GrBlendCoeff);
68011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
68111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
68211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrContext::AutoMatrix am;
68311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
68411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // Draw the mask into maskTexture with the path's top-left at the origin using tempPaint.
68511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkMatrix translate;
68611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    translate.setTranslate(-maskRect.fLeft, -maskRect.fTop);
68711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    am.set(context, translate);
688d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    context->drawPath(tempPaint, devPath, strokeInfo);
68911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    return true;
69011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
69111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
69211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comSkBitmap wrap_texture(GrTexture* texture) {
69311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkBitmap result;
6946c22573edb234ad14df947278cfed010669a39a7reed    result.setInfo(texture->info());
6956c22573edb234ad14df947278cfed010669a39a7reed    result.setPixelRef(SkNEW_ARGS(SkGrPixelRef, (result.info(), texture)))->unref();
69611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    return result;
69711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
69811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
69911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com};
70011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
70111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
70211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           const SkPaint& paint, const SkMatrix* prePathMatrix,
70311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           bool pathIsMutable) {
70411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_FOR_ANNOTATION(paint);
70511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_SHOULD_DRAW(draw, false);
706d78a168ec2ec2c07c0c1845e6a1781988e4a52d9egdaniel    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPath", fContext);
70711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
70811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint grPaint;
7093595f88aff0a1b490aa6661f0ba2d3534ee86353commit-bot@chromium.org    SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
71011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
71111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // If we have a prematrix, apply it to the path, optimizing for the case
71211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // where the original path can in fact be modified in place (even though
71311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // its parameter type is const).
71411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkPath* pathPtr = const_cast<SkPath*>(&origSrcPath);
715f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org    SkTLazy<SkPath> tmpPath;
716f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org    SkTLazy<SkPath> effectPath;
71711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
71811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (prePathMatrix) {
71911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkPath* result = pathPtr;
72011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
72111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (!pathIsMutable) {
722f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org            result = tmpPath.init();
72311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            pathIsMutable = true;
72411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
72511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // should I push prePathMatrix on our MV stack temporarily, instead
72611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // of applying it here? See SkDraw.cpp
72711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        pathPtr->transform(*prePathMatrix, result);
72811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        pathPtr = result;
72911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
73011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // at this point we're done with prePathMatrix
73111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;)
73211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
733d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    GrStrokeInfo strokeInfo(paint);
73411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkPathEffect* pathEffect = paint.getPathEffect();
73511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    const SkRect* cullRect = NULL;  // TODO: what is our bounds?
736d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    SkStrokeRec* strokePtr = strokeInfo.getStrokeRecPtr();
737d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    if (pathEffect && pathEffect->filterPath(effectPath.init(), *pathPtr, strokePtr,
73811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                             cullRect)) {
739f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org        pathPtr = effectPath.get();
740f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org        pathIsMutable = true;
741d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        strokeInfo.removeDash();
74211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
74311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
744d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    const SkStrokeRec& stroke = strokeInfo.getStrokeRec();
74511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (paint.getMaskFilter()) {
74611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (!stroke.isHairlineStyle()) {
747f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org            SkPath* strokedPath = pathIsMutable ? pathPtr : tmpPath.init();
748f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org            if (stroke.applyToPath(strokedPath, *pathPtr)) {
749f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org                pathPtr = strokedPath;
75011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                pathIsMutable = true;
751d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel                strokeInfo.setFillStyle();
75211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
75311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
75411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
75511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // avoid possibly allocating a new path in transform if we can
756f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org        SkPath* devPathPtr = pathIsMutable ? pathPtr : tmpPath.init();
75711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
75811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // transform the path into device space
75911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        pathPtr->transform(fContext->getMatrix(), devPathPtr);
7604c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com
76111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkRect maskRect;
76211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (paint.getMaskFilter()->canFilterMaskGPU(devPathPtr->getBounds(),
76311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                                    draw.fClip->getBounds(),
76411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                                    fContext->getMatrix(),
76511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                                    &maskRect)) {
766439ff1b9ca2b74a9dc3b04346aa1032c11b142e9commit-bot@chromium.org            // The context's matrix may change while creating the mask, so save the CTM here to
767439ff1b9ca2b74a9dc3b04346aa1032c11b142e9commit-bot@chromium.org            // pass to filterMaskGPU.
768439ff1b9ca2b74a9dc3b04346aa1032c11b142e9commit-bot@chromium.org            const SkMatrix ctm = fContext->getMatrix();
769439ff1b9ca2b74a9dc3b04346aa1032c11b142e9commit-bot@chromium.org
77011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkIRect finalIRect;
77111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            maskRect.roundOut(&finalIRect);
77211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            if (draw.fClip->quickReject(finalIRect)) {
77311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                // clipped out
77411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                return;
77511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
7764c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com
777cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org            if (paint.getMaskFilter()->directFilterMaskGPU(fContext, &grPaint,
778821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                                                           stroke, *devPathPtr)) {
779cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org                // the mask filter was able to draw itself directly, so there's nothing
780cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org                // left to do.
781cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org                return;
782cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org            }
78311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
78411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            GrAutoScratchTexture mask;
78511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
786d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel            if (create_mask_GPU(fContext, maskRect, *devPathPtr, strokeInfo,
78711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                grPaint.isAntiAlias(), &mask)) {
78811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                GrTexture* filtered;
78911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
79041bf930039314cc71039b12957195f1c65c30ce1commit-bot@chromium.org                if (paint.getMaskFilter()->filterMaskGPU(mask.texture(),
791439ff1b9ca2b74a9dc3b04346aa1032c11b142e9commit-bot@chromium.org                                                         ctm, maskRect, &filtered, true)) {
79211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    // filterMaskGPU gives us ownership of a ref to the result
79311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    SkAutoTUnref<GrTexture> atu(filtered);
79411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
79511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    // If the scratch texture that we used as the filter src also holds the filter
79611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    // result then we must detach so that this texture isn't recycled for a later
79711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    // draw.
79811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    if (filtered == mask.texture()) {
79911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                        mask.detach();
80011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                        filtered->unref(); // detach transfers GrAutoScratchTexture's ref to us.
80111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    }
80211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
80311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    if (draw_mask(fContext, maskRect, &grPaint, filtered)) {
80411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                        // This path is completely drawn
80511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                        return;
80611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    }
80711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                }
80811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
80911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
81011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
81111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // draw the mask on the CPU - this is a fallthrough path in case the
81211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // GPU path fails
81311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkPaint::Style style = stroke.isHairlineStyle() ? SkPaint::kStroke_Style :
81411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                                          SkPaint::kFill_Style;
815d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        draw_with_mask_filter(fContext, *devPathPtr, paint.getMaskFilter(),
816d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel                              *draw.fClip, &grPaint, style);
81711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
81811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
81911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
820d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    fContext->drawPath(grPaint, *pathPtr, strokeInfo);
82111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
82211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
82311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comstatic const int kBmpSmallTileSize = 1 << 10;
82411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
82511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comstatic inline int get_tile_count(const SkIRect& srcRect, int tileSize)  {
82611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    int tilesX = (srcRect.fRight / tileSize) - (srcRect.fLeft / tileSize) + 1;
82711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    int tilesY = (srcRect.fBottom / tileSize) - (srcRect.fTop / tileSize) + 1;
82811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    return tilesX * tilesY;
82911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
83011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
83111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comstatic int determine_tile_size(const SkBitmap& bitmap, const SkIRect& src, int maxTileSize) {
83211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (maxTileSize <= kBmpSmallTileSize) {
83311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return maxTileSize;
83411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
83511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
83611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    size_t maxTileTotalTileSize = get_tile_count(src, maxTileSize);
83711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    size_t smallTotalTileSize = get_tile_count(src, kBmpSmallTileSize);
83811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
83911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    maxTileTotalTileSize *= maxTileSize * maxTileSize;
84011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    smallTotalTileSize *= kBmpSmallTileSize * kBmpSmallTileSize;
84111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
84211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (maxTileTotalTileSize > 2 * smallTotalTileSize) {
84311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return kBmpSmallTileSize;
84411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
84511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return maxTileSize;
84611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
84711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
84811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
84911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// Given a bitmap, an optional src rect, and a context with a clip and matrix determine what
85011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// pixels from the bitmap are necessary.
85111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comstatic void determine_clipped_src_rect(const GrContext* context,
85211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                       const SkBitmap& bitmap,
85311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                       const SkRect* srcRectPtr,
85411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                       SkIRect* clippedSrcIRect) {
85511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    const GrClipData* clip = context->getClip();
85611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    clip->getConservativeBounds(context->getRenderTarget(), clippedSrcIRect, NULL);
85711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkMatrix inv;
85811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (!context->getMatrix().invert(&inv)) {
85911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        clippedSrcIRect->setEmpty();
86011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
86111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
86211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect clippedSrcRect = SkRect::Make(*clippedSrcIRect);
86311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    inv.mapRect(&clippedSrcRect);
86449f085dddff10473b6ebf832a974288300224e60bsalomon    if (srcRectPtr) {
865a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        // we've setup src space 0,0 to map to the top left of the src rect.
866a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        clippedSrcRect.offset(srcRectPtr->fLeft, srcRectPtr->fTop);
86711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (!clippedSrcRect.intersect(*srcRectPtr)) {
86811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            clippedSrcIRect->setEmpty();
86911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            return;
87011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
87111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
87211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    clippedSrcRect.roundOut(clippedSrcIRect);
87311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkIRect bmpBounds = SkIRect::MakeWH(bitmap.width(), bitmap.height());
87411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (!clippedSrcIRect->intersect(bmpBounds)) {
87511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        clippedSrcIRect->setEmpty();
87611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
87711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
87811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
87911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.combool SkGpuDevice::shouldTileBitmap(const SkBitmap& bitmap,
88011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   const GrTextureParams& params,
88111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   const SkRect* srcRectPtr,
88211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   int maxTileSize,
88311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   int* tileSize,
88411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   SkIRect* clippedSrcRect) const {
88511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // if bitmap is explictly texture backed then just use the texture
88649f085dddff10473b6ebf832a974288300224e60bsalomon    if (bitmap.getTexture()) {
88711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
88811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
88911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
89011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // if it's larger than the max tile size, then we have no choice but tiling.
89111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (bitmap.width() > maxTileSize || bitmap.height() > maxTileSize) {
89211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        determine_clipped_src_rect(fContext, bitmap, srcRectPtr, clippedSrcRect);
89311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        *tileSize = determine_tile_size(bitmap, *clippedSrcRect, maxTileSize);
89411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return true;
89511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
89611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
89711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (bitmap.width() * bitmap.height() < 4 * kBmpSmallTileSize * kBmpSmallTileSize) {
89811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
89911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
90011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
90111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // if the entire texture is already in our cache then no reason to tile it
90211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (GrIsBitmapInCache(fContext, bitmap, &params)) {
90311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
90411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
90511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
90611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // At this point we know we could do the draw by uploading the entire bitmap
90711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // as a texture. However, if the texture would be large compared to the
90811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // cache size and we don't require most of it for this draw then tile to
90911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // reduce the amount of upload and cache spill.
91011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
91111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // assumption here is that sw bitmap size is a good proxy for its size as
91211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // a texture
91311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    size_t bmpSize = bitmap.getSize();
91411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    size_t cacheSize;
91595c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org    fContext->getResourceCacheLimits(NULL, &cacheSize);
91611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (bmpSize < cacheSize / 2) {
91711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
91811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
91911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
92011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // Figure out how much of the src we will need based on the src rect and clipping.
92111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    determine_clipped_src_rect(fContext, bitmap, srcRectPtr, clippedSrcRect);
92211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    *tileSize = kBmpSmallTileSize; // already know whole bitmap fits in one max sized tile.
92311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    size_t usedTileBytes = get_tile_count(*clippedSrcRect, kBmpSmallTileSize) *
92411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           kBmpSmallTileSize * kBmpSmallTileSize;
92511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
92611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    return usedTileBytes < 2 * bmpSize;
92711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
92811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
929a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.orgvoid SkGpuDevice::drawBitmap(const SkDraw& origDraw,
93011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                             const SkBitmap& bitmap,
93111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                             const SkMatrix& m,
93211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                             const SkPaint& paint) {
933a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    SkMatrix concat;
934a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    SkTCopyOnFirstWrite<SkDraw> draw(origDraw);
935a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    if (!m.isIdentity()) {
936a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        concat.setConcat(*draw->fMatrix, m);
937a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        draw.writable()->fMatrix = &concat;
938a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    }
939a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    this->drawBitmapCommon(*draw, bitmap, NULL, NULL, paint, SkCanvas::kNone_DrawBitmapRectFlag);
94011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
94111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
942dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org// This method outsets 'iRect' by 'outset' all around and then clamps its extents to
94311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// 'clamp'. 'offset' is adjusted to remain positioned over the top-left corner
94411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// of 'iRect' for all possible outsets/clamps.
945dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.orgstatic inline void clamped_outset_with_offset(SkIRect* iRect,
946dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                                              int outset,
947dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                                              SkPoint* offset,
948dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                                              const SkIRect& clamp) {
949dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    iRect->outset(outset, outset);
950dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org
951dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    int leftClampDelta = clamp.fLeft - iRect->fLeft;
952dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    if (leftClampDelta > 0) {
953dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org        offset->fX -= outset - leftClampDelta;
95411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        iRect->fLeft = clamp.fLeft;
95511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
956dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org        offset->fX -= outset;
95711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
958dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org
959dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    int topClampDelta = clamp.fTop - iRect->fTop;
960dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    if (topClampDelta > 0) {
961dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org        offset->fY -= outset - topClampDelta;
96211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        iRect->fTop = clamp.fTop;
96311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
964dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org        offset->fY -= outset;
96511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
96611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
96711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (iRect->fRight > clamp.fRight) {
96811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        iRect->fRight = clamp.fRight;
96911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
97011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (iRect->fBottom > clamp.fBottom) {
97111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        iRect->fBottom = clamp.fBottom;
97211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
97311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
97411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
975a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.orgstatic bool has_aligned_samples(const SkRect& srcRect,
976a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                const SkRect& transformedRect) {
977a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // detect pixel disalignment
978a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    if (SkScalarAbs(SkScalarRoundToScalar(transformedRect.left()) -
979a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            transformedRect.left()) < COLOR_BLEED_TOLERANCE &&
980a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        SkScalarAbs(SkScalarRoundToScalar(transformedRect.top()) -
981a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            transformedRect.top()) < COLOR_BLEED_TOLERANCE &&
982a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        SkScalarAbs(transformedRect.width() - srcRect.width()) <
983a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            COLOR_BLEED_TOLERANCE &&
984a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        SkScalarAbs(transformedRect.height() - srcRect.height()) <
985a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            COLOR_BLEED_TOLERANCE) {
986a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        return true;
987a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    }
988a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    return false;
989a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org}
990a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org
991a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.orgstatic bool may_color_bleed(const SkRect& srcRect,
992a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                            const SkRect& transformedRect,
993a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                            const SkMatrix& m) {
994a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // Only gets called if has_aligned_samples returned false.
995a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // So we can assume that sampling is axis aligned but not texel aligned.
996a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    SkASSERT(!has_aligned_samples(srcRect, transformedRect));
997a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    SkRect innerSrcRect(srcRect), innerTransformedRect,
998a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        outerTransformedRect(transformedRect);
999a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    innerSrcRect.inset(SK_ScalarHalf, SK_ScalarHalf);
1000a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    m.mapRect(&innerTransformedRect, innerSrcRect);
1001a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org
1002a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // The gap between outerTransformedRect and innerTransformedRect
1003a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // represents the projection of the source border area, which is
1004a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // problematic for color bleeding.  We must check whether any
1005a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // destination pixels sample the border area.
1006a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    outerTransformedRect.inset(COLOR_BLEED_TOLERANCE, COLOR_BLEED_TOLERANCE);
1007a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    innerTransformedRect.outset(COLOR_BLEED_TOLERANCE, COLOR_BLEED_TOLERANCE);
1008a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    SkIRect outer, inner;
1009a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    outerTransformedRect.round(&outer);
1010a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    innerTransformedRect.round(&inner);
1011a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // If the inner and outer rects round to the same result, it means the
1012a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // border does not overlap any pixel centers. Yay!
1013a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    return inner != outer;
1014a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org}
1015a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org
1016a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.orgstatic bool needs_texture_domain(const SkBitmap& bitmap,
1017a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 const SkRect& srcRect,
1018a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 GrTextureParams &params,
1019a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 const SkMatrix& contextMatrix,
1020a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 bool bicubic) {
1021a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    bool needsTextureDomain = false;
1022a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org
1023a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    if (bicubic || params.filterMode() != GrTextureParams::kNone_FilterMode) {
1024a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        // Need texture domain if drawing a sub rect
1025a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        needsTextureDomain = srcRect.width() < bitmap.width() ||
1026a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                             srcRect.height() < bitmap.height();
1027a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        if (!bicubic && needsTextureDomain && contextMatrix.rectStaysRect()) {
1028a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            // sampling is axis-aligned
1029a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            SkRect transformedRect;
1030a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            contextMatrix.mapRect(&transformedRect, srcRect);
1031a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org
1032a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            if (has_aligned_samples(srcRect, transformedRect)) {
1033a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                params.setFilterMode(GrTextureParams::kNone_FilterMode);
1034a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                needsTextureDomain = false;
1035a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            } else {
1036a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                needsTextureDomain = may_color_bleed(srcRect, transformedRect, contextMatrix);
1037a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            }
1038a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        }
1039a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    }
1040a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    return needsTextureDomain;
1041a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org}
1042a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org
104311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawBitmapCommon(const SkDraw& draw,
104411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   const SkBitmap& bitmap,
104511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   const SkRect* srcRectPtr,
1046a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org                                   const SkSize* dstSizePtr,
104711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   const SkPaint& paint,
104811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   SkCanvas::DrawBitmapRectFlags flags) {
104911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_SHOULD_DRAW(draw, false);
105011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
105111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect srcRect;
1052a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    SkSize dstSize;
1053dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    // If there is no src rect, or the src rect contains the entire bitmap then we're effectively
1054dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    // in the (easier) bleed case, so update flags.
105511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (NULL == srcRectPtr) {
1056a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        SkScalar w = SkIntToScalar(bitmap.width());
1057a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        SkScalar h = SkIntToScalar(bitmap.height());
1058a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        dstSize.fWidth = w;
1059a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        dstSize.fHeight = h;
1060a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        srcRect.set(0, 0, w, h);
1061dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org        flags = (SkCanvas::DrawBitmapRectFlags) (flags | SkCanvas::kBleed_DrawBitmapRectFlag);
106211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
106349f085dddff10473b6ebf832a974288300224e60bsalomon        SkASSERT(dstSizePtr);
106411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        srcRect = *srcRectPtr;
1065a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        dstSize = *dstSizePtr;
1066dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org        if (srcRect.fLeft <= 0 && srcRect.fTop <= 0 &&
1067dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org            srcRect.fRight >= bitmap.width() && srcRect.fBottom >= bitmap.height()) {
1068dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org            flags = (SkCanvas::DrawBitmapRectFlags) (flags | SkCanvas::kBleed_DrawBitmapRectFlag);
1069dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org        }
107011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
107111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
107211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (paint.getMaskFilter()){
107311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // Convert the bitmap to a shader so that the rect can be drawn
107411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // through drawRect, which supports mask filters.
107511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkBitmap        tmp;    // subset of bitmap, if necessary
107611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        const SkBitmap* bitmapPtr = &bitmap;
1077a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        SkMatrix localM;
107849f085dddff10473b6ebf832a974288300224e60bsalomon        if (srcRectPtr) {
1079a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org            localM.setTranslate(-srcRectPtr->fLeft, -srcRectPtr->fTop);
1080a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org            localM.postScale(dstSize.fWidth / srcRectPtr->width(),
1081a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org                             dstSize.fHeight / srcRectPtr->height());
1082d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org            // In bleed mode we position and trim the bitmap based on the src rect which is
1083d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org            // already accounted for in 'm' and 'srcRect'. In clamp mode we need to chop out
1084d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org            // the desired portion of the bitmap and then update 'm' and 'srcRect' to
1085d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org            // compensate.
1086d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org            if (!(SkCanvas::kBleed_DrawBitmapRectFlag & flags)) {
1087d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                SkIRect iSrc;
1088d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                srcRect.roundOut(&iSrc);
1089d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org
1090d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                SkPoint offset = SkPoint::Make(SkIntToScalar(iSrc.fLeft),
1091d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                                               SkIntToScalar(iSrc.fTop));
1092d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org
1093d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                if (!bitmap.extractSubset(&tmp, iSrc)) {
1094d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                    return;     // extraction failed
1095d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                }
1096d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                bitmapPtr = &tmp;
1097d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                srcRect.offset(-offset.fX, -offset.fY);
1098a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org
1099d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                // The source rect has changed so update the matrix
1100a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org                localM.preTranslate(offset.fX, offset.fY);
110111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
1102a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        } else {
1103a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org            localM.reset();
110411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
110511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1106a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        SkPaint paintWithShader(paint);
1107a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        paintWithShader.setShader(SkShader::CreateBitmapShader(*bitmapPtr,
11089c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org            SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, &localM))->unref();
1109a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        SkRect dstRect = {0, 0, dstSize.fWidth, dstSize.fHeight};
1110a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        this->drawRect(draw, dstRect, paintWithShader);
111111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
111211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
111311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
111411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1115a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    // If there is no mask filter than it is OK to handle the src rect -> dst rect scaling using
1116a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    // the view matrix rather than a local matrix.
1117a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    SkMatrix m;
1118a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    m.setScale(dstSize.fWidth / srcRect.width(),
1119a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org               dstSize.fHeight / srcRect.height());
112011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext->concatMatrix(m);
112111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
112211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTextureParams params;
112311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkPaint::FilterLevel paintFilterLevel = paint.getFilterLevel();
112411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTextureParams::FilterMode textureFilterMode;
1125dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org
1126dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    bool doBicubic = false;
1127dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org
112811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    switch(paintFilterLevel) {
112911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        case SkPaint::kNone_FilterLevel:
113011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            textureFilterMode = GrTextureParams::kNone_FilterMode;
113111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            break;
113211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        case SkPaint::kLow_FilterLevel:
113311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            textureFilterMode = GrTextureParams::kBilerp_FilterMode;
113411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            break;
113511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        case SkPaint::kMedium_FilterLevel:
11361878651990d7c9da72cf43481432232bbef3550dcommit-bot@chromium.org            if (fContext->getMatrix().getMinScale() < SK_Scalar1) {
113779b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org                textureFilterMode = GrTextureParams::kMipMap_FilterMode;
113879b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org            } else {
113979b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org                // Don't trigger MIP level generation unnecessarily.
114079b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org                textureFilterMode = GrTextureParams::kBilerp_FilterMode;
114179b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org            }
114211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            break;
114379b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org        case SkPaint::kHigh_FilterLevel:
1144cea9abb001b07eaf4340a78db708bfac9e8c68c2commit-bot@chromium.org            // Minification can look bad with the bicubic effect.
11459927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org            doBicubic =
11469927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org                GrBicubicEffect::ShouldUseBicubic(fContext->getMatrix(), &textureFilterMode);
114711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            break;
114811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        default:
114911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkErrorInternals::SetError( kInvalidPaint_SkError,
115011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                        "Sorry, I don't understand the filtering "
115111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                        "mode you asked for.  Falling back to "
115211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                        "MIPMaps.");
115311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            textureFilterMode = GrTextureParams::kMipMap_FilterMode;
115411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            break;
115511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
115611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
11579927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org    int tileFilterPad;
11589927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org    if (doBicubic) {
11599927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org        tileFilterPad = GrBicubicEffect::kFilterTexelPad;
11609927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org    } else if (GrTextureParams::kNone_FilterMode == textureFilterMode) {
11619927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org        tileFilterPad = 0;
11629927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org    } else {
11639927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org        tileFilterPad = 1;
11649927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org    }
116511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    params.setFilterMode(textureFilterMode);
116611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1167dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    int maxTileSize = fContext->getMaxTextureSize() - 2 * tileFilterPad;
116811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    int tileSize;
116911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
117011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkIRect clippedSrcRect;
117111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (this->shouldTileBitmap(bitmap, params, srcRectPtr, maxTileSize, &tileSize,
117211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                               &clippedSrcRect)) {
1173dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org        this->drawTiledBitmap(bitmap, srcRect, clippedSrcRect, params, paint, flags, tileSize,
1174dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                              doBicubic);
117511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
117611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // take the simple case
1177a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        bool needsTextureDomain = needs_texture_domain(bitmap,
1178a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                                       srcRect,
1179a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                                       params,
1180a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                                       fContext->getMatrix(),
1181a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                                       doBicubic);
1182a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        this->internalDrawBitmap(bitmap,
1183a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 srcRect,
1184a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 params,
1185a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 paint,
1186a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 flags,
1187a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 doBicubic,
1188a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 needsTextureDomain);
118911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
119011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
119111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
119211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// Break 'bitmap' into several tiles to draw it since it has already
119311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// been determined to be too large to fit in VRAM
119411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap,
119511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                  const SkRect& srcRect,
119611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                  const SkIRect& clippedSrcIRect,
119711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                  const GrTextureParams& params,
119811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                  const SkPaint& paint,
119911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                  SkCanvas::DrawBitmapRectFlags flags,
1200dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                                  int tileSize,
1201dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                                  bool bicubic) {
12029d5e3f11a35e2059476a55e52349d3c6b3058f70commit-bot@chromium.org    // The following pixel lock is technically redundant, but it is desirable
12039d5e3f11a35e2059476a55e52349d3c6b3058f70commit-bot@chromium.org    // to lock outside of the tile loop to prevent redecoding the whole image
12049d5e3f11a35e2059476a55e52349d3c6b3058f70commit-bot@chromium.org    // at each tile in cases where 'bitmap' holds an SkDiscardablePixelRef that
12059d5e3f11a35e2059476a55e52349d3c6b3058f70commit-bot@chromium.org    // is larger than the limit of the discardable memory pool.
12069d5e3f11a35e2059476a55e52349d3c6b3058f70commit-bot@chromium.org    SkAutoLockPixels alp(bitmap);
120711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect clippedSrcRect = SkRect::Make(clippedSrcIRect);
120811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
120911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    int nx = bitmap.width() / tileSize;
121011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    int ny = bitmap.height() / tileSize;
121111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    for (int x = 0; x <= nx; x++) {
121211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        for (int y = 0; y <= ny; y++) {
121311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkRect tileR;
121411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            tileR.set(SkIntToScalar(x * tileSize),
121511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                      SkIntToScalar(y * tileSize),
121611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                      SkIntToScalar((x + 1) * tileSize),
121711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                      SkIntToScalar((y + 1) * tileSize));
121811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
121911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            if (!SkRect::Intersects(tileR, clippedSrcRect)) {
122011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                continue;
122111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
122211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
122311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            if (!tileR.intersect(srcRect)) {
122411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                continue;
122511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
122611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
122711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkBitmap tmpB;
122811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkIRect iTileR;
122911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            tileR.roundOut(&iTileR);
123011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkPoint offset = SkPoint::Make(SkIntToScalar(iTileR.fLeft),
123111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                           SkIntToScalar(iTileR.fTop));
123211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1233a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org            // Adjust the context matrix to draw at the right x,y in device space
1234a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org            SkMatrix tmpM;
1235a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org            GrContext::AutoMatrix am;
1236a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org            tmpM.setTranslate(offset.fX - srcRect.fLeft, offset.fY - srcRect.fTop);
1237a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org            am.setPreConcat(fContext, tmpM);
1238a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org
1239dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org            if (SkPaint::kNone_FilterLevel != paint.getFilterLevel() || bicubic) {
124011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                SkIRect iClampRect;
124111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
124211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                if (SkCanvas::kBleed_DrawBitmapRectFlag & flags) {
124311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    // In bleed mode we want to always expand the tile on all edges
124411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    // but stay within the bitmap bounds
124511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    iClampRect = SkIRect::MakeWH(bitmap.width(), bitmap.height());
124611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                } else {
124711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    // In texture-domain/clamp mode we only want to expand the
124811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    // tile on edges interior to "srcRect" (i.e., we want to
124911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    // not bleed across the original clamped edges)
125011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    srcRect.roundOut(&iClampRect);
125111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                }
1252dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                int outset = bicubic ? GrBicubicEffect::kFilterTexelPad : 1;
1253dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                clamped_outset_with_offset(&iTileR, outset, &offset, iClampRect);
125411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
125511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
125611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            if (bitmap.extractSubset(&tmpB, iTileR)) {
125711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                // now offset it to make it "local" to our tmp bitmap
125811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                tileR.offset(-offset.fX, -offset.fY);
1259a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                GrTextureParams paramsTemp = params;
1260a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                bool needsTextureDomain = needs_texture_domain(bitmap,
1261a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                                               srcRect,
1262a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                                               paramsTemp,
1263a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                                               fContext->getMatrix(),
1264a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                                               bicubic);
1265a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                this->internalDrawBitmap(tmpB,
1266a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                         tileR,
1267a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                         paramsTemp,
1268a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                         paint,
1269a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                         flags,
1270a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                         bicubic,
1271a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                         needsTextureDomain);
127211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
127311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
127411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
127511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
127611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
127711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
127811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com/*
127911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com *  This is called by drawBitmap(), which has to handle images that may be too
128011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com *  large to be represented by a single texture.
128111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com *
128211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com *  internalDrawBitmap assumes that the specified bitmap will fit in a texture
128311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com *  and that non-texture portion of the GrPaint has already been setup.
128411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com */
128511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap,
128611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                     const SkRect& srcRect,
128711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                     const GrTextureParams& params,
128811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                     const SkPaint& paint,
1289dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                                     SkCanvas::DrawBitmapRectFlags flags,
1290a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                     bool bicubic,
1291a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                     bool needsTextureDomain) {
129211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkASSERT(bitmap.width() <= fContext->getMaxTextureSize() &&
129311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com             bitmap.height() <= fContext->getMaxTextureSize());
129411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
129511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTexture* texture;
129611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoCachedTexture act(this, bitmap, &params, &texture);
129711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (NULL == texture) {
129811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
129911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
130011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1301a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    SkRect dstRect = {0, 0, srcRect.width(), srcRect.height() };
130211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect paintRect;
130311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkScalar wInv = SkScalarInvert(SkIntToScalar(texture->width()));
130411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkScalar hInv = SkScalarInvert(SkIntToScalar(texture->height()));
130511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    paintRect.setLTRB(SkScalarMul(srcRect.fLeft,   wInv),
130611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                      SkScalarMul(srcRect.fTop,    hInv),
130711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                      SkScalarMul(srcRect.fRight,  wInv),
130811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                      SkScalarMul(srcRect.fBottom, hInv));
130911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
131011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect textureDomain = SkRect::MakeEmpty();
1311b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    SkAutoTUnref<GrFragmentProcessor> fp;
1312a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    if (needsTextureDomain && !(flags & SkCanvas::kBleed_DrawBitmapRectFlag)) {
131311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // Use a constrained texture domain to avoid color bleeding
131411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkScalar left, top, right, bottom;
131511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (srcRect.width() > SK_Scalar1) {
131611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkScalar border = SK_ScalarHalf / texture->width();
131711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            left = paintRect.left() + border;
131811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            right = paintRect.right() - border;
131911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        } else {
132011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            left = right = SkScalarHalf(paintRect.left() + paintRect.right());
132111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
132211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (srcRect.height() > SK_Scalar1) {
132311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkScalar border = SK_ScalarHalf / texture->height();
132411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            top = paintRect.top() + border;
132511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            bottom = paintRect.bottom() - border;
132611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        } else {
132711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            top = bottom = SkScalarHalf(paintRect.top() + paintRect.bottom());
132811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
132911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        textureDomain.setLTRB(left, top, right, bottom);
13307d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org        if (bicubic) {
1331b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt            fp.reset(GrBicubicEffect::Create(texture, SkMatrix::I(), textureDomain));
13327d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org        } else {
1333b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt            fp.reset(GrTextureDomainEffect::Create(texture,
13347d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org                                                       SkMatrix::I(),
13357d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org                                                       textureDomain,
13367d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org                                                       GrTextureDomain::kClamp_Mode,
13377d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org                                                       params.filterMode()));
13387d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org        }
1339dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    } else if (bicubic) {
1340bc91fd71faa2c5fd14423fecd18e50701c922cedcommit-bot@chromium.org        SkASSERT(GrTextureParams::kNone_FilterMode == params.filterMode());
1341bc91fd71faa2c5fd14423fecd18e50701c922cedcommit-bot@chromium.org        SkShader::TileMode tileModes[2] = { params.getTileModeX(), params.getTileModeY() };
1342b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        fp.reset(GrBicubicEffect::Create(texture, SkMatrix::I(), tileModes));
134311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
1344b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        fp.reset(GrSimpleTextureEffect::Create(texture, SkMatrix::I(), params));
134511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
134611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
134711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // Construct a GrPaint by setting the bitmap texture as the first effect and then configuring
134811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // the rest from the SkPaint.
134911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint grPaint;
1350b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    grPaint.addColorProcessor(fp);
13510689d7b12e7c427a077b003d3d8ae759d86f798freed    bool alphaOnly = !(kAlpha_8_SkColorType == bitmap.colorType());
135283d081ae1d731b5039e99823620f5e287542ee39bsalomon    GrColor paintColor = (alphaOnly) ? SkColor2GrColorJustAlpha(paint.getColor()) :
135383d081ae1d731b5039e99823620f5e287542ee39bsalomon                                       SkColor2GrColor(paint.getColor());
135483d081ae1d731b5039e99823620f5e287542ee39bsalomon    SkPaint2GrPaintNoShader(this->context(), paint, paintColor, false, &grPaint);
135511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
135601c8da1eef36570374f7e8764a38b25bf16ab7a6bsalomon    fContext->drawRectToRect(grPaint, dstRect, paintRect);
135711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
135811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
135911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comstatic bool filter_texture(SkBaseDevice* device, GrContext* context,
1360ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org                           GrTexture* texture, const SkImageFilter* filter,
13614cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org                           int w, int h, const SkImageFilter::Context& ctx,
13624cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org                           SkBitmap* result, SkIPoint* offset) {
136311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkASSERT(filter);
136411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkDeviceImageFilterProxy proxy(device);
136511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
136611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (filter->canFilterImageGPU()) {
136711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // Save the render target and set it to NULL, so we don't accidentally draw to it in the
136811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // filter.  Also set the clip wide open and the matrix to identity.
136911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        GrContext::AutoWideOpenIdentityDraw awo(context, NULL);
13704cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org        return filter->filterImageGPU(&proxy, wrap_texture(texture), ctx, result, offset);
137111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
137211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
137311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
137411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
137511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
137611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
137711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                             int left, int top, const SkPaint& paint) {
137811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // drawSprite is defined to be in device coords.
137911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_SHOULD_DRAW(draw, true);
138011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
138111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoLockPixels alp(bitmap, !bitmap.getTexture());
138211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (!bitmap.getTexture() && !bitmap.readyToDraw()) {
138311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
138411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
138511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
138611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    int w = bitmap.width();
138711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    int h = bitmap.height();
138811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
138911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTexture* texture;
139011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // draw sprite uses the default texture params
139111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoCachedTexture act(this, bitmap, NULL, &texture);
139211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
139311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkImageFilter* filter = paint.getImageFilter();
139411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // This bitmap will own the filtered result as a texture.
139511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkBitmap filteredBitmap;
139611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
139749f085dddff10473b6ebf832a974288300224e60bsalomon    if (filter) {
13986776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org        SkIPoint offset = SkIPoint::Make(0, 0);
139911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkMatrix matrix(*draw.fMatrix);
140011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        matrix.postTranslate(SkIntToScalar(-left), SkIntToScalar(-top));
14014cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org        SkIRect clipBounds = SkIRect::MakeWH(bitmap.width(), bitmap.height());
1402be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblanco        SkAutoTUnref<SkImageFilter::Cache> cache(getImageFilterCache());
140355b6d8be997a447ef9ce0f029697677a940bfc24senorblanco        // This cache is transient, and is freed (along with all its contained
140455b6d8be997a447ef9ce0f029697677a940bfc24senorblanco        // textures) when it goes out of scope.
1405f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org        SkImageFilter::Context ctx(matrix, clipBounds, cache);
14064cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org        if (filter_texture(this, fContext, texture, filter, w, h, ctx, &filteredBitmap,
140711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           &offset)) {
140811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            texture = (GrTexture*) filteredBitmap.getTexture();
140911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            w = filteredBitmap.width();
141011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            h = filteredBitmap.height();
14116776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org            left += offset.x();
14126776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org            top += offset.y();
141311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        } else {
141411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            return;
141511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
141611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
141711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
141811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint grPaint;
1419b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    grPaint.addColorTextureProcessor(texture, SkMatrix::I());
142011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
14219de5b514d38c5b36066bcdc14fba2f7e5196d372dandov    SkPaint2GrPaintNoShader(this->context(), paint, SkColor2GrColorJustAlpha(paint.getColor()),
14229de5b514d38c5b36066bcdc14fba2f7e5196d372dandov                            false, &grPaint);
142311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
142411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext->drawRectToRect(grPaint,
14256776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org                             SkRect::MakeXYWH(SkIntToScalar(left),
14266776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org                                              SkIntToScalar(top),
142711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                              SkIntToScalar(w),
142811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                              SkIntToScalar(h)),
142911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                             SkRect::MakeXYWH(0,
143011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                              0,
143111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                              SK_Scalar1 * w / texture->width(),
143211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                              SK_Scalar1 * h / texture->height()));
143311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
143411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1435a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.orgvoid SkGpuDevice::drawBitmapRect(const SkDraw& origDraw, const SkBitmap& bitmap,
143611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                 const SkRect* src, const SkRect& dst,
143711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                 const SkPaint& paint,
143811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                 SkCanvas::DrawBitmapRectFlags flags) {
143911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkMatrix    matrix;
144011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect      bitmapBounds, tmpSrc;
144111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
144211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    bitmapBounds.set(0, 0,
144311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                     SkIntToScalar(bitmap.width()),
144411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                     SkIntToScalar(bitmap.height()));
144511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
144611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // Compute matrix from the two rectangles
144749f085dddff10473b6ebf832a974288300224e60bsalomon    if (src) {
144811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        tmpSrc = *src;
144911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
145011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        tmpSrc = bitmapBounds;
145111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
1452a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org
145311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit);
145411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
145511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // clip the tmpSrc to the bounds of the bitmap. No check needed if src==null.
145649f085dddff10473b6ebf832a974288300224e60bsalomon    if (src) {
145711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (!bitmapBounds.contains(tmpSrc)) {
145811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            if (!tmpSrc.intersect(bitmapBounds)) {
145911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                return; // nothing to draw
146011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
146111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
146211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
146311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1464a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    SkRect tmpDst;
1465a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    matrix.mapRect(&tmpDst, tmpSrc);
1466a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org
1467a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    SkTCopyOnFirstWrite<SkDraw> draw(origDraw);
1468a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    if (0 != tmpDst.fLeft || 0 != tmpDst.fTop) {
1469a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        // Translate so that tempDst's top left is at the origin.
1470a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        matrix = *origDraw.fMatrix;
1471a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        matrix.preTranslate(tmpDst.fLeft, tmpDst.fTop);
1472a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        draw.writable()->fMatrix = &matrix;
1473a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    }
1474a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    SkSize dstSize;
1475a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    dstSize.fWidth = tmpDst.width();
1476a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    dstSize.fHeight = tmpDst.height();
1477a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org
1478a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    this->drawBitmapCommon(*draw, bitmap, &tmpSrc, &dstSize, paint, flags);
147911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
148011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
148111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
148211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                             int x, int y, const SkPaint& paint) {
148311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // clear of the source device must occur before CHECK_SHOULD_DRAW
1484d78a168ec2ec2c07c0c1845e6a1781988e4a52d9egdaniel    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawDevice", fContext);
148511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkGpuDevice* dev = static_cast<SkGpuDevice*>(device);
148611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (dev->fNeedClear) {
148711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // TODO: could check here whether we really need to draw at all
148811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        dev->clear(0x0);
148911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
149011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
149111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // drawDevice is defined to be in device coords.
149211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_SHOULD_DRAW(draw, true);
149311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
149411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrRenderTarget* devRT = dev->accessRenderTarget();
149511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTexture* devTex;
149611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (NULL == (devTex = devRT->asTexture())) {
149711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
149811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
149911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
150011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    const SkBitmap& bm = dev->accessBitmap(false);
150111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    int w = bm.width();
150211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    int h = bm.height();
150311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
150411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkImageFilter* filter = paint.getImageFilter();
150511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // This bitmap will own the filtered result as a texture.
150611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkBitmap filteredBitmap;
150711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
150849f085dddff10473b6ebf832a974288300224e60bsalomon    if (filter) {
150911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkIPoint offset = SkIPoint::Make(0, 0);
151011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkMatrix matrix(*draw.fMatrix);
151111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y));
15124cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org        SkIRect clipBounds = SkIRect::MakeWH(devTex->width(), devTex->height());
151355b6d8be997a447ef9ce0f029697677a940bfc24senorblanco        // This cache is transient, and is freed (along with all its contained
151455b6d8be997a447ef9ce0f029697677a940bfc24senorblanco        // textures) when it goes out of scope.
1515be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblanco        SkAutoTUnref<SkImageFilter::Cache> cache(getImageFilterCache());
1516f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org        SkImageFilter::Context ctx(matrix, clipBounds, cache);
15174cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org        if (filter_texture(this, fContext, devTex, filter, w, h, ctx, &filteredBitmap,
151811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           &offset)) {
151911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            devTex = filteredBitmap.getTexture();
152011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            w = filteredBitmap.width();
152111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            h = filteredBitmap.height();
152211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            x += offset.fX;
152311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            y += offset.fY;
152411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        } else {
152511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            return;
152611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
152711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
152811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
152911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint grPaint;
1530b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    grPaint.addColorTextureProcessor(devTex, SkMatrix::I());
153111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
15329de5b514d38c5b36066bcdc14fba2f7e5196d372dandov    SkPaint2GrPaintNoShader(this->context(), paint, SkColor2GrColorJustAlpha(paint.getColor()),
15339de5b514d38c5b36066bcdc14fba2f7e5196d372dandov                            false, &grPaint);
153411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
153511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect dstRect = SkRect::MakeXYWH(SkIntToScalar(x),
153611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                      SkIntToScalar(y),
153711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                      SkIntToScalar(w),
153811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                      SkIntToScalar(h));
153911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
154011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // The device being drawn may not fill up its texture (e.g. saveLayer uses approximate
154111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // scratch texture).
154211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect srcRect = SkRect::MakeWH(SK_Scalar1 * w / devTex->width(),
154311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                    SK_Scalar1 * h / devTex->height());
154411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
154511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext->drawRectToRect(grPaint, dstRect, srcRect);
154611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
154711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1548ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.orgbool SkGpuDevice::canHandleImageFilter(const SkImageFilter* filter) {
154911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    return filter->canFilterImageGPU();
155011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
155111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1552ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.orgbool SkGpuDevice::filterImage(const SkImageFilter* filter, const SkBitmap& src,
15534cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org                              const SkImageFilter::Context& ctx,
155411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                              SkBitmap* result, SkIPoint* offset) {
155511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // want explicitly our impl, so guard against a subclass of us overriding it
155611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (!this->SkGpuDevice::canHandleImageFilter(filter)) {
155711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
155811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
155911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
156011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoLockPixels alp(src, !src.getTexture());
156111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (!src.getTexture() && !src.readyToDraw()) {
156211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
156311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
156411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
156511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTexture* texture;
156611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // We assume here that the filter will not attempt to tile the src. Otherwise, this cache lookup
156711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // must be pushed upstack.
156811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoCachedTexture act(this, src, NULL, &texture);
156911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
15704cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org    return filter_texture(this, fContext, texture, filter, src.width(), src.height(), ctx,
15714cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org                          result, offset);
157211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
157311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
157411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
157511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
157611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// must be in SkCanvas::VertexMode order
157711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comstatic const GrPrimitiveType gVertexMode2PrimitiveType[] = {
157811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    kTriangles_GrPrimitiveType,
157911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    kTriangleStrip_GrPrimitiveType,
158011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    kTriangleFan_GrPrimitiveType,
158111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com};
158211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
158311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
158411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                              int vertexCount, const SkPoint vertices[],
158511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                              const SkPoint texs[], const SkColor colors[],
158611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                              SkXfermode* xmode,
158711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                              const uint16_t indices[], int indexCount,
158811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                              const SkPaint& paint) {
158911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_SHOULD_DRAW(draw, false);
159011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1591d78a168ec2ec2c07c0c1845e6a1781988e4a52d9egdaniel    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawVertices", fContext);
1592533eb782edaa0b6fece6166d3001edf72ec39f11mtklein
159332a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov    const uint16_t* outIndices;
159432a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov    SkAutoTDeleteArray<uint16_t> outAlloc(NULL);
159532a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov    GrPrimitiveType primType;
159632a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov    GrPaint grPaint;
1597a098dd490cc4e434f054b7506c2f6e08f519585bbsalomon
1598559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org    // If both textures and vertex-colors are NULL, strokes hairlines with the paint's color.
1599559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org    if ((NULL == texs || NULL == paint.getShader()) && NULL == colors) {
1600533eb782edaa0b6fece6166d3001edf72ec39f11mtklein
1601559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        texs = NULL;
1602533eb782edaa0b6fece6166d3001edf72ec39f11mtklein
1603559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        SkPaint copy(paint);
1604559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        copy.setStyle(SkPaint::kStroke_Style);
1605559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        copy.setStrokeWidth(0);
1606533eb782edaa0b6fece6166d3001edf72ec39f11mtklein
160732a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        // we ignore the shader if texs is null.
160832a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        SkPaint2GrPaintNoShader(this->context(), copy, SkColor2GrColor(copy.getColor()),
160932a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov                                NULL == colors, &grPaint);
1610559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org
161132a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        primType = kLines_GrPrimitiveType;
161232a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        int triangleCount = 0;
1613a098dd490cc4e434f054b7506c2f6e08f519585bbsalomon        int n = (NULL == indices) ? vertexCount : indexCount;
161432a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        switch (vmode) {
161532a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov            case SkCanvas::kTriangles_VertexMode:
1616a098dd490cc4e434f054b7506c2f6e08f519585bbsalomon                triangleCount = n / 3;
161732a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov                break;
161832a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov            case SkCanvas::kTriangleStrip_VertexMode:
161932a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov            case SkCanvas::kTriangleFan_VertexMode:
1620a098dd490cc4e434f054b7506c2f6e08f519585bbsalomon                triangleCount = n - 2;
162132a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov                break;
162232a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        }
1623533eb782edaa0b6fece6166d3001edf72ec39f11mtklein
1624559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        VertState       state(vertexCount, indices, indexCount);
1625559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        VertState::Proc vertProc = state.chooseProc(vmode);
1626533eb782edaa0b6fece6166d3001edf72ec39f11mtklein
162732a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        //number of indices for lines per triangle with kLines
162832a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        indexCount = triangleCount * 6;
1629533eb782edaa0b6fece6166d3001edf72ec39f11mtklein
163032a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        outAlloc.reset(SkNEW_ARRAY(uint16_t, indexCount));
163132a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        outIndices = outAlloc.get();
163232a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        uint16_t* auxIndices = outAlloc.get();
1633559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        int i = 0;
1634559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        while (vertProc(&state)) {
163532a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov            auxIndices[i]     = state.f0;
163632a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov            auxIndices[i + 1] = state.f1;
163732a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov            auxIndices[i + 2] = state.f1;
163832a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov            auxIndices[i + 3] = state.f2;
163932a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov            auxIndices[i + 4] = state.f2;
164032a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov            auxIndices[i + 5] = state.f0;
1641559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org            i += 6;
1642559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        }
164311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
164432a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        outIndices = indices;
164532a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        primType = gVertexMode2PrimitiveType[vmode];
1646533eb782edaa0b6fece6166d3001edf72ec39f11mtklein
164732a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        if (NULL == texs || NULL == paint.getShader()) {
164832a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov            SkPaint2GrPaintNoShader(this->context(), paint, SkColor2GrColor(paint.getColor()),
164932a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov                                    NULL == colors, &grPaint);
165032a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        } else {
165132a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov            SkPaint2GrPaintShader(this->context(), paint, NULL == colors, &grPaint);
165232a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        }
165311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
165411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
16552583b6257fea931c31c6b3b75cc583106335ad90mtklein#if 0
165649f085dddff10473b6ebf832a974288300224e60bsalomon    if (xmode && texs && colors) {
165711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (!SkXfermode::IsMode(xmode, SkXfermode::kModulate_Mode)) {
165811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkDebugf("Unsupported vertex-color/texture xfer mode.\n");
16592583b6257fea931c31c6b3b75cc583106335ad90mtklein            return;
166011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
166111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
16622583b6257fea931c31c6b3b75cc583106335ad90mtklein#endif
166311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
166411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoSTMalloc<128, GrColor> convertedColors(0);
166549f085dddff10473b6ebf832a974288300224e60bsalomon    if (colors) {
166611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // need to convert byte order and from non-PM to PM
166711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        convertedColors.reset(vertexCount);
1668c93e68161f78542d90b28b6cf9911b1de3788054commit-bot@chromium.org        SkColor color;
166911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        for (int i = 0; i < vertexCount; ++i) {
1670c93e68161f78542d90b28b6cf9911b1de3788054commit-bot@chromium.org            color = colors[i];
1671c93e68161f78542d90b28b6cf9911b1de3788054commit-bot@chromium.org            if (paint.getAlpha() != 255) {
1672c93e68161f78542d90b28b6cf9911b1de3788054commit-bot@chromium.org                color = SkColorSetA(color, SkMulDiv255Round(SkColorGetA(color), paint.getAlpha()));
1673c93e68161f78542d90b28b6cf9911b1de3788054commit-bot@chromium.org            }
1674c93e68161f78542d90b28b6cf9911b1de3788054commit-bot@chromium.org            convertedColors[i] = SkColor2GrColor(color);
167511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
167611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        colors = convertedColors.get();
167711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
167811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext->drawVertices(grPaint,
167932a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov                           primType,
168011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           vertexCount,
1681972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org                           vertices,
1682972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org                           texs,
168311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           colors,
168432a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov                           outIndices,
168511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           indexCount);
168611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
168711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
168811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
168911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
169011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawText(const SkDraw& draw, const void* text,
169111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                          size_t byteLength, SkScalar x, SkScalar y,
169211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                          const SkPaint& paint) {
169311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_SHOULD_DRAW(draw, false);
1694d78a168ec2ec2c07c0c1845e6a1781988e4a52d9egdaniel    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawText", fContext);
169511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1696cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    if (fMainTextContext->canDraw(paint)) {
16978128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        GrPaint grPaint;
16983595f88aff0a1b490aa6661f0ba2d3534ee86353commit-bot@chromium.org        SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
16998128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
17008128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        SkDEBUGCODE(this->validate();)
17018128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
1702cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org        fMainTextContext->drawText(grPaint, paint, (const char *)text, byteLength, x, y);
1703cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    } else if (fFallbackTextContext && fFallbackTextContext->canDraw(paint)) {
17049f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org        GrPaint grPaint;
17053595f88aff0a1b490aa6661f0ba2d3534ee86353commit-bot@chromium.org        SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
17069f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org
17079f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org        SkDEBUGCODE(this->validate();)
17089f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org
1709cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org        fFallbackTextContext->drawText(grPaint, paint, (const char *)text, byteLength, x, y);
17109f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org    } else {
17119f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org        // this guy will just call our drawPath()
17129f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org        draw.drawText_asPaths((const char*)text, byteLength, x, y, paint);
171311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
171411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
171511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
171611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawPosText(const SkDraw& draw, const void* text,
171711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                             size_t byteLength, const SkScalar pos[],
171811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                             SkScalar constY, int scalarsPerPos,
171911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                             const SkPaint& paint) {
1720bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPosText", fContext);
172111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_SHOULD_DRAW(draw, false);
172211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1723cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    if (fMainTextContext->canDraw(paint)) {
17248128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        GrPaint grPaint;
17253595f88aff0a1b490aa6661f0ba2d3534ee86353commit-bot@chromium.org        SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
17268128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
17278128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        SkDEBUGCODE(this->validate();)
17288128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
17294c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com        fMainTextContext->drawPosText(grPaint, paint, (const char *)text, byteLength, pos,
1730cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org                                      constY, scalarsPerPos);
1731cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    } else if (fFallbackTextContext && fFallbackTextContext->canDraw(paint)) {
17329f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org        GrPaint grPaint;
17333595f88aff0a1b490aa6661f0ba2d3534ee86353commit-bot@chromium.org        SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
17344c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com
17359f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org        SkDEBUGCODE(this->validate();)
17364c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com
17374c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com        fFallbackTextContext->drawPosText(grPaint, paint, (const char *)text, byteLength, pos,
1738cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org                                          constY, scalarsPerPos);
17399f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org    } else {
17409f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org        draw.drawPosText_asPaths((const char*)text, byteLength, pos, constY,
17419f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org                                 scalarsPerPos, paint);
174211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
174311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
174411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
174511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawTextOnPath(const SkDraw& draw, const void* text,
174611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                size_t len, const SkPath& path,
174711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                const SkMatrix* m, const SkPaint& paint) {
174811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_SHOULD_DRAW(draw, false);
174911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
175011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkASSERT(draw.fDevice == this);
175111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    draw.drawTextOnPath((const char*)text, len, path, m, paint);
175211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
175311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
175411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
175511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
175611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.combool SkGpuDevice::filterTextFlags(const SkPaint& paint, TextFlags* flags) {
175711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (!paint.isLCDRenderText()) {
175811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // we're cool with the paint as is
175911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
176011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
176111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
176211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (paint.getShader() ||
176311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        paint.getXfermode() || // unless its srcover
176411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        paint.getMaskFilter() ||
176511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        paint.getRasterizer() ||
176611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        paint.getColorFilter() ||
176711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        paint.getPathEffect() ||
176811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        paint.isFakeBoldText() ||
176911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        paint.getStyle() != SkPaint::kFill_Style) {
17703375c8047e7f10e6bf9a2ce1c2e8b0df08c56024reed        // turn off lcd, but turn on kGenA8
177111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        flags->fFlags = paint.getFlags() & ~SkPaint::kLCDRenderText_Flag;
17723375c8047e7f10e6bf9a2ce1c2e8b0df08c56024reed        flags->fFlags |= SkPaint::kGenA8FromLCD_Flag;
177311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return true;
177411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
177511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // we're cool with the paint as is
177611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    return false;
177711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
177811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
177911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::flush() {
178011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    DO_DEFERRED_CLEAR();
178111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext->resolveRenderTarget(fRenderTarget);
178211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
178311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
178411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
178511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
178615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.orgSkBaseDevice* SkGpuDevice::onCreateDevice(const SkImageInfo& info, Usage usage) {
178711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTextureDesc desc;
178811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fConfig = fRenderTarget->config();
178911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fFlags = kRenderTarget_GrTextureFlagBit;
179015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    desc.fWidth = info.width();
179115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    desc.fHeight = info.height();
179211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fSampleCnt = fRenderTarget->numSamples();
179311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
179411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoTUnref<GrTexture> texture;
179511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // Skia's convention is to only clear a device if it is non-opaque.
1796d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org    unsigned flags = info.isOpaque() ? 0 : kNeedClear_Flag;
179711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
179811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#if CACHE_COMPATIBLE_DEVICE_TEXTURES
179911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // layers are never draw in repeat modes, so we can request an approx
180011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // match and ignore any padding.
1801d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org    flags |= kCached_Flag;
180211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    const GrContext::ScratchTexMatch match = (kSaveLayer_Usage == usage) ?
180311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                                GrContext::kApprox_ScratchTexMatch :
180411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                                GrContext::kExact_ScratchTexMatch;
180511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    texture.reset(fContext->lockAndRefScratchTexture(desc, match));
180611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#else
180711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    texture.reset(fContext->createUncachedTexture(desc, NULL, 0));
180811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#endif
180949f085dddff10473b6ebf832a974288300224e60bsalomon    if (texture.get()) {
18104a8126e7f81384526629b1e21bf89b632ea13cd9reed        return SkGpuDevice::Create(texture, SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType), flags);
181111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
181215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        GrPrintf("---- failed to create compatible device texture [%d %d]\n",
181315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org                 info.width(), info.height());
181411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return NULL;
181511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
181611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
181711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
18184a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurface* SkGpuDevice::newSurface(const SkImageInfo& info, const SkSurfaceProps& props) {
18194a8126e7f81384526629b1e21bf89b632ea13cd9reed    return SkSurface::NewRenderTarget(fContext, info, fRenderTarget->numSamples(), &props);
182076f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com}
182176f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com
18229b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillipsvoid SkGpuDevice::EXPERIMENTAL_optimize(const SkPicture* picture) {
1823d771f6bc273457bc7aa95938ac326dfbbf876e1arobertphillips    fContext->getLayerCache()->processDeletedPictures();
1824d771f6bc273457bc7aa95938ac326dfbbf876e1arobertphillips
182549f085dddff10473b6ebf832a974288300224e60bsalomon    if (picture->fData.get() && !picture->fData->suitableForLayerOptimization()) {
1826c019ec412ba2704bc6e2cdfd321ea06787ba415drobertphillips        return;
1827c019ec412ba2704bc6e2cdfd321ea06787ba415drobertphillips    }
1828c019ec412ba2704bc6e2cdfd321ea06787ba415drobertphillips
18296617d509ab0b056c57952bb1ee04b4c94904284brobertphillips    SkPicture::AccelData::Key key = GrAccelData::ComputeAccelDataKey();
1830145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org
18318ec8bab7780cc458ad53c3c44f2027fbc7c14a54commit-bot@chromium.org    const SkPicture::AccelData* existing = picture->EXPERIMENTAL_getAccelData(key);
183249f085dddff10473b6ebf832a974288300224e60bsalomon    if (existing) {
18338ec8bab7780cc458ad53c3c44f2027fbc7c14a54commit-bot@chromium.org        return;
18348ec8bab7780cc458ad53c3c44f2027fbc7c14a54commit-bot@chromium.org    }
18358ec8bab7780cc458ad53c3c44f2027fbc7c14a54commit-bot@chromium.org
1836d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips    GPUOptimize(picture);
1837d771f6bc273457bc7aa95938ac326dfbbf876e1arobertphillips
1838d771f6bc273457bc7aa95938ac326dfbbf876e1arobertphillips    fContext->getLayerCache()->trackPicture(picture);
1839145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org}
1840145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org
184130d2cc6ff47cb7f981d83e9a536971beec920f61robertphillipsbool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture* mainPicture,
184264bf76722ef06eabf51b55afda9f4ff431e41460robertphillips                                           const SkMatrix* matrix, const SkPaint* paint) {
184364bf76722ef06eabf51b55afda9f4ff431e41460robertphillips    // todo: should handle these natively
184464bf76722ef06eabf51b55afda9f4ff431e41460robertphillips    if (matrix || paint) {
184564bf76722ef06eabf51b55afda9f4ff431e41460robertphillips        return false;
184664bf76722ef06eabf51b55afda9f4ff431e41460robertphillips    }
184764bf76722ef06eabf51b55afda9f4ff431e41460robertphillips
184864bf76722ef06eabf51b55afda9f4ff431e41460robertphillips    fContext->getLayerCache()->processDeletedPictures();
184964bf76722ef06eabf51b55afda9f4ff431e41460robertphillips
185064bf76722ef06eabf51b55afda9f4ff431e41460robertphillips    SkRect clipBounds;
185164bf76722ef06eabf51b55afda9f4ff431e41460robertphillips    if (!mainCanvas->getClipBounds(&clipBounds)) {
185264bf76722ef06eabf51b55afda9f4ff431e41460robertphillips        return true;
185364bf76722ef06eabf51b55afda9f4ff431e41460robertphillips    }
185464bf76722ef06eabf51b55afda9f4ff431e41460robertphillips
185530d2cc6ff47cb7f981d83e9a536971beec920f61robertphillips    SkTDArray<GrLayerHoister::HoistedLayer> atlased, nonAtlased;
1856beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
185730d2cc6ff47cb7f981d83e9a536971beec920f61robertphillips    if (!GrLayerHoister::FindLayersToHoist(mainPicture, clipBounds, &atlased, &nonAtlased,
18581c4c528c2a5693c88ceb94888c747559c6a32091robertphillips                                           fContext->getLayerCache())) {
18591c4c528c2a5693c88ceb94888c747559c6a32091robertphillips        return false;
18600c4233285919c10df63c6cb207e580a7d1ff66b4robertphillips    }
1861952841bf41a81228c23d16c7204b458abe0d7136robertphillips
18624aa6dfc0b77af9ac298bb9d48991b72a2fec00b2robertphillips    GrReplacements replacements;
18634aa6dfc0b77af9ac298bb9d48991b72a2fec00b2robertphillips
186430d2cc6ff47cb7f981d83e9a536971beec920f61robertphillips    GrLayerHoister::DrawLayers(atlased, nonAtlased, &replacements);
18654aa6dfc0b77af9ac298bb9d48991b72a2fec00b2robertphillips
186664bf76722ef06eabf51b55afda9f4ff431e41460robertphillips    // Render the entire picture using new layers
186730d2cc6ff47cb7f981d83e9a536971beec920f61robertphillips    GrRecordReplaceDraw(*mainPicture->fRecord, mainCanvas, mainPicture->fBBH.get(),
186830d2cc6ff47cb7f981d83e9a536971beec920f61robertphillips                        &replacements, NULL);
186964bf76722ef06eabf51b55afda9f4ff431e41460robertphillips
187030d2cc6ff47cb7f981d83e9a536971beec920f61robertphillips    GrLayerHoister::UnlockLayers(fContext->getLayerCache(), atlased, nonAtlased);
187164bf76722ef06eabf51b55afda9f4ff431e41460robertphillips
187264bf76722ef06eabf51b55afda9f4ff431e41460robertphillips    return true;
187364bf76722ef06eabf51b55afda9f4ff431e41460robertphillips}
187464bf76722ef06eabf51b55afda9f4ff431e41460robertphillips
1875be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblancoSkImageFilter::Cache* SkGpuDevice::getImageFilterCache() {
187655b6d8be997a447ef9ce0f029697677a940bfc24senorblanco    // We always return a transient cache, so it is freed after each
187755b6d8be997a447ef9ce0f029697677a940bfc24senorblanco    // filter traversal.
1878be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblanco    return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize);
187955b6d8be997a447ef9ce0f029697677a940bfc24senorblanco}
1880