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