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