diff options
author | 2012-08-28 12:19:02 +0000 | |
---|---|---|
committer | 2012-08-28 12:19:02 +0000 | |
commit | 97af1a64ae6bdddd346d8babfd9f188279dd6644 (patch) | |
tree | 00ed8f9919b9f2623b4d08e33ef61f80018d6eb4 /src/image/SkSurface_Raster.cpp | |
parent | 91ee3a11ed476f4f08e1e4ae183002c56349ec19 (diff) |
Add caching of the snapshot image form a surface
Notify the surface when the canvas draws into it, so it can invalidate the
cached image, and (if needed) perform a copy-on-write on the surface if it
was being shared with the image.
Review URL: https://codereview.appspot.com/6441115
git-svn-id: http://skia.googlecode.com/svn/trunk@5306 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/image/SkSurface_Raster.cpp')
-rw-r--r-- | src/image/SkSurface_Raster.cpp | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/src/image/SkSurface_Raster.cpp b/src/image/SkSurface_Raster.cpp index c4ac959730..8afab6b01c 100644 --- a/src/image/SkSurface_Raster.cpp +++ b/src/image/SkSurface_Raster.cpp @@ -8,6 +8,7 @@ #include "SkSurface_Base.h" #include "SkImagePriv.h" #include "SkCanvas.h" +#include "SkDevice.h" #include "SkMallocPixelRef.h" static const size_t kIgnoreRowBytesValue = (size_t)~0; @@ -24,6 +25,7 @@ public: virtual SkImage* onNewImageShapshot() SK_OVERRIDE; virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) SK_OVERRIDE; + virtual void onCopyOnWrite(SkImage*, SkCanvas*) SK_OVERRIDE; private: SkBitmap fBitmap; @@ -89,7 +91,7 @@ SkSurface_Raster::SkSurface_Raster(const SkImage::Info& info, SkColorSpace* cs, fBitmap.setConfig(config, info.fWidth, info.fHeight, rb); fBitmap.setPixels(pixels); fBitmap.setIsOpaque(isOpaque); - fWeOwnThePixels = false; + fWeOwnThePixels = false; // We are "Direct" } SkSurface_Raster::SkSurface_Raster(const SkImage::Info& info, SkColorSpace* cs, @@ -117,18 +119,28 @@ SkSurface* SkSurface_Raster::onNewSurface(const SkImage::Info& info, return SkSurface::NewRaster(info, cs); } -SkImage* SkSurface_Raster::onNewImageShapshot() { - // if we don't own the pixels, we need to make a deep-copy - // if we do, we need to perform a copy-on-write the next time - // we draw to this bitmap from our canvas... - return SkNewImageFromBitmap(fBitmap); -} - void SkSurface_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) { canvas->drawBitmap(fBitmap, x, y, paint); } +SkImage* SkSurface_Raster::onNewImageShapshot() { + return SkNewImageFromBitmap(fBitmap, fWeOwnThePixels); +} + +void SkSurface_Raster::onCopyOnWrite(SkImage* image, SkCanvas* canvas) { + // are we sharing pixelrefs with the image? + if (SkBitmapImageGetPixelRef(image) == fBitmap.pixelRef()) { + SkASSERT(fWeOwnThePixels); + SkBitmap prev(fBitmap); + prev.deepCopyTo(&fBitmap, prev.config()); + // Now fBitmap is a deep copy of itself (and therefore different from + // what is being used by the image. Next we update the canvas to use + // this as its backend, so we can't modify the image's pixels anymore. + canvas->getDevice()->replaceBitmapBackendForRasterSurface(fBitmap); + } +} + /////////////////////////////////////////////////////////////////////////////// SkSurface* SkSurface::NewRasterDirect(const SkImage::Info& info, |