1736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com/* 2736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com * Copyright 2013 Google Inc. 3736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com * 4736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com * Use of this source code is governed by a BSD-style license that can be 5736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com * found in the LICENSE file. 6736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com */ 7736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 8736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com#include "SkGpuBlurUtils.h" 9736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 10736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com#include "SkRect.h" 11736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 12736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com#if SK_SUPPORT_GPU 13736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com#include "effects/GrConvolutionEffect.h" 14907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#include "effects/GrTextureDomain.h" 15736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com#include "GrContext.h" 16736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com#endif 17736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 18736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.comnamespace SkGpuBlurUtils { 19736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 20736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com#if SK_SUPPORT_GPU 21736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 22736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com#define MAX_BLUR_SIGMA 4.0f 23736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 24736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.comstatic void scale_rect(SkRect* rect, float xScale, float yScale) { 254b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org rect->fLeft = SkScalarMul(rect->fLeft, xScale); 264b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org rect->fTop = SkScalarMul(rect->fTop, yScale); 274b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org rect->fRight = SkScalarMul(rect->fRight, xScale); 284b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org rect->fBottom = SkScalarMul(rect->fBottom, yScale); 29736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com} 30736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 3109843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.orgstatic float adjust_sigma(float sigma, int maxTextureSize, int *scaleFactor, int *radius) { 32736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com *scaleFactor = 1; 33736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com while (sigma > MAX_BLUR_SIGMA) { 34736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com *scaleFactor *= 2; 35736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com sigma *= 0.5f; 3609843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org if (*scaleFactor > maxTextureSize) { 3709843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org *scaleFactor = maxTextureSize; 3809843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org sigma = MAX_BLUR_SIGMA; 3909843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org } 40736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com } 41736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com *radius = static_cast<int>(ceilf(sigma * 3.0f)); 4296ae688f03f05a53c2ae6e66a431e180b90be9cdcommit-bot@chromium.org SkASSERT(*radius <= GrConvolutionEffect::kMaxKernelRadius); 43736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com return sigma; 44736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com} 45736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 46d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.orgstatic void convolve_gaussian_pass(GrContext* context, 47d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org const SkRect& srcRect, 48d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org const SkRect& dstRect, 49d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org GrTexture* texture, 50d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org Gr1DKernelEffect::Direction direction, 51d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org int radius, 52d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org float sigma, 53d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org bool useBounds, 54d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org float bounds[2]) { 55d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org GrPaint paint; 56d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org paint.reset(); 57d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org SkAutoTUnref<GrEffectRef> conv(GrConvolutionEffect::CreateGaussian( 58d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org texture, direction, radius, sigma, useBounds, bounds)); 59d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org paint.reset(); 60d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org paint.addColorEffect(conv); 61d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org context->drawRectToRect(paint, dstRect, srcRect); 62d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org} 63d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org 64736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.comstatic void convolve_gaussian(GrContext* context, 65194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org const SkRect& srcRect, 66194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org const SkRect& dstRect, 67d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org GrTexture* texture, 68d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org Gr1DKernelEffect::Direction direction, 69736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com int radius, 70d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org float sigma, 71d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org bool cropToSrcRect) { 72e8232bc6f0719f381d437483271ce3c78af3c819senorblanco@chromium.org float bounds[2] = { 0.0f, 1.0f }; 73d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org if (!cropToSrcRect) { 74d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org convolve_gaussian_pass(context, srcRect, dstRect, texture, 75d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org direction, radius, sigma, false, bounds); 76d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org return; 77d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org } 78d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org SkRect lowerSrcRect = srcRect, lowerDstRect = dstRect; 79d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org SkRect middleSrcRect = srcRect, middleDstRect = dstRect; 80d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org SkRect upperSrcRect = srcRect, upperDstRect = dstRect; 81d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org SkScalar size; 82d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org SkScalar rad = SkIntToScalar(radius); 83d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org if (direction == Gr1DKernelEffect::kX_Direction) { 84d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org bounds[0] = SkScalarToFloat(srcRect.left()) / texture->width(); 85d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org bounds[1] = SkScalarToFloat(srcRect.right()) / texture->width(); 86d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org size = srcRect.width(); 87d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org lowerSrcRect.fRight = srcRect.left() + rad; 88d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org lowerDstRect.fRight = dstRect.left() + rad; 89d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org upperSrcRect.fLeft = srcRect.right() - rad; 90d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org upperDstRect.fLeft = dstRect.right() - rad; 91d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org middleSrcRect.inset(rad, 0); 92d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org middleDstRect.inset(rad, 0); 93d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org } else { 94d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org bounds[0] = SkScalarToFloat(srcRect.top()) / texture->height(); 95d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org bounds[1] = SkScalarToFloat(srcRect.bottom()) / texture->height(); 96d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org size = srcRect.height(); 97d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org lowerSrcRect.fBottom = srcRect.top() + rad; 98d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org lowerDstRect.fBottom = dstRect.top() + rad; 99d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org upperSrcRect.fTop = srcRect.bottom() - rad; 100d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org upperDstRect.fTop = dstRect.bottom() - rad; 101d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org middleSrcRect.inset(0, rad); 102d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org middleDstRect.inset(0, rad); 103d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org } 104d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org if (radius >= size * SK_ScalarHalf) { 105d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org // Blur radius covers srcRect; use bounds over entire draw 106d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org convolve_gaussian_pass(context, srcRect, dstRect, texture, 107d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org direction, radius, sigma, true, bounds); 108d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org } else { 109d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org // Draw upper and lower margins with bounds; middle without. 110d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org convolve_gaussian_pass(context, lowerSrcRect, lowerDstRect, texture, 111d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org direction, radius, sigma, true, bounds); 112d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org convolve_gaussian_pass(context, upperSrcRect, upperDstRect, texture, 113d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org direction, radius, sigma, true, bounds); 114d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org convolve_gaussian_pass(context, middleSrcRect, middleDstRect, texture, 115d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org direction, radius, sigma, false, bounds); 116194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org } 117736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com} 118736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 119736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.comGrTexture* GaussianBlur(GrContext* context, 120736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com GrTexture* srcTexture, 121736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com bool canClobberSrc, 122736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com const SkRect& rect, 123194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org bool cropToRect, 124977409aceb949a9e834a9fb181a0581792d044cfskia.committer@gmail.com float sigmaX, 125736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com float sigmaY) { 12696ae688f03f05a53c2ae6e66a431e180b90be9cdcommit-bot@chromium.org SkASSERT(NULL != context); 127736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 128736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com GrContext::AutoRenderTarget art(context); 129736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 130736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com GrContext::AutoMatrix am; 131736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com am.setIdentity(context); 132736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 133736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com SkIRect clearRect; 134736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com int scaleFactorX, radiusX; 135736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com int scaleFactorY, radiusY; 13609843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org int maxTextureSize = context->getMaxTextureSize(); 13709843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org sigmaX = adjust_sigma(sigmaX, maxTextureSize, &scaleFactorX, &radiusX); 13809843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org sigmaY = adjust_sigma(sigmaY, maxTextureSize, &scaleFactorY, &radiusY); 139736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 140736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com SkRect srcRect(rect); 141736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY); 142736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com srcRect.roundOut(); 143736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com scale_rect(&srcRect, static_cast<float>(scaleFactorX), 144736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com static_cast<float>(scaleFactorY)); 145736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 146194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org GrContext::AutoClip acs(context, SkRect::MakeWH(srcRect.width(), srcRect.height())); 147736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 14896ae688f03f05a53c2ae6e66a431e180b90be9cdcommit-bot@chromium.org SkASSERT(kBGRA_8888_GrPixelConfig == srcTexture->config() || 149736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com kRGBA_8888_GrPixelConfig == srcTexture->config() || 150736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com kAlpha_8_GrPixelConfig == srcTexture->config()); 151736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 152736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com GrTextureDesc desc; 153736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; 154736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com desc.fWidth = SkScalarFloorToInt(srcRect.width()); 155736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com desc.fHeight = SkScalarFloorToInt(srcRect.height()); 156736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com desc.fConfig = srcTexture->config(); 157736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 158736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com GrAutoScratchTexture temp1, temp2; 159736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com GrTexture* dstTexture = temp1.set(context, desc); 160736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com GrTexture* tempTexture = canClobberSrc ? srcTexture : temp2.set(context, desc); 161736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com if (NULL == dstTexture || NULL == tempTexture) { 162736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com return NULL; 163736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com } 164736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 165736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) { 166736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com GrPaint paint; 167736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com SkMatrix matrix; 168736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com matrix.setIDiv(srcTexture->width(), srcTexture->height()); 169736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com context->setRenderTarget(dstTexture->asRenderTarget()); 170736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com SkRect dstRect(srcRect); 171194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org if (cropToRect && i == 1) { 172194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org dstRect.offset(-dstRect.fLeft, -dstRect.fTop); 173194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org SkRect domain; 174194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org matrix.mapRect(&domain, rect); 175194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org domain.inset(i < scaleFactorX ? SK_ScalarHalf / srcTexture->width() : 0.0f, 176194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org i < scaleFactorY ? SK_ScalarHalf / srcTexture->height() : 0.0f); 177194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org SkAutoTUnref<GrEffectRef> effect(GrTextureDomainEffect::Create( 178194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org srcTexture, 179194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org matrix, 180194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org domain, 181907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org GrTextureDomain::kDecal_Mode, 182b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com GrTextureParams::kBilerp_FilterMode)); 183194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org paint.addColorEffect(effect); 184194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org } else { 185b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_FilterMode); 186194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org paint.addColorTextureEffect(srcTexture, matrix, params); 187194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org } 188736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f, 189736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com i < scaleFactorY ? 0.5f : 1.0f); 190736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com context->drawRectToRect(paint, dstRect, srcRect); 191736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com srcRect = dstRect; 192736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com srcTexture = dstTexture; 193736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com SkTSwap(dstTexture, tempTexture); 194736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com } 195736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 196736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com SkIRect srcIRect; 197736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com srcRect.roundOut(&srcIRect); 198736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 199736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com if (sigmaX > 0.0f) { 200736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com if (scaleFactorX > 1) { 201736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com // Clear out a radius to the right of the srcRect to prevent the 202736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com // X convolution from reading garbage. 203736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, 204736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com radiusX, srcIRect.height()); 20556ce48ade325f6f49acb0da31d6252806e4ed7efrobertphillips@google.com context->clear(&clearRect, 0x0, false); 206736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com } 207736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com context->setRenderTarget(dstTexture->asRenderTarget()); 208194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); 209d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org convolve_gaussian(context, srcRect, dstRect, srcTexture, 210d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org Gr1DKernelEffect::kX_Direction, radiusX, sigmaX, cropToRect); 211736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com srcTexture = dstTexture; 212194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org srcRect = dstRect; 213736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com SkTSwap(dstTexture, tempTexture); 214736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com } 215736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 216736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com if (sigmaY > 0.0f) { 217736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com if (scaleFactorY > 1 || sigmaX > 0.0f) { 218736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com // Clear out a radius below the srcRect to prevent the Y 219736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com // convolution from reading garbage. 220736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, 221736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com srcIRect.width(), radiusY); 22256ce48ade325f6f49acb0da31d6252806e4ed7efrobertphillips@google.com context->clear(&clearRect, 0x0, false); 223736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com } 224736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 225736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com context->setRenderTarget(dstTexture->asRenderTarget()); 226194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); 227d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org convolve_gaussian(context, srcRect, dstRect, srcTexture, 228d71732a5baf4a0a1d912b27ded5360c7e82656c3senorblanco@chromium.org Gr1DKernelEffect::kY_Direction, radiusY, sigmaY, cropToRect); 229736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com srcTexture = dstTexture; 230194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org srcRect = dstRect; 231736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com SkTSwap(dstTexture, tempTexture); 232736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com } 233736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 234736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com if (scaleFactorX > 1 || scaleFactorY > 1) { 235736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com // Clear one pixel to the right and below, to accommodate bilinear 236736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com // upsampling. 237736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, 238736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com srcIRect.width() + 1, 1); 23956ce48ade325f6f49acb0da31d6252806e4ed7efrobertphillips@google.com context->clear(&clearRect, 0x0, false); 240736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, 241736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 1, srcIRect.height()); 24256ce48ade325f6f49acb0da31d6252806e4ed7efrobertphillips@google.com context->clear(&clearRect, 0x0, false); 243736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com SkMatrix matrix; 244736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com matrix.setIDiv(srcTexture->width(), srcTexture->height()); 245736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com context->setRenderTarget(dstTexture->asRenderTarget()); 246736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 247736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com GrPaint paint; 248736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com // FIXME: this should be mitchell, not bilinear. 249b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_FilterMode); 250736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com paint.addColorTextureEffect(srcTexture, matrix, params); 251736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 252736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com SkRect dstRect(srcRect); 253736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY); 254736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com context->drawRectToRect(paint, dstRect, srcRect); 255736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com srcRect = dstRect; 256736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com srcTexture = dstTexture; 257736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com SkTSwap(dstTexture, tempTexture); 258736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com } 259736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com if (srcTexture == temp1.texture()) { 260736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com return temp1.detach(); 261736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com } else if (srcTexture == temp2.texture()) { 262736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com return temp2.detach(); 263736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com } else { 264736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com srcTexture->ref(); 265736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com return srcTexture; 266736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com } 267736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com} 268736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com#endif 269736dd031f177681bfa284e19291ef031ad0822d5robertphillips@google.com 270cce4102f3127cbabfb18f49ffa27e22d1207d96erobertphillips@google.com} 271