Index: src/image/SkSurface_Raster.cpp |
diff --git a/src/image/SkSurface_Raster.cpp b/src/image/SkSurface_Raster.cpp |
index f581c9da28929fc78ef5652b6032f41ff2385bda..e124d265acdf77b929da63f12466477ae0641262 100644 |
--- a/src/image/SkSurface_Raster.cpp |
+++ b/src/image/SkSurface_Raster.cpp |
@@ -6,12 +6,15 @@ |
*/ |
#include "SkSurface_Base.h" |
-#include "SkImagePriv.h" |
+#include "SkBitmapDevice.h" |
#include "SkCanvas.h" |
-#include "SkDevice.h" |
+#include "SkDeviceProperties.h" |
+#include "SkImage_Base.h" |
+#include "SkImagePriv.h" |
#include "SkMallocPixelRef.h" |
static const size_t kIgnoreRowBytesValue = (size_t)~0; |
+class SkRasterDevice; |
class SkSurface_Raster : public SkSurface_Base { |
public: |
@@ -21,20 +24,58 @@ public: |
void (*releaseProc)(void* pixels, void* context), void* context, |
const SkSurfaceProps*); |
SkSurface_Raster(SkPixelRef*, const SkSurfaceProps*); |
- |
+ ~SkSurface_Raster(); |
SkCanvas* onNewCanvas() SK_OVERRIDE; |
SkSurface* onNewSurface(const SkImageInfo&) SK_OVERRIDE; |
SkImage* onNewImageSnapshot(Budgeted) SK_OVERRIDE; |
- virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, |
- const SkPaint*) SK_OVERRIDE; |
- void onCopyOnWrite(ContentChangeMode) SK_OVERRIDE; |
+ uint32_t generationID() SK_OVERRIDE; |
private: |
- SkBitmap fBitmap; |
+ SkRasterDevice* fDevice; |
+ uint32_t fLastDeviceGenerationID; |
+ uint32_t fGenerationID; |
typedef SkSurface_Base INHERITED; |
}; |
+/** A bitmap device that is used by SkSurface_Raster. */ |
+class SkRasterDevice : public SkBitmapDevice { |
+public: |
+ SkRasterDevice(const SkBitmap& bitmap); |
+ |
+ void setSurface(SkSurface_Raster* surface) { |
+ fSurface = surface; |
+ if (NULL != fSurface) { |
+ fSurfaceProps = fSurface->props(); |
+ } |
+ } |
+ |
+ uint32_t generationID() { return this->getBackendBitmap().getGenerationID(); } |
+ |
+private: |
+ SkImage* onNewImageSnapshot() SK_OVERRIDE; |
+ |
+ SkBitmap& getBackendBitmap() { |
+ return fBitmap; // Note: accessing private SkBitmapDevice::fBitmap |
+ } |
+ |
+ SkSurface_Raster* fSurface; |
+ SkSurfaceProps fSurfaceProps; |
+ |
+ typedef SkBitmapDevice INHERITED; |
+}; |
+ |
+SkRasterDevice::SkRasterDevice(const SkBitmap& bitmap) |
+ : INHERITED(bitmap) |
+ , fSurface(NULL) |
+ , fSurfaceProps(0, kUnknown_SkPixelGeometry) { |
+} |
+ |
+SkImage* SkRasterDevice::onNewImageSnapshot() { |
+ // Override the SkImage creation to set the correct surface properties. |
+ return SkNewImageFromBitmap(fBitmap, &fSurfaceProps); |
+} |
+ |
/////////////////////////////////////////////////////////////////////////////// |
bool SkSurface_Raster::Valid(const SkImageInfo& info, size_t rowBytes) { |
@@ -86,58 +127,59 @@ SkSurface_Raster::SkSurface_Raster(const SkImageInfo& info, void* pixels, size_t |
const SkSurfaceProps* props) |
: INHERITED(info, props) |
{ |
- fBitmap.installPixels(info, pixels, rb, NULL, releaseProc, context); |
+ SkBitmap bitmap; |
+ bitmap.installPixels(info, pixels, rb, NULL, releaseProc, context); |
+ fDevice = SkNEW_ARGS(SkRasterDevice, (bitmap)); |
+ fDevice->setSurface(this); |
+ fLastDeviceGenerationID = fDevice->generationID(); |
+ fGenerationID = this->newGenerationID(); |
} |
SkSurface_Raster::SkSurface_Raster(SkPixelRef* pr, const SkSurfaceProps* props) |
: INHERITED(pr->info().width(), pr->info().height(), props) |
{ |
const SkImageInfo& info = pr->info(); |
- |
- fBitmap.setInfo(info, info.minRowBytes()); |
- fBitmap.setPixelRef(pr); |
- |
+ SkBitmap bitmap; |
+ bitmap.setInfo(info, info.minRowBytes()); |
+ bitmap.setPixelRef(pr); |
if (!info.isOpaque()) { |
- fBitmap.eraseColor(SK_ColorTRANSPARENT); |
+ bitmap.eraseColor(SK_ColorTRANSPARENT); |
} |
+ fDevice = SkNEW_ARGS(SkRasterDevice, (bitmap)); |
+ fDevice->setSurface(this); |
+ fLastDeviceGenerationID = fDevice->generationID(); |
+ fGenerationID = this->newGenerationID(); |
+} |
+ |
+SkSurface_Raster::~SkSurface_Raster() { |
+ fDevice->setSurface(NULL); |
+ fDevice->unref(); |
} |
SkCanvas* SkSurface_Raster::onNewCanvas() { |
- return SkNEW_ARGS(SkCanvas, (fBitmap, this->props())); |
+ return SkNEW_ARGS(SkCanvas, (fDevice, &this->props(), SkCanvas::kDefault_InitFlags)); |
} |
SkSurface* SkSurface_Raster::onNewSurface(const SkImageInfo& info) { |
return SkSurface::NewRaster(info); |
} |
-void SkSurface_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, |
- const SkPaint* paint) { |
- canvas->drawBitmap(fBitmap, x, y, paint); |
-} |
- |
SkImage* SkSurface_Raster::onNewImageSnapshot(Budgeted) { |
- return SkNewImageFromBitmap(fBitmap, &this->props()); |
+ return fDevice->newImageSnapshot(); |
} |
-void SkSurface_Raster::onCopyOnWrite(ContentChangeMode mode) { |
- // are we sharing pixelrefs with the image? |
- SkASSERT(this->getCachedImage(kNo_Budgeted)); |
- if (SkBitmapImageGetPixelRef(this->getCachedImage(kNo_Budgeted)) == fBitmap.pixelRef()) { |
- if (kDiscard_ContentChangeMode == mode) { |
- fBitmap.setPixelRef(NULL); |
- fBitmap.allocPixels(); |
- } else { |
- SkBitmap prev(fBitmap); |
- prev.deepCopyTo(&fBitmap); |
- } |
- // 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. |
- SkASSERT(this->getCachedCanvas()); |
- this->getCachedCanvas()->getDevice()->replaceBitmapBackendForRasterSurface(fBitmap); |
+uint32_t SkSurface_Raster::generationID() { |
+ uint32_t deviceGenerationID = fDevice->generationID(); |
+ if (fLastDeviceGenerationID != deviceGenerationID) { |
+ fLastDeviceGenerationID = deviceGenerationID; |
+ // We do not return the device generation id, as that might clash with another |
+ // SkSurface::generationID() generated by other SkSurface subclass. |
+ fGenerationID = this->newGenerationID(); |
} |
+ // The SkSurface API mandates that empty surfaces return zero. However, those are not valid by |
+ // SkSurface_Raster::Valid, so currently this is not taken into account. |
+ return fGenerationID; |
} |
- |
/////////////////////////////////////////////////////////////////////////////// |
SkSurface* SkSurface::NewRasterDirectReleaseProc(const SkImageInfo& info, void* pixels, size_t rb, |