OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2008 The Android Open Source Project | 2 * Copyright 2008 The Android Open Source Project |
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 "SkBitmapDevice.h" | 8 #include "SkBitmapDevice.h" |
9 #include "SkCanvas.h" | 9 #include "SkCanvas.h" |
10 #include "SkCanvasPriv.h" | 10 #include "SkCanvasPriv.h" |
(...skipping 20 matching lines...) Expand all Loading... |
31 #include "SkTextFormatParams.h" | 31 #include "SkTextFormatParams.h" |
32 #include "SkTLazy.h" | 32 #include "SkTLazy.h" |
33 #include "SkTraceEvent.h" | 33 #include "SkTraceEvent.h" |
34 | 34 |
35 #include <new> | 35 #include <new> |
36 | 36 |
37 #if SK_SUPPORT_GPU | 37 #if SK_SUPPORT_GPU |
38 #include "GrRenderTarget.h" | 38 #include "GrRenderTarget.h" |
39 #endif | 39 #endif |
40 | 40 |
| 41 #ifndef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED |
| 42 #define SK_SUPPORT_SRC_BOUNDS_BLOAT_FOR_IMAGEFILTERS |
| 43 #endif |
| 44 |
41 /* | 45 /* |
42 * Return true if the drawing this rect would hit every pixels in the canvas. | 46 * Return true if the drawing this rect would hit every pixels in the canvas. |
43 * | 47 * |
44 * Returns false if | 48 * Returns false if |
45 * - rect does not contain the canvas' bounds | 49 * - rect does not contain the canvas' bounds |
46 * - paint is not fill | 50 * - paint is not fill |
47 * - paint would blur or otherwise change the coverage of the rect | 51 * - paint would blur or otherwise change the coverage of the rect |
48 */ | 52 */ |
49 bool SkCanvas::wouldOverwriteEntireSurface(const SkRect* rect, const SkPaint* pa
int, | 53 bool SkCanvas::wouldOverwriteEntireSurface(const SkRect* rect, const SkPaint* pa
int, |
50 ShaderOverrideOpacity overrideOpacity
) const { | 54 ShaderOverrideOpacity overrideOpacity
) const { |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
401 // there is no existing paint colorfilter, so we can just return the ima
gefilter's | 405 // there is no existing paint colorfilter, so we can just return the ima
gefilter's |
402 return imgCF; | 406 return imgCF; |
403 } | 407 } |
404 | 408 |
405 // The paint has both a colorfilter(paintCF) and an imagefilter-which-is-a-c
olorfilter(imgCF) | 409 // The paint has both a colorfilter(paintCF) and an imagefilter-which-is-a-c
olorfilter(imgCF) |
406 // and we need to combine them into a single colorfilter. | 410 // and we need to combine them into a single colorfilter. |
407 SkAutoTUnref<SkColorFilter> autoImgCF(imgCF); | 411 SkAutoTUnref<SkColorFilter> autoImgCF(imgCF); |
408 return SkColorFilter::CreateComposeFilter(imgCF, paintCF); | 412 return SkColorFilter::CreateComposeFilter(imgCF, paintCF); |
409 } | 413 } |
410 | 414 |
| 415 /** |
| 416 * There are many bounds in skia. A circle's bounds is just its center extended
by its radius. |
| 417 * However, if we stroke a circle, then the "bounds" of that is larger, since it
will now draw |
| 418 * outside of its raw-bounds by 1/2 the stroke width. SkPaint has lots of optio
nal |
| 419 * effects/attributes that can modify the effective bounds of a given primitive
-- maskfilters, |
| 420 * patheffects, stroking, etc. This function takes a raw bounds and a paint, an
d returns the |
| 421 * conservative "effective" bounds based on the settings in the paint... with on
e exception. This |
| 422 * function does *not* look at the imagefilter, which can also modify the effect
ive bounds. It is |
| 423 * deliberately ignored. |
| 424 */ |
| 425 static const SkRect& apply_paint_to_bounds_sans_imagefilter(const SkPaint& paint
, |
| 426 const SkRect& rawBou
nds, |
| 427 SkRect* storage) { |
| 428 SkPaint tmpUnfiltered(paint); |
| 429 tmpUnfiltered.setImageFilter(nullptr); |
| 430 if (tmpUnfiltered.canComputeFastBounds()) { |
| 431 return tmpUnfiltered.computeFastBounds(rawBounds, storage); |
| 432 } else { |
| 433 return rawBounds; |
| 434 } |
| 435 } |
| 436 |
411 class AutoDrawLooper { | 437 class AutoDrawLooper { |
412 public: | 438 public: |
| 439 // "rawBounds" is the original bounds of the primitive about to be drawn, un
modified by the |
| 440 // paint. It's used to determine the size of the offscreen layer for filters
. |
| 441 // If null, the clip will be used instead. |
413 AutoDrawLooper(SkCanvas* canvas, const SkSurfaceProps& props, const SkPaint&
paint, | 442 AutoDrawLooper(SkCanvas* canvas, const SkSurfaceProps& props, const SkPaint&
paint, |
414 bool skipLayerForImageFilter = false, | 443 bool skipLayerForImageFilter = false, |
415 const SkRect* bounds = nullptr) : fOrigPaint(paint) { | 444 const SkRect* rawBounds = nullptr) : fOrigPaint(paint) { |
416 fCanvas = canvas; | 445 fCanvas = canvas; |
417 fFilter = canvas->getDrawFilter(); | 446 fFilter = canvas->getDrawFilter(); |
418 fPaint = &fOrigPaint; | 447 fPaint = &fOrigPaint; |
419 fSaveCount = canvas->getSaveCount(); | 448 fSaveCount = canvas->getSaveCount(); |
420 fTempLayerForImageFilter = false; | 449 fTempLayerForImageFilter = false; |
421 fDone = false; | 450 fDone = false; |
422 | 451 |
423 SkColorFilter* simplifiedCF = image_to_color_filter(fOrigPaint); | 452 SkColorFilter* simplifiedCF = image_to_color_filter(fOrigPaint); |
424 if (simplifiedCF) { | 453 if (simplifiedCF) { |
425 SkPaint* paint = set_if_needed(&fLazyPaintInit, fOrigPaint); | 454 SkPaint* paint = set_if_needed(&fLazyPaintInit, fOrigPaint); |
(...skipping 14 matching lines...) Expand all Loading... |
440 * return (fPaint). We then draw the primitive (using srcover)
into a cleared | 469 * return (fPaint). We then draw the primitive (using srcover)
into a cleared |
441 * buffer/surface. | 470 * buffer/surface. |
442 * 3. Restore the layer created in #1 | 471 * 3. Restore the layer created in #1 |
443 * The imagefilter is passed the buffer/surface from the layer
(now filled with the | 472 * The imagefilter is passed the buffer/surface from the layer
(now filled with the |
444 * src pixels of the primitive). It returns a new "filtered" bu
ffer, which we | 473 * src pixels of the primitive). It returns a new "filtered" bu
ffer, which we |
445 * draw onto the previous layer using the xfermode from the ori
ginal paint. | 474 * draw onto the previous layer using the xfermode from the ori
ginal paint. |
446 */ | 475 */ |
447 SkPaint tmp; | 476 SkPaint tmp; |
448 tmp.setImageFilter(fPaint->getImageFilter()); | 477 tmp.setImageFilter(fPaint->getImageFilter()); |
449 tmp.setXfermode(fPaint->getXfermode()); | 478 tmp.setXfermode(fPaint->getXfermode()); |
450 (void)canvas->internalSaveLayer(bounds, &tmp, SkCanvas::kARGB_ClipLa
yer_SaveFlag, | 479 #ifndef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED |
| 480 SkRect storage; |
| 481 if (rawBounds) { |
| 482 // Make rawBounds include all paint outsets except for those due
to image filters. |
| 483 rawBounds = &apply_paint_to_bounds_sans_imagefilter(*fPaint, *ra
wBounds, &storage); |
| 484 } |
| 485 #endif |
| 486 (void)canvas->internalSaveLayer(rawBounds, &tmp, SkCanvas::kARGB_Cli
pLayer_SaveFlag, |
451 SkCanvas::kFullLayer_SaveLayerStrate
gy); | 487 SkCanvas::kFullLayer_SaveLayerStrate
gy); |
452 fTempLayerForImageFilter = true; | 488 fTempLayerForImageFilter = true; |
453 // we remove the imagefilter/xfermode inside doNext() | 489 // we remove the imagefilter/xfermode inside doNext() |
454 } | 490 } |
455 | 491 |
456 if (SkDrawLooper* looper = paint.getLooper()) { | 492 if (SkDrawLooper* looper = paint.getLooper()) { |
457 void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Contex
t>( | 493 void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Contex
t>( |
458 looper->contextSize()); | 494 looper->contextSize()); |
459 fLooperContext = looper->createContext(canvas, buffer); | 495 fLooperContext = looper->createContext(canvas, buffer); |
460 fIsSimple = false; | 496 fIsSimple = false; |
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1012 | 1048 |
1013 bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags, | 1049 bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags, |
1014 SkIRect* intersection, const SkImageFilter* imageF
ilter) { | 1050 SkIRect* intersection, const SkImageFilter* imageF
ilter) { |
1015 SkIRect clipBounds; | 1051 SkIRect clipBounds; |
1016 if (!this->getClipDeviceBounds(&clipBounds)) { | 1052 if (!this->getClipDeviceBounds(&clipBounds)) { |
1017 return false; | 1053 return false; |
1018 } | 1054 } |
1019 | 1055 |
1020 const SkMatrix& ctm = fMCRec->fMatrix; // this->getTotalMatrix() | 1056 const SkMatrix& ctm = fMCRec->fMatrix; // this->getTotalMatrix() |
1021 | 1057 |
| 1058 // This is a temporary hack, until individual filters can do their own |
| 1059 // bloating, when this will be removed. |
| 1060 #ifdef SK_SUPPORT_SRC_BOUNDS_BLOAT_FOR_IMAGEFILTERS |
| 1061 SkRect storage; |
| 1062 #endif |
1022 if (imageFilter) { | 1063 if (imageFilter) { |
1023 imageFilter->filterBounds(clipBounds, ctm, &clipBounds); | 1064 imageFilter->filterBounds(clipBounds, ctm, &clipBounds); |
| 1065 #ifdef SK_SUPPORT_SRC_BOUNDS_BLOAT_FOR_IMAGEFILTERS |
| 1066 if (bounds && imageFilter->canComputeFastBounds()) { |
| 1067 imageFilter->computeFastBounds(*bounds, &storage); |
| 1068 bounds = &storage; |
| 1069 } else { |
| 1070 bounds = nullptr; |
| 1071 } |
| 1072 #endif |
1024 } | 1073 } |
1025 SkIRect ir; | 1074 SkIRect ir; |
1026 if (bounds) { | 1075 if (bounds) { |
1027 SkRect r; | 1076 SkRect r; |
1028 | 1077 |
1029 ctm.mapRect(&r, *bounds); | 1078 ctm.mapRect(&r, *bounds); |
1030 r.roundOut(&ir); | 1079 r.roundOut(&ir); |
1031 // early exit if the layer's bounds are clipped out | 1080 // early exit if the layer's bounds are clipped out |
1032 if (!ir.intersect(clipBounds)) { | 1081 if (!ir.intersect(clipBounds)) { |
1033 if (bounds_affects_clip(flags)) { | 1082 if (bounds_affects_clip(flags)) { |
(...skipping 924 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1958 | 2007 |
1959 SkRect r, storage; | 2008 SkRect r, storage; |
1960 const SkRect* bounds = nullptr; | 2009 const SkRect* bounds = nullptr; |
1961 if (paint.canComputeFastBounds()) { | 2010 if (paint.canComputeFastBounds()) { |
1962 // special-case 2 points (common for drawing a single line) | 2011 // special-case 2 points (common for drawing a single line) |
1963 if (2 == count) { | 2012 if (2 == count) { |
1964 r.set(pts[0], pts[1]); | 2013 r.set(pts[0], pts[1]); |
1965 } else { | 2014 } else { |
1966 r.set(pts, SkToInt(count)); | 2015 r.set(pts, SkToInt(count)); |
1967 } | 2016 } |
| 2017 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED |
1968 bounds = &paint.computeFastStrokeBounds(r, &storage); | 2018 bounds = &paint.computeFastStrokeBounds(r, &storage); |
1969 if (this->quickReject(*bounds)) { | 2019 if (this->quickReject(*bounds)) { |
1970 return; | 2020 return; |
1971 } | 2021 } |
| 2022 #else |
| 2023 if (this->quickReject(paint.computeFastStrokeBounds(r, &storage))) { |
| 2024 return; |
| 2025 } |
| 2026 bounds = &r; |
| 2027 #endif |
1972 } | 2028 } |
1973 | 2029 |
1974 SkASSERT(pts != nullptr); | 2030 SkASSERT(pts != nullptr); |
1975 | 2031 |
1976 LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds) | 2032 LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds) |
1977 | 2033 |
1978 while (iter.next()) { | 2034 while (iter.next()) { |
1979 iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint()); | 2035 iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint()); |
1980 } | 2036 } |
1981 | 2037 |
1982 LOOPER_END | 2038 LOOPER_END |
1983 } | 2039 } |
1984 | 2040 |
1985 void SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) { | 2041 void SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) { |
1986 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRect()"); | 2042 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRect()"); |
1987 SkRect storage; | 2043 SkRect storage; |
1988 const SkRect* bounds = nullptr; | 2044 const SkRect* bounds = nullptr; |
1989 if (paint.canComputeFastBounds()) { | 2045 if (paint.canComputeFastBounds()) { |
1990 // Skia will draw an inverted rect, because it explicitly "sorts" it dow
nstream. | 2046 // Skia will draw an inverted rect, because it explicitly "sorts" it dow
nstream. |
1991 // To prevent accidental rejecting at this stage, we have to sort it bef
ore we check. | 2047 // To prevent accidental rejecting at this stage, we have to sort it bef
ore we check. |
1992 SkRect tmp(r); | 2048 SkRect tmp(r); |
1993 tmp.sort(); | 2049 tmp.sort(); |
1994 | 2050 |
| 2051 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED |
1995 bounds = &paint.computeFastBounds(tmp, &storage); | 2052 bounds = &paint.computeFastBounds(tmp, &storage); |
1996 if (this->quickReject(*bounds)) { | 2053 if (this->quickReject(*bounds)) { |
1997 return; | 2054 return; |
1998 } | 2055 } |
| 2056 #else |
| 2057 if (this->quickReject(paint.computeFastBounds(tmp, &storage))) { |
| 2058 return; |
| 2059 } |
| 2060 bounds = &r; |
| 2061 #endif |
1999 } | 2062 } |
2000 | 2063 |
2001 LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kRect_Type, bound
s, false) | 2064 LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kRect_Type, bound
s, false) |
2002 | 2065 |
2003 while (iter.next()) { | 2066 while (iter.next()) { |
2004 iter.fDevice->drawRect(iter, r, looper.paint()); | 2067 iter.fDevice->drawRect(iter, r, looper.paint()); |
2005 } | 2068 } |
2006 | 2069 |
2007 LOOPER_END | 2070 LOOPER_END |
2008 } | 2071 } |
2009 | 2072 |
2010 void SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) { | 2073 void SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) { |
2011 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawOval()"); | 2074 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawOval()"); |
2012 SkRect storage; | 2075 SkRect storage; |
2013 const SkRect* bounds = nullptr; | 2076 const SkRect* bounds = nullptr; |
2014 if (paint.canComputeFastBounds()) { | 2077 if (paint.canComputeFastBounds()) { |
| 2078 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED |
2015 bounds = &paint.computeFastBounds(oval, &storage); | 2079 bounds = &paint.computeFastBounds(oval, &storage); |
2016 if (this->quickReject(*bounds)) { | 2080 if (this->quickReject(*bounds)) { |
2017 return; | 2081 return; |
2018 } | 2082 } |
| 2083 #else |
| 2084 if (this->quickReject(paint.computeFastBounds(oval, &storage))) { |
| 2085 return; |
| 2086 } |
| 2087 bounds = &oval; |
| 2088 #endif |
2019 } | 2089 } |
2020 | 2090 |
2021 LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds) | 2091 LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds) |
2022 | 2092 |
2023 while (iter.next()) { | 2093 while (iter.next()) { |
2024 iter.fDevice->drawOval(iter, oval, looper.paint()); | 2094 iter.fDevice->drawOval(iter, oval, looper.paint()); |
2025 } | 2095 } |
2026 | 2096 |
2027 LOOPER_END | 2097 LOOPER_END |
2028 } | 2098 } |
2029 | 2099 |
2030 void SkCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { | 2100 void SkCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { |
2031 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRRect()"); | 2101 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRRect()"); |
2032 SkRect storage; | 2102 SkRect storage; |
2033 const SkRect* bounds = nullptr; | 2103 const SkRect* bounds = nullptr; |
2034 if (paint.canComputeFastBounds()) { | 2104 if (paint.canComputeFastBounds()) { |
| 2105 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED |
2035 bounds = &paint.computeFastBounds(rrect.getBounds(), &storage); | 2106 bounds = &paint.computeFastBounds(rrect.getBounds(), &storage); |
2036 if (this->quickReject(*bounds)) { | 2107 if (this->quickReject(*bounds)) { |
2037 return; | 2108 return; |
2038 } | 2109 } |
| 2110 #else |
| 2111 if (this->quickReject(paint.computeFastBounds(rrect.getBounds(), &storag
e))) { |
| 2112 return; |
| 2113 } |
| 2114 bounds = &rrect.getBounds(); |
| 2115 #endif |
2039 } | 2116 } |
2040 | 2117 |
2041 if (rrect.isRect()) { | 2118 if (rrect.isRect()) { |
2042 // call the non-virtual version | 2119 // call the non-virtual version |
2043 this->SkCanvas::drawRect(rrect.getBounds(), paint); | 2120 this->SkCanvas::drawRect(rrect.getBounds(), paint); |
2044 return; | 2121 return; |
2045 } else if (rrect.isOval()) { | 2122 } else if (rrect.isOval()) { |
2046 // call the non-virtual version | 2123 // call the non-virtual version |
2047 this->SkCanvas::drawOval(rrect.getBounds(), paint); | 2124 this->SkCanvas::drawOval(rrect.getBounds(), paint); |
2048 return; | 2125 return; |
2049 } | 2126 } |
2050 | 2127 |
2051 LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) | 2128 LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) |
2052 | 2129 |
2053 while (iter.next()) { | 2130 while (iter.next()) { |
2054 iter.fDevice->drawRRect(iter, rrect, looper.paint()); | 2131 iter.fDevice->drawRRect(iter, rrect, looper.paint()); |
2055 } | 2132 } |
2056 | 2133 |
2057 LOOPER_END | 2134 LOOPER_END |
2058 } | 2135 } |
2059 | 2136 |
2060 void SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, | 2137 void SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, |
2061 const SkPaint& paint) { | 2138 const SkPaint& paint) { |
2062 SkRect storage; | 2139 SkRect storage; |
2063 const SkRect* bounds = nullptr; | 2140 const SkRect* bounds = nullptr; |
2064 if (paint.canComputeFastBounds()) { | 2141 if (paint.canComputeFastBounds()) { |
| 2142 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED |
2065 bounds = &paint.computeFastBounds(outer.getBounds(), &storage); | 2143 bounds = &paint.computeFastBounds(outer.getBounds(), &storage); |
2066 if (this->quickReject(*bounds)) { | 2144 if (this->quickReject(*bounds)) { |
2067 return; | 2145 return; |
2068 } | 2146 } |
| 2147 #else |
| 2148 if (this->quickReject(paint.computeFastBounds(outer.getBounds(), &storag
e))) { |
| 2149 return; |
| 2150 } |
| 2151 bounds = &outer.getBounds(); |
| 2152 #endif |
2069 } | 2153 } |
2070 | 2154 |
2071 LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) | 2155 LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) |
2072 | 2156 |
2073 while (iter.next()) { | 2157 while (iter.next()) { |
2074 iter.fDevice->drawDRRect(iter, outer, inner, looper.paint()); | 2158 iter.fDevice->drawDRRect(iter, outer, inner, looper.paint()); |
2075 } | 2159 } |
2076 | 2160 |
2077 LOOPER_END | 2161 LOOPER_END |
2078 } | 2162 } |
2079 | 2163 |
2080 void SkCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { | 2164 void SkCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { |
2081 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPath()"); | 2165 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPath()"); |
2082 if (!path.isFinite()) { | 2166 if (!path.isFinite()) { |
2083 return; | 2167 return; |
2084 } | 2168 } |
2085 | 2169 |
2086 SkRect storage; | 2170 SkRect storage; |
2087 const SkRect* bounds = nullptr; | 2171 const SkRect* bounds = nullptr; |
2088 if (!path.isInverseFillType() && paint.canComputeFastBounds()) { | 2172 if (!path.isInverseFillType() && paint.canComputeFastBounds()) { |
2089 const SkRect& pathBounds = path.getBounds(); | 2173 const SkRect& pathBounds = path.getBounds(); |
| 2174 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED |
2090 bounds = &paint.computeFastBounds(pathBounds, &storage); | 2175 bounds = &paint.computeFastBounds(pathBounds, &storage); |
2091 if (this->quickReject(*bounds)) { | 2176 if (this->quickReject(*bounds)) { |
2092 return; | 2177 return; |
2093 } | 2178 } |
| 2179 #else |
| 2180 if (this->quickReject(paint.computeFastBounds(pathBounds, &storage))) { |
| 2181 return; |
| 2182 } |
| 2183 bounds = &pathBounds; |
| 2184 #endif |
2094 } | 2185 } |
2095 | 2186 |
2096 const SkRect& r = path.getBounds(); | 2187 const SkRect& r = path.getBounds(); |
2097 if (r.width() <= 0 && r.height() <= 0) { | 2188 if (r.width() <= 0 && r.height() <= 0) { |
2098 if (path.isInverseFillType()) { | 2189 if (path.isInverseFillType()) { |
2099 this->internalDrawPaint(paint); | 2190 this->internalDrawPaint(paint); |
2100 return; | 2191 return; |
2101 } | 2192 } |
2102 } | 2193 } |
2103 | 2194 |
2104 LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, bounds) | 2195 LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, bounds) |
2105 | 2196 |
2106 while (iter.next()) { | 2197 while (iter.next()) { |
2107 iter.fDevice->drawPath(iter, path, looper.paint()); | 2198 iter.fDevice->drawPath(iter, path, looper.paint()); |
2108 } | 2199 } |
2109 | 2200 |
2110 LOOPER_END | 2201 LOOPER_END |
2111 } | 2202 } |
2112 | 2203 |
2113 void SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const S
kPaint* paint) { | 2204 void SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const S
kPaint* paint) { |
2114 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImage()"); | 2205 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImage()"); |
2115 SkRect bounds = SkRect::MakeXYWH(x, y, | 2206 SkRect bounds = SkRect::MakeXYWH(x, y, |
2116 SkIntToScalar(image->width()), SkIntToScala
r(image->height())); | 2207 SkIntToScalar(image->width()), SkIntToScala
r(image->height())); |
2117 if (nullptr == paint || paint->canComputeFastBounds()) { | 2208 if (nullptr == paint || paint->canComputeFastBounds()) { |
| 2209 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED |
2118 if (paint) { | 2210 if (paint) { |
2119 paint->computeFastBounds(bounds, &bounds); | 2211 paint->computeFastBounds(bounds, &bounds); |
2120 } | 2212 } |
2121 if (this->quickReject(bounds)) { | 2213 if (this->quickReject(bounds)) { |
2122 return; | 2214 return; |
2123 } | 2215 } |
| 2216 #else |
| 2217 SkRect tmp = bounds; |
| 2218 if (paint) { |
| 2219 paint->computeFastBounds(tmp, &tmp); |
| 2220 } |
| 2221 if (this->quickReject(tmp)) { |
| 2222 return; |
| 2223 } |
| 2224 #endif |
2124 } | 2225 } |
2125 | 2226 |
2126 SkLazyPaint lazy; | 2227 SkLazyPaint lazy; |
2127 if (nullptr == paint) { | 2228 if (nullptr == paint) { |
2128 paint = lazy.init(); | 2229 paint = lazy.init(); |
2129 } | 2230 } |
2130 | 2231 |
2131 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &bounds) | 2232 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &bounds) |
2132 | 2233 |
2133 while (iter.next()) { | 2234 while (iter.next()) { |
2134 iter.fDevice->drawImage(iter, image, x, y, looper.paint()); | 2235 iter.fDevice->drawImage(iter, image, x, y, looper.paint()); |
2135 } | 2236 } |
2136 | 2237 |
2137 LOOPER_END | 2238 LOOPER_END |
2138 } | 2239 } |
2139 | 2240 |
2140 void SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const Sk
Rect& dst, | 2241 void SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const Sk
Rect& dst, |
2141 const SkPaint* paint, SrcRectConstraint constrain
t) { | 2242 const SkPaint* paint, SrcRectConstraint constrain
t) { |
2142 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageRect()"); | 2243 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageRect()"); |
2143 SkRect storage; | 2244 SkRect storage; |
2144 const SkRect* bounds = &dst; | 2245 const SkRect* bounds = &dst; |
2145 if (nullptr == paint || paint->canComputeFastBounds()) { | 2246 if (nullptr == paint || paint->canComputeFastBounds()) { |
| 2247 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED |
2146 if (paint) { | 2248 if (paint) { |
2147 bounds = &paint->computeFastBounds(dst, &storage); | 2249 bounds = &paint->computeFastBounds(dst, &storage); |
2148 } | 2250 } |
2149 if (this->quickReject(*bounds)) { | 2251 if (this->quickReject(*bounds)) { |
2150 return; | 2252 return; |
2151 } | 2253 } |
| 2254 #else |
| 2255 storage = dst; |
| 2256 if (paint) { |
| 2257 paint->computeFastBounds(dst, &storage); |
| 2258 } |
| 2259 if (this->quickReject(storage)) { |
| 2260 return; |
| 2261 } |
| 2262 #endif |
2152 } | 2263 } |
2153 SkLazyPaint lazy; | 2264 SkLazyPaint lazy; |
2154 if (nullptr == paint) { | 2265 if (nullptr == paint) { |
2155 paint = lazy.init(); | 2266 paint = lazy.init(); |
2156 } | 2267 } |
2157 | 2268 |
2158 LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, bo
unds, | 2269 LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, bo
unds, |
2159 image->isOpaque()) | 2270 image->isOpaque()) |
2160 | 2271 |
2161 while (iter.next()) { | 2272 while (iter.next()) { |
(...skipping 16 matching lines...) Expand all Loading... |
2178 paint = lazy.init(); | 2289 paint = lazy.init(); |
2179 } | 2290 } |
2180 | 2291 |
2181 const SkMatrix matrix = SkMatrix::MakeTrans(x, y); | 2292 const SkMatrix matrix = SkMatrix::MakeTrans(x, y); |
2182 | 2293 |
2183 SkRect storage; | 2294 SkRect storage; |
2184 const SkRect* bounds = nullptr; | 2295 const SkRect* bounds = nullptr; |
2185 if (paint->canComputeFastBounds()) { | 2296 if (paint->canComputeFastBounds()) { |
2186 bitmap.getBounds(&storage); | 2297 bitmap.getBounds(&storage); |
2187 matrix.mapRect(&storage); | 2298 matrix.mapRect(&storage); |
| 2299 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED |
2188 bounds = &paint->computeFastBounds(storage, &storage); | 2300 bounds = &paint->computeFastBounds(storage, &storage); |
2189 if (this->quickReject(*bounds)) { | 2301 if (this->quickReject(*bounds)) { |
2190 return; | 2302 return; |
2191 } | 2303 } |
| 2304 #else |
| 2305 SkRect tmp = storage; |
| 2306 if (this->quickReject(paint->computeFastBounds(tmp, &tmp))) { |
| 2307 return; |
| 2308 } |
| 2309 bounds = &storage; |
| 2310 #endif |
2192 } | 2311 } |
2193 | 2312 |
2194 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) | 2313 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) |
2195 | 2314 |
2196 while (iter.next()) { | 2315 while (iter.next()) { |
2197 iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint()); | 2316 iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint()); |
2198 } | 2317 } |
2199 | 2318 |
2200 LOOPER_END | 2319 LOOPER_END |
2201 } | 2320 } |
2202 | 2321 |
2203 // this one is non-virtual, so it can be called safely by other canvas apis | 2322 // this one is non-virtual, so it can be called safely by other canvas apis |
2204 void SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, | 2323 void SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, |
2205 const SkRect& dst, const SkPaint* paint, | 2324 const SkRect& dst, const SkPaint* paint, |
2206 SrcRectConstraint constraint) { | 2325 SrcRectConstraint constraint) { |
2207 if (bitmap.drawsNothing() || dst.isEmpty()) { | 2326 if (bitmap.drawsNothing() || dst.isEmpty()) { |
2208 return; | 2327 return; |
2209 } | 2328 } |
2210 | 2329 |
2211 SkRect storage; | 2330 SkRect storage; |
2212 const SkRect* bounds = &dst; | 2331 const SkRect* bounds = &dst; |
2213 if (nullptr == paint || paint->canComputeFastBounds()) { | 2332 if (nullptr == paint || paint->canComputeFastBounds()) { |
| 2333 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED |
2214 if (paint) { | 2334 if (paint) { |
2215 bounds = &paint->computeFastBounds(dst, &storage); | 2335 bounds = &paint->computeFastBounds(dst, &storage); |
2216 } | 2336 } |
2217 if (this->quickReject(*bounds)) { | 2337 if (this->quickReject(*bounds)) { |
2218 return; | 2338 return; |
2219 } | 2339 } |
| 2340 #else |
| 2341 if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) :
dst)) { |
| 2342 return; |
| 2343 } |
| 2344 #endif |
2220 } | 2345 } |
2221 | 2346 |
2222 SkLazyPaint lazy; | 2347 SkLazyPaint lazy; |
2223 if (nullptr == paint) { | 2348 if (nullptr == paint) { |
2224 paint = lazy.init(); | 2349 paint = lazy.init(); |
2225 } | 2350 } |
2226 | 2351 |
2227 LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, bo
unds, | 2352 LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, bo
unds, |
2228 bitmap.isOpaque()) | 2353 bitmap.isOpaque()) |
2229 | 2354 |
(...skipping 11 matching lines...) Expand all Loading... |
2241 this->internalDrawBitmapRect(bitmap, src, dst, paint, constraint); | 2366 this->internalDrawBitmapRect(bitmap, src, dst, paint, constraint); |
2242 } | 2367 } |
2243 | 2368 |
2244 void SkCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, cons
t SkRect& dst, | 2369 void SkCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, cons
t SkRect& dst, |
2245 const SkPaint* paint) { | 2370 const SkPaint* paint) { |
2246 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageNine()"); | 2371 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageNine()"); |
2247 | 2372 |
2248 SkRect storage; | 2373 SkRect storage; |
2249 const SkRect* bounds = &dst; | 2374 const SkRect* bounds = &dst; |
2250 if (nullptr == paint || paint->canComputeFastBounds()) { | 2375 if (nullptr == paint || paint->canComputeFastBounds()) { |
| 2376 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED |
2251 if (paint) { | 2377 if (paint) { |
2252 bounds = &paint->computeFastBounds(dst, &storage); | 2378 bounds = &paint->computeFastBounds(dst, &storage); |
2253 } | 2379 } |
2254 if (this->quickReject(*bounds)) { | 2380 if (this->quickReject(*bounds)) { |
2255 return; | 2381 return; |
2256 } | 2382 } |
| 2383 #else |
| 2384 if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) :
dst)) { |
| 2385 return; |
| 2386 } |
| 2387 #endif |
2257 } | 2388 } |
2258 | 2389 |
2259 SkLazyPaint lazy; | 2390 SkLazyPaint lazy; |
2260 if (nullptr == paint) { | 2391 if (nullptr == paint) { |
2261 paint = lazy.init(); | 2392 paint = lazy.init(); |
2262 } | 2393 } |
2263 | 2394 |
2264 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) | 2395 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) |
2265 | 2396 |
2266 while (iter.next()) { | 2397 while (iter.next()) { |
2267 iter.fDevice->drawImageNine(iter, image, center, dst, looper.paint()); | 2398 iter.fDevice->drawImageNine(iter, image, center, dst, looper.paint()); |
2268 } | 2399 } |
2269 | 2400 |
2270 LOOPER_END | 2401 LOOPER_END |
2271 } | 2402 } |
2272 | 2403 |
2273 void SkCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, c
onst SkRect& dst, | 2404 void SkCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, c
onst SkRect& dst, |
2274 const SkPaint* paint) { | 2405 const SkPaint* paint) { |
2275 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapNine()"); | 2406 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapNine()"); |
2276 SkDEBUGCODE(bitmap.validate();) | 2407 SkDEBUGCODE(bitmap.validate();) |
2277 | 2408 |
2278 SkRect storage; | 2409 SkRect storage; |
2279 const SkRect* bounds = &dst; | 2410 const SkRect* bounds = &dst; |
2280 if (nullptr == paint || paint->canComputeFastBounds()) { | 2411 if (nullptr == paint || paint->canComputeFastBounds()) { |
| 2412 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED |
2281 if (paint) { | 2413 if (paint) { |
2282 bounds = &paint->computeFastBounds(dst, &storage); | 2414 bounds = &paint->computeFastBounds(dst, &storage); |
2283 } | 2415 } |
2284 if (this->quickReject(*bounds)) { | 2416 if (this->quickReject(*bounds)) { |
2285 return; | 2417 return; |
2286 } | 2418 } |
| 2419 #else |
| 2420 if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) :
dst)) { |
| 2421 return; |
| 2422 } |
| 2423 #endif |
2287 } | 2424 } |
2288 | 2425 |
2289 SkLazyPaint lazy; | 2426 SkLazyPaint lazy; |
2290 if (nullptr == paint) { | 2427 if (nullptr == paint) { |
2291 paint = lazy.init(); | 2428 paint = lazy.init(); |
2292 } | 2429 } |
2293 | 2430 |
2294 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) | 2431 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) |
2295 | 2432 |
2296 while (iter.next()) { | 2433 while (iter.next()) { |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2449 LOOPER_END | 2586 LOOPER_END |
2450 } | 2587 } |
2451 | 2588 |
2452 void SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, | 2589 void SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, |
2453 const SkPaint& paint) { | 2590 const SkPaint& paint) { |
2454 | 2591 |
2455 SkRect storage; | 2592 SkRect storage; |
2456 const SkRect* bounds = nullptr; | 2593 const SkRect* bounds = nullptr; |
2457 if (paint.canComputeFastBounds()) { | 2594 if (paint.canComputeFastBounds()) { |
2458 storage = blob->bounds().makeOffset(x, y); | 2595 storage = blob->bounds().makeOffset(x, y); |
| 2596 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED |
2459 bounds = &paint.computeFastBounds(storage, &storage); | 2597 bounds = &paint.computeFastBounds(storage, &storage); |
2460 | 2598 |
2461 if (this->quickReject(*bounds)) { | 2599 if (this->quickReject(*bounds)) { |
2462 return; | 2600 return; |
2463 } | 2601 } |
| 2602 #else |
| 2603 SkRect tmp; |
| 2604 if (this->quickReject(paint.computeFastBounds(storage, &tmp))) { |
| 2605 return; |
| 2606 } |
| 2607 bounds = &storage; |
| 2608 #endif |
2464 } | 2609 } |
2465 | 2610 |
2466 // We cannot filter in the looper as we normally do, because the paint is | 2611 // We cannot filter in the looper as we normally do, because the paint is |
2467 // incomplete at this point (text-related attributes are embedded within blo
b run paints). | 2612 // incomplete at this point (text-related attributes are embedded within blo
b run paints). |
2468 SkDrawFilter* drawFilter = fMCRec->fFilter; | 2613 SkDrawFilter* drawFilter = fMCRec->fFilter; |
2469 fMCRec->fFilter = nullptr; | 2614 fMCRec->fFilter = nullptr; |
2470 | 2615 |
2471 LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, bounds) | 2616 LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, bounds) |
2472 | 2617 |
2473 while (iter.next()) { | 2618 while (iter.next()) { |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2882 } | 3027 } |
2883 | 3028 |
2884 if (matrix) { | 3029 if (matrix) { |
2885 canvas->concat(*matrix); | 3030 canvas->concat(*matrix); |
2886 } | 3031 } |
2887 } | 3032 } |
2888 | 3033 |
2889 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { | 3034 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { |
2890 fCanvas->restoreToCount(fSaveCount); | 3035 fCanvas->restoreToCount(fSaveCount); |
2891 } | 3036 } |
OLD | NEW |