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