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: |
robertphillips
2015/10/28 16:21:47
Well, isn't rawBounds the completely raw bounds -
Stephen White
2015/10/28 16:45:46
Good point. Fixed.
| |
439 // "rawBounds" is the bounds of the primitive about to be drawn, excluding f ilter | |
440 // outsets. It's used to determine the size of the offscreen layer for filte rs. | |
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) { | |
robertphillips
2015/10/28 16:21:47
// Make rawBounds include all paint outsets except
Stephen White
2015/10/28 16:45:46
Done.
| |
482 rawBounds = &apply_paint_to_bounds_sans_imagefilter(*fPaint, *ra wBounds, &storage); | |
483 } | |
484 #endif | |
485 (void)canvas->internalSaveLayer(rawBounds, &tmp, SkCanvas::kARGB_Cli pLayer_SaveFlag, | |
451 SkCanvas::kFullLayer_SaveLayerStrate gy); | 486 SkCanvas::kFullLayer_SaveLayerStrate gy); |
452 fTempLayerForImageFilter = true; | 487 fTempLayerForImageFilter = true; |
453 // we remove the imagefilter/xfermode inside doNext() | 488 // we remove the imagefilter/xfermode inside doNext() |
454 } | 489 } |
455 | 490 |
456 if (SkDrawLooper* looper = paint.getLooper()) { | 491 if (SkDrawLooper* looper = paint.getLooper()) { |
457 void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Contex t>( | 492 void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Contex t>( |
458 looper->contextSize()); | 493 looper->contextSize()); |
459 fLooperContext = looper->createContext(canvas, buffer); | 494 fLooperContext = looper->createContext(canvas, buffer); |
460 fIsSimple = false; | 495 fIsSimple = false; |
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1012 | 1047 |
1013 bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags, | 1048 bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags, |
1014 SkIRect* intersection, const SkImageFilter* imageF ilter) { | 1049 SkIRect* intersection, const SkImageFilter* imageF ilter) { |
1015 SkIRect clipBounds; | 1050 SkIRect clipBounds; |
1016 if (!this->getClipDeviceBounds(&clipBounds)) { | 1051 if (!this->getClipDeviceBounds(&clipBounds)) { |
1017 return false; | 1052 return false; |
1018 } | 1053 } |
1019 | 1054 |
1020 const SkMatrix& ctm = fMCRec->fMatrix; // this->getTotalMatrix() | 1055 const SkMatrix& ctm = fMCRec->fMatrix; // this->getTotalMatrix() |
1021 | 1056 |
1057 // This is a temporary hack, until individual filters can do their own | |
1058 // bloating, when this will be removed. | |
1059 #ifdef SK_SUPPORT_SRC_BOUNDS_BLOAT_FOR_IMAGEFILTERS | |
1060 SkRect storage; | |
1061 #endif | |
1022 if (imageFilter) { | 1062 if (imageFilter) { |
1023 imageFilter->filterBounds(clipBounds, ctm, &clipBounds); | 1063 imageFilter->filterBounds(clipBounds, ctm, &clipBounds); |
1064 #ifdef SK_SUPPORT_SRC_BOUNDS_BLOAT_FOR_IMAGEFILTERS | |
1065 if (bounds && imageFilter->canComputeFastBounds()) { | |
1066 imageFilter->computeFastBounds(*bounds, &storage); | |
1067 bounds = &storage; | |
1068 } else { | |
1069 bounds = nullptr; | |
1070 } | |
1071 #endif | |
1024 } | 1072 } |
1025 SkIRect ir; | 1073 SkIRect ir; |
1026 if (bounds) { | 1074 if (bounds) { |
1027 SkRect r; | 1075 SkRect r; |
1028 | 1076 |
1029 ctm.mapRect(&r, *bounds); | 1077 ctm.mapRect(&r, *bounds); |
1030 r.roundOut(&ir); | 1078 r.roundOut(&ir); |
1031 // early exit if the layer's bounds are clipped out | 1079 // early exit if the layer's bounds are clipped out |
1032 if (!ir.intersect(clipBounds)) { | 1080 if (!ir.intersect(clipBounds)) { |
1033 if (bounds_affects_clip(flags)) { | 1081 if (bounds_affects_clip(flags)) { |
(...skipping 924 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1958 | 2006 |
1959 SkRect r, storage; | 2007 SkRect r, storage; |
1960 const SkRect* bounds = nullptr; | 2008 const SkRect* bounds = nullptr; |
1961 if (paint.canComputeFastBounds()) { | 2009 if (paint.canComputeFastBounds()) { |
1962 // special-case 2 points (common for drawing a single line) | 2010 // special-case 2 points (common for drawing a single line) |
1963 if (2 == count) { | 2011 if (2 == count) { |
1964 r.set(pts[0], pts[1]); | 2012 r.set(pts[0], pts[1]); |
1965 } else { | 2013 } else { |
1966 r.set(pts, SkToInt(count)); | 2014 r.set(pts, SkToInt(count)); |
1967 } | 2015 } |
2016 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
1968 bounds = &paint.computeFastStrokeBounds(r, &storage); | 2017 bounds = &paint.computeFastStrokeBounds(r, &storage); |
1969 if (this->quickReject(*bounds)) { | 2018 if (this->quickReject(*bounds)) { |
1970 return; | 2019 return; |
1971 } | 2020 } |
2021 #else | |
2022 if (this->quickReject(paint.computeFastStrokeBounds(r, &storage))) { | |
2023 return; | |
2024 } | |
2025 bounds = &r; | |
2026 #endif | |
1972 } | 2027 } |
1973 | 2028 |
1974 SkASSERT(pts != nullptr); | 2029 SkASSERT(pts != nullptr); |
1975 | 2030 |
1976 LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds) | 2031 LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds) |
1977 | 2032 |
1978 while (iter.next()) { | 2033 while (iter.next()) { |
1979 iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint()); | 2034 iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint()); |
1980 } | 2035 } |
1981 | 2036 |
1982 LOOPER_END | 2037 LOOPER_END |
1983 } | 2038 } |
1984 | 2039 |
1985 void SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) { | 2040 void SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) { |
1986 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRect()"); | 2041 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRect()"); |
1987 SkRect storage; | 2042 SkRect storage; |
1988 const SkRect* bounds = nullptr; | 2043 const SkRect* bounds = nullptr; |
1989 if (paint.canComputeFastBounds()) { | 2044 if (paint.canComputeFastBounds()) { |
1990 // Skia will draw an inverted rect, because it explicitly "sorts" it dow nstream. | 2045 // 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. | 2046 // To prevent accidental rejecting at this stage, we have to sort it bef ore we check. |
1992 SkRect tmp(r); | 2047 SkRect tmp(r); |
1993 tmp.sort(); | 2048 tmp.sort(); |
1994 | 2049 |
2050 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
1995 bounds = &paint.computeFastBounds(tmp, &storage); | 2051 bounds = &paint.computeFastBounds(tmp, &storage); |
1996 if (this->quickReject(*bounds)) { | 2052 if (this->quickReject(*bounds)) { |
1997 return; | 2053 return; |
1998 } | 2054 } |
2055 #else | |
2056 if (this->quickReject(paint.computeFastBounds(tmp, &storage))) { | |
2057 return; | |
2058 } | |
2059 bounds = &r; | |
2060 #endif | |
1999 } | 2061 } |
2000 | 2062 |
2001 LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kRect_Type, bound s, false) | 2063 LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kRect_Type, bound s, false) |
2002 | 2064 |
2003 while (iter.next()) { | 2065 while (iter.next()) { |
2004 iter.fDevice->drawRect(iter, r, looper.paint()); | 2066 iter.fDevice->drawRect(iter, r, looper.paint()); |
2005 } | 2067 } |
2006 | 2068 |
2007 LOOPER_END | 2069 LOOPER_END |
2008 } | 2070 } |
2009 | 2071 |
2010 void SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) { | 2072 void SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) { |
2011 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawOval()"); | 2073 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawOval()"); |
2012 SkRect storage; | 2074 SkRect storage; |
2013 const SkRect* bounds = nullptr; | 2075 const SkRect* bounds = nullptr; |
2014 if (paint.canComputeFastBounds()) { | 2076 if (paint.canComputeFastBounds()) { |
2077 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
2015 bounds = &paint.computeFastBounds(oval, &storage); | 2078 bounds = &paint.computeFastBounds(oval, &storage); |
2016 if (this->quickReject(*bounds)) { | 2079 if (this->quickReject(*bounds)) { |
2017 return; | 2080 return; |
2018 } | 2081 } |
2082 #else | |
2083 if (this->quickReject(paint.computeFastBounds(oval, &storage))) { | |
2084 return; | |
2085 } | |
2086 bounds = &oval; | |
2087 #endif | |
2019 } | 2088 } |
2020 | 2089 |
2021 LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds) | 2090 LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds) |
2022 | 2091 |
2023 while (iter.next()) { | 2092 while (iter.next()) { |
2024 iter.fDevice->drawOval(iter, oval, looper.paint()); | 2093 iter.fDevice->drawOval(iter, oval, looper.paint()); |
2025 } | 2094 } |
2026 | 2095 |
2027 LOOPER_END | 2096 LOOPER_END |
2028 } | 2097 } |
2029 | 2098 |
2030 void SkCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { | 2099 void SkCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { |
2031 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRRect()"); | 2100 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRRect()"); |
2032 SkRect storage; | 2101 SkRect storage; |
2033 const SkRect* bounds = nullptr; | 2102 const SkRect* bounds = nullptr; |
2034 if (paint.canComputeFastBounds()) { | 2103 if (paint.canComputeFastBounds()) { |
2104 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
2035 bounds = &paint.computeFastBounds(rrect.getBounds(), &storage); | 2105 bounds = &paint.computeFastBounds(rrect.getBounds(), &storage); |
2036 if (this->quickReject(*bounds)) { | 2106 if (this->quickReject(*bounds)) { |
2037 return; | 2107 return; |
2038 } | 2108 } |
2109 #else | |
2110 if (this->quickReject(paint.computeFastBounds(rrect.getBounds(), &storag e))) { | |
2111 return; | |
2112 } | |
2113 bounds = &rrect.getBounds(); | |
2114 #endif | |
2039 } | 2115 } |
2040 | 2116 |
2041 if (rrect.isRect()) { | 2117 if (rrect.isRect()) { |
2042 // call the non-virtual version | 2118 // call the non-virtual version |
2043 this->SkCanvas::drawRect(rrect.getBounds(), paint); | 2119 this->SkCanvas::drawRect(rrect.getBounds(), paint); |
2044 return; | 2120 return; |
2045 } else if (rrect.isOval()) { | 2121 } else if (rrect.isOval()) { |
2046 // call the non-virtual version | 2122 // call the non-virtual version |
2047 this->SkCanvas::drawOval(rrect.getBounds(), paint); | 2123 this->SkCanvas::drawOval(rrect.getBounds(), paint); |
2048 return; | 2124 return; |
2049 } | 2125 } |
2050 | 2126 |
2051 LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) | 2127 LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) |
2052 | 2128 |
2053 while (iter.next()) { | 2129 while (iter.next()) { |
2054 iter.fDevice->drawRRect(iter, rrect, looper.paint()); | 2130 iter.fDevice->drawRRect(iter, rrect, looper.paint()); |
2055 } | 2131 } |
2056 | 2132 |
2057 LOOPER_END | 2133 LOOPER_END |
2058 } | 2134 } |
2059 | 2135 |
2060 void SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, | 2136 void SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, |
2061 const SkPaint& paint) { | 2137 const SkPaint& paint) { |
2062 SkRect storage; | 2138 SkRect storage; |
2063 const SkRect* bounds = nullptr; | 2139 const SkRect* bounds = nullptr; |
2064 if (paint.canComputeFastBounds()) { | 2140 if (paint.canComputeFastBounds()) { |
2141 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
2065 bounds = &paint.computeFastBounds(outer.getBounds(), &storage); | 2142 bounds = &paint.computeFastBounds(outer.getBounds(), &storage); |
2066 if (this->quickReject(*bounds)) { | 2143 if (this->quickReject(*bounds)) { |
2067 return; | 2144 return; |
2068 } | 2145 } |
2146 #else | |
2147 if (this->quickReject(paint.computeFastBounds(outer.getBounds(), &storag e))) { | |
2148 return; | |
2149 } | |
2150 bounds = &outer.getBounds(); | |
2151 #endif | |
2069 } | 2152 } |
2070 | 2153 |
2071 LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) | 2154 LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) |
2072 | 2155 |
2073 while (iter.next()) { | 2156 while (iter.next()) { |
2074 iter.fDevice->drawDRRect(iter, outer, inner, looper.paint()); | 2157 iter.fDevice->drawDRRect(iter, outer, inner, looper.paint()); |
2075 } | 2158 } |
2076 | 2159 |
2077 LOOPER_END | 2160 LOOPER_END |
2078 } | 2161 } |
2079 | 2162 |
2080 void SkCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { | 2163 void SkCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { |
2081 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPath()"); | 2164 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPath()"); |
2082 if (!path.isFinite()) { | 2165 if (!path.isFinite()) { |
2083 return; | 2166 return; |
2084 } | 2167 } |
2085 | 2168 |
2086 SkRect storage; | 2169 SkRect storage; |
2087 const SkRect* bounds = nullptr; | 2170 const SkRect* bounds = nullptr; |
2088 if (!path.isInverseFillType() && paint.canComputeFastBounds()) { | 2171 if (!path.isInverseFillType() && paint.canComputeFastBounds()) { |
2089 const SkRect& pathBounds = path.getBounds(); | 2172 const SkRect& pathBounds = path.getBounds(); |
2173 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
2090 bounds = &paint.computeFastBounds(pathBounds, &storage); | 2174 bounds = &paint.computeFastBounds(pathBounds, &storage); |
2091 if (this->quickReject(*bounds)) { | 2175 if (this->quickReject(*bounds)) { |
2092 return; | 2176 return; |
2093 } | 2177 } |
2178 #else | |
2179 if (this->quickReject(paint.computeFastBounds(pathBounds, &storage))) { | |
2180 return; | |
2181 } | |
2182 bounds = &pathBounds; | |
2183 #endif | |
2094 } | 2184 } |
2095 | 2185 |
2096 const SkRect& r = path.getBounds(); | 2186 const SkRect& r = path.getBounds(); |
2097 if (r.width() <= 0 && r.height() <= 0) { | 2187 if (r.width() <= 0 && r.height() <= 0) { |
2098 if (path.isInverseFillType()) { | 2188 if (path.isInverseFillType()) { |
2099 this->internalDrawPaint(paint); | 2189 this->internalDrawPaint(paint); |
2100 return; | 2190 return; |
2101 } | 2191 } |
2102 } | 2192 } |
2103 | 2193 |
2104 LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, bounds) | 2194 LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, bounds) |
2105 | 2195 |
2106 while (iter.next()) { | 2196 while (iter.next()) { |
2107 iter.fDevice->drawPath(iter, path, looper.paint()); | 2197 iter.fDevice->drawPath(iter, path, looper.paint()); |
2108 } | 2198 } |
2109 | 2199 |
2110 LOOPER_END | 2200 LOOPER_END |
2111 } | 2201 } |
2112 | 2202 |
2113 void SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const S kPaint* paint) { | 2203 void SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const S kPaint* paint) { |
2114 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImage()"); | 2204 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImage()"); |
2115 SkRect bounds = SkRect::MakeXYWH(x, y, | 2205 SkRect bounds = SkRect::MakeXYWH(x, y, |
2116 SkIntToScalar(image->width()), SkIntToScala r(image->height())); | 2206 SkIntToScalar(image->width()), SkIntToScala r(image->height())); |
2117 if (nullptr == paint || paint->canComputeFastBounds()) { | 2207 if (nullptr == paint || paint->canComputeFastBounds()) { |
2208 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
2118 if (paint) { | 2209 if (paint) { |
2119 paint->computeFastBounds(bounds, &bounds); | 2210 paint->computeFastBounds(bounds, &bounds); |
2120 } | 2211 } |
2121 if (this->quickReject(bounds)) { | 2212 if (this->quickReject(bounds)) { |
2122 return; | 2213 return; |
2123 } | 2214 } |
2215 #else | |
2216 SkRect tmp = bounds; | |
2217 if (paint) { | |
2218 paint->computeFastBounds(tmp, &tmp); | |
2219 } | |
2220 if (this->quickReject(tmp)) { | |
2221 return; | |
2222 } | |
2223 #endif | |
2124 } | 2224 } |
2125 | 2225 |
2126 SkLazyPaint lazy; | 2226 SkLazyPaint lazy; |
2127 if (nullptr == paint) { | 2227 if (nullptr == paint) { |
2128 paint = lazy.init(); | 2228 paint = lazy.init(); |
2129 } | 2229 } |
2130 | 2230 |
2131 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &bounds) | 2231 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &bounds) |
2132 | 2232 |
2133 while (iter.next()) { | 2233 while (iter.next()) { |
2134 iter.fDevice->drawImage(iter, image, x, y, looper.paint()); | 2234 iter.fDevice->drawImage(iter, image, x, y, looper.paint()); |
2135 } | 2235 } |
2136 | 2236 |
2137 LOOPER_END | 2237 LOOPER_END |
2138 } | 2238 } |
2139 | 2239 |
2140 void SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const Sk Rect& dst, | 2240 void SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const Sk Rect& dst, |
2141 const SkPaint* paint, SrcRectConstraint constrain t) { | 2241 const SkPaint* paint, SrcRectConstraint constrain t) { |
2142 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageRect()"); | 2242 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageRect()"); |
2143 SkRect storage; | 2243 SkRect storage; |
2144 const SkRect* bounds = &dst; | 2244 const SkRect* bounds = &dst; |
2145 if (nullptr == paint || paint->canComputeFastBounds()) { | 2245 if (nullptr == paint || paint->canComputeFastBounds()) { |
2246 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
2146 if (paint) { | 2247 if (paint) { |
2147 bounds = &paint->computeFastBounds(dst, &storage); | 2248 bounds = &paint->computeFastBounds(dst, &storage); |
2148 } | 2249 } |
2149 if (this->quickReject(*bounds)) { | 2250 if (this->quickReject(*bounds)) { |
2150 return; | 2251 return; |
2151 } | 2252 } |
2253 #else | |
2254 storage = dst; | |
2255 if (paint) { | |
2256 paint->computeFastBounds(dst, &storage); | |
2257 } | |
2258 if (this->quickReject(storage)) { | |
2259 return; | |
2260 } | |
2261 #endif | |
2152 } | 2262 } |
2153 SkLazyPaint lazy; | 2263 SkLazyPaint lazy; |
2154 if (nullptr == paint) { | 2264 if (nullptr == paint) { |
2155 paint = lazy.init(); | 2265 paint = lazy.init(); |
2156 } | 2266 } |
2157 | 2267 |
2158 LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, bo unds, | 2268 LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, bo unds, |
2159 image->isOpaque()) | 2269 image->isOpaque()) |
2160 | 2270 |
2161 while (iter.next()) { | 2271 while (iter.next()) { |
(...skipping 16 matching lines...) Expand all Loading... | |
2178 paint = lazy.init(); | 2288 paint = lazy.init(); |
2179 } | 2289 } |
2180 | 2290 |
2181 const SkMatrix matrix = SkMatrix::MakeTrans(x, y); | 2291 const SkMatrix matrix = SkMatrix::MakeTrans(x, y); |
2182 | 2292 |
2183 SkRect storage; | 2293 SkRect storage; |
2184 const SkRect* bounds = nullptr; | 2294 const SkRect* bounds = nullptr; |
2185 if (paint->canComputeFastBounds()) { | 2295 if (paint->canComputeFastBounds()) { |
2186 bitmap.getBounds(&storage); | 2296 bitmap.getBounds(&storage); |
2187 matrix.mapRect(&storage); | 2297 matrix.mapRect(&storage); |
2298 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
2188 bounds = &paint->computeFastBounds(storage, &storage); | 2299 bounds = &paint->computeFastBounds(storage, &storage); |
2189 if (this->quickReject(*bounds)) { | 2300 if (this->quickReject(*bounds)) { |
2190 return; | 2301 return; |
2191 } | 2302 } |
2303 #else | |
2304 SkRect tmp = storage; | |
2305 if (this->quickReject(paint->computeFastBounds(tmp, &tmp))) { | |
2306 return; | |
2307 } | |
2308 bounds = &storage; | |
2309 #endif | |
2192 } | 2310 } |
2193 | 2311 |
2194 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) | 2312 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) |
2195 | 2313 |
2196 while (iter.next()) { | 2314 while (iter.next()) { |
2197 iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint()); | 2315 iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint()); |
2198 } | 2316 } |
2199 | 2317 |
2200 LOOPER_END | 2318 LOOPER_END |
2201 } | 2319 } |
2202 | 2320 |
2203 // this one is non-virtual, so it can be called safely by other canvas apis | 2321 // 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, | 2322 void SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, |
2205 const SkRect& dst, const SkPaint* paint, | 2323 const SkRect& dst, const SkPaint* paint, |
2206 SrcRectConstraint constraint) { | 2324 SrcRectConstraint constraint) { |
2207 if (bitmap.drawsNothing() || dst.isEmpty()) { | 2325 if (bitmap.drawsNothing() || dst.isEmpty()) { |
2208 return; | 2326 return; |
2209 } | 2327 } |
2210 | 2328 |
2211 SkRect storage; | 2329 SkRect storage; |
2212 const SkRect* bounds = &dst; | 2330 const SkRect* bounds = &dst; |
2213 if (nullptr == paint || paint->canComputeFastBounds()) { | 2331 if (nullptr == paint || paint->canComputeFastBounds()) { |
2332 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
2214 if (paint) { | 2333 if (paint) { |
2215 bounds = &paint->computeFastBounds(dst, &storage); | 2334 bounds = &paint->computeFastBounds(dst, &storage); |
2216 } | 2335 } |
2217 if (this->quickReject(*bounds)) { | 2336 if (this->quickReject(*bounds)) { |
2218 return; | 2337 return; |
2219 } | 2338 } |
2339 #else | |
2340 if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { | |
2341 return; | |
2342 } | |
2343 #endif | |
2220 } | 2344 } |
2221 | 2345 |
2222 SkLazyPaint lazy; | 2346 SkLazyPaint lazy; |
2223 if (nullptr == paint) { | 2347 if (nullptr == paint) { |
2224 paint = lazy.init(); | 2348 paint = lazy.init(); |
2225 } | 2349 } |
2226 | 2350 |
2227 LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, bo unds, | 2351 LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, bo unds, |
2228 bitmap.isOpaque()) | 2352 bitmap.isOpaque()) |
2229 | 2353 |
(...skipping 11 matching lines...) Expand all Loading... | |
2241 this->internalDrawBitmapRect(bitmap, src, dst, paint, constraint); | 2365 this->internalDrawBitmapRect(bitmap, src, dst, paint, constraint); |
2242 } | 2366 } |
2243 | 2367 |
2244 void SkCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, cons t SkRect& dst, | 2368 void SkCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, cons t SkRect& dst, |
2245 const SkPaint* paint) { | 2369 const SkPaint* paint) { |
2246 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageNine()"); | 2370 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageNine()"); |
2247 | 2371 |
2248 SkRect storage; | 2372 SkRect storage; |
2249 const SkRect* bounds = &dst; | 2373 const SkRect* bounds = &dst; |
2250 if (nullptr == paint || paint->canComputeFastBounds()) { | 2374 if (nullptr == paint || paint->canComputeFastBounds()) { |
2375 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
2251 if (paint) { | 2376 if (paint) { |
2252 bounds = &paint->computeFastBounds(dst, &storage); | 2377 bounds = &paint->computeFastBounds(dst, &storage); |
2253 } | 2378 } |
2254 if (this->quickReject(*bounds)) { | 2379 if (this->quickReject(*bounds)) { |
2255 return; | 2380 return; |
2256 } | 2381 } |
2382 #else | |
2383 if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { | |
2384 return; | |
2385 } | |
2386 #endif | |
2257 } | 2387 } |
2258 | 2388 |
2259 SkLazyPaint lazy; | 2389 SkLazyPaint lazy; |
2260 if (nullptr == paint) { | 2390 if (nullptr == paint) { |
2261 paint = lazy.init(); | 2391 paint = lazy.init(); |
2262 } | 2392 } |
2263 | 2393 |
2264 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) | 2394 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) |
2265 | 2395 |
2266 while (iter.next()) { | 2396 while (iter.next()) { |
2267 iter.fDevice->drawImageNine(iter, image, center, dst, looper.paint()); | 2397 iter.fDevice->drawImageNine(iter, image, center, dst, looper.paint()); |
2268 } | 2398 } |
2269 | 2399 |
2270 LOOPER_END | 2400 LOOPER_END |
2271 } | 2401 } |
2272 | 2402 |
2273 void SkCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, c onst SkRect& dst, | 2403 void SkCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, c onst SkRect& dst, |
2274 const SkPaint* paint) { | 2404 const SkPaint* paint) { |
2275 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapNine()"); | 2405 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapNine()"); |
2276 SkDEBUGCODE(bitmap.validate();) | 2406 SkDEBUGCODE(bitmap.validate();) |
2277 | 2407 |
2278 SkRect storage; | 2408 SkRect storage; |
2279 const SkRect* bounds = &dst; | 2409 const SkRect* bounds = &dst; |
2280 if (nullptr == paint || paint->canComputeFastBounds()) { | 2410 if (nullptr == paint || paint->canComputeFastBounds()) { |
2411 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
2281 if (paint) { | 2412 if (paint) { |
2282 bounds = &paint->computeFastBounds(dst, &storage); | 2413 bounds = &paint->computeFastBounds(dst, &storage); |
2283 } | 2414 } |
2284 if (this->quickReject(*bounds)) { | 2415 if (this->quickReject(*bounds)) { |
2285 return; | 2416 return; |
2286 } | 2417 } |
2418 #else | |
2419 if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { | |
2420 return; | |
2421 } | |
2422 #endif | |
2287 } | 2423 } |
2288 | 2424 |
2289 SkLazyPaint lazy; | 2425 SkLazyPaint lazy; |
2290 if (nullptr == paint) { | 2426 if (nullptr == paint) { |
2291 paint = lazy.init(); | 2427 paint = lazy.init(); |
2292 } | 2428 } |
2293 | 2429 |
2294 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) | 2430 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) |
2295 | 2431 |
2296 while (iter.next()) { | 2432 while (iter.next()) { |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2449 LOOPER_END | 2585 LOOPER_END |
2450 } | 2586 } |
2451 | 2587 |
2452 void SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, | 2588 void SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, |
2453 const SkPaint& paint) { | 2589 const SkPaint& paint) { |
2454 | 2590 |
2455 SkRect storage; | 2591 SkRect storage; |
2456 const SkRect* bounds = nullptr; | 2592 const SkRect* bounds = nullptr; |
2457 if (paint.canComputeFastBounds()) { | 2593 if (paint.canComputeFastBounds()) { |
2458 storage = blob->bounds().makeOffset(x, y); | 2594 storage = blob->bounds().makeOffset(x, y); |
2595 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
2459 bounds = &paint.computeFastBounds(storage, &storage); | 2596 bounds = &paint.computeFastBounds(storage, &storage); |
2460 | 2597 |
2461 if (this->quickReject(*bounds)) { | 2598 if (this->quickReject(*bounds)) { |
2462 return; | 2599 return; |
2463 } | 2600 } |
2601 #else | |
2602 SkRect tmp; | |
2603 if (this->quickReject(paint.computeFastBounds(storage, &tmp))) { | |
2604 return; | |
2605 } | |
2606 bounds = &storage; | |
2607 #endif | |
2464 } | 2608 } |
2465 | 2609 |
2466 // We cannot filter in the looper as we normally do, because the paint is | 2610 // 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). | 2611 // incomplete at this point (text-related attributes are embedded within blo b run paints). |
2468 SkDrawFilter* drawFilter = fMCRec->fFilter; | 2612 SkDrawFilter* drawFilter = fMCRec->fFilter; |
2469 fMCRec->fFilter = nullptr; | 2613 fMCRec->fFilter = nullptr; |
2470 | 2614 |
2471 LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, bounds) | 2615 LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, bounds) |
2472 | 2616 |
2473 while (iter.next()) { | 2617 while (iter.next()) { |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2882 } | 3026 } |
2883 | 3027 |
2884 if (matrix) { | 3028 if (matrix) { |
2885 canvas->concat(*matrix); | 3029 canvas->concat(*matrix); |
2886 } | 3030 } |
2887 } | 3031 } |
2888 | 3032 |
2889 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { | 3033 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { |
2890 fCanvas->restoreToCount(fSaveCount); | 3034 fCanvas->restoreToCount(fSaveCount); |
2891 } | 3035 } |
OLD | NEW |