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

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

Issue 1959493002: Retract GrRenderTarget from SkGpuBlurUtils Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Clean up Created 4 years, 7 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 | « src/effects/SkGpuBlurUtils.h ('k') | src/gpu/GrBlurUtils.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 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"
11 11
12 #if SK_SUPPORT_GPU 12 #if SK_SUPPORT_GPU
13 #include "effects/GrConvolutionEffect.h" 13 #include "effects/GrConvolutionEffect.h"
14 #include "effects/GrMatrixConvolutionEffect.h" 14 #include "effects/GrMatrixConvolutionEffect.h"
15 #include "GrContext.h" 15 #include "GrContext.h"
16 #include "GrCaps.h" 16 #include "GrCaps.h"
17 #include "GrDrawContext.h" 17 #include "GrDrawContext.h"
18 #endif
19
20 namespace SkGpuBlurUtils {
21
22 #if SK_SUPPORT_GPU
23 18
24 #define MAX_BLUR_SIGMA 4.0f 19 #define MAX_BLUR_SIGMA 4.0f
25 20
26 static void scale_rect(SkRect* rect, float xScale, float yScale) { 21 static void scale_irect_roundout(SkIRect* rect, float xScale, float yScale) {
27 rect->fLeft = SkScalarMul(rect->fLeft, xScale); 22 rect->fLeft = SkScalarFloorToInt(SkScalarMul(rect->fLeft, xScale));
28 rect->fTop = SkScalarMul(rect->fTop, yScale); 23 rect->fTop = SkScalarFloorToInt(SkScalarMul(rect->fTop, yScale));
29 rect->fRight = SkScalarMul(rect->fRight, xScale); 24 rect->fRight = SkScalarCeilToInt(SkScalarMul(rect->fRight, xScale));
30 rect->fBottom = SkScalarMul(rect->fBottom, yScale); 25 rect->fBottom = SkScalarCeilToInt(SkScalarMul(rect->fBottom, yScale));
26 }
27
28 static void scale_irect(SkIRect* rect, int xScale, int yScale) {
29 rect->fLeft *= xScale;
30 rect->fTop *= yScale;
31 rect->fRight *= xScale;
32 rect->fBottom *= yScale;
33 }
34
35 #ifdef SK_DEBUG
36 static inline int is_even(int x) { return !(x & 1); }
37 #endif
38
39 static void shrink_irect_by_2(SkIRect* rect, bool xAxis, bool yAxis) {
40 if (xAxis) {
41 SkASSERT(is_even(rect->fLeft) && is_even(rect->fRight));
42 rect->fLeft /= 2;
43 rect->fRight /= 2;
44 }
45 if (yAxis) {
46 SkASSERT(is_even(rect->fTop) && is_even(rect->fBottom));
47 rect->fTop /= 2;
48 rect->fBottom /= 2;
49 }
31 } 50 }
32 51
33 static float adjust_sigma(float sigma, int maxTextureSize, int *scaleFactor, int *radius) { 52 static float adjust_sigma(float sigma, int maxTextureSize, int *scaleFactor, int *radius) {
34 *scaleFactor = 1; 53 *scaleFactor = 1;
35 while (sigma > MAX_BLUR_SIGMA) { 54 while (sigma > MAX_BLUR_SIGMA) {
36 *scaleFactor *= 2; 55 *scaleFactor *= 2;
37 sigma *= 0.5f; 56 sigma *= 0.5f;
38 if (*scaleFactor > maxTextureSize) { 57 if (*scaleFactor > maxTextureSize) {
39 *scaleFactor = maxTextureSize; 58 *scaleFactor = maxTextureSize;
40 sigma = MAX_BLUR_SIGMA; 59 sigma = MAX_BLUR_SIGMA;
41 } 60 }
42 } 61 }
43 *radius = static_cast<int>(ceilf(sigma * 3.0f)); 62 *radius = static_cast<int>(ceilf(sigma * 3.0f));
44 SkASSERT(*radius <= GrConvolutionEffect::kMaxKernelRadius); 63 SkASSERT(*radius <= GrConvolutionEffect::kMaxKernelRadius);
45 return sigma; 64 return sigma;
46 } 65 }
47 66
48 static void convolve_gaussian_1d(GrDrawContext* drawContext, 67 static void convolve_gaussian_1d(GrDrawContext* drawContext,
49 const GrClip& clip, 68 const GrClip& clip,
50 const SkRect& dstRect, 69 const SkIRect& dstRect,
51 const SkPoint& srcOffset, 70 const SkIPoint& srcOffset,
52 GrTexture* texture, 71 GrTexture* texture,
53 Gr1DKernelEffect::Direction direction, 72 Gr1DKernelEffect::Direction direction,
54 int radius, 73 int radius,
55 float sigma, 74 float sigma,
56 bool useBounds, 75 bool useBounds,
57 float bounds[2]) { 76 float bounds[2]) {
58 GrPaint paint; 77 GrPaint paint;
59 paint.setGammaCorrect(drawContext->isGammaCorrect()); 78 paint.setGammaCorrect(drawContext->isGammaCorrect());
60 SkAutoTUnref<GrFragmentProcessor> conv(GrConvolutionEffect::CreateGaussian( 79 SkAutoTUnref<GrFragmentProcessor> conv(GrConvolutionEffect::CreateGaussian(
61 texture, direction, radius, sigma, useBounds, bounds)); 80 texture, direction, radius, sigma, useBounds, bounds));
62 paint.addColorFragmentProcessor(conv); 81 paint.addColorFragmentProcessor(conv);
63 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); 82 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
64 SkMatrix localMatrix = SkMatrix::MakeTrans(-srcOffset.x(), -srcOffset.y()); 83 SkMatrix localMatrix = SkMatrix::MakeTrans(-SkIntToScalar(srcOffset.x()),
65 drawContext->fillRectWithLocalMatrix(clip, paint, SkMatrix::I(), dstRect, lo calMatrix); 84 -SkIntToScalar(srcOffset.y()));
85 drawContext->fillRectWithLocalMatrix(clip, paint, SkMatrix::I(),
86 SkRect::Make(dstRect), localMatrix);
66 } 87 }
67 88
68 static void convolve_gaussian_2d(GrDrawContext* drawContext, 89 static void convolve_gaussian_2d(GrDrawContext* drawContext,
69 const GrClip& clip, 90 const GrClip& clip,
70 const SkRect& dstRect, 91 const SkIRect& dstRect,
71 const SkPoint& srcOffset, 92 const SkIPoint& srcOffset,
72 GrTexture* texture, 93 GrTexture* texture,
73 int radiusX, 94 int radiusX,
74 int radiusY, 95 int radiusY,
75 SkScalar sigmaX, 96 SkScalar sigmaX,
76 SkScalar sigmaY, 97 SkScalar sigmaY,
77 const SkRect* srcBounds) { 98 const SkIRect* srcBounds) {
78 SkMatrix localMatrix = SkMatrix::MakeTrans(-srcOffset.x(), -srcOffset.y()); 99 SkMatrix localMatrix = SkMatrix::MakeTrans(-SkIntToScalar(srcOffset.x()),
100 -SkIntToScalar(srcOffset.y()));
79 SkISize size = SkISize::Make(2 * radiusX + 1, 2 * radiusY + 1); 101 SkISize size = SkISize::Make(2 * radiusX + 1, 2 * radiusY + 1);
80 SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY); 102 SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY);
81 GrPaint paint; 103 GrPaint paint;
82 paint.setGammaCorrect(drawContext->isGammaCorrect()); 104 paint.setGammaCorrect(drawContext->isGammaCorrect());
83 SkIRect bounds; 105 SkIRect bounds = srcBounds ? *srcBounds : SkIRect::EmptyIRect();
84 if (srcBounds) {
85 srcBounds->roundOut(&bounds);
86 } else {
87 bounds.setEmpty();
88 }
89 106
90 SkAutoTUnref<GrFragmentProcessor> conv(GrMatrixConvolutionEffect::CreateGaus sian( 107 SkAutoTUnref<GrFragmentProcessor> conv(GrMatrixConvolutionEffect::CreateGaus sian(
91 texture, bounds, size, 1.0, 0.0, kernelOffset, 108 texture, bounds, size, 1.0, 0.0, kernelOffset,
92 srcBounds ? GrTextureDomain::kDecal_Mode : GrTextureDomain::kIgnore_ Mode, 109 srcBounds ? GrTextureDomain::kDecal_Mode : GrTextureDomain::kIgnore_ Mode,
93 true, sigmaX, sigmaY)); 110 true, sigmaX, sigmaY));
94 paint.addColorFragmentProcessor(conv); 111 paint.addColorFragmentProcessor(conv);
95 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); 112 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
96 drawContext->fillRectWithLocalMatrix(clip, paint, SkMatrix::I(), dstRect, lo calMatrix); 113 drawContext->fillRectWithLocalMatrix(clip, paint, SkMatrix::I(),
114 SkRect::Make(dstRect), localMatrix);
97 } 115 }
98 116
99 static void convolve_gaussian(GrDrawContext* drawContext, 117 static void convolve_gaussian(GrDrawContext* drawContext,
100 const GrClip& clip, 118 const GrClip& clip,
101 const SkRect& srcRect, 119 const SkIRect& srcRect,
102 GrTexture* texture, 120 GrTexture* texture,
103 Gr1DKernelEffect::Direction direction, 121 Gr1DKernelEffect::Direction direction,
104 int radius, 122 int radius,
105 float sigma, 123 float sigma,
106 const SkRect* srcBounds, 124 const SkIRect* srcBounds,
107 const SkPoint& srcOffset) { 125 const SkIPoint& srcOffset) {
108 float bounds[2] = { 0.0f, 1.0f }; 126 float bounds[2] = { 0.0f, 1.0f };
109 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); 127 SkIRect dstRect = SkIRect::MakeWH(srcRect.width(), srcRect.height());
110 if (!srcBounds) { 128 if (!srcBounds) {
111 convolve_gaussian_1d(drawContext, clip, dstRect, srcOffset, texture, 129 convolve_gaussian_1d(drawContext, clip, dstRect, srcOffset, texture,
112 direction, radius, sigma, false, bounds); 130 direction, radius, sigma, false, bounds);
113 return; 131 return;
114 } 132 }
115 SkRect midRect = *srcBounds, leftRect, rightRect; 133 SkIRect midRect = *srcBounds, leftRect, rightRect;
116 midRect.offset(srcOffset); 134 midRect.offset(srcOffset);
117 SkIRect topRect, bottomRect; 135 SkIRect topRect, bottomRect;
118 SkScalar rad = SkIntToScalar(radius);
119 if (direction == Gr1DKernelEffect::kX_Direction) { 136 if (direction == Gr1DKernelEffect::kX_Direction) {
120 bounds[0] = SkScalarToFloat(srcBounds->left()) / texture->width(); 137 bounds[0] = SkIntToFloat(srcBounds->left()) / texture->width();
121 bounds[1] = SkScalarToFloat(srcBounds->right()) / texture->width(); 138 bounds[1] = SkIntToFloat(srcBounds->right()) / texture->width();
122 SkRect::MakeLTRB(0, 0, dstRect.right(), midRect.top()).roundOut(&topRect ); 139 topRect = SkIRect::MakeLTRB(0, 0, dstRect.right(), midRect.top());
123 SkRect::MakeLTRB(0, midRect.bottom(), dstRect.right(), dstRect.bottom()) 140 bottomRect = SkIRect::MakeLTRB(0, midRect.bottom(), dstRect.right(), dst Rect.bottom());
124 .roundOut(&bottomRect); 141 midRect.inset(radius, 0);
125 midRect.inset(rad, 0); 142 leftRect = SkIRect::MakeLTRB(0, midRect.top(), midRect.left(), midRect.b ottom());
126 leftRect = SkRect::MakeLTRB(0, midRect.top(), midRect.left(), midRect.bo ttom());
127 rightRect = 143 rightRect =
128 SkRect::MakeLTRB(midRect.right(), midRect.top(), dstRect.width(), mi dRect.bottom()); 144 SkIRect::MakeLTRB(midRect.right(), midRect.top(), dstRect.width(), m idRect.bottom());
129 dstRect.fTop = midRect.top(); 145 dstRect.fTop = midRect.top();
130 dstRect.fBottom = midRect.bottom(); 146 dstRect.fBottom = midRect.bottom();
131 } else { 147 } else {
132 bounds[0] = SkScalarToFloat(srcBounds->top()) / texture->height(); 148 bounds[0] = SkIntToFloat(srcBounds->top()) / texture->height();
133 bounds[1] = SkScalarToFloat(srcBounds->bottom()) / texture->height(); 149 bounds[1] = SkIntToFloat(srcBounds->bottom()) / texture->height();
134 SkRect::MakeLTRB(0, 0, midRect.left(), dstRect.bottom()).roundOut(&topRe ct); 150 topRect = SkIRect::MakeLTRB(0, 0, midRect.left(), dstRect.bottom());
135 SkRect::MakeLTRB(midRect.right(), 0, dstRect.right(), dstRect.bottom()) 151 bottomRect = SkIRect::MakeLTRB(midRect.right(), 0, dstRect.right(), dstR ect.bottom());
136 .roundOut(&bottomRect);; 152 midRect.inset(0, radius);
137 midRect.inset(0, rad); 153 leftRect = SkIRect::MakeLTRB(midRect.left(), 0, midRect.right(), midRect .top());
138 leftRect = SkRect::MakeLTRB(midRect.left(), 0, midRect.right(), midRect. top());
139 rightRect = 154 rightRect =
140 SkRect::MakeLTRB(midRect.left(), midRect.bottom(), midRect.right(), dstRect.height()); 155 SkIRect::MakeLTRB(midRect.left(), midRect.bottom(), midRect.right(), dstRect.height());
141 dstRect.fLeft = midRect.left(); 156 dstRect.fLeft = midRect.left();
142 dstRect.fRight = midRect.right(); 157 dstRect.fRight = midRect.right();
143 } 158 }
144 if (!topRect.isEmpty()) { 159 if (!topRect.isEmpty()) {
145 drawContext->clear(&topRect, 0, false); 160 drawContext->clear(&topRect, 0, false);
146 } 161 }
147 162
148 if (!bottomRect.isEmpty()) { 163 if (!bottomRect.isEmpty()) {
149 drawContext->clear(&bottomRect, 0, false); 164 drawContext->clear(&bottomRect, 0, false);
150 } 165 }
151 if (midRect.isEmpty()) { 166 if (midRect.isEmpty()) {
152 // Blur radius covers srcBounds; use bounds over entire draw 167 // Blur radius covers srcBounds; use bounds over entire draw
153 convolve_gaussian_1d(drawContext, clip, dstRect, srcOffset, texture, 168 convolve_gaussian_1d(drawContext, clip, dstRect, srcOffset, texture,
154 direction, radius, sigma, true, bounds); 169 direction, radius, sigma, true, bounds);
155 } else { 170 } else {
156 // Draw right and left margins with bounds; middle without. 171 // Draw right and left margins with bounds; middle without.
157 convolve_gaussian_1d(drawContext, clip, leftRect, srcOffset, texture, 172 convolve_gaussian_1d(drawContext, clip, leftRect, srcOffset, texture,
158 direction, radius, sigma, true, bounds); 173 direction, radius, sigma, true, bounds);
159 convolve_gaussian_1d(drawContext, clip, rightRect, srcOffset, texture, 174 convolve_gaussian_1d(drawContext, clip, rightRect, srcOffset, texture,
160 direction, radius, sigma, true, bounds); 175 direction, radius, sigma, true, bounds);
161 convolve_gaussian_1d(drawContext, clip, midRect, srcOffset, texture, 176 convolve_gaussian_1d(drawContext, clip, midRect, srcOffset, texture,
162 direction, radius, sigma, false, bounds); 177 direction, radius, sigma, false, bounds);
163 } 178 }
164 } 179 }
165 180
181 namespace SkGpuBlurUtils {
182
166 sk_sp<GrDrawContext> GaussianBlur(GrContext* context, 183 sk_sp<GrDrawContext> GaussianBlur(GrContext* context,
167 GrTexture* srcTexture, 184 GrTexture* srcTexture,
168 bool gammaCorrect, 185 bool gammaCorrect,
169 const SkRect& dstBounds, 186 const SkIRect& dstBounds,
170 const SkRect* srcBounds, 187 const SkIRect* srcBounds,
171 float sigmaX, 188 float sigmaX,
172 float sigmaY) { 189 float sigmaY) {
173 SkASSERT(context); 190 SkASSERT(context);
174 SkIRect clearRect; 191 SkIRect clearRect;
175 int scaleFactorX, radiusX; 192 int scaleFactorX, radiusX;
176 int scaleFactorY, radiusY; 193 int scaleFactorY, radiusY;
177 int maxTextureSize = context->caps()->maxTextureSize(); 194 int maxTextureSize = context->caps()->maxTextureSize();
178 sigmaX = adjust_sigma(sigmaX, maxTextureSize, &scaleFactorX, &radiusX); 195 sigmaX = adjust_sigma(sigmaX, maxTextureSize, &scaleFactorX, &radiusX);
179 sigmaY = adjust_sigma(sigmaY, maxTextureSize, &scaleFactorY, &radiusY); 196 sigmaY = adjust_sigma(sigmaY, maxTextureSize, &scaleFactorY, &radiusY);
197 SkASSERT(sigmaX || sigmaY);
180 198
181 SkPoint srcOffset = SkPoint::Make(-dstBounds.x(), -dstBounds.y()); 199 SkIPoint srcOffset = SkIPoint::Make(-dstBounds.x(), -dstBounds.y());
182 SkRect localDstBounds = SkRect::MakeWH(dstBounds.width(), dstBounds.height() ); 200 SkIRect localDstBounds = SkIRect::MakeWH(dstBounds.width(), dstBounds.height ());
183 SkRect localSrcBounds; 201 SkIRect localSrcBounds;
184 SkRect srcRect; 202 SkIRect srcRect;
185 if (srcBounds) { 203 if (srcBounds) {
186 srcRect = localSrcBounds = *srcBounds; 204 srcRect = localSrcBounds = *srcBounds;
187 srcRect.offset(srcOffset); 205 srcRect.offset(srcOffset);
188 srcBounds = &localSrcBounds; 206 srcBounds = &localSrcBounds;
189 } else { 207 } else {
190 srcRect = localDstBounds; 208 srcRect = localDstBounds;
191 } 209 }
192 210
193 scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY); 211 scale_irect_roundout(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY);
194 srcRect.roundOut(&srcRect); 212 scale_irect(&srcRect, scaleFactorX, scaleFactorY);
195 scale_rect(&srcRect, static_cast<float>(scaleFactorX),
196 static_cast<float>(scaleFactorY));
197 213
198 // setup new clip 214 // setup new clip
199 GrClip clip(localDstBounds); 215 GrClip clip(localDstBounds);
200 216
201 SkASSERT(kBGRA_8888_GrPixelConfig == srcTexture->config() || 217 SkASSERT(kBGRA_8888_GrPixelConfig == srcTexture->config() ||
202 kRGBA_8888_GrPixelConfig == srcTexture->config() || 218 kRGBA_8888_GrPixelConfig == srcTexture->config() ||
203 kSRGBA_8888_GrPixelConfig == srcTexture->config() || 219 kSRGBA_8888_GrPixelConfig == srcTexture->config() ||
204 kSBGRA_8888_GrPixelConfig == srcTexture->config() || 220 kSBGRA_8888_GrPixelConfig == srcTexture->config() ||
205 kAlpha_8_GrPixelConfig == srcTexture->config()); 221 kAlpha_8_GrPixelConfig == srcTexture->config());
206 222
207 const int width = SkScalarFloorToInt(dstBounds.width()); 223 const int width = dstBounds.width();
208 const int height = SkScalarFloorToInt(dstBounds.height()); 224 const int height = dstBounds.height();
209 const GrPixelConfig config = srcTexture->config(); 225 const GrPixelConfig config = srcTexture->config();
210 226
211 const SkSurfaceProps props(gammaCorrect ? SkSurfaceProps::kGammaCorrect_Flag : 0, 227 const SkSurfaceProps props(gammaCorrect ? SkSurfaceProps::kGammaCorrect_Flag : 0,
212 SkSurfaceProps::kLegacyFontHost_InitType); 228 SkSurfaceProps::kLegacyFontHost_InitType);
213 229
214 sk_sp<GrDrawContext> dstDrawContext(context->newDrawContext(SkBackingFit::kA pprox, 230 sk_sp<GrDrawContext> dstDrawContext(context->newDrawContext(SkBackingFit::kA pprox,
215 width, height, c onfig, 231 width, height, c onfig,
216 0, kDefault_GrSu rfaceOrigin, 232 0, kDefault_GrSu rfaceOrigin,
217 &props)); 233 &props));
218 if (!dstDrawContext) { 234 if (!dstDrawContext) {
(...skipping 16 matching lines...) Expand all
235 sk_sp<GrDrawContext> tmpDrawContext(context->newDrawContext(SkBackingFit::kA pprox, 251 sk_sp<GrDrawContext> tmpDrawContext(context->newDrawContext(SkBackingFit::kA pprox,
236 width, height, c onfig, 252 width, height, c onfig,
237 0, kDefault_GrSu rfaceOrigin, 253 0, kDefault_GrSu rfaceOrigin,
238 &props)); 254 &props));
239 if (!tmpDrawContext) { 255 if (!tmpDrawContext) {
240 return nullptr; 256 return nullptr;
241 } 257 }
242 258
243 sk_sp<GrDrawContext> srcDrawContext; 259 sk_sp<GrDrawContext> srcDrawContext;
244 260
261 SkASSERT(SkIsPow2(scaleFactorX) && SkIsPow2(scaleFactorY));
262
245 for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) { 263 for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) {
246 GrPaint paint; 264 GrPaint paint;
247 paint.setGammaCorrect(gammaCorrect); 265 paint.setGammaCorrect(gammaCorrect);
248 SkMatrix matrix; 266 SkMatrix matrix;
249 matrix.setIDiv(srcTexture->width(), srcTexture->height()); 267 matrix.setIDiv(srcTexture->width(), srcTexture->height());
250 SkRect dstRect(srcRect); 268 SkIRect dstRect(srcRect);
251 if (srcBounds && i == 1) { 269 if (srcBounds && i == 1) {
252 SkRect domain; 270 SkRect domain;
253 matrix.mapRect(&domain, *srcBounds); 271 matrix.mapRect(&domain, SkRect::Make(*srcBounds));
254 domain.inset((i < scaleFactorX) ? SK_ScalarHalf / srcTexture->width( ) : 0.0f, 272 domain.inset((i < scaleFactorX) ? SK_ScalarHalf / srcTexture->width( ) : 0.0f,
255 (i < scaleFactorY) ? SK_ScalarHalf / srcTexture->height () : 0.0f); 273 (i < scaleFactorY) ? SK_ScalarHalf / srcTexture->height () : 0.0f);
256 sk_sp<const GrFragmentProcessor> fp(GrTextureDomainEffect::Create( 274 sk_sp<const GrFragmentProcessor> fp(GrTextureDomainEffect::Create(
257 srcTexture, 275 srcTexture,
258 matrix, 276 matrix,
259 domain, 277 domain,
260 GrTextureDomain::kDecal_ Mode, 278 GrTextureDomain::kDecal_ Mode,
261 GrTextureParams::kBilerp _FilterMode)); 279 GrTextureParams::kBilerp _FilterMode));
262 paint.addColorFragmentProcessor(fp.get()); 280 paint.addColorFragmentProcessor(fp.get());
263 srcRect.offset(-srcOffset); 281 srcRect.offset(-srcOffset);
264 srcOffset.set(0, 0); 282 srcOffset.set(0, 0);
265 } else { 283 } else {
266 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::k Bilerp_FilterMode); 284 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::k Bilerp_FilterMode);
267 paint.addColorTextureProcessor(srcTexture, matrix, params); 285 paint.addColorTextureProcessor(srcTexture, matrix, params);
268 } 286 }
269 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); 287 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
270 scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f, 288 shrink_irect_by_2(&dstRect, i < scaleFactorX, i < scaleFactorY);
271 i < scaleFactorY ? 0.5f : 1.0f);
272 289
273 dstDrawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcR ect); 290 dstDrawContext->fillRectToRect(clip, paint, SkMatrix::I(),
291 SkRect::Make(dstRect), SkRect::Make(srcRe ct));
274 292
275 srcDrawContext = dstDrawContext; 293 srcDrawContext = dstDrawContext;
276 srcRect = dstRect; 294 srcRect = dstRect;
277 srcTexture = srcDrawContext->asTexture().release(); 295 srcTexture = srcDrawContext->asTexture().release();
278 SkTSwap(dstDrawContext, tmpDrawContext); 296 SkTSwap(dstDrawContext, tmpDrawContext);
279 localSrcBounds = srcRect; 297 localSrcBounds = srcRect;
280 } 298 }
281 299
282 srcRect = localDstBounds; 300 srcRect = localDstBounds;
283 301 scale_irect_roundout(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY);
284 scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY);
285 srcRect.roundOut(&srcRect);
286 SkIRect srcIRect = srcRect.roundOut();
287 if (sigmaX > 0.0f) { 302 if (sigmaX > 0.0f) {
288 if (scaleFactorX > 1) { 303 if (scaleFactorX > 1) {
289 SkASSERT(srcDrawContext); 304 SkASSERT(srcDrawContext);
290 305
291 // Clear out a radius to the right of the srcRect to prevent the 306 // Clear out a radius to the right of the srcRect to prevent the
292 // X convolution from reading garbage. 307 // X convolution from reading garbage.
293 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, 308 clearRect = SkIRect::MakeXYWH(srcRect.fRight, srcRect.fTop,
294 radiusX, srcIRect.height()); 309 radiusX, srcRect.height());
295 srcDrawContext->clear(&clearRect, 0x0, false); 310 srcDrawContext->clear(&clearRect, 0x0, false);
296 } 311 }
297 312
298 convolve_gaussian(dstDrawContext.get(), clip, srcRect, 313 convolve_gaussian(dstDrawContext.get(), clip, srcRect,
299 srcTexture, Gr1DKernelEffect::kX_Direction, radiusX, s igmaX, 314 srcTexture, Gr1DKernelEffect::kX_Direction, radiusX, s igmaX,
300 srcBounds, srcOffset); 315 srcBounds, srcOffset);
301 srcDrawContext = dstDrawContext; 316 srcDrawContext = dstDrawContext;
302 srcTexture = srcDrawContext->asTexture().release(); 317 srcTexture = srcDrawContext->asTexture().release();
303 srcRect.offsetTo(0, 0); 318 srcRect.offsetTo(0, 0);
304 SkTSwap(dstDrawContext, tmpDrawContext); 319 SkTSwap(dstDrawContext, tmpDrawContext);
305 localSrcBounds = srcRect; 320 localSrcBounds = srcRect;
306 srcOffset.set(0, 0); 321 srcOffset.set(0, 0);
307 } 322 }
308 323
309 if (sigmaY > 0.0f) { 324 if (sigmaY > 0.0f) {
310 if (scaleFactorY > 1 || sigmaX > 0.0f) { 325 if (scaleFactorY > 1 || sigmaX > 0.0f) {
311 SkASSERT(srcDrawContext); 326 SkASSERT(srcDrawContext);
312 327
313 // Clear out a radius below the srcRect to prevent the Y 328 // Clear out a radius below the srcRect to prevent the Y
314 // convolution from reading garbage. 329 // convolution from reading garbage.
315 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, 330 clearRect = SkIRect::MakeXYWH(srcRect.fLeft, srcRect.fBottom,
316 srcIRect.width(), radiusY); 331 srcRect.width(), radiusY);
317 srcDrawContext->clear(&clearRect, 0x0, false); 332 srcDrawContext->clear(&clearRect, 0x0, false);
318 } 333 }
319 334
320 convolve_gaussian(dstDrawContext.get(), clip, srcRect, 335 convolve_gaussian(dstDrawContext.get(), clip, srcRect,
321 srcTexture, Gr1DKernelEffect::kY_Direction, radiusY, s igmaY, 336 srcTexture, Gr1DKernelEffect::kY_Direction, radiusY, s igmaY,
322 srcBounds, srcOffset); 337 srcBounds, srcOffset);
323 338
324 srcDrawContext = dstDrawContext; 339 srcDrawContext = dstDrawContext;
325 srcRect.offsetTo(0, 0); 340 srcRect.offsetTo(0, 0);
326 SkTSwap(dstDrawContext, tmpDrawContext); 341 SkTSwap(dstDrawContext, tmpDrawContext);
327 } 342 }
328 343
329 SkASSERT(srcDrawContext); 344 SkASSERT(srcDrawContext);
330 srcTexture = nullptr; // we don't use this from here on out 345 srcTexture = nullptr; // we don't use this from here on out
331 srcIRect = srcRect.roundOut();
332 346
333 if (scaleFactorX > 1 || scaleFactorY > 1) { 347 if (scaleFactorX > 1 || scaleFactorY > 1) {
334 // Clear one pixel to the right and below, to accommodate bilinear upsam pling. 348 // Clear one pixel to the right and below, to accommodate bilinear upsam pling.
335 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, srcIRect .width() + 1, 1); 349 clearRect = SkIRect::MakeXYWH(srcRect.fLeft, srcRect.fBottom, srcRect.wi dth() + 1, 1);
336 srcDrawContext->clear(&clearRect, 0x0, false); 350 srcDrawContext->clear(&clearRect, 0x0, false);
337 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, 1, srcIRec t.height()); 351 clearRect = SkIRect::MakeXYWH(srcRect.fRight, srcRect.fTop, 1, srcRect.h eight());
338 srcDrawContext->clear(&clearRect, 0x0, false); 352 srcDrawContext->clear(&clearRect, 0x0, false);
339 353
340 SkMatrix matrix; 354 SkMatrix matrix;
341 matrix.setIDiv(srcDrawContext->width(), srcDrawContext->height()); 355 matrix.setIDiv(srcDrawContext->width(), srcDrawContext->height());
342 356
343 GrPaint paint; 357 GrPaint paint;
344 paint.setGammaCorrect(gammaCorrect); 358 paint.setGammaCorrect(gammaCorrect);
345 // FIXME: this should be mitchell, not bilinear. 359 // FIXME: this should be mitchell, not bilinear.
346 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBile rp_FilterMode); 360 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBile rp_FilterMode);
347 paint.addColorTextureProcessor(srcDrawContext->asTexture().release(), ma trix, params); 361 paint.addColorTextureProcessor(srcDrawContext->asTexture().release(), ma trix, params);
348 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); 362 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
349 363
350 SkRect dstRect(srcRect); 364 SkIRect dstRect(srcRect);
351 scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY); 365 scale_irect(&dstRect, scaleFactorX, scaleFactorY);
352 366
353 dstDrawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcR ect); 367 dstDrawContext->fillRectToRect(clip, paint, SkMatrix::I(),
368 SkRect::Make(dstRect), SkRect::Make(srcRe ct));
354 369
355 srcDrawContext = dstDrawContext; 370 srcDrawContext = dstDrawContext;
356 srcRect = dstRect; 371 srcRect = dstRect;
357 SkTSwap(dstDrawContext, tmpDrawContext); 372 SkTSwap(dstDrawContext, tmpDrawContext);
358 } 373 }
359 374
360 return srcDrawContext; 375 return srcDrawContext;
361 } 376 }
377
378 }
379
362 #endif 380 #endif
363 381
364 }
OLDNEW
« no previous file with comments | « src/effects/SkGpuBlurUtils.h ('k') | src/gpu/GrBlurUtils.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698