180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc. 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkGpuDevice.h" 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "effects/GrTextureDomainEffect.h" 11d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#include "effects/GrSimpleTextureEffect.h" 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrContext.h" 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrTextContext.h" 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkGrTexturePixelRef.h" 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkColorFilter.h" 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkDeviceImageFilterProxy.h" 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkDrawProcs.h" 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkGlyphCache.h" 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkImageFilter.h" 23363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "SkPathEffect.h" 24363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "SkStroke.h" 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkUtils.h" 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define CACHE_COMPATIBLE_DEVICE_TEXTURES 1 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if 0 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru extern bool (*gShouldDrawProc)(); 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru #define CHECK_SHOULD_DRAW(draw, forceI) \ 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { \ 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (gShouldDrawProc && !gShouldDrawProc()) return; \ 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->prepareDraw(draw, forceI); \ 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } while (0) 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru #define CHECK_SHOULD_DRAW(draw, forceI) this->prepareDraw(draw, forceI) 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// we use the same texture slot on GrPaint for bitmaps and shaders 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// (since drawBitmap, drawSprite, and drawDevice ignore skia's shader) 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruenum { 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kBitmapTextureIdx = 0, 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kShaderTextureIdx = 0, 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kColorFilterTextureIdx = 1 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define MAX_BLUR_SIGMA 4.0f 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// FIXME: This value comes from from SkBlurMaskFilter.cpp. 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// Should probably be put in a common header someplace. 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define MAX_BLUR_RADIUS SkIntToScalar(128) 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// This constant approximates the scaling done in the software path's 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// "high quality" mode, in SkBlurMask::Blur() (1 / sqrt(3)). 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// IMHO, it actually should be 1: we blur "less" than we should do 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// according to the CSS and canvas specs, simply because Safari does the same. 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// Firefox used to do the same too, until 4.0 where they fixed it. So at some 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// point we should probably get rid of these scaling constants and rebaseline 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// all the blur tests. 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define BLUR_SIGMA_SCALE 0.6f 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// This constant represents the screen alignment criterion in texels for 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// requiring texture domain clamping to prevent color bleeding when drawing 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// a sub region of a larger source image. 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define COLOR_BLEED_TOLERANCE SkFloatToScalar(0.001f) 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 65363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#define DO_DEFERRED_CLEAR() \ 66363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger do { \ 67363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (fNeedClear) { \ 68363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->clear(SK_ColorTRANSPARENT); \ 69363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } \ 70363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } while (false) \ 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define CHECK_FOR_NODRAW_ANNOTATION(paint) \ 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { if (paint.isNoDrawAnnotation()) { return; } } while (0) 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkGpuDevice::SkAutoCachedTexture : public ::SkNoncopyable { 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAutoCachedTexture() 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru : fDevice(NULL) 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru , fTexture(NULL) { 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAutoCachedTexture(SkGpuDevice* device, 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkBitmap& bitmap, 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrTextureParams* params, 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTexture** texture) 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru : fDevice(NULL) 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru , fTexture(NULL) { 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(NULL != texture); 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *texture = this->set(device, bitmap, params); 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ~SkAutoCachedTexture() { 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != fTexture) { 99d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrUnlockAndUnrefCachedBitmapTexture(fTexture); 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTexture* set(SkGpuDevice* device, 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkBitmap& bitmap, 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrTextureParams* params) { 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != fTexture) { 107d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrUnlockAndUnrefCachedBitmapTexture(fTexture); 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTexture = NULL; 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDevice = device; 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTexture* result = (GrTexture*)bitmap.getTexture(); 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == result) { 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Cannot return the native texture so look it up in our cache 114d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger fTexture = GrLockAndRefCachedBitmapTexture(device->context(), bitmap, params); 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru result = fTexture; 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return result; 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate: 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkGpuDevice* fDevice; 12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTexture* fTexture; 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustruct GrSkDrawProcs : public SkDrawProcs { 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrContext* fContext; 13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTextContext* fTextContext; 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrFontScaler* fFontScaler; // cached in the skia glyphcache 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkBitmap::Config grConfig2skConfig(GrPixelConfig config, bool* isOpaque) { 13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru switch (config) { 13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kAlpha_8_GrPixelConfig: 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *isOpaque = false; 14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkBitmap::kA8_Config; 14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kRGB_565_GrPixelConfig: 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *isOpaque = true; 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkBitmap::kRGB_565_Config; 14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kRGBA_4444_GrPixelConfig: 14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *isOpaque = false; 14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkBitmap::kARGB_4444_Config; 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kSkia8888_PM_GrPixelConfig: 14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we don't currently have a way of knowing whether 14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // a 8888 is opaque based on the config. 15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *isOpaque = false; 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkBitmap::kARGB_8888_Config; 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru default: 15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *isOpaque = false; 15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkBitmap::kNo_Config; 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkBitmap make_bitmap(GrContext* context, GrRenderTarget* renderTarget) { 15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPixelConfig config = renderTarget->config(); 16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool isOpaque; 16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkBitmap bitmap; 16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bitmap.setConfig(grConfig2skConfig(config, &isOpaque), 16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru renderTarget->width(), renderTarget->height()); 16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bitmap.setIsOpaque(isOpaque); 16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return bitmap; 16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkGpuDevice::SkGpuDevice(GrContext* context, GrTexture* texture) 17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru: SkDevice(make_bitmap(context, texture->asRenderTarget())) { 17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->initFromRenderTarget(context, texture->asRenderTarget(), false); 17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkGpuDevice::SkGpuDevice(GrContext* context, GrRenderTarget* renderTarget) 17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru: SkDevice(make_bitmap(context, renderTarget)) { 17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->initFromRenderTarget(context, renderTarget, false); 17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkGpuDevice::initFromRenderTarget(GrContext* context, 18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrRenderTarget* renderTarget, 18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool cached) { 18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawProcs = NULL; 18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fContext = context; 18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fContext->ref(); 18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fRenderTarget = NULL; 18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fNeedClear = false; 18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(NULL != renderTarget); 19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fRenderTarget = renderTarget; 19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fRenderTarget->ref(); 19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Hold onto to the texture in the pixel ref (if there is one) because the texture holds a ref 19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // on the RT but not vice-versa. 19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // TODO: Remove this trickery once we figure out how to make SkGrPixelRef do this without 19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // busting chrome (for a currently unknown reason). 19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrSurface* surface = fRenderTarget->asTexture(); 19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == surface) { 20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru surface = fRenderTarget; 20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (surface, cached)); 20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setPixelRef(pr, 0)->unref(); 20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkGpuDevice::SkGpuDevice(GrContext* context, 20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkBitmap::Config config, 20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int width, 210363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger int height, 211363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger int sampleCount) 21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru : SkDevice(config, width, height, false /*isOpaque*/) { 21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawProcs = NULL; 21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fContext = context; 21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fContext->ref(); 21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fRenderTarget = NULL; 22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fNeedClear = false; 22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (config != SkBitmap::kRGB_565_Config) { 22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru config = SkBitmap::kARGB_8888_Config; 22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTextureDesc desc; 22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fFlags = kRenderTarget_GrTextureFlagBit; 22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fWidth = width; 22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fHeight = height; 230363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger desc.fConfig = SkBitmapConfig2GrPixelConfig(config); 231363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger desc.fSampleCnt = sampleCount; 23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAutoTUnref<GrTexture> texture(fContext->createUncachedTexture(desc, NULL, 0)); 23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != texture) { 23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fRenderTarget = texture->asRenderTarget(); 23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fRenderTarget->ref(); 23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(NULL != fRenderTarget); 24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // wrap the bitmap with a pixelref to expose our texture 24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkGrPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (texture)); 24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setPixelRef(pr, 0)->unref(); 24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPrintf("--- failed to create gpu-offscreen [%d %d]\n", 24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru width, height); 24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(false); 24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkGpuDevice::~SkGpuDevice() { 25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fDrawProcs) { 25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete fDrawProcs; 25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // The GrContext takes a ref on the target. We don't want to cause the render 25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // target to be unnecessarily kept alive. 25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fContext->getRenderTarget() == fRenderTarget) { 25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fContext->setRenderTarget(NULL); 26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 262363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (fContext->getClip() == &fClipData) { 263363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fContext->setClip(NULL); 264363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 265363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkSafeUnref(fRenderTarget); 26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fContext->unref(); 26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkGpuDevice::makeRenderTargetCurrent() { 27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru DO_DEFERRED_CLEAR(); 27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fContext->setRenderTarget(fRenderTarget); 27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace { 28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrPixelConfig config8888_to_grconfig_and_flags(SkCanvas::Config8888 config8888, uint32_t* flags) { 28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru switch (config8888) { 28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkCanvas::kNative_Premul_Config8888: 28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *flags = 0; 28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return kSkia8888_GrPixelConfig; 28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkCanvas::kNative_Unpremul_Config8888: 28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *flags = GrContext::kUnpremul_PixelOpsFlag; 28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return kSkia8888_PM_GrPixelConfig; 28880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkCanvas::kBGRA_Premul_Config8888: 28980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *flags = 0; 29080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return kBGRA_8888_GrPixelConfig; 29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkCanvas::kBGRA_Unpremul_Config8888: 29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *flags = GrContext::kUnpremul_PixelOpsFlag; 29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return kBGRA_8888_GrPixelConfig; 29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkCanvas::kRGBA_Premul_Config8888: 29580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *flags = 0; 29680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return kRGBA_8888_GrPixelConfig; 29780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkCanvas::kRGBA_Unpremul_Config8888: 29880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *flags = GrContext::kUnpremul_PixelOpsFlag; 29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return kRGBA_8888_GrPixelConfig; 30080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru default: 30180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrCrash("Unexpected Config8888."); 30280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *flags = 0; // suppress warning 30380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return kSkia8888_PM_GrPixelConfig; 30480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 30780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 30880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkGpuDevice::onReadPixels(const SkBitmap& bitmap, 30980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int x, int y, 31080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkCanvas::Config8888 config8888) { 31180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru DO_DEFERRED_CLEAR(); 31280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(SkBitmap::kARGB_8888_Config == bitmap.config()); 31380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(!bitmap.isNull()); 31480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(SkIRect::MakeWH(this->width(), this->height()).contains(SkIRect::MakeXYWH(x, y, bitmap.width(), bitmap.height()))); 31580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 31680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAutoLockPixels alp(bitmap); 31780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPixelConfig config; 31880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t flags; 31980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru config = config8888_to_grconfig_and_flags(config8888, &flags); 32080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fContext->readRenderTargetPixels(fRenderTarget, 32180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru x, y, 32280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bitmap.width(), 32380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bitmap.height(), 32480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru config, 32580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bitmap.getPixels(), 32680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bitmap.rowBytes(), 32780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru flags); 32880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 32980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 33080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkGpuDevice::writePixels(const SkBitmap& bitmap, int x, int y, 33180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkCanvas::Config8888 config8888) { 33280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAutoLockPixels alp(bitmap); 33380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!bitmap.readyToDraw()) { 33480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 33580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 33680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 33780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPixelConfig config; 33880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t flags; 33980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (SkBitmap::kARGB_8888_Config == bitmap.config()) { 34080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru config = config8888_to_grconfig_and_flags(config8888, &flags); 34180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 34280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru flags = 0; 34380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru config= SkBitmapConfig2GrPixelConfig(bitmap.config()); 34480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 34580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 34680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fRenderTarget->writePixels(x, y, bitmap.width(), bitmap.height(), 34780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru config, bitmap.getPixels(), bitmap.rowBytes(), flags); 34880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 34980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 35080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace { 351d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergervoid purgeClipCB(int genID, void* ) { 35280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 35380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (SkClipStack::kInvalidGenID == genID || 35480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkClipStack::kEmptyGenID == genID || 35580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkClipStack::kWideOpenGenID == genID) { 35680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // none of these cases will have a cached clip mask 35780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 35880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 35980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 36080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 36180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 36280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 36380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkGpuDevice::onAttachToCanvas(SkCanvas* canvas) { 36480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru INHERITED::onAttachToCanvas(canvas); 36580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 36680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Canvas promises that this ptr is valid until onDetachFromCanvas is called 36780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fClipData.fClipStack = canvas->getClipStack(); 36880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 36980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fClipData.fClipStack->addPurgeClipCallback(purgeClipCB, fContext); 37080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 37180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 37280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkGpuDevice::onDetachFromCanvas() { 37380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru INHERITED::onDetachFromCanvas(); 37480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 37580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // TODO: iterate through the clip stack and clean up any cached clip masks 37680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fClipData.fClipStack->removePurgeClipCallback(purgeClipCB, fContext); 37780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 37880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fClipData.fClipStack = NULL; 37980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 38080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 38180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG 38280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void check_bounds(const GrClipData& clipData, 38380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkRegion& clipRegion, 38480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int renderTargetWidth, 38580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int renderTargetHeight) { 38680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 38780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIRect devBound; 38880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 38980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru devBound.setLTRB(0, 0, renderTargetWidth, renderTargetHeight); 39080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 39180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkClipStack::BoundsType boundType; 39280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect canvTemp; 39380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 39480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru clipData.fClipStack->getBounds(&canvTemp, &boundType); 39580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (SkClipStack::kNormal_BoundsType == boundType) { 39680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIRect devTemp; 39780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 39880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvTemp.roundOut(&devTemp); 39980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 40080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru devTemp.offset(-clipData.fOrigin.fX, -clipData.fOrigin.fY); 40180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 40280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!devBound.intersect(devTemp)) { 40380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru devBound.setEmpty(); 40480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 40580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 40680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 40780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(devBound.contains(clipRegion.getBounds())); 40880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 40980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 41080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 41180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 41280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 41380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// call this every draw call, to ensure that the context reflects our state, 41480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// and not the state from some other canvas/device 41580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkGpuDevice::prepareDraw(const SkDraw& draw, bool forceIdentity) { 41680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(NULL != fClipData.fClipStack); 41780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 41880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fContext->setRenderTarget(fRenderTarget); 41980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 42080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(draw.fClipStack && draw.fClipStack == fClipData.fClipStack); 42180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 42280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (forceIdentity) { 42380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fContext->setIdentityMatrix(); 42480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 42580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fContext->setMatrix(*draw.fMatrix); 42680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 42780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fClipData.fOrigin = this->getOrigin(); 42880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 42980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG 43080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru check_bounds(fClipData, *draw.fClip, fRenderTarget->width(), fRenderTarget->height()); 43180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 43280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 43380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fContext->setClip(&fClipData); 43480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 43580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru DO_DEFERRED_CLEAR(); 43680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 43780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 43880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkGpuRenderTarget* SkGpuDevice::accessRenderTarget() { 43980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru DO_DEFERRED_CLEAR(); 44080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return (SkGpuRenderTarget*)fRenderTarget; 44180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 44280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 44380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkGpuDevice::bindDeviceAsTexture(GrPaint* paint) { 44480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTexture* texture = fRenderTarget->asTexture(); 44580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != texture) { 446363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger paint->colorStage(kBitmapTextureIdx)->setEffect( 447d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrSimpleTextureEffect::Create(texture, SkMatrix::I()))->unref(); 44880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 44980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 45080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 45180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 45280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 45380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 45480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 45580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSK_COMPILE_ASSERT(SkShader::kNone_BitmapType == 0, shader_type_mismatch); 45680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSK_COMPILE_ASSERT(SkShader::kDefault_BitmapType == 1, shader_type_mismatch); 45780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSK_COMPILE_ASSERT(SkShader::kRadial_BitmapType == 2, shader_type_mismatch); 45880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSK_COMPILE_ASSERT(SkShader::kSweep_BitmapType == 3, shader_type_mismatch); 45980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSK_COMPILE_ASSERT(SkShader::kTwoPointRadial_BitmapType == 4, 46080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru shader_type_mismatch); 46180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSK_COMPILE_ASSERT(SkShader::kTwoPointConical_BitmapType == 5, 46280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru shader_type_mismatch); 46380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSK_COMPILE_ASSERT(SkShader::kLinear_BitmapType == 6, shader_type_mismatch); 46480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSK_COMPILE_ASSERT(SkShader::kLast_BitmapType == 6, shader_type_mismatch); 46580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 46680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace { 46780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 46880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// converts a SkPaint to a GrPaint, ignoring the skPaint's shader 46980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// justAlpha indicates that skPaint's alpha should be used rather than the color 47080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// Callers may subsequently modify the GrPaint. Setting constantColor indicates 47180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// that the final paint will draw the same color at every pixel. This allows 47280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// an optimization where the the color filter can be applied to the skPaint's 47380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// color once while converting to GrPaint and then ignored. 47480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruinline bool skPaint2GrPaintNoShader(SkGpuDevice* dev, 47580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPaint& skPaint, 47680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool justAlpha, 47780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool constantColor, 47880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPaint* grPaint) { 47980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 48080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru grPaint->setDither(skPaint.isDither()); 48180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru grPaint->setAntiAlias(skPaint.isAntiAlias()); 48280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 48380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkXfermode::Coeff sm = SkXfermode::kOne_Coeff; 48480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkXfermode::Coeff dm = SkXfermode::kISA_Coeff; 48580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 48680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkXfermode* mode = skPaint.getXfermode(); 48780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (mode) { 48880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!mode->asCoeff(&sm, &dm)) { 48980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru //SkDEBUGCODE(SkDebugf("Unsupported xfer mode.\n");) 49080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if 0 49180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 49280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 49380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 49480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 49580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru grPaint->setBlendFunc(sk_blend_to_grblend(sm), sk_blend_to_grblend(dm)); 49680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 49780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (justAlpha) { 49880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint8_t alpha = skPaint.getAlpha(); 49980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru grPaint->setColor(GrColorPackRGBA(alpha, alpha, alpha, alpha)); 50080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // justAlpha is currently set to true only if there is a texture, 50180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // so constantColor should not also be true. 50280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(!constantColor); 50380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 50480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru grPaint->setColor(SkColor2GrColor(skPaint.getColor())); 50580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(!grPaint->isColorStageEnabled(kShaderTextureIdx)); 50680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 507363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 50880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkColorFilter* colorFilter = skPaint.getColorFilter(); 509363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (NULL != colorFilter) { 510363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // if the source color is a constant then apply the filter here once rather than per pixel 511363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // in a shader. 512363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (constantColor) { 51380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkColor filtered = colorFilter->filterColor(skPaint.getColor()); 51480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru grPaint->setColor(SkColor2GrColor(filtered)); 515363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } else { 516d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkAutoTUnref<GrEffectRef> effect(colorFilter->asNewEffect(dev->context())); 517363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (NULL != effect.get()) { 518363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger grPaint->colorStage(kColorFilterTextureIdx)->setEffect(effect); 519363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } else { 520363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // TODO: rewrite this using asNewEffect() 521363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkColor color; 522363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkXfermode::Mode filterMode; 523363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (colorFilter->asColorMode(&color, &filterMode)) { 524363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger grPaint->setXfermodeColorFilter(filterMode, SkColor2GrColor(color)); 525363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 526363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 52780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 52880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 529363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 53080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 53180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 53280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 53380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// This function is similar to skPaint2GrPaintNoShader but also converts 534363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger// skPaint's shader to a GrTexture/GrEffectStage if possible. The texture to 53580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// be used is set on grPaint and returned in param act. constantColor has the 53680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// same meaning as in skPaint2GrPaintNoShader. 53780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruinline bool skPaint2GrPaintShader(SkGpuDevice* dev, 53880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPaint& skPaint, 53980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool constantColor, 54080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPaint* grPaint) { 54180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkShader* shader = skPaint.getShader(); 54280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == shader) { 543d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return skPaint2GrPaintNoShader(dev, skPaint, false, constantColor, grPaint); 544d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } else if (!skPaint2GrPaintNoShader(dev, skPaint, true, false, grPaint)) { 54580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 54680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 54780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 548d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkAutoTUnref<GrEffectRef> effect(shader->asNewEffect(dev->context(), skPaint)); 549d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (NULL != effect.get()) { 550d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger grPaint->colorStage(kShaderTextureIdx)->setEffect(effect); 55180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 55280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 55380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 554d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // We still don't have SkColorShader::asNewEffect() implemented. 555d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkShader::GradientInfo info; 556d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkColor color; 55780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 558d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger info.fColors = &color; 559d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger info.fColorOffsets = NULL; 560d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger info.fColorCount = 1; 561d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (SkShader::kColor_GradientType == shader->asAGradient(&info)) { 562d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkPaint copy(skPaint); 563d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger copy.setShader(NULL); 564d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // modulate the paint alpha by the shader's solid color alpha 565d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger U8CPU newA = SkMulDiv255Round(SkColorGetA(color), copy.getAlpha()); 566d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger copy.setColor(SkColorSetA(color, newA)); 567d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return skPaint2GrPaintNoShader(dev, copy, false, constantColor, grPaint); 568363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 569d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return false; 57080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 57180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 57280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 57380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 57480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkGpuDevice::clear(SkColor color) { 575d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkIRect rect = SkIRect::MakeWH(this->width(), this->height()); 576d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger fContext->clear(&rect, SkColor2GrColor(color), fRenderTarget); 57780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fNeedClear = false; 57880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 57980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 58080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) { 58180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CHECK_SHOULD_DRAW(draw, false); 58280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 58380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPaint grPaint; 584d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { 58580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 58680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 58780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 58880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fContext->drawPaint(grPaint); 58980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 59080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 59180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// must be in SkCanvas::PointMode order 59280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const GrPrimitiveType gPointMode2PrimtiveType[] = { 59380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kPoints_GrPrimitiveType, 59480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kLines_GrPrimitiveType, 59580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kLineStrip_GrPrimitiveType 59680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 59780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 59880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, 59980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t count, const SkPoint pts[], const SkPaint& paint) { 60080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CHECK_SHOULD_DRAW(draw, false); 60180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 60280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar width = paint.getStrokeWidth(); 60380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (width < 0) { 60480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 60580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 60680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 60780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we only handle hairlines and paints without path effects or mask filters, 60880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // else we let the SkDraw call our drawPath() 60980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (width > 0 || paint.getPathEffect() || paint.getMaskFilter()) { 61080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru draw.drawPoints(mode, count, pts, paint, true); 61180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 61280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 61380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 61480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPaint grPaint; 615d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { 61680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 61780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 61880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 61980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fContext->drawVertices(grPaint, 62080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru gPointMode2PrimtiveType[mode], 62180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru count, 62280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru (GrPoint*)pts, 62380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru NULL, 62480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru NULL, 62580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru NULL, 62680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 0); 62780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 62880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 62980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 63080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 63180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect, 63280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPaint& paint) { 63380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CHECK_FOR_NODRAW_ANNOTATION(paint); 63480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CHECK_SHOULD_DRAW(draw, false); 63580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 63680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool doStroke = paint.getStyle() != SkPaint::kFill_Style; 63780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar width = paint.getStrokeWidth(); 63880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 63980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /* 64080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru We have special code for hairline strokes, miter-strokes, and fills. 64180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Anything else we just call our path code. 64280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 64380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool usePath = doStroke && width > 0 && 64480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.getStrokeJoin() != SkPaint::kMiter_Join; 64580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // another two reasons we might need to call drawPath... 64680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (paint.getMaskFilter() || paint.getPathEffect()) { 64780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru usePath = true; 64880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 64980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // until we aa rotated rects... 65080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!usePath && paint.isAntiAlias() && !fContext->getMatrix().rectStaysRect()) { 65180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru usePath = true; 65280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 65380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // small miter limit means right angles show bevel... 65480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (SkPaint::kMiter_Join == paint.getStrokeJoin() && 65580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.getStrokeMiter() < SK_ScalarSqrt2) 65680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 65780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru usePath = true; 65880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 65980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // until we can both stroke and fill rectangles 66080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (paint.getStyle() == SkPaint::kStrokeAndFill_Style) { 66180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru usePath = true; 66280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 66380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 66480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (usePath) { 66580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPath path; 66680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru path.addRect(rect); 66780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->drawPath(draw, path, paint, NULL, true); 66880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 66980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 67080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 67180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPaint grPaint; 672d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { 67380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 67480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 67580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fContext->drawRect(grPaint, rect, doStroke ? width : -1); 67680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 67780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 678d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 679d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 680d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergervoid SkGpuDevice::drawOval(const SkDraw& draw, const SkRect& oval, 681d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const SkPaint& paint) { 682d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger CHECK_FOR_NODRAW_ANNOTATION(paint); 683d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger CHECK_SHOULD_DRAW(draw, false); 684d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 685d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger bool usePath = false; 686d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // some basic reasons we might need to call drawPath... 687d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (paint.getMaskFilter() || paint.getPathEffect()) { 688d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger usePath = true; 689d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 690d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 691d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (usePath) { 692d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkPath path; 693d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger path.addOval(oval); 694d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger this->drawPath(draw, path, paint, NULL, true); 695d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return; 696d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 697d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 698d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrPaint grPaint; 699d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { 700d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return; 701d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 702d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkStrokeRec stroke(paint); 703d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 704d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger fContext->drawOval(grPaint, oval, stroke); 705d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger} 706d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 70780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkMaskFilter.h" 70880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkBounder.h" 70980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 71080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 71180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 71280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// helpers for applying mask filters 71380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace { 71480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 71580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// We prefer to blur small rect with small radius via CPU. 71680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define MIN_GPU_BLUR_SIZE SkIntToScalar(64) 71780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define MIN_GPU_BLUR_RADIUS SkIntToScalar(32) 71880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruinline bool shouldDrawBlurWithCPU(const SkRect& rect, SkScalar radius) { 71980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (rect.width() <= MIN_GPU_BLUR_SIZE && 72080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rect.height() <= MIN_GPU_BLUR_SIZE && 72180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru radius <= MIN_GPU_BLUR_RADIUS) { 72280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 72380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 72480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 72580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 72680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 727363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerbool drawWithGPUMaskFilter(GrContext* context, const SkPath& devPath, const SkStrokeRec& stroke, 72880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMaskFilter* filter, const SkRegion& clip, 729363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkBounder* bounder, GrPaint* grp) { 73080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMaskFilter::BlurInfo info; 73180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMaskFilter::BlurType blurType = filter->asABlur(&info); 73280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (SkMaskFilter::kNone_BlurType == blurType) { 73380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 73480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 73580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar radius = info.fIgnoreTransform ? info.fRadius 73680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru : context->getMatrix().mapRadius(info.fRadius); 73780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru radius = SkMinScalar(radius, MAX_BLUR_RADIUS); 73880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (radius <= 0) { 73980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 74080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 74180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 74280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect srcRect = devPath.getBounds(); 74380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (shouldDrawBlurWithCPU(srcRect, radius)) { 74480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 74580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 74680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 74780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float sigma = SkScalarToFloat(radius) * BLUR_SIGMA_SCALE; 74880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float sigma3 = sigma * 3.0f; 74980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 75080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect clipRect; 75180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru clipRect.set(clip.getBounds()); 75280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 75380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Outset srcRect and clipRect by 3 * sigma, to compute affected blur area. 75480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcRect.inset(SkFloatToScalar(-sigma3), SkFloatToScalar(-sigma3)); 75580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru clipRect.inset(SkFloatToScalar(-sigma3), SkFloatToScalar(-sigma3)); 75680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcRect.intersect(clipRect); 75780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect finalRect = srcRect; 75880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIRect finalIRect; 75980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru finalRect.roundOut(&finalIRect); 76080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (clip.quickReject(finalIRect)) { 76180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 76280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 76380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (bounder && !bounder->doIRect(finalIRect)) { 76480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 76580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 76680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPoint offset = GrPoint::Make(-srcRect.fLeft, -srcRect.fTop); 76780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcRect.offset(offset); 76880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTextureDesc desc; 76980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fFlags = kRenderTarget_GrTextureFlagBit; 77080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fWidth = SkScalarCeilToInt(srcRect.width()); 77180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fHeight = SkScalarCeilToInt(srcRect.height()); 77280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // We actually only need A8, but it often isn't supported as a 77380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // render target so default to RGBA_8888 77480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fConfig = kRGBA_8888_GrPixelConfig; 77580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 77680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (context->isConfigRenderable(kAlpha_8_GrPixelConfig)) { 77780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fConfig = kAlpha_8_GrPixelConfig; 77880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 77980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 78080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAutoScratchTexture pathEntry(context, desc); 78180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTexture* pathTexture = pathEntry.texture(); 78280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == pathTexture) { 78380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 78480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 78580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 78680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAutoTUnref<GrTexture> blurTexture; 78780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 78880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 78980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrContext::AutoRenderTarget art(context, pathTexture->asRenderTarget()); 79080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrContext::AutoClip ac(context, srcRect); 79180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 79280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru context->clear(NULL, 0); 79380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 79480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPaint tempPaint; 79580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (grp->isAntiAlias()) { 79680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tempPaint.setAntiAlias(true); 79780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // AA uses the "coverage" stages on GrDrawTarget. Coverage with a dst 79880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // blend coeff of zero requires dual source blending support in order 79980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // to properly blend partially covered pixels. This means the AA 80080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // code path may not be taken. So we use a dst blend coeff of ISA. We 80180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // could special case AA draws to a dst surface with known alpha=0 to 80280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // use a zero dst coeff when dual source blending isn't available.f 80380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tempPaint.setBlendFunc(kOne_GrBlendCoeff, kISC_GrBlendCoeff); 80480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 80580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 80680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrContext::AutoMatrix am; 80780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 80880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Draw hard shadow to pathTexture with path top-left at origin using tempPaint. 809363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMatrix translate; 81080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru translate.setTranslate(offset.fX, offset.fY); 81180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru am.set(context, translate); 812363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger context->drawPath(tempPaint, devPath, stroke); 81380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 81480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // If we're doing a normal blur, we can clobber the pathTexture in the 81580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // gaussianBlur. Otherwise, we need to save it for later compositing. 81680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool isNormalBlur = blurType == SkMaskFilter::kNormal_BlurType; 81780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru blurTexture.reset(context->gaussianBlur(pathTexture, isNormalBlur, 81880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcRect, sigma, sigma)); 819363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (NULL == blurTexture) { 820363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return false; 821363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 82280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 82380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!isNormalBlur) { 82480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru context->setIdentityMatrix(); 82580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPaint paint; 826363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMatrix matrix; 82780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru matrix.setIDiv(pathTexture->width(), pathTexture->height()); 82880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Blend pathTexture over blurTexture. 82980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru context->setRenderTarget(blurTexture->asRenderTarget()); 830d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger paint.colorStage(0)->setEffect( 831d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrSimpleTextureEffect::Create(pathTexture, matrix))->unref(); 83280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (SkMaskFilter::kInner_BlurType == blurType) { 83380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // inner: dst = dst * src 83480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.setBlendFunc(kDC_GrBlendCoeff, kZero_GrBlendCoeff); 83580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else if (SkMaskFilter::kSolid_BlurType == blurType) { 83680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // solid: dst = src + dst - src * dst 83780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // = (1 - dst) * src + 1 * dst 83880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.setBlendFunc(kIDC_GrBlendCoeff, kOne_GrBlendCoeff); 83980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else if (SkMaskFilter::kOuter_BlurType == blurType) { 84080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // outer: dst = dst * (1 - src) 84180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // = 0 * src + (1 - src) * dst 84280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.setBlendFunc(kZero_GrBlendCoeff, kISC_GrBlendCoeff); 84380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 84480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru context->drawRect(paint, srcRect); 84580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 84680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 84780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 84880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrContext::AutoMatrix am; 84980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!am.setIdentity(context, grp)) { 85080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 85180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 85280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 85380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static const int MASK_IDX = GrPaint::kMaxCoverageStages - 1; 85480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we assume the last mask index is available for use 85580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(!grp->isCoverageStageEnabled(MASK_IDX)); 85680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 857363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMatrix matrix; 85880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru matrix.setTranslate(-finalRect.fLeft, -finalRect.fTop); 85980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru matrix.postIDiv(blurTexture->width(), blurTexture->height()); 86080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 861363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger grp->coverageStage(MASK_IDX)->reset(); 862d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger grp->coverageStage(MASK_IDX)->setEffect( 863d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrSimpleTextureEffect::Create(blurTexture, matrix))->unref(); 86480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru context->drawRect(*grp, finalRect); 86580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 86680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 86780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 86880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool drawWithMaskFilter(GrContext* context, const SkPath& devPath, 86980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMaskFilter* filter, const SkRegion& clip, SkBounder* bounder, 87080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPaint* grp, SkPaint::Style style) { 87180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMask srcM, dstM; 87280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 87380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!SkDraw::DrawToMask(devPath, &clip.getBounds(), filter, &context->getMatrix(), &srcM, 87480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMask::kComputeBoundsAndRenderImage_CreateMode, style)) { 87580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 87680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 87780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAutoMaskFreeImage autoSrc(srcM.fImage); 87880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 87980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!filter->filterMask(&dstM, srcM, context->getMatrix(), NULL)) { 88080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 88180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 88280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // this will free-up dstM when we're done (allocated in filterMask()) 88380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAutoMaskFreeImage autoDst(dstM.fImage); 88480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 88580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (clip.quickReject(dstM.fBounds)) { 88680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 88780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 88880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (bounder && !bounder->doIRect(dstM.fBounds)) { 88980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 89080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 89180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 89280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we now have a device-aligned 8bit mask in dstM, ready to be drawn using 89380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // the current clip (and identity matrix) and GrPaint settings 89480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrContext::AutoMatrix am; 89580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru am.setIdentity(context, grp); 89680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 89780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTextureDesc desc; 89880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fWidth = dstM.fBounds.width(); 89980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fHeight = dstM.fBounds.height(); 90080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fConfig = kAlpha_8_GrPixelConfig; 90180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 90280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAutoScratchTexture ast(context, desc); 90380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTexture* texture = ast.texture(); 90480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 90580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == texture) { 90680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 90780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 90880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig, 90980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dstM.fImage, dstM.fRowBytes); 91080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 91180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static const int MASK_IDX = GrPaint::kMaxCoverageStages - 1; 91280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we assume the last mask index is available for use 91380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(!grp->isCoverageStageEnabled(MASK_IDX)); 91480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 915363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMatrix m; 91680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m.setTranslate(-dstM.fBounds.fLeft*SK_Scalar1, -dstM.fBounds.fTop*SK_Scalar1); 91780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m.postIDiv(texture->width(), texture->height()); 91880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 919d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger grp->coverageStage(MASK_IDX)->setEffect(GrSimpleTextureEffect::Create(texture, m))->unref(); 92080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrRect d; 921363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger d.setLTRB(SkIntToScalar(dstM.fBounds.fLeft), 922363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkIntToScalar(dstM.fBounds.fTop), 923363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkIntToScalar(dstM.fBounds.fRight), 924363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkIntToScalar(dstM.fBounds.fBottom)); 92580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 92680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru context->drawRect(*grp, d); 92780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 92880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 92980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 93080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 93180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 93280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 93380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 93480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, 93580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPaint& paint, const SkMatrix* prePathMatrix, 93680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool pathIsMutable) { 93780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CHECK_FOR_NODRAW_ANNOTATION(paint); 93880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CHECK_SHOULD_DRAW(draw, false); 93980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 94080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPaint grPaint; 941d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { 94280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 94380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 94480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 945d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // can we cheat, and treat a thin stroke as a hairline w/ coverage 94680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // if we can, we draw lots faster (raster device does this same test) 94780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar hairlineCoverage; 948363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger bool doHairLine = SkDrawTreatAsHairline(paint, fContext->getMatrix(), &hairlineCoverage); 949363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (doHairLine) { 95080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru grPaint.setCoverage(SkScalarRoundToInt(hairlineCoverage * grPaint.getCoverage())); 95180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 95280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 95380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // If we have a prematrix, apply it to the path, optimizing for the case 95480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // where the original path can in fact be modified in place (even though 95580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // its parameter type is const). 95680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPath* pathPtr = const_cast<SkPath*>(&origSrcPath); 957363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkPath tmpPath, effectPath; 95880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 95980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (prePathMatrix) { 96080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPath* result = pathPtr; 96180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 96280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!pathIsMutable) { 96380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru result = &tmpPath; 96480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pathIsMutable = true; 96580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 96680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // should I push prePathMatrix on our MV stack temporarily, instead 96780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // of applying it here? See SkDraw.cpp 96880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pathPtr->transform(*prePathMatrix, result); 96980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pathPtr = result; 97080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 97180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // at this point we're done with prePathMatrix 97280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;) 97380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 974363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkStrokeRec stroke(paint); 975363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkPathEffect* pathEffect = paint.getPathEffect(); 976d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const SkRect* cullRect = NULL; // TODO: what is our bounds? 977d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (pathEffect && pathEffect->filterPath(&effectPath, *pathPtr, &stroke, 978d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger cullRect)) { 979363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger pathPtr = &effectPath; 980363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 981363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 982363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (!pathEffect && doHairLine) { 983363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger stroke.setHairlineStyle(); 98480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 98580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 98680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (paint.getMaskFilter()) { 987363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (!stroke.isHairlineStyle()) { 988363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (stroke.applyToPath(&tmpPath, *pathPtr)) { 989363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger pathPtr = &tmpPath; 990363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger stroke.setFillStyle(); 991363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 992363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 993363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 99480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // avoid possibly allocating a new path in transform if we can 99580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPath* devPathPtr = pathIsMutable ? pathPtr : &tmpPath; 99680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 99780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // transform the path into device space 99880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pathPtr->transform(fContext->getMatrix(), devPathPtr); 999363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (!drawWithGPUMaskFilter(fContext, *devPathPtr, stroke, paint.getMaskFilter(), 1000363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger *draw.fClip, draw.fBounder, &grPaint)) { 1001363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkPaint::Style style = stroke.isHairlineStyle() ? SkPaint::kStroke_Style : 1002363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkPaint::kFill_Style; 100380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru drawWithMaskFilter(fContext, *devPathPtr, paint.getMaskFilter(), 100480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *draw.fClip, draw.fBounder, &grPaint, style); 100580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 100680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 100780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 100880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1009363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fContext->drawPath(grPaint, *pathPtr, stroke); 101080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 101180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 101280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace { 101380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 101480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruinline int get_tile_count(int l, int t, int r, int b, int tileSize) { 101580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int tilesX = (r / tileSize) - (l / tileSize) + 1; 101680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int tilesY = (b / tileSize) - (t / tileSize) + 1; 101780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return tilesX * tilesY; 101880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 101980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 102080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruinline int determine_tile_size(const SkBitmap& bitmap, 102180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkRect& src, 102280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int maxTextureSize) { 102380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static const int kSmallTileSize = 1 << 10; 102480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (maxTextureSize <= kSmallTileSize) { 102580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return maxTextureSize; 102680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 102780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 102880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t maxTexTotalTileSize; 102980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t smallTotalTileSize; 103080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 103180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIRect iSrc; 103280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru src.roundOut(&iSrc); 103380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 103480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru maxTexTotalTileSize = get_tile_count(iSrc.fLeft, 103580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru iSrc.fTop, 103680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru iSrc.fRight, 103780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru iSrc.fBottom, 103880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru maxTextureSize); 103980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru smallTotalTileSize = get_tile_count(iSrc.fLeft, 104080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru iSrc.fTop, 104180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru iSrc.fRight, 104280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru iSrc.fBottom, 104380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kSmallTileSize); 104480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 104580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru maxTexTotalTileSize *= maxTextureSize * maxTextureSize; 104680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru smallTotalTileSize *= kSmallTileSize * kSmallTileSize; 104780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 104880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (maxTexTotalTileSize > 2 * smallTotalTileSize) { 104980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return kSmallTileSize; 105080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 105180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return maxTextureSize; 105280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 105380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 105480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 105580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 105680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkGpuDevice::shouldTileBitmap(const SkBitmap& bitmap, 105780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrTextureParams& params, 105880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkRect* srcRectPtr) const { 105980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // if bitmap is explictly texture backed then just use the texture 106080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != bitmap.getTexture()) { 106180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 106280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 106380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // if it's larger than the max texture size, then we have no choice but 106480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // tiling 106580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const int maxTextureSize = fContext->getMaxTextureSize(); 106680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (bitmap.width() > maxTextureSize || 106780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bitmap.height() > maxTextureSize) { 106880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 106980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 107080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // if we are going to have to draw the whole thing, then don't tile 107180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == srcRectPtr) { 107280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 107380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 107480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // if the entire texture is already in our cache then no reason to tile it 1075d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (GrIsBitmapInCache(fContext, bitmap, ¶ms)) { 107680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 107780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 107880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 107980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // At this point we know we could do the draw by uploading the entire bitmap 108080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // as a texture. However, if the texture would be large compared to the 108180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // cache size and we don't require most of it for this draw then tile to 108280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // reduce the amount of upload and cache spill. 108380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 108480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // assumption here is that sw bitmap size is a good proxy for its size as 108580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // a texture 108680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t bmpSize = bitmap.getSize(); 108780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t cacheSize; 108880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fContext->getTextureCacheLimits(NULL, &cacheSize); 108980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (bmpSize < cacheSize / 2) { 109080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 109180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 109280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 109380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar fracUsed = SkScalarMul(srcRectPtr->width() / bitmap.width(), 109480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcRectPtr->height() / bitmap.height()); 109580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fracUsed <= SK_ScalarHalf) { 109680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 109780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 109880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 109980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 110080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 110180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 110280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkGpuDevice::drawBitmap(const SkDraw& draw, 110380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkBitmap& bitmap, 110480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkIRect* srcRectPtr, 110580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkMatrix& m, 110680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPaint& paint) { 110780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 110880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect tmp; 110980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect* tmpPtr = NULL; 111080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 111180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // convert from SkIRect to SkRect 111280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != srcRectPtr) { 111380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp.set(*srcRectPtr); 111480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmpPtr = &tmp; 111580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 111680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 111780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // We cannot call drawBitmapRect here since 'm' could be anything 111880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->drawBitmapCommon(draw, bitmap, tmpPtr, m, paint); 111980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 112080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 112180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkGpuDevice::drawBitmapCommon(const SkDraw& draw, 112280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkBitmap& bitmap, 112380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkRect* srcRectPtr, 112480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkMatrix& m, 112580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPaint& paint) { 112680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CHECK_SHOULD_DRAW(draw, false); 112780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 112880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect srcRect; 112980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == srcRectPtr) { 113080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcRect.set(0, 0, SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.height())); 113180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 113280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcRect = *srcRectPtr; 113380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 113480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 113580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (paint.getMaskFilter()){ 113680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Convert the bitmap to a shader so that the rect can be drawn 113780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // through drawRect, which supports mask filters. 113880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix newM(m); 113980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkBitmap tmp; // subset of bitmap, if necessary 114080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkBitmap* bitmapPtr = &bitmap; 114180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != srcRectPtr) { 114280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIRect iSrc; 114380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcRect.roundOut(&iSrc); 114480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!bitmap.extractSubset(&tmp, iSrc)) { 114580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; // extraction failed 114680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 114780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bitmapPtr = &tmp; 114880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcRect.offset(SkIntToScalar(-iSrc.fLeft), SkIntToScalar(-iSrc.fTop)); 114980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // The source rect has changed so update the matrix 115080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru newM.preTranslate(SkIntToScalar(iSrc.fLeft), SkIntToScalar(iSrc.fTop)); 115180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 115280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 115380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPaint paintWithTexture(paint); 115480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paintWithTexture.setShader(SkShader::CreateBitmapShader(*bitmapPtr, 115580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkShader::kClamp_TileMode, SkShader::kClamp_TileMode))->unref(); 115680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 115780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Transform 'newM' needs to be concatenated to the current matrix, 115880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // rather than transforming the primitive directly, so that 'newM' will 115980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // also affect the behavior of the mask filter. 116080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix drawMatrix; 116180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru drawMatrix.setConcat(fContext->getMatrix(), newM); 116280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDraw transformedDraw(draw); 116380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru transformedDraw.fMatrix = &drawMatrix; 116480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 116580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->drawRect(transformedDraw, srcRect, paintWithTexture); 116680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 116780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 116880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 116980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 117080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPaint grPaint; 1171d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1172d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger bool alphaOnly = !(SkBitmap::kA8_Config == bitmap.config()); 1173d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (!skPaint2GrPaintNoShader(this, paint, alphaOnly, false, &grPaint)) { 117480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 117580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 117680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTextureParams params; 117780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru params.setBilerp(paint.isFilterBitmap()); 117880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 117980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!this->shouldTileBitmap(bitmap, params, srcRectPtr)) { 118080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // take the simple case 118180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->internalDrawBitmap(bitmap, srcRect, m, params, &grPaint); 118280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 118380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->drawTiledBitmap(bitmap, srcRect, m, params, &grPaint); 118480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 118580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 118680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 118780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// Break 'bitmap' into several tiles to draw it since it has already 118880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// been determined to be too large to fit in VRAM 118980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap, 119080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkRect& srcRect, 119180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkMatrix& m, 119280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrTextureParams& params, 119380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPaint* grPaint) { 119480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const int maxTextureSize = fContext->getMaxTextureSize(); 119580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 119680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int tileSize = determine_tile_size(bitmap, srcRect, maxTextureSize); 119780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 119880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // compute clip bounds in local coordinates 119980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect clipRect; 120080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 120180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrRenderTarget* rt = fContext->getRenderTarget(); 120280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru clipRect.setWH(SkIntToScalar(rt->width()), SkIntToScalar(rt->height())); 120380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!fContext->getClip()->fClipStack->intersectRectWithClip(&clipRect)) { 120480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 120580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 120680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix matrix, inverse; 120780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru matrix.setConcat(fContext->getMatrix(), m); 120880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!matrix.invert(&inverse)) { 120980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 121080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 121180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inverse.mapRect(&clipRect); 121280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 121380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 121480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int nx = bitmap.width() / tileSize; 121580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int ny = bitmap.height() / tileSize; 121680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int x = 0; x <= nx; x++) { 121780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int y = 0; y <= ny; y++) { 121880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect tileR; 121980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tileR.set(SkIntToScalar(x * tileSize), 122080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIntToScalar(y * tileSize), 122180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIntToScalar((x + 1) * tileSize), 122280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIntToScalar((y + 1) * tileSize)); 122380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 122480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!SkRect::Intersects(tileR, clipRect)) { 122580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru continue; 122680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 122780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 122880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!tileR.intersect(srcRect)) { 122980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru continue; 123080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 123180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 123280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkBitmap tmpB; 123380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIRect iTileR; 123480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tileR.roundOut(&iTileR); 123580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (bitmap.extractSubset(&tmpB, iTileR)) { 123680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // now offset it to make it "local" to our tmp bitmap 123780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tileR.offset(SkIntToScalar(-iTileR.fLeft), SkIntToScalar(-iTileR.fTop)); 123880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix tmpM(m); 123980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmpM.preTranslate(SkIntToScalar(iTileR.fLeft), 124080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIntToScalar(iTileR.fTop)); 124180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 124280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->internalDrawBitmap(tmpB, tileR, tmpM, params, grPaint); 124380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 124480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 124580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 124680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 124780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 124880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace { 124980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 125080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool hasAlignedSamples(const SkRect& srcRect, const SkRect& transformedRect) { 125180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // detect pixel disalignment 125280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (SkScalarAbs(SkScalarRoundToScalar(transformedRect.left()) - 125380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru transformedRect.left()) < COLOR_BLEED_TOLERANCE && 125480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarAbs(SkScalarRoundToScalar(transformedRect.top()) - 125580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru transformedRect.top()) < COLOR_BLEED_TOLERANCE && 125680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarAbs(transformedRect.width() - srcRect.width()) < 125780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru COLOR_BLEED_TOLERANCE && 125880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarAbs(transformedRect.height() - srcRect.height()) < 125980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru COLOR_BLEED_TOLERANCE) { 126080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 126180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 126280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 126380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 126480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 126580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool mayColorBleed(const SkRect& srcRect, const SkRect& transformedRect, 126680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkMatrix& m) { 126780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Only gets called if hasAlignedSamples returned false. 126880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // So we can assume that sampling is axis aligned but not texel aligned. 126980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(!hasAlignedSamples(srcRect, transformedRect)); 127080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect innerSrcRect(srcRect), innerTransformedRect, 127180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru outerTransformedRect(transformedRect); 127280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru innerSrcRect.inset(SK_ScalarHalf, SK_ScalarHalf); 127380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m.mapRect(&innerTransformedRect, innerSrcRect); 127480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 127580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // The gap between outerTransformedRect and innerTransformedRect 127680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // represents the projection of the source border area, which is 127780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // problematic for color bleeding. We must check whether any 127880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // destination pixels sample the border area. 127980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru outerTransformedRect.inset(COLOR_BLEED_TOLERANCE, COLOR_BLEED_TOLERANCE); 128080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru innerTransformedRect.outset(COLOR_BLEED_TOLERANCE, COLOR_BLEED_TOLERANCE); 128180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIRect outer, inner; 128280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru outerTransformedRect.round(&outer); 128380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru innerTransformedRect.round(&inner); 128480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // If the inner and outer rects round to the same result, it means the 128580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // border does not overlap any pixel centers. Yay! 128680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return inner != outer; 128780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 128880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 128980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} // unnamed namespace 129080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 129180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 129280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * This is called by drawBitmap(), which has to handle images that may be too 129380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * large to be represented by a single texture. 129480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 129580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * internalDrawBitmap assumes that the specified bitmap will fit in a texture 129680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * and that non-texture portion of the GrPaint has already been setup. 129780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 129880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap, 129980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkRect& srcRect, 130080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkMatrix& m, 130180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrTextureParams& params, 130280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPaint* grPaint) { 130380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(bitmap.width() <= fContext->getMaxTextureSize() && 130480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bitmap.height() <= fContext->getMaxTextureSize()); 130580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 130680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAutoLockPixels alp(bitmap, !bitmap.getTexture()); 130780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!bitmap.getTexture() && !bitmap.readyToDraw()) { 130880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("nothing to draw\n"); 130980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 131080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 131180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 131280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTexture* texture; 131380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAutoCachedTexture act(this, bitmap, ¶ms, &texture); 131480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == texture) { 131580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 131680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 131780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 131880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrRect dstRect(srcRect); 131980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrRect paintRect; 132080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar wInv = SkScalarInvert(SkIntToScalar(bitmap.width())); 132180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar hInv = SkScalarInvert(SkIntToScalar(bitmap.height())); 132280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paintRect.setLTRB(SkScalarMul(srcRect.fLeft, wInv), 132380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarMul(srcRect.fTop, hInv), 132480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarMul(srcRect.fRight, wInv), 132580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarMul(srcRect.fBottom, hInv)); 132680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 132780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool needsTextureDomain = false; 132880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (params.isBilerp()) { 132980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Need texture domain if drawing a sub rect. 133080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru needsTextureDomain = srcRect.width() < bitmap.width() || 133180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcRect.height() < bitmap.height(); 133280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (m.rectStaysRect() && fContext->getMatrix().rectStaysRect()) { 133380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // sampling is axis-aligned 133480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrRect transformedRect; 133580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix srcToDeviceMatrix(m); 133680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcToDeviceMatrix.postConcat(fContext->getMatrix()); 133780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcToDeviceMatrix.mapRect(&transformedRect, srcRect); 133880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 133980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (hasAlignedSamples(srcRect, transformedRect)) { 134080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // We could also turn off filtering here (but we already did a cache lookup with 134180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // params). 134280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru needsTextureDomain = false; 134380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 134480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru needsTextureDomain = needsTextureDomain && 134580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru mayColorBleed(srcRect, transformedRect, m); 134680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 134780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 134880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 134980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 135080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrRect textureDomain = GrRect::MakeEmpty(); 1351d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkAutoTUnref<GrEffectRef> effect; 135280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (needsTextureDomain) { 135380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Use a constrained texture domain to avoid color bleeding 1354363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkScalar left, top, right, bottom; 1355363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (srcRect.width() > SK_Scalar1) { 1356363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkScalar border = SK_ScalarHalf / bitmap.width(); 135780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru left = paintRect.left() + border; 135880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru right = paintRect.right() - border; 135980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 1360363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger left = right = SkScalarHalf(paintRect.left() + paintRect.right()); 136180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 1362363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (srcRect.height() > SK_Scalar1) { 1363363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkScalar border = SK_ScalarHalf / bitmap.height(); 136480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru top = paintRect.top() + border; 136580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bottom = paintRect.bottom() - border; 136680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 1367363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger top = bottom = SkScalarHalf(paintRect.top() + paintRect.bottom()); 136880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 136980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru textureDomain.setLTRB(left, top, right, bottom); 1370363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger effect.reset(GrTextureDomainEffect::Create(texture, 1371363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMatrix::I(), 1372363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger textureDomain, 1373363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrTextureDomainEffect::kClamp_WrapMode, 1374363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger params.isBilerp())); 137580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 1376d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger effect.reset(GrSimpleTextureEffect::Create(texture, SkMatrix::I(), params)); 137780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 1378363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger grPaint->colorStage(kBitmapTextureIdx)->setEffect(effect); 137980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fContext->drawRectToRect(*grPaint, dstRect, paintRect, &m); 138080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 138180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 138280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace { 138380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1384363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid apply_effect(GrContext* context, 1385363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrTexture* srcTexture, 1386363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrTexture* dstTexture, 1387363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const GrRect& rect, 1388d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrEffectRef* effect) { 138980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(srcTexture && srcTexture->getContext() == context); 139080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrContext::AutoMatrix am; 139180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru am.setIdentity(context); 139280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrContext::AutoRenderTarget art(context, dstTexture->asRenderTarget()); 139380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrContext::AutoClip acs(context, rect); 139480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 139580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPaint paint; 1396363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger paint.colorStage(0)->setEffect(effect); 139780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru context->drawRect(paint, rect); 139880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 139980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 140080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 140180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1402d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerstatic SkBitmap wrap_texture(GrTexture* texture) { 1403d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkBitmap result; 1404d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger bool dummy; 1405d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkBitmap::Config config = grConfig2skConfig(texture->config(), &dummy); 1406d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger result.setConfig(config, texture->width(), texture->height()); 1407d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger result.setPixelRef(SkNEW_ARGS(SkGrPixelRef, (texture)))->unref(); 1408d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return result; 1409d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger} 1410d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1411d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerstatic bool filter_texture(SkDevice* device, GrContext* context, 1412d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrTexture* texture, SkImageFilter* filter, 1413d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger int w, int h, SkBitmap* result) { 141480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(filter); 141580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDeviceImageFilterProxy proxy(device); 141680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 141780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTextureDesc desc; 141880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fFlags = kRenderTarget_GrTextureFlagBit, 1419d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger desc.fWidth = w; 1420d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger desc.fHeight = h; 142180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fConfig = kRGBA_8888_GrPixelConfig; 1422d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrEffectRef* effect; 142380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 142480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (filter->canFilterImageGPU()) { 1425363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // Save the render target and set it to NULL, so we don't accidentally draw to it in the 1426363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // filter. Also set the clip wide open and the matrix to identity. 1427363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrContext::AutoWideOpenIdentityDraw awo(context, NULL); 1428d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return filter->filterImageGPU(&proxy, wrap_texture(texture), result); 1429363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } else if (filter->asNewEffect(&effect, texture)) { 143080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAutoScratchTexture dst(context, desc); 1431d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkRect r = SkRect::MakeWH(SkIntToScalar(w), SkIntToScalar(h)); 1432d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger apply_effect(context, texture, dst.texture(), r, effect); 1433d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkAutoTUnref<GrTexture> resultTex(dst.detach()); 1434363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger effect->unref(); 1435d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger *result = wrap_texture(resultTex.get()); 1436d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return true; 1437d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } else { 1438d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return false; 143980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 144080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 144180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 144280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap, 144380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int left, int top, const SkPaint& paint) { 144480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // drawSprite is defined to be in device coords. 144580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CHECK_SHOULD_DRAW(draw, true); 144680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 144780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAutoLockPixels alp(bitmap, !bitmap.getTexture()); 144880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!bitmap.getTexture() && !bitmap.readyToDraw()) { 144980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 145080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 145180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 145280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int w = bitmap.width(); 145380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int h = bitmap.height(); 145480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 145580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPaint grPaint; 1456d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if(!skPaint2GrPaintNoShader(this, paint, true, false, &grPaint)) { 145780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 145880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 145980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1460363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrEffectStage* stage = grPaint.colorStage(kBitmapTextureIdx); 146180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 146280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTexture* texture; 1463363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger stage->reset(); 146480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // draw sprite uses the default texture params 146580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAutoCachedTexture act(this, bitmap, NULL, &texture); 1466d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger grPaint.colorStage(kBitmapTextureIdx)->setEffect( 1467d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrSimpleTextureEffect::Create(texture, SkMatrix::I()))->unref(); 146880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 146980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkImageFilter* filter = paint.getImageFilter(); 147080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != filter) { 1471d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkBitmap filterBitmap; 1472d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (filter_texture(this, fContext, texture, filter, w, h, &filterBitmap)) { 1473d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger grPaint.colorStage(kBitmapTextureIdx)->setEffect( 1474d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrSimpleTextureEffect::Create((GrTexture*) filterBitmap.getTexture(), SkMatrix::I()))->unref(); 1475d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger texture = (GrTexture*) filterBitmap.getTexture(); 1476d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger w = filterBitmap.width(); 1477d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger h = filterBitmap.height(); 147880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 147980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 148080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 148180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fContext->drawRectToRect(grPaint, 1482363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrRect::MakeXYWH(SkIntToScalar(left), 1483363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkIntToScalar(top), 1484363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkIntToScalar(w), 1485363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkIntToScalar(h)), 1486363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrRect::MakeWH(SK_Scalar1 * w / texture->width(), 1487363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SK_Scalar1 * h / texture->height())); 148880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 148980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 149080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkGpuDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap, 149180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkRect* src, const SkRect& dst, 149280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPaint& paint) { 149380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix matrix; 149480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect bitmapBounds, tmpSrc; 149580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 149680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bitmapBounds.set(0, 0, 149780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIntToScalar(bitmap.width()), 149880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIntToScalar(bitmap.height())); 149980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 150080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Compute matrix from the two rectangles 150180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != src) { 150280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmpSrc = *src; 150380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 150480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmpSrc = bitmapBounds; 150580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 150680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit); 150780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 150880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // clip the tmpSrc to the bounds of the bitmap. No check needed if src==null. 150980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != src) { 151080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!bitmapBounds.contains(tmpSrc)) { 151180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!tmpSrc.intersect(bitmapBounds)) { 151280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; // nothing to draw 151380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 151480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 151580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 151680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 151780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->drawBitmapCommon(draw, bitmap, &tmpSrc, matrix, paint); 151880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 151980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 152080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* device, 152180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int x, int y, const SkPaint& paint) { 152280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // clear of the source device must occur before CHECK_SHOULD_DRAW 152380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkGpuDevice* dev = static_cast<SkGpuDevice*>(device); 152480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (dev->fNeedClear) { 152580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // TODO: could check here whether we really need to draw at all 152680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dev->clear(0x0); 152780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 152880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 152980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // drawDevice is defined to be in device coords. 153080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CHECK_SHOULD_DRAW(draw, true); 153180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 153280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPaint grPaint; 1533363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger grPaint.colorStage(kBitmapTextureIdx)->reset(); 153480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!dev->bindDeviceAsTexture(&grPaint) || 1535d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger !skPaint2GrPaintNoShader(this, paint, true, false, &grPaint)) { 153680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 153780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 153880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1539d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrTexture* devTex = (*grPaint.getColorStage(kBitmapTextureIdx).getEffect())->texture(0); 154080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(NULL != devTex); 154180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1542d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const SkBitmap& bm = dev->accessBitmap(false); 1543d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger int w = bm.width(); 1544d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger int h = bm.height(); 1545d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 154680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkImageFilter* filter = paint.getImageFilter(); 154780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != filter) { 1548d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkBitmap filterBitmap; 1549d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (filter_texture(this, fContext, devTex, filter, w, h, &filterBitmap)) { 1550d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger grPaint.colorStage(kBitmapTextureIdx)->setEffect( 1551d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrSimpleTextureEffect::Create((GrTexture*) filterBitmap.getTexture(), SkMatrix::I()))->unref(); 1552d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger devTex = (GrTexture*) filterBitmap.getTexture(); 1553d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger w = filterBitmap.width(); 1554d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger h = filterBitmap.height(); 155580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 155680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 155780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1558363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrRect dstRect = GrRect::MakeXYWH(SkIntToScalar(x), 1559363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkIntToScalar(y), 1560363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkIntToScalar(w), 1561363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkIntToScalar(h)); 156280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 156380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // The device being drawn may not fill up its texture (saveLayer uses 156480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // the approximate ). 1565363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrRect srcRect = GrRect::MakeWH(SK_Scalar1 * w / devTex->width(), 1566363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SK_Scalar1 * h / devTex->height()); 156780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 156880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fContext->drawRectToRect(grPaint, dstRect, srcRect); 156980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 157080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 157180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkGpuDevice::canHandleImageFilter(SkImageFilter* filter) { 1572363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (!filter->asNewEffect(NULL, NULL) && 157380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru !filter->canFilterImageGPU()) { 157480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 157580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 157680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 157780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 157880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 157980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkGpuDevice::filterImage(SkImageFilter* filter, const SkBitmap& src, 158080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkMatrix& ctm, 158180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkBitmap* result, SkIPoint* offset) { 158280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // want explicitly our impl, so guard against a subclass of us overriding it 158380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!this->SkGpuDevice::canHandleImageFilter(filter)) { 158480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 158580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 158680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 158780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAutoLockPixels alp(src, !src.getTexture()); 158880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!src.getTexture() && !src.readyToDraw()) { 158980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 159080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 159180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 159280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPaint paint; 159380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 159480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTexture* texture; 159580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // We assume here that the filter will not attempt to tile the src. Otherwise, this cache lookup 159680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // must be pushed upstack. 159780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAutoCachedTexture act(this, src, NULL, &texture); 159880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1599d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return filter_texture(this, fContext, texture, filter, src.width(), src.height(), result); 160080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 160180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 160280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 160380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 160480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// must be in SkCanvas::VertexMode order 160580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const GrPrimitiveType gVertexMode2PrimitiveType[] = { 160680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kTriangles_GrPrimitiveType, 160780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kTriangleStrip_GrPrimitiveType, 160880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kTriangleFan_GrPrimitiveType, 160980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 161080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 161180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode, 161280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int vertexCount, const SkPoint vertices[], 161380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPoint texs[], const SkColor colors[], 161480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkXfermode* xmode, 161580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const uint16_t indices[], int indexCount, 161680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPaint& paint) { 161780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CHECK_SHOULD_DRAW(draw, false); 161880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 161980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPaint grPaint; 162080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we ignore the shader if texs is null. 162180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == texs) { 1622d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (!skPaint2GrPaintNoShader(this, paint, false, NULL == colors, &grPaint)) { 162380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 162480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 162580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 1626d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (!skPaint2GrPaintShader(this, paint, NULL == colors, &grPaint)) { 162780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 162880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 162980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 163080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 163180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != xmode && NULL != texs && NULL != colors) { 1632d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (!SkXfermode::IsMode(xmode, SkXfermode::kModulate_Mode)) { 163380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("Unsupported vertex-color/texture xfer mode.\n"); 163480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if 0 163580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return 163680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 163780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 163880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 163980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 164080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAutoSTMalloc<128, GrColor> convertedColors(0); 164180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != colors) { 164280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // need to convert byte order and from non-PM to PM 164380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru convertedColors.reset(vertexCount); 164480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < vertexCount; ++i) { 164580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru convertedColors[i] = SkColor2GrColor(colors[i]); 164680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 164780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru colors = convertedColors.get(); 164880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 164980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fContext->drawVertices(grPaint, 165080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru gVertexMode2PrimitiveType[vmode], 165180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru vertexCount, 165280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru (GrPoint*) vertices, 165380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru (GrPoint*) texs, 165480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru colors, 165580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru indices, 165680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru indexCount); 165780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 165880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 165980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 166080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 166180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void GlyphCacheAuxProc(void* data) { 166280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrFontScaler* scaler = (GrFontScaler*)data; 166380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkSafeUnref(scaler); 166480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 166580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 166680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic GrFontScaler* get_gr_font_scaler(SkGlyphCache* cache) { 166780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void* auxData; 166880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrFontScaler* scaler = NULL; 166980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (cache->getAuxProcData(GlyphCacheAuxProc, &auxData)) { 167080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru scaler = (GrFontScaler*)auxData; 167180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 167280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == scaler) { 167380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru scaler = SkNEW_ARGS(SkGrFontScaler, (cache)); 167480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru cache->setAuxProc(GlyphCacheAuxProc, scaler); 167580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 167680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return scaler; 167780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 167880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 167980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void SkGPU_Draw1Glyph(const SkDraw1Glyph& state, 168080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixed fx, SkFixed fy, 168180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkGlyph& glyph) { 168280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(glyph.fWidth > 0 && glyph.fHeight > 0); 168380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 168480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrSkDrawProcs* procs = static_cast<GrSkDrawProcs*>(state.fDraw->fProcs); 168580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 168680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == procs->fFontScaler) { 168780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru procs->fFontScaler = get_gr_font_scaler(state.fCache); 168880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 168980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 169080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru procs->fTextContext->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(), 169180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru glyph.getSubXFixed(), 169280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru glyph.getSubYFixed()), 169380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixedFloorToFixed(fx), 169480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixedFloorToFixed(fy), 169580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru procs->fFontScaler); 169680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 169780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 169880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkDrawProcs* SkGpuDevice::initDrawForText(GrTextContext* context) { 169980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 170080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // deferred allocation 170180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == fDrawProcs) { 170280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawProcs = SkNEW(GrSkDrawProcs); 170380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawProcs->fD1GProc = SkGPU_Draw1Glyph; 170480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawProcs->fContext = fContext; 170580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 170680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 170780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // init our (and GL's) state 170880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawProcs->fTextContext = context; 170980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawProcs->fFontScaler = NULL; 171080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fDrawProcs; 171180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 171280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 171380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkGpuDevice::drawText(const SkDraw& draw, const void* text, 171480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t byteLength, SkScalar x, SkScalar y, 171580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPaint& paint) { 171680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CHECK_SHOULD_DRAW(draw, false); 171780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 171880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fContext->getMatrix().hasPerspective()) { 171980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // this guy will just call our drawPath() 172080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru draw.drawText((const char*)text, byteLength, x, y, paint); 172180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 172280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDraw myDraw(draw); 172380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 172480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPaint grPaint; 1725d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { 172680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 172780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 172880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTextContext context(fContext, grPaint); 172980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru myDraw.fProcs = this->initDrawForText(&context); 173080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->INHERITED::drawText(myDraw, text, byteLength, x, y, paint); 173180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 173280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 173380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 173480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, 173580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t byteLength, const SkScalar pos[], 173680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar constY, int scalarsPerPos, 173780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPaint& paint) { 173880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CHECK_SHOULD_DRAW(draw, false); 173980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 174080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fContext->getMatrix().hasPerspective()) { 174180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // this guy will just call our drawPath() 174280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru draw.drawPosText((const char*)text, byteLength, pos, constY, 174380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru scalarsPerPos, paint); 174480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 174580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDraw myDraw(draw); 174680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 174780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPaint grPaint; 1748d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { 174980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 175080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 175180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTextContext context(fContext, grPaint); 175280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru myDraw.fProcs = this->initDrawForText(&context); 175380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->INHERITED::drawPosText(myDraw, text, byteLength, pos, constY, 175480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru scalarsPerPos, paint); 175580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 175680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 175780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 175880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkGpuDevice::drawTextOnPath(const SkDraw& draw, const void* text, 175980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t len, const SkPath& path, 176080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkMatrix* m, const SkPaint& paint) { 176180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CHECK_SHOULD_DRAW(draw, false); 176280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 176380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(draw.fDevice == this); 176480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru draw.drawTextOnPath((const char*)text, len, path, m, paint); 176580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 176680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 176780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 176880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 176980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkGpuDevice::filterTextFlags(const SkPaint& paint, TextFlags* flags) { 177080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!paint.isLCDRenderText()) { 177180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we're cool with the paint as is 177280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 177380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 177480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 177580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (paint.getShader() || 177680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.getXfermode() || // unless its srcover 177780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.getMaskFilter() || 177880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.getRasterizer() || 177980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.getColorFilter() || 178080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.getPathEffect() || 178180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.isFakeBoldText() || 178280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.getStyle() != SkPaint::kFill_Style) { 178380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // turn off lcd 178480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru flags->fFlags = paint.getFlags() & ~SkPaint::kLCDRenderText_Flag; 178580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru flags->fHinting = paint.getHinting(); 178680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 178780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 178880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we're cool with the paint as is 178980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 179080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 179180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 179280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkGpuDevice::flush() { 179380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru DO_DEFERRED_CLEAR(); 179480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fContext->resolveRenderTarget(fRenderTarget); 179580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 179680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 179780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 179880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 179980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkDevice* SkGpuDevice::onCreateCompatibleDevice(SkBitmap::Config config, 180080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int width, int height, 180180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool isOpaque, 180280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Usage usage) { 180380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTextureDesc desc; 180480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fConfig = fRenderTarget->config(); 180580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fFlags = kRenderTarget_GrTextureFlagBit; 180680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fWidth = width; 180780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fHeight = height; 180880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fSampleCnt = fRenderTarget->numSamples(); 180980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1810d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkAutoTUnref<GrTexture> texture; 181180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Skia's convention is to only clear a device if it is non-opaque. 181280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool needClear = !isOpaque; 181380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 181480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if CACHE_COMPATIBLE_DEVICE_TEXTURES 181580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // layers are never draw in repeat modes, so we can request an approx 181680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // match and ignore any padding. 1817d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const GrContext::ScratchTexMatch match = (kSaveLayer_Usage == usage) ? 1818d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrContext::kApprox_ScratchTexMatch : 1819d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrContext::kExact_ScratchTexMatch; 1820d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger texture.reset(fContext->lockAndRefScratchTexture(desc, match)); 182180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 1822d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger texture.reset(fContext->createUncachedTexture(desc, NULL, 0)); 182380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 1824d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (NULL != texture.get()) { 1825d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return SkNEW_ARGS(SkGpuDevice,(fContext, texture, needClear)); 182680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 1827d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrPrintf("---- failed to create compatible device texture [%d %d]\n", width, height); 182880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return NULL; 182980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 183080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 183180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 183280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkGpuDevice::SkGpuDevice(GrContext* context, 183380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTexture* texture, 183480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool needClear) 183580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru : SkDevice(make_bitmap(context, texture->asRenderTarget())) { 183680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 183780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(texture && texture->asRenderTarget()); 183880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // This constructor is called from onCreateCompatibleDevice. It has locked the RT in the texture 183980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // cache. We pass true for the third argument so that it will get unlocked. 184080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->initFromRenderTarget(context, texture->asRenderTarget(), true); 184180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fNeedClear = needClear; 184280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 1843