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"
198ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org#include "GrPictureUtils.h"
20d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel#include "GrStrokeInfo.h"
21bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel#include "GrTracing.h"
2211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
2311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkGrTexturePixelRef.h"
2411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
2511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkDeviceImageFilterProxy.h"
2611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkDrawProcs.h"
2711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkGlyphCache.h"
2811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkImageFilter.h"
29821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org#include "SkMaskFilter.h"
3011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkPathEffect.h"
31145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org#include "SkPicture.h"
32beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com#include "SkPicturePlayback.h"
3311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkRRect.h"
3411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkStroke.h"
3576f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com#include "SkSurface.h"
36a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org#include "SkTLazy.h"
3711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkUtils.h"
38559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org#include "SkVertState.h"
3911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkErrorInternals.h"
4011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
4111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#define CACHE_COMPATIBLE_DEVICE_TEXTURES 1
4211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
4311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#if 0
4411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    extern bool (*gShouldDrawProc)();
4511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    #define CHECK_SHOULD_DRAW(draw, forceI)                     \
4611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        do {                                                    \
4711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            if (gShouldDrawProc && !gShouldDrawProc()) return;  \
4811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            this->prepareDraw(draw, forceI);                    \
4911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        } while (0)
5011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#else
5111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    #define CHECK_SHOULD_DRAW(draw, forceI) this->prepareDraw(draw, forceI)
5211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#endif
5311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
5411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// This constant represents the screen alignment criterion in texels for
5511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// requiring texture domain clamping to prevent color bleeding when drawing
5611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// a sub region of a larger source image.
574b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org#define COLOR_BLEED_TOLERANCE 0.001f
5811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
5911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#define DO_DEFERRED_CLEAR()             \
6011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    do {                                \
6111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (fNeedClear) {               \
6211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            this->clear(SK_ColorTRANSPARENT); \
6311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }                               \
6411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } while (false)                     \
6511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
6611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
6711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
6811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#define CHECK_FOR_ANNOTATION(paint) \
6911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    do { if (paint.getAnnotation()) { return; } } while (0)
7011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
7111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
7211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
7311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
7411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comclass SkGpuDevice::SkAutoCachedTexture : public ::SkNoncopyable {
7511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.compublic:
7611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoCachedTexture()
7711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        : fDevice(NULL)
7811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        , fTexture(NULL) {
7911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
8011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
8111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoCachedTexture(SkGpuDevice* device,
8211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                        const SkBitmap& bitmap,
8311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                        const GrTextureParams* params,
8411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                        GrTexture** texture)
8511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        : fDevice(NULL)
8611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        , fTexture(NULL) {
8711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkASSERT(NULL != texture);
8811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        *texture = this->set(device, bitmap, params);
8911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
9011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
9111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    ~SkAutoCachedTexture() {
9211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (NULL != fTexture) {
9311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            GrUnlockAndUnrefCachedBitmapTexture(fTexture);
9411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
9511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
9611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
9711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTexture* set(SkGpuDevice* device,
9811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                   const SkBitmap& bitmap,
9911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                   const GrTextureParams* params) {
10011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (NULL != fTexture) {
10111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            GrUnlockAndUnrefCachedBitmapTexture(fTexture);
10211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            fTexture = NULL;
10311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
10411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        fDevice = device;
10511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        GrTexture* result = (GrTexture*)bitmap.getTexture();
10611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (NULL == result) {
10711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            // Cannot return the native texture so look it up in our cache
10811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            fTexture = GrLockAndRefCachedBitmapTexture(device->context(), bitmap, params);
10911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            result = fTexture;
11011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
11111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return result;
11211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
11311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
11411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comprivate:
11511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkGpuDevice* fDevice;
11611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTexture*   fTexture;
11711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com};
11811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
11911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
12011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
12111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comstruct GrSkDrawProcs : public SkDrawProcs {
12211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.compublic:
12311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrContext* fContext;
12411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTextContext* fTextContext;
12511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrFontScaler* fFontScaler;  // cached in the skia glyphcache
12611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com};
12711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
12811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
12911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
13011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com/*
13111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com * GrRenderTarget does not know its opaqueness, only its config, so we have
13211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com * to make conservative guesses when we return an "equivalent" bitmap.
13311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com */
13411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comstatic SkBitmap make_bitmap(GrContext* context, GrRenderTarget* renderTarget) {
13511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkBitmap bitmap;
1366c22573edb234ad14df947278cfed010669a39a7reed    bitmap.setInfo(renderTarget->info());
13711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    return bitmap;
13811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
13911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
140d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.orgSkGpuDevice* SkGpuDevice::Create(GrSurface* surface, unsigned flags) {
14111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkASSERT(NULL != surface);
14211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (NULL == surface->asRenderTarget() || NULL == surface->getContext()) {
14311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return NULL;
14411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
14511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (surface->asTexture()) {
146d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org        return SkNEW_ARGS(SkGpuDevice, (surface->getContext(), surface->asTexture(), flags));
14711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
148d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org        return SkNEW_ARGS(SkGpuDevice, (surface->getContext(), surface->asRenderTarget(), flags));
14911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
15011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
15111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
152d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.orgSkGpuDevice::SkGpuDevice(GrContext* context, GrTexture* texture, unsigned flags)
15311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    : SkBitmapDevice(make_bitmap(context, texture->asRenderTarget())) {
154d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org    this->initFromRenderTarget(context, texture->asRenderTarget(), flags);
15511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
15611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
157d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.orgSkGpuDevice::SkGpuDevice(GrContext* context, GrRenderTarget* renderTarget, unsigned flags)
15811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    : SkBitmapDevice(make_bitmap(context, renderTarget)) {
159d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org    this->initFromRenderTarget(context, renderTarget, flags);
16011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
16111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
16211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::initFromRenderTarget(GrContext* context,
16311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                       GrRenderTarget* renderTarget,
164d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org                                       unsigned flags) {
16511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fDrawProcs = NULL;
16611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
16711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext = context;
16811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext->ref();
16911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1706fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org    bool useDFFonts = !!(flags & kDFFonts_Flag);
1716fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org    fMainTextContext = SkNEW_ARGS(GrDistanceFieldTextContext, (fContext, fLeakyProperties,
1726fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org                                                               useDFFonts));
1734784182993a336b673619f3eb13ce2539aa890dacommit-bot@chromium.org    fFallbackTextContext = SkNEW_ARGS(GrBitmapTextContext, (fContext, fLeakyProperties));
1744784182993a336b673619f3eb13ce2539aa890dacommit-bot@chromium.org
17511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fRenderTarget = NULL;
176d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org    fNeedClear = flags & kNeedClear_Flag;
17711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
17811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkASSERT(NULL != renderTarget);
17911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fRenderTarget = renderTarget;
18011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fRenderTarget->ref();
18111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
18211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // Hold onto to the texture in the pixel ref (if there is one) because the texture holds a ref
18311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // on the RT but not vice-versa.
18411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // TODO: Remove this trickery once we figure out how to make SkGrPixelRef do this without
18511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // busting chrome (for a currently unknown reason).
18611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrSurface* surface = fRenderTarget->asTexture();
18711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (NULL == surface) {
18811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        surface = fRenderTarget;
18911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
190bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com
1916c22573edb234ad14df947278cfed010669a39a7reed    SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef,
1926c22573edb234ad14df947278cfed010669a39a7reed                                (surface->info(), surface, SkToBool(flags & kCached_Flag)));
19311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
194672588b684d484dce6ae251e9e163e4a46924322reed@google.com    this->setPixelRef(pr)->unref();
19511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
19611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
19715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.orgSkGpuDevice* SkGpuDevice::Create(GrContext* context, const SkImageInfo& origInfo,
19815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org                                 int sampleCount) {
19915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    if (kUnknown_SkColorType == origInfo.colorType() ||
20015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        origInfo.width() < 0 || origInfo.height() < 0) {
20115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        return NULL;
20215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    }
20315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org
20415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    SkImageInfo info = origInfo;
20515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    // TODO: perhas we can loosen this check now that colortype is more detailed
20615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    // e.g. can we support both RGBA and BGRA here?
20715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    if (kRGB_565_SkColorType == info.colorType()) {
20815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        info.fAlphaType = kOpaque_SkAlphaType;  // force this setting
20915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    } else {
21028fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org        info.fColorType = kN32_SkColorType;
21115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        if (kOpaque_SkAlphaType != info.alphaType()) {
21215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org            info.fAlphaType = kPremul_SkAlphaType;  // force this setting
21315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        }
21415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    }
21515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org
21615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    GrTextureDesc desc;
21715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    desc.fFlags = kRenderTarget_GrTextureFlagBit;
21815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    desc.fWidth = info.width();
21915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    desc.fHeight = info.height();
2203adcc3403377c0b9a7afde6db8e0432325413a10commit-bot@chromium.org    desc.fConfig = SkImageInfo2GrPixelConfig(info);
22115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    desc.fSampleCnt = sampleCount;
22215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org
22315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    SkAutoTUnref<GrTexture> texture(context->createUncachedTexture(desc, NULL, 0));
22415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    if (!texture.get()) {
22515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        return NULL;
22615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    }
227969588f0c9030d5a4942085a4b5a5ea7e8d2bc25skia.committer@gmail.com
22815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    return SkNEW_ARGS(SkGpuDevice, (context, texture.get()));
22915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org}
23015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org
23111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comSkGpuDevice::~SkGpuDevice() {
23211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (fDrawProcs) {
23311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        delete fDrawProcs;
23411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
235d2ac07b64b7d46e81d00d389781f9f83810f0095skia.committer@gmail.com
236cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    delete fMainTextContext;
237cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    delete fFallbackTextContext;
23811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
23911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // The GrContext takes a ref on the target. We don't want to cause the render
24011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // target to be unnecessarily kept alive.
24111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (fContext->getRenderTarget() == fRenderTarget) {
24211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        fContext->setRenderTarget(NULL);
24311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
24411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
24511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (fContext->getClip() == &fClipData) {
24611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        fContext->setClip(NULL);
24711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
24811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
24911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkSafeUnref(fRenderTarget);
25011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext->unref();
25111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
25211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
25311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
25411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
25511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::makeRenderTargetCurrent() {
25611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    DO_DEFERRED_CLEAR();
25711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext->setRenderTarget(fRenderTarget);
25811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
25911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
26011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
26111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
262a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.orgbool SkGpuDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
263a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org                               int x, int y) {
264a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    DO_DEFERRED_CLEAR();
265a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org
266a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    // TODO: teach fRenderTarget to take ImageInfo directly to specify the src pixels
2673adcc3403377c0b9a7afde6db8e0432325413a10commit-bot@chromium.org    GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo);
268a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    if (kUnknown_GrPixelConfig == config) {
269a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org        return false;
270a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    }
271a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org
272a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    uint32_t flags = 0;
273a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    if (kUnpremul_SkAlphaType == dstInfo.alphaType()) {
274a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org        flags = GrContext::kUnpremul_PixelOpsFlag;
275a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    }
276a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    return fContext->readRenderTargetPixels(fRenderTarget, x, y, dstInfo.width(), dstInfo.height(),
277a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org                                            config, dstPixels, dstRowBytes, flags);
278a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org}
27911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
2804cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkGpuDevice::onWritePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes,
2814cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org                                int x, int y) {
2824cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    // TODO: teach fRenderTarget to take ImageInfo directly to specify the src pixels
2833adcc3403377c0b9a7afde6db8e0432325413a10commit-bot@chromium.org    GrPixelConfig config = SkImageInfo2GrPixelConfig(info);
2844cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    if (kUnknown_GrPixelConfig == config) {
2854cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org        return false;
2864cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    }
2874cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    uint32_t flags = 0;
2884cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    if (kUnpremul_SkAlphaType == info.alphaType()) {
2894cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org        flags = GrContext::kUnpremul_PixelOpsFlag;
2904cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    }
2914cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    fRenderTarget->writePixels(x, y, info.width(), info.height(), config, pixels, rowBytes, flags);
2924cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org
2934cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    // need to bump our genID for compatibility with clients that "know" we have a bitmap
2944cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    this->onAccessBitmap().notifyPixelsChanged();
2954cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org
2964cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    return true;
2974cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org}
29811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
299b7b7eb32f41729c136c939702b0c9a484accb541senorblanco@chromium.orgconst SkBitmap& SkGpuDevice::onAccessBitmap() {
300b7b7eb32f41729c136c939702b0c9a484accb541senorblanco@chromium.org    DO_DEFERRED_CLEAR();
301b7b7eb32f41729c136c939702b0c9a484accb541senorblanco@chromium.org    return INHERITED::onAccessBitmap();
302b7b7eb32f41729c136c939702b0c9a484accb541senorblanco@chromium.org}
303b7b7eb32f41729c136c939702b0c9a484accb541senorblanco@chromium.org
30411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::onAttachToCanvas(SkCanvas* canvas) {
30511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    INHERITED::onAttachToCanvas(canvas);
30611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
30711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // Canvas promises that this ptr is valid until onDetachFromCanvas is called
30811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fClipData.fClipStack = canvas->getClipStack();
30911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
31011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
31111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::onDetachFromCanvas() {
31211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    INHERITED::onDetachFromCanvas();
31311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fClipData.fClipStack = NULL;
31411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
31511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
31611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// call this every draw call, to ensure that the context reflects our state,
31711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// and not the state from some other canvas/device
31811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::prepareDraw(const SkDraw& draw, bool forceIdentity) {
31911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkASSERT(NULL != fClipData.fClipStack);
32011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
32111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext->setRenderTarget(fRenderTarget);
32211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
32311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkASSERT(draw.fClipStack && draw.fClipStack == fClipData.fClipStack);
32411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
32511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (forceIdentity) {
32611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        fContext->setIdentityMatrix();
32711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
32811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        fContext->setMatrix(*draw.fMatrix);
32911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
33011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fClipData.fOrigin = this->getOrigin();
33111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
33211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext->setClip(&fClipData);
33311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
33411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    DO_DEFERRED_CLEAR();
33511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
33611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
33711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comGrRenderTarget* SkGpuDevice::accessRenderTarget() {
33811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    DO_DEFERRED_CLEAR();
33911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    return fRenderTarget;
34011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
34111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
34211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
34311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
34411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comSK_COMPILE_ASSERT(SkShader::kNone_BitmapType == 0, shader_type_mismatch);
34511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comSK_COMPILE_ASSERT(SkShader::kDefault_BitmapType == 1, shader_type_mismatch);
34611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comSK_COMPILE_ASSERT(SkShader::kRadial_BitmapType == 2, shader_type_mismatch);
34711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comSK_COMPILE_ASSERT(SkShader::kSweep_BitmapType == 3, shader_type_mismatch);
34811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comSK_COMPILE_ASSERT(SkShader::kTwoPointRadial_BitmapType == 4,
34911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                  shader_type_mismatch);
35011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comSK_COMPILE_ASSERT(SkShader::kTwoPointConical_BitmapType == 5,
35111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                  shader_type_mismatch);
35211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comSK_COMPILE_ASSERT(SkShader::kLinear_BitmapType == 6, shader_type_mismatch);
35311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comSK_COMPILE_ASSERT(SkShader::kLast_BitmapType == 6, shader_type_mismatch);
35411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
35511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
35611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
35711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::clear(SkColor color) {
35811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkIRect rect = SkIRect::MakeWH(this->width(), this->height());
35911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext->clear(&rect, SkColor2GrColor(color), true, fRenderTarget);
36011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fNeedClear = false;
36111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
36211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
36311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
36411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_SHOULD_DRAW(draw, false);
36511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
36611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint grPaint;
3673595f88aff0a1b490aa6661f0ba2d3534ee86353commit-bot@chromium.org    SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
36811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
36911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext->drawPaint(grPaint);
37011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
37111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
37211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// must be in SkCanvas::PointMode order
37311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comstatic const GrPrimitiveType gPointMode2PrimtiveType[] = {
37411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    kPoints_GrPrimitiveType,
37511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    kLines_GrPrimitiveType,
37611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    kLineStrip_GrPrimitiveType
37711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com};
37811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
37911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
38011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                             size_t count, const SkPoint pts[], const SkPaint& paint) {
38111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_FOR_ANNOTATION(paint);
38211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_SHOULD_DRAW(draw, false);
38311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
38411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkScalar width = paint.getStrokeWidth();
38511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (width < 0) {
38611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
38711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
38811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
389628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org    if (paint.getPathEffect() && 2 == count && SkCanvas::kLines_PointMode == mode) {
390e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel        GrStrokeInfo strokeInfo(paint, SkPaint::kStroke_Style);
391e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel        GrPaint grPaint;
392e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel        SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
393e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel        SkPath path;
394e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel        path.moveTo(pts[0]);
395e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel        path.lineTo(pts[1]);
396e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel        fContext->drawPath(grPaint, path, strokeInfo);
397e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel        return;
398628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org    }
399628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org
40011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // we only handle hairlines and paints without path effects or mask filters,
40111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // else we let the SkDraw call our drawPath()
40211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (width > 0 || paint.getPathEffect() || paint.getMaskFilter()) {
40311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        draw.drawPoints(mode, count, pts, paint, true);
40411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
40511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
40611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
40711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint grPaint;
4083595f88aff0a1b490aa6661f0ba2d3534ee86353commit-bot@chromium.org    SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
40911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
41011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext->drawVertices(grPaint,
41111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           gPointMode2PrimtiveType[mode],
412a4662865e37a2ca95b5e3379072f6a274acc8ac8robertphillips@google.com                           SkToS32(count),
413972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org                           (SkPoint*)pts,
41411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           NULL,
41511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           NULL,
41611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           NULL,
41711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           0);
41811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
41911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
42011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
42111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
42211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect,
42311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           const SkPaint& paint) {
424bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawRect", fContext);
425bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel
42611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_FOR_ANNOTATION(paint);
42711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_SHOULD_DRAW(draw, false);
42811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
42911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    bool doStroke = paint.getStyle() != SkPaint::kFill_Style;
43011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkScalar width = paint.getStrokeWidth();
43111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
43211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    /*
43311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        We have special code for hairline strokes, miter-strokes, bevel-stroke
43411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        and fills. Anything else we just call our path code.
43511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com     */
43611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    bool usePath = doStroke && width > 0 &&
43711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                   (paint.getStrokeJoin() == SkPaint::kRound_Join ||
43811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    (paint.getStrokeJoin() == SkPaint::kBevel_Join && rect.isEmpty()));
43911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // another two reasons we might need to call drawPath...
440d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
441d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    if (paint.getMaskFilter()) {
44211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        usePath = true;
44311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
444d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
44511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (!usePath && paint.isAntiAlias() && !fContext->getMatrix().rectStaysRect()) {
44611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT)
44711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (doStroke) {
44811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#endif
44911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            usePath = true;
45011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT)
45111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        } else {
45211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            usePath = !fContext->getMatrix().preservesRightAngles();
45311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
45411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#endif
45511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
45611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // until we can both stroke and fill rectangles
45711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (paint.getStyle() == SkPaint::kStrokeAndFill_Style) {
45811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        usePath = true;
45911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
46011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
461d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    GrStrokeInfo strokeInfo(paint);
462d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
463d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    const SkPathEffect* pe = paint.getPathEffect();
464d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    if (!usePath && NULL != pe && !strokeInfo.isDashed()) {
465d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        usePath = true;
466d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    }
467d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
46811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (usePath) {
46911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkPath path;
47011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        path.addRect(rect);
47111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        this->drawPath(draw, path, paint, NULL, true);
47211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
47311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
47411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
47511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint grPaint;
4763595f88aff0a1b490aa6661f0ba2d3534ee86353commit-bot@chromium.org    SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
477d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
478d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    fContext->drawRect(grPaint, rect, &strokeInfo);
47911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
48011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
48111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
48211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
48311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rect,
48411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           const SkPaint& paint) {
48511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_FOR_ANNOTATION(paint);
48611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_SHOULD_DRAW(draw, false);
48711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
488821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org    GrPaint grPaint;
4893595f88aff0a1b490aa6661f0ba2d3534ee86353commit-bot@chromium.org    SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
490d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
491d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    GrStrokeInfo strokeInfo(paint);
492821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org    if (paint.getMaskFilter()) {
493821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org        // try to hit the fast path for drawing filtered round rects
494821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org
495821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org        SkRRect devRRect;
496821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org        if (rect.transform(fContext->getMatrix(), &devRRect)) {
497821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org            if (devRRect.allCornersCircular()) {
498821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                SkRect maskRect;
499821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                if (paint.getMaskFilter()->canFilterMaskGPU(devRRect.rect(),
500821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                                            draw.fClip->getBounds(),
501821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                                            fContext->getMatrix(),
502821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                                            &maskRect)) {
503821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                    SkIRect finalIRect;
504821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                    maskRect.roundOut(&finalIRect);
505821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                    if (draw.fClip->quickReject(finalIRect)) {
506821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                        // clipped out
507821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                        return;
508821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                    }
509821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                    if (paint.getMaskFilter()->directFilterRRectMaskGPU(fContext, &grPaint,
510d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel                                                                        strokeInfo.getStrokeRec(),
511d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel                                                                        devRRect)) {
512821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                        return;
513821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                    }
514821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                }
515821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org
516821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org            }
517821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org        }
518821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org
519821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org    }
520821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org
521d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    bool usePath = false;
522d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
523d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    if (paint.getMaskFilter()) {
524d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        usePath = true;
525d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    } else {
526d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        const SkPathEffect* pe = paint.getPathEffect();
527d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        if (NULL != pe && !strokeInfo.isDashed()) {
528d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel            usePath = true;
529d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        }
530d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    }
531d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
532d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
533d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    if (usePath) {
53411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkPath path;
53511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        path.addRRect(rect);
53611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        this->drawPath(draw, path, paint, NULL, true);
53711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
53811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
539d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
540d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    fContext->drawRRect(grPaint, rect, strokeInfo);
54111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
54211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
5430a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.orgvoid SkGpuDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
5440a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org                              const SkRRect& inner, const SkPaint& paint) {
5450a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    SkStrokeRec stroke(paint);
5460a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    if (stroke.isFillStyle()) {
5470a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
5480a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        CHECK_FOR_ANNOTATION(paint);
5490a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        CHECK_SHOULD_DRAW(draw, false);
5500a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
5510a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        GrPaint grPaint;
5523595f88aff0a1b490aa6661f0ba2d3534ee86353commit-bot@chromium.org        SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
5530a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
5540a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        if (NULL == paint.getMaskFilter() && NULL == paint.getPathEffect()) {
5550a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org            fContext->drawDRRect(grPaint, outer, inner);
5560a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org            return;
5570a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        }
5580a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    }
5590a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
5600a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    SkPath path;
5610a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    path.addRRect(outer);
5620a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    path.addRRect(inner);
5630a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    path.setFillType(SkPath::kEvenOdd_FillType);
5640a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
5650a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    this->drawPath(draw, path, paint, NULL, true);
5660a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org}
5670a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
5680a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
569821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////
57011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
57111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawOval(const SkDraw& draw, const SkRect& oval,
57211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           const SkPaint& paint) {
57311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_FOR_ANNOTATION(paint);
57411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_SHOULD_DRAW(draw, false);
57511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
576d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    GrStrokeInfo strokeInfo(paint);
577d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
57811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    bool usePath = false;
57911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // some basic reasons we might need to call drawPath...
580d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    if (paint.getMaskFilter()) {
58111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        usePath = true;
582d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    } else {
583d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        const SkPathEffect* pe = paint.getPathEffect();
584d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        if (NULL != pe && !strokeInfo.isDashed()) {
585d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel            usePath = true;
586d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        }
58711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
58811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
58911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (usePath) {
59011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkPath path;
59111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        path.addOval(oval);
59211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        this->drawPath(draw, path, paint, NULL, true);
59311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
59411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
59511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
59611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint grPaint;
5973595f88aff0a1b490aa6661f0ba2d3534ee86353commit-bot@chromium.org    SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
59811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
599d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    fContext->drawOval(grPaint, oval, strokeInfo);
60011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
60111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
60211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkMaskFilter.h"
60311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
60411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
60511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
60611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// helpers for applying mask filters
60711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comnamespace {
60811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
60911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// Draw a mask using the supplied paint. Since the coverage/geometry
61011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// is already burnt into the mask this boils down to a rect draw.
61111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// Return true if the mask was successfully drawn.
61211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.combool draw_mask(GrContext* context, const SkRect& maskRect,
61311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com               GrPaint* grp, GrTexture* mask) {
61411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrContext::AutoMatrix am;
61511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (!am.setIdentity(context, grp)) {
61611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
61711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
61811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
61911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkMatrix matrix;
62011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    matrix.setTranslate(-maskRect.fLeft, -maskRect.fTop);
62111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    matrix.postIDiv(mask->width(), mask->height());
62211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
62311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    grp->addCoverageEffect(GrSimpleTextureEffect::Create(mask, matrix))->unref();
62411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    context->drawRect(*grp, maskRect);
62511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    return true;
62611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
62711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
62811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.combool draw_with_mask_filter(GrContext* context, const SkPath& devPath,
629868074b50b0fc3e460d2aa97c1096827fe0a1935reed                           SkMaskFilter* filter, const SkRegion& clip,
63011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           GrPaint* grp, SkPaint::Style style) {
63111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkMask  srcM, dstM;
63211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
63311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (!SkDraw::DrawToMask(devPath, &clip.getBounds(), filter, &context->getMatrix(), &srcM,
63411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                            SkMask::kComputeBoundsAndRenderImage_CreateMode, style)) {
63511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
63611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
63711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoMaskFreeImage autoSrc(srcM.fImage);
63811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
63911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (!filter->filterMask(&dstM, srcM, context->getMatrix(), NULL)) {
64011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
64111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
64211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // this will free-up dstM when we're done (allocated in filterMask())
64311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoMaskFreeImage autoDst(dstM.fImage);
64411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
64511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (clip.quickReject(dstM.fBounds)) {
64611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
64711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
64811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
64911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // we now have a device-aligned 8bit mask in dstM, ready to be drawn using
65011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // the current clip (and identity matrix) and GrPaint settings
65111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTextureDesc desc;
65211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fWidth = dstM.fBounds.width();
65311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fHeight = dstM.fBounds.height();
65411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fConfig = kAlpha_8_GrPixelConfig;
65511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
65611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrAutoScratchTexture ast(context, desc);
65711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTexture* texture = ast.texture();
65811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
65911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (NULL == texture) {
66011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
66111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
66211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
66311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                               dstM.fImage, dstM.fRowBytes);
66411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
66511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect maskRect = SkRect::Make(dstM.fBounds);
66611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
66711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    return draw_mask(context, maskRect, grp, texture);
66811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
66911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
67011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// Create a mask of 'devPath' and place the result in 'mask'. Return true on
67111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// success; false otherwise.
67211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.combool create_mask_GPU(GrContext* context,
67311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                     const SkRect& maskRect,
67411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                     const SkPath& devPath,
675d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel                     const GrStrokeInfo& strokeInfo,
67611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                     bool doAA,
67711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                     GrAutoScratchTexture* mask) {
67811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTextureDesc desc;
67911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fFlags = kRenderTarget_GrTextureFlagBit;
68011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fWidth = SkScalarCeilToInt(maskRect.width());
68111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fHeight = SkScalarCeilToInt(maskRect.height());
68211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // We actually only need A8, but it often isn't supported as a
68311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // render target so default to RGBA_8888
68411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fConfig = kRGBA_8888_GrPixelConfig;
68511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (context->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
68611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        desc.fConfig = kAlpha_8_GrPixelConfig;
68711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
68811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
68911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    mask->set(context, desc);
69011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (NULL == mask->texture()) {
69111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
69211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
69311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
69411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTexture* maskTexture = mask->texture();
69511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect clipRect = SkRect::MakeWH(maskRect.width(), maskRect.height());
69611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
69711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrContext::AutoRenderTarget art(context, maskTexture->asRenderTarget());
69811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrContext::AutoClip ac(context, clipRect);
69911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
70011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    context->clear(NULL, 0x0, true);
70111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
70211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint tempPaint;
70311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (doAA) {
70411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        tempPaint.setAntiAlias(true);
70511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // AA uses the "coverage" stages on GrDrawTarget. Coverage with a dst
70611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // blend coeff of zero requires dual source blending support in order
70711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // to properly blend partially covered pixels. This means the AA
70811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // code path may not be taken. So we use a dst blend coeff of ISA. We
70911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // could special case AA draws to a dst surface with known alpha=0 to
71011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // use a zero dst coeff when dual source blending isn't available.
71111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        tempPaint.setBlendFunc(kOne_GrBlendCoeff, kISC_GrBlendCoeff);
71211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
71311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
71411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrContext::AutoMatrix am;
71511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
71611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // Draw the mask into maskTexture with the path's top-left at the origin using tempPaint.
71711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkMatrix translate;
71811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    translate.setTranslate(-maskRect.fLeft, -maskRect.fTop);
71911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    am.set(context, translate);
720d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    context->drawPath(tempPaint, devPath, strokeInfo);
72111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    return true;
72211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
72311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
72411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comSkBitmap wrap_texture(GrTexture* texture) {
72511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkBitmap result;
7266c22573edb234ad14df947278cfed010669a39a7reed    result.setInfo(texture->info());
7276c22573edb234ad14df947278cfed010669a39a7reed    result.setPixelRef(SkNEW_ARGS(SkGrPixelRef, (result.info(), texture)))->unref();
72811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    return result;
72911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
73011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
73111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com};
73211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
73311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
73411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           const SkPaint& paint, const SkMatrix* prePathMatrix,
73511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           bool pathIsMutable) {
73611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_FOR_ANNOTATION(paint);
73711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_SHOULD_DRAW(draw, false);
73811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
73911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint grPaint;
7403595f88aff0a1b490aa6661f0ba2d3534ee86353commit-bot@chromium.org    SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
74111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
74211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // If we have a prematrix, apply it to the path, optimizing for the case
74311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // where the original path can in fact be modified in place (even though
74411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // its parameter type is const).
74511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkPath* pathPtr = const_cast<SkPath*>(&origSrcPath);
746f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org    SkTLazy<SkPath> tmpPath;
747f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org    SkTLazy<SkPath> effectPath;
74811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
74911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (prePathMatrix) {
75011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkPath* result = pathPtr;
75111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
75211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (!pathIsMutable) {
753f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org            result = tmpPath.init();
75411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            pathIsMutable = true;
75511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
75611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // should I push prePathMatrix on our MV stack temporarily, instead
75711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // of applying it here? See SkDraw.cpp
75811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        pathPtr->transform(*prePathMatrix, result);
75911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        pathPtr = result;
76011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
76111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // at this point we're done with prePathMatrix
76211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;)
76311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
764d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    GrStrokeInfo strokeInfo(paint);
76511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkPathEffect* pathEffect = paint.getPathEffect();
76611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    const SkRect* cullRect = NULL;  // TODO: what is our bounds?
767d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    SkStrokeRec* strokePtr = strokeInfo.getStrokeRecPtr();
768d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    if (pathEffect && pathEffect->filterPath(effectPath.init(), *pathPtr, strokePtr,
76911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                             cullRect)) {
770f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org        pathPtr = effectPath.get();
771f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org        pathIsMutable = true;
772d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        strokeInfo.removeDash();
77311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
77411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
775d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    const SkStrokeRec& stroke = strokeInfo.getStrokeRec();
77611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (paint.getMaskFilter()) {
77711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (!stroke.isHairlineStyle()) {
778f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org            SkPath* strokedPath = pathIsMutable ? pathPtr : tmpPath.init();
779f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org            if (stroke.applyToPath(strokedPath, *pathPtr)) {
780f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org                pathPtr = strokedPath;
78111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                pathIsMutable = true;
782d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel                strokeInfo.setFillStyle();
78311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
78411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
78511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
78611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // avoid possibly allocating a new path in transform if we can
787f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org        SkPath* devPathPtr = pathIsMutable ? pathPtr : tmpPath.init();
78811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
78911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // transform the path into device space
79011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        pathPtr->transform(fContext->getMatrix(), devPathPtr);
7914c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com
79211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkRect maskRect;
79311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (paint.getMaskFilter()->canFilterMaskGPU(devPathPtr->getBounds(),
79411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                                    draw.fClip->getBounds(),
79511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                                    fContext->getMatrix(),
79611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                                    &maskRect)) {
797439ff1b9ca2b74a9dc3b04346aa1032c11b142e9commit-bot@chromium.org            // The context's matrix may change while creating the mask, so save the CTM here to
798439ff1b9ca2b74a9dc3b04346aa1032c11b142e9commit-bot@chromium.org            // pass to filterMaskGPU.
799439ff1b9ca2b74a9dc3b04346aa1032c11b142e9commit-bot@chromium.org            const SkMatrix ctm = fContext->getMatrix();
800439ff1b9ca2b74a9dc3b04346aa1032c11b142e9commit-bot@chromium.org
80111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkIRect finalIRect;
80211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            maskRect.roundOut(&finalIRect);
80311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            if (draw.fClip->quickReject(finalIRect)) {
80411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                // clipped out
80511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                return;
80611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
8074c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com
808cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org            if (paint.getMaskFilter()->directFilterMaskGPU(fContext, &grPaint,
809821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                                                           stroke, *devPathPtr)) {
810cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org                // the mask filter was able to draw itself directly, so there's nothing
811cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org                // left to do.
812cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org                return;
813cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org            }
81411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
81511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            GrAutoScratchTexture mask;
81611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
817d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel            if (create_mask_GPU(fContext, maskRect, *devPathPtr, strokeInfo,
81811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                grPaint.isAntiAlias(), &mask)) {
81911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                GrTexture* filtered;
82011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
82141bf930039314cc71039b12957195f1c65c30ce1commit-bot@chromium.org                if (paint.getMaskFilter()->filterMaskGPU(mask.texture(),
822439ff1b9ca2b74a9dc3b04346aa1032c11b142e9commit-bot@chromium.org                                                         ctm, maskRect, &filtered, true)) {
82311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    // filterMaskGPU gives us ownership of a ref to the result
82411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    SkAutoTUnref<GrTexture> atu(filtered);
82511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
82611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    // If the scratch texture that we used as the filter src also holds the filter
82711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    // result then we must detach so that this texture isn't recycled for a later
82811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    // draw.
82911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    if (filtered == mask.texture()) {
83011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                        mask.detach();
83111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                        filtered->unref(); // detach transfers GrAutoScratchTexture's ref to us.
83211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    }
83311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
83411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    if (draw_mask(fContext, maskRect, &grPaint, filtered)) {
83511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                        // This path is completely drawn
83611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                        return;
83711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    }
83811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                }
83911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
84011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
84111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
84211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // draw the mask on the CPU - this is a fallthrough path in case the
84311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // GPU path fails
84411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkPaint::Style style = stroke.isHairlineStyle() ? SkPaint::kStroke_Style :
84511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                                          SkPaint::kFill_Style;
846d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        draw_with_mask_filter(fContext, *devPathPtr, paint.getMaskFilter(),
847d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel                              *draw.fClip, &grPaint, style);
84811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
84911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
85011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
851d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    fContext->drawPath(grPaint, *pathPtr, strokeInfo);
85211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
85311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
85411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comstatic const int kBmpSmallTileSize = 1 << 10;
85511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
85611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comstatic inline int get_tile_count(const SkIRect& srcRect, int tileSize)  {
85711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    int tilesX = (srcRect.fRight / tileSize) - (srcRect.fLeft / tileSize) + 1;
85811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    int tilesY = (srcRect.fBottom / tileSize) - (srcRect.fTop / tileSize) + 1;
85911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    return tilesX * tilesY;
86011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
86111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
86211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comstatic int determine_tile_size(const SkBitmap& bitmap, const SkIRect& src, int maxTileSize) {
86311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (maxTileSize <= kBmpSmallTileSize) {
86411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return maxTileSize;
86511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
86611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
86711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    size_t maxTileTotalTileSize = get_tile_count(src, maxTileSize);
86811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    size_t smallTotalTileSize = get_tile_count(src, kBmpSmallTileSize);
86911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
87011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    maxTileTotalTileSize *= maxTileSize * maxTileSize;
87111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    smallTotalTileSize *= kBmpSmallTileSize * kBmpSmallTileSize;
87211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
87311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (maxTileTotalTileSize > 2 * smallTotalTileSize) {
87411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return kBmpSmallTileSize;
87511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
87611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return maxTileSize;
87711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
87811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
87911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
88011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// Given a bitmap, an optional src rect, and a context with a clip and matrix determine what
88111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// pixels from the bitmap are necessary.
88211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comstatic void determine_clipped_src_rect(const GrContext* context,
88311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                       const SkBitmap& bitmap,
88411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                       const SkRect* srcRectPtr,
88511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                       SkIRect* clippedSrcIRect) {
88611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    const GrClipData* clip = context->getClip();
88711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    clip->getConservativeBounds(context->getRenderTarget(), clippedSrcIRect, NULL);
88811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkMatrix inv;
88911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (!context->getMatrix().invert(&inv)) {
89011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        clippedSrcIRect->setEmpty();
89111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
89211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
89311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect clippedSrcRect = SkRect::Make(*clippedSrcIRect);
89411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    inv.mapRect(&clippedSrcRect);
89511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (NULL != srcRectPtr) {
896a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        // we've setup src space 0,0 to map to the top left of the src rect.
897a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        clippedSrcRect.offset(srcRectPtr->fLeft, srcRectPtr->fTop);
89811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (!clippedSrcRect.intersect(*srcRectPtr)) {
89911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            clippedSrcIRect->setEmpty();
90011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            return;
90111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
90211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
90311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    clippedSrcRect.roundOut(clippedSrcIRect);
90411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkIRect bmpBounds = SkIRect::MakeWH(bitmap.width(), bitmap.height());
90511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (!clippedSrcIRect->intersect(bmpBounds)) {
90611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        clippedSrcIRect->setEmpty();
90711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
90811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
90911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
91011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.combool SkGpuDevice::shouldTileBitmap(const SkBitmap& bitmap,
91111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   const GrTextureParams& params,
91211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   const SkRect* srcRectPtr,
91311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   int maxTileSize,
91411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   int* tileSize,
91511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   SkIRect* clippedSrcRect) const {
91611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // if bitmap is explictly texture backed then just use the texture
91711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (NULL != bitmap.getTexture()) {
91811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
91911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
92011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
92111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // if it's larger than the max tile size, then we have no choice but tiling.
92211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (bitmap.width() > maxTileSize || bitmap.height() > maxTileSize) {
92311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        determine_clipped_src_rect(fContext, bitmap, srcRectPtr, clippedSrcRect);
92411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        *tileSize = determine_tile_size(bitmap, *clippedSrcRect, maxTileSize);
92511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return true;
92611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
92711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
92811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (bitmap.width() * bitmap.height() < 4 * kBmpSmallTileSize * kBmpSmallTileSize) {
92911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
93011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
93111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
93211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // if the entire texture is already in our cache then no reason to tile it
93311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (GrIsBitmapInCache(fContext, bitmap, &params)) {
93411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
93511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
93611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
93711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // At this point we know we could do the draw by uploading the entire bitmap
93811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // as a texture. However, if the texture would be large compared to the
93911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // cache size and we don't require most of it for this draw then tile to
94011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // reduce the amount of upload and cache spill.
94111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
94211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // assumption here is that sw bitmap size is a good proxy for its size as
94311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // a texture
94411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    size_t bmpSize = bitmap.getSize();
94511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    size_t cacheSize;
94695c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org    fContext->getResourceCacheLimits(NULL, &cacheSize);
94711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (bmpSize < cacheSize / 2) {
94811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
94911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
95011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
95111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // Figure out how much of the src we will need based on the src rect and clipping.
95211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    determine_clipped_src_rect(fContext, bitmap, srcRectPtr, clippedSrcRect);
95311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    *tileSize = kBmpSmallTileSize; // already know whole bitmap fits in one max sized tile.
95411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    size_t usedTileBytes = get_tile_count(*clippedSrcRect, kBmpSmallTileSize) *
95511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           kBmpSmallTileSize * kBmpSmallTileSize;
95611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
95711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    return usedTileBytes < 2 * bmpSize;
95811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
95911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
960a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.orgvoid SkGpuDevice::drawBitmap(const SkDraw& origDraw,
96111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                             const SkBitmap& bitmap,
96211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                             const SkMatrix& m,
96311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                             const SkPaint& paint) {
964a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    SkMatrix concat;
965a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    SkTCopyOnFirstWrite<SkDraw> draw(origDraw);
966a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    if (!m.isIdentity()) {
967a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        concat.setConcat(*draw->fMatrix, m);
968a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        draw.writable()->fMatrix = &concat;
969a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    }
970a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    this->drawBitmapCommon(*draw, bitmap, NULL, NULL, paint, SkCanvas::kNone_DrawBitmapRectFlag);
97111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
97211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
973dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org// This method outsets 'iRect' by 'outset' all around and then clamps its extents to
97411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// 'clamp'. 'offset' is adjusted to remain positioned over the top-left corner
97511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// of 'iRect' for all possible outsets/clamps.
976dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.orgstatic inline void clamped_outset_with_offset(SkIRect* iRect,
977dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                                              int outset,
978dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                                              SkPoint* offset,
979dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                                              const SkIRect& clamp) {
980dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    iRect->outset(outset, outset);
981dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org
982dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    int leftClampDelta = clamp.fLeft - iRect->fLeft;
983dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    if (leftClampDelta > 0) {
984dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org        offset->fX -= outset - leftClampDelta;
98511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        iRect->fLeft = clamp.fLeft;
98611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
987dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org        offset->fX -= outset;
98811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
989dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org
990dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    int topClampDelta = clamp.fTop - iRect->fTop;
991dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    if (topClampDelta > 0) {
992dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org        offset->fY -= outset - topClampDelta;
99311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        iRect->fTop = clamp.fTop;
99411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
995dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org        offset->fY -= outset;
99611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
99711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
99811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (iRect->fRight > clamp.fRight) {
99911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        iRect->fRight = clamp.fRight;
100011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
100111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (iRect->fBottom > clamp.fBottom) {
100211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        iRect->fBottom = clamp.fBottom;
100311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
100411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
100511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1006a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.orgstatic bool has_aligned_samples(const SkRect& srcRect,
1007a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                const SkRect& transformedRect) {
1008a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // detect pixel disalignment
1009a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    if (SkScalarAbs(SkScalarRoundToScalar(transformedRect.left()) -
1010a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            transformedRect.left()) < COLOR_BLEED_TOLERANCE &&
1011a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        SkScalarAbs(SkScalarRoundToScalar(transformedRect.top()) -
1012a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            transformedRect.top()) < COLOR_BLEED_TOLERANCE &&
1013a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        SkScalarAbs(transformedRect.width() - srcRect.width()) <
1014a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            COLOR_BLEED_TOLERANCE &&
1015a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        SkScalarAbs(transformedRect.height() - srcRect.height()) <
1016a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            COLOR_BLEED_TOLERANCE) {
1017a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        return true;
1018a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    }
1019a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    return false;
1020a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org}
1021a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org
1022a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.orgstatic bool may_color_bleed(const SkRect& srcRect,
1023a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                            const SkRect& transformedRect,
1024a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                            const SkMatrix& m) {
1025a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // Only gets called if has_aligned_samples returned false.
1026a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // So we can assume that sampling is axis aligned but not texel aligned.
1027a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    SkASSERT(!has_aligned_samples(srcRect, transformedRect));
1028a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    SkRect innerSrcRect(srcRect), innerTransformedRect,
1029a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        outerTransformedRect(transformedRect);
1030a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    innerSrcRect.inset(SK_ScalarHalf, SK_ScalarHalf);
1031a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    m.mapRect(&innerTransformedRect, innerSrcRect);
1032a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org
1033a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // The gap between outerTransformedRect and innerTransformedRect
1034a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // represents the projection of the source border area, which is
1035a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // problematic for color bleeding.  We must check whether any
1036a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // destination pixels sample the border area.
1037a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    outerTransformedRect.inset(COLOR_BLEED_TOLERANCE, COLOR_BLEED_TOLERANCE);
1038a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    innerTransformedRect.outset(COLOR_BLEED_TOLERANCE, COLOR_BLEED_TOLERANCE);
1039a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    SkIRect outer, inner;
1040a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    outerTransformedRect.round(&outer);
1041a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    innerTransformedRect.round(&inner);
1042a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // If the inner and outer rects round to the same result, it means the
1043a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // border does not overlap any pixel centers. Yay!
1044a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    return inner != outer;
1045a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org}
1046a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org
1047a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.orgstatic bool needs_texture_domain(const SkBitmap& bitmap,
1048a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 const SkRect& srcRect,
1049a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 GrTextureParams &params,
1050a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 const SkMatrix& contextMatrix,
1051a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 bool bicubic) {
1052a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    bool needsTextureDomain = false;
1053a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org
1054a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    if (bicubic || params.filterMode() != GrTextureParams::kNone_FilterMode) {
1055a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        // Need texture domain if drawing a sub rect
1056a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        needsTextureDomain = srcRect.width() < bitmap.width() ||
1057a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                             srcRect.height() < bitmap.height();
1058a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        if (!bicubic && needsTextureDomain && contextMatrix.rectStaysRect()) {
1059a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            // sampling is axis-aligned
1060a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            SkRect transformedRect;
1061a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            contextMatrix.mapRect(&transformedRect, srcRect);
1062a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org
1063a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            if (has_aligned_samples(srcRect, transformedRect)) {
1064a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                params.setFilterMode(GrTextureParams::kNone_FilterMode);
1065a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                needsTextureDomain = false;
1066a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            } else {
1067a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                needsTextureDomain = may_color_bleed(srcRect, transformedRect, contextMatrix);
1068a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            }
1069a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        }
1070a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    }
1071a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    return needsTextureDomain;
1072a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org}
1073a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org
107411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawBitmapCommon(const SkDraw& draw,
107511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   const SkBitmap& bitmap,
107611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   const SkRect* srcRectPtr,
1077a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org                                   const SkSize* dstSizePtr,
107811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   const SkPaint& paint,
107911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   SkCanvas::DrawBitmapRectFlags flags) {
108011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_SHOULD_DRAW(draw, false);
108111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
108211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect srcRect;
1083a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    SkSize dstSize;
1084dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    // If there is no src rect, or the src rect contains the entire bitmap then we're effectively
1085dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    // in the (easier) bleed case, so update flags.
108611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (NULL == srcRectPtr) {
1087a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        SkScalar w = SkIntToScalar(bitmap.width());
1088a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        SkScalar h = SkIntToScalar(bitmap.height());
1089a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        dstSize.fWidth = w;
1090a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        dstSize.fHeight = h;
1091a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        srcRect.set(0, 0, w, h);
1092dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org        flags = (SkCanvas::DrawBitmapRectFlags) (flags | SkCanvas::kBleed_DrawBitmapRectFlag);
109311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
1094a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        SkASSERT(NULL != dstSizePtr);
109511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        srcRect = *srcRectPtr;
1096a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        dstSize = *dstSizePtr;
1097dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org        if (srcRect.fLeft <= 0 && srcRect.fTop <= 0 &&
1098dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org            srcRect.fRight >= bitmap.width() && srcRect.fBottom >= bitmap.height()) {
1099dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org            flags = (SkCanvas::DrawBitmapRectFlags) (flags | SkCanvas::kBleed_DrawBitmapRectFlag);
1100dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org        }
110111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
110211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
110311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (paint.getMaskFilter()){
110411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // Convert the bitmap to a shader so that the rect can be drawn
110511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // through drawRect, which supports mask filters.
110611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkBitmap        tmp;    // subset of bitmap, if necessary
110711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        const SkBitmap* bitmapPtr = &bitmap;
1108a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        SkMatrix localM;
110911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (NULL != srcRectPtr) {
1110a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org            localM.setTranslate(-srcRectPtr->fLeft, -srcRectPtr->fTop);
1111a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org            localM.postScale(dstSize.fWidth / srcRectPtr->width(),
1112a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org                             dstSize.fHeight / srcRectPtr->height());
1113d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org            // In bleed mode we position and trim the bitmap based on the src rect which is
1114d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org            // already accounted for in 'm' and 'srcRect'. In clamp mode we need to chop out
1115d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org            // the desired portion of the bitmap and then update 'm' and 'srcRect' to
1116d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org            // compensate.
1117d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org            if (!(SkCanvas::kBleed_DrawBitmapRectFlag & flags)) {
1118d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                SkIRect iSrc;
1119d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                srcRect.roundOut(&iSrc);
1120d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org
1121d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                SkPoint offset = SkPoint::Make(SkIntToScalar(iSrc.fLeft),
1122d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                                               SkIntToScalar(iSrc.fTop));
1123d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org
1124d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                if (!bitmap.extractSubset(&tmp, iSrc)) {
1125d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                    return;     // extraction failed
1126d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                }
1127d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                bitmapPtr = &tmp;
1128d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                srcRect.offset(-offset.fX, -offset.fY);
1129a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org
1130d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                // The source rect has changed so update the matrix
1131a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org                localM.preTranslate(offset.fX, offset.fY);
113211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
1133a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        } else {
1134a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org            localM.reset();
113511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
113611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1137a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        SkPaint paintWithShader(paint);
1138a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        paintWithShader.setShader(SkShader::CreateBitmapShader(*bitmapPtr,
11399c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org            SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, &localM))->unref();
1140a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        SkRect dstRect = {0, 0, dstSize.fWidth, dstSize.fHeight};
1141a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        this->drawRect(draw, dstRect, paintWithShader);
114211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
114311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
114411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
114511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1146a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    // If there is no mask filter than it is OK to handle the src rect -> dst rect scaling using
1147a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    // the view matrix rather than a local matrix.
1148a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    SkMatrix m;
1149a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    m.setScale(dstSize.fWidth / srcRect.width(),
1150a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org               dstSize.fHeight / srcRect.height());
115111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext->concatMatrix(m);
115211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
115311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTextureParams params;
115411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkPaint::FilterLevel paintFilterLevel = paint.getFilterLevel();
115511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTextureParams::FilterMode textureFilterMode;
1156dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org
1157dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    bool doBicubic = false;
1158dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org
115911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    switch(paintFilterLevel) {
116011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        case SkPaint::kNone_FilterLevel:
116111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            textureFilterMode = GrTextureParams::kNone_FilterMode;
116211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            break;
116311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        case SkPaint::kLow_FilterLevel:
116411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            textureFilterMode = GrTextureParams::kBilerp_FilterMode;
116511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            break;
116611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        case SkPaint::kMedium_FilterLevel:
11671878651990d7c9da72cf43481432232bbef3550dcommit-bot@chromium.org            if (fContext->getMatrix().getMinScale() < SK_Scalar1) {
116879b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org                textureFilterMode = GrTextureParams::kMipMap_FilterMode;
116979b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org            } else {
117079b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org                // Don't trigger MIP level generation unnecessarily.
117179b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org                textureFilterMode = GrTextureParams::kBilerp_FilterMode;
117279b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org            }
117311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            break;
117479b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org        case SkPaint::kHigh_FilterLevel:
1175cea9abb001b07eaf4340a78db708bfac9e8c68c2commit-bot@chromium.org            // Minification can look bad with the bicubic effect.
11769927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org            doBicubic =
11779927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org                GrBicubicEffect::ShouldUseBicubic(fContext->getMatrix(), &textureFilterMode);
117811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            break;
117911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        default:
118011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkErrorInternals::SetError( kInvalidPaint_SkError,
118111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                        "Sorry, I don't understand the filtering "
118211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                        "mode you asked for.  Falling back to "
118311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                        "MIPMaps.");
118411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            textureFilterMode = GrTextureParams::kMipMap_FilterMode;
118511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            break;
118611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
118711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
11889927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org    int tileFilterPad;
11899927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org    if (doBicubic) {
11909927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org        tileFilterPad = GrBicubicEffect::kFilterTexelPad;
11919927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org    } else if (GrTextureParams::kNone_FilterMode == textureFilterMode) {
11929927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org        tileFilterPad = 0;
11939927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org    } else {
11949927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org        tileFilterPad = 1;
11959927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org    }
119611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    params.setFilterMode(textureFilterMode);
119711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1198dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    int maxTileSize = fContext->getMaxTextureSize() - 2 * tileFilterPad;
119911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    int tileSize;
120011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
120111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkIRect clippedSrcRect;
120211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (this->shouldTileBitmap(bitmap, params, srcRectPtr, maxTileSize, &tileSize,
120311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                               &clippedSrcRect)) {
1204dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org        this->drawTiledBitmap(bitmap, srcRect, clippedSrcRect, params, paint, flags, tileSize,
1205dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                              doBicubic);
120611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
120711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // take the simple case
1208a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        bool needsTextureDomain = needs_texture_domain(bitmap,
1209a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                                       srcRect,
1210a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                                       params,
1211a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                                       fContext->getMatrix(),
1212a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                                       doBicubic);
1213a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        this->internalDrawBitmap(bitmap,
1214a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 srcRect,
1215a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 params,
1216a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 paint,
1217a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 flags,
1218a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 doBicubic,
1219a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 needsTextureDomain);
122011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
122111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
122211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
122311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// Break 'bitmap' into several tiles to draw it since it has already
122411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// been determined to be too large to fit in VRAM
122511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap,
122611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                  const SkRect& srcRect,
122711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                  const SkIRect& clippedSrcIRect,
122811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                  const GrTextureParams& params,
122911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                  const SkPaint& paint,
123011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                  SkCanvas::DrawBitmapRectFlags flags,
1231dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                                  int tileSize,
1232dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                                  bool bicubic) {
12339d5e3f11a35e2059476a55e52349d3c6b3058f70commit-bot@chromium.org    // The following pixel lock is technically redundant, but it is desirable
12349d5e3f11a35e2059476a55e52349d3c6b3058f70commit-bot@chromium.org    // to lock outside of the tile loop to prevent redecoding the whole image
12359d5e3f11a35e2059476a55e52349d3c6b3058f70commit-bot@chromium.org    // at each tile in cases where 'bitmap' holds an SkDiscardablePixelRef that
12369d5e3f11a35e2059476a55e52349d3c6b3058f70commit-bot@chromium.org    // is larger than the limit of the discardable memory pool.
12379d5e3f11a35e2059476a55e52349d3c6b3058f70commit-bot@chromium.org    SkAutoLockPixels alp(bitmap);
123811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect clippedSrcRect = SkRect::Make(clippedSrcIRect);
123911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
124011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    int nx = bitmap.width() / tileSize;
124111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    int ny = bitmap.height() / tileSize;
124211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    for (int x = 0; x <= nx; x++) {
124311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        for (int y = 0; y <= ny; y++) {
124411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkRect tileR;
124511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            tileR.set(SkIntToScalar(x * tileSize),
124611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                      SkIntToScalar(y * tileSize),
124711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                      SkIntToScalar((x + 1) * tileSize),
124811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                      SkIntToScalar((y + 1) * tileSize));
124911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
125011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            if (!SkRect::Intersects(tileR, clippedSrcRect)) {
125111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                continue;
125211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
125311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
125411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            if (!tileR.intersect(srcRect)) {
125511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                continue;
125611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
125711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
125811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkBitmap tmpB;
125911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkIRect iTileR;
126011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            tileR.roundOut(&iTileR);
126111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkPoint offset = SkPoint::Make(SkIntToScalar(iTileR.fLeft),
126211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                           SkIntToScalar(iTileR.fTop));
126311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1264a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org            // Adjust the context matrix to draw at the right x,y in device space
1265a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org            SkMatrix tmpM;
1266a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org            GrContext::AutoMatrix am;
1267a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org            tmpM.setTranslate(offset.fX - srcRect.fLeft, offset.fY - srcRect.fTop);
1268a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org            am.setPreConcat(fContext, tmpM);
1269a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org
1270dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org            if (SkPaint::kNone_FilterLevel != paint.getFilterLevel() || bicubic) {
127111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                SkIRect iClampRect;
127211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
127311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                if (SkCanvas::kBleed_DrawBitmapRectFlag & flags) {
127411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    // In bleed mode we want to always expand the tile on all edges
127511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    // but stay within the bitmap bounds
127611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    iClampRect = SkIRect::MakeWH(bitmap.width(), bitmap.height());
127711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                } else {
127811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    // In texture-domain/clamp mode we only want to expand the
127911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    // tile on edges interior to "srcRect" (i.e., we want to
128011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    // not bleed across the original clamped edges)
128111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    srcRect.roundOut(&iClampRect);
128211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                }
1283dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                int outset = bicubic ? GrBicubicEffect::kFilterTexelPad : 1;
1284dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                clamped_outset_with_offset(&iTileR, outset, &offset, iClampRect);
128511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
128611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
128711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            if (bitmap.extractSubset(&tmpB, iTileR)) {
128811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                // now offset it to make it "local" to our tmp bitmap
128911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                tileR.offset(-offset.fX, -offset.fY);
1290a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                GrTextureParams paramsTemp = params;
1291a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                bool needsTextureDomain = needs_texture_domain(bitmap,
1292a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                                               srcRect,
1293a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                                               paramsTemp,
1294a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                                               fContext->getMatrix(),
1295a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                                               bicubic);
1296a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                this->internalDrawBitmap(tmpB,
1297a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                         tileR,
1298a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                         paramsTemp,
1299a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                         paint,
1300a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                         flags,
1301a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                         bicubic,
1302a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                         needsTextureDomain);
130311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
130411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
130511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
130611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
130711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
130811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
130911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com/*
131011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com *  This is called by drawBitmap(), which has to handle images that may be too
131111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com *  large to be represented by a single texture.
131211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com *
131311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com *  internalDrawBitmap assumes that the specified bitmap will fit in a texture
131411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com *  and that non-texture portion of the GrPaint has already been setup.
131511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com */
131611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap,
131711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                     const SkRect& srcRect,
131811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                     const GrTextureParams& params,
131911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                     const SkPaint& paint,
1320dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                                     SkCanvas::DrawBitmapRectFlags flags,
1321a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                     bool bicubic,
1322a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                     bool needsTextureDomain) {
132311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkASSERT(bitmap.width() <= fContext->getMaxTextureSize() &&
132411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com             bitmap.height() <= fContext->getMaxTextureSize());
132511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
132611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTexture* texture;
132711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoCachedTexture act(this, bitmap, &params, &texture);
132811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (NULL == texture) {
132911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
133011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
133111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1332a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    SkRect dstRect = {0, 0, srcRect.width(), srcRect.height() };
133311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect paintRect;
133411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkScalar wInv = SkScalarInvert(SkIntToScalar(texture->width()));
133511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkScalar hInv = SkScalarInvert(SkIntToScalar(texture->height()));
133611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    paintRect.setLTRB(SkScalarMul(srcRect.fLeft,   wInv),
133711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                      SkScalarMul(srcRect.fTop,    hInv),
133811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                      SkScalarMul(srcRect.fRight,  wInv),
133911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                      SkScalarMul(srcRect.fBottom, hInv));
134011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
134111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect textureDomain = SkRect::MakeEmpty();
134211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoTUnref<GrEffectRef> effect;
1343a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    if (needsTextureDomain && !(flags & SkCanvas::kBleed_DrawBitmapRectFlag)) {
134411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // Use a constrained texture domain to avoid color bleeding
134511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkScalar left, top, right, bottom;
134611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (srcRect.width() > SK_Scalar1) {
134711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkScalar border = SK_ScalarHalf / texture->width();
134811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            left = paintRect.left() + border;
134911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            right = paintRect.right() - border;
135011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        } else {
135111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            left = right = SkScalarHalf(paintRect.left() + paintRect.right());
135211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
135311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (srcRect.height() > SK_Scalar1) {
135411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkScalar border = SK_ScalarHalf / texture->height();
135511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            top = paintRect.top() + border;
135611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            bottom = paintRect.bottom() - border;
135711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        } else {
135811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            top = bottom = SkScalarHalf(paintRect.top() + paintRect.bottom());
135911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
136011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        textureDomain.setLTRB(left, top, right, bottom);
13617d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org        if (bicubic) {
13627d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org            effect.reset(GrBicubicEffect::Create(texture, SkMatrix::I(), textureDomain));
13637d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org        } else {
13647d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org            effect.reset(GrTextureDomainEffect::Create(texture,
13657d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org                                                       SkMatrix::I(),
13667d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org                                                       textureDomain,
13677d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org                                                       GrTextureDomain::kClamp_Mode,
13687d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org                                                       params.filterMode()));
13697d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org        }
1370dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    } else if (bicubic) {
1371bc91fd71faa2c5fd14423fecd18e50701c922cedcommit-bot@chromium.org        SkASSERT(GrTextureParams::kNone_FilterMode == params.filterMode());
1372bc91fd71faa2c5fd14423fecd18e50701c922cedcommit-bot@chromium.org        SkShader::TileMode tileModes[2] = { params.getTileModeX(), params.getTileModeY() };
1373bc91fd71faa2c5fd14423fecd18e50701c922cedcommit-bot@chromium.org        effect.reset(GrBicubicEffect::Create(texture, SkMatrix::I(), tileModes));
137411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
137511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        effect.reset(GrSimpleTextureEffect::Create(texture, SkMatrix::I(), params));
137611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
137711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
137811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // Construct a GrPaint by setting the bitmap texture as the first effect and then configuring
137911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // the rest from the SkPaint.
138011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint grPaint;
138111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    grPaint.addColorEffect(effect);
13820689d7b12e7c427a077b003d3d8ae759d86f798freed    bool alphaOnly = !(kAlpha_8_SkColorType == bitmap.colorType());
13839de5b514d38c5b36066bcdc14fba2f7e5196d372dandov    GrColor grColor = (alphaOnly) ? SkColor2GrColorJustAlpha(paint.getColor()) :
13849de5b514d38c5b36066bcdc14fba2f7e5196d372dandov                                    SkColor2GrColor(paint.getColor());
13859de5b514d38c5b36066bcdc14fba2f7e5196d372dandov    SkPaint2GrPaintNoShader(this->context(), paint, grColor, false, &grPaint);
138611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
138711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext->drawRectToRect(grPaint, dstRect, paintRect, NULL);
138811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
138911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
139011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comstatic bool filter_texture(SkBaseDevice* device, GrContext* context,
1391ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org                           GrTexture* texture, const SkImageFilter* filter,
13924cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org                           int w, int h, const SkImageFilter::Context& ctx,
13934cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org                           SkBitmap* result, SkIPoint* offset) {
139411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkASSERT(filter);
139511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkDeviceImageFilterProxy proxy(device);
139611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
139711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (filter->canFilterImageGPU()) {
139811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // Save the render target and set it to NULL, so we don't accidentally draw to it in the
139911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // filter.  Also set the clip wide open and the matrix to identity.
140011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        GrContext::AutoWideOpenIdentityDraw awo(context, NULL);
14014cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org        return filter->filterImageGPU(&proxy, wrap_texture(texture), ctx, result, offset);
140211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
140311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
140411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
140511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
140611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
140711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
140811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                             int left, int top, const SkPaint& paint) {
140911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // drawSprite is defined to be in device coords.
141011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_SHOULD_DRAW(draw, true);
141111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
141211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoLockPixels alp(bitmap, !bitmap.getTexture());
141311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (!bitmap.getTexture() && !bitmap.readyToDraw()) {
141411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
141511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
141611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
141711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    int w = bitmap.width();
141811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    int h = bitmap.height();
141911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
142011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTexture* texture;
142111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // draw sprite uses the default texture params
142211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoCachedTexture act(this, bitmap, NULL, &texture);
142311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
142411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkImageFilter* filter = paint.getImageFilter();
142511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // This bitmap will own the filtered result as a texture.
142611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkBitmap filteredBitmap;
142711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
142811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (NULL != filter) {
14296776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org        SkIPoint offset = SkIPoint::Make(0, 0);
143011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkMatrix matrix(*draw.fMatrix);
143111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        matrix.postTranslate(SkIntToScalar(-left), SkIntToScalar(-top));
14324cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org        SkIRect clipBounds = SkIRect::MakeWH(bitmap.width(), bitmap.height());
1433f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org        SkImageFilter::Cache* cache = SkImageFilter::Cache::Create();
1434f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org        SkAutoUnref aur(cache);
1435f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org        SkImageFilter::Context ctx(matrix, clipBounds, cache);
14364cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org        if (filter_texture(this, fContext, texture, filter, w, h, ctx, &filteredBitmap,
143711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           &offset)) {
143811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            texture = (GrTexture*) filteredBitmap.getTexture();
143911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            w = filteredBitmap.width();
144011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            h = filteredBitmap.height();
14416776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org            left += offset.x();
14426776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org            top += offset.y();
144311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        } else {
144411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            return;
144511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
144611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
144711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
144811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint grPaint;
144911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    grPaint.addColorTextureEffect(texture, SkMatrix::I());
145011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
14519de5b514d38c5b36066bcdc14fba2f7e5196d372dandov    SkPaint2GrPaintNoShader(this->context(), paint, SkColor2GrColorJustAlpha(paint.getColor()),
14529de5b514d38c5b36066bcdc14fba2f7e5196d372dandov                            false, &grPaint);
145311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
145411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext->drawRectToRect(grPaint,
14556776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org                             SkRect::MakeXYWH(SkIntToScalar(left),
14566776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org                                              SkIntToScalar(top),
145711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                              SkIntToScalar(w),
145811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                              SkIntToScalar(h)),
145911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                             SkRect::MakeXYWH(0,
146011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                              0,
146111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                              SK_Scalar1 * w / texture->width(),
146211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                              SK_Scalar1 * h / texture->height()));
146311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
146411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1465a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.orgvoid SkGpuDevice::drawBitmapRect(const SkDraw& origDraw, const SkBitmap& bitmap,
146611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                 const SkRect* src, const SkRect& dst,
146711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                 const SkPaint& paint,
146811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                 SkCanvas::DrawBitmapRectFlags flags) {
146911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkMatrix    matrix;
147011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect      bitmapBounds, tmpSrc;
147111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
147211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    bitmapBounds.set(0, 0,
147311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                     SkIntToScalar(bitmap.width()),
147411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                     SkIntToScalar(bitmap.height()));
147511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
147611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // Compute matrix from the two rectangles
147711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (NULL != src) {
147811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        tmpSrc = *src;
147911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
148011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        tmpSrc = bitmapBounds;
148111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
1482a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org
148311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit);
148411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
148511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // clip the tmpSrc to the bounds of the bitmap. No check needed if src==null.
148611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (NULL != src) {
148711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (!bitmapBounds.contains(tmpSrc)) {
148811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            if (!tmpSrc.intersect(bitmapBounds)) {
148911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                return; // nothing to draw
149011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
149111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
149211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
149311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1494a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    SkRect tmpDst;
1495a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    matrix.mapRect(&tmpDst, tmpSrc);
1496a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org
1497a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    SkTCopyOnFirstWrite<SkDraw> draw(origDraw);
1498a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    if (0 != tmpDst.fLeft || 0 != tmpDst.fTop) {
1499a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        // Translate so that tempDst's top left is at the origin.
1500a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        matrix = *origDraw.fMatrix;
1501a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        matrix.preTranslate(tmpDst.fLeft, tmpDst.fTop);
1502a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        draw.writable()->fMatrix = &matrix;
1503a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    }
1504a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    SkSize dstSize;
1505a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    dstSize.fWidth = tmpDst.width();
1506a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    dstSize.fHeight = tmpDst.height();
1507a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org
1508a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    this->drawBitmapCommon(*draw, bitmap, &tmpSrc, &dstSize, paint, flags);
150911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
151011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
151111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
151211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                             int x, int y, const SkPaint& paint) {
151311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // clear of the source device must occur before CHECK_SHOULD_DRAW
151411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkGpuDevice* dev = static_cast<SkGpuDevice*>(device);
151511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (dev->fNeedClear) {
151611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // TODO: could check here whether we really need to draw at all
151711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        dev->clear(0x0);
151811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
151911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
152011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // drawDevice is defined to be in device coords.
152111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_SHOULD_DRAW(draw, true);
152211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
152311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrRenderTarget* devRT = dev->accessRenderTarget();
152411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTexture* devTex;
152511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (NULL == (devTex = devRT->asTexture())) {
152611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
152711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
152811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
152911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    const SkBitmap& bm = dev->accessBitmap(false);
153011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    int w = bm.width();
153111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    int h = bm.height();
153211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
153311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkImageFilter* filter = paint.getImageFilter();
153411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // This bitmap will own the filtered result as a texture.
153511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkBitmap filteredBitmap;
153611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
153711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (NULL != filter) {
153811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkIPoint offset = SkIPoint::Make(0, 0);
153911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkMatrix matrix(*draw.fMatrix);
154011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y));
15414cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org        SkIRect clipBounds = SkIRect::MakeWH(devTex->width(), devTex->height());
1542f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org        SkImageFilter::Cache* cache = SkImageFilter::Cache::Create();
1543f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org        SkAutoUnref aur(cache);
1544f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org        SkImageFilter::Context ctx(matrix, clipBounds, cache);
15454cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org        if (filter_texture(this, fContext, devTex, filter, w, h, ctx, &filteredBitmap,
154611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           &offset)) {
154711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            devTex = filteredBitmap.getTexture();
154811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            w = filteredBitmap.width();
154911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            h = filteredBitmap.height();
155011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            x += offset.fX;
155111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            y += offset.fY;
155211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        } else {
155311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            return;
155411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
155511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
155611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
155711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint grPaint;
155811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    grPaint.addColorTextureEffect(devTex, SkMatrix::I());
155911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
15609de5b514d38c5b36066bcdc14fba2f7e5196d372dandov    SkPaint2GrPaintNoShader(this->context(), paint, SkColor2GrColorJustAlpha(paint.getColor()),
15619de5b514d38c5b36066bcdc14fba2f7e5196d372dandov                            false, &grPaint);
156211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
156311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect dstRect = SkRect::MakeXYWH(SkIntToScalar(x),
156411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                      SkIntToScalar(y),
156511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                      SkIntToScalar(w),
156611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                      SkIntToScalar(h));
156711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
156811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // The device being drawn may not fill up its texture (e.g. saveLayer uses approximate
156911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // scratch texture).
157011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect srcRect = SkRect::MakeWH(SK_Scalar1 * w / devTex->width(),
157111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                    SK_Scalar1 * h / devTex->height());
157211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
157311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext->drawRectToRect(grPaint, dstRect, srcRect);
157411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
157511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1576ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.orgbool SkGpuDevice::canHandleImageFilter(const SkImageFilter* filter) {
157711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    return filter->canFilterImageGPU();
157811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
157911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1580ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.orgbool SkGpuDevice::filterImage(const SkImageFilter* filter, const SkBitmap& src,
15814cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org                              const SkImageFilter::Context& ctx,
158211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                              SkBitmap* result, SkIPoint* offset) {
158311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // want explicitly our impl, so guard against a subclass of us overriding it
158411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (!this->SkGpuDevice::canHandleImageFilter(filter)) {
158511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
158611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
158711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
158811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoLockPixels alp(src, !src.getTexture());
158911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (!src.getTexture() && !src.readyToDraw()) {
159011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
159111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
159211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
159311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTexture* texture;
159411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // We assume here that the filter will not attempt to tile the src. Otherwise, this cache lookup
159511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // must be pushed upstack.
159611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoCachedTexture act(this, src, NULL, &texture);
159711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
15984cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org    return filter_texture(this, fContext, texture, filter, src.width(), src.height(), ctx,
15994cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org                          result, offset);
160011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
160111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
160211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
160311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
160411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// must be in SkCanvas::VertexMode order
160511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comstatic const GrPrimitiveType gVertexMode2PrimitiveType[] = {
160611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    kTriangles_GrPrimitiveType,
160711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    kTriangleStrip_GrPrimitiveType,
160811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    kTriangleFan_GrPrimitiveType,
160911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com};
161011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
161111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
161211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                              int vertexCount, const SkPoint vertices[],
161311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                              const SkPoint texs[], const SkColor colors[],
161411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                              SkXfermode* xmode,
161511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                              const uint16_t indices[], int indexCount,
161611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                              const SkPaint& paint) {
161711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_SHOULD_DRAW(draw, false);
161811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1619559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org    // If both textures and vertex-colors are NULL, strokes hairlines with the paint's color.
1620559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org    if ((NULL == texs || NULL == paint.getShader()) && NULL == colors) {
1621559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        texs = NULL;
1622559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        SkPaint copy(paint);
1623559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        copy.setStyle(SkPaint::kStroke_Style);
1624559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        copy.setStrokeWidth(0);
1625559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org
1626559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        VertState       state(vertexCount, indices, indexCount);
1627559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        VertState::Proc vertProc = state.chooseProc(vmode);
1628559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org
1629559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        SkPoint* pts = new SkPoint[vertexCount * 6];
1630559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        int i = 0;
1631559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        while (vertProc(&state)) {
1632559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org            pts[i] = vertices[state.f0];
1633559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org            pts[i + 1] = vertices[state.f1];
1634559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org            pts[i + 2] = vertices[state.f1];
1635559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org            pts[i + 3] = vertices[state.f2];
1636559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org            pts[i + 4] = vertices[state.f2];
1637559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org            pts[i + 5] = vertices[state.f0];
1638559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org            i += 6;
1639559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        }
1640559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        draw.drawPoints(SkCanvas::kLines_PointMode, i, pts, copy, true);
1641559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        return;
1642559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org    }
1643559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org
164411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint grPaint;
164511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // we ignore the shader if texs is null.
164611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (NULL == texs) {
16479de5b514d38c5b36066bcdc14fba2f7e5196d372dandov        SkPaint2GrPaintNoShader(this->context(), paint, SkColor2GrColor(paint.getColor()),
16489de5b514d38c5b36066bcdc14fba2f7e5196d372dandov                                NULL == colors, &grPaint);
164911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
16503595f88aff0a1b490aa6661f0ba2d3534ee86353commit-bot@chromium.org        SkPaint2GrPaintShader(this->context(), paint, NULL == colors, &grPaint);
165111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
165211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
16532583b6257fea931c31c6b3b75cc583106335ad90mtklein#if 0
165411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (NULL != xmode && NULL != texs && NULL != colors) {
165511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (!SkXfermode::IsMode(xmode, SkXfermode::kModulate_Mode)) {
165611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkDebugf("Unsupported vertex-color/texture xfer mode.\n");
16572583b6257fea931c31c6b3b75cc583106335ad90mtklein            return;
165811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
165911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
16602583b6257fea931c31c6b3b75cc583106335ad90mtklein#endif
166111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
166211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoSTMalloc<128, GrColor> convertedColors(0);
166311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (NULL != colors) {
166411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // need to convert byte order and from non-PM to PM
166511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        convertedColors.reset(vertexCount);
1666c93e68161f78542d90b28b6cf9911b1de3788054commit-bot@chromium.org        SkColor color;
166711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        for (int i = 0; i < vertexCount; ++i) {
1668c93e68161f78542d90b28b6cf9911b1de3788054commit-bot@chromium.org            color = colors[i];
1669c93e68161f78542d90b28b6cf9911b1de3788054commit-bot@chromium.org            if (paint.getAlpha() != 255) {
1670c93e68161f78542d90b28b6cf9911b1de3788054commit-bot@chromium.org                color = SkColorSetA(color, SkMulDiv255Round(SkColorGetA(color), paint.getAlpha()));
1671c93e68161f78542d90b28b6cf9911b1de3788054commit-bot@chromium.org            }
1672c93e68161f78542d90b28b6cf9911b1de3788054commit-bot@chromium.org            convertedColors[i] = SkColor2GrColor(color);
167311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
167411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        colors = convertedColors.get();
167511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
167611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext->drawVertices(grPaint,
167711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           gVertexMode2PrimitiveType[vmode],
167811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           vertexCount,
1679972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org                           vertices,
1680972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org                           texs,
168111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           colors,
168211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           indices,
168311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           indexCount);
168411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
168511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
168611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
168711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
168811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawText(const SkDraw& draw, const void* text,
168911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                          size_t byteLength, SkScalar x, SkScalar y,
169011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                          const SkPaint& paint) {
169111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_SHOULD_DRAW(draw, false);
169211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1693cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    if (fMainTextContext->canDraw(paint)) {
16948128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        GrPaint grPaint;
16953595f88aff0a1b490aa6661f0ba2d3534ee86353commit-bot@chromium.org        SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
16968128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
16978128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        SkDEBUGCODE(this->validate();)
16988128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
1699cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org        fMainTextContext->drawText(grPaint, paint, (const char *)text, byteLength, x, y);
1700cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    } else if (fFallbackTextContext && fFallbackTextContext->canDraw(paint)) {
17019f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org        GrPaint grPaint;
17023595f88aff0a1b490aa6661f0ba2d3534ee86353commit-bot@chromium.org        SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
17039f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org
17049f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org        SkDEBUGCODE(this->validate();)
17059f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org
1706cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org        fFallbackTextContext->drawText(grPaint, paint, (const char *)text, byteLength, x, y);
17079f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org    } else {
17089f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org        // this guy will just call our drawPath()
17099f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org        draw.drawText_asPaths((const char*)text, byteLength, x, y, paint);
171011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
171111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
171211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
171311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawPosText(const SkDraw& draw, const void* text,
171411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                             size_t byteLength, const SkScalar pos[],
171511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                             SkScalar constY, int scalarsPerPos,
171611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                             const SkPaint& paint) {
1717bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPosText", fContext);
171811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_SHOULD_DRAW(draw, false);
171911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1720cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    if (fMainTextContext->canDraw(paint)) {
17218128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        GrPaint grPaint;
17223595f88aff0a1b490aa6661f0ba2d3534ee86353commit-bot@chromium.org        SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
17238128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
17248128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        SkDEBUGCODE(this->validate();)
17258128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
17264c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com        fMainTextContext->drawPosText(grPaint, paint, (const char *)text, byteLength, pos,
1727cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org                                      constY, scalarsPerPos);
1728cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    } else if (fFallbackTextContext && fFallbackTextContext->canDraw(paint)) {
17299f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org        GrPaint grPaint;
17303595f88aff0a1b490aa6661f0ba2d3534ee86353commit-bot@chromium.org        SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
17314c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com
17329f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org        SkDEBUGCODE(this->validate();)
17334c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com
17344c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com        fFallbackTextContext->drawPosText(grPaint, paint, (const char *)text, byteLength, pos,
1735cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org                                          constY, scalarsPerPos);
17369f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org    } else {
17379f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org        draw.drawPosText_asPaths((const char*)text, byteLength, pos, constY,
17389f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org                                 scalarsPerPos, paint);
173911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
174011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
174111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
174211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawTextOnPath(const SkDraw& draw, const void* text,
174311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                size_t len, const SkPath& path,
174411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                const SkMatrix* m, const SkPaint& paint) {
174511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_SHOULD_DRAW(draw, false);
174611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
174711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkASSERT(draw.fDevice == this);
174811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    draw.drawTextOnPath((const char*)text, len, path, m, paint);
174911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
175011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
175111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
175211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
175311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.combool SkGpuDevice::filterTextFlags(const SkPaint& paint, TextFlags* flags) {
175411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (!paint.isLCDRenderText()) {
175511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // we're cool with the paint as is
175611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
175711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
175811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
175911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (paint.getShader() ||
176011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        paint.getXfermode() || // unless its srcover
176111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        paint.getMaskFilter() ||
176211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        paint.getRasterizer() ||
176311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        paint.getColorFilter() ||
176411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        paint.getPathEffect() ||
176511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        paint.isFakeBoldText() ||
176611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        paint.getStyle() != SkPaint::kFill_Style) {
176711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // turn off lcd
176811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        flags->fFlags = paint.getFlags() & ~SkPaint::kLCDRenderText_Flag;
176911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        flags->fHinting = paint.getHinting();
177011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return true;
177111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
177211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // we're cool with the paint as is
177311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    return false;
177411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
177511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
177611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::flush() {
177711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    DO_DEFERRED_CLEAR();
177811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext->resolveRenderTarget(fRenderTarget);
177911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
178011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
178111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
178211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
178315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.orgSkBaseDevice* SkGpuDevice::onCreateDevice(const SkImageInfo& info, Usage usage) {
178411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTextureDesc desc;
178511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fConfig = fRenderTarget->config();
178611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fFlags = kRenderTarget_GrTextureFlagBit;
178715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    desc.fWidth = info.width();
178815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    desc.fHeight = info.height();
178911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fSampleCnt = fRenderTarget->numSamples();
179011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
179111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoTUnref<GrTexture> texture;
179211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // Skia's convention is to only clear a device if it is non-opaque.
1793d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org    unsigned flags = info.isOpaque() ? 0 : kNeedClear_Flag;
179411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
179511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#if CACHE_COMPATIBLE_DEVICE_TEXTURES
179611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // layers are never draw in repeat modes, so we can request an approx
179711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // match and ignore any padding.
1798d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org    flags |= kCached_Flag;
179911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    const GrContext::ScratchTexMatch match = (kSaveLayer_Usage == usage) ?
180011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                                GrContext::kApprox_ScratchTexMatch :
180111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                                GrContext::kExact_ScratchTexMatch;
180211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    texture.reset(fContext->lockAndRefScratchTexture(desc, match));
180311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#else
180411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    texture.reset(fContext->createUncachedTexture(desc, NULL, 0));
180511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#endif
180611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (NULL != texture.get()) {
1807d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org        return SkGpuDevice::Create(texture, flags);
180811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
180915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        GrPrintf("---- failed to create compatible device texture [%d %d]\n",
181015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org                 info.width(), info.height());
181111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return NULL;
181211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
181311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
181411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
181576f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.comSkSurface* SkGpuDevice::newSurface(const SkImageInfo& info) {
181676f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com    return SkSurface::NewRenderTarget(fContext, info, fRenderTarget->numSamples());
181776f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com}
181876f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com
18199b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillipsvoid SkGpuDevice::EXPERIMENTAL_optimize(const SkPicture* picture) {
18200205aba7d5e8802d2a3ef55d999f5aa41db3adc9commit-bot@chromium.org    SkPicture::AccelData::Key key = GPUAccelData::ComputeAccelDataKey();
1821145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org
18228ec8bab7780cc458ad53c3c44f2027fbc7c14a54commit-bot@chromium.org    const SkPicture::AccelData* existing = picture->EXPERIMENTAL_getAccelData(key);
18238ec8bab7780cc458ad53c3c44f2027fbc7c14a54commit-bot@chromium.org    if (NULL != existing) {
18248ec8bab7780cc458ad53c3c44f2027fbc7c14a54commit-bot@chromium.org        return;
18258ec8bab7780cc458ad53c3c44f2027fbc7c14a54commit-bot@chromium.org    }
18268ec8bab7780cc458ad53c3c44f2027fbc7c14a54commit-bot@chromium.org
18278fd9382c25804d8e4e296c11ae7c63ed2d2691d5commit-bot@chromium.org    SkAutoTUnref<GPUAccelData> data(SkNEW_ARGS(GPUAccelData, (key)));
1828145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org
1829145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org    picture->EXPERIMENTAL_addAccelData(data);
18308ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org
18318ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org    GatherGPUInfo(picture, data);
1832145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org}
1833145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org
1834beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.comstatic void wrap_texture(GrTexture* texture, int width, int height, SkBitmap* result) {
1835beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
1836a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org    result->setInfo(info);
1837beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref();
1838beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com}
1839beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
18409b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillipsvoid SkGpuDevice::EXPERIMENTAL_purge(const SkPicture* picture) {
1841c873329ae9ff00b0c45f7294172ad2e9b1ec44c8commit-bot@chromium.org
1842c873329ae9ff00b0c45f7294172ad2e9b1ec44c8commit-bot@chromium.org}
1843c873329ae9ff00b0c45f7294172ad2e9b1ec44c8commit-bot@chromium.org
18449b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillipsbool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* canvas, const SkPicture* picture) {
18458ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org
18460205aba7d5e8802d2a3ef55d999f5aa41db3adc9commit-bot@chromium.org    SkPicture::AccelData::Key key = GPUAccelData::ComputeAccelDataKey();
1847145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org
18488ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org    const SkPicture::AccelData* data = picture->EXPERIMENTAL_getAccelData(key);
1849145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org    if (NULL == data) {
1850145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org        return false;
1851145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org    }
1852145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org
1853145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org    const GPUAccelData *gpuData = static_cast<const GPUAccelData*>(data);
18548ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org
18558ec8bab7780cc458ad53c3c44f2027fbc7c14a54commit-bot@chromium.org    if (0 == gpuData->numSaveLayers()) {
18568ec8bab7780cc458ad53c3c44f2027fbc7c14a54commit-bot@chromium.org        return false;
18578ec8bab7780cc458ad53c3c44f2027fbc7c14a54commit-bot@chromium.org    }
18588ec8bab7780cc458ad53c3c44f2027fbc7c14a54commit-bot@chromium.org
18598ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org    SkAutoTArray<bool> pullForward(gpuData->numSaveLayers());
18608ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org    for (int i = 0; i < gpuData->numSaveLayers(); ++i) {
18618ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org        pullForward[i] = false;
18628ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org    }
18638ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org
1864beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    SkRect clipBounds;
1865beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    if (!canvas->getClipBounds(&clipBounds)) {
1866beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        return true;
1867beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    }
1868beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    SkIRect query;
1869beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    clipBounds.roundOut(&query);
18708ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org
1871beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    const SkPicture::OperationList& ops = picture->EXPERIMENTAL_getActiveOps(query);
18728ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org
1873beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    // This code pre-renders the entire layer since it will be cached and potentially
1874beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    // reused with different clips (e.g., in different tiles). Because of this the
1875beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    // clip will not be limiting the size of the pre-rendered layer. kSaveLayerMaxSize
1876beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    // is used to limit which clips are pre-rendered.
1877beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    static const int kSaveLayerMaxSize = 256;
1878beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
1879beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    if (ops.valid()) {
1880beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        // In this case the picture has been generated with a BBH so we use
1881b2c82c99f891e4e846e4959c811661bf68fa43d6skia.committer@gmail.com        // the BBH to limit the pre-rendering to just the layers needed to cover
1882b2c82c99f891e4e846e4959c811661bf68fa43d6skia.committer@gmail.com        // the region being drawn
1883beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        for (int i = 0; i < ops.numOps(); ++i) {
1884beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com            uint32_t offset = ops.offset(i);
1885beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
1886beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com            // For now we're saving all the layers in the GPUAccelData so they
1887b2c82c99f891e4e846e4959c811661bf68fa43d6skia.committer@gmail.com            // can be nested. Additionally, the nested layers appear before
1888beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com            // their parent in the list.
1889beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com            for (int j = 0 ; j < gpuData->numSaveLayers(); ++j) {
1890beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                const GPUAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(j);
1891beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
1892beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                if (pullForward[j]) {
1893beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    continue;            // already pulling forward
1894beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                }
18958ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org
1896beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                if (offset < info.fSaveLayerOpID || offset > info.fRestoreOpID) {
1897beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    continue;            // the op isn't in this range
1898beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                }
18998ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org
1900beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                // TODO: once this code is more stable unsuitable layers can
1901beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                // just be omitted during the optimization stage
1902beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                if (!info.fValid ||
1903beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    kSaveLayerMaxSize < info.fSize.fWidth ||
1904beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    kSaveLayerMaxSize < info.fSize.fHeight ||
1905beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    info.fIsNested) {
1906beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    continue;            // this layer is unsuitable
1907beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                }
19088ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org
1909beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                pullForward[j] = true;
1910beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com            }
1911beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        }
1912beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    } else {
1913beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        // In this case there is no BBH associated with the picture. Pre-render
1914f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org        // all the layers that intersect the drawn region
19158ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org        for (int j = 0; j < gpuData->numSaveLayers(); ++j) {
19168ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org            const GPUAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(j);
19178ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org
1918f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org            SkIRect layerRect = SkIRect::MakeXYWH(info.fOffset.fX,
1919f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                                                  info.fOffset.fY,
1920f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                                                  info.fSize.fWidth,
1921f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                                                  info.fSize.fHeight);
1922f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org
1923f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org            if (!SkIRect::Intersects(query, layerRect)) {
1924f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                continue;
1925f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org            }
1926f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org
1927beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com            // TODO: once this code is more stable unsuitable layers can
1928beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com            // just be omitted during the optimization stage
1929beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com            if (!info.fValid ||
1930beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                kSaveLayerMaxSize < info.fSize.fWidth ||
1931beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                kSaveLayerMaxSize < info.fSize.fHeight ||
1932beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                info.fIsNested) {
1933beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                continue;
19348ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org            }
1935beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
1936b2c82c99f891e4e846e4959c811661bf68fa43d6skia.committer@gmail.com            pullForward[j] = true;
19378ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org        }
19388ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org    }
19398ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org
1940beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    SkPicturePlayback::PlaybackReplacements replacements;
1941beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
1942beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    for (int i = 0; i < gpuData->numSaveLayers(); ++i) {
1943beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        if (pullForward[i]) {
1944beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com            GrCachedLayer* layer = fContext->getLayerCache()->findLayerOrCreate(picture, i);
1945beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
1946beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com            const GPUAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(i);
1947beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
1948beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com            if (NULL != picture->fPlayback) {
1949b2c82c99f891e4e846e4959c811661bf68fa43d6skia.committer@gmail.com                SkPicturePlayback::PlaybackReplacements::ReplacementInfo* layerInfo =
1950beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                                                                        replacements.push();
1951beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                layerInfo->fStart = info.fSaveLayerOpID;
1952beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                layerInfo->fStop = info.fRestoreOpID;
1953beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                layerInfo->fPos = info.fOffset;
1954beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
1955beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                GrTextureDesc desc;
1956beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                desc.fFlags = kRenderTarget_GrTextureFlagBit;
1957beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                desc.fWidth = info.fSize.fWidth;
1958beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                desc.fHeight = info.fSize.fHeight;
1959beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                desc.fConfig = kSkia8888_GrPixelConfig;
1960beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                // TODO: need to deal with sample count
1961beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
1962beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                bool bNeedsRendering = true;
1963beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
1964beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                // This just uses scratch textures and doesn't cache the texture.
1965beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                // This can yield a lot of re-rendering
1966beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                if (NULL == layer->getTexture()) {
1967b2c82c99f891e4e846e4959c811661bf68fa43d6skia.committer@gmail.com                    layer->setTexture(fContext->lockAndRefScratchTexture(desc,
1968beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                                                        GrContext::kApprox_ScratchTexMatch));
1969beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    if (NULL == layer->getTexture()) {
1970beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                        continue;
1971beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    }
1972beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                } else {
1973beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    bNeedsRendering = false;
1974beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                }
1975beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
1976beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                layerInfo->fBM = SkNEW(SkBitmap);
1977beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                wrap_texture(layer->getTexture(), desc.fWidth, desc.fHeight, layerInfo->fBM);
1978beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
1979beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                SkASSERT(info.fPaint);
1980beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                layerInfo->fPaint = info.fPaint;
1981beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
1982beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                if (bNeedsRendering) {
1983beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
1984beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                                                        layer->getTexture()->asRenderTarget()));
1985beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
1986beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    SkCanvas* canvas = surface->getCanvas();
1987beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
1988beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    canvas->setMatrix(info.fCTM);
1989beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    canvas->clear(SK_ColorTRANSPARENT);
1990beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
1991beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    picture->fPlayback->setDrawLimits(info.fSaveLayerOpID, info.fRestoreOpID);
1992beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    picture->fPlayback->draw(*canvas, NULL);
1993beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    picture->fPlayback->setDrawLimits(0, 0);
1994beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    canvas->flush();
1995beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                }
1996beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com            }
1997beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        }
1998beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    }
1999beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
2000beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    // Playback using new layers
2001beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    picture->fPlayback->setReplacements(&replacements);
2002beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    picture->fPlayback->draw(*canvas, NULL);
2003beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    picture->fPlayback->setReplacements(NULL);
2004beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
2005beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    for (int i = 0; i < gpuData->numSaveLayers(); ++i) {
2006beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        GrCachedLayer* layer = fContext->getLayerCache()->findLayerOrCreate(picture, i);
2007beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
2008beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        if (NULL != layer->getTexture()) {
2009beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com            fContext->unlockScratchTexture(layer->getTexture());
2010beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com            layer->setTexture(NULL);
2011beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        }
2012beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    }
2013beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
2014beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    return true;
2015145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org}
2016