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

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

Issue 18771004: Move gaussianBlur functionality to src\effects (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « src/effects/SkBlurUtils.h ('k') | src/gpu/GrContext.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 /*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SkBlurUtils.h"
9 #include "SkRect.h"
tfarina 2013/07/13 22:19:30 can we have a blank line separating these?
robertphillips 2013/07/15 12:05:04 Done.
10
11 #if SK_SUPPORT_GPU
12 #include "effects\GrConvolutionEffect.h"
tfarina 2013/07/13 22:19:30 is effects necessary here? I think we don't use fu
robertphillips 2013/07/15 12:05:04 GrConvolutionEffect.h lives in src\gpu\effects. sr
13 #include "GrContext.h"
14 #endif
15
16 namespace SkBlurUtils {
17
18 #if SK_SUPPORT_GPU
19
20 #define MAX_BLUR_SIGMA 4.0f
21
22 static void scale_rect(SkRect* rect, float xScale, float yScale) {
23 rect->fLeft = SkScalarMul(rect->fLeft, SkFloatToScalar(xScale));
24 rect->fTop = SkScalarMul(rect->fTop, SkFloatToScalar(yScale));
25 rect->fRight = SkScalarMul(rect->fRight, SkFloatToScalar(xScale));
26 rect->fBottom = SkScalarMul(rect->fBottom, SkFloatToScalar(yScale));
27 }
28
29 static float adjust_sigma(float sigma, int *scaleFactor, int *radius) {
30 *scaleFactor = 1;
31 while (sigma > MAX_BLUR_SIGMA) {
32 *scaleFactor *= 2;
33 sigma *= 0.5f;
34 }
35 *radius = static_cast<int>(ceilf(sigma * 3.0f));
36 GrAssert(*radius <= GrConvolutionEffect::kMaxKernelRadius);
37 return sigma;
38 }
39
40 static void convolve_gaussian(GrContext* context,
41 GrTexture* texture,
42 const SkRect& rect,
43 float sigma,
44 int radius,
45 Gr1DKernelEffect::Direction direction) {
46 GrPaint paint;
47
48 SkAutoTUnref<GrEffectRef> conv(GrConvolutionEffect::CreateGaussian(texture,
49 direction ,
50 radius,
51 sigma));
52 paint.addColorEffect(conv);
53 context->drawRect(paint, rect);
54 }
55
56 GrTexture* GaussianBlur(GrContext* context,
57 GrTexture* srcTexture,
58 bool canClobberSrc,
59 const SkRect& rect,
60 float sigmaX,
61 float sigmaY) {
62 GrAssert(NULL != context);
63
64 GrContext::AutoRenderTarget art(context);
65
66 GrContext::AutoMatrix am;
67 am.setIdentity(context);
68
69 SkIRect clearRect;
70 int scaleFactorX, radiusX;
71 int scaleFactorY, radiusY;
72 sigmaX = adjust_sigma(sigmaX, &scaleFactorX, &radiusX);
73 sigmaY = adjust_sigma(sigmaY, &scaleFactorY, &radiusY);
74
75 SkRect srcRect(rect);
76 scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY);
77 srcRect.roundOut();
78 scale_rect(&srcRect, static_cast<float>(scaleFactorX),
79 static_cast<float>(scaleFactorY));
80
81 GrContext::AutoClip acs(context, srcRect);
82
83 GrAssert(kBGRA_8888_GrPixelConfig == srcTexture->config() ||
84 kRGBA_8888_GrPixelConfig == srcTexture->config() ||
85 kAlpha_8_GrPixelConfig == srcTexture->config());
86
87 GrTextureDesc desc;
88 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
89 desc.fWidth = SkScalarFloorToInt(srcRect.width());
90 desc.fHeight = SkScalarFloorToInt(srcRect.height());
91 desc.fConfig = srcTexture->config();
92
93 GrAutoScratchTexture temp1, temp2;
94 GrTexture* dstTexture = temp1.set(context, desc);
95 GrTexture* tempTexture = canClobberSrc ? srcTexture : temp2.set(context, des c);
96 if (NULL == dstTexture || NULL == tempTexture) {
97 return NULL;
98 }
99
100 for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) {
101 GrPaint paint;
102 SkMatrix matrix;
103 matrix.setIDiv(srcTexture->width(), srcTexture->height());
104 context->setRenderTarget(dstTexture->asRenderTarget());
105 SkRect dstRect(srcRect);
106 scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f,
107 i < scaleFactorY ? 0.5f : 1.0f);
108 GrTextureParams params(SkShader::kClamp_TileMode, true);
109 paint.addColorTextureEffect(srcTexture, matrix, params);
110 context->drawRectToRect(paint, dstRect, srcRect);
111 srcRect = dstRect;
112 srcTexture = dstTexture;
113 SkTSwap(dstTexture, tempTexture);
114 }
115
116 SkIRect srcIRect;
117 srcRect.roundOut(&srcIRect);
118
119 if (sigmaX > 0.0f) {
120 if (scaleFactorX > 1) {
121 // Clear out a radius to the right of the srcRect to prevent the
122 // X convolution from reading garbage.
123 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
124 radiusX, srcIRect.height());
125 context->clear(&clearRect, 0x0);
126 }
127 context->setRenderTarget(dstTexture->asRenderTarget());
128 convolve_gaussian(context, srcTexture, srcRect, sigmaX, radiusX,
129 Gr1DKernelEffect::kX_Direction);
130 srcTexture = dstTexture;
131 SkTSwap(dstTexture, tempTexture);
132 }
133
134 if (sigmaY > 0.0f) {
135 if (scaleFactorY > 1 || sigmaX > 0.0f) {
136 // Clear out a radius below the srcRect to prevent the Y
137 // convolution from reading garbage.
138 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
139 srcIRect.width(), radiusY);
140 context->clear(&clearRect, 0x0);
141 }
142
143 context->setRenderTarget(dstTexture->asRenderTarget());
144 convolve_gaussian(context, srcTexture, srcRect, sigmaY, radiusY,
145 Gr1DKernelEffect::kY_Direction);
146 srcTexture = dstTexture;
147 SkTSwap(dstTexture, tempTexture);
148 }
149
150 if (scaleFactorX > 1 || scaleFactorY > 1) {
151 // Clear one pixel to the right and below, to accommodate bilinear
152 // upsampling.
153 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
154 srcIRect.width() + 1, 1);
155 context->clear(&clearRect, 0x0);
156 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
157 1, srcIRect.height());
158 context->clear(&clearRect, 0x0);
159 SkMatrix matrix;
160 matrix.setIDiv(srcTexture->width(), srcTexture->height());
161 context->setRenderTarget(dstTexture->asRenderTarget());
162
163 GrPaint paint;
164 // FIXME: this should be mitchell, not bilinear.
165 GrTextureParams params(SkShader::kClamp_TileMode, true);
166 paint.addColorTextureEffect(srcTexture, matrix, params);
167
168 SkRect dstRect(srcRect);
169 scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY);
170 context->drawRectToRect(paint, dstRect, srcRect);
171 srcRect = dstRect;
172 srcTexture = dstTexture;
173 SkTSwap(dstTexture, tempTexture);
174 }
175 if (srcTexture == temp1.texture()) {
176 return temp1.detach();
177 } else if (srcTexture == temp2.texture()) {
178 return temp2.detach();
179 } else {
180 srcTexture->ref();
181 return srcTexture;
182 }
183 }
184 #endif
185
186 };
tfarina 2013/07/13 22:19:30 no need of ; here. I'd just write: } // namespa
robertphillips 2013/07/15 12:05:04 Done.
OLDNEW
« no previous file with comments | « src/effects/SkBlurUtils.h ('k') | src/gpu/GrContext.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698