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