Chromium Code Reviews| 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 |