1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlurMaskFilter.h" 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlurMask.h" 11736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com#include "SkGpuBlurUtils.h" 128b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h" 138b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMaskFilter.h" 15a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com#include "SkRRect.h" 167c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com#include "SkRTConf.h" 170bd80fa01bba2b3f0f49937fcb17928c74bde5a6robertphillips@google.com#include "SkStringUtils.h" 18491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com#include "SkStrokeRec.h" 19491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com 20491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com#if SK_SUPPORT_GPU 21491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com#include "GrContext.h" 22491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com#include "GrTexture.h" 23b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "GrProcessor.h" 24b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "gl/GrGLProcessor.h" 2530ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "gl/builders/GrGLProgramBuilder.h" 26491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com#include "effects/GrSimpleTextureEffect.h" 27b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "GrTBackendProcessorFactory.h" 28491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com#include "SkGrPixelRef.h" 293d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org#include "SkDraw.h" 30491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com#endif 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 32508022cff04c5226cfd1714ba049528f57f9f25ecommit-bot@chromium.orgSkScalar SkBlurMaskFilter::ConvertRadiusToSigma(SkScalar radius) { 33508022cff04c5226cfd1714ba049528f57f9f25ecommit-bot@chromium.org return SkBlurMask::ConvertRadiusToSigma(radius); 34508022cff04c5226cfd1714ba049528f57f9f25ecommit-bot@chromium.org} 35508022cff04c5226cfd1714ba049528f57f9f25ecommit-bot@chromium.org 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkBlurMaskFilterImpl : public SkMaskFilter { 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 38e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle, uint32_t flags); 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // overrides from SkMaskFilter 4130711b764be6bbb58caa30a0ac5d1474c894efe7reed@google.com virtual SkMask::Format getFormat() const SK_OVERRIDE; 4203016a36206be42e91e8e0eb62fe8fb95da97b38reed@google.com virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&, 4330711b764be6bbb58caa30a0ac5d1474c894efe7reed@google.com SkIPoint* margin) const SK_OVERRIDE; 442e71f1619d9a2c51c1292e618f42a56ad2da1de8skia.committer@gmail.com 45491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com#if SK_SUPPORT_GPU 461842adf01320f9197b449de7375d08ccac43f389skia.committer@gmail.com virtual bool canFilterMaskGPU(const SkRect& devBounds, 47491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com const SkIRect& clipBounds, 48491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com const SkMatrix& ctm, 49491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com SkRect* maskRect) const SK_OVERRIDE; 50cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org virtual bool directFilterMaskGPU(GrContext* context, 51cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org GrPaint* grp, 52cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org const SkStrokeRec& strokeRec, 53cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org const SkPath& path) const SK_OVERRIDE; 54821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org virtual bool directFilterRRectMaskGPU(GrContext* context, 55821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org GrPaint* grp, 56821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org const SkStrokeRec& strokeRec, 57821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org const SkRRect& rrect) const SK_OVERRIDE; 58cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 591842adf01320f9197b449de7375d08ccac43f389skia.committer@gmail.com virtual bool filterMaskGPU(GrTexture* src, 6041bf930039314cc71039b12957195f1c65c30ce1commit-bot@chromium.org const SkMatrix& ctm, 611842adf01320f9197b449de7375d08ccac43f389skia.committer@gmail.com const SkRect& maskRect, 62491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com GrTexture** result, 6341bf930039314cc71039b12957195f1c65c30ce1commit-bot@chromium.org bool canOverwriteSrc) const SK_OVERRIDE; 64491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com#endif 65491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com 6630711b764be6bbb58caa30a0ac5d1474c894efe7reed@google.com virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE; 67daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com virtual bool asABlur(BlurRec*) const SK_OVERRIDE; 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 690f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org SK_TO_STRING_OVERRIDE() 70ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBlurMaskFilterImpl) 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 72d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.comprotected: 73dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com virtual FilterReturn filterRectsToNine(const SkRect[], int count, const SkMatrix&, 74dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com const SkIRect& clipBounds, 7530711b764be6bbb58caa30a0ac5d1474c894efe7reed@google.com NinePatch*) const SK_OVERRIDE; 762e71f1619d9a2c51c1292e618f42a56ad2da1de8skia.committer@gmail.com 77a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com virtual FilterReturn filterRRectToNine(const SkRRect&, const SkMatrix&, 78a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com const SkIRect& clipBounds, 79a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com NinePatch*) const SK_OVERRIDE; 80a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 812e71f1619d9a2c51c1292e618f42a56ad2da1de8skia.committer@gmail.com bool filterRectMask(SkMask* dstM, const SkRect& r, const SkMatrix& matrix, 827c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com SkIPoint* margin, SkMask::CreateMode createMode) const; 83a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org bool filterRRectMask(SkMask* dstM, const SkRRect& r, const SkMatrix& matrix, 84a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org SkIPoint* margin, SkMask::CreateMode createMode) const; 85453995e01d884d62ce2e808e0067e494c0c9c7faskia.committer@gmail.com 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 87491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com // To avoid unseemly allocation requests (esp. for finite platforms like 88491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com // handset) we limit the radius so something manageable. (as opposed to 89491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com // a request like 10,000) 907ce661d19c5cf4484305a1b20c44bd111f129847robertphillips@google.com static const SkScalar kMAX_BLUR_SIGMA; 917ce661d19c5cf4484305a1b20c44bd111f129847robertphillips@google.com 92e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org SkScalar fSigma; 93e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org SkBlurStyle fBlurStyle; 94e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org uint32_t fBlurFlags; 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 96daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com SkBlurQuality getQuality() const { 97daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com return (fBlurFlags & SkBlurMaskFilter::kHighQuality_BlurFlag) ? 98daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com kHigh_SkBlurQuality : kLow_SkBlurQuality; 99daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com } 100daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com 1018b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org SkBlurMaskFilterImpl(SkReadBuffer&); 1028b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; 1037ce661d19c5cf4484305a1b20c44bd111f129847robertphillips@google.com 1047ce661d19c5cf4484305a1b20c44bd111f129847robertphillips@google.com SkScalar computeXformedSigma(const SkMatrix& ctm) const { 105491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com bool ignoreTransform = SkToBool(fBlurFlags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag); 106491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com 1077ce661d19c5cf4484305a1b20c44bd111f129847robertphillips@google.com SkScalar xformedSigma = ignoreTransform ? fSigma : ctm.mapRadius(fSigma); 1087ce661d19c5cf4484305a1b20c44bd111f129847robertphillips@google.com return SkMinScalar(xformedSigma, kMAX_BLUR_SIGMA); 109491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com } 110fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1119fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed friend class SkBlurMaskFilter; 1129fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkMaskFilter INHERITED; 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1167ce661d19c5cf4484305a1b20c44bd111f129847robertphillips@google.comconst SkScalar SkBlurMaskFilterImpl::kMAX_BLUR_SIGMA = SkIntToScalar(128); 117491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com 118e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.orgSkMaskFilter* SkBlurMaskFilter::Create(SkBlurStyle style, SkScalar sigma, uint32_t flags) { 119e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org if (!SkScalarIsFinite(sigma) || sigma <= 0) { 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; 12103016a36206be42e91e8e0eb62fe8fb95da97b38reed@google.com } 122e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org if ((unsigned)style > (unsigned)kLastEnum_SkBlurStyle) { 123e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org return NULL; 124e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org } 125e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org if (flags > SkBlurMaskFilter::kAll_BlurFlag) { 126e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org return NULL; 127e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org } 128e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org return SkNEW_ARGS(SkBlurMaskFilterImpl, (sigma, style, flags)); 129e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org} 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13103016a36206be42e91e8e0eb62fe8fb95da97b38reed@google.com/////////////////////////////////////////////////////////////////////////////// 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 133e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.orgSkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle style, uint32_t flags) 134e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org : fSigma(sigma) 135e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org , fBlurStyle(style) 136e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org , fBlurFlags(flags) { 137e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org SkASSERT(fSigma > 0); 138e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org SkASSERT((unsigned)style <= kLastEnum_SkBlurStyle); 139038aff623d9fd47946cd31685f74cf473f7c84f0senorblanco@chromium.org SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag); 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14230711b764be6bbb58caa30a0ac5d1474c894efe7reed@google.comSkMask::Format SkBlurMaskFilterImpl::getFormat() const { 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkMask::kA8_Format; 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 146daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.combool SkBlurMaskFilterImpl::asABlur(BlurRec* rec) const { 147daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com if (fBlurFlags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag) { 148daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com return false; 149daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com } 150daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com 151daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com if (rec) { 152daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com rec->fSigma = fSigma; 153daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com rec->fStyle = fBlurStyle; 154daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com rec->fQuality = this->getQuality(); 155daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com } 156daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com return true; 157daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com} 158daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com 15903016a36206be42e91e8e0eb62fe8fb95da97b38reed@google.combool SkBlurMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src, 16030711b764be6bbb58caa30a0ac5d1474c894efe7reed@google.com const SkMatrix& matrix, 16130711b764be6bbb58caa30a0ac5d1474c894efe7reed@google.com SkIPoint* margin) const{ 1627ce661d19c5cf4484305a1b20c44bd111f129847robertphillips@google.com SkScalar sigma = this->computeXformedSigma(matrix); 163daaafa6e81860e3dc52660ba019c336f0a43f1e7reed@google.com return SkBlurMask::BoxBlur(dst, src, sigma, fBlurStyle, this->getQuality(), margin); 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1667c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.combool SkBlurMaskFilterImpl::filterRectMask(SkMask* dst, const SkRect& r, 1677c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com const SkMatrix& matrix, 1687c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com SkIPoint* margin, SkMask::CreateMode createMode) const{ 1697ce661d19c5cf4484305a1b20c44bd111f129847robertphillips@google.com SkScalar sigma = computeXformedSigma(matrix); 1707c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com 171e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org return SkBlurMask::BlurRect(sigma, dst, r, fBlurStyle, 1727c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com margin, createMode); 1737c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com} 1747c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com 175a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.orgbool SkBlurMaskFilterImpl::filterRRectMask(SkMask* dst, const SkRRect& r, 176a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org const SkMatrix& matrix, 177a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org SkIPoint* margin, SkMask::CreateMode createMode) const{ 178a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org SkScalar sigma = computeXformedSigma(matrix); 179a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org 180e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org return SkBlurMask::BlurRRect(sigma, dst, r, fBlurStyle, 181a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org margin, createMode); 182a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org} 183a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org 184d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com#include "SkCanvas.h" 185d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com 186a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.comstatic bool prepare_to_draw_into_mask(const SkRect& bounds, SkMask* mask) { 187a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com SkASSERT(mask != NULL); 188a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 189a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com bounds.roundOut(&mask->fBounds); 190d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com mask->fRowBytes = SkAlign4(mask->fBounds.width()); 191d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com mask->fFormat = SkMask::kA8_Format; 192a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com const size_t size = mask->computeImageSize(); 193d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com mask->fImage = SkMask::AllocImage(size); 194d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com if (NULL == mask->fImage) { 195d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com return false; 196d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com } 197a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 198a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com // FIXME: use sk_calloc in AllocImage? 199d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com sk_bzero(mask->fImage, size); 200a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com return true; 201a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com} 202a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 203a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.comstatic bool draw_rrect_into_mask(const SkRRect rrect, SkMask* mask) { 204a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com if (!prepare_to_draw_into_mask(rrect.rect(), mask)) { 205a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com return false; 206a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com } 207a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 208a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com // FIXME: This code duplicates code in draw_rects_into_mask, below. Is there a 209a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com // clean way to share more code? 210a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com SkBitmap bitmap; 211dac522589e9395b4654a1a708f1bd971f37f95a5commit-bot@chromium.org bitmap.installMaskPixels(*mask); 212a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 213a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com SkCanvas canvas(bitmap); 214a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com canvas.translate(-SkIntToScalar(mask->fBounds.left()), 215a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com -SkIntToScalar(mask->fBounds.top())); 216a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 217a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com SkPaint paint; 218a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com paint.setAntiAlias(true); 219a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com canvas.drawRRect(rrect, paint); 220a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com return true; 221a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com} 222a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 223a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.comstatic bool draw_rects_into_mask(const SkRect rects[], int count, SkMask* mask) { 224a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com if (!prepare_to_draw_into_mask(rects[0], mask)) { 225a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com return false; 226a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com } 227d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com 228d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com SkBitmap bitmap; 229e24ad23ae67ffcb0dc545b7e426cf08d102e0868commit-bot@chromium.org bitmap.installPixels(SkImageInfo::Make(mask->fBounds.width(), 230e24ad23ae67ffcb0dc545b7e426cf08d102e0868commit-bot@chromium.org mask->fBounds.height(), 231e24ad23ae67ffcb0dc545b7e426cf08d102e0868commit-bot@chromium.org kAlpha_8_SkColorType, 232e24ad23ae67ffcb0dc545b7e426cf08d102e0868commit-bot@chromium.org kPremul_SkAlphaType), 23300f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org mask->fImage, mask->fRowBytes); 234d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com 235d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com SkCanvas canvas(bitmap); 236dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com canvas.translate(-SkIntToScalar(mask->fBounds.left()), 237dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com -SkIntToScalar(mask->fBounds.top())); 238d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com 239d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com SkPaint paint; 240d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com paint.setAntiAlias(true); 241d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com 242dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com if (1 == count) { 243dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com canvas.drawRect(rects[0], paint); 244dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com } else { 245dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com // todo: do I need a fast way to do this? 246dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com SkPath path; 247dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com path.addRect(rects[0]); 248dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com path.addRect(rects[1]); 249dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com path.setFillType(SkPath::kEvenOdd_FillType); 250dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com canvas.drawPath(path, paint); 251dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com } 252d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com return true; 253d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com} 254d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com 255f276fa74f56d0c691716163d3149fce5de97c9eareed@google.comstatic bool rect_exceeds(const SkRect& r, SkScalar v) { 256f276fa74f56d0c691716163d3149fce5de97c9eareed@google.com return r.fLeft < -v || r.fTop < -v || r.fRight > v || r.fBottom > v || 257f276fa74f56d0c691716163d3149fce5de97c9eareed@google.com r.width() > v || r.height() > v; 25807784a041925f9a921e390e782195a622c76fbfareed@google.com} 25907784a041925f9a921e390e782195a622c76fbfareed@google.com 260a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org#ifdef SK_IGNORE_FAST_RRECT_BLUR 2613d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.orgSK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect", false, "Use the faster analytic blur approach for ninepatch rects" ); 262a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org#else 2633d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.orgSK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect", true, "Use the faster analytic blur approach for ninepatch round rects" ); 264a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org#endif 265a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org 266a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.comSkMaskFilter::FilterReturn 267a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.comSkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& matrix, 268a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com const SkIRect& clipBounds, 269a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com NinePatch* patch) const { 270a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com SkASSERT(patch != NULL); 271a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com switch (rrect.getType()) { 272a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com case SkRRect::kUnknown_Type: 273a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com // Unknown should never be returned. 274a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com SkASSERT(false); 275a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com // Fall through. 276a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com case SkRRect::kEmpty_Type: 277a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com // Nothing to draw. 278a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com return kFalse_FilterReturn; 279a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 280a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com case SkRRect::kRect_Type: 281a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com // We should have caught this earlier. 282a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com SkASSERT(false); 283a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com // Fall through. 284a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com case SkRRect::kOval_Type: 285a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com // The nine patch special case does not handle ovals, and we 286a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com // already have code for rectangles. 287a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com return kUnimplemented_FilterReturn; 288a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 289f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org // These three can take advantage of this fast path. 290a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com case SkRRect::kSimple_Type: 291f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org case SkRRect::kNinePatch_Type: 292a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com case SkRRect::kComplex_Type: 293a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com break; 294a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com } 295a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 296a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com // TODO: report correct metrics for innerstyle, where we do not grow the 297a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com // total bounds, but we do need an inset the size of our blur-radius 298e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org if (kInner_SkBlurStyle == fBlurStyle) { 299a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com return kUnimplemented_FilterReturn; 300a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com } 301a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 302a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com // TODO: take clipBounds into account to limit our coordinates up front 303a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com // for now, just skip too-large src rects (to take the old code path). 304a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com if (rect_exceeds(rrect.rect(), SkIntToScalar(32767))) { 305a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com return kUnimplemented_FilterReturn; 306a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com } 307a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 308a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com SkIPoint margin; 309a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com SkMask srcM, dstM; 310a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com rrect.rect().roundOut(&srcM.fBounds); 311a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com srcM.fImage = NULL; 312a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com srcM.fFormat = SkMask::kA8_Format; 313a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com srcM.fRowBytes = 0; 314a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 315a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org bool filterResult = false; 316a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org if (c_analyticBlurRRect) { 317a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org // special case for fast round rect blur 318a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org // don't actually do the blur the first time, just compute the correct size 319a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org filterResult = this->filterRRectMask(&dstM, rrect, matrix, &margin, 320a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org SkMask::kJustComputeBounds_CreateMode); 321a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org } 322a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org 323a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org if (!filterResult) { 324a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org filterResult = this->filterMask(&dstM, srcM, matrix, &margin); 325a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org } 326a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org 327a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org if (!filterResult) { 328a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com return kFalse_FilterReturn; 329a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com } 330a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 331a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com // Now figure out the appropriate width and height of the smaller round rectangle 332a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com // to stretch. It will take into account the larger radius per side as well as double 333a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com // the margin, to account for inner and outer blur. 334a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com const SkVector& UL = rrect.radii(SkRRect::kUpperLeft_Corner); 335a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com const SkVector& UR = rrect.radii(SkRRect::kUpperRight_Corner); 336a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com const SkVector& LR = rrect.radii(SkRRect::kLowerRight_Corner); 337a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com const SkVector& LL = rrect.radii(SkRRect::kLowerLeft_Corner); 338a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 339a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com const SkScalar leftUnstretched = SkTMax(UL.fX, LL.fX) + SkIntToScalar(2 * margin.fX); 340a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com const SkScalar rightUnstretched = SkTMax(UR.fX, LR.fX) + SkIntToScalar(2 * margin.fX); 341a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 342a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com // Extra space in the middle to ensure an unchanging piece for stretching. Use 3 to cover 343a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com // any fractional space on either side plus 1 for the part to stretch. 344a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com const SkScalar stretchSize = SkIntToScalar(3); 345a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 346a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com const SkScalar totalSmallWidth = leftUnstretched + rightUnstretched + stretchSize; 347a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com if (totalSmallWidth >= rrect.rect().width()) { 348a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com // There is no valid piece to stretch. 349a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com return kUnimplemented_FilterReturn; 350a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com } 351a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 352a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com const SkScalar topUnstretched = SkTMax(UL.fY, UR.fY) + SkIntToScalar(2 * margin.fY); 353a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com const SkScalar bottomUnstretched = SkTMax(LL.fY, LR.fY) + SkIntToScalar(2 * margin.fY); 354a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 355a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com const SkScalar totalSmallHeight = topUnstretched + bottomUnstretched + stretchSize; 356a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com if (totalSmallHeight >= rrect.rect().height()) { 357a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com // There is no valid piece to stretch. 358a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com return kUnimplemented_FilterReturn; 359a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com } 360a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 361a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com SkRect smallR = SkRect::MakeWH(totalSmallWidth, totalSmallHeight); 362a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 363a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com SkRRect smallRR; 364a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com SkVector radii[4]; 365a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com radii[SkRRect::kUpperLeft_Corner] = UL; 366a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com radii[SkRRect::kUpperRight_Corner] = UR; 367a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com radii[SkRRect::kLowerRight_Corner] = LR; 368a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com radii[SkRRect::kLowerLeft_Corner] = LL; 369a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com smallRR.setRectRadii(smallR, radii); 370a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 371a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org bool analyticBlurWorked = false; 372a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org if (c_analyticBlurRRect) { 373a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org analyticBlurWorked = 374a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org this->filterRRectMask(&patch->fMask, smallRR, matrix, &margin, 375a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org SkMask::kComputeBoundsAndRenderImage_CreateMode); 376a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com } 377a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 378a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org if (!analyticBlurWorked) { 379a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org if (!draw_rrect_into_mask(smallRR, &srcM)) { 380a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org return kFalse_FilterReturn; 381a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org } 382ad99358bdd7ca4ffb047121946abf0d5fdbde1e8robertphillips@google.com 383a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org SkAutoMaskFreeImage amf(srcM.fImage); 384a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org 385a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { 386a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org return kFalse_FilterReturn; 387a477154cfce6276277f4eacc20908a6c986c112ccommit-bot@chromium.org } 388a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com } 389a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 390a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com patch->fMask.fBounds.offsetTo(0, 0); 391a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com patch->fOuterRect = dstM.fBounds; 392a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1; 393a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1; 394a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com return kTrue_FilterReturn; 395a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com} 396a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com 397e86af1f4bacd4a9aa99a09905e29b3cf4cea9322humper@google.comSK_CONF_DECLARE( bool, c_analyticBlurNinepatch, "mask.filter.analyticNinePatch", true, "Use the faster analytic blur approach for ninepatch rects" ); 3987c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com 399d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.comSkMaskFilter::FilterReturn 400dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.comSkBlurMaskFilterImpl::filterRectsToNine(const SkRect rects[], int count, 401dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com const SkMatrix& matrix, 402dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com const SkIRect& clipBounds, 40330711b764be6bbb58caa30a0ac5d1474c894efe7reed@google.com NinePatch* patch) const { 404dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com if (count < 1 || count > 2) { 405dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com return kUnimplemented_FilterReturn; 406dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com } 4073458716b52aa25dcd1b270141c7628c380696e35skia.committer@gmail.com 40857850b9daddd941f880d94faaf83f2169355a0c8reed@google.com // TODO: report correct metrics for innerstyle, where we do not grow the 40957850b9daddd941f880d94faaf83f2169355a0c8reed@google.com // total bounds, but we do need an inset the size of our blur-radius 410e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org if (kInner_SkBlurStyle == fBlurStyle || kOuter_SkBlurStyle == fBlurStyle) { 41157850b9daddd941f880d94faaf83f2169355a0c8reed@google.com return kUnimplemented_FilterReturn; 41257850b9daddd941f880d94faaf83f2169355a0c8reed@google.com } 41357850b9daddd941f880d94faaf83f2169355a0c8reed@google.com 41407784a041925f9a921e390e782195a622c76fbfareed@google.com // TODO: take clipBounds into account to limit our coordinates up front 41507784a041925f9a921e390e782195a622c76fbfareed@google.com // for now, just skip too-large src rects (to take the old code path). 416f276fa74f56d0c691716163d3149fce5de97c9eareed@google.com if (rect_exceeds(rects[0], SkIntToScalar(32767))) { 41707784a041925f9a921e390e782195a622c76fbfareed@google.com return kUnimplemented_FilterReturn; 41807784a041925f9a921e390e782195a622c76fbfareed@google.com } 4193458716b52aa25dcd1b270141c7628c380696e35skia.committer@gmail.com 420d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com SkIPoint margin; 421d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com SkMask srcM, dstM; 422dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com rects[0].roundOut(&srcM.fBounds); 423d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com srcM.fImage = NULL; 424d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com srcM.fFormat = SkMask::kA8_Format; 425d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com srcM.fRowBytes = 0; 4262e71f1619d9a2c51c1292e618f42a56ad2da1de8skia.committer@gmail.com 4277c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com bool filterResult = false; 4287c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com if (count == 1 && c_analyticBlurNinepatch) { 4297c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com // special case for fast rect blur 4307c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com // don't actually do the blur the first time, just compute the correct size 4312e71f1619d9a2c51c1292e618f42a56ad2da1de8skia.committer@gmail.com filterResult = this->filterRectMask(&dstM, rects[0], matrix, &margin, 4327c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com SkMask::kJustComputeBounds_CreateMode); 4337c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com } else { 4347c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com filterResult = this->filterMask(&dstM, srcM, matrix, &margin); 4357c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com } 4362e71f1619d9a2c51c1292e618f42a56ad2da1de8skia.committer@gmail.com 4377c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com if (!filterResult) { 438d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com return kFalse_FilterReturn; 439d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com } 440d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com 441d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com /* 442d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com * smallR is the smallest version of 'rect' that will still guarantee that 443d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com * we get the same blur results on all edges, plus 1 center row/col that is 444d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com * representative of the extendible/stretchable edges of the ninepatch. 445d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com * Since our actual edge may be fractional we inset 1 more to be sure we 446d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com * don't miss any interior blur. 447d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com * x is an added pixel of blur, and { and } are the (fractional) edge 448d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com * pixels from the original rect. 449d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com * 450d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com * x x { x x .... x x } x x 451d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com * 452d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com * Thus, in this case, we inset by a total of 5 (on each side) beginning 453d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com * with our outer-rect (dstM.fBounds) 454d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com */ 455dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com SkRect smallR[2]; 456dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com SkIPoint center; 457dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com 458dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com // +2 is from +1 for each edge (to account for possible fractional edges 459dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com int smallW = dstM.fBounds.width() - srcM.fBounds.width() + 2; 460dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com int smallH = dstM.fBounds.height() - srcM.fBounds.height() + 2; 461dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com SkIRect innerIR; 462dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com 463dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com if (1 == count) { 464dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com innerIR = srcM.fBounds; 465dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com center.set(smallW, smallH); 466dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com } else { 467dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com SkASSERT(2 == count); 468dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com rects[1].roundIn(&innerIR); 469dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com center.set(smallW + (innerIR.left() - srcM.fBounds.left()), 470dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com smallH + (innerIR.top() - srcM.fBounds.top())); 471dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com } 472dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com 473dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com // +1 so we get a clean, stretchable, center row/col 474dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com smallW += 1; 475dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com smallH += 1; 476dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com 477dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com // we want the inset amounts to be integral, so we don't change any 478dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com // fractional phase on the fRight or fBottom of our smallR. 479dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com const SkScalar dx = SkIntToScalar(innerIR.width() - smallW); 480dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com const SkScalar dy = SkIntToScalar(innerIR.height() - smallH); 481dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com if (dx < 0 || dy < 0) { 482dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com // we're too small, relative to our blur, to break into nine-patch, 483dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com // so we ask to have our normal filterMask() be called. 484dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com return kUnimplemented_FilterReturn; 485dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com } 486dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com 487dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com smallR[0].set(rects[0].left(), rects[0].top(), rects[0].right() - dx, rects[0].bottom() - dy); 488112a23e0fa027b423a656f0a1aa06868617e982arobertphillips@google.com if (smallR[0].width() < 2 || smallR[0].height() < 2) { 489112a23e0fa027b423a656f0a1aa06868617e982arobertphillips@google.com return kUnimplemented_FilterReturn; 490112a23e0fa027b423a656f0a1aa06868617e982arobertphillips@google.com } 491dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com if (2 == count) { 492dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com smallR[1].set(rects[1].left(), rects[1].top(), 493dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com rects[1].right() - dx, rects[1].bottom() - dy); 494dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com SkASSERT(!smallR[1].isEmpty()); 495d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com } 496d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com 4977c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com if (count > 1 || !c_analyticBlurNinepatch) { 498a8e33a92e27ca1523601226cad83c79a7e00c93bscroggo@google.com if (!draw_rects_into_mask(smallR, count, &srcM)) { 4997c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com return kFalse_FilterReturn; 5007c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com } 501d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com 5027c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com SkAutoMaskFreeImage amf(srcM.fImage); 503d198a5b8a706d2bcfa94e351d3a41f5379777e4areed@google.com 5047c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { 5057c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com return kFalse_FilterReturn; 5067c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com } 5077c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com } else { 5082e71f1619d9a2c51c1292e618f42a56ad2da1de8skia.committer@gmail.com if (!this->filterRectMask(&patch->fMask, smallR[0], matrix, &margin, 5097c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com SkMask::kComputeBoundsAndRenderImage_CreateMode)) { 5107c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com return kFalse_FilterReturn; 5117c5d7b781385c47e5be9a343d60c5b7d33b5b8cdhumper@google.com } 512d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com } 513dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com patch->fMask.fBounds.offsetTo(0, 0); 514dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com patch->fOuterRect = dstM.fBounds; 515dab9b4fe035c1e8a79e110139953c19bd48d66f9reed@google.com patch->fCenter = center; 516d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com return kTrue_FilterReturn; 517d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com} 518d729b3e504ae547ee0978e8f7156bd8dd8124172reed@google.com 51930711b764be6bbb58caa30a0ac5d1474c894efe7reed@google.comvoid SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src, 52030711b764be6bbb58caa30a0ac5d1474c894efe7reed@google.com SkRect* dst) const { 5217ce661d19c5cf4484305a1b20c44bd111f129847robertphillips@google.com SkScalar pad = 3.0f * fSigma; 52217ad2bd077af50dcaca18cf00607b194a1491a44robertphillips@google.com 52317ad2bd077af50dcaca18cf00607b194a1491a44robertphillips@google.com dst->set(src.fLeft - pad, src.fTop - pad, 52417ad2bd077af50dcaca18cf00607b194a1491a44robertphillips@google.com src.fRight + pad, src.fBottom + pad); 5259efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com} 5269efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com 5279fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 5289fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedSkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkReadBuffer& buffer) : SkMaskFilter(buffer) { 529fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org fSigma = buffer.readScalar(); 530e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org fBlurStyle = (SkBlurStyle)buffer.readInt(); 531c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com fBlurFlags = buffer.readUInt() & SkBlurMaskFilter::kAll_BlurFlag; 532e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org SkASSERT(fSigma > 0); 533e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org SkASSERT((unsigned)fBlurStyle <= kLastEnum_SkBlurStyle); 5348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5359fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#endif 5369fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 5379fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedSkFlattenable* SkBlurMaskFilterImpl::CreateProc(SkReadBuffer& buffer) { 5389fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed const SkScalar sigma = buffer.readScalar(); 5399fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed const unsigned style = buffer.readUInt(); 5409fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed const unsigned flags = buffer.readUInt(); 5419fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed if (style <= kLastEnum_SkBlurStyle) { 5429fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed return SkBlurMaskFilter::Create((SkBlurStyle)style, sigma, flags); 5439fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed } 5449fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed return NULL; 5459fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed} 5468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5478b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkBlurMaskFilterImpl::flatten(SkWriteBuffer& buffer) const { 54811e055518a0cbe5329232a55fe2cd177e83836d8robertphillips@google.com buffer.writeScalar(fSigma); 5499fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed buffer.writeUInt(fBlurStyle); 550c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com buffer.writeUInt(fBlurFlags); 5518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 553491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com#if SK_SUPPORT_GPU 5542b75f4279a237ceea929ff8ac019f7fbd3ad08b5reed@google.com 555cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.orgclass GrGLRectBlurEffect; 556cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 557b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrRectBlurEffect : public GrFragmentProcessor { 558cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.orgpublic: 559cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org virtual ~GrRectBlurEffect(); 560cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 561cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org static const char* Name() { return "RectBlur"; } 562cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 563b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt typedef GrGLRectBlurEffect GLProcessor; 564cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 565b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE; 566cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; 567cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 568cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org /** 569cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org * Create a simple filter effect with custom bicubic coefficients. 570cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org */ 571b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt static GrFragmentProcessor* Create(GrContext *context, const SkRect& rect, float sigma) { 5724a24cd8ff41a8b3d292d60e4351a631240a7ed75humper GrTexture *blurProfileTexture = NULL; 5734a24cd8ff41a8b3d292d60e4351a631240a7ed75humper int doubleProfileSize = SkScalarCeilToInt(12*sigma); 5744a24cd8ff41a8b3d292d60e4351a631240a7ed75humper 5754a24cd8ff41a8b3d292d60e4351a631240a7ed75humper if (doubleProfileSize >= rect.width() || doubleProfileSize >= rect.height()) { 5764a24cd8ff41a8b3d292d60e4351a631240a7ed75humper // if the blur sigma is too large so the gaussian overlaps the whole 5774a24cd8ff41a8b3d292d60e4351a631240a7ed75humper // rect in either direction, fall back to CPU path for now. 5784a24cd8ff41a8b3d292d60e4351a631240a7ed75humper 579cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org return NULL; 580cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org } 5814a24cd8ff41a8b3d292d60e4351a631240a7ed75humper 5824a24cd8ff41a8b3d292d60e4351a631240a7ed75humper bool createdBlurProfileTexture = CreateBlurProfileTexture(context, sigma, &blurProfileTexture); 5834a24cd8ff41a8b3d292d60e4351a631240a7ed75humper SkAutoTUnref<GrTexture> hunref(blurProfileTexture); 5844a24cd8ff41a8b3d292d60e4351a631240a7ed75humper if (!createdBlurProfileTexture) { 5854a24cd8ff41a8b3d292d60e4351a631240a7ed75humper return NULL; 5864a24cd8ff41a8b3d292d60e4351a631240a7ed75humper } 58755fad7af61c21d502acb9891d631e8aa29e3628cbsalomon return SkNEW_ARGS(GrRectBlurEffect, (rect, sigma, blurProfileTexture)); 588cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org } 5894c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com 5904a24cd8ff41a8b3d292d60e4351a631240a7ed75humper const SkRect& getRect() const { return fRect; } 591cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org float getSigma() const { return fSigma; } 592cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 593cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.orgprivate: 5944a24cd8ff41a8b3d292d60e4351a631240a7ed75humper GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture *blur_profile); 595b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE; 5964c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com 5974a24cd8ff41a8b3d292d60e4351a631240a7ed75humper static bool CreateBlurProfileTexture(GrContext *context, float sigma, 5984a24cd8ff41a8b3d292d60e4351a631240a7ed75humper GrTexture **blurProfileTexture); 5994c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com 6004a24cd8ff41a8b3d292d60e4351a631240a7ed75humper SkRect fRect; 6014a24cd8ff41a8b3d292d60e4351a631240a7ed75humper float fSigma; 6024a24cd8ff41a8b3d292d60e4351a631240a7ed75humper GrTextureAccess fBlurProfileAccess; 603cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 604b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GR_DECLARE_FRAGMENT_PROCESSOR_TEST; 605cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 606b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt typedef GrFragmentProcessor INHERITED; 607cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org}; 608cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 609b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrGLRectBlurEffect : public GrGLFragmentProcessor { 610cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.orgpublic: 611b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrGLRectBlurEffect(const GrBackendProcessorFactory& factory, 612b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessor&); 61330ba436f04e61d4505fb854d5fc56079636e0788joshualitt virtual void emitCode(GrGLProgramBuilder*, 614b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrFragmentProcessor&, 615b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessorKey&, 616cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org const char* outputColor, 617cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org const char* inputColor, 618cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org const TransformedCoordsArray&, 619cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org const TextureSamplerArray&) SK_OVERRIDE; 620cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 621b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE; 622cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 623cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.orgprivate: 6247510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen typedef GrGLProgramDataManager::UniformHandle UniformHandle; 625cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 6264a24cd8ff41a8b3d292d60e4351a631240a7ed75humper UniformHandle fProxyRectUniform; 6274a24cd8ff41a8b3d292d60e4351a631240a7ed75humper UniformHandle fProfileSizeUniform; 628cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 629b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt typedef GrGLFragmentProcessor INHERITED; 630cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org}; 631cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 6324a24cd8ff41a8b3d292d60e4351a631240a7ed75humper 6334a24cd8ff41a8b3d292d60e4351a631240a7ed75humper 634b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrGLRectBlurEffect::GrGLRectBlurEffect(const GrBackendProcessorFactory& factory, const GrProcessor&) 635cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org : INHERITED(factory) { 636cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org} 637cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 63830ba436f04e61d4505fb854d5fc56079636e0788joshualittvoid OutputRectBlurProfileLookup(GrGLFragmentShaderBuilder* fsBuilder, 6394a24cd8ff41a8b3d292d60e4351a631240a7ed75humper const GrGLShaderBuilder::TextureSampler& sampler, 6404a24cd8ff41a8b3d292d60e4351a631240a7ed75humper const char *output, 6414a24cd8ff41a8b3d292d60e4351a631240a7ed75humper const char *profileSize, const char *loc, 6424a24cd8ff41a8b3d292d60e4351a631240a7ed75humper const char *blurred_width, 6434a24cd8ff41a8b3d292d60e4351a631240a7ed75humper const char *sharp_width) { 64430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tfloat %s;\n", output); 64530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t{\n"); 64630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\tfloat coord = (0.5 * (abs(2.0*%s - %s) - %s))/%s;\n", 6474a24cd8ff41a8b3d292d60e4351a631240a7ed75humper loc, blurred_width, sharp_width, profileSize); 64830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\t%s = ", output); 64930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->appendTextureLookup(sampler, "vec2(coord,0.5)"); 65030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(".a;\n"); 65130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t}\n"); 6524a24cd8ff41a8b3d292d60e4351a631240a7ed75humper} 6534a24cd8ff41a8b3d292d60e4351a631240a7ed75humper 65430ba436f04e61d4505fb854d5fc56079636e0788joshualittvoid GrGLRectBlurEffect::emitCode(GrGLProgramBuilder* builder, 655b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrFragmentProcessor&, 656b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessorKey& key, 657cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org const char* outputColor, 658cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org const char* inputColor, 659cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org const TransformedCoordsArray& coords, 660cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org const TextureSamplerArray& samplers) { 6614c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com 6624a24cd8ff41a8b3d292d60e4351a631240a7ed75humper const char *rectName; 6634a24cd8ff41a8b3d292d60e4351a631240a7ed75humper const char *profileSizeName; 6644a24cd8ff41a8b3d292d60e4351a631240a7ed75humper 66530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fProxyRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, 6664a24cd8ff41a8b3d292d60e4351a631240a7ed75humper kVec4f_GrSLType, 6674a24cd8ff41a8b3d292d60e4351a631240a7ed75humper "proxyRect", 6684a24cd8ff41a8b3d292d60e4351a631240a7ed75humper &rectName); 66930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fProfileSizeUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, 6704a24cd8ff41a8b3d292d60e4351a631240a7ed75humper kFloat_GrSLType, 6714a24cd8ff41a8b3d292d60e4351a631240a7ed75humper "profileSize", 6724a24cd8ff41a8b3d292d60e4351a631240a7ed75humper &profileSizeName); 6734a24cd8ff41a8b3d292d60e4351a631240a7ed75humper 67430ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 67530ba436f04e61d4505fb854d5fc56079636e0788joshualitt const char *fragmentPos = fsBuilder->fragmentPosition(); 6764c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com 677cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org if (inputColor) { 67830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tvec4 src=%s;\n", inputColor); 679cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org } else { 68030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tvec4 src=vec4(1)\n;"); 681cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org } 6824c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com 68330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tvec2 translatedPos = %s.xy - %s.xy;\n", fragmentPos, rectName ); 68430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tfloat width = %s.z - %s.x;\n", rectName, rectName); 68530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tfloat height = %s.w - %s.y;\n", rectName, rectName); 6864c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com 68730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tvec2 smallDims = vec2(width - %s, height-%s);\n", profileSizeName, profileSizeName); 68830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tfloat center = 2.0 * floor(%s/2.0 + .25) - 1.0;\n", profileSizeName); 68930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tvec2 wh = smallDims - vec2(center,center);\n"); 6904a24cd8ff41a8b3d292d60e4351a631240a7ed75humper 69130ba436f04e61d4505fb854d5fc56079636e0788joshualitt OutputRectBlurProfileLookup(fsBuilder, samplers[0], "horiz_lookup", profileSizeName, "translatedPos.x", "width", "wh.x"); 69230ba436f04e61d4505fb854d5fc56079636e0788joshualitt OutputRectBlurProfileLookup(fsBuilder, samplers[0], "vert_lookup", profileSizeName, "translatedPos.y", "height", "wh.y"); 6934a24cd8ff41a8b3d292d60e4351a631240a7ed75humper 69430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tfloat final = horiz_lookup * vert_lookup;\n"); 69530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t%s = src * vec4(final);\n", outputColor ); 696cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org} 697cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 6987510b224e52b9518a8ddf7418db0e9c258f79539kkinnunenvoid GrGLRectBlurEffect::setData(const GrGLProgramDataManager& pdman, 699b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessor& proc) { 700b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrRectBlurEffect& rbe = proc.cast<GrRectBlurEffect>(); 7014a24cd8ff41a8b3d292d60e4351a631240a7ed75humper SkRect rect = rbe.getRect(); 7024a24cd8ff41a8b3d292d60e4351a631240a7ed75humper 7037510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set4f(fProxyRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBottom); 7047510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set1f(fProfileSizeUniform, SkScalarCeilToScalar(6*rbe.getSigma())); 705cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org} 706cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 7074a24cd8ff41a8b3d292d60e4351a631240a7ed75humperbool GrRectBlurEffect::CreateBlurProfileTexture(GrContext *context, float sigma, 7084a24cd8ff41a8b3d292d60e4351a631240a7ed75humper GrTexture **blurProfileTexture) { 709cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org GrTextureParams params; 710cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org GrTextureDesc texDesc; 7114c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com 7124a24cd8ff41a8b3d292d60e4351a631240a7ed75humper unsigned int profile_size = SkScalarCeilToInt(6*sigma); 7134c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com 7144a24cd8ff41a8b3d292d60e4351a631240a7ed75humper texDesc.fWidth = profile_size; 715cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org texDesc.fHeight = 1; 716cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org texDesc.fConfig = kAlpha_8_GrPixelConfig; 7174c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com 718cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org static const GrCacheID::Domain gBlurProfileDomain = GrCacheID::GenerateDomain(); 719cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org GrCacheID::Key key; 720cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org memset(&key, 0, sizeof(key)); 721cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org key.fData32[0] = profile_size; 7224a24cd8ff41a8b3d292d60e4351a631240a7ed75humper key.fData32[1] = 1; 7234a24cd8ff41a8b3d292d60e4351a631240a7ed75humper GrCacheID blurProfileKey(gBlurProfileDomain, key); 7244c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com 725cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org uint8_t *profile = NULL; 726cc787fa8029889877da8edbb70a284cb0e19de33commit-bot@chromium.org SkAutoTDeleteArray<uint8_t> ada(NULL); 7274c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com 7284a24cd8ff41a8b3d292d60e4351a631240a7ed75humper *blurProfileTexture = context->findAndRefTexture(texDesc, blurProfileKey, ¶ms); 7294c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com 7304a24cd8ff41a8b3d292d60e4351a631240a7ed75humper if (NULL == *blurProfileTexture) { 7314c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com 732cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org SkBlurMask::ComputeBlurProfile(sigma, &profile); 733cc787fa8029889877da8edbb70a284cb0e19de33commit-bot@chromium.org ada.reset(profile); 7344c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com 7354a24cd8ff41a8b3d292d60e4351a631240a7ed75humper *blurProfileTexture = context->createTexture(¶ms, texDesc, blurProfileKey, 7364a24cd8ff41a8b3d292d60e4351a631240a7ed75humper profile, 0); 737e07c1ab40882078b505f2b0ceb7413c44af569e8scroggo 7384a24cd8ff41a8b3d292d60e4351a631240a7ed75humper if (NULL == *blurProfileTexture) { 739cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org return false; 740cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org } 741cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org } 7424c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com 743cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org return true; 744cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org} 745cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 746cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.orgGrRectBlurEffect::GrRectBlurEffect(const SkRect& rect, float sigma, 7474a24cd8ff41a8b3d292d60e4351a631240a7ed75humper GrTexture *blur_profile) 7484c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com : INHERITED(), 7494a24cd8ff41a8b3d292d60e4351a631240a7ed75humper fRect(rect), 750cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org fSigma(sigma), 7514a24cd8ff41a8b3d292d60e4351a631240a7ed75humper fBlurProfileAccess(blur_profile) { 7524a24cd8ff41a8b3d292d60e4351a631240a7ed75humper this->addTextureAccess(&fBlurProfileAccess); 7534a24cd8ff41a8b3d292d60e4351a631240a7ed75humper this->setWillReadFragmentPosition(); 754cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org} 755cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 756cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.orgGrRectBlurEffect::~GrRectBlurEffect() { 757cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org} 758cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 759b0a8a377f832c59cee939ad721e1f87d378b7142joshualittconst GrBackendFragmentProcessorFactory& GrRectBlurEffect::getFactory() const { 760b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt return GrTBackendFragmentProcessorFactory<GrRectBlurEffect>::getInstance(); 761cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org} 762cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 763b0a8a377f832c59cee939ad721e1f87d378b7142joshualittbool GrRectBlurEffect::onIsEqual(const GrProcessor& sBase) const { 76449586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt const GrRectBlurEffect& s = sBase.cast<GrRectBlurEffect>(); 7654a24cd8ff41a8b3d292d60e4351a631240a7ed75humper return this->getSigma() == s.getSigma() && this->getRect() == s.getRect(); 766cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org} 767cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 768cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.orgvoid GrRectBlurEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { 769cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org *validFlags = 0; 770cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org return; 771cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org} 772cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 773b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRectBlurEffect); 774cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 775b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* GrRectBlurEffect::TestCreate(SkRandom* random, 776b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrContext* context, 777b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrDrawTargetCaps&, 778b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture**) { 779cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org float sigma = random->nextRangeF(3,8); 780cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org float width = random->nextRangeF(200,300); 781cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org float height = random->nextRangeF(200,300); 782cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org return GrRectBlurEffect::Create(context, SkRect::MakeWH(width, height), sigma); 783cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org} 784cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 785cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 786cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.orgbool SkBlurMaskFilterImpl::directFilterMaskGPU(GrContext* context, 787cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org GrPaint* grp, 788cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org const SkStrokeRec& strokeRec, 789cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org const SkPath& path) const { 790e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org if (fBlurStyle != kNormal_SkBlurStyle) { 791cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org return false; 792cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org } 7934c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com 794cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org SkRect rect; 795cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org if (!path.isRect(&rect)) { 796cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org return false; 797cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org } 7984c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com 799cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org if (!strokeRec.isFillStyle()) { 800cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org return false; 801cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org } 8024c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com 803cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org SkMatrix ctm = context->getMatrix(); 804cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org SkScalar xformedSigma = this->computeXformedSigma(ctm); 8054a24cd8ff41a8b3d292d60e4351a631240a7ed75humper 8064a24cd8ff41a8b3d292d60e4351a631240a7ed75humper int pad=SkScalarCeilToInt(6*xformedSigma)/2; 8074a24cd8ff41a8b3d292d60e4351a631240a7ed75humper rect.outset(SkIntToScalar(pad), SkIntToScalar(pad)); 8084c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com 809b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkAutoTUnref<GrFragmentProcessor> fp(GrRectBlurEffect::Create(context, rect, xformedSigma)); 810b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (!fp) { 811cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org return false; 812cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org } 813cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 814cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org GrContext::AutoMatrix am; 815cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org if (!am.setIdentity(context, grp)) { 816cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org return false; 817cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org } 818cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 819b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt grp->addCoverageProcessor(fp); 8204c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com 821cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org context->drawRect(*grp, rect); 822cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org return true; 823cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org} 824cf34bc06347dd2734a7fdaef5cf8853e92979d5ecommit-bot@chromium.org 8253d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.orgclass GrGLRRectBlurEffect; 8263d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 827b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrRRectBlurEffect : public GrFragmentProcessor { 8283d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.orgpublic: 8293d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 830b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt static GrFragmentProcessor* Create(GrContext* context, float sigma, const SkRRect&); 8313d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 8323d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org virtual ~GrRRectBlurEffect() {}; 8333d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org static const char* Name() { return "GrRRectBlur"; } 8343d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 8353d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org const SkRRect& getRRect() const { return fRRect; } 8363d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org float getSigma() const { return fSigma; } 8373d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 838b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt typedef GrGLRRectBlurEffect GLProcessor; 8393d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 8403d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; 8413d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 842b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE; 8433d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 8443d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.orgprivate: 8453d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org GrRRectBlurEffect(float sigma, const SkRRect&, GrTexture* profileTexture); 8463d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 847b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE; 8483d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 8493d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org SkRRect fRRect; 8503d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org float fSigma; 8513d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org GrTextureAccess fNinePatchAccess; 8523d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 853b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GR_DECLARE_FRAGMENT_PROCESSOR_TEST; 8543d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 855b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt typedef GrFragmentProcessor INHERITED; 8563d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org}; 8573d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 8583d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 859b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* GrRRectBlurEffect::Create(GrContext* context, float sigma, 860b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const SkRRect& rrect) { 8613d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org if (!rrect.isSimpleCircular()) { 8623d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org return NULL; 8633d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org } 8643d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 8653d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org // Make sure we can successfully ninepatch this rrect -- the blur sigma has to be 8663d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org // sufficiently small relative to both the size of the corner radius and the 8673d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org // width (and height) of the rrect. 8683d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 8693d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org unsigned int blurRadius = 3*SkScalarCeilToInt(sigma-1/6.0f); 8703d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org unsigned int cornerRadius = SkScalarCeilToInt(rrect.getSimpleRadii().x()); 8713d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org if (cornerRadius + blurRadius > rrect.width()/2 || 8723d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org cornerRadius + blurRadius > rrect.height()/2) { 8733d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org return NULL; 8743d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org } 8753d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 8763d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org static const GrCacheID::Domain gRRectBlurDomain = GrCacheID::GenerateDomain(); 8773d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org GrCacheID::Key key; 8783d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org memset(&key, 0, sizeof(key)); 8793d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org key.fData32[0] = blurRadius; 8803d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org key.fData32[1] = cornerRadius; 8813d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org GrCacheID blurRRectNinePatchID(gRRectBlurDomain, key); 8823d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 8833d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org GrTextureParams params; 8843d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org params.setFilterMode(GrTextureParams::kBilerp_FilterMode); 8853d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 8863d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org unsigned int smallRectSide = 2*(blurRadius + cornerRadius) + 1; 8873d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org unsigned int texSide = smallRectSide + 2*blurRadius; 8883d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org GrTextureDesc texDesc; 8893d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org texDesc.fWidth = texSide; 8903d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org texDesc.fHeight = texSide; 8913d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org texDesc.fConfig = kAlpha_8_GrPixelConfig; 8923d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 8933d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org GrTexture *blurNinePatchTexture = context->findAndRefTexture(texDesc, blurRRectNinePatchID, ¶ms); 8943d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 8953d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org if (NULL == blurNinePatchTexture) { 8963d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org SkMask mask; 8973d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 8983d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org mask.fBounds = SkIRect::MakeWH(smallRectSide, smallRectSide); 8993d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org mask.fFormat = SkMask::kA8_Format; 9003d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org mask.fRowBytes = mask.fBounds.width(); 9013d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org mask.fImage = SkMask::AllocImage(mask.computeTotalImageSize()); 9023d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org SkAutoMaskFreeImage amfi(mask.fImage); 9033d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 9043d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org memset(mask.fImage, 0, mask.computeTotalImageSize()); 9053d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 9063d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org SkRect smallRect; 9073d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org smallRect.setWH(SkIntToScalar(smallRectSide), SkIntToScalar(smallRectSide)); 9083d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 9093d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org SkRRect smallRRect; 9103d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org smallRRect.setRectXY(smallRect, SkIntToScalar(cornerRadius), SkIntToScalar(cornerRadius)); 9113d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 9123d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org SkPath path; 9133d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org path.addRRect( smallRRect ); 9143d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 9153d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org SkDraw::DrawToMask(path, &mask.fBounds, NULL, NULL, &mask, SkMask::kJustRenderImage_CreateMode, SkPaint::kFill_Style); 9163d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 9173d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org SkMask blurred_mask; 9183d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org SkBlurMask::BoxBlur(&blurred_mask, mask, sigma, kNormal_SkBlurStyle, kHigh_SkBlurQuality, NULL, true ); 9193d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 9203d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org blurNinePatchTexture = context->createTexture(¶ms, texDesc, blurRRectNinePatchID, blurred_mask.fImage, 0); 9216b127cd2b1b2cb4ab5ef995f2f8f937b24f6d682commit-bot@chromium.org SkMask::FreeImage(blurred_mask.fImage); 9223d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org } 9233d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 9246b127cd2b1b2cb4ab5ef995f2f8f937b24f6d682commit-bot@chromium.org SkAutoTUnref<GrTexture> blurunref(blurNinePatchTexture); 9253d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org if (NULL == blurNinePatchTexture) { 9263d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org return NULL; 9273d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org } 9283d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 92955fad7af61c21d502acb9891d631e8aa29e3628cbsalomon return SkNEW_ARGS(GrRRectBlurEffect, (sigma, rrect, blurNinePatchTexture)); 9303d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org} 9313d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 9323d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.orgvoid GrRRectBlurEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { 9333d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org *validFlags = 0; 9343d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org} 9353d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 936b0a8a377f832c59cee939ad721e1f87d378b7142joshualittconst GrBackendFragmentProcessorFactory& GrRRectBlurEffect::getFactory() const { 937b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt return GrTBackendFragmentProcessorFactory<GrRRectBlurEffect>::getInstance(); 9383d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org} 9393d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 9403d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.orgGrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTexture *ninePatchTexture) 9413d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org : fRRect(rrect), 9423d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org fSigma(sigma), 9433d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org fNinePatchAccess(ninePatchTexture) { 9443d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org this->addTextureAccess(&fNinePatchAccess); 9453d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org this->setWillReadFragmentPosition(); 9463d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org} 9473d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 948b0a8a377f832c59cee939ad721e1f87d378b7142joshualittbool GrRRectBlurEffect::onIsEqual(const GrProcessor& other) const { 94949586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt const GrRRectBlurEffect& rrbe = other.cast<GrRRectBlurEffect>(); 9503d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org return fRRect.getSimpleRadii().fX == rrbe.fRRect.getSimpleRadii().fX && fSigma == rrbe.fSigma; 9513d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org} 9523d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 9533d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org////////////////////////////////////////////////////////////////////////////// 9543d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 955b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRRectBlurEffect); 9563d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 957b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* GrRRectBlurEffect::TestCreate(SkRandom* random, 95883d081ae1d731b5039e99823620f5e287542ee39bsalomon GrContext* context, 95983d081ae1d731b5039e99823620f5e287542ee39bsalomon const GrDrawTargetCaps& caps, 96083d081ae1d731b5039e99823620f5e287542ee39bsalomon GrTexture*[]) { 9613d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org SkScalar w = random->nextRangeScalar(100.f, 1000.f); 9623d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org SkScalar h = random->nextRangeScalar(100.f, 1000.f); 9633d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org SkScalar r = random->nextRangeF(1.f, 9.f); 9643d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org SkScalar sigma = random->nextRangeF(1.f,10.f); 9653d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org SkRRect rrect; 9663d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org rrect.setRectXY(SkRect::MakeWH(w, h), r, r); 9673d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org return GrRRectBlurEffect::Create(context, sigma, rrect); 9683d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org} 9693d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 9703d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org////////////////////////////////////////////////////////////////////////////// 9713d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 972b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrGLRRectBlurEffect : public GrGLFragmentProcessor { 9733d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.orgpublic: 974b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrGLRRectBlurEffect(const GrBackendProcessorFactory&, const GrProcessor&); 9753d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 976b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual void emitCode(GrGLProgramBuilder*, 977b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrFragmentProcessor&, 978b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessorKey&, 9793d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org const char* outputColor, 9803d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org const char* inputColor, 9813d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org const TransformedCoordsArray&, 9823d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org const TextureSamplerArray&) SK_OVERRIDE; 9833d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 984b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE; 9853d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 9863d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.orgprivate: 9877510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrGLProgramDataManager::UniformHandle fProxyRectUniform; 9887510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrGLProgramDataManager::UniformHandle fCornerRadiusUniform; 9897510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrGLProgramDataManager::UniformHandle fBlurRadiusUniform; 990b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt typedef GrGLFragmentProcessor INHERITED; 9913d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org}; 9923d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 993b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrGLRRectBlurEffect::GrGLRRectBlurEffect(const GrBackendProcessorFactory& factory, 994b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessor&) 9953d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org : INHERITED (factory) { 9963d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org} 9973d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 99830ba436f04e61d4505fb854d5fc56079636e0788joshualittvoid GrGLRRectBlurEffect::emitCode(GrGLProgramBuilder* builder, 999b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrFragmentProcessor&, 1000b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessorKey&, 1001b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const char* outputColor, 1002b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const char* inputColor, 1003b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const TransformedCoordsArray&, 1004b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const TextureSamplerArray& samplers) { 10053d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org const char *rectName; 10063d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org const char *cornerRadiusName; 10073d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org const char *blurRadiusName; 10083d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 10093d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org // The proxy rect has left, top, right, and bottom edges correspond to 10103d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org // components x, y, z, and w, respectively. 10113d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 101230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fProxyRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, 10133d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org kVec4f_GrSLType, 10143d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org "proxyRect", 10153d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org &rectName); 101630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fCornerRadiusUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, 10173d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org kFloat_GrSLType, 10183d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org "cornerRadius", 10193d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org &cornerRadiusName); 102030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fBlurRadiusUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, 10213d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org kFloat_GrSLType, 10223d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org "blurRadius", 10233d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org &blurRadiusName); 102430ba436f04e61d4505fb854d5fc56079636e0788joshualitt 102530ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 102630ba436f04e61d4505fb854d5fc56079636e0788joshualitt const char* fragmentPos = fsBuilder->fragmentPosition(); 10273d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 10283d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org // warp the fragment position to the appropriate part of the 9patch blur texture 10293d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 103030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tvec2 rectCenter = (%s.xy + %s.zw)/2.0;\n", rectName, rectName); 103130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tvec2 translatedFragPos = %s.xy - %s.xy;\n", fragmentPos, rectName); 103230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tfloat threshold = %s + 2.0*%s;\n", cornerRadiusName, blurRadiusName ); 103330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tvec2 middle = %s.zw - %s.xy - 2.0*threshold;\n", rectName, rectName ); 103430ba436f04e61d4505fb854d5fc56079636e0788joshualitt 103530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tif (translatedFragPos.x >= threshold && translatedFragPos.x < (middle.x+threshold)) {\n" ); 103630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\ttranslatedFragPos.x = threshold;\n"); 103730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t} else if (translatedFragPos.x >= (middle.x + threshold)) {\n"); 103830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\ttranslatedFragPos.x -= middle.x - 1.0;\n"); 103930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t}\n"); 104030ba436f04e61d4505fb854d5fc56079636e0788joshualitt 104130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tif (translatedFragPos.y > threshold && translatedFragPos.y < (middle.y+threshold)) {\n" ); 104230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\ttranslatedFragPos.y = threshold;\n"); 104330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t} else if (translatedFragPos.y >= (middle.y + threshold)) {\n"); 104430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\ttranslatedFragPos.y -= middle.y - 1.0;\n"); 104530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t}\n"); 104630ba436f04e61d4505fb854d5fc56079636e0788joshualitt 104730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tvec2 proxyDims = vec2(2.0*threshold+1.0);\n"); 104830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tvec2 texCoord = translatedFragPos / proxyDims;\n"); 104930ba436f04e61d4505fb854d5fc56079636e0788joshualitt 105030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t%s = ", outputColor); 105130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->appendTextureLookupAndModulate(inputColor, samplers[0], "texCoord"); 105230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 10533d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org} 10543d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 10557510b224e52b9518a8ddf7418db0e9c258f79539kkinnunenvoid GrGLRRectBlurEffect::setData(const GrGLProgramDataManager& pdman, 1056b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessor& proc) { 1057b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrRRectBlurEffect& brre = proc.cast<GrRRectBlurEffect>(); 10583d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org SkRRect rrect = brre.getRRect(); 10593d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 10603d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org float blurRadius = 3.f*SkScalarCeilToScalar(brre.getSigma()-1/6.0f); 10617510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set1f(fBlurRadiusUniform, blurRadius); 10623d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 10633d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org SkRect rect = rrect.getBounds(); 10643d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org rect.outset(blurRadius, blurRadius); 10657510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set4f(fProxyRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBottom); 10663d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 10673d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org SkScalar radius = 0; 10683d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org SkASSERT(rrect.isSimpleCircular() || rrect.isRect()); 10693d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org radius = rrect.getSimpleRadii().fX; 10707510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set1f(fCornerRadiusUniform, radius); 10713d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org} 10723d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 10733d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 1074821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.orgbool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context, 1075821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org GrPaint* grp, 1076821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org const SkStrokeRec& strokeRec, 1077821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org const SkRRect& rrect) const { 10783d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org if (fBlurStyle != kNormal_SkBlurStyle) { 10793d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org return false; 10803d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org } 10813d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 10823d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org if (!strokeRec.isFillStyle()) { 10833d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org return false; 10843d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org } 10853d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 10863d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org SkRect proxy_rect = rrect.rect(); 10873d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org SkMatrix ctm = context->getMatrix(); 10883d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org SkScalar xformedSigma = this->computeXformedSigma(ctm); 10893d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org float extra=3.f*SkScalarCeilToScalar(xformedSigma-1/6.0f); 10903d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org proxy_rect.outset(extra, extra); 10913d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 1092b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkAutoTUnref<GrFragmentProcessor> fp(GrRRectBlurEffect::Create(context, xformedSigma, rrect)); 1093b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (!fp) { 10943d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org return false; 10953d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org } 10963d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 10973d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org GrContext::AutoMatrix am; 10983d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org if (!am.setIdentity(context, grp)) { 10993d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org return false; 11003d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org } 11013d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 1102b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt grp->addCoverageProcessor(fp); 11033d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org 11043d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org context->drawRect(*grp, proxy_rect); 11053d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org return true; 1106821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org} 1107821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org 1108491493119c11206c5823b76eb6420a705be243a1robertphillips@google.combool SkBlurMaskFilterImpl::canFilterMaskGPU(const SkRect& srcBounds, 1109491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com const SkIRect& clipBounds, 1110491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com const SkMatrix& ctm, 1111491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com SkRect* maskRect) const { 11127ce661d19c5cf4484305a1b20c44bd111f129847robertphillips@google.com SkScalar xformedSigma = this->computeXformedSigma(ctm); 11137ce661d19c5cf4484305a1b20c44bd111f129847robertphillips@google.com if (xformedSigma <= 0) { 1114491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com return false; 11152b75f4279a237ceea929ff8ac019f7fbd3ad08b5reed@google.com } 1116491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com 11177ce661d19c5cf4484305a1b20c44bd111f129847robertphillips@google.com static const SkScalar kMIN_GPU_BLUR_SIZE = SkIntToScalar(64); 11187ce661d19c5cf4484305a1b20c44bd111f129847robertphillips@google.com static const SkScalar kMIN_GPU_BLUR_SIGMA = SkIntToScalar(32); 1119491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com 1120491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com if (srcBounds.width() <= kMIN_GPU_BLUR_SIZE && 1121491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com srcBounds.height() <= kMIN_GPU_BLUR_SIZE && 11227ce661d19c5cf4484305a1b20c44bd111f129847robertphillips@google.com xformedSigma <= kMIN_GPU_BLUR_SIGMA) { 1123491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com // We prefer to blur small rect with small radius via CPU. 1124491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com return false; 1125491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com } 1126491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com 1127491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com if (NULL == maskRect) { 1128491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com // don't need to compute maskRect 1129491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com return true; 1130491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com } 1131491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com 11327ce661d19c5cf4484305a1b20c44bd111f129847robertphillips@google.com float sigma3 = 3 * SkScalarToFloat(xformedSigma); 1133491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com 11344469938e92d779dff05e745559e67907bbf21e78reed@google.com SkRect clipRect = SkRect::Make(clipBounds); 1135491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com SkRect srcRect(srcBounds); 1136491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com 1137491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com // Outset srcRect and clipRect by 3 * sigma, to compute affected blur area. 11384b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org srcRect.outset(sigma3, sigma3); 11394b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org clipRect.outset(sigma3, sigma3); 1140491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com srcRect.intersect(clipRect); 1141491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com *maskRect = srcRect; 11421842adf01320f9197b449de7375d08ccac43f389skia.committer@gmail.com return true; 1143491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com} 1144491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com 11451842adf01320f9197b449de7375d08ccac43f389skia.committer@gmail.combool SkBlurMaskFilterImpl::filterMaskGPU(GrTexture* src, 1146439ff1b9ca2b74a9dc3b04346aa1032c11b142e9commit-bot@chromium.org const SkMatrix& ctm, 11471842adf01320f9197b449de7375d08ccac43f389skia.committer@gmail.com const SkRect& maskRect, 1148491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com GrTexture** result, 1149491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com bool canOverwriteSrc) const { 1150491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com SkRect clipRect = SkRect::MakeWH(maskRect.width(), maskRect.height()); 1151491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com 1152491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com GrContext* context = src->getContext(); 1153491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com 1154491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com GrContext::AutoWideOpenIdentityDraw awo(context, NULL); 1155491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com 1156439ff1b9ca2b74a9dc3b04346aa1032c11b142e9commit-bot@chromium.org SkScalar xformedSigma = this->computeXformedSigma(ctm); 11577ce661d19c5cf4484305a1b20c44bd111f129847robertphillips@google.com SkASSERT(xformedSigma > 0); 1158491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com 1159491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com // If we're doing a normal blur, we can clobber the pathTexture in the 1160491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com // gaussianBlur. Otherwise, we need to save it for later compositing. 1161e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org bool isNormalBlur = (kNormal_SkBlurStyle == fBlurStyle); 1162736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com *result = SkGpuBlurUtils::GaussianBlur(context, src, isNormalBlur && canOverwriteSrc, 11637ce661d19c5cf4484305a1b20c44bd111f129847robertphillips@google.com clipRect, false, xformedSigma, xformedSigma); 11643cc820c0504dc6de081d08391affe68b69031c63robertphillips@google.com if (NULL == *result) { 1165491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com return false; 1166491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com } 1167491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com 1168491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com if (!isNormalBlur) { 1169491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com context->setIdentityMatrix(); 1170491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com GrPaint paint; 1171491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com SkMatrix matrix; 1172491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com matrix.setIDiv(src->width(), src->height()); 1173491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com // Blend pathTexture over blurTexture. 1174491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com GrContext::AutoRenderTarget art(context, (*result)->asRenderTarget()); 1175b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt paint.addColorProcessor(GrSimpleTextureEffect::Create(src, matrix))->unref(); 1176e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org if (kInner_SkBlurStyle == fBlurStyle) { 1177491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com // inner: dst = dst * src 1178491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com paint.setBlendFunc(kDC_GrBlendCoeff, kZero_GrBlendCoeff); 1179e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org } else if (kSolid_SkBlurStyle == fBlurStyle) { 1180491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com // solid: dst = src + dst - src * dst 1181491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com // = (1 - dst) * src + 1 * dst 1182491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com paint.setBlendFunc(kIDC_GrBlendCoeff, kOne_GrBlendCoeff); 1183e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org } else if (kOuter_SkBlurStyle == fBlurStyle) { 1184491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com // outer: dst = dst * (1 - src) 1185491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com // = 0 * src + (1 - src) * dst 1186491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com paint.setBlendFunc(kZero_GrBlendCoeff, kISC_GrBlendCoeff); 1187491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com } 1188491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com context->drawRect(paint, clipRect); 1189491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com } 1190491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com 1191491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com return true; 11922b75f4279a237ceea929ff8ac019f7fbd3ad08b5reed@google.com} 11932b75f4279a237ceea929ff8ac019f7fbd3ad08b5reed@google.com 1194491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com#endif // SK_SUPPORT_GPU 1195491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com 1196491493119c11206c5823b76eb6420a705be243a1robertphillips@google.com 11970f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 11980bd80fa01bba2b3f0f49937fcb17928c74bde5a6robertphillips@google.comvoid SkBlurMaskFilterImpl::toString(SkString* str) const { 11990bd80fa01bba2b3f0f49937fcb17928c74bde5a6robertphillips@google.com str->append("SkBlurMaskFilterImpl: ("); 12000bd80fa01bba2b3f0f49937fcb17928c74bde5a6robertphillips@google.com 12017ce661d19c5cf4484305a1b20c44bd111f129847robertphillips@google.com str->append("sigma: "); 12027ce661d19c5cf4484305a1b20c44bd111f129847robertphillips@google.com str->appendScalar(fSigma); 12030bd80fa01bba2b3f0f49937fcb17928c74bde5a6robertphillips@google.com str->append(" "); 12040bd80fa01bba2b3f0f49937fcb17928c74bde5a6robertphillips@google.com 1205e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org static const char* gStyleName[kLastEnum_SkBlurStyle + 1] = { 12060bd80fa01bba2b3f0f49937fcb17928c74bde5a6robertphillips@google.com "normal", "solid", "outer", "inner" 12070bd80fa01bba2b3f0f49937fcb17928c74bde5a6robertphillips@google.com }; 12080bd80fa01bba2b3f0f49937fcb17928c74bde5a6robertphillips@google.com 12090bd80fa01bba2b3f0f49937fcb17928c74bde5a6robertphillips@google.com str->appendf("style: %s ", gStyleName[fBlurStyle]); 12100bd80fa01bba2b3f0f49937fcb17928c74bde5a6robertphillips@google.com str->append("flags: ("); 12110bd80fa01bba2b3f0f49937fcb17928c74bde5a6robertphillips@google.com if (fBlurFlags) { 12120bd80fa01bba2b3f0f49937fcb17928c74bde5a6robertphillips@google.com bool needSeparator = false; 12138eaddb0089a170760e157646192813bd940c26e7skia.committer@gmail.com SkAddFlagToString(str, 12148eaddb0089a170760e157646192813bd940c26e7skia.committer@gmail.com SkToBool(fBlurFlags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag), 12150bd80fa01bba2b3f0f49937fcb17928c74bde5a6robertphillips@google.com "IgnoreXform", &needSeparator); 12168eaddb0089a170760e157646192813bd940c26e7skia.committer@gmail.com SkAddFlagToString(str, 12178eaddb0089a170760e157646192813bd940c26e7skia.committer@gmail.com SkToBool(fBlurFlags & SkBlurMaskFilter::kHighQuality_BlurFlag), 12180bd80fa01bba2b3f0f49937fcb17928c74bde5a6robertphillips@google.com "HighQuality", &needSeparator); 12190bd80fa01bba2b3f0f49937fcb17928c74bde5a6robertphillips@google.com } else { 12200bd80fa01bba2b3f0f49937fcb17928c74bde5a6robertphillips@google.com str->append("None"); 12210bd80fa01bba2b3f0f49937fcb17928c74bde5a6robertphillips@google.com } 12220bd80fa01bba2b3f0f49937fcb17928c74bde5a6robertphillips@google.com str->append("))"); 12230bd80fa01bba2b3f0f49937fcb17928c74bde5a6robertphillips@google.com} 12240bd80fa01bba2b3f0f49937fcb17928c74bde5a6robertphillips@google.com#endif 12250bd80fa01bba2b3f0f49937fcb17928c74bde5a6robertphillips@google.com 1226d26147adbbdca85f07dff432025afee0c8614387caryclark@google.comSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) 1227d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) 1228d26147adbbdca85f07dff432025afee0c8614387caryclark@google.comSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 1229