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::willOverwriteAllPixels(const SkRect* rect, const SkPaint* paint, | |
|
Justin Novosad
2015/07/15 18:00:46
"will" is ambiguous and can be interpreted as a de
reed1
2015/07/15 21:41:02
Done.
| |
| 49 bool auxOpaque) const { | |
| 50 const SkISize size = this->getBaseLayerSize(); | |
| 51 const SkRect bounds = SkRect::MakeIWH(size.width(), size.height()); | |
| 52 if (!this->getClipStack()->quickContains(bounds)) { | |
| 53 return false; | |
| 54 } | |
| 55 | |
| 56 if (rect) { | |
| 57 if (!this->getTotalMatrix().rectStaysRect()) { | |
| 58 return false; // conservative | |
| 59 } | |
| 60 | |
| 61 SkRect devRect; | |
| 62 this->getTotalMatrix().mapRect(&devRect, *rect); | |
| 63 | |
| 64 if (paint) { | |
| 65 SkPaint::Style paintStyle = paint->getStyle(); | |
| 66 if (!(paintStyle == SkPaint::kFill_Style || | |
| 67 paintStyle == SkPaint::kStrokeAndFill_Style)) { | |
| 68 return false; | |
| 69 } | |
| 70 if (paint->getMaskFilter() || paint->getLooper() | |
| 71 || paint->getPathEffect() || paint->getImageFilter()) { | |
| 72 return false; // conservative | |
| 73 } | |
| 74 } | |
| 75 | |
| 76 if (devRect.contains(bounds)) { | |
| 77 return false; | |
| 78 } | |
| 79 } | |
| 80 return true; | |
| 81 } | |
| 82 | |
| 83 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
| 84 | |
| 39 static bool gIgnoreSaveLayerBounds; | 85 static bool gIgnoreSaveLayerBounds; |
| 40 void SkCanvas::Internal_Private_SetIgnoreSaveLayerBounds(bool ignore) { | 86 void SkCanvas::Internal_Private_SetIgnoreSaveLayerBounds(bool ignore) { |
| 41 gIgnoreSaveLayerBounds = ignore; | 87 gIgnoreSaveLayerBounds = ignore; |
| 42 } | 88 } |
| 43 bool SkCanvas::Internal_Private_GetIgnoreSaveLayerBounds() { | 89 bool SkCanvas::Internal_Private_GetIgnoreSaveLayerBounds() { |
| 44 return gIgnoreSaveLayerBounds; | 90 return gIgnoreSaveLayerBounds; |
| 45 } | 91 } |
| 46 | 92 |
| 47 static bool gTreatSpriteAsBitmap; | 93 static bool gTreatSpriteAsBitmap; |
| 48 void SkCanvas::Internal_Private_SetTreatSpriteAsBitmap(bool spriteAsBitmap) { | 94 void SkCanvas::Internal_Private_SetTreatSpriteAsBitmap(bool spriteAsBitmap) { |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 73 #define inc_layer() | 119 #define inc_layer() |
| 74 #define dec_layer() | 120 #define dec_layer() |
| 75 #define inc_rec() | 121 #define inc_rec() |
| 76 #define dec_rec() | 122 #define dec_rec() |
| 77 #define inc_canvas() | 123 #define inc_canvas() |
| 78 #define dec_canvas() | 124 #define dec_canvas() |
| 79 #endif | 125 #endif |
| 80 | 126 |
| 81 typedef SkTLazy<SkPaint> SkLazyPaint; | 127 typedef SkTLazy<SkPaint> SkLazyPaint; |
| 82 | 128 |
| 83 void SkCanvas::predrawNotify() { | 129 void SkCanvas::predrawNotify(bool completeOverwrite) { |
| 84 if (fSurfaceBase) { | 130 if (fSurfaceBase) { |
| 85 fSurfaceBase->aboutToDraw(SkSurface::kRetain_ContentChangeMode); | 131 fSurfaceBase->aboutToDraw(completeOverwrite ? SkSurface::kDiscard_Conten tChangeMode |
| 132 : SkSurface::kRetain_Content ChangeMode); | |
| 86 } | 133 } |
| 87 } | 134 } |
| 88 | 135 |
| 136 void SkCanvas::predrawNotify(const SkRect* rect, const SkPaint* paint, bool auxO paque) { | |
| 137 if (fSurfaceBase) { | |
| 138 SkSurface::ContentChangeMode mode = SkSurface::kRetain_ContentChangeMode ; | |
| 139 // Since willOverwriteAllPixels() may not be complete free to call, we o nly do so if | |
| 140 // there is an outstanding snapshot, since w/o that, there will be no co py-on-write | |
| 141 // and therefore we don't care which mode we're in. | |
| 142 // | |
| 143 if (fSurfaceBase->outstandingImageSnapshot()) { | |
|
Justin Novosad
2015/07/15 18:00:46
+1 This is a an interesting optimization
| |
| 144 if (this->willOverwriteAllPixels(rect, paint, auxOpaque)) { | |
| 145 mode = SkSurface::kDiscard_ContentChangeMode; | |
| 146 } | |
| 147 } | |
| 148 fSurfaceBase->aboutToDraw(mode); | |
| 149 } | |
| 150 } | |
| 151 | |
| 89 /////////////////////////////////////////////////////////////////////////////// | 152 /////////////////////////////////////////////////////////////////////////////// |
| 90 | 153 |
| 91 static uint32_t filter_paint_flags(const SkSurfaceProps& props, uint32_t flags) { | 154 static uint32_t filter_paint_flags(const SkSurfaceProps& props, uint32_t flags) { |
| 92 const uint32_t propFlags = props.flags(); | 155 const uint32_t propFlags = props.flags(); |
| 93 if (propFlags & SkSurfaceProps::kDisallowDither_Flag) { | 156 if (propFlags & SkSurfaceProps::kDisallowDither_Flag) { |
| 94 flags &= ~SkPaint::kDither_Flag; | 157 flags &= ~SkPaint::kDither_Flag; |
| 95 } | 158 } |
| 96 if (propFlags & SkSurfaceProps::kDisallowAntiAlias_Flag) { | 159 if (propFlags & SkSurfaceProps::kDisallowAntiAlias_Flag) { |
| 97 flags &= ~SkPaint::kAntiAlias_Flag; | 160 flags &= ~SkPaint::kAntiAlias_Flag; |
| 98 } | 161 } |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 490 AutoDrawLooper looper(this, fProps, paint, true); \ | 553 AutoDrawLooper looper(this, fProps, paint, true); \ |
| 491 while (looper.next(type)) { \ | 554 while (looper.next(type)) { \ |
| 492 SkDrawIter iter(this); | 555 SkDrawIter iter(this); |
| 493 | 556 |
| 494 #define LOOPER_BEGIN(paint, type, bounds) \ | 557 #define LOOPER_BEGIN(paint, type, bounds) \ |
| 495 this->predrawNotify(); \ | 558 this->predrawNotify(); \ |
| 496 AutoDrawLooper looper(this, fProps, paint, false, bounds); \ | 559 AutoDrawLooper looper(this, fProps, paint, false, bounds); \ |
| 497 while (looper.next(type)) { \ | 560 while (looper.next(type)) { \ |
| 498 SkDrawIter iter(this); | 561 SkDrawIter iter(this); |
| 499 | 562 |
| 563 #define LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, type, bounds, auxOpaque) \ | |
| 564 this->predrawNotify(bounds, &paint, auxOpaque); \ | |
| 565 AutoDrawLooper looper(this, fProps, paint, false, bounds); \ | |
| 566 while (looper.next(type)) { \ | |
| 567 SkDrawIter iter(this); | |
| 568 | |
| 500 #define LOOPER_END } | 569 #define LOOPER_END } |
| 501 | 570 |
| 502 //////////////////////////////////////////////////////////////////////////// | 571 //////////////////////////////////////////////////////////////////////////// |
| 503 | 572 |
| 504 void SkCanvas::resetForNextPicture(const SkIRect& bounds) { | 573 void SkCanvas::resetForNextPicture(const SkIRect& bounds) { |
| 505 this->restoreToCount(1); | 574 this->restoreToCount(1); |
| 506 fCachedLocalClipBounds.setEmpty(); | 575 fCachedLocalClipBounds.setEmpty(); |
| 507 fCachedLocalClipBoundsDirty = true; | 576 fCachedLocalClipBoundsDirty = true; |
| 508 fClipStack->reset(); | 577 fClipStack->reset(); |
| 509 fMCRec->reset(bounds); | 578 fMCRec->reset(bounds); |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 808 if (x > 0) { | 877 if (x > 0) { |
| 809 x = 0; | 878 x = 0; |
| 810 } | 879 } |
| 811 if (y > 0) { | 880 if (y > 0) { |
| 812 y = 0; | 881 y = 0; |
| 813 } | 882 } |
| 814 // here x,y are either 0 or negative | 883 // here x,y are either 0 or negative |
| 815 pixels = ((const char*)pixels - y * rowBytes - x * info.bytesPerPixel()); | 884 pixels = ((const char*)pixels - y * rowBytes - x * info.bytesPerPixel()); |
| 816 | 885 |
| 817 // Tell our owning surface to bump its generation ID | 886 // Tell our owning surface to bump its generation ID |
| 818 this->predrawNotify(); | 887 const bool completeOverwrite = info.dimensions() == size; |
| 888 this->predrawNotify(completeOverwrite); | |
| 819 | 889 |
| 820 // The device can assert that the requested area is always contained in its bounds | 890 // 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()); | 891 return device->writePixels(info, pixels, rowBytes, target.x(), target.y()); |
| 822 } | 892 } |
| 823 | 893 |
| 824 SkCanvas* SkCanvas::canvasForDrawIter() { | 894 SkCanvas* SkCanvas::canvasForDrawIter() { |
| 825 return this; | 895 return this; |
| 826 } | 896 } |
| 827 | 897 |
| 828 ////////////////////////////////////////////////////////////////////////////// | 898 ////////////////////////////////////////////////////////////////////////////// |
| (...skipping 1016 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1845 fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode); | 1915 fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode); |
| 1846 } | 1916 } |
| 1847 } | 1917 } |
| 1848 | 1918 |
| 1849 void SkCanvas::onDrawPaint(const SkPaint& paint) { | 1919 void SkCanvas::onDrawPaint(const SkPaint& paint) { |
| 1850 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPaint()"); | 1920 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPaint()"); |
| 1851 this->internalDrawPaint(paint); | 1921 this->internalDrawPaint(paint); |
| 1852 } | 1922 } |
| 1853 | 1923 |
| 1854 void SkCanvas::internalDrawPaint(const SkPaint& paint) { | 1924 void SkCanvas::internalDrawPaint(const SkPaint& paint) { |
| 1855 LOOPER_BEGIN(paint, SkDrawFilter::kPaint_Type, NULL) | 1925 LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kPaint_Type, NULL ) |
| 1856 | 1926 |
| 1857 while (iter.next()) { | 1927 while (iter.next()) { |
| 1858 iter.fDevice->drawPaint(iter, looper.paint()); | 1928 iter.fDevice->drawPaint(iter, looper.paint()); |
| 1859 } | 1929 } |
| 1860 | 1930 |
| 1861 LOOPER_END | 1931 LOOPER_END |
| 1862 } | 1932 } |
| 1863 | 1933 |
| 1864 void SkCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], | 1934 void SkCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], |
| 1865 const SkPaint& paint) { | 1935 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. | 1973 // To prevent accidental rejecting at this stage, we have to sort it bef ore we check. |
| 1904 SkRect tmp(r); | 1974 SkRect tmp(r); |
| 1905 tmp.sort(); | 1975 tmp.sort(); |
| 1906 | 1976 |
| 1907 bounds = &paint.computeFastBounds(tmp, &storage); | 1977 bounds = &paint.computeFastBounds(tmp, &storage); |
| 1908 if (this->quickReject(*bounds)) { | 1978 if (this->quickReject(*bounds)) { |
| 1909 return; | 1979 return; |
| 1910 } | 1980 } |
| 1911 } | 1981 } |
| 1912 | 1982 |
| 1913 LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, bounds) | 1983 LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kRect_Type, bound s) |
| 1914 | 1984 |
| 1915 while (iter.next()) { | 1985 while (iter.next()) { |
| 1916 iter.fDevice->drawRect(iter, r, looper.paint()); | 1986 iter.fDevice->drawRect(iter, r, looper.paint()); |
| 1917 } | 1987 } |
| 1918 | 1988 |
| 1919 LOOPER_END | 1989 LOOPER_END |
| 1920 } | 1990 } |
| 1921 | 1991 |
| 1922 void SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) { | 1992 void SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) { |
| 1923 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawOval()"); | 1993 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawOval()"); |
| (...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2769 } | 2839 } |
| 2770 | 2840 |
| 2771 if (matrix) { | 2841 if (matrix) { |
| 2772 canvas->concat(*matrix); | 2842 canvas->concat(*matrix); |
| 2773 } | 2843 } |
| 2774 } | 2844 } |
| 2775 | 2845 |
| 2776 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { | 2846 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { |
| 2777 fCanvas->restoreToCount(fSaveCount); | 2847 fCanvas->restoreToCount(fSaveCount); |
| 2778 } | 2848 } |
| OLD | NEW |