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

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

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

Powered by Google App Engine
This is Rietveld 408576698