Expose SkPicture::willPlayBackBitmaps()

This returns true if (1) the picture has finished recording and
(2) this picture or any picture drawn into it refers to any bitmaps. 
It allows clients doing complicated manipulations of the picture to 
early-out when there are no bitmaps present. 

BUG=303281
R=reed@google.com



git-svn-id: http://skia.googlecode.com/svn/trunk@11935 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
tomhudson@google.com 2013-10-24 11:12:47 +00:00
parent 583b18a209
commit 381010e550
5 changed files with 71 additions and 0 deletions

View File

@ -186,6 +186,13 @@ public:
*/
void serialize(SkWStream*, EncodeBitmap encoder = NULL) const;
/**
* Returns true if any bitmaps may be produced when this SkPicture
* is replayed.
* Returns false if called while still recording.
*/
bool willPlayBackBitmaps() const;
#ifdef SK_BUILD_FOR_ANDROID
/** Signals that the caller is prematurely done replaying the drawing
commands. This can be called from a canvas virtual while the picture

View File

@ -354,6 +354,11 @@ void SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const {
}
}
bool SkPicture::willPlayBackBitmaps() const {
if (!fPlayback) return false;
return fPlayback->containsBitmaps();
}
#ifdef SK_BUILD_FOR_ANDROID
void SkPicture::abortPlayback() {
if (NULL == fPlayback) {

View File

@ -300,6 +300,18 @@ void SkPicturePlayback::dumpSize() const {
SafeCount(fRegions));
}
bool SkPicturePlayback::containsBitmaps() const {
if (fBitmaps && fBitmaps->count() > 0) {
return true;
}
for (int i = 0; i < fPictureCount; ++i) {
if (fPictureRefs[i]->willPlayBackBitmaps()) {
return true;
}
}
return false;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

View File

@ -73,6 +73,8 @@ public:
void dumpSize() const;
bool containsBitmaps() const;
#ifdef SK_BUILD_FOR_ANDROID
// Can be called in the middle of playback (the draw() call). WIll abort the
// drawing and return from draw() after the "current" op code is done

View File

@ -182,6 +182,7 @@ static void test_gatherpixelrefs(skiatest::Reporter* reporter) {
for (size_t k = 0; k < SK_ARRAY_COUNT(procs); ++k) {
SkAutoTUnref<SkPicture> pic(record_bitmaps(bm, pos, N, procs[k]));
REPORTER_ASSERT(reporter, pic->willPlayBackBitmaps() || N == 0);
// quick check for a small piece of each quadrant, which should just
// contain 1 bitmap.
for (size_t i = 0; i < SK_ARRAY_COUNT(pos); ++i) {
@ -607,6 +608,49 @@ static void test_clip_expansion(skiatest::Reporter* reporter) {
REPORTER_ASSERT(reporter, testCanvas.getClipCount() == 2);
}
static void test_hierarchical(skiatest::Reporter* reporter) {
SkBitmap bm;
make_bm(&bm, 10, 10, SK_ColorRED, true);
SkCanvas* canvas;
SkPicture childPlain;
childPlain.beginRecording(10, 10);
childPlain.endRecording();
REPORTER_ASSERT(reporter, !childPlain.willPlayBackBitmaps()); // 0
SkPicture childWithBitmap;
childWithBitmap.beginRecording(10, 10)->drawBitmap(bm, 0, 0);
childWithBitmap.endRecording();
REPORTER_ASSERT(reporter, childWithBitmap.willPlayBackBitmaps()); // 1
SkPicture parentPP;
canvas = parentPP.beginRecording(10, 10);
canvas->drawPicture(childPlain);
parentPP.endRecording();
REPORTER_ASSERT(reporter, !parentPP.willPlayBackBitmaps()); // 0
SkPicture parentPWB;
canvas = parentPWB.beginRecording(10, 10);
canvas->drawPicture(childWithBitmap);
parentPWB.endRecording();
REPORTER_ASSERT(reporter, parentPWB.willPlayBackBitmaps()); // 1
SkPicture parentWBP;
canvas = parentWBP.beginRecording(10, 10);
canvas->drawBitmap(bm, 0, 0);
canvas->drawPicture(childPlain);
parentWBP.endRecording();
REPORTER_ASSERT(reporter, parentWBP.willPlayBackBitmaps()); // 1
SkPicture parentWBWB;
canvas = parentWBWB.beginRecording(10, 10);
canvas->drawBitmap(bm, 0, 0);
canvas->drawPicture(childWithBitmap);
parentWBWB.endRecording();
REPORTER_ASSERT(reporter, parentWBWB.willPlayBackBitmaps()); // 2
}
static void TestPicture(skiatest::Reporter* reporter) {
#ifdef SK_DEBUG
test_deleting_empty_playback();
@ -620,6 +664,7 @@ static void TestPicture(skiatest::Reporter* reporter) {
test_clone_empty(reporter);
test_clip_bound_opt(reporter);
test_clip_expansion(reporter);
test_hierarchical(reporter);
}
#include "TestClassDef.h"