Allow reset of the SkPictureRecorder cull rect and other parameters during endRecording.

For some users of SkPictureRecorder, the cull rect is more efficiently
determined while drawing is in progress, rather than when recording starts.
The existing API requires the cull rect at start time, even though the
information is not used for any culling purpose until the end of recording.

This patch provides a means to reset the cull rect when recording ends,
allowing users to update the rect based on information learned during
drawing and for the new rect to be used as the culling bound. A valid
bound is still required on the beginRecording call because
it sizes the underlying canvas and sets the aspect ratio for any bounding
box hierarchy. The bounding box factory can also be specified and parameters
that control SkPicture creation.

R=mtklein, reed1
BUG=skia:3919

Review URL: https://codereview.chromium.org/1178673007
This commit is contained in:
schenney 2015-07-07 14:27:10 -07:00 committed by Commit bot
parent 0dacc6708d
commit eeff8bb8ff
3 changed files with 45 additions and 0 deletions

View File

@ -74,6 +74,17 @@ public:
*/
SkPicture* SK_WARN_UNUSED_RESULT endRecordingAsPicture();
/**
* Signal that the caller is done recording, and update the cull rect to use for bounding
* box hierarchy (BBH) generation. The behavior is the same as calling
* endRecordingAsPicture(), except that this method updates the cull rect initially passed
* into beginRecording.
* @param cullRect the new culling rectangle to use as the overall bound for BBH generation
* and subsequent culling operations.
* @return the picture containing the recorded content.
*/
SkPicture* SK_WARN_UNUSED_RESULT endRecordingAsPicture(const SkRect& cullRect);
/**
* Signal that the caller is done recording. This invalidates the canvas returned by
* beginRecording/getRecordingCanvas. Ownership of the object is passed to the caller, who

View File

@ -95,6 +95,12 @@ SkPicture* SkPictureRecorder::endRecordingAsPicture() {
subPictureBytes));
}
SkPicture* SkPictureRecorder::endRecordingAsPicture(const SkRect& cullRect) {
fCullRect = cullRect;
return this->endRecordingAsPicture();
}
void SkPictureRecorder::partialReplay(SkCanvas* canvas) const {
if (NULL == canvas) {
return;

View File

@ -984,6 +984,33 @@ static void test_clip_bound_opt(skiatest::Reporter* reporter) {
}
}
static void test_cull_rect_reset(skiatest::Reporter* reporter) {
SkPictureRecorder recorder;
SkRect bounds = SkRect::MakeWH(10, 10);
SkRTreeFactory factory;
SkCanvas* canvas = recorder.beginRecording(bounds, &factory);
bounds = SkRect::MakeWH(100, 100);
SkPaint paint;
canvas->drawRect(bounds, paint);
canvas->drawRect(bounds, paint);
const SkBigPicture* picture = recorder.endRecordingAsPicture(bounds)->asSkBigPicture();
REPORTER_ASSERT(reporter, picture);
SkRect finalCullRect = picture->cullRect();
REPORTER_ASSERT(reporter, 0 == finalCullRect.fLeft);
REPORTER_ASSERT(reporter, 0 == finalCullRect.fTop);
REPORTER_ASSERT(reporter, 100 == finalCullRect.fBottom);
REPORTER_ASSERT(reporter, 100 == finalCullRect.fRight);
const SkBBoxHierarchy* pictureBBH = picture->bbh();
SkRect bbhCullRect = pictureBBH->getRootBound();
REPORTER_ASSERT(reporter, 0 == bbhCullRect.fLeft);
REPORTER_ASSERT(reporter, 0 == bbhCullRect.fTop);
REPORTER_ASSERT(reporter, 100 == bbhCullRect.fBottom);
REPORTER_ASSERT(reporter, 100 == bbhCullRect.fRight);
}
/**
* A canvas that records the number of clip commands.
*/
@ -1129,6 +1156,7 @@ DEF_TEST(Picture, reporter) {
test_hierarchical(reporter);
test_gen_id(reporter);
test_savelayer_extraction(reporter);
test_cull_rect_reset(reporter);
}
static void draw_bitmaps(const SkBitmap bitmap, SkCanvas* canvas) {