Adding SkSurface support to SkDeferredCanvas
Review URL: https://codereview.chromium.org/14178002
git-svn-id: http://skia.googlecode.com/svn/trunk@8648 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/utils/SkDeferredCanvas.cpp b/src/utils/SkDeferredCanvas.cpp
index 5119729..21f717c 100644
--- a/src/utils/SkDeferredCanvas.cpp
+++ b/src/utils/SkDeferredCanvas.cpp
@@ -17,6 +17,7 @@
#include "SkPaintPriv.h"
#include "SkRRect.h"
#include "SkShader.h"
+#include "SkSurface.h"
enum {
// Deferred canvas will auto-flush when recording reaches this limit
@@ -138,14 +139,15 @@
//-----------------------------------------------------------------------------
class DeferredDevice : public SkDevice {
public:
- DeferredDevice(SkDevice* immediateDevice,
- SkDeferredCanvas::NotificationClient* notificationClient = NULL);
+ explicit DeferredDevice(SkDevice* immediateDevice);
+ explicit DeferredDevice(SkSurface* surface);
~DeferredDevice();
void setNotificationClient(SkDeferredCanvas::NotificationClient* notificationClient);
SkCanvas* recordingCanvas();
SkCanvas* immediateCanvas() const {return fImmediateCanvas;}
SkDevice* immediateDevice() const {return fImmediateDevice;}
+ SkImage* newImageShapshot();
bool isFreshFrame();
bool hasPendingCommands();
size_t storageAllocatedForRecording() const;
@@ -237,12 +239,14 @@
virtual void flush();
void beginRecording();
+ void init();
DeferredPipeController fPipeController;
SkGPipeWriter fPipeWriter;
SkDevice* fImmediateDevice;
SkCanvas* fImmediateCanvas;
SkCanvas* fRecordingCanvas;
+ SkSurface* fSurface;
SkDeferredCanvas::NotificationClient* fNotificationClient;
bool fFreshFrame;
size_t fMaxRecordingStorageBytes;
@@ -250,21 +254,40 @@
size_t fBitmapSizeThreshold;
};
-DeferredDevice::DeferredDevice(
- SkDevice* immediateDevice, SkDeferredCanvas::NotificationClient* notificationClient) :
- SkDevice(SkBitmap::kNo_Config,
- immediateDevice->width(), immediateDevice->height(),
- immediateDevice->isOpaque(),
- immediateDevice->getDeviceProperties())
- , fRecordingCanvas(NULL)
- , fFreshFrame(true)
- , fPreviousStorageAllocated(0)
- , fBitmapSizeThreshold(kDeferredCanvasBitmapSizeThreshold){
-
- fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes;
- fNotificationClient = notificationClient;
- fImmediateDevice = immediateDevice; // ref counted via fImmediateCanvas
+DeferredDevice::DeferredDevice(SkDevice* immediateDevice)
+ : SkDevice(SkBitmap::kNo_Config,
+ immediateDevice->width(), immediateDevice->height(),
+ immediateDevice->isOpaque(),
+ immediateDevice->getDeviceProperties()) {
+ fSurface = NULL;
+ fImmediateDevice = immediateDevice; // ref counted via fImmediateCanvas
fImmediateCanvas = SkNEW_ARGS(SkCanvas, (fImmediateDevice));
+ this->init();
+}
+
+DeferredDevice::DeferredDevice(SkSurface* surface)
+ : SkDevice(SkBitmap::kNo_Config,
+ surface->getCanvas()->getDevice()->width(),
+ surface->getCanvas()->getDevice()->height(),
+ surface->getCanvas()->getDevice()->isOpaque(),
+ surface->getCanvas()->getDevice()->getDeviceProperties()) {
+ fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes;
+ fNotificationClient = NULL;
+ fImmediateCanvas = surface->getCanvas();
+ SkSafeRef(fImmediateCanvas);
+ fSurface = surface;
+ SkSafeRef(fSurface);
+ fImmediateDevice = fImmediateCanvas->getDevice(); // ref counted via fImmediateCanvas
+ this->init();
+}
+
+void DeferredDevice::init() {
+ fRecordingCanvas = NULL;
+ fFreshFrame = true;
+ fPreviousStorageAllocated = 0;
+ fBitmapSizeThreshold = kDeferredCanvasBitmapSizeThreshold;
+ fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes;
+ fNotificationClient = NULL;
fPipeController.setPlaybackCanvas(fImmediateCanvas);
this->beginRecording();
}
@@ -272,6 +295,7 @@
DeferredDevice::~DeferredDevice() {
this->flushPendingCommands(kSilent_PlaybackMode);
SkSafeUnref(fImmediateCanvas);
+ SkSafeUnref(fSurface);
}
void DeferredDevice::setMaxRecordingStorage(size_t maxStorage) {
@@ -376,6 +400,11 @@
return fRecordingCanvas;
}
+SkImage* DeferredDevice::newImageShapshot() {
+ this->flush();
+ return fSurface ? fSurface->newImageShapshot() : NULL;
+}
+
uint32_t DeferredDevice::getDeviceCapabilities() {
return fImmediateDevice->getDeviceCapabilities();
}
@@ -437,7 +466,9 @@
SkAutoTUnref<SkDevice> compatibleDevice
(fImmediateDevice->createCompatibleDevice(config, width, height,
isOpaque));
- return SkNEW_ARGS(DeferredDevice, (compatibleDevice, fNotificationClient));
+ DeferredDevice* device = SkNEW_ARGS(DeferredDevice, (compatibleDevice));
+ device->setNotificationClient(fNotificationClient);
+ return device;
}
bool DeferredDevice::onReadPixels(
@@ -488,6 +519,11 @@
this->setDevice(device);
}
+SkDeferredCanvas::SkDeferredCanvas(SkSurface* surface) {
+ this->init();
+ this->INHERITED::setDevice(SkNEW_ARGS(DeferredDevice, (surface)))->unref();
+}
+
void SkDeferredCanvas::init() {
fDeferredDrawing = true; // On by default
}
@@ -584,6 +620,12 @@
return notificationClient;
}
+SkImage* SkDeferredCanvas::newImageShapshot() {
+ DeferredDevice* deferredDevice = this->getDeferredDevice();
+ SkASSERT(deferredDevice);
+ return deferredDevice ? deferredDevice->newImageShapshot() : NULL;
+}
+
bool SkDeferredCanvas::isFullFrame(const SkRect* rect,
const SkPaint* paint) const {
SkCanvas* canvas = this->drawingCanvas();