Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Side by Side Diff: src/effects/SkGpuBlurUtils.cpp

Issue 1431593002: Make SkBlurImageFilter capable of cropping during blur (GPU path). (Closed) Base URL: senorblanco-linux.mon:src/skia@blur-applyCropRect4-separate-loops
Patch Set: Fix uninitialized bounds in convolve_gaussian_2d() Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/effects/SkGpuBlurUtils.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2013 Google Inc. 2 * Copyright 2013 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkGpuBlurUtils.h" 8 #include "SkGpuBlurUtils.h"
9 9
10 #include "SkRect.h" 10 #include "SkRect.h"
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 } 64 }
65 65
66 static void convolve_gaussian_2d(GrDrawContext* drawContext, 66 static void convolve_gaussian_2d(GrDrawContext* drawContext,
67 const GrClip& clip, 67 const GrClip& clip,
68 const SkRect& srcRect, 68 const SkRect& srcRect,
69 GrTexture* texture, 69 GrTexture* texture,
70 int radiusX, 70 int radiusX,
71 int radiusY, 71 int radiusY,
72 SkScalar sigmaX, 72 SkScalar sigmaX,
73 SkScalar sigmaY, 73 SkScalar sigmaY,
74 bool useBounds, 74 const SkRect* srcBounds) {
75 SkIRect bounds) {
76 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); 75 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
77 SkMatrix localMatrix = SkMatrix::MakeTrans(srcRect.x(), srcRect.y()); 76 SkMatrix localMatrix = SkMatrix::MakeTrans(srcRect.x(), srcRect.y());
78 SkISize size = SkISize::Make(2 * radiusX + 1, 2 * radiusY + 1); 77 SkISize size = SkISize::Make(2 * radiusX + 1, 2 * radiusY + 1);
79 SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY); 78 SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY);
80 GrPaint paint; 79 GrPaint paint;
80 SkIRect bounds;
81 if (srcBounds) {
82 srcBounds->roundOut(&bounds);
83 } else {
84 bounds.setEmpty();
85 }
86
81 SkAutoTUnref<GrFragmentProcessor> conv(GrMatrixConvolutionEffect::CreateGaus sian( 87 SkAutoTUnref<GrFragmentProcessor> conv(GrMatrixConvolutionEffect::CreateGaus sian(
82 texture, bounds, size, 1.0, 0.0, kernelOffset, 88 texture, bounds, size, 1.0, 0.0, kernelOffset,
83 useBounds ? GrTextureDomain::kClamp_Mode : GrTextureDomain::kIgnore_ Mode, 89 srcBounds ? GrTextureDomain::kDecal_Mode : GrTextureDomain::kIgnore_ Mode,
84 true, sigmaX, sigmaY)); 90 true, sigmaX, sigmaY));
85 paint.addColorFragmentProcessor(conv); 91 paint.addColorFragmentProcessor(conv);
86 drawContext->fillRectWithLocalMatrix(clip, paint, SkMatrix::I(), dstRect, lo calMatrix); 92 drawContext->fillRectWithLocalMatrix(clip, paint, SkMatrix::I(), dstRect, lo calMatrix);
87 } 93 }
88 94
89 static void convolve_gaussian(GrDrawContext* drawContext, 95 static void convolve_gaussian(GrDrawContext* drawContext,
90 const GrClip& clip, 96 const GrClip& clip,
91 const SkRect& srcRect, 97 const SkRect& srcRect,
92 GrTexture* texture, 98 GrTexture* texture,
93 Gr1DKernelEffect::Direction direction, 99 Gr1DKernelEffect::Direction direction,
94 int radius, 100 int radius,
95 float sigma, 101 float sigma,
96 bool cropToSrcRect) { 102 const SkRect* srcBounds,
103 const SkPoint& srcOffset) {
97 float bounds[2] = { 0.0f, 1.0f }; 104 float bounds[2] = { 0.0f, 1.0f };
98 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); 105 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
99 SkPoint srcOffset = SkPoint::Make(srcRect.x(), srcRect.y()); 106 if (!srcBounds) {
100 if (!cropToSrcRect) {
101 convolve_gaussian_1d(drawContext, clip, dstRect, srcOffset, texture, 107 convolve_gaussian_1d(drawContext, clip, dstRect, srcOffset, texture,
102 direction, radius, sigma, false, bounds); 108 direction, radius, sigma, false, bounds);
103 return; 109 return;
104 } 110 }
105 SkRect lowerDstRect = dstRect; 111 SkRect midRect = *srcBounds, leftRect, rightRect;
106 SkRect middleDstRect = dstRect; 112 midRect.offset(srcOffset);
107 SkRect upperDstRect = dstRect; 113 SkIRect topRect, bottomRect;
108 SkScalar size;
109 SkScalar rad = SkIntToScalar(radius); 114 SkScalar rad = SkIntToScalar(radius);
110 if (direction == Gr1DKernelEffect::kX_Direction) { 115 if (direction == Gr1DKernelEffect::kX_Direction) {
111 bounds[0] = SkScalarToFloat(srcRect.left()) / texture->width(); 116 bounds[0] = SkScalarToFloat(srcBounds->left()) / texture->width();
112 bounds[1] = SkScalarToFloat(srcRect.right()) / texture->width(); 117 bounds[1] = SkScalarToFloat(srcBounds->right()) / texture->width();
113 size = dstRect.width(); 118 SkRect::MakeLTRB(0, 0, dstRect.right(), midRect.top()).roundOut(&topRect );
114 lowerDstRect.fRight = dstRect.left() + rad; 119 SkRect::MakeLTRB(0, midRect.bottom(), dstRect.right(), dstRect.bottom())
115 upperDstRect.fLeft = dstRect.right() - rad; 120 .roundOut(&bottomRect);
116 middleDstRect.inset(rad, 0); 121 midRect.inset(rad, 0);
122 leftRect = SkRect::MakeLTRB(0, midRect.top(), midRect.left(), midRect.bo ttom());
123 rightRect =
124 SkRect::MakeLTRB(midRect.right(), midRect.top(), dstRect.width(), mi dRect.bottom());
125 dstRect.fTop = midRect.top();
126 dstRect.fBottom = midRect.bottom();
117 } else { 127 } else {
118 bounds[0] = SkScalarToFloat(srcRect.top()) / texture->height(); 128 bounds[0] = SkScalarToFloat(srcBounds->top()) / texture->height();
119 bounds[1] = SkScalarToFloat(srcRect.bottom()) / texture->height(); 129 bounds[1] = SkScalarToFloat(srcBounds->bottom()) / texture->height();
120 size = dstRect.height(); 130 SkRect::MakeLTRB(0, 0, midRect.left(), dstRect.bottom()).roundOut(&topRe ct);
121 lowerDstRect.fBottom = dstRect.top() + rad; 131 SkRect::MakeLTRB(midRect.right(), 0, dstRect.right(), dstRect.bottom())
122 upperDstRect.fTop = dstRect.bottom() - rad; 132 .roundOut(&bottomRect);;
123 middleDstRect.inset(0, rad); 133 midRect.inset(0, rad);
134 leftRect = SkRect::MakeLTRB(midRect.left(), 0, midRect.right(), midRect. top());
135 rightRect =
136 SkRect::MakeLTRB(midRect.left(), midRect.bottom(), midRect.right(), dstRect.height());
137 dstRect.fLeft = midRect.left();
138 dstRect.fRight = midRect.right();
124 } 139 }
125 if (radius >= size * SK_ScalarHalf) { 140 if (!topRect.isEmpty()) {
126 // Blur radius covers srcRect; use bounds over entire draw 141 drawContext->clear(&topRect, 0, false);
127 convolve_gaussian_1d(drawContext, clip, dstRect, srcOffset, texture, 142 }
143
144 if (!bottomRect.isEmpty()) {
145 drawContext->clear(&bottomRect, 0, false);
146 }
147 if (midRect.isEmpty()) {
148 // Blur radius covers srcBounds; use bounds over entire draw
149 convolve_gaussian_1d(drawContext, clip, dstRect, -srcOffset, texture,
128 direction, radius, sigma, true, bounds); 150 direction, radius, sigma, true, bounds);
129 } else { 151 } else {
130 // Draw upper and lower margins with bounds; middle without. 152 // Draw right and left margins with bounds; middle without.
131 convolve_gaussian_1d(drawContext, clip, lowerDstRect, srcOffset, texture , 153 convolve_gaussian_1d(drawContext, clip, leftRect, -srcOffset, texture,
132 direction, radius, sigma, true, bounds); 154 direction, radius, sigma, true, bounds);
133 convolve_gaussian_1d(drawContext, clip, upperDstRect, srcOffset, texture , 155 convolve_gaussian_1d(drawContext, clip, rightRect, -srcOffset, texture,
134 direction, radius, sigma, true, bounds); 156 direction, radius, sigma, true, bounds);
135 convolve_gaussian_1d(drawContext, clip, middleDstRect, srcOffset, textur e, 157 convolve_gaussian_1d(drawContext, clip, midRect, -srcOffset, texture,
136 direction, radius, sigma, false, bounds); 158 direction, radius, sigma, false, bounds);
137 } 159 }
138 } 160 }
139 161
140 GrTexture* GaussianBlur(GrContext* context, 162 GrTexture* GaussianBlur(GrContext* context,
141 GrTexture* srcTexture, 163 GrTexture* srcTexture,
142 bool canClobberSrc, 164 bool canClobberSrc,
143 const SkRect& rect, 165 const SkRect& dstBounds,
144 bool cropToRect, 166 const SkRect* srcBounds,
145 float sigmaX, 167 float sigmaX,
146 float sigmaY, 168 float sigmaY,
147 GrTextureProvider::SizeConstraint constraint) { 169 GrTextureProvider::SizeConstraint constraint) {
148 SkASSERT(context); 170 SkASSERT(context);
149
150 SkIRect clearRect; 171 SkIRect clearRect;
151 int scaleFactorX, radiusX; 172 int scaleFactorX, radiusX;
152 int scaleFactorY, radiusY; 173 int scaleFactorY, radiusY;
153 int maxTextureSize = context->caps()->maxTextureSize(); 174 int maxTextureSize = context->caps()->maxTextureSize();
154 sigmaX = adjust_sigma(sigmaX, maxTextureSize, &scaleFactorX, &radiusX); 175 sigmaX = adjust_sigma(sigmaX, maxTextureSize, &scaleFactorX, &radiusX);
155 sigmaY = adjust_sigma(sigmaY, maxTextureSize, &scaleFactorY, &radiusY); 176 sigmaY = adjust_sigma(sigmaY, maxTextureSize, &scaleFactorY, &radiusY);
156 177
157 SkRect srcRect(rect); 178 SkPoint srcOffset = SkPoint::Make(-dstBounds.x(), -dstBounds.y());
179 SkRect localDstBounds = SkRect::MakeWH(dstBounds.width(), dstBounds.height() );
180 SkRect localSrcBounds;
181 SkRect srcRect;
182 if (srcBounds) {
183 srcRect = localSrcBounds = *srcBounds;
184 srcRect.offset(srcOffset);
185 srcBounds = &localSrcBounds;
186 } else {
187 srcRect = localDstBounds;
188 }
189
158 scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY); 190 scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY);
159 srcRect.roundOut(&srcRect); 191 srcRect.roundOut(&srcRect);
160 scale_rect(&srcRect, static_cast<float>(scaleFactorX), 192 scale_rect(&srcRect, static_cast<float>(scaleFactorX),
161 static_cast<float>(scaleFactorY)); 193 static_cast<float>(scaleFactorY));
162 194
163 // setup new clip 195 // setup new clip
164 GrClip clip(SkRect::MakeWH(srcRect.width(), srcRect.height())); 196 GrClip clip(localDstBounds);
165 197
166 SkASSERT(kBGRA_8888_GrPixelConfig == srcTexture->config() || 198 SkASSERT(kBGRA_8888_GrPixelConfig == srcTexture->config() ||
167 kRGBA_8888_GrPixelConfig == srcTexture->config() || 199 kRGBA_8888_GrPixelConfig == srcTexture->config() ||
168 kAlpha_8_GrPixelConfig == srcTexture->config()); 200 kAlpha_8_GrPixelConfig == srcTexture->config());
169 201
170 GrSurfaceDesc desc; 202 GrSurfaceDesc desc;
171 desc.fFlags = kRenderTarget_GrSurfaceFlag; 203 desc.fFlags = kRenderTarget_GrSurfaceFlag;
172 desc.fWidth = SkScalarFloorToInt(srcRect.width()); 204 desc.fWidth = SkScalarFloorToInt(dstBounds.width());
173 desc.fHeight = SkScalarFloorToInt(srcRect.height()); 205 desc.fHeight = SkScalarFloorToInt(dstBounds.height());
174 desc.fConfig = srcTexture->config(); 206 desc.fConfig = srcTexture->config();
175 207
176 GrTexture* dstTexture; 208 GrTexture* dstTexture;
177 GrTexture* tempTexture; 209 GrTexture* tempTexture;
178 SkAutoTUnref<GrTexture> temp1, temp2; 210 SkAutoTUnref<GrTexture> temp1, temp2;
179 211
180 temp1.reset(context->textureProvider()->createTexture(desc, constraint)); 212 temp1.reset(context->textureProvider()->createTexture(desc, constraint));
181 dstTexture = temp1.get(); 213 dstTexture = temp1.get();
182 if (canClobberSrc) { 214 if (canClobberSrc) {
183 tempTexture = srcTexture; 215 tempTexture = srcTexture;
184 } else { 216 } else {
185 temp2.reset(context->textureProvider()->createTexture(desc, constraint)) ; 217 temp2.reset(context->textureProvider()->createTexture(desc, constraint)) ;
186 tempTexture = temp2.get(); 218 tempTexture = temp2.get();
187 } 219 }
188 220
189 if (nullptr == dstTexture || nullptr == tempTexture) { 221 if (nullptr == dstTexture || nullptr == tempTexture) {
190 return nullptr; 222 return nullptr;
191 } 223 }
192 224
193 SkAutoTUnref<GrDrawContext> srcDrawContext; 225 SkAutoTUnref<GrDrawContext> srcDrawContext;
194 226
195 for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) { 227 for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) {
196 GrPaint paint; 228 GrPaint paint;
197 SkMatrix matrix; 229 SkMatrix matrix;
198 matrix.setIDiv(srcTexture->width(), srcTexture->height()); 230 matrix.setIDiv(srcTexture->width(), srcTexture->height());
199 SkRect dstRect(srcRect); 231 SkRect dstRect(srcRect);
200 if (cropToRect && i == 1) { 232 if (srcBounds && i == 1) {
201 dstRect.offset(-dstRect.fLeft, -dstRect.fTop);
202 SkRect domain; 233 SkRect domain;
203 matrix.mapRect(&domain, rect); 234 matrix.mapRect(&domain, *srcBounds);
204 domain.inset(i < scaleFactorX ? SK_ScalarHalf / srcTexture->width() : 0.0f, 235 domain.inset((i < scaleFactorX) ? SK_ScalarHalf / srcTexture->width( ) : 0.0f,
205 i < scaleFactorY ? SK_ScalarHalf / srcTexture->height() : 0.0f); 236 (i < scaleFactorY) ? SK_ScalarHalf / srcTexture->height () : 0.0f);
206 SkAutoTUnref<const GrFragmentProcessor> fp(GrTextureDomainEffect::Cr eate( 237 SkAutoTUnref<const GrFragmentProcessor> fp(GrTextureDomainEffect::Cr eate(
207 srcTexture, 238 srcTexture,
208 matrix, 239 matrix,
209 domain, 240 domain,
210 GrTextureDomain::kDecal_Mode, 241 GrTextureDomain::kDecal_Mode,
211 GrTextureParams::kBilerp_FilterMode)); 242 GrTextureParams::kBilerp_FilterMode));
212 paint.addColorFragmentProcessor(fp); 243 paint.addColorFragmentProcessor(fp);
244 srcRect.offset(-srcOffset);
245 srcOffset.set(0, 0);
213 } else { 246 } else {
214 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::k Bilerp_FilterMode); 247 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::k Bilerp_FilterMode);
215 paint.addColorTextureProcessor(srcTexture, matrix, params); 248 paint.addColorTextureProcessor(srcTexture, matrix, params);
216 } 249 }
217 scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f, 250 scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f,
218 i < scaleFactorY ? 0.5f : 1.0f); 251 i < scaleFactorY ? 0.5f : 1.0f);
219 252
220 SkAutoTUnref<GrDrawContext> dstDrawContext( 253 SkAutoTUnref<GrDrawContext> dstDrawContext(
221 context->drawContext(dstTexture->as RenderTarget())); 254 context->drawContext(dstTexture->as RenderTarget()));
222 if (!dstDrawContext) { 255 if (!dstDrawContext) {
223 return nullptr; 256 return nullptr;
224 } 257 }
225 dstDrawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcR ect); 258 dstDrawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcR ect);
226 259
227 srcDrawContext.swap(dstDrawContext); 260 srcDrawContext.swap(dstDrawContext);
228 srcRect = dstRect; 261 srcRect = dstRect;
229 srcTexture = dstTexture; 262 srcTexture = dstTexture;
230 SkTSwap(dstTexture, tempTexture); 263 SkTSwap(dstTexture, tempTexture);
264 localSrcBounds = srcRect;
231 } 265 }
232 266
233 const SkIRect srcIRect = srcRect.roundOut();
234
235 // For really small blurs (certainly no wider than 5x5 on desktop gpus) it i s faster to just 267 // For really small blurs (certainly no wider than 5x5 on desktop gpus) it i s faster to just
236 // launch a single non separable kernel vs two launches 268 // launch a single non separable kernel vs two launches
237 if (sigmaX > 0.0f && sigmaY > 0.0f && 269 if (sigmaX > 0.0f && sigmaY > 0.0f &&
238 (2 * radiusX + 1) * (2 * radiusY + 1) <= MAX_KERNEL_SIZE) { 270 (2 * radiusX + 1) * (2 * radiusY + 1) <= MAX_KERNEL_SIZE) {
239 // We shouldn't be scaling because this is a small size blur 271 // We shouldn't be scaling because this is a small size blur
240 SkASSERT((1 == scaleFactorX) && (1 == scaleFactorY)); 272 SkASSERT((1 == scaleFactorX) && (1 == scaleFactorY));
241 273
242 SkAutoTUnref<GrDrawContext> dstDrawContext( 274 SkAutoTUnref<GrDrawContext> dstDrawContext(
243 context->drawContext(dstTexture->as RenderTarget())); 275 context->drawContext(dstTexture->as RenderTarget()));
244 if (!dstDrawContext) { 276 if (!dstDrawContext) {
245 return nullptr; 277 return nullptr;
246 } 278 }
247 convolve_gaussian_2d(dstDrawContext, clip, srcRect, 279 convolve_gaussian_2d(dstDrawContext, clip, srcRect,
248 srcTexture, radiusX, radiusY, sigmaX, sigmaY, cropT oRect, srcIRect); 280 srcTexture, radiusX, radiusY, sigmaX, sigmaY, srcBo unds);
249 281
250 srcDrawContext.swap(dstDrawContext); 282 srcDrawContext.swap(dstDrawContext);
251 srcRect.offsetTo(0, 0); 283 srcRect.offsetTo(0, 0);
252 srcTexture = dstTexture; 284 srcTexture = dstTexture;
253 SkTSwap(dstTexture, tempTexture); 285 SkTSwap(dstTexture, tempTexture);
254 286
255 } else { 287 } else {
288 srcRect = localDstBounds;
289 scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY);
290 srcRect.roundOut(&srcRect);
291 const SkIRect srcIRect = srcRect.roundOut();
256 if (sigmaX > 0.0f) { 292 if (sigmaX > 0.0f) {
257 if (scaleFactorX > 1) { 293 if (scaleFactorX > 1) {
258 // TODO: if we pass in the source draw context we don't need thi s here 294 // TODO: if we pass in the source draw context we don't need thi s here
259 if (!srcDrawContext) { 295 if (!srcDrawContext) {
260 srcDrawContext.reset(context->drawContext(srcTexture->asRend erTarget())); 296 srcDrawContext.reset(context->drawContext(srcTexture->asRend erTarget()));
261 if (!srcDrawContext) { 297 if (!srcDrawContext) {
262 return nullptr; 298 return nullptr;
263 } 299 }
264 } 300 }
265 301
266 // Clear out a radius to the right of the srcRect to prevent the 302 // Clear out a radius to the right of the srcRect to prevent the
267 // X convolution from reading garbage. 303 // X convolution from reading garbage.
268 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, 304 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
269 radiusX, srcIRect.height()); 305 radiusX, srcIRect.height());
270 srcDrawContext->clear(&clearRect, 0x0, false); 306 srcDrawContext->clear(&clearRect, 0x0, false);
271 } 307 }
272 308
273 SkAutoTUnref<GrDrawContext> dstDrawContext( 309 SkAutoTUnref<GrDrawContext> dstDrawContext(
274 context->drawContext(dstTexture->as RenderTarget())); 310 context->drawContext(dstTexture->as RenderTarget()));
275 if (!dstDrawContext) { 311 if (!dstDrawContext) {
276 return nullptr; 312 return nullptr;
277 } 313 }
278 convolve_gaussian(dstDrawContext, clip, srcRect, 314 convolve_gaussian(dstDrawContext, clip, srcRect,
279 srcTexture, Gr1DKernelEffect::kX_Direction, radius X, sigmaX, 315 srcTexture, Gr1DKernelEffect::kX_Direction, radius X, sigmaX,
280 cropToRect); 316 srcBounds, srcOffset);
281
282 srcDrawContext.swap(dstDrawContext); 317 srcDrawContext.swap(dstDrawContext);
283 srcTexture = dstTexture; 318 srcTexture = dstTexture;
284 srcRect.offsetTo(0, 0); 319 srcRect.offsetTo(0, 0);
285 SkTSwap(dstTexture, tempTexture); 320 SkTSwap(dstTexture, tempTexture);
321 localSrcBounds = srcRect;
322 srcOffset.set(0, 0);
286 } 323 }
287 324
288 if (sigmaY > 0.0f) { 325 if (sigmaY > 0.0f) {
289 if (scaleFactorY > 1 || sigmaX > 0.0f) { 326 if (scaleFactorY > 1 || sigmaX > 0.0f) {
290 // TODO: if we pass in the source draw context we don't need thi s here 327 // TODO: if we pass in the source draw context we don't need thi s here
291 if (!srcDrawContext) { 328 if (!srcDrawContext) {
292 srcDrawContext.reset(context->drawContext(srcTexture->asRend erTarget())); 329 srcDrawContext.reset(context->drawContext(srcTexture->asRend erTarget()));
293 if (!srcDrawContext) { 330 if (!srcDrawContext) {
294 return nullptr; 331 return nullptr;
295 } 332 }
296 } 333 }
297 334
298 // Clear out a radius below the srcRect to prevent the Y 335 // Clear out a radius below the srcRect to prevent the Y
299 // convolution from reading garbage. 336 // convolution from reading garbage.
300 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, 337 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
301 srcIRect.width(), radiusY); 338 srcIRect.width(), radiusY);
302 srcDrawContext->clear(&clearRect, 0x0, false); 339 srcDrawContext->clear(&clearRect, 0x0, false);
303 } 340 }
304 341
305 SkAutoTUnref<GrDrawContext> dstDrawContext( 342 SkAutoTUnref<GrDrawContext> dstDrawContext(
306 context->drawContext(dstTexture-> asRenderTarget())); 343 context->drawContext(dstTexture-> asRenderTarget()));
307 if (!dstDrawContext) { 344 if (!dstDrawContext) {
308 return nullptr; 345 return nullptr;
309 } 346 }
310 convolve_gaussian(dstDrawContext, clip, srcRect, 347 convolve_gaussian(dstDrawContext, clip, srcRect,
311 srcTexture, Gr1DKernelEffect::kY_Direction, radius Y, sigmaY, 348 srcTexture, Gr1DKernelEffect::kY_Direction, radius Y, sigmaY,
312 cropToRect); 349 srcBounds, srcOffset);
313 350
314 srcDrawContext.swap(dstDrawContext); 351 srcDrawContext.swap(dstDrawContext);
315 srcTexture = dstTexture; 352 srcTexture = dstTexture;
316 srcRect.offsetTo(0, 0); 353 srcRect.offsetTo(0, 0);
317 SkTSwap(dstTexture, tempTexture); 354 SkTSwap(dstTexture, tempTexture);
318 } 355 }
319 } 356 }
357 const SkIRect srcIRect = srcRect.roundOut();
320 358
321 if (scaleFactorX > 1 || scaleFactorY > 1) { 359 if (scaleFactorX > 1 || scaleFactorY > 1) {
322 SkASSERT(srcDrawContext); 360 SkASSERT(srcDrawContext);
323 361
324 // Clear one pixel to the right and below, to accommodate bilinear 362 // Clear one pixel to the right and below, to accommodate bilinear
325 // upsampling. 363 // upsampling.
326 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, 364 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
327 srcIRect.width() + 1, 1); 365 srcIRect.width() + 1, 1);
328 srcDrawContext->clear(&clearRect, 0x0, false); 366 srcDrawContext->clear(&clearRect, 0x0, false);
329 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, 367 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
(...skipping 21 matching lines...) Expand all
351 srcRect = dstRect; 389 srcRect = dstRect;
352 srcTexture = dstTexture; 390 srcTexture = dstTexture;
353 SkTSwap(dstTexture, tempTexture); 391 SkTSwap(dstTexture, tempTexture);
354 } 392 }
355 393
356 return SkRef(srcTexture); 394 return SkRef(srcTexture);
357 } 395 }
358 #endif 396 #endif
359 397
360 } 398 }
OLDNEW
« no previous file with comments | « src/effects/SkGpuBlurUtils.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698