Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: src/core/SkCanvas.cpp

Issue 1304883004: Change saveLayer() semantics to take unfiltered bounds. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: More changes per review comments Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698