OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "SkMaskFilter.h" | 10 #include "SkMaskFilter.h" |
11 #include "SkBlitter.h" | 11 #include "SkBlitter.h" |
12 #include "SkDraw.h" | 12 #include "SkDraw.h" |
| 13 #include "SkMaskCache.h" |
13 #include "SkRasterClip.h" | 14 #include "SkRasterClip.h" |
14 #include "SkRRect.h" | 15 #include "SkRRect.h" |
15 #include "SkTypes.h" | 16 #include "SkTypes.h" |
16 | 17 |
17 #if SK_SUPPORT_GPU | 18 #if SK_SUPPORT_GPU |
18 #include "GrTexture.h" | 19 #include "GrTexture.h" |
19 #include "SkGr.h" | 20 #include "SkGr.h" |
20 #include "SkGrPixelRef.h" | 21 #include "SkGrPixelRef.h" |
21 #endif | 22 #endif |
22 | 23 |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 clip.getBounds(), | 217 clip.getBounds(), |
217 &patch)) { | 218 &patch)) { |
218 SkASSERT(NULL == patch.fMask.fImage); | 219 SkASSERT(NULL == patch.fMask.fImage); |
219 return false; | 220 return false; |
220 } | 221 } |
221 draw_nine(patch.fMask, patch.fOuterRect, patch.fCenter, true, clip, blitter)
; | 222 draw_nine(patch.fMask, patch.fOuterRect, patch.fCenter, true, clip, blitter)
; |
222 SkMask::FreeImage(patch.fMask.fImage); | 223 SkMask::FreeImage(patch.fMask.fImage); |
223 return true; | 224 return true; |
224 } | 225 } |
225 | 226 |
| 227 static bool rect_exceeds(const SkRect& r, SkScalar v) { |
| 228 return r.fLeft < -v || r.fTop < -v || r.fRight > v || r.fBottom > v || |
| 229 r.width() > v || r.height() > v; |
| 230 } |
| 231 |
226 bool SkMaskFilter::filterPath(const SkPath& devPath, const SkMatrix& matrix, | 232 bool SkMaskFilter::filterPath(const SkPath& devPath, const SkMatrix& matrix, |
227 const SkRasterClip& clip, SkBlitter* blitter, | 233 const SkRasterClip& clip, SkBlitter* blitter, |
228 SkPaint::Style style) const { | 234 SkPaint::Style style) const { |
229 SkRect rects[2]; | 235 SkRect rects[2]; |
230 int rectCount = 0; | 236 int rectCount = 0; |
231 if (SkPaint::kFill_Style == style) { | 237 if (SkPaint::kFill_Style == style) { |
232 rectCount = countNestedRects(devPath, rects); | 238 rectCount = countNestedRects(devPath, rects); |
233 } | 239 } |
234 if (rectCount > 0) { | 240 if (rectCount > 0) { |
235 NinePatch patch; | 241 NinePatch patch; |
(...skipping 20 matching lines...) Expand all Loading... |
256 | 262 |
257 SkMask srcM, dstM; | 263 SkMask srcM, dstM; |
258 | 264 |
259 if (!SkDraw::DrawToMask(devPath, &clip.getBounds(), this, &matrix, &srcM, | 265 if (!SkDraw::DrawToMask(devPath, &clip.getBounds(), this, &matrix, &srcM, |
260 SkMask::kComputeBoundsAndRenderImage_CreateMode, | 266 SkMask::kComputeBoundsAndRenderImage_CreateMode, |
261 style)) { | 267 style)) { |
262 return false; | 268 return false; |
263 } | 269 } |
264 SkAutoMaskFreeImage autoSrc(srcM.fImage); | 270 SkAutoMaskFreeImage autoSrc(srcM.fImage); |
265 | 271 |
266 if (!this->filterMask(&dstM, srcM, matrix, NULL)) { | 272 // Don't actually do the blur the first time, just compute the correct bound
s. |
| 273 SkMask tmpSrc, tmpDst; |
| 274 tmpSrc = srcM; |
| 275 tmpSrc.fImage = NULL; |
| 276 if (!this->filterMask(&tmpDst, tmpSrc, matrix, NULL)) { |
267 return false; | 277 return false; |
268 } | 278 } |
269 SkAutoMaskFreeImage autoDst(dstM.fImage); | 279 |
| 280 BlurRec rec; |
| 281 uint8_t* maskImage = NULL; |
| 282 |
| 283 // Try to cache blur effect applied on a path which is consist of 1 or 2 rec
ts. |
| 284 // Dst mask of unclipped path is saved in the cache. |
| 285 // Actual clipped dst mask is extracted from the unclipped dst mask accordin
g bounds. |
| 286 if (this->asABlur(&rec) && rectCount && !rect_exceeds(rects[0], SkIntToScala
r(32767))) { |
| 287 SkMask srcMUnclipped, dstMUnclipped; |
| 288 SkScalar scaledSigma = matrix.mapRadius(rec.fSigma); |
| 289 |
| 290 if (SkMaskCache::FindAndCopy(scaledSigma, rec.fStyle, rec.fQuality, |
| 291 rects, rectCount, &dstMUnclipped)) { |
| 292 if (!SkDraw::DrawToMask(devPath, NULL, this, &matrix, &srcMUnclipped
, |
| 293 SkMask::kJustComputeBounds_CreateMode, |
| 294 style)) { |
| 295 return false; |
| 296 } |
| 297 srcMUnclipped.fFormat = SkMask::kA8_Format; |
| 298 srcMUnclipped.fRowBytes = srcMUnclipped.fBounds.width(); |
| 299 } else { |
| 300 if (!SkDraw::DrawToMask(devPath, NULL, this, &matrix, &srcMUnclipped
, |
| 301 SkMask::kComputeBoundsAndRenderImage_CreateM
ode, |
| 302 style)) { |
| 303 return false; |
| 304 } |
| 305 SkAutoMaskFreeImage autoSrcUnclipped(srcMUnclipped.fImage); |
| 306 if (!this->filterMask(&dstMUnclipped, srcMUnclipped, matrix, NULL))
{ |
| 307 return false; |
| 308 } |
| 309 dstMUnclipped.fBounds.offsetTo(0, 0); |
| 310 SkMaskCache::AddAndCopy(scaledSigma, rec.fStyle, rec.fQuality, |
| 311 rects, rectCount, dstMUnclipped); |
| 312 } |
| 313 |
| 314 SkMask tmpSrcUnclipped, tmpDstUnclipped; |
| 315 tmpSrcUnclipped = srcMUnclipped; |
| 316 tmpSrcUnclipped.fImage = NULL; |
| 317 if (!this->filterMask(&tmpDstUnclipped, tmpSrcUnclipped, matrix, NULL))
{ |
| 318 return false; |
| 319 } |
| 320 SkASSERT(tmpDstUnclipped.fBounds.contains(tmpDst.fBounds)); |
| 321 |
| 322 dstM.fBounds = tmpDst.fBounds; |
| 323 dstM.fBounds.offsetTo(tmpDst.fBounds.fLeft - tmpDstUnclipped.fBounds.fLe
ft, |
| 324 tmpDst.fBounds.fTop - tmpDstUnclipped.fBounds.fTop
); |
| 325 extractMaskSubset(dstMUnclipped, &dstM); |
| 326 dstM.fBounds.offsetTo(tmpDst.fBounds.fLeft, tmpDst.fBounds.fTop); |
| 327 |
| 328 maskImage = dstMUnclipped.fImage; |
| 329 } else { |
| 330 if (!this->filterMask(&dstM, srcM, matrix, NULL)) { |
| 331 return false; |
| 332 } |
| 333 |
| 334 maskImage = dstM.fImage; |
| 335 } |
| 336 |
| 337 SkAutoMaskFreeImage autoDst(maskImage); |
270 | 338 |
271 // if we get here, we need to (possibly) resolve the clip and blitter | 339 // if we get here, we need to (possibly) resolve the clip and blitter |
272 SkAAClipBlitterWrapper wrapper(clip, blitter); | 340 SkAAClipBlitterWrapper wrapper(clip, blitter); |
273 blitter = wrapper.getBlitter(); | 341 blitter = wrapper.getBlitter(); |
274 | 342 |
275 SkRegion::Cliperator clipper(wrapper.getRgn(), dstM.fBounds); | 343 SkRegion::Cliperator clipper(wrapper.getRgn(), dstM.fBounds); |
276 | 344 |
277 if (!clipper.done()) { | 345 if (!clipper.done()) { |
278 const SkIRect& cr = clipper.rect(); | 346 const SkIRect& cr = clipper.rect(); |
279 do { | 347 do { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 srcM.fRowBytes = 0; | 411 srcM.fRowBytes = 0; |
344 srcM.fFormat = SkMask::kA8_Format; | 412 srcM.fFormat = SkMask::kA8_Format; |
345 | 413 |
346 SkIPoint margin; // ignored | 414 SkIPoint margin; // ignored |
347 if (this->filterMask(&dstM, srcM, SkMatrix::I(), &margin)) { | 415 if (this->filterMask(&dstM, srcM, SkMatrix::I(), &margin)) { |
348 dst->set(dstM.fBounds); | 416 dst->set(dstM.fBounds); |
349 } else { | 417 } else { |
350 dst->set(srcM.fBounds); | 418 dst->set(srcM.fBounds); |
351 } | 419 } |
352 } | 420 } |
OLD | NEW |