add SkPicture::MakePlaceholder()

Bug: skia:7536

Change-Id: I6ca7c680ef4fd69419254dc7f1af27343dbb8e89
Reviewed-on: https://skia-review.googlesource.com/99664
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
This commit is contained in:
Mike Klein 2018-01-26 09:49:48 -05:00 committed by Skia Commit-Bot
parent d3c1b84a6e
commit fbe6620284
3 changed files with 46 additions and 3 deletions

View File

@ -46,7 +46,7 @@ public:
/**
* Recreate a picture that was serialized into a buffer. If the creation requires bitmap
* decoding, the decoder must be set on the SkReadBuffer parameter by calling
* SkReadBuffer::setBitmapDecoder() before calling SkPicture::CreateFromBuffer().
* SkReadBuffer::setBitmapDecoder() before calling SkPicture::MakeFromBuffer().
* @param SkReadBuffer Serialized picture data.
* @return A new SkPicture representing the serialized data, or NULL if the buffer is
* invalid.
@ -90,6 +90,14 @@ public:
sk_sp<SkData> serialize(const SkSerialProcs* = nullptr) const;
void serialize(SkWStream*, const SkSerialProcs* = nullptr) const;
/**
* Return a placeholder SkPicture.
* This placeholder does not draw anything itself. It has a distinct uniqueID()
* (just like all SkPictures) and will always be visible to SkSerialProcs.
* @param cull the placeholder's dimensions
*/
static sk_sp<SkPicture> MakePlaceholder(SkRect cull);
/**
* Serialize to a buffer.
*/
@ -122,8 +130,8 @@ private:
/** Return true if the SkStream/Buffer represents a serialized picture, and
fills out SkPictInfo. After this function returns, the data source is not
rewound so it will have to be manually reset before passing to
CreateFromStream or CreateFromBuffer. Note, CreateFromStream and
CreateFromBuffer perform this check internally so these entry points are
MakeFromStream or MakeFromBuffer. Note, MakeFromStream and
MakeFromBuffer perform this check internally so these entry points are
intended for stand alone tools.
If false is returned, SkPictInfo is unmodified.
*/

View File

@ -316,3 +316,19 @@ void SkPicture::flatten(SkWriteBuffer& buffer) const {
}
}
sk_sp<SkPicture> SkPicture::MakePlaceholder(SkRect cull) {
struct Placeholder : public SkPicture {
explicit Placeholder(SkRect cull) : fCull(cull) {}
void playback(SkCanvas*, AbortCallback*) const override { }
// approximateOpCount() needs to be greater than kMaxPictureOpsToUnrollInsteadOfRef
// in SkCanvas.cpp to avoid that unrolling. SK_MaxS32 can't not be big enough!
int approximateOpCount() const override { return SK_MaxS32; }
size_t approximateBytesUsed() const override { return sizeof(*this); }
SkRect cullRect() const override { return fCull; }
SkRect fCull;
};
return sk_make_sp<Placeholder>(cull);
}

View File

@ -834,3 +834,22 @@ DEF_TEST(Picture_RecordsFlush, r) {
auto back = SkPicture::MakeFromData(skp->data(), skp->size());
REPORTER_ASSERT(r, back->approximateOpCount() == pic->approximateOpCount());
}
DEF_TEST(Placeholder, r) {
SkRect cull = { 0,0, 10,20 };
// Each placeholder is unique.
sk_sp<SkPicture> p1 = SkPicture::MakePlaceholder(cull),
p2 = SkPicture::MakePlaceholder(cull);
REPORTER_ASSERT(r, p1->cullRect() == p2->cullRect());
REPORTER_ASSERT(r, p1->cullRect() == cull);
REPORTER_ASSERT(r, p1->uniqueID() != p2->uniqueID());
// Placeholders are never unrolled by SkCanvas (while other small pictures may be).
SkPictureRecorder recorder;
SkCanvas* canvas = recorder.beginRecording(cull);
canvas->drawPicture(p1);
canvas->drawPicture(p2);
sk_sp<SkPicture> pic = recorder.finishRecordingAsPicture();
REPORTER_ASSERT(r, pic->approximateOpCount() == 2);
}