Index: src/image/SkSurface_Raster.cpp |
diff --git a/src/image/SkSurface_Raster.cpp b/src/image/SkSurface_Raster.cpp |
index 9c38640933926fdef9becf5221626faeba8e79ee..d4084889969b3d41f84c54f1eff10004aa018621 100644 |
--- a/src/image/SkSurface_Raster.cpp |
+++ b/src/image/SkSurface_Raster.cpp |
@@ -8,11 +8,14 @@ |
#include "SkSurface_Base.h" |
#include "SkImagePriv.h" |
#include "SkCanvas.h" |
-#include "SkDevice.h" |
+#include "SkBitmapDevice.h" |
#include "SkMallocPixelRef.h" |
+#include "SkDeviceProperties.h" |
static const size_t kIgnoreRowBytesValue = (size_t)~0; |
+class SkRasterSurfaceDevice; |
+ |
class SkSurface_Raster : public SkSurface_Base { |
public: |
static bool Valid(const SkImageInfo&, size_t rb = kIgnoreRowBytesValue); |
@@ -22,6 +25,8 @@ public: |
const SkSurfaceProps*); |
SkSurface_Raster(SkPixelRef*, const SkSurfaceProps*); |
+ ~SkSurface_Raster(); |
+ |
SkCanvas* onNewCanvas() SK_OVERRIDE; |
SkSurface* onNewSurface(const SkImageInfo&) SK_OVERRIDE; |
SkImage* onNewImageSnapshot(Budgeted) SK_OVERRIDE; |
@@ -29,13 +34,96 @@ public: |
const SkPaint*) SK_OVERRIDE; |
void onCopyOnWrite(ContentChangeMode) SK_OVERRIDE; |
+ /** Creates a surface that is attached to a device. |
+ * The device will own the reference to the surface, and the surface will go out of scope when |
+ * the device goes out of scope. Note: This function is deprecated, it will be renamed to |
+ * SkSurface_Raster* createCompatibleSurface(const SkBaseDevice::CreateInfo& cinfo) |
+ */ |
+ SkBaseDevice* createCompatibleDeviceDeprecated(const SkBaseDevice::CreateInfo& cinfo); |
+ |
+ SkRasterSurfaceDevice* CreateWithReverseOwnership(SkPixelRef*, const SkDeviceProperties&, |
+ const SkSurfaceProps*); |
private: |
- SkBitmap fBitmap; |
- bool fWeOwnThePixels; |
+ /** Deprecated constructor for standalone devices, eg. devices that own the surface. |
+ */ |
+ SkSurface_Raster(SkPixelRef*, const SkDeviceProperties&, const SkSurfaceProps*); |
+ void initWithPixelRef(SkPixelRef* pr); |
+ |
+ SkBitmap fBitmap; |
+ SkRasterSurfaceDevice* fDevice; |
+ bool fSurfaceOwnsDevice;; |
+ bool fWeOwnThePixels; |
typedef SkSurface_Base INHERITED; |
}; |
+/** A bitmap device that is backed by SkSurface_Raster. |
+ */ |
+class SkRasterSurfaceDevice : public SkBitmapDevice { |
+public: |
+ SkRasterSurfaceDevice(SkSurface_Raster*, const SkBitmap& bitmap); |
+ |
+ /** Deprecated constructor for devices that own their surface.*/ |
+ SkRasterSurfaceDevice(SkSurface_Raster*, const SkBitmap& bitmap, |
+ const SkDeviceProperties& deviceProps); |
+ |
+ ~SkRasterSurfaceDevice(); |
+ |
+ void swapBitmap(const SkBitmap&); |
+ |
+ void discard() SK_OVERRIDE; |
+ |
+private: |
+ SkBaseDevice* onCreateCompatibleDevice(const CreateInfo& cinfo) SK_OVERRIDE; |
+ const SkBitmap& onAccessBitmap() SK_OVERRIDE; |
+ |
+ SkSurface_Raster* fSurface; |
+ bool fDeviceOwnsSurface; |
+ |
+ typedef SkBitmapDevice INHERITED; |
+}; |
+ |
+SkRasterSurfaceDevice::SkRasterSurfaceDevice(SkSurface_Raster* surface, const SkBitmap& bitmap) |
+ : INHERITED(bitmap) |
+ , fSurface(surface) |
+ , fDeviceOwnsSurface(false) { |
+} |
+ |
+SkRasterSurfaceDevice::SkRasterSurfaceDevice(SkSurface_Raster* surface, |
+ const SkBitmap& bitmap, |
+ const SkDeviceProperties& deviceProps) |
+ : INHERITED(bitmap, deviceProps) |
+ , fSurface(surface) |
+ , fDeviceOwnsSurface(true) { |
+} |
+ |
+SkRasterSurfaceDevice::~SkRasterSurfaceDevice() { |
+ if (fDeviceOwnsSurface) { |
+ fSurface->unref(); |
+ } |
+} |
+ |
+SkBaseDevice* SkRasterSurfaceDevice::onCreateCompatibleDevice(const CreateInfo& cinfo) { |
+ return fSurface->createCompatibleDeviceDeprecated(cinfo); |
+} |
+ |
+void SkRasterSurfaceDevice::swapBitmap(const SkBitmap& bitmap) { |
+ this->replaceBitmapBackendForRasterSurface(bitmap); |
+} |
+ |
+const SkBitmap& SkRasterSurfaceDevice::onAccessBitmap() { |
+ if (fSurface) { |
+ fSurface->aboutToDraw(SkSurface::kRetain_ContentChangeMode); |
+ } |
+ return this->INHERITED::onAccessBitmap(); |
+} |
+ |
+void SkRasterSurfaceDevice::discard() { |
+ if (fSurface) { |
+ fSurface->aboutToDraw(SkSurface::kDiscard_ContentChangeMode); |
+ } |
+} |
+ |
/////////////////////////////////////////////////////////////////////////////// |
bool SkSurface_Raster::Valid(const SkImageInfo& info, size_t rowBytes) { |
@@ -85,15 +173,27 @@ bool SkSurface_Raster::Valid(const SkImageInfo& info, size_t rowBytes) { |
SkSurface_Raster::SkSurface_Raster(const SkImageInfo& info, void* pixels, size_t rb, |
void (*releaseProc)(void* pixels, void* context), void* context, |
const SkSurfaceProps* props) |
- : INHERITED(info, props) |
-{ |
+ : INHERITED(info, props) { |
fBitmap.installPixels(info, pixels, rb, NULL, releaseProc, context); |
fWeOwnThePixels = false; // We are "Direct" |
} |
SkSurface_Raster::SkSurface_Raster(SkPixelRef* pr, const SkSurfaceProps* props) |
- : INHERITED(pr->info().width(), pr->info().height(), props) |
-{ |
+ : INHERITED(pr->info().width(), pr->info().height(), props) { |
+ this->initWithPixelRef(pr); |
+ fDevice = SkNEW_ARGS(SkRasterSurfaceDevice, (this, fBitmap)); |
+ fSurfaceOwnsDevice = true; |
+} |
+ |
+SkSurface_Raster::SkSurface_Raster(SkPixelRef* pr, const SkDeviceProperties& deviceProps, |
+ const SkSurfaceProps* props) |
+ : INHERITED(pr->info().width(), pr->info().height(), props) { |
+ this->initWithPixelRef(pr); |
+ fDevice = SkNEW_ARGS(SkRasterSurfaceDevice, (this, fBitmap, deviceProps)); |
+ fSurfaceOwnsDevice = false; |
+} |
+ |
+void SkSurface_Raster::initWithPixelRef(SkPixelRef* pr) { |
const SkImageInfo& info = pr->info(); |
fBitmap.setInfo(info, info.minRowBytes()); |
@@ -105,8 +205,23 @@ SkSurface_Raster::SkSurface_Raster(SkPixelRef* pr, const SkSurfaceProps* props) |
} |
} |
+SkSurface_Raster::~SkSurface_Raster() { |
+ if (fSurfaceOwnsDevice) { |
+ fDevice->unref(); |
+ } |
+} |
+SkRasterSurfaceDevice* SkSurface_Raster::CreateWithReverseOwnership( |
+ SkPixelRef* pr, const SkDeviceProperties& deviceProperties, |
+ const SkSurfaceProps* surfaceProperties) { |
+ SkSurface_Raster* surface = SkNEW_ARGS(SkSurface_Raster, |
+ (pr, deviceProperties, surfaceProperties)); |
+ |
+ // Caller owns ref to the device, and the device owns ref to the surface. |
+ return surface->fDevice; |
+} |
+ |
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) { |
@@ -137,9 +252,18 @@ void SkSurface_Raster::onCopyOnWrite(ContentChangeMode mode) { |
// 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); |
+ fDevice->swapBitmap(fBitmap); |
+ } |
+} |
+ |
+SkBaseDevice* SkSurface_Raster::createCompatibleDeviceDeprecated( |
+ const SkBaseDevice::CreateInfo& cinfo) { |
+ SkDeviceProperties leaky(cinfo.fPixelGeometry); |
+ SkAutoTUnref<SkPixelRef> pr(SkMallocPixelRef::NewAllocate(cinfo.fInfo, 0, NULL)); |
+ if (NULL == pr.get()) { |
+ return NULL; |
} |
+ return SkSurface_Raster::CreateWithReverseOwnership(pr, leaky, &this->props()); |
} |
/////////////////////////////////////////////////////////////////////////////// |