Index: src/core/SkBitmapDevice.cpp |
diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp |
index 2d2fe9e6d4049a8802f27302059a0b866604cf54..a09821e941b8c25d0009703c1c991e40c43ac838 100644 |
--- a/src/core/SkBitmapDevice.cpp |
+++ b/src/core/SkBitmapDevice.cpp |
@@ -9,6 +9,7 @@ |
#include "SkConfig8888.h" |
#include "SkDeviceProperties.h" |
#include "SkDraw.h" |
+#include "SkImagePriv.h" |
#include "SkImage_Base.h" |
#include "SkRasterClip.h" |
#include "SkShader.h" |
@@ -70,6 +71,9 @@ SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap, const SkDeviceProperties& |
SkASSERT(valid_for_bitmap_device(bitmap.info(), NULL)); |
} |
+SkBitmapDevice::~SkBitmapDevice() { |
+} |
+ |
SkBitmapDevice* SkBitmapDevice::Create(const SkImageInfo& origInfo, |
const SkDeviceProperties* props) { |
SkAlphaType newAT = origInfo.alphaType(); |
@@ -104,11 +108,15 @@ SkImageInfo SkBitmapDevice::imageInfo() const { |
return fBitmap.info(); |
} |
-void SkBitmapDevice::replaceBitmapBackendForRasterSurface(const SkBitmap& bm) { |
- SkASSERT(bm.width() == fBitmap.width()); |
- SkASSERT(bm.height() == fBitmap.height()); |
- fBitmap = bm; // intent is to use bm's pixelRef (and rowbytes/config) |
- fBitmap.lockPixels(); |
+void SkBitmapDevice::deepCopyBackendIfNeeded() { |
+ if (NULL != fSnapshot) { |
+ if (!fSnapshot->unique()) { |
+ SkBitmap prev(fBitmap); |
+ prev.deepCopyTo(&fBitmap); |
+ fBitmap.lockPixels(); |
+ } |
+ fSnapshot.reset(NULL); |
+ } |
} |
SkBaseDevice* SkBitmapDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint*) { |
@@ -129,11 +137,13 @@ void SkBitmapDevice::unlockPixels() { |
} |
const SkBitmap& SkBitmapDevice::onAccessBitmap() { |
+ this->deepCopyBackendIfNeeded(); |
return fBitmap; |
} |
void* SkBitmapDevice::onAccessPixels(SkImageInfo* info, size_t* rowBytes) { |
if (fBitmap.getPixels()) { |
+ this->deepCopyBackendIfNeeded(); |
*info = fBitmap.info(); |
*rowBytes = fBitmap.rowBytes(); |
return fBitmap.getPixels(); |
@@ -351,7 +361,14 @@ void SkBitmapDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode |
void SkBitmapDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device, |
int x, int y, const SkPaint& paint) { |
- const SkBitmap& src = device->accessBitmap(false); |
+ SkAutoTUnref<SkImage> image(device->newImageSnapshot()); |
+ if (NULL == image) { |
+ return; |
+ } |
+ SkBitmap src; |
+ if (!as_IB(image.get())->getROPixels(&src)) { |
+ return; |
+ } |
draw.drawSprite(src, x, y, paint); |
} |
@@ -359,6 +376,27 @@ SkSurface* SkBitmapDevice::newSurface(const SkImageInfo& info, const SkSurfacePr |
return SkSurface::NewRaster(info, &props); |
} |
+void SkBitmapDevice::discard() { |
+ if (NULL != fSnapshot) { |
+ if (!fSnapshot->unique()) { |
+ fBitmap.setPixelRef(NULL); |
+ fBitmap.allocPixels(); |
+ } |
+ fSnapshot.reset(NULL); |
+ } |
+} |
+ |
+SkImage* SkBitmapDevice::newImageSnapshot() { |
+ if (NULL == fSnapshot) { |
+ fSnapshot.reset(this->onNewImageSnapshot()); |
+ } |
+ return SkSafeRef(fSnapshot.get()); |
+} |
+ |
+SkImage* SkBitmapDevice::onNewImageSnapshot() { |
+ return SkNewImageFromBitmap(fBitmap, NULL); |
+} |
+ |
const void* SkBitmapDevice::peekPixels(SkImageInfo* info, size_t* rowBytes) { |
const SkImageInfo bmInfo = fBitmap.info(); |
if (fBitmap.getPixels() && (kUnknown_SkColorType != bmInfo.colorType())) { |