Remove legacy picture recording

This is unblocked now that Android no longer uses the old interface.

This is just the first step in cleaning this up. Future CLs will constify SkPicture access in SkCanvas and split up the SkPicture/SkPicturePlayback/SkPictureRecord trio.

R=bsalomon@google.com, reed@google.com, mtklein@google.com

Author: robertphillips@google.com

Review URL: https://codereview.chromium.org/313613002
This commit is contained in:
robertphillips 2014-06-03 10:04:47 -07:00 committed by Commit bot
parent 66aa609a49
commit dcf9ab14a1
11 changed files with 31 additions and 470 deletions

View File

@ -148,8 +148,6 @@
'<(skia_src_path)/core/SkQuadClipper.h',
'<(skia_src_path)/core/SkQuadTree.cpp',
'<(skia_src_path)/core/SkQuadTree.h',
'<(skia_src_path)/core/SkQuadTreePicture.cpp',
'<(skia_src_path)/core/SkQuadTreePicture.h',
'<(skia_src_path)/core/SkRasterClip.cpp',
'<(skia_src_path)/core/SkRasterizer.cpp',
'<(skia_src_path)/core/SkReadBuffer.cpp',
@ -161,7 +159,6 @@
'<(skia_src_path)/core/SkRRect.cpp',
'<(skia_src_path)/core/SkRTree.h',
'<(skia_src_path)/core/SkRTree.cpp',
'<(skia_src_path)/core/SkRTreePicture.cpp',
'<(skia_src_path)/core/SkScaledImageCache.cpp',
'<(skia_src_path)/core/SkScalar.cpp',
'<(skia_src_path)/core/SkScalerContext.cpp',
@ -190,7 +187,6 @@
'<(skia_src_path)/core/SkTextFormatParams.h',
'<(skia_src_path)/core/SkTileGrid.cpp',
'<(skia_src_path)/core/SkTileGrid.h',
'<(skia_src_path)/core/SkTileGridPicture.cpp',
'<(skia_src_path)/core/SkTLList.h',
'<(skia_src_path)/core/SkTLS.cpp',
'<(skia_src_path)/core/SkTraceEvent.h',
@ -286,7 +282,6 @@
'<(skia_include_path)/core/SkRefCnt.h',
'<(skia_include_path)/core/SkRegion.h',
'<(skia_include_path)/core/SkRRect.h',
'<(skia_include_path)/core/SkRTreePicture.h',
'<(skia_include_path)/core/SkScalar.h',
'<(skia_include_path)/core/SkShader.h',
'<(skia_include_path)/core/SkStream.h',

View File

@ -132,6 +132,9 @@ public:
*/
void clone(SkPicture* pictures, int count) const;
// TODO: kUsePathBoundsForClip_RecordingFlag no longer belongs in
// SkPicture. It should be moved to SkPictureRecorder (or just made
// the default behavior).
enum RecordingFlags {
/* This flag specifies that when clipPath() is called, the path will
be faithfully recorded, but the recording canvas' current clip will
@ -144,68 +147,6 @@ public:
kUsePathBoundsForClip_RecordingFlag = 0x01
};
#ifndef SK_SUPPORT_DEPRECATED_RECORD_FLAGS
// TODO: once kOptimizeForClippedPlayback_RecordingFlag is hidden from
// all external consumers, SkPicture::createBBoxHierarchy can also be
// cleaned up.
private:
#endif
enum Deprecated_RecordingFlags {
/* This flag causes the picture to compute bounding boxes and build
up a spatial hierarchy (currently an R-Tree), plus a tree of Canvas'
usually stack-based clip/etc state. This requires an increase in
recording time (often ~2x; likely more for very complex pictures),
but allows us to perform much faster culling at playback time, and
completely avoid some unnecessary clips and other operations. This
is ideal for tiled rendering, or any other situation where you're
drawing a fraction of a large scene into a smaller viewport.
In most cases the record cost is offset by the playback improvement
after a frame or two of tiled rendering (and complex pictures that
induce the worst record times will generally get the largest
speedups at playback time).
Note: Currently this is not serializable, the bounding data will be
discarded if you serialize into a stream and then deserialize.
*/
kOptimizeForClippedPlayback_RecordingFlag = 0x02,
};
#ifndef SK_SUPPORT_DEPRECATED_RECORD_FLAGS
public:
#endif
#ifndef SK_SUPPORT_LEGACY_PICTURE_CAN_RECORD
private:
#endif
#ifdef SK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES
/** Returns the canvas that records the drawing commands.
@param width the base width for the picture, as if the recording
canvas' bitmap had this width.
@param height the base width for the picture, as if the recording
canvas' bitmap had this height.
@param recordFlags optional flags that control recording.
@return the picture canvas.
*/
SkCanvas* beginRecording(int width, int height, uint32_t recordFlags = 0);
#endif
/** Returns the recording canvas if one is active, or NULL if recording is
not active. This does not alter the refcnt on the canvas (if present).
*/
SkCanvas* getRecordingCanvas() const;
/** Signal that the caller is done recording. This invalidates the canvas
returned by beginRecording/getRecordingCanvas, and prepares the picture
for drawing. Note: this happens implicitly the first time the picture
is drawn.
*/
void endRecording();
#ifndef SK_SUPPORT_LEGACY_PICTURE_CAN_RECORD
public:
#endif
/** Replays the drawing commands on the specified canvas. This internally
calls endRecording() if that has not already been called.
@param canvas the canvas receiving the drawing commands.
@ -353,14 +294,6 @@ protected:
// playback is unchanged.
SkPicture(SkPicturePlayback*, int width, int height);
#ifdef SK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES
// For testing. Derived classes may instantiate an alternate
// SkBBoxHierarchy implementation
virtual SkBBoxHierarchy* createBBoxHierarchy() const;
#endif
SkCanvas* beginRecording(int width, int height, SkBBHFactory* factory, uint32_t recordFlags);
private:
friend class SkPictureRecord;
friend class SkPictureTester; // for unit testing
@ -486,6 +419,31 @@ private:
friend class GrGatherDevice;
friend class SkDebugCanvas;
// TODO: beginRecording, getRecordingCanvas & endRecording can now be
// be moved out of SkPicture (and, presumably, be directly implemented
// in SkPictureRecorder)
/** Returns the canvas that records the drawing commands.
@param width the base width for the picture, as if the recording
canvas' bitmap had this width.
@param height the base width for the picture, as if the recording
canvas' bitmap had this height.
@param factory if non-NULL, the factory used to the BBH for the recorded picture
@param recordFlags optional flags that control recording.
@return the picture canvas.
*/
SkCanvas* beginRecording(int width, int height, SkBBHFactory* factory, uint32_t recordFlags);
/** Returns the recording canvas if one is active, or NULL if recording is
not active. This does not alter the refcnt on the canvas (if present).
*/
SkCanvas* getRecordingCanvas() const;
/** Signal that the caller is done recording. This invalidates the canvas
returned by beginRecording/getRecordingCanvas, and prepares the picture
for drawing. Note: this happens implicitly the first time the picture
is drawn.
*/
void endRecording();
typedef SkRefCnt INHERITED;
};
@ -507,23 +465,4 @@ public:
virtual bool abortDrawing() = 0;
};
#ifdef SK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES
class SkPictureFactory : public SkRefCnt {
public:
/**
* Allocate a new SkPicture. Return NULL on failure.
*/
virtual SkPicture* create(int width, int height) = 0;
private:
typedef SkRefCnt INHERITED;
};
#endif
#ifdef SK_SUPPORT_LEGACY_PICTURE_HEADERS
#include "SkPictureRecorder.h"
#endif
#endif

View File

@ -16,35 +16,6 @@ class SkCanvas;
class SK_API SkPictureRecorder : SkNoncopyable {
public:
#ifdef SK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES
SkPictureRecorder(SkPictureFactory* factory = NULL) {
fFactory.reset(factory);
if (NULL != fFactory.get()) {
fFactory.get()->ref();
}
}
/** Returns the canvas that records the drawing commands.
@param width the base width for the picture, as if the recording
canvas' bitmap had this width.
@param height the base width for the picture, as if the recording
canvas' bitmap had this height.
@param recordFlags optional flags that control recording.
@return the canvas.
*/
SkCanvas* beginRecording(int width, int height, uint32_t recordFlags = 0) {
if (NULL != fFactory) {
fPicture.reset(fFactory->create(width, height));
recordFlags |= SkPicture::kOptimizeForClippedPlayback_RecordingFlag;
} else {
fPicture.reset(SkNEW(SkPicture));
}
return fPicture->beginRecording(width, height, recordFlags);
}
#endif
/** Returns the canvas that records the drawing commands.
@param width the base width for the picture, as if the recording
canvas' bitmap had this width.
@ -95,10 +66,6 @@ public:
}
private:
#ifdef SK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES
SkAutoTUnref<SkPictureFactory> fFactory;
#endif
#ifdef SK_BUILD_FOR_ANDROID
/** Replay the current (partially recorded) operation stream into
canvas. This call doesn't close the current recording.

View File

@ -1,43 +0,0 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkRTreePicture_DEFINED
#define SkRTreePicture_DEFINED
#ifdef SK_SUPPORT_LEGACY_PICTURE_HEADERS
#include "SkBBHFactory.h"
#endif
#ifdef SK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES
#include "SkPicture.h"
/**
* Subclass of SkPicture that creates an RTree acceleration structure.
*/
class SkRTreePicture : public SkPicture {
public:
virtual SkBBoxHierarchy* createBBoxHierarchy() const SK_OVERRIDE;
private:
typedef SkPicture INHERITED;
};
class SkRTreePictureFactory : public SkPictureFactory {
public:
SkRTreePictureFactory() {}
virtual SkPicture* create(int width, int height) SK_OVERRIDE {
return SkNEW(SkRTreePicture);
}
private:
typedef SkPictureFactory INHERITED;
};
#endif
#endif

View File

@ -1,64 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkTileGridPicture_DEFINED
#define SkTileGridPicture_DEFINED
#ifdef SK_SUPPORT_LEGACY_PICTURE_HEADERS
#include "SkBBHFactory.h"
#endif
#ifdef SK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES
#include "SkPicture.h"
#include "SkPoint.h"
#include "SkSize.h"
/**
* Subclass of SkPicture that creates an SkTileGrid. The tile grid has lower recording
* and playback costs then rTree, but is less effective at eliminating extraneous
* primitives for arbitrary query rectangles. It is most effective for
* tiled playback when the tile structure is known at record time.
*/
class SK_API SkTileGridPicture : public SkPicture {
public:
typedef SkTileGridFactory::TileGridInfo TileGridInfo;
/**
* Constructor
* @param width recording canvas width in device pixels
* @param height recording canvas height in device pixels
* @param info description of the tiling layout
*/
SkTileGridPicture(int width, int height, const SkTileGridFactory::TileGridInfo& info);
virtual SkBBoxHierarchy* createBBoxHierarchy() const SK_OVERRIDE;
private:
int fXTileCount, fYTileCount;
SkTileGridFactory::TileGridInfo fInfo;
typedef SkPicture INHERITED;
};
class SkTileGridPictureFactory : public SkPictureFactory {
public:
SkTileGridPictureFactory(const SkTileGridFactory::TileGridInfo& info) : fInfo(info) { }
virtual SkPicture* create(int width, int height) SK_OVERRIDE {
return SkNEW_ARGS(SkTileGridPicture, (width, height, fInfo));
}
protected:
SkTileGridFactory::TileGridInfo fInfo;
private:
typedef SkPictureFactory INHERITED;
};
#endif
#endif

View File

@ -312,41 +312,6 @@ SkPicture::AccelData::Domain SkPicture::AccelData::GenerateDomain() {
///////////////////////////////////////////////////////////////////////////////
#ifdef SK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES
SkCanvas* SkPicture::beginRecording(int width, int height,
uint32_t recordingFlags) {
if (fPlayback) {
SkDELETE(fPlayback);
fPlayback = NULL;
}
SkSafeUnref(fAccelData);
SkSafeSetNull(fRecord);
fContentInfo.reset();
this->needsNewGenID();
// Must be set before calling createBBoxHierarchy
fWidth = width;
fHeight = height;
const SkISize size = SkISize::Make(width, height);
if (recordingFlags & kOptimizeForClippedPlayback_RecordingFlag) {
SkBBoxHierarchy* tree = this->createBBoxHierarchy();
SkASSERT(NULL != tree);
fRecord = SkNEW_ARGS(SkBBoxHierarchyRecord, (this, size, recordingFlags, tree));
tree->unref();
} else {
fRecord = SkNEW_ARGS(SkPictureRecord, (this, size, recordingFlags));
}
fRecord->beginRecording();
return fRecord;
}
#endif
SkCanvas* SkPicture::beginRecording(int width, int height,
SkBBHFactory* bbhFactory,
uint32_t recordingFlags) {
@ -369,10 +334,7 @@ SkCanvas* SkPicture::beginRecording(int width, int height,
if (NULL != bbhFactory) {
SkAutoTUnref<SkBBoxHierarchy> tree((*bbhFactory)(width, height));
SkASSERT(NULL != tree);
fRecord = SkNEW_ARGS(SkBBoxHierarchyRecord, (this, size,
recordingFlags|
kOptimizeForClippedPlayback_RecordingFlag,
tree.get()));
fRecord = SkNEW_ARGS(SkBBoxHierarchyRecord, (this, size, recordingFlags, tree.get()));
} else {
fRecord = SkNEW_ARGS(SkPictureRecord, (this, size, recordingFlags));
}
@ -381,29 +343,6 @@ SkCanvas* SkPicture::beginRecording(int width, int height,
return fRecord;
}
#ifdef SK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES
SkBBoxHierarchy* SkPicture::createBBoxHierarchy() const {
// TODO: this code is now replicated in SkRTreePicture. Once all external
// clients have been weaned off of kOptimizeForClippedPlayback_RecordingFlag,
// this code can be removed.
// These values were empirically determined to produce reasonable
// performance in most cases.
static const int kRTreeMinChildren = 6;
static const int kRTreeMaxChildren = 11;
SkScalar aspectRatio = SkScalarDiv(SkIntToScalar(fWidth),
SkIntToScalar(fHeight));
bool sortDraws = false; // Do not sort draw calls when bulk loading.
return SkRTree::Create(kRTreeMinChildren, kRTreeMaxChildren,
aspectRatio, sortDraws);
}
#endif
SkCanvas* SkPicture::getRecordingCanvas() const {
// will be null if we are not recording
return fRecord;
@ -428,7 +367,7 @@ const SkPicture::OperationList& SkPicture::OperationList::InvalidList() {
}
const SkPicture::OperationList& SkPicture::EXPERIMENTAL_getActiveOps(const SkIRect& queryRect) {
this->endRecording(); // TODO: remove eventually
SkASSERT(NULL != fPlayback && NULL == fRecord);
if (NULL != fPlayback) {
return fPlayback->getActiveOps(queryRect);
}
@ -443,7 +382,7 @@ size_t SkPicture::EXPERIMENTAL_curOpID() const {
}
void SkPicture::draw(SkCanvas* surface, SkDrawPictureCallback* callback) {
this->endRecording(); // TODO: remove eventually
SkASSERT(NULL != fPlayback && NULL == fRecord);
if (NULL != fPlayback) {
fPlayback->draw(*surface, callback);
}

View File

@ -1,18 +0,0 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifdef SK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES
#include "SkQuadTreePicture.h"
#include "SkQuadTree.h"
SkBBoxHierarchy* SkQuadTreePicture::createBBoxHierarchy() const {
return SkNEW_ARGS(SkQuadTree, (fBounds));
}
#endif

View File

@ -1,50 +0,0 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkQuadTreePicture_DEFINED
#define SkQuadTreePicture_DEFINED
#ifdef SK_SUPPORT_LEGACY_PICTURE_HEADERS
#include "SkBBHFactory.h"
#endif
#ifdef SK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES
#include "SkPicture.h"
#include "SkRect.h"
/**
* Subclass of SkPicture that creates an SkQuadGrid
* structure. The quad tree has generally faster
* tree creation time, but slightly slower query times, as compared to
* R-Tree, so some cases may be faster and some cases slower.
*/
class SK_API SkQuadTreePicture : public SkPicture {
public:
SkQuadTreePicture(const SkIRect& bounds) : fBounds(bounds) {}
virtual SkBBoxHierarchy* createBBoxHierarchy() const SK_OVERRIDE;
private:
SkIRect fBounds;
typedef SkPicture INHERITED;
};
class SkQuadTreePictureFactory : public SkPictureFactory {
public:
SkQuadTreePictureFactory() {}
virtual SkPicture* create(int width, int height) SK_OVERRIDE {
return SkNEW_ARGS(SkQuadTreePicture, (SkIRect::MakeWH(width, height)));
}
private:
typedef SkPictureFactory INHERITED;
};
#endif
#endif

View File

@ -1,28 +0,0 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifdef SK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES
#include "SkRTreePicture.h"
#include "SkRTree.h"
SkBBoxHierarchy* SkRTreePicture::createBBoxHierarchy() const {
// These values were empirically determined to produce reasonable
// performance in most cases.
static const int kRTreeMinChildren = 6;
static const int kRTreeMaxChildren = 11;
SkScalar aspectRatio = SkScalarDiv(SkIntToScalar(fWidth),
SkIntToScalar(fHeight));
bool sortDraws = false; // Do not sort draw calls when bulk loading.
return SkRTree::Create(kRTreeMinChildren, kRTreeMaxChildren,
aspectRatio, sortDraws);
}
#endif

View File

@ -1,33 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifdef SK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES
#include "SkTileGridPicture.h"
#include "SkPictureStateTree.h"
#include "SkTileGrid.h"
SkTileGridPicture::SkTileGridPicture(int width, int height,
const SkTileGridFactory::TileGridInfo& info) {
SkASSERT(info.fMargin.width() >= 0);
SkASSERT(info.fMargin.height() >= 0);
fInfo = info;
// Note: SkIRects are non-inclusive of the right() column and bottom() row.
// For example, an SkIRect at 0,0 with a size of (1,1) will only have
// content at pixel (0,0) and will report left=0 and right=1, hence the
// "-1"s below.
fXTileCount = (width + info.fTileInterval.width() - 1) / info.fTileInterval.width();
fYTileCount = (height + info.fTileInterval.height() - 1) / info.fTileInterval.height();
}
SkBBoxHierarchy* SkTileGridPicture::createBBoxHierarchy() const {
return SkNEW_ARGS(SkTileGrid, (fXTileCount, fYTileCount, fInfo,
SkTileGridNextDatum<SkPictureStateTree::Draw>));
}
#endif

View File

@ -1103,49 +1103,6 @@ static void test_unbalanced_save_restores(skiatest::Reporter* reporter) {
REPORTER_ASSERT(reporter, 4 == testCanvas.getSaveCount());
REPORTER_ASSERT(reporter, testCanvas.getTotalMatrix().isIdentity());
}
#if defined(SK_SUPPORT_LEGACY_PICTURE_CAN_RECORD) && \
defined(SK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES)
set_canvas_to_save_count_4(&testCanvas);
// Due to "fake" endRecording, the old SkPicture recording interface
// allowed unbalanced saves/restores to leak out. This sub-test checks
// that the situation has been remedied.
{
SkPicture p;
SkCanvas* canvas = p.beginRecording(100, 100);
for (int i = 0; i < 4; ++i) {
canvas->save();
}
SkRect r = SkRect::MakeWH(50, 50);
SkPaint paint;
canvas->drawRect(r, paint);
// Check that copying a mid-recording picture does not result in unbalanced saves/restores
SkPicture p2(p);
testCanvas.drawPicture(p2);
REPORTER_ASSERT(reporter, 4 == testCanvas.getSaveCount());
set_canvas_to_save_count_4(&testCanvas);
// Check that cloning a mid-recording picture does not result in unbalanced saves/restores
SkAutoTUnref<SkPicture> p3(p.clone());
testCanvas.drawPicture(*p3);
REPORTER_ASSERT(reporter, 4 == testCanvas.getSaveCount());
set_canvas_to_save_count_4(&testCanvas);
// Check that serializing a mid-recording picture doesn't result in unbalanced
// saves/restores
SkDynamicMemoryWStream wStream;
p.serialize(&wStream);
SkAutoDataUnref data(wStream.copyToData());
SkMemoryStream stream(data);
SkAutoTUnref<SkPicture> p4(SkPicture::CreateFromStream(&stream, NULL));
testCanvas.drawPicture(*p4);
REPORTER_ASSERT(reporter, 4 == testCanvas.getSaveCount());
}
#endif
}
static void test_peephole() {