From 2e14ba8ceb41c68042ff133fecf0561a2c22efca Mon Sep 17 00:00:00 2001 From: "junov@chromium.org" Date: Tue, 7 Aug 2012 14:26:57 +0000 Subject: Adding API to SkGPipe and SkDeferredCanvas for controlling memory usage externally BUG=http://code.google.com/p/chromium/issues/detail?id=136828 Review URL: https://codereview.appspot.com/6454102 git-svn-id: http://skia.googlecode.com/svn/trunk@4971 2bbb7eff-a529-9590-31e7-b0007b416f81 --- src/utils/SkDeferredCanvas.cpp | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) (limited to 'src/utils/SkDeferredCanvas.cpp') diff --git a/src/utils/SkDeferredCanvas.cpp b/src/utils/SkDeferredCanvas.cpp index 2bcecf97e9..acac47cf06 100644 --- a/src/utils/SkDeferredCanvas.cpp +++ b/src/utils/SkDeferredCanvas.cpp @@ -164,6 +164,18 @@ void SkDeferredCanvas::setMaxRecordingStorage(size_t maxStorage) { this->getDeferredDevice()->setMaxRecordingStorage(maxStorage); } +size_t SkDeferredCanvas::storageAllocatedForRecording() const { + return this->getDeferredDevice()->storageAllocatedForRecording(); +} + +size_t SkDeferredCanvas::freeMemoryIfPossible(size_t bytesToFree) { +#if SK_DEFERRED_CANVAS_USES_GPIPE + return this->getDeferredDevice()->freeMemoryIfPossible(bytesToFree); +#else + return 0; +#endif +} + void SkDeferredCanvas::validate() const { SkASSERT(getDevice()); } @@ -690,12 +702,34 @@ void SkDeferredCanvas::DeferredDevice::flush() { fImmediateCanvas->flush(); } +#if SK_DEFERRED_CANVAS_USES_GPIPE +size_t SkDeferredCanvas::DeferredDevice::freeMemoryIfPossible(size_t bytesToFree) { + return fPipeWriter.freeMemoryIfPossible(bytesToFree); +} +#endif + +size_t SkDeferredCanvas::DeferredDevice::storageAllocatedForRecording() const { +#if SK_DEFERRED_CANVAS_USES_GPIPE + return (fPipeController.storageAllocatedForRecording() + + fPipeWriter.storageAllocatedForRecording()); +#else + return 0; +#endif +} + SkCanvas* SkDeferredCanvas::DeferredDevice::recordingCanvas() { #if SK_DEFERRED_CANVAS_USES_GPIPE - if (fPipeController.storageAllocatedForRecording() - + fPipeWriter.storageAllocatedForRecording() - > fMaxRecordingStorageBytes) { - this->flushPending(); + size_t storageAllocated = this->storageAllocatedForRecording(); + if (storageAllocated > fMaxRecordingStorageBytes) { + // First, attempt to reduce cache without flushing + size_t tryFree = storageAllocated - fMaxRecordingStorageBytes; + if (this->freeMemoryIfPossible(tryFree) < tryFree) { + // Flush is necessary to free more space. + this->flushPending(); + // Free as much as possible to avoid oscillating around fMaxRecordingStorageBytes + // which could cause a high flushing frequency. + this->freeMemoryIfPossible(~0); + } } #endif return fRecordingCanvas; -- cgit v1.2.3