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 | 41 #define SK_SUPPORT_SRC_BOUNDS_BLOAT_FOR_IMAGEFILTERS |
43 #endif | |
44 | 42 |
45 /* | 43 /* |
46 * Return true if the drawing this rect would hit every pixels in the canvas. | 44 * Return true if the drawing this rect would hit every pixels in the canvas. |
47 * | 45 * |
48 * Returns false if | 46 * Returns false if |
49 * - rect does not contain the canvas' bounds | 47 * - rect does not contain the canvas' bounds |
50 * - paint is not fill | 48 * - paint is not fill |
51 * - paint would blur or otherwise change the coverage of the rect | 49 * - paint would blur or otherwise change the coverage of the rect |
52 */ | 50 */ |
53 bool SkCanvas::wouldOverwriteEntireSurface(const SkRect* rect, const SkPaint* pa
int, | 51 bool SkCanvas::wouldOverwriteEntireSurface(const SkRect* rect, const SkPaint* pa
int, |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 // there is no existing paint colorfilter, so we can just return the ima
gefilter's | 403 // there is no existing paint colorfilter, so we can just return the ima
gefilter's |
406 return imgCF; | 404 return imgCF; |
407 } | 405 } |
408 | 406 |
409 // The paint has both a colorfilter(paintCF) and an imagefilter-which-is-a-c
olorfilter(imgCF) | 407 // The paint has both a colorfilter(paintCF) and an imagefilter-which-is-a-c
olorfilter(imgCF) |
410 // and we need to combine them into a single colorfilter. | 408 // and we need to combine them into a single colorfilter. |
411 SkAutoTUnref<SkColorFilter> autoImgCF(imgCF); | 409 SkAutoTUnref<SkColorFilter> autoImgCF(imgCF); |
412 return SkColorFilter::CreateComposeFilter(imgCF, paintCF); | 410 return SkColorFilter::CreateComposeFilter(imgCF, paintCF); |
413 } | 411 } |
414 | 412 |
415 #ifndef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
416 /** | 413 /** |
417 * There are many bounds in skia. A circle's bounds is just its center extended
by its radius. | 414 * There are many bounds in skia. A circle's bounds is just its center extended
by its radius. |
418 * However, if we stroke a circle, then the "bounds" of that is larger, since it
will now draw | 415 * However, if we stroke a circle, then the "bounds" of that is larger, since it
will now draw |
419 * outside of its raw-bounds by 1/2 the stroke width. SkPaint has lots of optio
nal | 416 * outside of its raw-bounds by 1/2 the stroke width. SkPaint has lots of optio
nal |
420 * effects/attributes that can modify the effective bounds of a given primitive
-- maskfilters, | 417 * effects/attributes that can modify the effective bounds of a given primitive
-- maskfilters, |
421 * patheffects, stroking, etc. This function takes a raw bounds and a paint, an
d returns the | 418 * patheffects, stroking, etc. This function takes a raw bounds and a paint, an
d returns the |
422 * conservative "effective" bounds based on the settings in the paint... with on
e exception. This | 419 * conservative "effective" bounds based on the settings in the paint... with on
e exception. This |
423 * function does *not* look at the imagefilter, which can also modify the effect
ive bounds. It is | 420 * function does *not* look at the imagefilter, which can also modify the effect
ive bounds. It is |
424 * deliberately ignored. | 421 * deliberately ignored. |
425 */ | 422 */ |
426 static const SkRect& apply_paint_to_bounds_sans_imagefilter(const SkPaint& paint
, | 423 static const SkRect& apply_paint_to_bounds_sans_imagefilter(const SkPaint& paint
, |
427 const SkRect& rawBou
nds, | 424 const SkRect& rawBou
nds, |
428 SkRect* storage) { | 425 SkRect* storage) { |
429 SkPaint tmpUnfiltered(paint); | 426 SkPaint tmpUnfiltered(paint); |
430 tmpUnfiltered.setImageFilter(nullptr); | 427 tmpUnfiltered.setImageFilter(nullptr); |
431 if (tmpUnfiltered.canComputeFastBounds()) { | 428 if (tmpUnfiltered.canComputeFastBounds()) { |
432 return tmpUnfiltered.computeFastBounds(rawBounds, storage); | 429 return tmpUnfiltered.computeFastBounds(rawBounds, storage); |
433 } else { | 430 } else { |
434 return rawBounds; | 431 return rawBounds; |
435 } | 432 } |
436 } | 433 } |
437 #endif | |
438 | 434 |
439 class AutoDrawLooper { | 435 class AutoDrawLooper { |
440 public: | 436 public: |
441 // "rawBounds" is the original bounds of the primitive about to be drawn, un
modified by the | 437 // "rawBounds" is the original bounds of the primitive about to be drawn, un
modified by the |
442 // paint. It's used to determine the size of the offscreen layer for filters
. | 438 // paint. It's used to determine the size of the offscreen layer for filters
. |
443 // If null, the clip will be used instead. | 439 // If null, the clip will be used instead. |
444 AutoDrawLooper(SkCanvas* canvas, const SkSurfaceProps& props, const SkPaint&
paint, | 440 AutoDrawLooper(SkCanvas* canvas, const SkSurfaceProps& props, const SkPaint&
paint, |
445 bool skipLayerForImageFilter = false, | 441 bool skipLayerForImageFilter = false, |
446 const SkRect* rawBounds = nullptr) : fOrigPaint(paint) { | 442 const SkRect* rawBounds = nullptr) : fOrigPaint(paint) { |
447 fCanvas = canvas; | 443 fCanvas = canvas; |
(...skipping 23 matching lines...) Expand all Loading... |
471 * return (fPaint). We then draw the primitive (using srcover)
into a cleared | 467 * return (fPaint). We then draw the primitive (using srcover)
into a cleared |
472 * buffer/surface. | 468 * buffer/surface. |
473 * 3. Restore the layer created in #1 | 469 * 3. Restore the layer created in #1 |
474 * The imagefilter is passed the buffer/surface from the layer
(now filled with the | 470 * The imagefilter is passed the buffer/surface from the layer
(now filled with the |
475 * src pixels of the primitive). It returns a new "filtered" bu
ffer, which we | 471 * src pixels of the primitive). It returns a new "filtered" bu
ffer, which we |
476 * draw onto the previous layer using the xfermode from the ori
ginal paint. | 472 * draw onto the previous layer using the xfermode from the ori
ginal paint. |
477 */ | 473 */ |
478 SkPaint tmp; | 474 SkPaint tmp; |
479 tmp.setImageFilter(fPaint->getImageFilter()); | 475 tmp.setImageFilter(fPaint->getImageFilter()); |
480 tmp.setXfermode(fPaint->getXfermode()); | 476 tmp.setXfermode(fPaint->getXfermode()); |
481 #ifndef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
482 SkRect storage; | 477 SkRect storage; |
483 if (rawBounds) { | 478 if (rawBounds) { |
484 // Make rawBounds include all paint outsets except for those due
to image filters. | 479 // Make rawBounds include all paint outsets except for those due
to image filters. |
485 rawBounds = &apply_paint_to_bounds_sans_imagefilter(*fPaint, *ra
wBounds, &storage); | 480 rawBounds = &apply_paint_to_bounds_sans_imagefilter(*fPaint, *ra
wBounds, &storage); |
486 } | 481 } |
487 #endif | |
488 (void)canvas->internalSaveLayer(rawBounds, &tmp, SkCanvas::kARGB_Cli
pLayer_SaveFlag, | 482 (void)canvas->internalSaveLayer(rawBounds, &tmp, SkCanvas::kARGB_Cli
pLayer_SaveFlag, |
489 SkCanvas::kFullLayer_SaveLayerStrate
gy); | 483 SkCanvas::kFullLayer_SaveLayerStrate
gy); |
490 fTempLayerForImageFilter = true; | 484 fTempLayerForImageFilter = true; |
491 // we remove the imagefilter/xfermode inside doNext() | 485 // we remove the imagefilter/xfermode inside doNext() |
492 } | 486 } |
493 | 487 |
494 if (SkDrawLooper* looper = paint.getLooper()) { | 488 if (SkDrawLooper* looper = paint.getLooper()) { |
495 void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Contex
t>( | 489 void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Contex
t>( |
496 looper->contextSize()); | 490 looper->contextSize()); |
497 fLooperContext = looper->createContext(canvas, buffer); | 491 fLooperContext = looper->createContext(canvas, buffer); |
(...skipping 1511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2009 | 2003 |
2010 SkRect r, storage; | 2004 SkRect r, storage; |
2011 const SkRect* bounds = nullptr; | 2005 const SkRect* bounds = nullptr; |
2012 if (paint.canComputeFastBounds()) { | 2006 if (paint.canComputeFastBounds()) { |
2013 // special-case 2 points (common for drawing a single line) | 2007 // special-case 2 points (common for drawing a single line) |
2014 if (2 == count) { | 2008 if (2 == count) { |
2015 r.set(pts[0], pts[1]); | 2009 r.set(pts[0], pts[1]); |
2016 } else { | 2010 } else { |
2017 r.set(pts, SkToInt(count)); | 2011 r.set(pts, SkToInt(count)); |
2018 } | 2012 } |
2019 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
2020 bounds = &paint.computeFastStrokeBounds(r, &storage); | |
2021 if (this->quickReject(*bounds)) { | |
2022 return; | |
2023 } | |
2024 #else | |
2025 if (this->quickReject(paint.computeFastStrokeBounds(r, &storage))) { | 2013 if (this->quickReject(paint.computeFastStrokeBounds(r, &storage))) { |
2026 return; | 2014 return; |
2027 } | 2015 } |
2028 bounds = &r; | 2016 bounds = &r; |
2029 #endif | |
2030 } | 2017 } |
2031 | 2018 |
2032 SkASSERT(pts != nullptr); | 2019 SkASSERT(pts != nullptr); |
2033 | 2020 |
2034 LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds) | 2021 LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds) |
2035 | 2022 |
2036 while (iter.next()) { | 2023 while (iter.next()) { |
2037 iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint()); | 2024 iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint()); |
2038 } | 2025 } |
2039 | 2026 |
2040 LOOPER_END | 2027 LOOPER_END |
2041 } | 2028 } |
2042 | 2029 |
2043 void SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) { | 2030 void SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) { |
2044 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRect()"); | 2031 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRect()"); |
2045 SkRect storage; | 2032 SkRect storage; |
2046 const SkRect* bounds = nullptr; | 2033 const SkRect* bounds = nullptr; |
2047 if (paint.canComputeFastBounds()) { | 2034 if (paint.canComputeFastBounds()) { |
2048 // Skia will draw an inverted rect, because it explicitly "sorts" it dow
nstream. | 2035 // Skia will draw an inverted rect, because it explicitly "sorts" it dow
nstream. |
2049 // To prevent accidental rejecting at this stage, we have to sort it bef
ore we check. | 2036 // To prevent accidental rejecting at this stage, we have to sort it bef
ore we check. |
2050 SkRect tmp(r); | 2037 SkRect tmp(r); |
2051 tmp.sort(); | 2038 tmp.sort(); |
2052 | 2039 |
2053 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
2054 bounds = &paint.computeFastBounds(tmp, &storage); | |
2055 if (this->quickReject(*bounds)) { | |
2056 return; | |
2057 } | |
2058 #else | |
2059 if (this->quickReject(paint.computeFastBounds(tmp, &storage))) { | 2040 if (this->quickReject(paint.computeFastBounds(tmp, &storage))) { |
2060 return; | 2041 return; |
2061 } | 2042 } |
2062 bounds = &r; | 2043 bounds = &r; |
2063 #endif | |
2064 } | 2044 } |
2065 | 2045 |
2066 LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kRect_Type, bound
s, false) | 2046 LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kRect_Type, bound
s, false) |
2067 | 2047 |
2068 while (iter.next()) { | 2048 while (iter.next()) { |
2069 iter.fDevice->drawRect(iter, r, looper.paint()); | 2049 iter.fDevice->drawRect(iter, r, looper.paint()); |
2070 } | 2050 } |
2071 | 2051 |
2072 LOOPER_END | 2052 LOOPER_END |
2073 } | 2053 } |
2074 | 2054 |
2075 void SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) { | 2055 void SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) { |
2076 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawOval()"); | 2056 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawOval()"); |
2077 SkRect storage; | 2057 SkRect storage; |
2078 const SkRect* bounds = nullptr; | 2058 const SkRect* bounds = nullptr; |
2079 if (paint.canComputeFastBounds()) { | 2059 if (paint.canComputeFastBounds()) { |
2080 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
2081 bounds = &paint.computeFastBounds(oval, &storage); | |
2082 if (this->quickReject(*bounds)) { | |
2083 return; | |
2084 } | |
2085 #else | |
2086 if (this->quickReject(paint.computeFastBounds(oval, &storage))) { | 2060 if (this->quickReject(paint.computeFastBounds(oval, &storage))) { |
2087 return; | 2061 return; |
2088 } | 2062 } |
2089 bounds = &oval; | 2063 bounds = &oval; |
2090 #endif | |
2091 } | 2064 } |
2092 | 2065 |
2093 LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds) | 2066 LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds) |
2094 | 2067 |
2095 while (iter.next()) { | 2068 while (iter.next()) { |
2096 iter.fDevice->drawOval(iter, oval, looper.paint()); | 2069 iter.fDevice->drawOval(iter, oval, looper.paint()); |
2097 } | 2070 } |
2098 | 2071 |
2099 LOOPER_END | 2072 LOOPER_END |
2100 } | 2073 } |
2101 | 2074 |
2102 void SkCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { | 2075 void SkCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { |
2103 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRRect()"); | 2076 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRRect()"); |
2104 SkRect storage; | 2077 SkRect storage; |
2105 const SkRect* bounds = nullptr; | 2078 const SkRect* bounds = nullptr; |
2106 if (paint.canComputeFastBounds()) { | 2079 if (paint.canComputeFastBounds()) { |
2107 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
2108 bounds = &paint.computeFastBounds(rrect.getBounds(), &storage); | |
2109 if (this->quickReject(*bounds)) { | |
2110 return; | |
2111 } | |
2112 #else | |
2113 if (this->quickReject(paint.computeFastBounds(rrect.getBounds(), &storag
e))) { | 2080 if (this->quickReject(paint.computeFastBounds(rrect.getBounds(), &storag
e))) { |
2114 return; | 2081 return; |
2115 } | 2082 } |
2116 bounds = &rrect.getBounds(); | 2083 bounds = &rrect.getBounds(); |
2117 #endif | |
2118 } | 2084 } |
2119 | 2085 |
2120 if (rrect.isRect()) { | 2086 if (rrect.isRect()) { |
2121 // call the non-virtual version | 2087 // call the non-virtual version |
2122 this->SkCanvas::drawRect(rrect.getBounds(), paint); | 2088 this->SkCanvas::drawRect(rrect.getBounds(), paint); |
2123 return; | 2089 return; |
2124 } else if (rrect.isOval()) { | 2090 } else if (rrect.isOval()) { |
2125 // call the non-virtual version | 2091 // call the non-virtual version |
2126 this->SkCanvas::drawOval(rrect.getBounds(), paint); | 2092 this->SkCanvas::drawOval(rrect.getBounds(), paint); |
2127 return; | 2093 return; |
2128 } | 2094 } |
2129 | 2095 |
2130 LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) | 2096 LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) |
2131 | 2097 |
2132 while (iter.next()) { | 2098 while (iter.next()) { |
2133 iter.fDevice->drawRRect(iter, rrect, looper.paint()); | 2099 iter.fDevice->drawRRect(iter, rrect, looper.paint()); |
2134 } | 2100 } |
2135 | 2101 |
2136 LOOPER_END | 2102 LOOPER_END |
2137 } | 2103 } |
2138 | 2104 |
2139 void SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, | 2105 void SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, |
2140 const SkPaint& paint) { | 2106 const SkPaint& paint) { |
2141 SkRect storage; | 2107 SkRect storage; |
2142 const SkRect* bounds = nullptr; | 2108 const SkRect* bounds = nullptr; |
2143 if (paint.canComputeFastBounds()) { | 2109 if (paint.canComputeFastBounds()) { |
2144 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
2145 bounds = &paint.computeFastBounds(outer.getBounds(), &storage); | |
2146 if (this->quickReject(*bounds)) { | |
2147 return; | |
2148 } | |
2149 #else | |
2150 if (this->quickReject(paint.computeFastBounds(outer.getBounds(), &storag
e))) { | 2110 if (this->quickReject(paint.computeFastBounds(outer.getBounds(), &storag
e))) { |
2151 return; | 2111 return; |
2152 } | 2112 } |
2153 bounds = &outer.getBounds(); | 2113 bounds = &outer.getBounds(); |
2154 #endif | |
2155 } | 2114 } |
2156 | 2115 |
2157 LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) | 2116 LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) |
2158 | 2117 |
2159 while (iter.next()) { | 2118 while (iter.next()) { |
2160 iter.fDevice->drawDRRect(iter, outer, inner, looper.paint()); | 2119 iter.fDevice->drawDRRect(iter, outer, inner, looper.paint()); |
2161 } | 2120 } |
2162 | 2121 |
2163 LOOPER_END | 2122 LOOPER_END |
2164 } | 2123 } |
2165 | 2124 |
2166 void SkCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { | 2125 void SkCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { |
2167 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPath()"); | 2126 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPath()"); |
2168 if (!path.isFinite()) { | 2127 if (!path.isFinite()) { |
2169 return; | 2128 return; |
2170 } | 2129 } |
2171 | 2130 |
2172 SkRect storage; | 2131 SkRect storage; |
2173 const SkRect* bounds = nullptr; | 2132 const SkRect* bounds = nullptr; |
2174 if (!path.isInverseFillType() && paint.canComputeFastBounds()) { | 2133 if (!path.isInverseFillType() && paint.canComputeFastBounds()) { |
2175 const SkRect& pathBounds = path.getBounds(); | 2134 const SkRect& pathBounds = path.getBounds(); |
2176 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
2177 bounds = &paint.computeFastBounds(pathBounds, &storage); | |
2178 if (this->quickReject(*bounds)) { | |
2179 return; | |
2180 } | |
2181 #else | |
2182 if (this->quickReject(paint.computeFastBounds(pathBounds, &storage))) { | 2135 if (this->quickReject(paint.computeFastBounds(pathBounds, &storage))) { |
2183 return; | 2136 return; |
2184 } | 2137 } |
2185 bounds = &pathBounds; | 2138 bounds = &pathBounds; |
2186 #endif | |
2187 } | 2139 } |
2188 | 2140 |
2189 const SkRect& r = path.getBounds(); | 2141 const SkRect& r = path.getBounds(); |
2190 if (r.width() <= 0 && r.height() <= 0) { | 2142 if (r.width() <= 0 && r.height() <= 0) { |
2191 if (path.isInverseFillType()) { | 2143 if (path.isInverseFillType()) { |
2192 this->internalDrawPaint(paint); | 2144 this->internalDrawPaint(paint); |
2193 return; | 2145 return; |
2194 } | 2146 } |
2195 } | 2147 } |
2196 | 2148 |
2197 LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, bounds) | 2149 LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, bounds) |
2198 | 2150 |
2199 while (iter.next()) { | 2151 while (iter.next()) { |
2200 iter.fDevice->drawPath(iter, path, looper.paint()); | 2152 iter.fDevice->drawPath(iter, path, looper.paint()); |
2201 } | 2153 } |
2202 | 2154 |
2203 LOOPER_END | 2155 LOOPER_END |
2204 } | 2156 } |
2205 | 2157 |
2206 void SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const S
kPaint* paint) { | 2158 void SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const S
kPaint* paint) { |
2207 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImage()"); | 2159 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImage()"); |
2208 SkRect bounds = SkRect::MakeXYWH(x, y, | 2160 SkRect bounds = SkRect::MakeXYWH(x, y, |
2209 SkIntToScalar(image->width()), SkIntToScala
r(image->height())); | 2161 SkIntToScalar(image->width()), SkIntToScala
r(image->height())); |
2210 if (nullptr == paint || paint->canComputeFastBounds()) { | 2162 if (nullptr == paint || paint->canComputeFastBounds()) { |
2211 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
2212 if (paint) { | |
2213 paint->computeFastBounds(bounds, &bounds); | |
2214 } | |
2215 if (this->quickReject(bounds)) { | |
2216 return; | |
2217 } | |
2218 #else | |
2219 SkRect tmp = bounds; | 2163 SkRect tmp = bounds; |
2220 if (paint) { | 2164 if (paint) { |
2221 paint->computeFastBounds(tmp, &tmp); | 2165 paint->computeFastBounds(tmp, &tmp); |
2222 } | 2166 } |
2223 if (this->quickReject(tmp)) { | 2167 if (this->quickReject(tmp)) { |
2224 return; | 2168 return; |
2225 } | 2169 } |
2226 #endif | |
2227 } | 2170 } |
2228 | 2171 |
2229 SkLazyPaint lazy; | 2172 SkLazyPaint lazy; |
2230 if (nullptr == paint) { | 2173 if (nullptr == paint) { |
2231 paint = lazy.init(); | 2174 paint = lazy.init(); |
2232 } | 2175 } |
2233 | 2176 |
2234 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &bounds) | 2177 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &bounds) |
2235 | 2178 |
2236 while (iter.next()) { | 2179 while (iter.next()) { |
2237 iter.fDevice->drawImage(iter, image, x, y, looper.paint()); | 2180 iter.fDevice->drawImage(iter, image, x, y, looper.paint()); |
2238 } | 2181 } |
2239 | 2182 |
2240 LOOPER_END | 2183 LOOPER_END |
2241 } | 2184 } |
2242 | 2185 |
2243 void SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const Sk
Rect& dst, | 2186 void SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const Sk
Rect& dst, |
2244 const SkPaint* paint, SrcRectConstraint constrain
t) { | 2187 const SkPaint* paint, SrcRectConstraint constrain
t) { |
2245 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageRect()"); | 2188 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageRect()"); |
2246 SkRect storage; | 2189 SkRect storage; |
2247 const SkRect* bounds = &dst; | 2190 const SkRect* bounds = &dst; |
2248 if (nullptr == paint || paint->canComputeFastBounds()) { | 2191 if (nullptr == paint || paint->canComputeFastBounds()) { |
2249 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
2250 if (paint) { | |
2251 bounds = &paint->computeFastBounds(dst, &storage); | |
2252 } | |
2253 if (this->quickReject(*bounds)) { | |
2254 return; | |
2255 } | |
2256 #else | |
2257 storage = dst; | 2192 storage = dst; |
2258 if (paint) { | 2193 if (paint) { |
2259 paint->computeFastBounds(dst, &storage); | 2194 paint->computeFastBounds(dst, &storage); |
2260 } | 2195 } |
2261 if (this->quickReject(storage)) { | 2196 if (this->quickReject(storage)) { |
2262 return; | 2197 return; |
2263 } | 2198 } |
2264 #endif | |
2265 } | 2199 } |
2266 SkLazyPaint lazy; | 2200 SkLazyPaint lazy; |
2267 if (nullptr == paint) { | 2201 if (nullptr == paint) { |
2268 paint = lazy.init(); | 2202 paint = lazy.init(); |
2269 } | 2203 } |
2270 | 2204 |
2271 LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, bo
unds, | 2205 LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, bo
unds, |
2272 image->isOpaque()) | 2206 image->isOpaque()) |
2273 | 2207 |
2274 while (iter.next()) { | 2208 while (iter.next()) { |
(...skipping 16 matching lines...) Expand all Loading... |
2291 paint = lazy.init(); | 2225 paint = lazy.init(); |
2292 } | 2226 } |
2293 | 2227 |
2294 const SkMatrix matrix = SkMatrix::MakeTrans(x, y); | 2228 const SkMatrix matrix = SkMatrix::MakeTrans(x, y); |
2295 | 2229 |
2296 SkRect storage; | 2230 SkRect storage; |
2297 const SkRect* bounds = nullptr; | 2231 const SkRect* bounds = nullptr; |
2298 if (paint->canComputeFastBounds()) { | 2232 if (paint->canComputeFastBounds()) { |
2299 bitmap.getBounds(&storage); | 2233 bitmap.getBounds(&storage); |
2300 matrix.mapRect(&storage); | 2234 matrix.mapRect(&storage); |
2301 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
2302 bounds = &paint->computeFastBounds(storage, &storage); | |
2303 if (this->quickReject(*bounds)) { | |
2304 return; | |
2305 } | |
2306 #else | |
2307 SkRect tmp = storage; | 2235 SkRect tmp = storage; |
2308 if (this->quickReject(paint->computeFastBounds(tmp, &tmp))) { | 2236 if (this->quickReject(paint->computeFastBounds(tmp, &tmp))) { |
2309 return; | 2237 return; |
2310 } | 2238 } |
2311 bounds = &storage; | 2239 bounds = &storage; |
2312 #endif | |
2313 } | 2240 } |
2314 | 2241 |
2315 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) | 2242 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) |
2316 | 2243 |
2317 while (iter.next()) { | 2244 while (iter.next()) { |
2318 iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint()); | 2245 iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint()); |
2319 } | 2246 } |
2320 | 2247 |
2321 LOOPER_END | 2248 LOOPER_END |
2322 } | 2249 } |
2323 | 2250 |
2324 // this one is non-virtual, so it can be called safely by other canvas apis | 2251 // this one is non-virtual, so it can be called safely by other canvas apis |
2325 void SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, | 2252 void SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, |
2326 const SkRect& dst, const SkPaint* paint, | 2253 const SkRect& dst, const SkPaint* paint, |
2327 SrcRectConstraint constraint) { | 2254 SrcRectConstraint constraint) { |
2328 if (bitmap.drawsNothing() || dst.isEmpty()) { | 2255 if (bitmap.drawsNothing() || dst.isEmpty()) { |
2329 return; | 2256 return; |
2330 } | 2257 } |
2331 | 2258 |
2332 SkRect storage; | 2259 SkRect storage; |
2333 const SkRect* bounds = &dst; | 2260 const SkRect* bounds = &dst; |
2334 if (nullptr == paint || paint->canComputeFastBounds()) { | 2261 if (nullptr == paint || paint->canComputeFastBounds()) { |
2335 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
2336 if (paint) { | |
2337 bounds = &paint->computeFastBounds(dst, &storage); | |
2338 } | |
2339 if (this->quickReject(*bounds)) { | |
2340 return; | |
2341 } | |
2342 #else | |
2343 if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) :
dst)) { | 2262 if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) :
dst)) { |
2344 return; | 2263 return; |
2345 } | 2264 } |
2346 #endif | |
2347 } | 2265 } |
2348 | 2266 |
2349 SkLazyPaint lazy; | 2267 SkLazyPaint lazy; |
2350 if (nullptr == paint) { | 2268 if (nullptr == paint) { |
2351 paint = lazy.init(); | 2269 paint = lazy.init(); |
2352 } | 2270 } |
2353 | 2271 |
2354 LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, bo
unds, | 2272 LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, bo
unds, |
2355 bitmap.isOpaque()) | 2273 bitmap.isOpaque()) |
2356 | 2274 |
(...skipping 11 matching lines...) Expand all Loading... |
2368 this->internalDrawBitmapRect(bitmap, src, dst, paint, constraint); | 2286 this->internalDrawBitmapRect(bitmap, src, dst, paint, constraint); |
2369 } | 2287 } |
2370 | 2288 |
2371 void SkCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, cons
t SkRect& dst, | 2289 void SkCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, cons
t SkRect& dst, |
2372 const SkPaint* paint) { | 2290 const SkPaint* paint) { |
2373 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageNine()"); | 2291 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageNine()"); |
2374 | 2292 |
2375 SkRect storage; | 2293 SkRect storage; |
2376 const SkRect* bounds = &dst; | 2294 const SkRect* bounds = &dst; |
2377 if (nullptr == paint || paint->canComputeFastBounds()) { | 2295 if (nullptr == paint || paint->canComputeFastBounds()) { |
2378 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
2379 if (paint) { | |
2380 bounds = &paint->computeFastBounds(dst, &storage); | |
2381 } | |
2382 if (this->quickReject(*bounds)) { | |
2383 return; | |
2384 } | |
2385 #else | |
2386 if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) :
dst)) { | 2296 if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) :
dst)) { |
2387 return; | 2297 return; |
2388 } | 2298 } |
2389 #endif | |
2390 } | 2299 } |
2391 | 2300 |
2392 SkLazyPaint lazy; | 2301 SkLazyPaint lazy; |
2393 if (nullptr == paint) { | 2302 if (nullptr == paint) { |
2394 paint = lazy.init(); | 2303 paint = lazy.init(); |
2395 } | 2304 } |
2396 | 2305 |
2397 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) | 2306 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) |
2398 | 2307 |
2399 while (iter.next()) { | 2308 while (iter.next()) { |
2400 iter.fDevice->drawImageNine(iter, image, center, dst, looper.paint()); | 2309 iter.fDevice->drawImageNine(iter, image, center, dst, looper.paint()); |
2401 } | 2310 } |
2402 | 2311 |
2403 LOOPER_END | 2312 LOOPER_END |
2404 } | 2313 } |
2405 | 2314 |
2406 void SkCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, c
onst SkRect& dst, | 2315 void SkCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, c
onst SkRect& dst, |
2407 const SkPaint* paint) { | 2316 const SkPaint* paint) { |
2408 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapNine()"); | 2317 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapNine()"); |
2409 SkDEBUGCODE(bitmap.validate();) | 2318 SkDEBUGCODE(bitmap.validate();) |
2410 | 2319 |
2411 SkRect storage; | 2320 SkRect storage; |
2412 const SkRect* bounds = &dst; | 2321 const SkRect* bounds = &dst; |
2413 if (nullptr == paint || paint->canComputeFastBounds()) { | 2322 if (nullptr == paint || paint->canComputeFastBounds()) { |
2414 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
2415 if (paint) { | |
2416 bounds = &paint->computeFastBounds(dst, &storage); | |
2417 } | |
2418 if (this->quickReject(*bounds)) { | |
2419 return; | |
2420 } | |
2421 #else | |
2422 if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) :
dst)) { | 2323 if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) :
dst)) { |
2423 return; | 2324 return; |
2424 } | 2325 } |
2425 #endif | |
2426 } | 2326 } |
2427 | 2327 |
2428 SkLazyPaint lazy; | 2328 SkLazyPaint lazy; |
2429 if (nullptr == paint) { | 2329 if (nullptr == paint) { |
2430 paint = lazy.init(); | 2330 paint = lazy.init(); |
2431 } | 2331 } |
2432 | 2332 |
2433 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) | 2333 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) |
2434 | 2334 |
2435 while (iter.next()) { | 2335 while (iter.next()) { |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2588 LOOPER_END | 2488 LOOPER_END |
2589 } | 2489 } |
2590 | 2490 |
2591 void SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, | 2491 void SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, |
2592 const SkPaint& paint) { | 2492 const SkPaint& paint) { |
2593 | 2493 |
2594 SkRect storage; | 2494 SkRect storage; |
2595 const SkRect* bounds = nullptr; | 2495 const SkRect* bounds = nullptr; |
2596 if (paint.canComputeFastBounds()) { | 2496 if (paint.canComputeFastBounds()) { |
2597 storage = blob->bounds().makeOffset(x, y); | 2497 storage = blob->bounds().makeOffset(x, y); |
2598 #ifdef SK_SAVE_LAYER_BOUNDS_ARE_FILTERED | |
2599 bounds = &paint.computeFastBounds(storage, &storage); | |
2600 | |
2601 if (this->quickReject(*bounds)) { | |
2602 return; | |
2603 } | |
2604 #else | |
2605 SkRect tmp; | 2498 SkRect tmp; |
2606 if (this->quickReject(paint.computeFastBounds(storage, &tmp))) { | 2499 if (this->quickReject(paint.computeFastBounds(storage, &tmp))) { |
2607 return; | 2500 return; |
2608 } | 2501 } |
2609 bounds = &storage; | 2502 bounds = &storage; |
2610 #endif | |
2611 } | 2503 } |
2612 | 2504 |
2613 // We cannot filter in the looper as we normally do, because the paint is | 2505 // We cannot filter in the looper as we normally do, because the paint is |
2614 // incomplete at this point (text-related attributes are embedded within blo
b run paints). | 2506 // incomplete at this point (text-related attributes are embedded within blo
b run paints). |
2615 SkDrawFilter* drawFilter = fMCRec->fFilter; | 2507 SkDrawFilter* drawFilter = fMCRec->fFilter; |
2616 fMCRec->fFilter = nullptr; | 2508 fMCRec->fFilter = nullptr; |
2617 | 2509 |
2618 LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, bounds) | 2510 LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, bounds) |
2619 | 2511 |
2620 while (iter.next()) { | 2512 while (iter.next()) { |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3029 } | 2921 } |
3030 | 2922 |
3031 if (matrix) { | 2923 if (matrix) { |
3032 canvas->concat(*matrix); | 2924 canvas->concat(*matrix); |
3033 } | 2925 } |
3034 } | 2926 } |
3035 | 2927 |
3036 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { | 2928 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { |
3037 fCanvas->restoreToCount(fSaveCount); | 2929 fCanvas->restoreToCount(fSaveCount); |
3038 } | 2930 } |
OLD | NEW |