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 "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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |