/* * Copyright 2016 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "SkMatrix.h" #include "SkPictureData.h" #include "SkPicturePlayback.h" #include "SkPictureRecord.h" #include "SkPictureRecorder.h" #include "SkRecordedDrawable.h" #include "SkRecordDraw.h" void SkRecordedDrawable::onDraw(SkCanvas* canvas) { SkDrawable* const* drawables = nullptr; int drawableCount = 0; if (fDrawableList) { drawables = fDrawableList->begin(); drawableCount = fDrawableList->count(); } SkRecordDraw(*fRecord, canvas, nullptr, drawables, drawableCount, fBBH.get(), nullptr); } SkPicture* SkRecordedDrawable::onNewPictureSnapshot() { SkBigPicture::SnapshotArray* pictList = nullptr; if (fDrawableList) { // TODO: should we plumb-down the BBHFactory and recordFlags from our host // PictureRecorder? pictList = fDrawableList->newDrawableSnapshot(); } size_t subPictureBytes = 0; for (int i = 0; pictList && i < pictList->count(); i++) { subPictureBytes += pictList->begin()[i]->approximateBytesUsed(); } // SkBigPicture will take ownership of a ref on both fRecord and fBBH. // We're not willing to give up our ownership, so we must ref them for SkPicture. return new SkBigPicture(fBounds, SkRef(fRecord.get()), pictList, SkSafeRef(fBBH.get()), subPictureBytes); } void SkRecordedDrawable::flatten(SkWriteBuffer& buffer) const { // Write the bounds. buffer.writeRect(fBounds); // Create an SkPictureRecord to record the draw commands. SkPictInfo info; SkPictureRecord pictureRecord(SkISize::Make(fBounds.width(), fBounds.height()), 0); // If the query contains the whole picture, don't bother with the bounding box hierarchy. SkBBoxHierarchy* bbh; if (pictureRecord.getLocalClipBounds().contains(fBounds)) { bbh = nullptr; } else { bbh = fBBH.get(); } // Record the draw commands. pictureRecord.beginRecording(); SkRecordDraw(*fRecord, &pictureRecord, nullptr, fDrawableList->begin(), fDrawableList->count(), bbh, nullptr); pictureRecord.endRecording(); // Flatten the recorded commands and drawables. SkPictureData pictureData(pictureRecord, info); pictureData.flatten(buffer); } sk_sp SkRecordedDrawable::CreateProc(SkReadBuffer& buffer) { // Read the bounds. SkRect bounds; buffer.readRect(&bounds); // Unflatten into a SkPictureData. SkPictInfo info; info.setVersion(buffer.getVersion()); info.fCullRect = bounds; std::unique_ptr pictureData(SkPictureData::CreateFromBuffer(buffer, info)); if (!pictureData) { return nullptr; } // Create a drawable. SkPicturePlayback playback(pictureData.get()); SkPictureRecorder recorder; playback.draw(recorder.beginRecording(bounds), nullptr, &buffer); return recorder.finishRecordingAsDrawable(); }