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
10abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen#include "GrContext.h"
11abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen#include "GrGpu.h"
12abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen#include "GrGpuResourcePriv.h"
1398d709bc8d0761df8e0ad35e92c06e500f0be50drobertphillips#include "GrLayerHoister.h"
14274b4ba6bde67bb8b6d8f1721ef5d6d4294f2aa8robertphillips#include "GrRecordReplaceDraw.h"
15d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel#include "GrStrokeInfo.h"
168f94bb2b25a30917746c5180614e58253c76ae77joshualitt#include "GrTextContext.h"
17bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel#include "GrTracing.h"
1830d7841f906116c3945ec8125a816a5c5462fed0robertphillips#include "SkCanvasPriv.h"
1911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkDeviceImageFilterProxy.h"
2011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkDrawProcs.h"
21abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen#include "SkErrorInternals.h"
2211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkGlyphCache.h"
23abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen#include "SkGrTexturePixelRef.h"
24a85d4d0814818e4ddabb9237da209d61d6cd5854reed#include "SkImage_Base.h"
2511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkImageFilter.h"
2682365915476caedc130d0e36012a1ce0c007c4aerobertphillips#include "SkLayerInfo.h"
27821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org#include "SkMaskFilter.h"
2811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkPathEffect.h"
29145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org#include "SkPicture.h"
30db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips#include "SkPictureData.h"
3111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkRRect.h"
32abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen#include "SkRecord.h"
3311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkStroke.h"
3476f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com#include "SkSurface.h"
35abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen#include "SkSurface_Gpu.h"
36a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org#include "SkTLazy.h"
3711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkUtils.h"
38559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org#include "SkVertState.h"
39320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips#include "SkXfermode.h"
40abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen#include "effects/GrBicubicEffect.h"
41abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen#include "effects/GrDashingEffect.h"
42abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen#include "effects/GrSimpleTextureEffect.h"
43abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen#include "effects/GrTextureDomain.h"
4411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
45f037e0bf138a4e842f39e19864d05010a54950c9reed#if SK_SUPPORT_GPU
46f037e0bf138a4e842f39e19864d05010a54950c9reed
4755b6d8be997a447ef9ce0f029697677a940bfc24senorblancoenum { kDefaultImageFilterCacheSize = 32 * 1024 * 1024 };
4855b6d8be997a447ef9ce0f029697677a940bfc24senorblanco
4911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#if 0
5011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    extern bool (*gShouldDrawProc)();
515531d51ce7426bdae7563547326fcf0bf926a083joshualitt    #define CHECK_SHOULD_DRAW(draw)                             \
5211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        do {                                                    \
5311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            if (gShouldDrawProc && !gShouldDrawProc()) return;  \
545531d51ce7426bdae7563547326fcf0bf926a083joshualitt            this->prepareDraw(draw);                            \
5511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        } while (0)
5611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#else
575531d51ce7426bdae7563547326fcf0bf926a083joshualitt    #define CHECK_SHOULD_DRAW(draw) this->prepareDraw(draw)
5811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#endif
5911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
6011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// This constant represents the screen alignment criterion in texels for
6111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// requiring texture domain clamping to prevent color bleeding when drawing
6211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// a sub region of a larger source image.
634b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org#define COLOR_BLEED_TOLERANCE 0.001f
6411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
6511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#define DO_DEFERRED_CLEAR()             \
6611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    do {                                \
67afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon        if (fNeedClear) {               \
68afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon            this->clearAll();           \
6911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }                               \
7011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } while (false)                     \
7111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
7211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
7311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
7411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#define CHECK_FOR_ANNOTATION(paint) \
7511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    do { if (paint.getAnnotation()) { return; } } while (0)
7611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
7711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
7811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
79bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon// Helper for turning a bitmap into a texture. If the bitmap is GrTexture backed this
80bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon// just accesses the backing GrTexture. Otherwise, it creates a cached texture
81bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon// representation and releases it in the destructor.
82bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomonclass AutoBitmapTexture : public SkNoncopyable {
8311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.compublic:
84bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon    AutoBitmapTexture() {}
8511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
86bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon    AutoBitmapTexture(GrContext* context,
87bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon                      const SkBitmap& bitmap,
88bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon                      const GrTextureParams* params,
89bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon                      GrTexture** texture) {
9049f085dddff10473b6ebf832a974288300224e60bsalomon        SkASSERT(texture);
91bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon        *texture = this->set(context, bitmap, params);
9211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
9311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
94bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon    GrTexture* set(GrContext* context,
9511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                   const SkBitmap& bitmap,
9611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                   const GrTextureParams* params) {
97bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon        // Either get the texture directly from the bitmap, or else use the cache and
98bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon        // remember to unref it.
99bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon        if (GrTexture* bmpTexture = bitmap.getTexture()) {
100bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon            fTexture.reset(NULL);
101bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon            return bmpTexture;
102bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon        } else {
103bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon            fTexture.reset(GrRefCachedBitmapTexture(context, bitmap, params));
104bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon            return fTexture.get();
10511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
10611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
10711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
10811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comprivate:
109bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon    SkAutoTUnref<GrTexture> fTexture;
11011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com};
11111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
11211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
11311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
11411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comstruct GrSkDrawProcs : public SkDrawProcs {
11511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.compublic:
11611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrContext* fContext;
11711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTextContext* fTextContext;
11811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrFontScaler* fFontScaler;  // cached in the skia glyphcache
11911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com};
12011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
12111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
12211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
123afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomonSkGpuDevice* SkGpuDevice::Create(GrRenderTarget* rt, const SkSurfaceProps* props, unsigned flags) {
124d0d37cace08f12abf8d316e6949e947551d418e6senorblanco    return SkGpuDevice::Create(rt, rt->width(), rt->height(), props, flags);
125d0d37cace08f12abf8d316e6949e947551d418e6senorblanco}
126d0d37cace08f12abf8d316e6949e947551d418e6senorblanco
127d0d37cace08f12abf8d316e6949e947551d418e6senorblancoSkGpuDevice* SkGpuDevice::Create(GrRenderTarget* rt, int width, int height,
128d0d37cace08f12abf8d316e6949e947551d418e6senorblanco                                 const SkSurfaceProps* props, unsigned flags) {
129afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon    if (!rt || rt->wasDestroyed()) {
13011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return NULL;
13111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
132d0d37cace08f12abf8d316e6949e947551d418e6senorblanco    return SkNEW_ARGS(SkGpuDevice, (rt, width, height, props, flags));
13311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
13411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
135afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomonstatic SkDeviceProperties surfaceprops_to_deviceprops(const SkSurfaceProps* props) {
136afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon    if (props) {
137afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon        return SkDeviceProperties(props->pixelGeometry());
138afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon    } else {
139afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon        return SkDeviceProperties(SkDeviceProperties::kLegacyLCD_InitType);
140afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon    }
141b2db898573e3cdcc8234eebf51961bfc4977ebbcreed}
14211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
143afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomonstatic SkSurfaceProps copy_or_default_props(const SkSurfaceProps* props) {
144afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon    if (props) {
145afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon        return SkSurfaceProps(*props);
146afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon    } else {
147afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon        return SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType);
148afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon    }
149afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon}
150afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon
151d0d37cace08f12abf8d316e6949e947551d418e6senorblancoSkGpuDevice::SkGpuDevice(GrRenderTarget* rt, int width, int height,
152d0d37cace08f12abf8d316e6949e947551d418e6senorblanco                         const SkSurfaceProps* props, unsigned flags)
153b2db898573e3cdcc8234eebf51961bfc4977ebbcreed    : INHERITED(surfaceprops_to_deviceprops(props))
154afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon    , fSurfaceProps(copy_or_default_props(props))
155b2db898573e3cdcc8234eebf51961bfc4977ebbcreed{
15611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fDrawProcs = NULL;
15711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
158afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon    fContext = SkRef(rt->getContext());
159afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon    fNeedClear = flags & kNeedClear_Flag;
16011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
161afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon    fRenderTarget = SkRef(rt);
16211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
163d0d37cace08f12abf8d316e6949e947551d418e6senorblanco    SkImageInfo info = rt->surfacePriv().info().makeWH(width, height);
164afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon    SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, rt));
165afbf2d6273cd22c683f20a7e5773843876af3085bsalomon    fLegacyBitmap.setInfo(info);
16689443aba5bfa2b040dc9fd24938b7d0b3decd737reed    fLegacyBitmap.setPixelRef(pr)->unref();
167c6cb56f36c4aad8ed45486a3bb4de614bb822f1bkkinnunen
168afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon    bool useDFT = fSurfaceProps.isUseDistanceFieldFonts();
1696e8cd9671958c69babde9338c5c18a4c3d895575joshualitt    fTextContext = fContext->createTextContext(fRenderTarget, this, this->getLeakyProperties(),
1706e8cd9671958c69babde9338c5c18a4c3d895575joshualitt                                               useDFT);
17111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
17211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
173abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunenGrRenderTarget* SkGpuDevice::CreateRenderTarget(GrContext* context, SkSurface::Budgeted budgeted,
174abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen                                                const SkImageInfo& origInfo, int sampleCount) {
17515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    if (kUnknown_SkColorType == origInfo.colorType() ||
17615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        origInfo.width() < 0 || origInfo.height() < 0) {
17715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        return NULL;
17815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    }
17915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org
180afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon    if (!context) {
181afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon        return NULL;
182afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon    }
183afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon
184e5ea500d4714a7d84de2bf913e81be3b65d2de68reed    SkColorType ct = origInfo.colorType();
185e5ea500d4714a7d84de2bf913e81be3b65d2de68reed    SkAlphaType at = origInfo.alphaType();
186e5ea500d4714a7d84de2bf913e81be3b65d2de68reed    if (kRGB_565_SkColorType == ct) {
187e5ea500d4714a7d84de2bf913e81be3b65d2de68reed        at = kOpaque_SkAlphaType;  // force this setting
188afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon    } else if (ct != kBGRA_8888_SkColorType && ct != kRGBA_8888_SkColorType) {
189afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon        // Fall back from whatever ct was to default of kRGBA or kBGRA which is aliased as kN32
190e5ea500d4714a7d84de2bf913e81be3b65d2de68reed        ct = kN32_SkColorType;
191afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon    }
192afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon    if (kOpaque_SkAlphaType != at) {
193afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon        at = kPremul_SkAlphaType;  // force this setting
19415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    }
195e5ea500d4714a7d84de2bf913e81be3b65d2de68reed    const SkImageInfo info = SkImageInfo::Make(origInfo.width(), origInfo.height(), ct, at);
19615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org
197f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon    GrSurfaceDesc desc;
198f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon    desc.fFlags = kRenderTarget_GrSurfaceFlag;
19915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    desc.fWidth = info.width();
20015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    desc.fHeight = info.height();
2013adcc3403377c0b9a7afde6db8e0432325413a10commit-bot@chromium.org    desc.fConfig = SkImageInfo2GrPixelConfig(info);
20215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    desc.fSampleCnt = sampleCount;
203d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon    GrTexture* texture = context->textureProvider()->createTexture(
204d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon        desc, SkToBool(budgeted), NULL, 0);
205abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen    if (NULL == texture) {
206abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen        return NULL;
207abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen    }
208abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen    SkASSERT(NULL != texture->asRenderTarget());
209abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen    return texture->asRenderTarget();
210abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen}
21115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org
212abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunenSkGpuDevice* SkGpuDevice::Create(GrContext* context, SkSurface::Budgeted budgeted,
213abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen                                 const SkImageInfo& info, int sampleCount,
214abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen                                 const SkSurfaceProps* props, unsigned flags) {
215abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen
216abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen    SkAutoTUnref<GrRenderTarget> rt(CreateRenderTarget(context, budgeted, info,  sampleCount));
217abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen    if (NULL == rt) {
21815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org        return NULL;
21915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    }
220969588f0c9030d5a4942085a4b5a5ea7e8d2bc25skia.committer@gmail.com
221d0d37cace08f12abf8d316e6949e947551d418e6senorblanco    return SkNEW_ARGS(SkGpuDevice, (rt, info.width(), info.height(), props, flags));
22215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org}
22315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org
22411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comSkGpuDevice::~SkGpuDevice() {
22511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (fDrawProcs) {
22611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        delete fDrawProcs;
22711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
228d2ac07b64b7d46e81d00d389781f9f83810f0095skia.committer@gmail.com
2298c27a188a0b216021d439eb627622d17b9f78343jvanverth    delete fTextContext;
23011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
23132d0b3b5463c11032f12d03d993f11ea0af05959bsalomon    fRenderTarget->unref();
23211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    fContext->unref();
23311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
23411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
23511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
23611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
237a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.orgbool SkGpuDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
238a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org                               int x, int y) {
239a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    DO_DEFERRED_CLEAR();
240a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org
241a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    // TODO: teach fRenderTarget to take ImageInfo directly to specify the src pixels
2423adcc3403377c0b9a7afde6db8e0432325413a10commit-bot@chromium.org    GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo);
243a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    if (kUnknown_GrPixelConfig == config) {
244a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org        return false;
245a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    }
246a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org
247a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    uint32_t flags = 0;
248a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    if (kUnpremul_SkAlphaType == dstInfo.alphaType()) {
249a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org        flags = GrContext::kUnpremul_PixelOpsFlag;
250a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    }
251a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org    return fContext->readRenderTargetPixels(fRenderTarget, x, y, dstInfo.width(), dstInfo.height(),
252a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org                                            config, dstPixels, dstRowBytes, flags);
253a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org}
25411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
2554cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkGpuDevice::onWritePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes,
2564cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org                                int x, int y) {
2574cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    // TODO: teach fRenderTarget to take ImageInfo directly to specify the src pixels
2583adcc3403377c0b9a7afde6db8e0432325413a10commit-bot@chromium.org    GrPixelConfig config = SkImageInfo2GrPixelConfig(info);
2594cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    if (kUnknown_GrPixelConfig == config) {
2604cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org        return false;
2614cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    }
2624cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    uint32_t flags = 0;
2634cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    if (kUnpremul_SkAlphaType == info.alphaType()) {
2644cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org        flags = GrContext::kUnpremul_PixelOpsFlag;
2654cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    }
2664cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    fRenderTarget->writePixels(x, y, info.width(), info.height(), config, pixels, rowBytes, flags);
2674cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org
2684cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    // need to bump our genID for compatibility with clients that "know" we have a bitmap
26989443aba5bfa2b040dc9fd24938b7d0b3decd737reed    fLegacyBitmap.notifyPixelsChanged();
2704cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org
2714cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org    return true;
2724cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org}
27311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
274b7b7eb32f41729c136c939702b0c9a484accb541senorblanco@chromium.orgconst SkBitmap& SkGpuDevice::onAccessBitmap() {
275b7b7eb32f41729c136c939702b0c9a484accb541senorblanco@chromium.org    DO_DEFERRED_CLEAR();
27689443aba5bfa2b040dc9fd24938b7d0b3decd737reed    return fLegacyBitmap;
277b7b7eb32f41729c136c939702b0c9a484accb541senorblanco@chromium.org}
278b7b7eb32f41729c136c939702b0c9a484accb541senorblanco@chromium.org
27911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::onAttachToCanvas(SkCanvas* canvas) {
28011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    INHERITED::onAttachToCanvas(canvas);
28111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
28211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // Canvas promises that this ptr is valid until onDetachFromCanvas is called
28344701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt    fClipStack.reset(SkRef(canvas->getClipStack()));
28411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
28511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
28611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::onDetachFromCanvas() {
28711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    INHERITED::onDetachFromCanvas();
288570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    fClip.reset();
28944701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt    fClipStack.reset(NULL);
29011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
29111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
29211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// call this every draw call, to ensure that the context reflects our state,
29311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// and not the state from some other canvas/device
2945531d51ce7426bdae7563547326fcf0bf926a083joshualittvoid SkGpuDevice::prepareDraw(const SkDraw& draw) {
29544701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt    SkASSERT(fClipStack.get());
29611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
29744701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt    SkASSERT(draw.fClipStack && draw.fClipStack == fClipStack);
29811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
299570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    fClip.setClipStack(fClipStack, &this->getOrigin());
30011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
30111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    DO_DEFERRED_CLEAR();
30211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
30311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
30411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comGrRenderTarget* SkGpuDevice::accessRenderTarget() {
3057156b09c4bc25af772826d5ac592dcdacdf15317robertphillips    DO_DEFERRED_CLEAR();
30611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    return fRenderTarget;
30711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
30811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
3098eddfb50c0c9e4bcba6384a2ce39852b5fb5becbreedvoid SkGpuDevice::clearAll() {
3108eddfb50c0c9e4bcba6384a2ce39852b5fb5becbreed    GrColor color = 0;
3118eddfb50c0c9e4bcba6384a2ce39852b5fb5becbreed    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::clearAll", fContext);
3128eddfb50c0c9e4bcba6384a2ce39852b5fb5becbreed    SkIRect rect = SkIRect::MakeWH(this->width(), this->height());
3138eddfb50c0c9e4bcba6384a2ce39852b5fb5becbreed    fContext->clear(&rect, color, true, fRenderTarget);
314afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon    fNeedClear = false;
3158eddfb50c0c9e4bcba6384a2ce39852b5fb5becbreed}
3168eddfb50c0c9e4bcba6384a2ce39852b5fb5becbreed
317abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunenvoid SkGpuDevice::replaceRenderTarget(bool shouldRetainContent) {
318abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen    // Caller must have accessed the render target, because it knows the rt must be replaced.
319abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen    SkASSERT(!fNeedClear);
320abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen
321abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen    SkSurface::Budgeted budgeted =
322abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen            fRenderTarget->resourcePriv().isBudgeted() ? SkSurface::kYes_Budgeted
323abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen                                                       : SkSurface::kNo_Budgeted;
324abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen
325abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen    SkAutoTUnref<GrRenderTarget> newRT(CreateRenderTarget(
326abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen        fRenderTarget->getContext(), budgeted, this->imageInfo(), fRenderTarget->numSamples()));
327abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen
328abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen    if (NULL == newRT) {
329abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen        return;
330abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen    }
331abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen
332abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen    if (shouldRetainContent) {
333abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen        if (fRenderTarget->wasDestroyed()) {
334abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen            return;
335abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen        }
336abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen        this->context()->copySurface(newRT, fRenderTarget);
337abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen    }
338abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen
339abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen    SkASSERT(fRenderTarget != newRT);
340abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen
341abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen    fRenderTarget->unref();
342abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen    fRenderTarget = newRT.detach();
343abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen
344abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen    SkASSERT(fRenderTarget->surfacePriv().info() == fLegacyBitmap.info());
345abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen    SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (fRenderTarget->surfacePriv().info(), fRenderTarget));
346abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen    fLegacyBitmap.setPixelRef(pr)->unref();
347abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen}
348abcfab4d68d53900ef33320bb2622696c14d14b0kkinnunen
34911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
35011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
35111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
3525531d51ce7426bdae7563547326fcf0bf926a083joshualitt    CHECK_SHOULD_DRAW(draw);
353d78a168ec2ec2c07c0c1845e6a1781988e4a52d9egdaniel    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPaint", fContext);
35411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
35511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint grPaint;
356bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    if (!SkPaint2GrPaint(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint)) {
357bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon        return;
358bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    }
35911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
360570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    fContext->drawPaint(fRenderTarget, fClip, grPaint, *draw.fMatrix);
36111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
36211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
36311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// must be in SkCanvas::PointMode order
36411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comstatic const GrPrimitiveType gPointMode2PrimtiveType[] = {
36511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    kPoints_GrPrimitiveType,
36611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    kLines_GrPrimitiveType,
36711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    kLineStrip_GrPrimitiveType
36811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com};
36911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
37011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
37111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                             size_t count, const SkPoint pts[], const SkPaint& paint) {
37211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_FOR_ANNOTATION(paint);
3735531d51ce7426bdae7563547326fcf0bf926a083joshualitt    CHECK_SHOULD_DRAW(draw);
37411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
37511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkScalar width = paint.getStrokeWidth();
37611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (width < 0) {
37711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
37811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
37911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
380628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org    if (paint.getPathEffect() && 2 == count && SkCanvas::kLines_PointMode == mode) {
381e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel        GrStrokeInfo strokeInfo(paint, SkPaint::kStroke_Style);
382e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel        GrPaint grPaint;
383bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon        if (!SkPaint2GrPaint(this->context(), fRenderTarget, paint, *draw.fMatrix, true,
384bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon                             &grPaint)) {
385bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon            return;
386bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon        }
387e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel        SkPath path;
388b3eb687f8a89eb1eacd1afb4016401eb392f66abjvanverth        path.setIsVolatile(true);
389e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel        path.moveTo(pts[0]);
390e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel        path.lineTo(pts[1]);
391570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt        fContext->drawPath(fRenderTarget, fClip, grPaint, *draw.fMatrix, path, strokeInfo);
392e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel        return;
393628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org    }
394628ed0b22045a9544b56e00e73137d6050ce900ccommit-bot@chromium.org
39511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // we only handle hairlines and paints without path effects or mask filters,
39611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // else we let the SkDraw call our drawPath()
39711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (width > 0 || paint.getPathEffect() || paint.getMaskFilter()) {
39811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        draw.drawPoints(mode, count, pts, paint, true);
39911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
40011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
40111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
40211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint grPaint;
403bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    if (!SkPaint2GrPaint(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint)) {
404bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon        return;
405bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    }
40611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
40725d9c154087d2132a51d1ca74a104726f60ef380joshualitt    fContext->drawVertices(fRenderTarget,
408570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt                           fClip,
40925d9c154087d2132a51d1ca74a104726f60ef380joshualitt                           grPaint,
4105531d51ce7426bdae7563547326fcf0bf926a083joshualitt                           *draw.fMatrix,
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);
4275531d51ce7426bdae7563547326fcf0bf926a083joshualitt    CHECK_SHOULD_DRAW(draw);
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
4455531d51ce7426bdae7563547326fcf0bf926a083joshualitt    if (!usePath && paint.isAntiAlias() && !draw.fMatrix->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 {
4525531d51ce7426bdae7563547326fcf0bf926a083joshualitt            usePath = !draw.fMatrix->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();
46449f085dddff10473b6ebf832a974288300224e60bsalomon    if (!usePath && pe && !strokeInfo.isDashed()) {
465d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        usePath = true;
466d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    }
467d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
46811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (usePath) {
46911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkPath path;
470b3eb687f8a89eb1eacd1afb4016401eb392f66abjvanverth        path.setIsVolatile(true);
47111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        path.addRect(rect);
47211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        this->drawPath(draw, path, paint, NULL, true);
47311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
47411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
47511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
47611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint grPaint;
477bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    if (!SkPaint2GrPaint(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint)) {
478bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon        return;
479bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    }
480744fb7313f31069e9eceeca4c0ff33dbe2fe1737Mike Klein
481570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    fContext->drawRect(fRenderTarget, fClip, grPaint, *draw.fMatrix, rect, &strokeInfo);
48211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
48311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
48411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
48511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
48611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rect,
4875531d51ce7426bdae7563547326fcf0bf926a083joshualitt                            const SkPaint& paint) {
488d78a168ec2ec2c07c0c1845e6a1781988e4a52d9egdaniel    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawRRect", fContext);
48911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_FOR_ANNOTATION(paint);
4905531d51ce7426bdae7563547326fcf0bf926a083joshualitt    CHECK_SHOULD_DRAW(draw);
49111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
492821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org    GrPaint grPaint;
493bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    if (!SkPaint2GrPaint(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint)) {
494bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon        return;
495bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    }
496744fb7313f31069e9eceeca4c0ff33dbe2fe1737Mike Klein
497d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    GrStrokeInfo strokeInfo(paint);
498821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org    if (paint.getMaskFilter()) {
499821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org        // try to hit the fast path for drawing filtered round rects
500821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org
501821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org        SkRRect devRRect;
5025531d51ce7426bdae7563547326fcf0bf926a083joshualitt        if (rect.transform(*draw.fMatrix, &devRRect)) {
503821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org            if (devRRect.allCornersCircular()) {
504821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                SkRect maskRect;
505821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                if (paint.getMaskFilter()->canFilterMaskGPU(devRRect.rect(),
5065531d51ce7426bdae7563547326fcf0bf926a083joshualitt                                                            draw.fClip->getBounds(),
5075531d51ce7426bdae7563547326fcf0bf926a083joshualitt                                                            *draw.fMatrix,
5085531d51ce7426bdae7563547326fcf0bf926a083joshualitt                                                            &maskRect)) {
509821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                    SkIRect finalIRect;
510821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                    maskRect.roundOut(&finalIRect);
511821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                    if (draw.fClip->quickReject(finalIRect)) {
512821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                        // clipped out
513821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                        return;
514821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                    }
51525d9c154087d2132a51d1ca74a104726f60ef380joshualitt                    if (paint.getMaskFilter()->directFilterRRectMaskGPU(fContext,
51625d9c154087d2132a51d1ca74a104726f60ef380joshualitt                                                                        fRenderTarget,
51725d9c154087d2132a51d1ca74a104726f60ef380joshualitt                                                                        &grPaint,
518570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt                                                                        fClip,
5195531d51ce7426bdae7563547326fcf0bf926a083joshualitt                                                                        *draw.fMatrix,
520d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel                                                                        strokeInfo.getStrokeRec(),
521d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel                                                                        devRRect)) {
522821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                        return;
523821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                    }
524821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org                }
525821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org
526821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org            }
527821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org        }
528821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org
529821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org    }
530821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org
531d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    bool usePath = false;
532d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
533d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    if (paint.getMaskFilter()) {
534d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        usePath = true;
535d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    } else {
536d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        const SkPathEffect* pe = paint.getPathEffect();
53749f085dddff10473b6ebf832a974288300224e60bsalomon        if (pe && !strokeInfo.isDashed()) {
538d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel            usePath = true;
539d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        }
540d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    }
541d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
542d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
543d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    if (usePath) {
54411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkPath path;
545b3eb687f8a89eb1eacd1afb4016401eb392f66abjvanverth        path.setIsVolatile(true);
54611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        path.addRRect(rect);
54711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        this->drawPath(draw, path, paint, NULL, true);
54811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
54911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
550744fb7313f31069e9eceeca4c0ff33dbe2fe1737Mike Klein
551570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    fContext->drawRRect(fRenderTarget, fClip, grPaint, *draw.fMatrix, rect, strokeInfo);
55211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
55311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
5540a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.orgvoid SkGpuDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
5555531d51ce7426bdae7563547326fcf0bf926a083joshualitt                             const SkRRect& inner, const SkPaint& paint) {
5560a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    SkStrokeRec stroke(paint);
5570a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    if (stroke.isFillStyle()) {
5580a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
5590a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        CHECK_FOR_ANNOTATION(paint);
5605531d51ce7426bdae7563547326fcf0bf926a083joshualitt        CHECK_SHOULD_DRAW(draw);
5610a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
5620a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        GrPaint grPaint;
563bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon        if (!SkPaint2GrPaint(this->context(), fRenderTarget, paint, *draw.fMatrix, true,
564bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon                             &grPaint)) {
565bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon            return;
566bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon        }
5670a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
5680a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        if (NULL == paint.getMaskFilter() && NULL == paint.getPathEffect()) {
569570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt            fContext->drawDRRect(fRenderTarget, fClip, grPaint, *draw.fMatrix, outer, inner);
5700a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org            return;
5710a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        }
5720a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    }
5730a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
5740a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    SkPath path;
575b3eb687f8a89eb1eacd1afb4016401eb392f66abjvanverth    path.setIsVolatile(true);
5760a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    path.addRRect(outer);
5770a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    path.addRRect(inner);
5780a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    path.setFillType(SkPath::kEvenOdd_FillType);
5790a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
5800a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    this->drawPath(draw, path, paint, NULL, true);
5810a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org}
5820a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
5830a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
584821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////
58511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
58611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawOval(const SkDraw& draw, const SkRect& oval,
58711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           const SkPaint& paint) {
588d78a168ec2ec2c07c0c1845e6a1781988e4a52d9egdaniel    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawOval", fContext);
58911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_FOR_ANNOTATION(paint);
5905531d51ce7426bdae7563547326fcf0bf926a083joshualitt    CHECK_SHOULD_DRAW(draw);
59111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
592d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    GrStrokeInfo strokeInfo(paint);
593d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
59411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    bool usePath = false;
59511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // some basic reasons we might need to call drawPath...
596d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    if (paint.getMaskFilter()) {
59711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        usePath = true;
598d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    } else {
599d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        const SkPathEffect* pe = paint.getPathEffect();
60049f085dddff10473b6ebf832a974288300224e60bsalomon        if (pe && !strokeInfo.isDashed()) {
601d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel            usePath = true;
602d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        }
60311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
60411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
60511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (usePath) {
60611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkPath path;
607b3eb687f8a89eb1eacd1afb4016401eb392f66abjvanverth        path.setIsVolatile(true);
60811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        path.addOval(oval);
60911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        this->drawPath(draw, path, paint, NULL, true);
61011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
61111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
61211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
61311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint grPaint;
614bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    if (!SkPaint2GrPaint(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint)) {
615bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon        return;
616bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    }
61711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
618570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    fContext->drawOval(fRenderTarget, fClip, grPaint, *draw.fMatrix, oval, strokeInfo);
61911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
62011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
62111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com#include "SkMaskFilter.h"
62211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
62311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
62411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
62511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// helpers for applying mask filters
62611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comnamespace {
62711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
62811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// Draw a mask using the supplied paint. Since the coverage/geometry
62911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// is already burnt into the mask this boils down to a rect draw.
63011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// Return true if the mask was successfully drawn.
63125d9c154087d2132a51d1ca74a104726f60ef380joshualittbool draw_mask(GrContext* context,
63225d9c154087d2132a51d1ca74a104726f60ef380joshualitt               GrRenderTarget* rt,
633570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt               const GrClip& clip,
63425d9c154087d2132a51d1ca74a104726f60ef380joshualitt               const SkMatrix& viewMatrix,
63525d9c154087d2132a51d1ca74a104726f60ef380joshualitt               const SkRect& maskRect,
63625d9c154087d2132a51d1ca74a104726f60ef380joshualitt               GrPaint* grp,
63725d9c154087d2132a51d1ca74a104726f60ef380joshualitt               GrTexture* mask) {
63811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkMatrix matrix;
63911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    matrix.setTranslate(-maskRect.fLeft, -maskRect.fTop);
64011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    matrix.postIDiv(mask->width(), mask->height());
64111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
64216b278989532ee9f9a38e3eb4754b228ff495cb8joshualitt    grp->addCoverageProcessor(GrSimpleTextureEffect::Create(mask, matrix,
64316b278989532ee9f9a38e3eb4754b228ff495cb8joshualitt                                                            kDevice_GrCoordSet))->unref();
64416b278989532ee9f9a38e3eb4754b228ff495cb8joshualitt
64516b278989532ee9f9a38e3eb4754b228ff495cb8joshualitt    SkMatrix inverse;
64616b278989532ee9f9a38e3eb4754b228ff495cb8joshualitt    if (!viewMatrix.invert(&inverse)) {
64716b278989532ee9f9a38e3eb4754b228ff495cb8joshualitt        return false;
64816b278989532ee9f9a38e3eb4754b228ff495cb8joshualitt    }
649570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    context->drawNonAARectWithLocalMatrix(rt, clip, *grp, SkMatrix::I(), maskRect, inverse);
65011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    return true;
65111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
65211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
6535efb8b8407c956b7fbb85236f3f538f2a104fe98joshualittstatic bool clip_bounds_quick_reject(const SkIRect& clipBounds, const SkIRect& rect) {
6545efb8b8407c956b7fbb85236f3f538f2a104fe98joshualitt    return clipBounds.isEmpty() || rect.isEmpty() || !SkIRect::Intersects(clipBounds, rect);
6555efb8b8407c956b7fbb85236f3f538f2a104fe98joshualitt}
6565efb8b8407c956b7fbb85236f3f538f2a104fe98joshualitt
65725d9c154087d2132a51d1ca74a104726f60ef380joshualittbool draw_with_mask_filter(GrContext* context,
65825d9c154087d2132a51d1ca74a104726f60ef380joshualitt                           GrRenderTarget* rt,
659570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt                           const GrClip& clipData,
66025d9c154087d2132a51d1ca74a104726f60ef380joshualitt                           const SkMatrix& viewMatrix,
66125d9c154087d2132a51d1ca74a104726f60ef380joshualitt                           const SkPath& devPath,
66225d9c154087d2132a51d1ca74a104726f60ef380joshualitt                           SkMaskFilter* filter,
6635efb8b8407c956b7fbb85236f3f538f2a104fe98joshualitt                           const SkIRect& clipBounds,
66425d9c154087d2132a51d1ca74a104726f60ef380joshualitt                           GrPaint* grp,
66525d9c154087d2132a51d1ca74a104726f60ef380joshualitt                           SkPaint::Style style) {
66611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkMask  srcM, dstM;
66711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
6685efb8b8407c956b7fbb85236f3f538f2a104fe98joshualitt    if (!SkDraw::DrawToMask(devPath, &clipBounds, filter, &viewMatrix, &srcM,
66911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                            SkMask::kComputeBoundsAndRenderImage_CreateMode, style)) {
67011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
67111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
67211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoMaskFreeImage autoSrc(srcM.fImage);
67311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
6745531d51ce7426bdae7563547326fcf0bf926a083joshualitt    if (!filter->filterMask(&dstM, srcM, viewMatrix, NULL)) {
67511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
67611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
67711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // this will free-up dstM when we're done (allocated in filterMask())
67811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoMaskFreeImage autoDst(dstM.fImage);
67911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
6805efb8b8407c956b7fbb85236f3f538f2a104fe98joshualitt    if (clip_bounds_quick_reject(clipBounds, dstM.fBounds)) {
68111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
68211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
68311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
68411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // we now have a device-aligned 8bit mask in dstM, ready to be drawn using
68511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // the current clip (and identity matrix) and GrPaint settings
686f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon    GrSurfaceDesc desc;
68711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fWidth = dstM.fBounds.width();
68811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fHeight = dstM.fBounds.height();
68911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fConfig = kAlpha_8_GrPixelConfig;
69011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
691d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon    SkAutoTUnref<GrTexture> texture(context->textureProvider()->refScratchTexture(
692d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon        desc, GrTextureProvider::kApprox_ScratchTexMatch));
693e30597375c19dfb5197fd065a3d1768401eb00fabsalomon    if (!texture) {
69411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
69511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
69611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
69711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                               dstM.fImage, dstM.fRowBytes);
69811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
69911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect maskRect = SkRect::Make(dstM.fBounds);
70011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
701570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    return draw_mask(context, rt, clipData, viewMatrix, maskRect, grp, texture);
70211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
70311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
704e30597375c19dfb5197fd065a3d1768401eb00fabsalomon// Create a mask of 'devPath' and place the result in 'mask'.
705e30597375c19dfb5197fd065a3d1768401eb00fabsalomonGrTexture* create_mask_GPU(GrContext* context,
70625d9c154087d2132a51d1ca74a104726f60ef380joshualitt                           GrRenderTarget* rt,
707e30597375c19dfb5197fd065a3d1768401eb00fabsalomon                           const SkRect& maskRect,
708e30597375c19dfb5197fd065a3d1768401eb00fabsalomon                           const SkPath& devPath,
709e30597375c19dfb5197fd065a3d1768401eb00fabsalomon                           const GrStrokeInfo& strokeInfo,
710e30597375c19dfb5197fd065a3d1768401eb00fabsalomon                           bool doAA,
711e30597375c19dfb5197fd065a3d1768401eb00fabsalomon                           int sampleCnt) {
712f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon    GrSurfaceDesc desc;
713f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon    desc.fFlags = kRenderTarget_GrSurfaceFlag;
71411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fWidth = SkScalarCeilToInt(maskRect.width());
71511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fHeight = SkScalarCeilToInt(maskRect.height());
716e30597375c19dfb5197fd065a3d1768401eb00fabsalomon    desc.fSampleCnt = doAA ? sampleCnt : 0;
71711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // We actually only need A8, but it often isn't supported as a
71811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // render target so default to RGBA_8888
71911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fConfig = kRGBA_8888_GrPixelConfig;
720f4555aa53c62a4cb396c77aeed809b5c103349e0derekf
721f4555aa53c62a4cb396c77aeed809b5c103349e0derekf    if (context->isConfigRenderable(kAlpha_8_GrPixelConfig,
722f4555aa53c62a4cb396c77aeed809b5c103349e0derekf                                    desc.fSampleCnt > 0)) {
72311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        desc.fConfig = kAlpha_8_GrPixelConfig;
72411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
72511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
726d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon    GrTexture* mask = context->textureProvider()->refScratchTexture(
727d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon        desc, GrTextureProvider::kApprox_ScratchTexMatch);
728e30597375c19dfb5197fd065a3d1768401eb00fabsalomon    if (NULL == mask) {
729e30597375c19dfb5197fd065a3d1768401eb00fabsalomon        return NULL;
73011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
73111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
73211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect clipRect = SkRect::MakeWH(maskRect.width(), maskRect.height());
73311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
73489c62980c1eb50b2090f33312086c7e8c66739b4bsalomon    context->clear(NULL, 0x0, true, mask->asRenderTarget());
73511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
73611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint tempPaint;
737b197b8ff31b73ccb20423023e03592df8ae78ea6egdaniel    tempPaint.setAntiAlias(doAA);
738b197b8ff31b73ccb20423023e03592df8ae78ea6egdaniel    tempPaint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op);
73911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
740570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    // setup new clip
741570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    GrClip clip(clipRect);
742570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt
74311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // Draw the mask into maskTexture with the path's top-left at the origin using tempPaint.
74411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkMatrix translate;
74511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    translate.setTranslate(-maskRect.fLeft, -maskRect.fTop);
746570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    context->drawPath(mask->asRenderTarget(), clip, tempPaint, translate, devPath, strokeInfo);
747e30597375c19dfb5197fd065a3d1768401eb00fabsalomon    return mask;
74811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
74911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
750d0d37cace08f12abf8d316e6949e947551d418e6senorblancoSkBitmap wrap_texture(GrTexture* texture, int width, int height) {
75111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkBitmap result;
752d0d37cace08f12abf8d316e6949e947551d418e6senorblanco    result.setInfo(SkImageInfo::MakeN32Premul(width, height));
7536c22573edb234ad14df947278cfed010669a39a7reed    result.setPixelRef(SkNEW_ARGS(SkGrPixelRef, (result.info(), texture)))->unref();
75411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    return result;
75511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
75611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
75711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com};
75811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
75911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
76011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           const SkPaint& paint, const SkMatrix* prePathMatrix,
76111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           bool pathIsMutable) {
76211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    CHECK_FOR_ANNOTATION(paint);
7635531d51ce7426bdae7563547326fcf0bf926a083joshualitt    CHECK_SHOULD_DRAW(draw);
764d78a168ec2ec2c07c0c1845e6a1781988e4a52d9egdaniel    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPath", fContext);
76511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
7665efb8b8407c956b7fbb85236f3f538f2a104fe98joshualitt    return this->internalDrawPath(origSrcPath, paint, *draw.fMatrix, prePathMatrix,
7675efb8b8407c956b7fbb85236f3f538f2a104fe98joshualitt                                  draw.fClip->getBounds(), pathIsMutable);
7685efb8b8407c956b7fbb85236f3f538f2a104fe98joshualitt}
7695efb8b8407c956b7fbb85236f3f538f2a104fe98joshualitt
7705efb8b8407c956b7fbb85236f3f538f2a104fe98joshualittvoid SkGpuDevice::internalDrawPath(const SkPath& origSrcPath, const SkPaint& paint,
7715efb8b8407c956b7fbb85236f3f538f2a104fe98joshualitt                                   const SkMatrix& origViewMatrix, const SkMatrix* prePathMatrix,
7725efb8b8407c956b7fbb85236f3f538f2a104fe98joshualitt                                   const SkIRect& clipBounds, bool pathIsMutable) {
773b3eb687f8a89eb1eacd1afb4016401eb392f66abjvanverth    SkASSERT(!pathIsMutable || origSrcPath.isVolatile());
7745531d51ce7426bdae7563547326fcf0bf926a083joshualitt
77554443932e86812258eda6ec23d0a0827822edf19bsalomon    GrStrokeInfo strokeInfo(paint);
77611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
77711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // If we have a prematrix, apply it to the path, optimizing for the case
77811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // where the original path can in fact be modified in place (even though
77911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // its parameter type is const).
78011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkPath* pathPtr = const_cast<SkPath*>(&origSrcPath);
781f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org    SkTLazy<SkPath> tmpPath;
782f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org    SkTLazy<SkPath> effectPath;
78354443932e86812258eda6ec23d0a0827822edf19bsalomon    SkPathEffect* pathEffect = paint.getPathEffect();
78454443932e86812258eda6ec23d0a0827822edf19bsalomon
7855efb8b8407c956b7fbb85236f3f538f2a104fe98joshualitt    SkMatrix viewMatrix = origViewMatrix;
78611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
78711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (prePathMatrix) {
788fc0725645cee5dabc8d282da4c1fab7335152e15joshualitt        // stroking, path effects, and blurs are supposed to be applied *after* the prePathMatrix.
789fc0725645cee5dabc8d282da4c1fab7335152e15joshualitt        // The pre-path-matrix also should not affect shading.
790fc0725645cee5dabc8d282da4c1fab7335152e15joshualitt        if (NULL == paint.getMaskFilter() && NULL == pathEffect && NULL == paint.getShader() &&
79154443932e86812258eda6ec23d0a0827822edf19bsalomon            (strokeInfo.getStrokeRec().isFillStyle() ||
79254443932e86812258eda6ec23d0a0827822edf19bsalomon             strokeInfo.getStrokeRec().isHairlineStyle())) {
79354443932e86812258eda6ec23d0a0827822edf19bsalomon            viewMatrix.preConcat(*prePathMatrix);
79454443932e86812258eda6ec23d0a0827822edf19bsalomon        } else {
79554443932e86812258eda6ec23d0a0827822edf19bsalomon            SkPath* result = pathPtr;
79611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
79754443932e86812258eda6ec23d0a0827822edf19bsalomon            if (!pathIsMutable) {
79854443932e86812258eda6ec23d0a0827822edf19bsalomon                result = tmpPath.init();
79954443932e86812258eda6ec23d0a0827822edf19bsalomon                result->setIsVolatile(true);
80054443932e86812258eda6ec23d0a0827822edf19bsalomon                pathIsMutable = true;
80154443932e86812258eda6ec23d0a0827822edf19bsalomon            }
80254443932e86812258eda6ec23d0a0827822edf19bsalomon            // should I push prePathMatrix on our MV stack temporarily, instead
80354443932e86812258eda6ec23d0a0827822edf19bsalomon            // of applying it here? See SkDraw.cpp
80454443932e86812258eda6ec23d0a0827822edf19bsalomon            pathPtr->transform(*prePathMatrix, result);
80554443932e86812258eda6ec23d0a0827822edf19bsalomon            pathPtr = result;
80611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
80711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
80811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // at this point we're done with prePathMatrix
80911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;)
81011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
81154443932e86812258eda6ec23d0a0827822edf19bsalomon    GrPaint grPaint;
812bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    if (!SkPaint2GrPaint(this->context(), fRenderTarget, paint, viewMatrix, true, &grPaint)) {
813bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon        return;
814bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    }
81554443932e86812258eda6ec23d0a0827822edf19bsalomon
81611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    const SkRect* cullRect = NULL;  // TODO: what is our bounds?
817d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    SkStrokeRec* strokePtr = strokeInfo.getStrokeRecPtr();
818280a9c81aa38271bc3b8ad4d442dd894cd2af3dbkkinnunen    if (!strokeInfo.isDashed() && pathEffect && pathEffect->filterPath(effectPath.init(), *pathPtr,
819280a9c81aa38271bc3b8ad4d442dd894cd2af3dbkkinnunen                                                                       strokePtr, cullRect)) {
820f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org        pathPtr = effectPath.get();
821f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org        pathIsMutable = true;
82211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
82311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
824d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    const SkStrokeRec& stroke = strokeInfo.getStrokeRec();
82511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (paint.getMaskFilter()) {
82611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (!stroke.isHairlineStyle()) {
827f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org            SkPath* strokedPath = pathIsMutable ? pathPtr : tmpPath.init();
828280a9c81aa38271bc3b8ad4d442dd894cd2af3dbkkinnunen            if (strokeInfo.isDashed()) {
829280a9c81aa38271bc3b8ad4d442dd894cd2af3dbkkinnunen                if (pathEffect->filterPath(strokedPath, *pathPtr, strokePtr, cullRect)) {
830280a9c81aa38271bc3b8ad4d442dd894cd2af3dbkkinnunen                    pathPtr = strokedPath;
831280a9c81aa38271bc3b8ad4d442dd894cd2af3dbkkinnunen                    pathIsMutable = true;
832280a9c81aa38271bc3b8ad4d442dd894cd2af3dbkkinnunen                }
833280a9c81aa38271bc3b8ad4d442dd894cd2af3dbkkinnunen                strokeInfo.removeDash();
834280a9c81aa38271bc3b8ad4d442dd894cd2af3dbkkinnunen            }
835f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org            if (stroke.applyToPath(strokedPath, *pathPtr)) {
836f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org                pathPtr = strokedPath;
83711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                pathIsMutable = true;
838d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel                strokeInfo.setFillStyle();
83911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
84011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
84111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
84211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // avoid possibly allocating a new path in transform if we can
843f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org        SkPath* devPathPtr = pathIsMutable ? pathPtr : tmpPath.init();
844b3eb687f8a89eb1eacd1afb4016401eb392f66abjvanverth        if (!pathIsMutable) {
845b3eb687f8a89eb1eacd1afb4016401eb392f66abjvanverth            devPathPtr->setIsVolatile(true);
846b3eb687f8a89eb1eacd1afb4016401eb392f66abjvanverth        }
84711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
84811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // transform the path into device space
84954443932e86812258eda6ec23d0a0827822edf19bsalomon        pathPtr->transform(viewMatrix, devPathPtr);
8504c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com
85111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkRect maskRect;
85211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (paint.getMaskFilter()->canFilterMaskGPU(devPathPtr->getBounds(),
8535efb8b8407c956b7fbb85236f3f538f2a104fe98joshualitt                                                    clipBounds,
85454443932e86812258eda6ec23d0a0827822edf19bsalomon                                                    viewMatrix,
85511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                                    &maskRect)) {
85611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkIRect finalIRect;
85711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            maskRect.roundOut(&finalIRect);
8585efb8b8407c956b7fbb85236f3f538f2a104fe98joshualitt            if (clip_bounds_quick_reject(clipBounds, finalIRect)) {
85911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                // clipped out
86011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                return;
86111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
8624c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com
86325d9c154087d2132a51d1ca74a104726f60ef380joshualitt            if (paint.getMaskFilter()->directFilterMaskGPU(fContext,
86425d9c154087d2132a51d1ca74a104726f60ef380joshualitt                                                           fRenderTarget,
86525d9c154087d2132a51d1ca74a104726f60ef380joshualitt                                                           &grPaint,
866570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt                                                           fClip,
86725d9c154087d2132a51d1ca74a104726f60ef380joshualitt                                                           viewMatrix,
86825d9c154087d2132a51d1ca74a104726f60ef380joshualitt                                                           stroke,
86925d9c154087d2132a51d1ca74a104726f60ef380joshualitt                                                           *devPathPtr)) {
870cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org                // the mask filter was able to draw itself directly, so there's nothing
871cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org                // left to do.
872cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org                return;
873cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org            }
87411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
87511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
87625d9c154087d2132a51d1ca74a104726f60ef380joshualitt            SkAutoTUnref<GrTexture> mask(create_mask_GPU(fContext,
87725d9c154087d2132a51d1ca74a104726f60ef380joshualitt                                                         fRenderTarget,
87825d9c154087d2132a51d1ca74a104726f60ef380joshualitt                                                         maskRect,
87925d9c154087d2132a51d1ca74a104726f60ef380joshualitt                                                         *devPathPtr,
88025d9c154087d2132a51d1ca74a104726f60ef380joshualitt                                                         strokeInfo,
88125d9c154087d2132a51d1ca74a104726f60ef380joshualitt                                                         grPaint.isAntiAlias(),
882e30597375c19dfb5197fd065a3d1768401eb00fabsalomon                                                         fRenderTarget->numSamples()));
883e30597375c19dfb5197fd065a3d1768401eb00fabsalomon            if (mask) {
88411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                GrTexture* filtered;
88511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
88654443932e86812258eda6ec23d0a0827822edf19bsalomon                if (paint.getMaskFilter()->filterMaskGPU(mask, viewMatrix, maskRect, &filtered, true)) {
88711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    // filterMaskGPU gives us ownership of a ref to the result
88811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    SkAutoTUnref<GrTexture> atu(filtered);
889570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt                    if (draw_mask(fContext,
890570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt                                  fRenderTarget,
891570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt                                  fClip,
892570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt                                  viewMatrix,
893570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt                                  maskRect,
894570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt                                  &grPaint,
89525d9c154087d2132a51d1ca74a104726f60ef380joshualitt                                  filtered)) {
89611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                        // This path is completely drawn
89711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                        return;
89811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    }
89911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                }
90011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
90111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
90211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
90311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // draw the mask on the CPU - this is a fallthrough path in case the
90411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // GPU path fails
90511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkPaint::Style style = stroke.isHairlineStyle() ? SkPaint::kStroke_Style :
90611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                                          SkPaint::kFill_Style;
907570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt        draw_with_mask_filter(fContext, fRenderTarget, fClip, viewMatrix, *devPathPtr,
9085efb8b8407c956b7fbb85236f3f538f2a104fe98joshualitt                              paint.getMaskFilter(), clipBounds, &grPaint, style);
90911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
91011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
91111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
912570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    fContext->drawPath(fRenderTarget, fClip, grPaint, viewMatrix, *pathPtr, strokeInfo);
91311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
91411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
91511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comstatic const int kBmpSmallTileSize = 1 << 10;
91611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
91711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comstatic inline int get_tile_count(const SkIRect& srcRect, int tileSize)  {
91811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    int tilesX = (srcRect.fRight / tileSize) - (srcRect.fLeft / tileSize) + 1;
91911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    int tilesY = (srcRect.fBottom / tileSize) - (srcRect.fTop / tileSize) + 1;
92011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    return tilesX * tilesY;
92111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
92211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
92311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comstatic int determine_tile_size(const SkBitmap& bitmap, const SkIRect& src, int maxTileSize) {
92411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (maxTileSize <= kBmpSmallTileSize) {
92511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return maxTileSize;
92611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
92711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
92811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    size_t maxTileTotalTileSize = get_tile_count(src, maxTileSize);
92911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    size_t smallTotalTileSize = get_tile_count(src, kBmpSmallTileSize);
93011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
93111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    maxTileTotalTileSize *= maxTileSize * maxTileSize;
93211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    smallTotalTileSize *= kBmpSmallTileSize * kBmpSmallTileSize;
93311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
93411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (maxTileTotalTileSize > 2 * smallTotalTileSize) {
93511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return kBmpSmallTileSize;
93611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
93711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return maxTileSize;
93811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
93911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
94011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
94111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// Given a bitmap, an optional src rect, and a context with a clip and matrix determine what
94211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// pixels from the bitmap are necessary.
94311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comstatic void determine_clipped_src_rect(const GrContext* context,
94425d9c154087d2132a51d1ca74a104726f60ef380joshualitt                                       const GrRenderTarget* rt,
945570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt                                       const GrClip& clip,
9465531d51ce7426bdae7563547326fcf0bf926a083joshualitt                                       const SkMatrix& viewMatrix,
94711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                       const SkBitmap& bitmap,
94811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                       const SkRect* srcRectPtr,
94911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                       SkIRect* clippedSrcIRect) {
950570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    clip.getConservativeBounds(rt, clippedSrcIRect, NULL);
95111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkMatrix inv;
9525531d51ce7426bdae7563547326fcf0bf926a083joshualitt    if (!viewMatrix.invert(&inv)) {
95311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        clippedSrcIRect->setEmpty();
95411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
95511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
95611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect clippedSrcRect = SkRect::Make(*clippedSrcIRect);
95711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    inv.mapRect(&clippedSrcRect);
95849f085dddff10473b6ebf832a974288300224e60bsalomon    if (srcRectPtr) {
959a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        // we've setup src space 0,0 to map to the top left of the src rect.
960a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        clippedSrcRect.offset(srcRectPtr->fLeft, srcRectPtr->fTop);
96111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (!clippedSrcRect.intersect(*srcRectPtr)) {
96211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            clippedSrcIRect->setEmpty();
96311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            return;
96411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
96511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
96611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    clippedSrcRect.roundOut(clippedSrcIRect);
96711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkIRect bmpBounds = SkIRect::MakeWH(bitmap.width(), bitmap.height());
96811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (!clippedSrcIRect->intersect(bmpBounds)) {
96911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        clippedSrcIRect->setEmpty();
97011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
97111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
97211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
97311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.combool SkGpuDevice::shouldTileBitmap(const SkBitmap& bitmap,
9745531d51ce7426bdae7563547326fcf0bf926a083joshualitt                                   const SkMatrix& viewMatrix,
97511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   const GrTextureParams& params,
97611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   const SkRect* srcRectPtr,
97711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   int maxTileSize,
97811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   int* tileSize,
97911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   SkIRect* clippedSrcRect) const {
98011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // if bitmap is explictly texture backed then just use the texture
98149f085dddff10473b6ebf832a974288300224e60bsalomon    if (bitmap.getTexture()) {
98211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
98311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
98411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
98511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // if it's larger than the max tile size, then we have no choice but tiling.
98611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (bitmap.width() > maxTileSize || bitmap.height() > maxTileSize) {
987570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt        determine_clipped_src_rect(fContext, fRenderTarget, fClip, viewMatrix, bitmap,
988570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt                                   srcRectPtr, clippedSrcRect);
98911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        *tileSize = determine_tile_size(bitmap, *clippedSrcRect, maxTileSize);
99011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return true;
99111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
99211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
99311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (bitmap.width() * bitmap.height() < 4 * kBmpSmallTileSize * kBmpSmallTileSize) {
99411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
99511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
99611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
99711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // if the entire texture is already in our cache then no reason to tile it
99811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (GrIsBitmapInCache(fContext, bitmap, &params)) {
99911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
100011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
100111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
100211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // At this point we know we could do the draw by uploading the entire bitmap
100311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // as a texture. However, if the texture would be large compared to the
100411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // cache size and we don't require most of it for this draw then tile to
100511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // reduce the amount of upload and cache spill.
100611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
100711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // assumption here is that sw bitmap size is a good proxy for its size as
100811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // a texture
100911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    size_t bmpSize = bitmap.getSize();
101011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    size_t cacheSize;
101195c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org    fContext->getResourceCacheLimits(NULL, &cacheSize);
101211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (bmpSize < cacheSize / 2) {
101311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
101411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
101511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
101611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // Figure out how much of the src we will need based on the src rect and clipping.
1017570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    determine_clipped_src_rect(fContext, fRenderTarget, fClip, viewMatrix, bitmap, srcRectPtr,
101825d9c154087d2132a51d1ca74a104726f60ef380joshualitt                               clippedSrcRect);
101911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    *tileSize = kBmpSmallTileSize; // already know whole bitmap fits in one max sized tile.
102011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    size_t usedTileBytes = get_tile_count(*clippedSrcRect, kBmpSmallTileSize) *
102111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           kBmpSmallTileSize * kBmpSmallTileSize;
102211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
102311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    return usedTileBytes < 2 * bmpSize;
102411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
102511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1026a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.orgvoid SkGpuDevice::drawBitmap(const SkDraw& origDraw,
102711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                             const SkBitmap& bitmap,
102811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                             const SkMatrix& m,
102911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                             const SkPaint& paint) {
1030a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    SkMatrix concat;
1031a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    SkTCopyOnFirstWrite<SkDraw> draw(origDraw);
1032a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    if (!m.isIdentity()) {
1033a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        concat.setConcat(*draw->fMatrix, m);
1034a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        draw.writable()->fMatrix = &concat;
1035a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    }
1036a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    this->drawBitmapCommon(*draw, bitmap, NULL, NULL, paint, SkCanvas::kNone_DrawBitmapRectFlag);
103711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
103811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1039dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org// This method outsets 'iRect' by 'outset' all around and then clamps its extents to
104011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// 'clamp'. 'offset' is adjusted to remain positioned over the top-left corner
104111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// of 'iRect' for all possible outsets/clamps.
1042dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.orgstatic inline void clamped_outset_with_offset(SkIRect* iRect,
1043dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                                              int outset,
1044dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                                              SkPoint* offset,
1045dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                                              const SkIRect& clamp) {
1046dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    iRect->outset(outset, outset);
1047dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org
1048dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    int leftClampDelta = clamp.fLeft - iRect->fLeft;
1049dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    if (leftClampDelta > 0) {
1050dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org        offset->fX -= outset - leftClampDelta;
105111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        iRect->fLeft = clamp.fLeft;
105211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
1053dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org        offset->fX -= outset;
105411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
1055dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org
1056dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    int topClampDelta = clamp.fTop - iRect->fTop;
1057dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    if (topClampDelta > 0) {
1058dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org        offset->fY -= outset - topClampDelta;
105911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        iRect->fTop = clamp.fTop;
106011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
1061dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org        offset->fY -= outset;
106211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
106311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
106411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (iRect->fRight > clamp.fRight) {
106511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        iRect->fRight = clamp.fRight;
106611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
106711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (iRect->fBottom > clamp.fBottom) {
106811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        iRect->fBottom = clamp.fBottom;
106911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
107011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
107111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1072a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.orgstatic bool has_aligned_samples(const SkRect& srcRect,
1073a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                const SkRect& transformedRect) {
1074a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // detect pixel disalignment
1075a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    if (SkScalarAbs(SkScalarRoundToScalar(transformedRect.left()) -
1076a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            transformedRect.left()) < COLOR_BLEED_TOLERANCE &&
1077a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        SkScalarAbs(SkScalarRoundToScalar(transformedRect.top()) -
1078a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            transformedRect.top()) < COLOR_BLEED_TOLERANCE &&
1079a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        SkScalarAbs(transformedRect.width() - srcRect.width()) <
1080a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            COLOR_BLEED_TOLERANCE &&
1081a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        SkScalarAbs(transformedRect.height() - srcRect.height()) <
1082a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            COLOR_BLEED_TOLERANCE) {
1083a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        return true;
1084a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    }
1085a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    return false;
1086a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org}
1087a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org
1088a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.orgstatic bool may_color_bleed(const SkRect& srcRect,
1089a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                            const SkRect& transformedRect,
1090a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                            const SkMatrix& m) {
1091a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // Only gets called if has_aligned_samples returned false.
1092a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // So we can assume that sampling is axis aligned but not texel aligned.
1093a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    SkASSERT(!has_aligned_samples(srcRect, transformedRect));
1094a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    SkRect innerSrcRect(srcRect), innerTransformedRect,
1095a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        outerTransformedRect(transformedRect);
1096a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    innerSrcRect.inset(SK_ScalarHalf, SK_ScalarHalf);
1097a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    m.mapRect(&innerTransformedRect, innerSrcRect);
1098a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org
1099a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // The gap between outerTransformedRect and innerTransformedRect
1100a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // represents the projection of the source border area, which is
1101a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // problematic for color bleeding.  We must check whether any
1102a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // destination pixels sample the border area.
1103a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    outerTransformedRect.inset(COLOR_BLEED_TOLERANCE, COLOR_BLEED_TOLERANCE);
1104a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    innerTransformedRect.outset(COLOR_BLEED_TOLERANCE, COLOR_BLEED_TOLERANCE);
1105a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    SkIRect outer, inner;
1106a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    outerTransformedRect.round(&outer);
1107a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    innerTransformedRect.round(&inner);
1108a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // If the inner and outer rects round to the same result, it means the
1109a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    // border does not overlap any pixel centers. Yay!
1110a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    return inner != outer;
1111a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org}
1112a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org
1113a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.orgstatic bool needs_texture_domain(const SkBitmap& bitmap,
1114a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 const SkRect& srcRect,
1115a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 GrTextureParams &params,
1116a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 const SkMatrix& contextMatrix,
1117a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 bool bicubic) {
1118a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    bool needsTextureDomain = false;
1119d0d37cace08f12abf8d316e6949e947551d418e6senorblanco    GrTexture* tex = bitmap.getTexture();
1120d0d37cace08f12abf8d316e6949e947551d418e6senorblanco    int width = tex ? tex->width() : bitmap.width();
1121d0d37cace08f12abf8d316e6949e947551d418e6senorblanco    int height = tex ? tex->height() : bitmap.height();
1122a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org
1123a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    if (bicubic || params.filterMode() != GrTextureParams::kNone_FilterMode) {
1124a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        // Need texture domain if drawing a sub rect
1125d0d37cace08f12abf8d316e6949e947551d418e6senorblanco        needsTextureDomain = srcRect.width() < width ||
1126d0d37cace08f12abf8d316e6949e947551d418e6senorblanco                             srcRect.height() < height;
1127a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        if (!bicubic && needsTextureDomain && contextMatrix.rectStaysRect()) {
1128a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            // sampling is axis-aligned
1129a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            SkRect transformedRect;
1130a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            contextMatrix.mapRect(&transformedRect, srcRect);
1131a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org
1132a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            if (has_aligned_samples(srcRect, transformedRect)) {
1133a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                params.setFilterMode(GrTextureParams::kNone_FilterMode);
1134a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                needsTextureDomain = false;
1135a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            } else {
1136a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                needsTextureDomain = may_color_bleed(srcRect, transformedRect, contextMatrix);
1137a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org            }
1138a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        }
1139a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    }
1140a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    return needsTextureDomain;
1141a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org}
1142a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org
114311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawBitmapCommon(const SkDraw& draw,
114411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   const SkBitmap& bitmap,
114511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   const SkRect* srcRectPtr,
1146a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org                                   const SkSize* dstSizePtr,
114711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   const SkPaint& paint,
114811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                   SkCanvas::DrawBitmapRectFlags flags) {
11495531d51ce7426bdae7563547326fcf0bf926a083joshualitt    CHECK_SHOULD_DRAW(draw);
115011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
115111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect srcRect;
1152a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    SkSize dstSize;
1153dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    // If there is no src rect, or the src rect contains the entire bitmap then we're effectively
1154dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    // in the (easier) bleed case, so update flags.
115511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (NULL == srcRectPtr) {
1156a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        SkScalar w = SkIntToScalar(bitmap.width());
1157a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        SkScalar h = SkIntToScalar(bitmap.height());
1158a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        dstSize.fWidth = w;
1159a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        dstSize.fHeight = h;
1160a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        srcRect.set(0, 0, w, h);
116111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
116249f085dddff10473b6ebf832a974288300224e60bsalomon        SkASSERT(dstSizePtr);
116311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        srcRect = *srcRectPtr;
1164a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        dstSize = *dstSizePtr;
1165d0d37cace08f12abf8d316e6949e947551d418e6senorblanco    }
1166d0d37cace08f12abf8d316e6949e947551d418e6senorblanco    GrTexture* tex = bitmap.getTexture();
1167d0d37cace08f12abf8d316e6949e947551d418e6senorblanco    int width = tex ? tex->width() : bitmap.width();
1168d0d37cace08f12abf8d316e6949e947551d418e6senorblanco    int height = tex ? tex->height() : bitmap.height();
1169d0d37cace08f12abf8d316e6949e947551d418e6senorblanco    if (srcRect.fLeft <= 0 && srcRect.fTop <= 0 &&
1170d0d37cace08f12abf8d316e6949e947551d418e6senorblanco        srcRect.fRight >= width && srcRect.fBottom >= height) {
1171d0d37cace08f12abf8d316e6949e947551d418e6senorblanco        flags = (SkCanvas::DrawBitmapRectFlags) (flags | SkCanvas::kBleed_DrawBitmapRectFlag);
117211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
117311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1174367e1867b2d6901e3327d0707738d2bc7d13826ederekf    // If the render target is not msaa and draw is antialiased, we call
1175367e1867b2d6901e3327d0707738d2bc7d13826ederekf    // drawRect instead of drawing on the render target directly.
1176367e1867b2d6901e3327d0707738d2bc7d13826ederekf    // FIXME: the tiled bitmap code path doesn't currently support
1177367e1867b2d6901e3327d0707738d2bc7d13826ederekf    // anti-aliased edges, we work around that for now by drawing directly
1178367e1867b2d6901e3327d0707738d2bc7d13826ederekf    // if the image size exceeds maximum texture size.
1179367e1867b2d6901e3327d0707738d2bc7d13826ederekf    int maxTextureSize = fContext->getMaxTextureSize();
1180367e1867b2d6901e3327d0707738d2bc7d13826ederekf    bool directDraw = fRenderTarget->isMultisampled() ||
1181367e1867b2d6901e3327d0707738d2bc7d13826ederekf                      !paint.isAntiAlias() ||
1182367e1867b2d6901e3327d0707738d2bc7d13826ederekf                      bitmap.width() > maxTextureSize ||
1183367e1867b2d6901e3327d0707738d2bc7d13826ederekf                      bitmap.height() > maxTextureSize;
1184367e1867b2d6901e3327d0707738d2bc7d13826ederekf
1185367e1867b2d6901e3327d0707738d2bc7d13826ederekf    // we check whether dst rect are pixel aligned
1186367e1867b2d6901e3327d0707738d2bc7d13826ederekf    if (!directDraw) {
11875531d51ce7426bdae7563547326fcf0bf926a083joshualitt        bool staysRect = draw.fMatrix->rectStaysRect();
1188367e1867b2d6901e3327d0707738d2bc7d13826ederekf
1189367e1867b2d6901e3327d0707738d2bc7d13826ederekf        if (staysRect) {
1190367e1867b2d6901e3327d0707738d2bc7d13826ederekf            SkRect rect;
1191367e1867b2d6901e3327d0707738d2bc7d13826ederekf            SkRect dstRect = SkRect::MakeXYWH(0, 0, dstSize.fWidth, dstSize.fHeight);
11925531d51ce7426bdae7563547326fcf0bf926a083joshualitt            draw.fMatrix->mapRect(&rect, dstRect);
1193367e1867b2d6901e3327d0707738d2bc7d13826ederekf            const SkScalar *scalars = rect.asScalars();
1194367e1867b2d6901e3327d0707738d2bc7d13826ederekf            bool isDstPixelAligned = true;
1195367e1867b2d6901e3327d0707738d2bc7d13826ederekf            for (int i = 0; i < 4; i++) {
1196367e1867b2d6901e3327d0707738d2bc7d13826ederekf                if (!SkScalarIsInt(scalars[i])) {
1197367e1867b2d6901e3327d0707738d2bc7d13826ederekf                    isDstPixelAligned = false;
1198367e1867b2d6901e3327d0707738d2bc7d13826ederekf                    break;
1199367e1867b2d6901e3327d0707738d2bc7d13826ederekf                }
1200367e1867b2d6901e3327d0707738d2bc7d13826ederekf            }
1201367e1867b2d6901e3327d0707738d2bc7d13826ederekf
1202367e1867b2d6901e3327d0707738d2bc7d13826ederekf            if (isDstPixelAligned)
1203367e1867b2d6901e3327d0707738d2bc7d13826ederekf                directDraw = true;
1204367e1867b2d6901e3327d0707738d2bc7d13826ederekf        }
1205367e1867b2d6901e3327d0707738d2bc7d13826ederekf    }
1206367e1867b2d6901e3327d0707738d2bc7d13826ederekf
1207367e1867b2d6901e3327d0707738d2bc7d13826ederekf    if (paint.getMaskFilter() || !directDraw) {
120811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // Convert the bitmap to a shader so that the rect can be drawn
120911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // through drawRect, which supports mask filters.
121011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkBitmap        tmp;    // subset of bitmap, if necessary
121111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        const SkBitmap* bitmapPtr = &bitmap;
1212a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        SkMatrix localM;
121349f085dddff10473b6ebf832a974288300224e60bsalomon        if (srcRectPtr) {
1214a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org            localM.setTranslate(-srcRectPtr->fLeft, -srcRectPtr->fTop);
1215a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org            localM.postScale(dstSize.fWidth / srcRectPtr->width(),
1216a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org                             dstSize.fHeight / srcRectPtr->height());
1217d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org            // In bleed mode we position and trim the bitmap based on the src rect which is
1218d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org            // already accounted for in 'm' and 'srcRect'. In clamp mode we need to chop out
1219d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org            // the desired portion of the bitmap and then update 'm' and 'srcRect' to
1220d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org            // compensate.
1221d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org            if (!(SkCanvas::kBleed_DrawBitmapRectFlag & flags)) {
1222d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                SkIRect iSrc;
1223d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                srcRect.roundOut(&iSrc);
1224d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org
1225d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                SkPoint offset = SkPoint::Make(SkIntToScalar(iSrc.fLeft),
1226d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                                               SkIntToScalar(iSrc.fTop));
1227d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org
1228d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                if (!bitmap.extractSubset(&tmp, iSrc)) {
1229d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                    return;     // extraction failed
1230d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                }
1231d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                bitmapPtr = &tmp;
1232d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                srcRect.offset(-offset.fX, -offset.fY);
1233a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org
1234d6ca4ac1ee2a0096b42b02e9408181c9e0387939commit-bot@chromium.org                // The source rect has changed so update the matrix
1235a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org                localM.preTranslate(offset.fX, offset.fY);
123611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
1237a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        } else {
1238a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org            localM.reset();
123911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
124011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1241a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        SkPaint paintWithShader(paint);
1242a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        paintWithShader.setShader(SkShader::CreateBitmapShader(*bitmapPtr,
12439c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org            SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, &localM))->unref();
1244a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        SkRect dstRect = {0, 0, dstSize.fWidth, dstSize.fHeight};
1245a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        this->drawRect(draw, dstRect, paintWithShader);
124611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
124711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
124811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
124911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1250a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    // If there is no mask filter than it is OK to handle the src rect -> dst rect scaling using
1251a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    // the view matrix rather than a local matrix.
1252a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    SkMatrix m;
1253a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    m.setScale(dstSize.fWidth / srcRect.width(),
1254a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org               dstSize.fHeight / srcRect.height());
12555531d51ce7426bdae7563547326fcf0bf926a083joshualitt    SkMatrix viewM = *draw.fMatrix;
12565531d51ce7426bdae7563547326fcf0bf926a083joshualitt    viewM.preConcat(m);
125711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
125811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTextureParams params;
125993a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed    SkFilterQuality paintFilterQuality = paint.getFilterQuality();
126011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTextureParams::FilterMode textureFilterMode;
1261dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org
1262dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    bool doBicubic = false;
1263dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org
126493a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed    switch(paintFilterQuality) {
126593a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed        case kNone_SkFilterQuality:
126611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            textureFilterMode = GrTextureParams::kNone_FilterMode;
126711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            break;
126893a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed        case kLow_SkFilterQuality:
126911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            textureFilterMode = GrTextureParams::kBilerp_FilterMode;
127011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            break;
127193a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed        case kMedium_SkFilterQuality:
12725531d51ce7426bdae7563547326fcf0bf926a083joshualitt            if (viewM.getMinScale() < SK_Scalar1) {
127379b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org                textureFilterMode = GrTextureParams::kMipMap_FilterMode;
127479b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org            } else {
127579b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org                // Don't trigger MIP level generation unnecessarily.
127679b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org                textureFilterMode = GrTextureParams::kBilerp_FilterMode;
127779b7eeebdff3bfae8a517dc2e4763bc2c7f81557commit-bot@chromium.org            }
127811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            break;
127993a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed        case kHigh_SkFilterQuality:
1280cea9abb001b07eaf4340a78db708bfac9e8c68c2commit-bot@chromium.org            // Minification can look bad with the bicubic effect.
12819927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org            doBicubic =
12825531d51ce7426bdae7563547326fcf0bf926a083joshualitt                GrBicubicEffect::ShouldUseBicubic(viewM, &textureFilterMode);
128311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            break;
128411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        default:
128511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkErrorInternals::SetError( kInvalidPaint_SkError,
128611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                        "Sorry, I don't understand the filtering "
128711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                        "mode you asked for.  Falling back to "
128811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                        "MIPMaps.");
128911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            textureFilterMode = GrTextureParams::kMipMap_FilterMode;
129011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            break;
129111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
129211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
12939927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org    int tileFilterPad;
12949927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org    if (doBicubic) {
12959927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org        tileFilterPad = GrBicubicEffect::kFilterTexelPad;
12969927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org    } else if (GrTextureParams::kNone_FilterMode == textureFilterMode) {
12979927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org        tileFilterPad = 0;
12989927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org    } else {
12999927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org        tileFilterPad = 1;
13009927bd355fc1557aa2c98900266ba6f49f806889commit-bot@chromium.org    }
130111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    params.setFilterMode(textureFilterMode);
130211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1303dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    int maxTileSize = fContext->getMaxTextureSize() - 2 * tileFilterPad;
130411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    int tileSize;
130511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
130611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkIRect clippedSrcRect;
13075531d51ce7426bdae7563547326fcf0bf926a083joshualitt    if (this->shouldTileBitmap(bitmap, viewM, params, srcRectPtr, maxTileSize, &tileSize,
130811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                               &clippedSrcRect)) {
13095531d51ce7426bdae7563547326fcf0bf926a083joshualitt        this->drawTiledBitmap(bitmap, viewM, srcRect, clippedSrcRect, params, paint, flags,
13105531d51ce7426bdae7563547326fcf0bf926a083joshualitt                              tileSize, doBicubic);
131111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
131211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // take the simple case
1313a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        bool needsTextureDomain = needs_texture_domain(bitmap,
1314a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                                       srcRect,
1315a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                                       params,
13165531d51ce7426bdae7563547326fcf0bf926a083joshualitt                                                       viewM,
1317a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                                       doBicubic);
1318a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org        this->internalDrawBitmap(bitmap,
13195531d51ce7426bdae7563547326fcf0bf926a083joshualitt                                 viewM,
1320a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 srcRect,
1321a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 params,
1322a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 paint,
1323a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 flags,
1324a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 doBicubic,
1325a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                 needsTextureDomain);
132611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
132711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
132811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
132911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// Break 'bitmap' into several tiles to draw it since it has already
133011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// been determined to be too large to fit in VRAM
133111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap,
13325531d51ce7426bdae7563547326fcf0bf926a083joshualitt                                  const SkMatrix& viewMatrix,
133311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                  const SkRect& srcRect,
133411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                  const SkIRect& clippedSrcIRect,
133511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                  const GrTextureParams& params,
133611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                  const SkPaint& paint,
133711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                  SkCanvas::DrawBitmapRectFlags flags,
1338dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                                  int tileSize,
1339dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                                  bool bicubic) {
13409d5e3f11a35e2059476a55e52349d3c6b3058f70commit-bot@chromium.org    // The following pixel lock is technically redundant, but it is desirable
13419d5e3f11a35e2059476a55e52349d3c6b3058f70commit-bot@chromium.org    // to lock outside of the tile loop to prevent redecoding the whole image
13429d5e3f11a35e2059476a55e52349d3c6b3058f70commit-bot@chromium.org    // at each tile in cases where 'bitmap' holds an SkDiscardablePixelRef that
13439d5e3f11a35e2059476a55e52349d3c6b3058f70commit-bot@chromium.org    // is larger than the limit of the discardable memory pool.
13449d5e3f11a35e2059476a55e52349d3c6b3058f70commit-bot@chromium.org    SkAutoLockPixels alp(bitmap);
134511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect clippedSrcRect = SkRect::Make(clippedSrcIRect);
134611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
134711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    int nx = bitmap.width() / tileSize;
134811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    int ny = bitmap.height() / tileSize;
134911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    for (int x = 0; x <= nx; x++) {
135011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        for (int y = 0; y <= ny; y++) {
135111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkRect tileR;
135211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            tileR.set(SkIntToScalar(x * tileSize),
135311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                      SkIntToScalar(y * tileSize),
135411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                      SkIntToScalar((x + 1) * tileSize),
135511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                      SkIntToScalar((y + 1) * tileSize));
135611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
135711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            if (!SkRect::Intersects(tileR, clippedSrcRect)) {
135811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                continue;
135911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
136011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
136111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            if (!tileR.intersect(srcRect)) {
136211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                continue;
136311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
136411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
136511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkBitmap tmpB;
136611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkIRect iTileR;
136711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            tileR.roundOut(&iTileR);
136811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkPoint offset = SkPoint::Make(SkIntToScalar(iTileR.fLeft),
136911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                           SkIntToScalar(iTileR.fTop));
137011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1371a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org            // Adjust the context matrix to draw at the right x,y in device space
13725531d51ce7426bdae7563547326fcf0bf926a083joshualitt            SkMatrix viewM = viewMatrix;
1373a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org            SkMatrix tmpM;
1374a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org            tmpM.setTranslate(offset.fX - srcRect.fLeft, offset.fY - srcRect.fTop);
13755531d51ce7426bdae7563547326fcf0bf926a083joshualitt            viewM.preConcat(tmpM);
1376a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org
1377ec8bb946c37ace5d1ac76dfb56a9fc4be4fb142erobertphillips            if (GrTextureParams::kNone_FilterMode != params.filterMode() || bicubic) {
137811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                SkIRect iClampRect;
137911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
138011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                if (SkCanvas::kBleed_DrawBitmapRectFlag & flags) {
138111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    // In bleed mode we want to always expand the tile on all edges
138211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    // but stay within the bitmap bounds
138311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    iClampRect = SkIRect::MakeWH(bitmap.width(), bitmap.height());
138411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                } else {
138511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    // In texture-domain/clamp mode we only want to expand the
138611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    // tile on edges interior to "srcRect" (i.e., we want to
138711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    // not bleed across the original clamped edges)
138811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                    srcRect.roundOut(&iClampRect);
138911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                }
1390dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                int outset = bicubic ? GrBicubicEffect::kFilterTexelPad : 1;
1391dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                clamped_outset_with_offset(&iTileR, outset, &offset, iClampRect);
139211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
139311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
139411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            if (bitmap.extractSubset(&tmpB, iTileR)) {
139511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                // now offset it to make it "local" to our tmp bitmap
139611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                tileR.offset(-offset.fX, -offset.fY);
1397a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                GrTextureParams paramsTemp = params;
1398a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                bool needsTextureDomain = needs_texture_domain(bitmap,
1399a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                                               srcRect,
1400a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                                               paramsTemp,
14015531d51ce7426bdae7563547326fcf0bf926a083joshualitt                                                               viewM,
1402a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                                               bicubic);
1403a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                this->internalDrawBitmap(tmpB,
14045531d51ce7426bdae7563547326fcf0bf926a083joshualitt                                         viewM,
1405a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                         tileR,
1406a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                         paramsTemp,
1407a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                         paint,
1408a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                         flags,
1409a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                         bicubic,
1410a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                         needsTextureDomain);
141111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
141211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
141311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
141411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
141511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
141611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
141711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com/*
141811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com *  This is called by drawBitmap(), which has to handle images that may be too
141911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com *  large to be represented by a single texture.
142011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com *
142111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com *  internalDrawBitmap assumes that the specified bitmap will fit in a texture
142211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com *  and that non-texture portion of the GrPaint has already been setup.
142311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com */
142411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap,
14255531d51ce7426bdae7563547326fcf0bf926a083joshualitt                                     const SkMatrix& viewMatrix,
142611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                     const SkRect& srcRect,
142711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                     const GrTextureParams& params,
142811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                     const SkPaint& paint,
1429dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org                                     SkCanvas::DrawBitmapRectFlags flags,
1430a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                     bool bicubic,
1431a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org                                     bool needsTextureDomain) {
143211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkASSERT(bitmap.width() <= fContext->getMaxTextureSize() &&
143311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com             bitmap.height() <= fContext->getMaxTextureSize());
143411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
143511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTexture* texture;
1436bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon    AutoBitmapTexture abt(fContext, bitmap, &params, &texture);
143711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (NULL == texture) {
143811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
143911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
144011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1441a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    SkRect dstRect = {0, 0, srcRect.width(), srcRect.height() };
144211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect paintRect;
144311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkScalar wInv = SkScalarInvert(SkIntToScalar(texture->width()));
144411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkScalar hInv = SkScalarInvert(SkIntToScalar(texture->height()));
144511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    paintRect.setLTRB(SkScalarMul(srcRect.fLeft,   wInv),
144611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                      SkScalarMul(srcRect.fTop,    hInv),
144711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                      SkScalarMul(srcRect.fRight,  wInv),
144811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                      SkScalarMul(srcRect.fBottom, hInv));
144911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
145011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect textureDomain = SkRect::MakeEmpty();
1451b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    SkAutoTUnref<GrFragmentProcessor> fp;
1452a17773f0b0db6b195004d438ec6ceb9c99465482commit-bot@chromium.org    if (needsTextureDomain && !(flags & SkCanvas::kBleed_DrawBitmapRectFlag)) {
145311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // Use a constrained texture domain to avoid color bleeding
145411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkScalar left, top, right, bottom;
145511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (srcRect.width() > SK_Scalar1) {
145611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkScalar border = SK_ScalarHalf / texture->width();
145711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            left = paintRect.left() + border;
145811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            right = paintRect.right() - border;
145911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        } else {
146011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            left = right = SkScalarHalf(paintRect.left() + paintRect.right());
146111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
146211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (srcRect.height() > SK_Scalar1) {
146311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkScalar border = SK_ScalarHalf / texture->height();
146411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            top = paintRect.top() + border;
146511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            bottom = paintRect.bottom() - border;
146611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        } else {
146711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            top = bottom = SkScalarHalf(paintRect.top() + paintRect.bottom());
146811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
146911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        textureDomain.setLTRB(left, top, right, bottom);
14707d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org        if (bicubic) {
1471b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt            fp.reset(GrBicubicEffect::Create(texture, SkMatrix::I(), textureDomain));
14727d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org        } else {
1473b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt            fp.reset(GrTextureDomainEffect::Create(texture,
14745531d51ce7426bdae7563547326fcf0bf926a083joshualitt                                                   SkMatrix::I(),
14755531d51ce7426bdae7563547326fcf0bf926a083joshualitt                                                   textureDomain,
14765531d51ce7426bdae7563547326fcf0bf926a083joshualitt                                                   GrTextureDomain::kClamp_Mode,
14775531d51ce7426bdae7563547326fcf0bf926a083joshualitt                                                   params.filterMode()));
14787d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org        }
1479dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org    } else if (bicubic) {
1480bc91fd71faa2c5fd14423fecd18e50701c922cedcommit-bot@chromium.org        SkASSERT(GrTextureParams::kNone_FilterMode == params.filterMode());
1481bc91fd71faa2c5fd14423fecd18e50701c922cedcommit-bot@chromium.org        SkShader::TileMode tileModes[2] = { params.getTileModeX(), params.getTileModeY() };
1482b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        fp.reset(GrBicubicEffect::Create(texture, SkMatrix::I(), tileModes));
148311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
1484b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        fp.reset(GrSimpleTextureEffect::Create(texture, SkMatrix::I(), params));
148511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
148611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
148711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // Construct a GrPaint by setting the bitmap texture as the first effect and then configuring
148811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // the rest from the SkPaint.
148911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint grPaint;
1490b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    grPaint.addColorProcessor(fp);
14910689d7b12e7c427a077b003d3d8ae759d86f798freed    bool alphaOnly = !(kAlpha_8_SkColorType == bitmap.colorType());
149283d081ae1d731b5039e99823620f5e287542ee39bsalomon    GrColor paintColor = (alphaOnly) ? SkColor2GrColorJustAlpha(paint.getColor()) :
149383d081ae1d731b5039e99823620f5e287542ee39bsalomon                                       SkColor2GrColor(paint.getColor());
1494bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    if (!SkPaint2GrPaintNoShader(this->context(), fRenderTarget, paint, paintColor, false,
1495bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon                                 &grPaint)) {
1496bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon        return;
1497bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    }
149811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1499570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    fContext->drawNonAARectToRect(fRenderTarget, fClip, grPaint, viewMatrix, dstRect,
1500570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt                                  paintRect);
150111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
150211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
15032d97bc139a7de5813468bd3dbfd0037351ae5606fmalitabool SkGpuDevice::filterTexture(GrContext* context, GrTexture* texture,
1504d0d37cace08f12abf8d316e6949e947551d418e6senorblanco                                int width, int height,
15052d97bc139a7de5813468bd3dbfd0037351ae5606fmalita                                const SkImageFilter* filter,
15062d97bc139a7de5813468bd3dbfd0037351ae5606fmalita                                const SkImageFilter::Context& ctx,
15072d97bc139a7de5813468bd3dbfd0037351ae5606fmalita                                SkBitmap* result, SkIPoint* offset) {
150811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkASSERT(filter);
15092d97bc139a7de5813468bd3dbfd0037351ae5606fmalita
15102d97bc139a7de5813468bd3dbfd0037351ae5606fmalita    // FIXME: plumb actual surface props such that we don't have to lie about the flags here
15112d97bc139a7de5813468bd3dbfd0037351ae5606fmalita    //        (https://code.google.com/p/skia/issues/detail?id=3148).
15122d97bc139a7de5813468bd3dbfd0037351ae5606fmalita    SkDeviceImageFilterProxy proxy(this, SkSurfaceProps(0, getLeakyProperties().pixelGeometry()));
151311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
151411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (filter->canFilterImageGPU()) {
1515d0d37cace08f12abf8d316e6949e947551d418e6senorblanco        return filter->filterImageGPU(&proxy, wrap_texture(texture, width, height),
1516d0d37cace08f12abf8d316e6949e947551d418e6senorblanco                                      ctx, result, offset);
151711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
151811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
151911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
152011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
152111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
152211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
152311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                             int left, int top, const SkPaint& paint) {
152411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // drawSprite is defined to be in device coords.
15255531d51ce7426bdae7563547326fcf0bf926a083joshualitt    CHECK_SHOULD_DRAW(draw);
152611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
152711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoLockPixels alp(bitmap, !bitmap.getTexture());
152811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (!bitmap.getTexture() && !bitmap.readyToDraw()) {
152911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
153011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
153111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
153211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    int w = bitmap.width();
153311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    int h = bitmap.height();
153411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
153511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTexture* texture;
153611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // draw sprite uses the default texture params
1537bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon    AutoBitmapTexture abt(fContext, bitmap, NULL, &texture);
15385f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt    if (!texture) {
15395f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt        return;
15405f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt    }
154111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
154211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkImageFilter* filter = paint.getImageFilter();
154311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // This bitmap will own the filtered result as a texture.
154411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkBitmap filteredBitmap;
154511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
154649f085dddff10473b6ebf832a974288300224e60bsalomon    if (filter) {
15476776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org        SkIPoint offset = SkIPoint::Make(0, 0);
154811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkMatrix matrix(*draw.fMatrix);
154911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        matrix.postTranslate(SkIntToScalar(-left), SkIntToScalar(-top));
15504cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org        SkIRect clipBounds = SkIRect::MakeWH(bitmap.width(), bitmap.height());
1551be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblanco        SkAutoTUnref<SkImageFilter::Cache> cache(getImageFilterCache());
155255b6d8be997a447ef9ce0f029697677a940bfc24senorblanco        // This cache is transient, and is freed (along with all its contained
155355b6d8be997a447ef9ce0f029697677a940bfc24senorblanco        // textures) when it goes out of scope.
1554f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org        SkImageFilter::Context ctx(matrix, clipBounds, cache);
1555d0d37cace08f12abf8d316e6949e947551d418e6senorblanco        if (this->filterTexture(fContext, texture, w, h, filter, ctx, &filteredBitmap,
15562d97bc139a7de5813468bd3dbfd0037351ae5606fmalita                                &offset)) {
155711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            texture = (GrTexture*) filteredBitmap.getTexture();
155811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            w = filteredBitmap.width();
155911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            h = filteredBitmap.height();
15606776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org            left += offset.x();
15616776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org            top += offset.y();
156211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        } else {
156311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            return;
156411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
156511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
156611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
156711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint grPaint;
1568b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    grPaint.addColorTextureProcessor(texture, SkMatrix::I());
156911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1570bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    if (!SkPaint2GrPaintNoShader(this->context(), fRenderTarget, paint,
1571bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon                                 SkColor2GrColorJustAlpha(paint.getColor()), false, &grPaint)) {
1572bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon        return;
1573bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    }
157411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
157525d9c154087d2132a51d1ca74a104726f60ef380joshualitt    fContext->drawNonAARectToRect(fRenderTarget,
1576570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt                                  fClip,
157725d9c154087d2132a51d1ca74a104726f60ef380joshualitt                                  grPaint,
157816b278989532ee9f9a38e3eb4754b228ff495cb8joshualitt                                  SkMatrix::I(),
157916b278989532ee9f9a38e3eb4754b228ff495cb8joshualitt                                  SkRect::MakeXYWH(SkIntToScalar(left),
158016b278989532ee9f9a38e3eb4754b228ff495cb8joshualitt                                                   SkIntToScalar(top),
158116b278989532ee9f9a38e3eb4754b228ff495cb8joshualitt                                                   SkIntToScalar(w),
158216b278989532ee9f9a38e3eb4754b228ff495cb8joshualitt                                                   SkIntToScalar(h)),
158316b278989532ee9f9a38e3eb4754b228ff495cb8joshualitt                                  SkRect::MakeXYWH(0,
158416b278989532ee9f9a38e3eb4754b228ff495cb8joshualitt                                                   0,
158516b278989532ee9f9a38e3eb4754b228ff495cb8joshualitt                                                   SK_Scalar1 * w / texture->width(),
158616b278989532ee9f9a38e3eb4754b228ff495cb8joshualitt                                                   SK_Scalar1 * h / texture->height()));
158711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
158811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1589a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.orgvoid SkGpuDevice::drawBitmapRect(const SkDraw& origDraw, const SkBitmap& bitmap,
159011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                 const SkRect* src, const SkRect& dst,
159111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                 const SkPaint& paint,
159211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                 SkCanvas::DrawBitmapRectFlags flags) {
159311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkMatrix    matrix;
159411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect      bitmapBounds, tmpSrc;
159511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
159611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    bitmapBounds.set(0, 0,
159711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                     SkIntToScalar(bitmap.width()),
159811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                     SkIntToScalar(bitmap.height()));
159911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
160011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // Compute matrix from the two rectangles
160149f085dddff10473b6ebf832a974288300224e60bsalomon    if (src) {
160211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        tmpSrc = *src;
160311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
160411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        tmpSrc = bitmapBounds;
160511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
1606a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org
160711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit);
160811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
160911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // clip the tmpSrc to the bounds of the bitmap. No check needed if src==null.
161049f085dddff10473b6ebf832a974288300224e60bsalomon    if (src) {
161111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (!bitmapBounds.contains(tmpSrc)) {
161211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            if (!tmpSrc.intersect(bitmapBounds)) {
161311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                return; // nothing to draw
161411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            }
161511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
161611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
161711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1618a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    SkRect tmpDst;
1619a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    matrix.mapRect(&tmpDst, tmpSrc);
1620a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org
1621a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    SkTCopyOnFirstWrite<SkDraw> draw(origDraw);
1622a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    if (0 != tmpDst.fLeft || 0 != tmpDst.fTop) {
1623a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        // Translate so that tempDst's top left is at the origin.
1624a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        matrix = *origDraw.fMatrix;
1625a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        matrix.preTranslate(tmpDst.fLeft, tmpDst.fTop);
1626a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org        draw.writable()->fMatrix = &matrix;
1627a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    }
1628a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    SkSize dstSize;
1629a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    dstSize.fWidth = tmpDst.width();
1630a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    dstSize.fHeight = tmpDst.height();
1631a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org
1632a7d89c83a461aa3f549776060141a4f710de2da7commit-bot@chromium.org    this->drawBitmapCommon(*draw, bitmap, &tmpSrc, &dstSize, paint, flags);
163311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
163411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
163511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
163611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                             int x, int y, const SkPaint& paint) {
163711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // clear of the source device must occur before CHECK_SHOULD_DRAW
1638d78a168ec2ec2c07c0c1845e6a1781988e4a52d9egdaniel    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawDevice", fContext);
163911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkGpuDevice* dev = static_cast<SkGpuDevice*>(device);
16402e4414e60b1f98e1736aa1925cbe181ed37d11e8kkinnunen
16412e4414e60b1f98e1736aa1925cbe181ed37d11e8kkinnunen    // TODO: If the source device covers the whole of this device, we could
16422e4414e60b1f98e1736aa1925cbe181ed37d11e8kkinnunen    // omit fNeedsClear -related flushing.
16432e4414e60b1f98e1736aa1925cbe181ed37d11e8kkinnunen    // TODO: if source needs clear, we could maybe omit the draw fully.
164411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
164511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // drawDevice is defined to be in device coords.
16465531d51ce7426bdae7563547326fcf0bf926a083joshualitt    CHECK_SHOULD_DRAW(draw);
164711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
164811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrRenderTarget* devRT = dev->accessRenderTarget();
164911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTexture* devTex;
165011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (NULL == (devTex = devRT->asTexture())) {
165111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return;
165211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
165311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
16547b9e8a4b6af0f3df9bf20a5fdc0977bcd7c3c1abrobertphillips    const SkImageInfo ii = dev->imageInfo();
16557b9e8a4b6af0f3df9bf20a5fdc0977bcd7c3c1abrobertphillips    int w = ii.width();
16567b9e8a4b6af0f3df9bf20a5fdc0977bcd7c3c1abrobertphillips    int h = ii.height();
165711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
165811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkImageFilter* filter = paint.getImageFilter();
165911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // This bitmap will own the filtered result as a texture.
166011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkBitmap filteredBitmap;
166111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
166249f085dddff10473b6ebf832a974288300224e60bsalomon    if (filter) {
166311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkIPoint offset = SkIPoint::Make(0, 0);
166411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        SkMatrix matrix(*draw.fMatrix);
166511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y));
16664cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org        SkIRect clipBounds = SkIRect::MakeWH(devTex->width(), devTex->height());
166755b6d8be997a447ef9ce0f029697677a940bfc24senorblanco        // This cache is transient, and is freed (along with all its contained
166855b6d8be997a447ef9ce0f029697677a940bfc24senorblanco        // textures) when it goes out of scope.
1669be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblanco        SkAutoTUnref<SkImageFilter::Cache> cache(getImageFilterCache());
1670f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org        SkImageFilter::Context ctx(matrix, clipBounds, cache);
1671d0d37cace08f12abf8d316e6949e947551d418e6senorblanco        if (this->filterTexture(fContext, devTex, device->width(), device->height(),
1672d0d37cace08f12abf8d316e6949e947551d418e6senorblanco                                filter, ctx, &filteredBitmap, &offset)) {
167311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            devTex = filteredBitmap.getTexture();
167411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            w = filteredBitmap.width();
167511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            h = filteredBitmap.height();
167611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            x += offset.fX;
167711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            y += offset.fY;
167811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        } else {
167911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            return;
168011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
168111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
168211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
168311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrPaint grPaint;
1684b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    grPaint.addColorTextureProcessor(devTex, SkMatrix::I());
168511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1686bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    if (!SkPaint2GrPaintNoShader(this->context(), fRenderTarget, paint,
1687bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon                                 SkColor2GrColorJustAlpha(paint.getColor()), false, &grPaint)) {
1688bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon        return;
1689bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    }
169011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
169111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect dstRect = SkRect::MakeXYWH(SkIntToScalar(x),
169211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                      SkIntToScalar(y),
169311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                      SkIntToScalar(w),
169411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                      SkIntToScalar(h));
169511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
169611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // The device being drawn may not fill up its texture (e.g. saveLayer uses approximate
169711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // scratch texture).
169811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkRect srcRect = SkRect::MakeWH(SK_Scalar1 * w / devTex->width(),
169911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                    SK_Scalar1 * h / devTex->height());
170011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1701570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    fContext->drawNonAARectToRect(fRenderTarget, fClip, grPaint, SkMatrix::I(), dstRect,
1702570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt                                  srcRect);
170311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
170411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1705ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.orgbool SkGpuDevice::canHandleImageFilter(const SkImageFilter* filter) {
170611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    return filter->canFilterImageGPU();
170711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
170811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1709ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.orgbool SkGpuDevice::filterImage(const SkImageFilter* filter, const SkBitmap& src,
17104cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org                              const SkImageFilter::Context& ctx,
171111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                              SkBitmap* result, SkIPoint* offset) {
171211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // want explicitly our impl, so guard against a subclass of us overriding it
171311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (!this->SkGpuDevice::canHandleImageFilter(filter)) {
171411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
171511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
171611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
171711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoLockPixels alp(src, !src.getTexture());
171811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (!src.getTexture() && !src.readyToDraw()) {
171911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return false;
172011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
172111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
172211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    GrTexture* texture;
172311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // We assume here that the filter will not attempt to tile the src. Otherwise, this cache lookup
172411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // must be pushed upstack.
1725bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon    AutoBitmapTexture abt(fContext, src, NULL, &texture);
1726f83be823e435ecabd0655547f004556f6b589876robertphillips    if (!texture) {
1727f83be823e435ecabd0655547f004556f6b589876robertphillips        return false;
1728f83be823e435ecabd0655547f004556f6b589876robertphillips    }
172911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1730d0d37cace08f12abf8d316e6949e947551d418e6senorblanco    return this->filterTexture(fContext, texture, src.width(), src.height(),
1731d0d37cace08f12abf8d316e6949e947551d418e6senorblanco                               filter, ctx, result, offset);
173211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
173311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1734a85d4d0814818e4ddabb9237da209d61d6cd5854reedstatic bool wrap_as_bm(const SkImage* image, SkBitmap* bm) {
1735a85d4d0814818e4ddabb9237da209d61d6cd5854reed    GrTexture* tex = image->getTexture();
1736a85d4d0814818e4ddabb9237da209d61d6cd5854reed    if (tex) {
17378b26b99c97473f020df4b9d4ba789e074e06ceddreed        GrWrapTextureInBitmap(tex, image->width(), image->height(), image->isOpaque(), bm);
17388b26b99c97473f020df4b9d4ba789e074e06ceddreed        return true;
1739a85d4d0814818e4ddabb9237da209d61d6cd5854reed    } else {
17408b26b99c97473f020df4b9d4ba789e074e06ceddreed        return as_IB(image)->getROPixels(bm);
1741a85d4d0814818e4ddabb9237da209d61d6cd5854reed    }
1742a85d4d0814818e4ddabb9237da209d61d6cd5854reed}
1743a85d4d0814818e4ddabb9237da209d61d6cd5854reed
1744a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkGpuDevice::drawImage(const SkDraw& draw, const SkImage* image, SkScalar x, SkScalar y,
1745a85d4d0814818e4ddabb9237da209d61d6cd5854reed                            const SkPaint& paint) {
1746a85d4d0814818e4ddabb9237da209d61d6cd5854reed    SkBitmap bm;
1747a85d4d0814818e4ddabb9237da209d61d6cd5854reed    if (wrap_as_bm(image, &bm)) {
1748a85d4d0814818e4ddabb9237da209d61d6cd5854reed        this->drawBitmap(draw, bm, SkMatrix::MakeTrans(x, y), paint);
1749a85d4d0814818e4ddabb9237da209d61d6cd5854reed    }
1750a85d4d0814818e4ddabb9237da209d61d6cd5854reed}
1751a85d4d0814818e4ddabb9237da209d61d6cd5854reed
1752a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkGpuDevice::drawImageRect(const SkDraw& draw, const SkImage* image, const SkRect* src,
1753a85d4d0814818e4ddabb9237da209d61d6cd5854reed                                const SkRect& dst, const SkPaint& paint) {
1754a85d4d0814818e4ddabb9237da209d61d6cd5854reed    SkBitmap bm;
1755a85d4d0814818e4ddabb9237da209d61d6cd5854reed    if (wrap_as_bm(image, &bm)) {
1756a85d4d0814818e4ddabb9237da209d61d6cd5854reed        this->drawBitmapRect(draw, bm, src, dst, paint, SkCanvas::kNone_DrawBitmapRectFlag);
1757a85d4d0814818e4ddabb9237da209d61d6cd5854reed    }
1758a85d4d0814818e4ddabb9237da209d61d6cd5854reed}
1759a85d4d0814818e4ddabb9237da209d61d6cd5854reed
176011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
176111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
176211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com// must be in SkCanvas::VertexMode order
176311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comstatic const GrPrimitiveType gVertexMode2PrimitiveType[] = {
176411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    kTriangles_GrPrimitiveType,
176511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    kTriangleStrip_GrPrimitiveType,
176611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    kTriangleFan_GrPrimitiveType,
176711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com};
176811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
176911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
177011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                              int vertexCount, const SkPoint vertices[],
177111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                              const SkPoint texs[], const SkColor colors[],
177211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                              SkXfermode* xmode,
177311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                              const uint16_t indices[], int indexCount,
177411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                              const SkPaint& paint) {
17755531d51ce7426bdae7563547326fcf0bf926a083joshualitt    CHECK_SHOULD_DRAW(draw);
1776d78a168ec2ec2c07c0c1845e6a1781988e4a52d9egdaniel    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawVertices", fContext);
1777533eb782edaa0b6fece6166d3001edf72ec39f11mtklein
177832a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov    const uint16_t* outIndices;
177932a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov    SkAutoTDeleteArray<uint16_t> outAlloc(NULL);
178032a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov    GrPrimitiveType primType;
178132a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov    GrPaint grPaint;
1782a098dd490cc4e434f054b7506c2f6e08f519585bbsalomon
1783559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org    // If both textures and vertex-colors are NULL, strokes hairlines with the paint's color.
1784559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org    if ((NULL == texs || NULL == paint.getShader()) && NULL == colors) {
1785533eb782edaa0b6fece6166d3001edf72ec39f11mtklein
1786559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        texs = NULL;
1787533eb782edaa0b6fece6166d3001edf72ec39f11mtklein
1788559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        SkPaint copy(paint);
1789559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        copy.setStyle(SkPaint::kStroke_Style);
1790559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        copy.setStrokeWidth(0);
1791533eb782edaa0b6fece6166d3001edf72ec39f11mtklein
179232a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        // we ignore the shader if texs is null.
1793bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon        if (!SkPaint2GrPaintNoShader(this->context(), fRenderTarget, copy,
1794bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon                                     SkColor2GrColor(copy.getColor()), NULL == colors, &grPaint)) {
1795bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon            return;
1796bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon        }
1797559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org
179832a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        primType = kLines_GrPrimitiveType;
179932a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        int triangleCount = 0;
1800a098dd490cc4e434f054b7506c2f6e08f519585bbsalomon        int n = (NULL == indices) ? vertexCount : indexCount;
180132a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        switch (vmode) {
180232a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov            case SkCanvas::kTriangles_VertexMode:
1803a098dd490cc4e434f054b7506c2f6e08f519585bbsalomon                triangleCount = n / 3;
180432a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov                break;
180532a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov            case SkCanvas::kTriangleStrip_VertexMode:
180632a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov            case SkCanvas::kTriangleFan_VertexMode:
1807a098dd490cc4e434f054b7506c2f6e08f519585bbsalomon                triangleCount = n - 2;
180832a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov                break;
180932a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        }
1810533eb782edaa0b6fece6166d3001edf72ec39f11mtklein
1811559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        VertState       state(vertexCount, indices, indexCount);
1812559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        VertState::Proc vertProc = state.chooseProc(vmode);
1813533eb782edaa0b6fece6166d3001edf72ec39f11mtklein
181432a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        //number of indices for lines per triangle with kLines
181532a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        indexCount = triangleCount * 6;
1816533eb782edaa0b6fece6166d3001edf72ec39f11mtklein
181732a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        outAlloc.reset(SkNEW_ARRAY(uint16_t, indexCount));
181832a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        outIndices = outAlloc.get();
181932a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        uint16_t* auxIndices = outAlloc.get();
1820559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        int i = 0;
1821559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        while (vertProc(&state)) {
182232a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov            auxIndices[i]     = state.f0;
182332a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov            auxIndices[i + 1] = state.f1;
182432a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov            auxIndices[i + 2] = state.f1;
182532a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov            auxIndices[i + 3] = state.f2;
182632a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov            auxIndices[i + 4] = state.f2;
182732a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov            auxIndices[i + 5] = state.f0;
1828559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org            i += 6;
1829559a8833f0eae4af37dc0ffc3ee97e1fb14817b1commit-bot@chromium.org        }
183011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
183132a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        outIndices = indices;
183232a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        primType = gVertexMode2PrimitiveType[vmode];
1833533eb782edaa0b6fece6166d3001edf72ec39f11mtklein
183432a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        if (NULL == texs || NULL == paint.getShader()) {
1835bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon            if (!SkPaint2GrPaintNoShader(this->context(), fRenderTarget, paint,
1836bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon                                         SkColor2GrColor(paint.getColor()),
1837bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon                                         NULL == colors, &grPaint)) {
1838bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon                return;
1839bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon            }
184032a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        } else {
1841bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon            if (!SkPaint2GrPaint(this->context(), fRenderTarget, paint, *draw.fMatrix,
1842bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon                                 NULL == colors, &grPaint)) {
1843bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon                return;
1844bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon            }
184532a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov        }
184611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
184711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
18482583b6257fea931c31c6b3b75cc583106335ad90mtklein#if 0
184949f085dddff10473b6ebf832a974288300224e60bsalomon    if (xmode && texs && colors) {
185011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        if (!SkXfermode::IsMode(xmode, SkXfermode::kModulate_Mode)) {
185111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            SkDebugf("Unsupported vertex-color/texture xfer mode.\n");
18522583b6257fea931c31c6b3b75cc583106335ad90mtklein            return;
185311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
185411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
18552583b6257fea931c31c6b3b75cc583106335ad90mtklein#endif
185611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
185711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoSTMalloc<128, GrColor> convertedColors(0);
185849f085dddff10473b6ebf832a974288300224e60bsalomon    if (colors) {
185911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        // need to convert byte order and from non-PM to PM
186011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        convertedColors.reset(vertexCount);
1861c93e68161f78542d90b28b6cf9911b1de3788054commit-bot@chromium.org        SkColor color;
186211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        for (int i = 0; i < vertexCount; ++i) {
1863c93e68161f78542d90b28b6cf9911b1de3788054commit-bot@chromium.org            color = colors[i];
1864c93e68161f78542d90b28b6cf9911b1de3788054commit-bot@chromium.org            if (paint.getAlpha() != 255) {
1865c93e68161f78542d90b28b6cf9911b1de3788054commit-bot@chromium.org                color = SkColorSetA(color, SkMulDiv255Round(SkColorGetA(color), paint.getAlpha()));
1866c93e68161f78542d90b28b6cf9911b1de3788054commit-bot@chromium.org            }
1867c93e68161f78542d90b28b6cf9911b1de3788054commit-bot@chromium.org            convertedColors[i] = SkColor2GrColor(color);
186811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        }
186911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        colors = convertedColors.get();
187011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
187125d9c154087d2132a51d1ca74a104726f60ef380joshualitt    fContext->drawVertices(fRenderTarget,
1872570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt                           fClip,
187325d9c154087d2132a51d1ca74a104726f60ef380joshualitt                           grPaint,
18745531d51ce7426bdae7563547326fcf0bf926a083joshualitt                           *draw.fMatrix,
187532a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov                           primType,
187611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           vertexCount,
1877972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org                           vertices,
1878972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org                           texs,
187911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           colors,
188032a311bfc056169c9f3b1c299c57ff5139a0d8bcdandov                           outIndices,
188111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                           indexCount);
188211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
188311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
188411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
188511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
188611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::drawText(const SkDraw& draw, const void* text,
18875531d51ce7426bdae7563547326fcf0bf926a083joshualitt                           size_t byteLength, SkScalar x, SkScalar y,
18885531d51ce7426bdae7563547326fcf0bf926a083joshualitt                           const SkPaint& paint) {
18895531d51ce7426bdae7563547326fcf0bf926a083joshualitt    CHECK_SHOULD_DRAW(draw);
1890d78a168ec2ec2c07c0c1845e6a1781988e4a52d9egdaniel    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawText", fContext);
189111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
18928c27a188a0b216021d439eb627622d17b9f78343jvanverth    GrPaint grPaint;
1893bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    if (!SkPaint2GrPaint(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint)) {
1894bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon        return;
1895bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    }
18969f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org
18978c27a188a0b216021d439eb627622d17b9f78343jvanverth    SkDEBUGCODE(this->validate();)
18989f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org
18996e8cd9671958c69babde9338c5c18a4c3d895575joshualitt    fTextContext->drawText(fRenderTarget, fClip, grPaint, paint, *draw.fMatrix,
19006e8cd9671958c69babde9338c5c18a4c3d895575joshualitt                           (const char *)text, byteLength, x, y, draw.fClip->getBounds());
190111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
190211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
190305c4a4322e7d4f3417b7df33825bab8603d52051fmalitavoid SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, size_t byteLength,
190405c4a4322e7d4f3417b7df33825bab8603d52051fmalita                              const SkScalar pos[], int scalarsPerPos,
190505c4a4322e7d4f3417b7df33825bab8603d52051fmalita                              const SkPoint& offset, const SkPaint& paint) {
1906bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPosText", fContext);
19075531d51ce7426bdae7563547326fcf0bf926a083joshualitt    CHECK_SHOULD_DRAW(draw);
190811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
19098c27a188a0b216021d439eb627622d17b9f78343jvanverth    GrPaint grPaint;
1910bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    if (!SkPaint2GrPaint(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint)) {
1911bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon        return;
1912bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon    }
19134c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com
19148c27a188a0b216021d439eb627622d17b9f78343jvanverth    SkDEBUGCODE(this->validate();)
19154c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com
19166e8cd9671958c69babde9338c5c18a4c3d895575joshualitt    fTextContext->drawPosText(fRenderTarget, fClip, grPaint, paint, *draw.fMatrix,
19176e8cd9671958c69babde9338c5c18a4c3d895575joshualitt                              (const char *)text, byteLength, pos, scalarsPerPos, offset,
19186e8cd9671958c69babde9338c5c18a4c3d895575joshualitt                              draw.fClip->getBounds());
191911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
192011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
19219c328187d9dee33736b77dc14dfb59529d948bb1joshualittvoid SkGpuDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkScalar x, SkScalar y,
19229c328187d9dee33736b77dc14dfb59529d948bb1joshualitt                               const SkPaint& paint, SkDrawFilter* drawFilter) {
19239c328187d9dee33736b77dc14dfb59529d948bb1joshualitt    GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawTextBlob", fContext);
19249c328187d9dee33736b77dc14dfb59529d948bb1joshualitt    CHECK_SHOULD_DRAW(draw);
19259c328187d9dee33736b77dc14dfb59529d948bb1joshualitt
19269c328187d9dee33736b77dc14dfb59529d948bb1joshualitt    SkDEBUGCODE(this->validate();)
19279c328187d9dee33736b77dc14dfb59529d948bb1joshualitt
19289c328187d9dee33736b77dc14dfb59529d948bb1joshualitt    fTextContext->drawTextBlob(fRenderTarget, fClip, paint, *draw.fMatrix, blob, x, y, drawFilter,
19299c328187d9dee33736b77dc14dfb59529d948bb1joshualitt                               draw.fClip->getBounds());
19309c328187d9dee33736b77dc14dfb59529d948bb1joshualitt}
19319c328187d9dee33736b77dc14dfb59529d948bb1joshualitt
193211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
193311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
1934b2db898573e3cdcc8234eebf51961bfc4977ebbcreedbool SkGpuDevice::onShouldDisableLCD(const SkPaint& paint) const {
193511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    if (paint.getShader() ||
1936b2db898573e3cdcc8234eebf51961bfc4977ebbcreed        !SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode) ||
193711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        paint.getMaskFilter() ||
193811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        paint.getRasterizer() ||
193911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        paint.getColorFilter() ||
194011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        paint.getPathEffect() ||
194111a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        paint.isFakeBoldText() ||
1942b2db898573e3cdcc8234eebf51961bfc4977ebbcreed        paint.getStyle() != SkPaint::kFill_Style)
1943b2db898573e3cdcc8234eebf51961bfc4977ebbcreed    {
194411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return true;
194511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
194611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    return false;
194711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
194811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
194911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.comvoid SkGpuDevice::flush() {
195011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    DO_DEFERRED_CLEAR();
195187a94eb1632d06eeeb89490a91565e786440d6d0bsalomon    fRenderTarget->prepareForExternalRead();
195211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
195311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
195411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com///////////////////////////////////////////////////////////////////////////////
195511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
195676033be81b82c44fd5d4fdf2672eb22e505da1f0reedSkBaseDevice* SkGpuDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint*) {
1957f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon    GrSurfaceDesc desc;
195811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fConfig = fRenderTarget->config();
1959f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon    desc.fFlags = kRenderTarget_GrSurfaceFlag;
19606987dcaf257dd7c2c8e0014cf7452fde82bcba5bfmalita    desc.fWidth = cinfo.fInfo.width();
19616987dcaf257dd7c2c8e0014cf7452fde82bcba5bfmalita    desc.fHeight = cinfo.fInfo.height();
196211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    desc.fSampleCnt = fRenderTarget->numSamples();
196311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
196411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    SkAutoTUnref<GrTexture> texture;
196511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    // Skia's convention is to only clear a device if it is non-opaque.
19666987dcaf257dd7c2c8e0014cf7452fde82bcba5bfmalita    unsigned flags = cinfo.fInfo.isOpaque() ? 0 : kNeedClear_Flag;
196711a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
19684396fa594e8e3aaa40c5ee65f12e6a3dbb04173ehcm    // layers are never draw in repeat modes, so we can request an approx
19694396fa594e8e3aaa40c5ee65f12e6a3dbb04173ehcm    // match and ignore any padding.
1970d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon    const GrTextureProvider::ScratchTexMatch match = (kNever_TileUsage == cinfo.fTileUsage) ?
1971d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon                                                  GrTextureProvider::kApprox_ScratchTexMatch :
1972d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon                                                  GrTextureProvider::kExact_ScratchTexMatch;
1973d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon    texture.reset(fContext->textureProvider()->refScratchTexture(desc, match));
1974afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon
1975afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon    if (texture) {
1976afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon        SkSurfaceProps props(fSurfaceProps.flags(), cinfo.fPixelGeometry);
1977d0d37cace08f12abf8d316e6949e947551d418e6senorblanco        return SkGpuDevice::Create(
1978d0d37cace08f12abf8d316e6949e947551d418e6senorblanco            texture->asRenderTarget(), cinfo.fInfo.width(), cinfo.fInfo.height(), &props, flags);
197911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    } else {
19805f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt        SkErrorInternals::SetError( kInternalError_SkError,
198161f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed                                    "---- failed to create gpu device texture [%d %d]\n",
19825f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt                                    cinfo.fInfo.width(), cinfo.fInfo.height());
198311a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        return NULL;
198411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com    }
198511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com}
198611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
19874a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurface* SkGpuDevice::newSurface(const SkImageInfo& info, const SkSurfaceProps& props) {
1988afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon    // TODO: Change the signature of newSurface to take a budgeted parameter.
1989afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon    static const SkSurface::Budgeted kBudgeted = SkSurface::kNo_Budgeted;
1990afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon    return SkSurface::NewRenderTarget(fContext, kBudgeted, info, fRenderTarget->numSamples(),
1991afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon                                      &props);
199276f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com}
199376f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com
199430d2cc6ff47cb7f981d83e9a536971beec920f61robertphillipsbool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture* mainPicture,
199564bf76722ef06eabf51b55afda9f4ff431e41460robertphillips                                           const SkMatrix* matrix, const SkPaint* paint) {
199663242d7d24917f836eace34ee20faeb49def5e67robertphillips#ifndef SK_IGNORE_GPU_LAYER_HOISTING
199730d7841f906116c3945ec8125a816a5c5462fed0robertphillips    // todo: should handle this natively
199830d7841f906116c3945ec8125a816a5c5462fed0robertphillips    if (paint) {
199964bf76722ef06eabf51b55afda9f4ff431e41460robertphillips        return false;
200064bf76722ef06eabf51b55afda9f4ff431e41460robertphillips    }
200164bf76722ef06eabf51b55afda9f4ff431e41460robertphillips
2002b7ed856fadae52401d3bbcac22cfc3391780ace8reed    SkPicture::AccelData::Key key = SkLayerInfo::ComputeKey();
2003b7ed856fadae52401d3bbcac22cfc3391780ace8reed
2004b7ed856fadae52401d3bbcac22cfc3391780ace8reed    const SkPicture::AccelData* data = mainPicture->EXPERIMENTAL_getAccelData(key);
200581f71b6630a9b7398bf983689436cccdd8dd3ff7robertphillips    if (!data) {
200681f71b6630a9b7398bf983689436cccdd8dd3ff7robertphillips        return false;
200781f71b6630a9b7398bf983689436cccdd8dd3ff7robertphillips    }
200881f71b6630a9b7398bf983689436cccdd8dd3ff7robertphillips
2009e5524cd52d56f9b70d9b4a83bd73a3fa75d56509robertphillips    const SkLayerInfo *gpuData = static_cast<const SkLayerInfo*>(data);
2010e5524cd52d56f9b70d9b4a83bd73a3fa75d56509robertphillips    if (0 == gpuData->numBlocks()) {
2011e5524cd52d56f9b70d9b4a83bd73a3fa75d56509robertphillips        return false;
201264bf76722ef06eabf51b55afda9f4ff431e41460robertphillips    }
201364bf76722ef06eabf51b55afda9f4ff431e41460robertphillips
2014e5524cd52d56f9b70d9b4a83bd73a3fa75d56509robertphillips    SkTDArray<GrHoistedLayer> atlasedNeedRendering, atlasedRecycled;
2015e5524cd52d56f9b70d9b4a83bd73a3fa75d56509robertphillips
2016e5524cd52d56f9b70d9b4a83bd73a3fa75d56509robertphillips    SkIRect iBounds;
2017e5524cd52d56f9b70d9b4a83bd73a3fa75d56509robertphillips    if (!mainCanvas->getClipDeviceBounds(&iBounds)) {
2018e5524cd52d56f9b70d9b4a83bd73a3fa75d56509robertphillips        return false;
2019e5524cd52d56f9b70d9b4a83bd73a3fa75d56509robertphillips    }
202030d7841f906116c3945ec8125a816a5c5462fed0robertphillips
2021e5524cd52d56f9b70d9b4a83bd73a3fa75d56509robertphillips    SkRect clipBounds = SkRect::Make(iBounds);
202230d7841f906116c3945ec8125a816a5c5462fed0robertphillips
2023e5524cd52d56f9b70d9b4a83bd73a3fa75d56509robertphillips    SkMatrix initialMatrix = mainCanvas->getTotalMatrix();
2024beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
2025fd61ed0d7929cf85e0b936f48c72035af4c0a4b3robertphillips    GrLayerHoister::FindLayersToAtlas(fContext, mainPicture,
202630d7841f906116c3945ec8125a816a5c5462fed0robertphillips                                      initialMatrix,
2027fd61ed0d7929cf85e0b936f48c72035af4c0a4b3robertphillips                                      clipBounds,
2028a63f32e879a67c84f820c32ac2b10ffd7b2940b8robertphillips                                      &atlasedNeedRendering, &atlasedRecycled,
2029a63f32e879a67c84f820c32ac2b10ffd7b2940b8robertphillips                                      fRenderTarget->numSamples());
2030fd61ed0d7929cf85e0b936f48c72035af4c0a4b3robertphillips
2031fd61ed0d7929cf85e0b936f48c72035af4c0a4b3robertphillips    GrLayerHoister::DrawLayersToAtlas(fContext, atlasedNeedRendering);
2032fd61ed0d7929cf85e0b936f48c72035af4c0a4b3robertphillips
2033fd61ed0d7929cf85e0b936f48c72035af4c0a4b3robertphillips    SkTDArray<GrHoistedLayer> needRendering, recycled;
2034fd61ed0d7929cf85e0b936f48c72035af4c0a4b3robertphillips
2035e5524cd52d56f9b70d9b4a83bd73a3fa75d56509robertphillips    SkAutoCanvasMatrixPaint acmp(mainCanvas, matrix, paint, mainPicture->cullRect());
2036e5524cd52d56f9b70d9b4a83bd73a3fa75d56509robertphillips
2037fd61ed0d7929cf85e0b936f48c72035af4c0a4b3robertphillips    GrLayerHoister::FindLayersToHoist(fContext, mainPicture,
203830d7841f906116c3945ec8125a816a5c5462fed0robertphillips                                      initialMatrix,
2039fd61ed0d7929cf85e0b936f48c72035af4c0a4b3robertphillips                                      clipBounds,
2040a63f32e879a67c84f820c32ac2b10ffd7b2940b8robertphillips                                      &needRendering, &recycled,
2041a63f32e879a67c84f820c32ac2b10ffd7b2940b8robertphillips                                      fRenderTarget->numSamples());
2042fd61ed0d7929cf85e0b936f48c72035af4c0a4b3robertphillips
2043fd61ed0d7929cf85e0b936f48c72035af4c0a4b3robertphillips    GrLayerHoister::DrawLayers(fContext, needRendering);
2044952841bf41a81228c23d16c7204b458abe0d7136robertphillips
204564bf76722ef06eabf51b55afda9f4ff431e41460robertphillips    // Render the entire picture using new layers
2046e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips    GrRecordReplaceDraw(mainPicture, mainCanvas, fContext->getLayerCache(),
2047e99d499caa7dbc80b58e0faf5ce137e7d30cc5d0robertphillips                        initialMatrix, NULL);
204864bf76722ef06eabf51b55afda9f4ff431e41460robertphillips
2049fd61ed0d7929cf85e0b936f48c72035af4c0a4b3robertphillips    GrLayerHoister::UnlockLayers(fContext, needRendering);
2050fd61ed0d7929cf85e0b936f48c72035af4c0a4b3robertphillips    GrLayerHoister::UnlockLayers(fContext, recycled);
2051fd61ed0d7929cf85e0b936f48c72035af4c0a4b3robertphillips    GrLayerHoister::UnlockLayers(fContext, atlasedNeedRendering);
2052fd61ed0d7929cf85e0b936f48c72035af4c0a4b3robertphillips    GrLayerHoister::UnlockLayers(fContext, atlasedRecycled);
205364bf76722ef06eabf51b55afda9f4ff431e41460robertphillips
205464bf76722ef06eabf51b55afda9f4ff431e41460robertphillips    return true;
205563242d7d24917f836eace34ee20faeb49def5e67robertphillips#else
205663242d7d24917f836eace34ee20faeb49def5e67robertphillips    return false;
205763242d7d24917f836eace34ee20faeb49def5e67robertphillips#endif
205864bf76722ef06eabf51b55afda9f4ff431e41460robertphillips}
205964bf76722ef06eabf51b55afda9f4ff431e41460robertphillips
2060be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblancoSkImageFilter::Cache* SkGpuDevice::getImageFilterCache() {
206155b6d8be997a447ef9ce0f029697677a940bfc24senorblanco    // We always return a transient cache, so it is freed after each
206255b6d8be997a447ef9ce0f029697677a940bfc24senorblanco    // filter traversal.
2063be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblanco    return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize);
206455b6d8be997a447ef9ce0f029697677a940bfc24senorblanco}
2065f037e0bf138a4e842f39e19864d05010a54950c9reed
2066f037e0bf138a4e842f39e19864d05010a54950c9reed#endif
2067