Fixing a deferred canvas optimization that purges pending draws when the canvas is cleared
It appears that the recording canvas returns a save count of 1 when the save stack is empty. In order to pass Canvas unit tests when a clear occurs, changes to SkGPipe were necessary to allow SkDeferredCanvas to set the device bounds on the SkGPipeCanvas. A positive side effect of this change is that graphics primitives that fall outside of the device bounds will now always be culled at the recording stage (as opposed playback). BUG=http://code.google.com/p/skia/issues/detail?id=782 TEST=deferred_canvas_record bench test Review URL: https://codereview.appspot.com/6454157 git-svn-id: http://skia.googlecode.com/svn/trunk@5117 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
837d31a0c9
commit
a8db8fe39a
@ -103,7 +103,9 @@ public:
|
||||
kSharedAddressSpace_Flag = 1 << 1
|
||||
};
|
||||
|
||||
SkCanvas* startRecording(SkGPipeController*, uint32_t flags = 0);
|
||||
SkCanvas* startRecording(SkGPipeController*, uint32_t flags = 0,
|
||||
uint32_t width = kDefaultRecordingCanvasSize,
|
||||
uint32_t height = kDefaultRecordingCanvasSize);
|
||||
|
||||
// called in destructor, but can be called sooner once you know there
|
||||
// should be no more drawing calls made into the recording canvas.
|
||||
@ -136,6 +138,10 @@ public:
|
||||
size_t freeMemoryIfPossible(size_t bytesToFree);
|
||||
|
||||
private:
|
||||
enum {
|
||||
kDefaultRecordingCanvasSize = 32767,
|
||||
};
|
||||
|
||||
SkGPipeCanvas* fCanvas;
|
||||
SkWriter32 fWriter;
|
||||
};
|
||||
|
@ -163,7 +163,8 @@ public:
|
||||
|
||||
class SkGPipeCanvas : public SkCanvas {
|
||||
public:
|
||||
SkGPipeCanvas(SkGPipeController*, SkWriter32*, uint32_t flags);
|
||||
SkGPipeCanvas(SkGPipeController*, SkWriter32*, uint32_t flags,
|
||||
uint32_t width, uint32_t height);
|
||||
virtual ~SkGPipeCanvas();
|
||||
|
||||
void finish() {
|
||||
@ -400,7 +401,8 @@ private:
|
||||
#define FLATTENABLES_TO_KEEP 10
|
||||
|
||||
SkGPipeCanvas::SkGPipeCanvas(SkGPipeController* controller,
|
||||
SkWriter32* writer, uint32_t flags)
|
||||
SkWriter32* writer, uint32_t flags,
|
||||
uint32_t width, uint32_t height)
|
||||
: fFactorySet(isCrossProcess(flags) ? SkNEW(SkNamedFactorySet) : NULL)
|
||||
, fWriter(*writer)
|
||||
, fFlags(flags)
|
||||
@ -414,10 +416,9 @@ SkGPipeCanvas::SkGPipeCanvas(SkGPipeController* controller,
|
||||
sk_bzero(fCurrFlatIndex, sizeof(fCurrFlatIndex));
|
||||
|
||||
// we need a device to limit our clip
|
||||
// should the caller give us the bounds?
|
||||
// We don't allocate pixels for the bitmap
|
||||
SkBitmap bitmap;
|
||||
bitmap.setConfig(SkBitmap::kARGB_8888_Config, 32767, 32767);
|
||||
bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
|
||||
SkDevice* device = SkNEW_ARGS(SkDevice, (bitmap));
|
||||
this->setDevice(device)->unref();
|
||||
|
||||
@ -1091,10 +1092,11 @@ SkGPipeWriter::~SkGPipeWriter() {
|
||||
this->endRecording();
|
||||
}
|
||||
|
||||
SkCanvas* SkGPipeWriter::startRecording(SkGPipeController* controller, uint32_t flags) {
|
||||
SkCanvas* SkGPipeWriter::startRecording(SkGPipeController* controller, uint32_t flags,
|
||||
uint32_t width, uint32_t height) {
|
||||
if (NULL == fCanvas) {
|
||||
fWriter.reset(NULL, 0);
|
||||
fCanvas = SkNEW_ARGS(SkGPipeCanvas, (controller, &fWriter, flags));
|
||||
fCanvas = SkNEW_ARGS(SkGPipeCanvas, (controller, &fWriter, flags, width, height));
|
||||
}
|
||||
controller->setCanvas(fCanvas);
|
||||
return fCanvas;
|
||||
|
@ -348,6 +348,7 @@ DeferredDevice::DeferredDevice(
|
||||
SkDevice* immediateDevice, SkDeferredCanvas::NotificationClient* notificationClient) :
|
||||
SkDevice(SkBitmap::kNo_Config, immediateDevice->width(),
|
||||
immediateDevice->height(), immediateDevice->isOpaque())
|
||||
, fRecordingCanvas(NULL)
|
||||
, fFreshFrame(true)
|
||||
, fPreviousStorageAllocated(0){
|
||||
|
||||
@ -378,7 +379,9 @@ void DeferredDevice::endRecording() {
|
||||
}
|
||||
|
||||
void DeferredDevice::beginRecording() {
|
||||
fRecordingCanvas = fPipeWriter.startRecording(&fPipeController, 0);
|
||||
SkASSERT(NULL == fRecordingCanvas);
|
||||
fRecordingCanvas = fPipeWriter.startRecording(&fPipeController, 0,
|
||||
fImmediateDevice->width(), fImmediateDevice->height());
|
||||
}
|
||||
|
||||
void DeferredDevice::setNotificationClient(
|
||||
@ -392,8 +395,9 @@ void DeferredDevice::contentsCleared() {
|
||||
|
||||
// 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.
|
||||
if (fRecordingCanvas->getSaveCount() == 0) {
|
||||
// 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();
|
||||
|
Loading…
Reference in New Issue
Block a user