#ifndef SkDeferredCanvas_DEFINED
#define SkDeferredCanvas_DEFINED
-#ifndef SK_DEFERRED_CANVAS_USES_GPIPE
-#define SK_DEFERRED_CANVAS_USES_GPIPE 1
-#endif
-
#include "SkCanvas.h"
#include "SkDevice.h"
#include "SkPixelRef.h"
-#if SK_DEFERRED_CANVAS_USES_GPIPE
#include "SkGPipe.h"
#include "SkChunkAlloc.h"
-#else
-#include "SkPicture.h"
-#endif
/** \class SkDeferredCanvas
Subclass of SkCanvas that encapsulates an SkPicture or SkGPipe for deferred
typedef SkRefCnt INHERITED;
};
-#if SK_DEFERRED_CANVAS_USES_GPIPE
protected:
class DeferredPipeController : public SkGPipeController {
public:
SkTDArray<PipeBlock> fBlockList;
SkGPipeReader fReader;
};
-#endif
public:
class DeferredDevice : public SkDevice {
void endRecording();
void beginRecording();
-#if SK_DEFERRED_CANVAS_USES_GPIPE
DeferredPipeController fPipeController;
SkGPipeWriter fPipeWriter;
-#else
- SkPicture fPicture;
-#endif
SkDevice* fImmediateDevice;
SkCanvas* fImmediateCanvas;
SkCanvas* fRecordingCanvas;
}
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 {
return drawingCanvas();
}
-#if SK_DEFERRED_CANVAS_USES_GPIPE
-
// SkDeferredCanvas::DeferredPipeController
//-------------------------------------------
fAllocator.reset();
}
-#endif // SK_DEFERRED_CANVAS_USES_GPIPE
-
// SkDeferredCanvas::DeferredDevice
//------------------------------------
SkSafeRef(fDeviceContext);
fImmediateDevice = immediateDevice; // ref counted via fImmediateCanvas
fImmediateCanvas = SkNEW_ARGS(SkCanvas, (fImmediateDevice));
-#if SK_DEFERRED_CANVAS_USES_GPIPE
fPipeController.setPlaybackCanvas(fImmediateCanvas);
-#endif
beginRecording();
}
}
void SkDeferredCanvas::DeferredDevice::endRecording() {
-#if SK_DEFERRED_CANVAS_USES_GPIPE
fPipeWriter.endRecording();
fPipeController.reset();
-#else
- fPicture.endRecording();
-#endif
fRecordingCanvas = NULL;
}
void SkDeferredCanvas::DeferredDevice::beginRecording() {
-#if SK_DEFERRED_CANVAS_USES_GPIPE
fRecordingCanvas = fPipeWriter.startRecording(&fPipeController, 0);
-#else
- fRecordingCanvas = fPicture.beginRecording(fImmediateDevice->width(),
- fImmediateDevice->height());
-#endif
}
void SkDeferredCanvas::DeferredDevice::setDeviceContext(
}
void SkDeferredCanvas::DeferredDevice::flushPending() {
-#if SK_DEFERRED_CANVAS_USES_GPIPE
if (!fPipeController.hasRecorded()) {
return;
}
-#else
- if (!fPicture.hasRecorded()) {
- return;
- }
-#endif
if (fDeviceContext) {
fDeviceContext->prepareForDraw();
}
-#if SK_DEFERRED_CANVAS_USES_GPIPE
fPipeWriter.flushRecording(true);
fPipeController.playback();
-#else
- fPicture.draw(fImmediateCanvas);
- this->beginRecording();
-#endif
}
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
size_t storageAllocated = this->storageAllocatedForRecording();
if (storageAllocated > fMaxRecordingStorageBytes) {
// First, attempt to reduce cache without flushing
this->freeMemoryIfPossible(~0);
}
}
-#endif
return fRecordingCanvas;
}
AssertCanvasStatesEqual(reporter, &deferredCanvas, &referenceCanvas,
testStep);
-#if SK_DEFERRED_CANVAS_USES_GPIPE
deferredCanvas.flush();
testStep->setAssertMessageFormat(
kDeferredPostFlushPlaybackAssertMessageFormat);
AssertCanvasStatesEqual(reporter,
deferredCanvas.getDeferredDevice()->immediateCanvas(),
&referenceCanvas, testStep);
-#endif
// Verified that deferred canvas state is not affected by flushing
// pending draw operations
canvas.drawBitmap(sourceImage, 0, 0, NULL);
}
- // SkPicture path is not fixed
-#if SK_DEFERRED_CANVAS_USES_GPIPE
REPORTER_ASSERT(reporter, mockDevice.fDrawBitmapCallCount == 4);
-#endif
}
-#if SK_DEFERRED_CANVAS_USES_GPIPE
static void TestDeferredCanvasBitmapCaching(skiatest::Reporter* reporter) {
SkBitmap store;
store.setConfig(SkBitmap::kARGB_8888_Config, 100, 100);
canvas.drawBitmap(sourceImages[1], 0, 0, NULL);
REPORTER_ASSERT(reporter, canvas.storageAllocatedForRecording() > 2*bitmapSize);
}
-#endif
static void TestDeferredCanvas(skiatest::Reporter* reporter) {
TestDeferredCanvasBitmapAccess(reporter);
TestDeferredCanvasFlush(reporter);
TestDeferredCanvasFreshFrame(reporter);
TestDeferredCanvasMemoryLimit(reporter);
-#if SK_DEFERRED_CANVAS_USES_GPIPE
TestDeferredCanvasBitmapCaching(reporter);
-#endif
}
#include "TestClassDef.h"