| 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 |