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

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

Issue 1236023004: have canvas send discard instead of retain if the draw would overwrite everything (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 5 months 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
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 "SkCanvas.h" 8 #include "SkCanvas.h"
9 #include "SkCanvasPriv.h" 9 #include "SkCanvasPriv.h"
10 #include "SkBitmapDevice.h" 10 #include "SkBitmapDevice.h"
11 #include "SkColorFilter.h" 11 #include "SkColorFilter.h"
12 #include "SkDraw.h" 12 #include "SkDraw.h"
13 #include "SkDrawable.h" 13 #include "SkDrawable.h"
14 #include "SkDrawFilter.h" 14 #include "SkDrawFilter.h"
15 #include "SkDrawLooper.h" 15 #include "SkDrawLooper.h"
16 #include "SkErrorInternals.h" 16 #include "SkErrorInternals.h"
17 #include "SkImage.h" 17 #include "SkImage.h"
18 #include "SkMetaData.h" 18 #include "SkMetaData.h"
19 #include "SkNinePatchIter.h" 19 #include "SkNinePatchIter.h"
20 #include "SkPaintPriv.h"
20 #include "SkPathOps.h" 21 #include "SkPathOps.h"
21 #include "SkPatchUtils.h" 22 #include "SkPatchUtils.h"
22 #include "SkPicture.h" 23 #include "SkPicture.h"
23 #include "SkRasterClip.h" 24 #include "SkRasterClip.h"
24 #include "SkReadPixelsRec.h" 25 #include "SkReadPixelsRec.h"
25 #include "SkRRect.h" 26 #include "SkRRect.h"
26 #include "SkSmallAllocator.h" 27 #include "SkSmallAllocator.h"
27 #include "SkSurface_Base.h" 28 #include "SkSurface_Base.h"
28 #include "SkTemplates.h" 29 #include "SkTemplates.h"
29 #include "SkTextBlob.h" 30 #include "SkTextBlob.h"
30 #include "SkTextFormatParams.h" 31 #include "SkTextFormatParams.h"
31 #include "SkTLazy.h" 32 #include "SkTLazy.h"
32 #include "SkTraceEvent.h" 33 #include "SkTraceEvent.h"
33 #include "SkUtils.h" 34 #include "SkUtils.h"
34 35
35 #if SK_SUPPORT_GPU 36 #if SK_SUPPORT_GPU
36 #include "GrRenderTarget.h" 37 #include "GrRenderTarget.h"
37 #endif 38 #endif
38 39
40 /*
41 * Return true if the drawing this rect would hit every pixels in the canvas.
42 *
43 * Returns false if
44 * - rect does not contain the canvas' bounds
45 * - paint is not fill
46 * - paint would blur or otherwise change the coverage of the rect
47 */
48 bool SkCanvas::wouldOverwriteEntireSurface(const SkRect* rect, const SkPaint* pa int,
49 ShaderOverrideOpacity overrideOpacity ) const {
50 SK_COMPILE_ASSERT((int)SkPaintPriv::kNone_ShaderOverrideOpacity ==
51 (int)kNone_ShaderOverrideOpacity,
52 need_matching_enums0);
53 SK_COMPILE_ASSERT((int)SkPaintPriv::kOpaque_ShaderOverrideOpacity ==
54 (int)kOpaque_ShaderOverrideOpacity,
55 need_matching_enums1);
56 SK_COMPILE_ASSERT((int)SkPaintPriv::kNotOpaque_ShaderOverrideOpacity ==
57 (int)kNotOpaque_ShaderOverrideOpacity,
58 need_matching_enums2);
59
60 const SkISize size = this->getBaseLayerSize();
61 const SkRect bounds = SkRect::MakeIWH(size.width(), size.height());
62 if (!this->getClipStack()->quickContains(bounds)) {
63 return false;
64 }
65
66 if (rect) {
67 if (!this->getTotalMatrix().rectStaysRect()) {
68 return false; // conservative
69 }
70
71 SkRect devRect;
72 this->getTotalMatrix().mapRect(&devRect, *rect);
73 if (devRect.contains(bounds)) {
74 return false;
75 }
76 }
77
78 if (paint) {
79 SkPaint::Style paintStyle = paint->getStyle();
80 if (!(paintStyle == SkPaint::kFill_Style ||
81 paintStyle == SkPaint::kStrokeAndFill_Style)) {
82 return false;
83 }
84 if (paint->getMaskFilter() || paint->getLooper()
85 || paint->getPathEffect() || paint->getImageFilter()) {
86 return false; // conservative
87 }
88 }
89 return SkPaintPriv::Overwrites(paint, (SkPaintPriv::ShaderOverrideOpacity)ov errideOpacity);
90 }
91
92 //////////////////////////////////////////////////////////////////////////////// ///////////////////
93
39 static bool gIgnoreSaveLayerBounds; 94 static bool gIgnoreSaveLayerBounds;
40 void SkCanvas::Internal_Private_SetIgnoreSaveLayerBounds(bool ignore) { 95 void SkCanvas::Internal_Private_SetIgnoreSaveLayerBounds(bool ignore) {
41 gIgnoreSaveLayerBounds = ignore; 96 gIgnoreSaveLayerBounds = ignore;
42 } 97 }
43 bool SkCanvas::Internal_Private_GetIgnoreSaveLayerBounds() { 98 bool SkCanvas::Internal_Private_GetIgnoreSaveLayerBounds() {
44 return gIgnoreSaveLayerBounds; 99 return gIgnoreSaveLayerBounds;
45 } 100 }
46 101
47 static bool gTreatSpriteAsBitmap; 102 static bool gTreatSpriteAsBitmap;
48 void SkCanvas::Internal_Private_SetTreatSpriteAsBitmap(bool spriteAsBitmap) { 103 void SkCanvas::Internal_Private_SetTreatSpriteAsBitmap(bool spriteAsBitmap) {
(...skipping 23 matching lines...) Expand all
72 #else 127 #else
73 #define inc_layer() 128 #define inc_layer()
74 #define dec_layer() 129 #define dec_layer()
75 #define inc_rec() 130 #define inc_rec()
76 #define dec_rec() 131 #define dec_rec()
77 #define inc_canvas() 132 #define inc_canvas()
78 #define dec_canvas() 133 #define dec_canvas()
79 #endif 134 #endif
80 135
81 typedef SkTLazy<SkPaint> SkLazyPaint; 136 typedef SkTLazy<SkPaint> SkLazyPaint;
82 137
robertphillips 2015/07/20 15:15:30 same typo here
83 void SkCanvas::predrawNotify() { 138 void SkCanvas::predrawNotify(bool willOverwritesEntireSurface) {
84 if (fSurfaceBase) { 139 if (fSurfaceBase) {
85 fSurfaceBase->aboutToDraw(SkSurface::kRetain_ContentChangeMode); 140 fSurfaceBase->aboutToDraw(willOverwritesEntireSurface
141 ? SkSurface::kDiscard_ContentChangeMode
142 : SkSurface::kRetain_ContentChangeMode);
86 } 143 }
87 } 144 }
88 145
146 void SkCanvas::predrawNotify(const SkRect* rect, const SkPaint* paint,
147 ShaderOverrideOpacity overrideOpacity) {
148 if (fSurfaceBase) {
149 SkSurface::ContentChangeMode mode = SkSurface::kRetain_ContentChangeMode ;
robertphillips 2015/07/20 15:15:30 complete -> completely
150 // Since willOverwriteAllPixels() may not be complete free to call, we o nly do so if
151 // there is an outstanding snapshot, since w/o that, there will be no co py-on-write
152 // and therefore we don't care which mode we're in.
153 //
154 if (fSurfaceBase->outstandingImageSnapshot()) {
155 if (this->wouldOverwriteEntireSurface(rect, paint, overrideOpacity)) {
156 mode = SkSurface::kDiscard_ContentChangeMode;
157 }
158 }
159 fSurfaceBase->aboutToDraw(mode);
160 }
161 }
162
89 /////////////////////////////////////////////////////////////////////////////// 163 ///////////////////////////////////////////////////////////////////////////////
90 164
91 static uint32_t filter_paint_flags(const SkSurfaceProps& props, uint32_t flags) { 165 static uint32_t filter_paint_flags(const SkSurfaceProps& props, uint32_t flags) {
92 const uint32_t propFlags = props.flags(); 166 const uint32_t propFlags = props.flags();
93 if (propFlags & SkSurfaceProps::kDisallowDither_Flag) { 167 if (propFlags & SkSurfaceProps::kDisallowDither_Flag) {
94 flags &= ~SkPaint::kDither_Flag; 168 flags &= ~SkPaint::kDither_Flag;
95 } 169 }
96 if (propFlags & SkSurfaceProps::kDisallowAntiAlias_Flag) { 170 if (propFlags & SkSurfaceProps::kDisallowAntiAlias_Flag) {
97 flags &= ~SkPaint::kAntiAlias_Flag; 171 flags &= ~SkPaint::kAntiAlias_Flag;
98 } 172 }
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 AutoDrawLooper looper(this, fProps, paint, true); \ 564 AutoDrawLooper looper(this, fProps, paint, true); \
491 while (looper.next(type)) { \ 565 while (looper.next(type)) { \
492 SkDrawIter iter(this); 566 SkDrawIter iter(this);
493 567
494 #define LOOPER_BEGIN(paint, type, bounds) \ 568 #define LOOPER_BEGIN(paint, type, bounds) \
495 this->predrawNotify(); \ 569 this->predrawNotify(); \
496 AutoDrawLooper looper(this, fProps, paint, false, bounds); \ 570 AutoDrawLooper looper(this, fProps, paint, false, bounds); \
497 while (looper.next(type)) { \ 571 while (looper.next(type)) { \
498 SkDrawIter iter(this); 572 SkDrawIter iter(this);
499 573
574 #define LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, type, bounds, auxOpaque) \
575 this->predrawNotify(bounds, &paint, auxOpaque); \
576 AutoDrawLooper looper(this, fProps, paint, false, bounds); \
577 while (looper.next(type)) { \
578 SkDrawIter iter(this);
579
500 #define LOOPER_END } 580 #define LOOPER_END }
501 581
502 //////////////////////////////////////////////////////////////////////////// 582 ////////////////////////////////////////////////////////////////////////////
503 583
504 void SkCanvas::resetForNextPicture(const SkIRect& bounds) { 584 void SkCanvas::resetForNextPicture(const SkIRect& bounds) {
505 this->restoreToCount(1); 585 this->restoreToCount(1);
506 fCachedLocalClipBounds.setEmpty(); 586 fCachedLocalClipBounds.setEmpty();
507 fCachedLocalClipBoundsDirty = true; 587 fCachedLocalClipBoundsDirty = true;
508 fClipStack->reset(); 588 fClipStack->reset();
509 fMCRec->reset(bounds); 589 fMCRec->reset(bounds);
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 if (x > 0) { 888 if (x > 0) {
809 x = 0; 889 x = 0;
810 } 890 }
811 if (y > 0) { 891 if (y > 0) {
812 y = 0; 892 y = 0;
813 } 893 }
814 // here x,y are either 0 or negative 894 // here x,y are either 0 or negative
815 pixels = ((const char*)pixels - y * rowBytes - x * info.bytesPerPixel()); 895 pixels = ((const char*)pixels - y * rowBytes - x * info.bytesPerPixel());
816 896
817 // Tell our owning surface to bump its generation ID 897 // Tell our owning surface to bump its generation ID
818 this->predrawNotify(); 898 const bool completeOverwrite = info.dimensions() == size;
899 this->predrawNotify(completeOverwrite);
819 900
820 // The device can assert that the requested area is always contained in its bounds 901 // The device can assert that the requested area is always contained in its bounds
821 return device->writePixels(info, pixels, rowBytes, target.x(), target.y()); 902 return device->writePixels(info, pixels, rowBytes, target.x(), target.y());
822 } 903 }
823 904
824 SkCanvas* SkCanvas::canvasForDrawIter() { 905 SkCanvas* SkCanvas::canvasForDrawIter() {
825 return this; 906 return this;
826 } 907 }
827 908
828 ////////////////////////////////////////////////////////////////////////////// 909 //////////////////////////////////////////////////////////////////////////////
(...skipping 1016 matching lines...) Expand 10 before | Expand all | Expand 10 after
1845 fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode); 1926 fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode);
1846 } 1927 }
1847 } 1928 }
1848 1929
1849 void SkCanvas::onDrawPaint(const SkPaint& paint) { 1930 void SkCanvas::onDrawPaint(const SkPaint& paint) {
1850 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPaint()"); 1931 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPaint()");
1851 this->internalDrawPaint(paint); 1932 this->internalDrawPaint(paint);
1852 } 1933 }
1853 1934
1854 void SkCanvas::internalDrawPaint(const SkPaint& paint) { 1935 void SkCanvas::internalDrawPaint(const SkPaint& paint) {
1855 LOOPER_BEGIN(paint, SkDrawFilter::kPaint_Type, NULL) 1936 LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kPaint_Type, NULL , false)
1856 1937
1857 while (iter.next()) { 1938 while (iter.next()) {
1858 iter.fDevice->drawPaint(iter, looper.paint()); 1939 iter.fDevice->drawPaint(iter, looper.paint());
1859 } 1940 }
1860 1941
1861 LOOPER_END 1942 LOOPER_END
1862 } 1943 }
1863 1944
1864 void SkCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], 1945 void SkCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
1865 const SkPaint& paint) { 1946 const SkPaint& paint) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1903 // To prevent accidental rejecting at this stage, we have to sort it bef ore we check. 1984 // To prevent accidental rejecting at this stage, we have to sort it bef ore we check.
1904 SkRect tmp(r); 1985 SkRect tmp(r);
1905 tmp.sort(); 1986 tmp.sort();
1906 1987
1907 bounds = &paint.computeFastBounds(tmp, &storage); 1988 bounds = &paint.computeFastBounds(tmp, &storage);
1908 if (this->quickReject(*bounds)) { 1989 if (this->quickReject(*bounds)) {
1909 return; 1990 return;
1910 } 1991 }
1911 } 1992 }
1912 1993
1913 LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, bounds) 1994 LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kRect_Type, bound s, false)
1914 1995
1915 while (iter.next()) { 1996 while (iter.next()) {
1916 iter.fDevice->drawRect(iter, r, looper.paint()); 1997 iter.fDevice->drawRect(iter, r, looper.paint());
1917 } 1998 }
1918 1999
1919 LOOPER_END 2000 LOOPER_END
1920 } 2001 }
1921 2002
1922 void SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) { 2003 void SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) {
1923 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawOval()"); 2004 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawOval()");
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
2061 } 2142 }
2062 if (this->quickReject(*bounds)) { 2143 if (this->quickReject(*bounds)) {
2063 return; 2144 return;
2064 } 2145 }
2065 } 2146 }
2066 SkLazyPaint lazy; 2147 SkLazyPaint lazy;
2067 if (NULL == paint) { 2148 if (NULL == paint) {
2068 paint = lazy.init(); 2149 paint = lazy.init();
2069 } 2150 }
2070 2151
2071 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) 2152 LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, bo unds,
2153 image->isOpaque())
2072 2154
2073 while (iter.next()) { 2155 while (iter.next()) {
2074 iter.fDevice->drawImageRect(iter, image, src, dst, looper.paint(), const raint); 2156 iter.fDevice->drawImageRect(iter, image, src, dst, looper.paint(), const raint);
2075 } 2157 }
2076 2158
2077 LOOPER_END 2159 LOOPER_END
2078 } 2160 }
2079 2161
2080 void SkCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, cons t SkPaint* paint) { 2162 void SkCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, cons t SkPaint* paint) {
2081 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmap()"); 2163 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmap()");
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2117 if (this->quickReject(*bounds)) { 2199 if (this->quickReject(*bounds)) {
2118 return; 2200 return;
2119 } 2201 }
2120 } 2202 }
2121 2203
2122 SkLazyPaint lazy; 2204 SkLazyPaint lazy;
2123 if (NULL == paint) { 2205 if (NULL == paint) {
2124 paint = lazy.init(); 2206 paint = lazy.init();
2125 } 2207 }
2126 2208
2127 LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) 2209 LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, bo unds,
2210 bitmap.isOpaque())
2128 2211
2129 while (iter.next()) { 2212 while (iter.next()) {
2130 iter.fDevice->drawBitmapRect(iter, bitmap, src, dst, looper.paint(), 2213 iter.fDevice->drawBitmapRect(iter, bitmap, src, dst, looper.paint(),
2131 (SK_VIRTUAL_CONSTRAINT_TYPE)constraint); 2214 (SK_VIRTUAL_CONSTRAINT_TYPE)constraint);
2132 } 2215 }
2133 2216
2134 LOOPER_END 2217 LOOPER_END
2135 } 2218 }
2136 2219
2137 void SkCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 2220 void SkCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after
2769 } 2852 }
2770 2853
2771 if (matrix) { 2854 if (matrix) {
2772 canvas->concat(*matrix); 2855 canvas->concat(*matrix);
2773 } 2856 }
2774 } 2857 }
2775 2858
2776 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 2859 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() {
2777 fCanvas->restoreToCount(fSaveCount); 2860 fCanvas->restoreToCount(fSaveCount);
2778 } 2861 }
OLDNEW
« include/core/SkCanvas.h ('K') | « include/core/SkCanvas.h ('k') | src/core/SkPaintPriv.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698