| 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,
|
|
|