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

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

Issue 555603002: Allow negative values in SkBlurImageFilter sigma. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Five is the new three. :) Created 6 years, 3 months 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 | « no previous file | tests/ImageFilterTest.cpp » ('j') | 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 2011 The Android Open Source Project 2 * Copyright 2011 The Android Open Source Project
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 "SkBitmap.h" 8 #include "SkBitmap.h"
9 #include "SkBlurImageFilter.h" 9 #include "SkBlurImageFilter.h"
10 #include "SkColorPriv.h" 10 #include "SkColorPriv.h"
11 #include "SkReadBuffer.h" 11 #include "SkReadBuffer.h"
12 #include "SkWriteBuffer.h" 12 #include "SkWriteBuffer.h"
13 #include "SkGpuBlurUtils.h" 13 #include "SkGpuBlurUtils.h"
14 #include "SkBlurImage_opts.h" 14 #include "SkBlurImage_opts.h"
15 #if SK_SUPPORT_GPU 15 #if SK_SUPPORT_GPU
16 #include "GrContext.h" 16 #include "GrContext.h"
17 #endif 17 #endif
18 18
19 // This rather arbitrary-looking value results in a maximum box blur kernel size 19 // This rather arbitrary-looking value results in a maximum box blur kernel size
20 // of 1000 pixels on the raster path, which matches the WebKit and Firefox 20 // of 1000 pixels on the raster path, which matches the WebKit and Firefox
21 // implementations. Since the GPU path does not compute a box blur, putting 21 // implementations. Since the GPU path does not compute a box blur, putting
22 // the limit on sigma ensures consistent behaviour between the GPU and 22 // the limit on sigma ensures consistent behaviour between the GPU and
23 // raster paths. 23 // raster paths.
24 #define MAX_SIGMA SkIntToScalar(532) 24 #define MAX_SIGMA SkIntToScalar(532)
25 25
26 static SkVector mapSigma(const SkSize& localSigma, const SkMatrix& ctm) {
27 SkVector sigma = SkVector::Make(localSigma.width(), localSigma.height());
28 ctm.mapVectors(&sigma, 1);
29 sigma.fX = SkMinScalar(sigma.fX, MAX_SIGMA);
30 sigma.fY = SkMinScalar(sigma.fY, MAX_SIGMA);
sugoi1 2014/09/09 15:42:39 Shouldn't this happen after line 37? What if sigma
Stephen White 2014/09/09 16:03:59 Good catch. Fixed.
31 if (sigma.fX < 0) {
reed1 2014/09/09 15:37:38 SkScalarAbs()
Stephen White 2014/09/09 15:48:15 Done.
32 sigma.fX = -sigma.fX;
33 }
34
35 if (sigma.fY < 0) {
36 sigma.fY = -sigma.fY;
37 }
38 return sigma;
39 }
40
26 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 41 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
27 SkBlurImageFilter::SkBlurImageFilter(SkReadBuffer& buffer) 42 SkBlurImageFilter::SkBlurImageFilter(SkReadBuffer& buffer)
28 : INHERITED(1, buffer) { 43 : INHERITED(1, buffer) {
29 fSigma.fWidth = buffer.readScalar(); 44 fSigma.fWidth = buffer.readScalar();
30 fSigma.fHeight = buffer.readScalar(); 45 fSigma.fHeight = buffer.readScalar();
31 buffer.validate(SkScalarIsFinite(fSigma.fWidth) && 46 buffer.validate(SkScalarIsFinite(fSigma.fWidth) &&
32 SkScalarIsFinite(fSigma.fHeight) && 47 SkScalarIsFinite(fSigma.fHeight));
33 (fSigma.fWidth >= 0) &&
34 (fSigma.fHeight >= 0));
35 } 48 }
36 #endif 49 #endif
37 50
38 SkBlurImageFilter::SkBlurImageFilter(SkScalar sigmaX, 51 SkBlurImageFilter::SkBlurImageFilter(SkScalar sigmaX,
39 SkScalar sigmaY, 52 SkScalar sigmaY,
40 SkImageFilter* input, 53 SkImageFilter* input,
41 const CropRect* cropRect, 54 const CropRect* cropRect,
42 uint32_t uniqueID) 55 uint32_t uniqueID)
43 : INHERITED(1, &input, cropRect, uniqueID), fSigma(SkSize::Make(sigmaX, sigm aY)) { 56 : INHERITED(1, &input, cropRect, uniqueID), fSigma(SkSize::Make(sigmaX, sigm aY)) {
44 } 57 }
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 SkAutoLockPixels alp(src); 183 SkAutoLockPixels alp(src);
171 if (!src.getPixels()) { 184 if (!src.getPixels()) {
172 return false; 185 return false;
173 } 186 }
174 187
175 if (!dst->tryAllocPixels(src.info().makeWH(srcBounds.width(), srcBounds.heig ht()))) { 188 if (!dst->tryAllocPixels(src.info().makeWH(srcBounds.width(), srcBounds.heig ht()))) {
176 return false; 189 return false;
177 } 190 }
178 dst->getBounds(&dstBounds); 191 dst->getBounds(&dstBounds);
179 192
180 SkVector sigma = SkVector::Make(fSigma.width(), fSigma.height()); 193 SkVector sigma = mapSigma(fSigma, ctx.ctm());
181 ctx.ctm().mapVectors(&sigma, 1);
182 sigma.fX = SkMinScalar(sigma.fX, MAX_SIGMA);
183 sigma.fY = SkMinScalar(sigma.fY, MAX_SIGMA);
184 194
185 int kernelSizeX, kernelSizeX3, lowOffsetX, highOffsetX; 195 int kernelSizeX, kernelSizeX3, lowOffsetX, highOffsetX;
186 int kernelSizeY, kernelSizeY3, lowOffsetY, highOffsetY; 196 int kernelSizeY, kernelSizeY3, lowOffsetY, highOffsetY;
187 getBox3Params(sigma.x(), &kernelSizeX, &kernelSizeX3, &lowOffsetX, &highOffs etX); 197 getBox3Params(sigma.x(), &kernelSizeX, &kernelSizeX3, &lowOffsetX, &highOffs etX);
188 getBox3Params(sigma.y(), &kernelSizeY, &kernelSizeY3, &lowOffsetY, &highOffs etY); 198 getBox3Params(sigma.y(), &kernelSizeY, &kernelSizeY3, &lowOffsetY, &highOffs etY);
189 199
190 if (kernelSizeX < 0 || kernelSizeY < 0) { 200 if (kernelSizeX < 0 || kernelSizeY < 0) {
191 return false; 201 return false;
192 } 202 }
193 203
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 *dst = src; 256 *dst = src;
247 } 257 }
248 258
249 dst->outset(SkScalarMul(fSigma.width(), SkIntToScalar(3)), 259 dst->outset(SkScalarMul(fSigma.width(), SkIntToScalar(3)),
250 SkScalarMul(fSigma.height(), SkIntToScalar(3))); 260 SkScalarMul(fSigma.height(), SkIntToScalar(3)));
251 } 261 }
252 262
253 bool SkBlurImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, 263 bool SkBlurImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
254 SkIRect* dst) const { 264 SkIRect* dst) const {
255 SkIRect bounds = src; 265 SkIRect bounds = src;
256 SkVector sigma = SkVector::Make(fSigma.width(), fSigma.height()); 266 SkVector sigma = mapSigma(fSigma, ctm);
257 ctm.mapVectors(&sigma, 1);
258 bounds.outset(SkScalarCeilToInt(SkScalarMul(sigma.x(), SkIntToScalar(3))), 267 bounds.outset(SkScalarCeilToInt(SkScalarMul(sigma.x(), SkIntToScalar(3))),
259 SkScalarCeilToInt(SkScalarMul(sigma.y(), SkIntToScalar(3)))); 268 SkScalarCeilToInt(SkScalarMul(sigma.y(), SkIntToScalar(3))));
260 if (getInput(0) && !getInput(0)->filterBounds(bounds, ctm, &bounds)) { 269 if (getInput(0) && !getInput(0)->filterBounds(bounds, ctm, &bounds)) {
261 return false; 270 return false;
262 } 271 }
263 *dst = bounds; 272 *dst = bounds;
264 return true; 273 return true;
265 } 274 }
266 275
267 bool SkBlurImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, 276 bool SkBlurImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx,
268 SkBitmap* result, SkIPoint* offset) const { 277 SkBitmap* result, SkIPoint* offset) const {
269 #if SK_SUPPORT_GPU 278 #if SK_SUPPORT_GPU
270 SkBitmap input = src; 279 SkBitmap input = src;
271 SkIPoint srcOffset = SkIPoint::Make(0, 0); 280 SkIPoint srcOffset = SkIPoint::Make(0, 0);
272 if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, &input, &srcOffset)) { 281 if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, &input, &srcOffset)) {
273 return false; 282 return false;
274 } 283 }
275 SkIRect rect; 284 SkIRect rect;
276 if (!this->applyCropRect(ctx, proxy, input, &srcOffset, &rect, &input)) { 285 if (!this->applyCropRect(ctx, proxy, input, &srcOffset, &rect, &input)) {
277 return false; 286 return false;
278 } 287 }
279 GrTexture* source = input.getTexture(); 288 GrTexture* source = input.getTexture();
280 SkVector sigma = SkVector::Make(fSigma.width(), fSigma.height()); 289 SkVector sigma = mapSigma(fSigma, ctx.ctm());
281 ctx.ctm().mapVectors(&sigma, 1);
282 sigma.fX = SkMinScalar(sigma.fX, MAX_SIGMA);
283 sigma.fY = SkMinScalar(sigma.fY, MAX_SIGMA);
284 offset->fX = rect.fLeft; 290 offset->fX = rect.fLeft;
285 offset->fY = rect.fTop; 291 offset->fY = rect.fTop;
286 rect.offset(-srcOffset); 292 rect.offset(-srcOffset);
287 SkAutoTUnref<GrTexture> tex(SkGpuBlurUtils::GaussianBlur(source->getContext( ), 293 SkAutoTUnref<GrTexture> tex(SkGpuBlurUtils::GaussianBlur(source->getContext( ),
288 source, 294 source,
289 false, 295 false,
290 SkRect::Make(rect), 296 SkRect::Make(rect),
291 true, 297 true,
292 sigma.x(), 298 sigma.x(),
293 sigma.y())); 299 sigma.y()));
294 WrapTexture(tex, rect.width(), rect.height(), result); 300 WrapTexture(tex, rect.width(), rect.height(), result);
295 return true; 301 return true;
296 #else 302 #else
297 SkDEBUGFAIL("Should not call in GPU-less build"); 303 SkDEBUGFAIL("Should not call in GPU-less build");
298 return false; 304 return false;
299 #endif 305 #endif
300 } 306 }
OLDNEW
« no previous file with comments | « no previous file | tests/ImageFilterTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698