aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/utils/SkDeferredCanvas.cpp84
1 files changed, 22 insertions, 62 deletions
diff --git a/src/utils/SkDeferredCanvas.cpp b/src/utils/SkDeferredCanvas.cpp
index a3306c52a3..5beaa5bc92 100644
--- a/src/utils/SkDeferredCanvas.cpp
+++ b/src/utils/SkDeferredCanvas.cpp
@@ -21,6 +21,11 @@ enum {
kDefaultMaxRecordingStorageBytes = 64*1024*1024,
};
+enum PlaybackMode {
+ kNormal_PlaybackMode,
+ kSilent_PlaybackMode,
+};
+
namespace {
bool shouldDrawImmediately(const SkBitmap* bitmap, const SkPaint* paint) {
if (bitmap && bitmap->getTexture() && !bitmap->isImmutable()) {
@@ -152,7 +157,6 @@ public:
virtual void* requestBlock(size_t minRequest, size_t* actual) SK_OVERRIDE;
virtual void notifyWritten(size_t bytes) SK_OVERRIDE;
void playback(bool silent);
- void reset();
bool hasRecorded() const { return fAllocator.blockCount() != 0; }
size_t storageAllocatedForRecording() const { return fAllocator.totalCapacity(); }
private:
@@ -219,16 +223,9 @@ void DeferredPipeController::playback(bool silent) {
fAllocator.reset();
}
-void DeferredPipeController::reset() {
- fBlockList.reset();
- fBlock = NULL;
- fAllocator.reset();
-}
-
//-----------------------------------------------------------------------------
// DeferredDevice
//-----------------------------------------------------------------------------
-
class DeferredDevice : public SkDevice {
public:
DeferredDevice(SkDevice* immediateDevice,
@@ -242,7 +239,7 @@ public:
bool isFreshFrame();
size_t storageAllocatedForRecording() const;
size_t freeMemoryIfPossible(size_t bytesToFree);
- void flushPendingCommands(bool silent);
+ void flushPendingCommands(PlaybackMode);
void skipPendingCommands();
void setMaxRecordingStorage(size_t);
void recordedDrawCommand();
@@ -329,7 +326,6 @@ protected:
private:
virtual void flush();
- void endRecording();
void beginRecording();
DeferredPipeController fPipeController;
@@ -360,7 +356,7 @@ DeferredDevice::DeferredDevice(
}
DeferredDevice::~DeferredDevice() {
- this->flushPendingCommands(true);
+ this->flushPendingCommands(kSilent_PlaybackMode);
SkSafeUnref(fImmediateCanvas);
}
@@ -369,12 +365,6 @@ void DeferredDevice::setMaxRecordingStorage(size_t maxStorage) {
this->recordingCanvas(); // Accessing the recording canvas applies the new limit.
}
-void DeferredDevice::endRecording() {
- fPipeWriter.endRecording();
- fPipeController.reset();
- fRecordingCanvas = NULL;
-}
-
void DeferredDevice::beginRecording() {
SkASSERT(NULL == fRecordingCanvas);
fRecordingCanvas = fPipeWriter.startRecording(&fPipeController, 0,
@@ -387,39 +377,9 @@ void DeferredDevice::setNotificationClient(
}
void DeferredDevice::skipPendingCommands() {
- if (!fRecordingCanvas->isDrawingToLayer()) {
+ if (!fRecordingCanvas->isDrawingToLayer() && fPipeController.hasRecorded()) {
fFreshFrame = true;
-
- // TODO: find a way to transfer the state stack and layers
- // to the new recording canvas. For now, purging only works
- // with an empty stack. A save count of 1 means an empty stack.
- SkASSERT(fRecordingCanvas->getSaveCount() >= 1);
- if (fRecordingCanvas->getSaveCount() == 1) {
-
- // Save state that is trashed by the purge
- SkDrawFilter* drawFilter = fRecordingCanvas->getDrawFilter();
- SkSafeRef(drawFilter); // So that it survives the purge
- SkMatrix matrix = fRecordingCanvas->getTotalMatrix();
- SkRegion clipRegion = fRecordingCanvas->getTotalClip();
-
- // beginRecording creates a new recording canvas and discards the
- // old one, hence purging deferred draw ops.
- this->endRecording();
- this->beginRecording();
- fPreviousStorageAllocated = storageAllocatedForRecording();
-
- // Restore pre-purge state
- if (!clipRegion.isEmpty()) {
- fRecordingCanvas->clipRegion(clipRegion,
- SkRegion::kReplace_Op);
- }
- if (!matrix.isIdentity()) {
- fRecordingCanvas->setMatrix(matrix);
- }
- if (drawFilter) {
- fRecordingCanvas->setDrawFilter(drawFilter)->unref();
- }
- }
+ flushPendingCommands(kSilent_PlaybackMode);
}
}
@@ -429,23 +389,23 @@ bool DeferredDevice::isFreshFrame() {
return ret;
}
-void DeferredDevice::flushPendingCommands(bool silent) {
+void DeferredDevice::flushPendingCommands(PlaybackMode playbackMode) {
if (!fPipeController.hasRecorded()) {
return;
}
- if (fNotificationClient) {
+ if (playbackMode == kNormal_PlaybackMode && fNotificationClient) {
fNotificationClient->prepareForDraw();
}
fPipeWriter.flushRecording(true);
- fPipeController.playback(silent);
- if (fNotificationClient) {
+ fPipeController.playback(playbackMode);
+ if (playbackMode == kNormal_PlaybackMode && fNotificationClient) {
fNotificationClient->flushedDrawCommands();
}
fPreviousStorageAllocated = storageAllocatedForRecording();
}
void DeferredDevice::flush() {
- this->flushPendingCommands(false);
+ this->flushPendingCommands(kNormal_PlaybackMode);
fImmediateCanvas->flush();
}
@@ -468,7 +428,7 @@ void DeferredDevice::recordedDrawCommand() {
size_t tryFree = storageAllocated - fMaxRecordingStorageBytes;
if (this->freeMemoryIfPossible(tryFree) < tryFree) {
// Flush is necessary to free more space.
- this->flushPendingCommands(false);
+ this->flushPendingCommands(kNormal_PlaybackMode);
// Free as much as possible to avoid oscillating around fMaxRecordingStorageBytes
// which could cause a high flushing frequency.
this->freeMemoryIfPossible(~0U);
@@ -500,7 +460,7 @@ int DeferredDevice::height() const {
}
SkGpuRenderTarget* DeferredDevice::accessRenderTarget() {
- this->flushPendingCommands(false);
+ this->flushPendingCommands(kNormal_PlaybackMode);
return fImmediateDevice->accessRenderTarget();
}
@@ -516,7 +476,7 @@ void DeferredDevice::writePixels(const SkBitmap& bitmap,
SkCanvas::kNative_Premul_Config8888 != config8888 &&
kPMColorAlias != config8888) {
//Special case config: no deferral
- this->flushPendingCommands(false);
+ this->flushPendingCommands(kNormal_PlaybackMode);
fImmediateDevice->writePixels(bitmap, x, y, config8888);
return;
}
@@ -524,7 +484,7 @@ void DeferredDevice::writePixels(const SkBitmap& bitmap,
SkPaint paint;
paint.setXfermodeMode(SkXfermode::kSrc_Mode);
if (shouldDrawImmediately(&bitmap, NULL)) {
- this->flushPendingCommands(false);
+ this->flushPendingCommands(kNormal_PlaybackMode);
fImmediateCanvas->drawSprite(bitmap, x, y, &paint);
} else {
this->recordingCanvas()->drawSprite(bitmap, x, y, &paint);
@@ -534,7 +494,7 @@ void DeferredDevice::writePixels(const SkBitmap& bitmap,
}
const SkBitmap& DeferredDevice::onAccessBitmap(SkBitmap*) {
- this->flushPendingCommands(false);
+ this->flushPendingCommands(kNormal_PlaybackMode);
return fImmediateDevice->accessBitmap(false);
}
@@ -553,7 +513,7 @@ SkDevice* DeferredDevice::onCreateCompatibleDevice(
bool DeferredDevice::onReadPixels(
const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) {
- this->flushPendingCommands(false);
+ this->flushPendingCommands(kNormal_PlaybackMode);
return fImmediateCanvas->readPixels(const_cast<SkBitmap*>(&bitmap),
x, y, config8888);
}
@@ -615,7 +575,7 @@ void SkDeferredCanvas::setDeferredDrawing(bool val) {
if (val != fDeferredDrawing) {
if (fDeferredDrawing) {
// Going live.
- this->getDeferredDevice()->flushPendingCommands(false);
+ this->getDeferredDevice()->flushPendingCommands(kNormal_PlaybackMode);
}
fDeferredDrawing = val;
}
@@ -631,7 +591,7 @@ bool SkDeferredCanvas::isFreshFrame() const {
void SkDeferredCanvas::silentFlush() {
if (fDeferredDrawing) {
- this->getDeferredDevice()->flushPendingCommands(true);
+ this->getDeferredDevice()->flushPendingCommands(kSilent_PlaybackMode);
}
}