Index: src/core/SkRecordedDrawable.cpp |
diff --git a/src/core/SkRecordedDrawable.cpp b/src/core/SkRecordedDrawable.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9b5874f9272865047d0b58a770e4f2b0ddeca70b |
--- /dev/null |
+++ b/src/core/SkRecordedDrawable.cpp |
@@ -0,0 +1,102 @@ |
+/* |
+ * 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 "SkLayerInfo.h" |
+#include "SkMatrix.h" |
+#include "SkPictureData.h" |
+#include "SkPicturePlayback.h" |
+#include "SkPictureRecord.h" |
+#include "SkPictureRecorder.h" |
+#include "SkPictureUtils.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, nullptr/*callback*/); |
+} |
+ |
+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(); |
+ } |
+ |
+ SkAutoTUnref<SkLayerInfo> saveLayerData; |
+ if (fBBH && fDoSaveLayerInfo) { |
+ // TODO: can we avoid work by not allocating / filling these bounds? |
+ SkAutoTMalloc<SkRect> scratchBounds(fRecord->count()); |
+ saveLayerData.reset(new SkLayerInfo); |
+ |
+ SkRecordComputeLayers(fBounds, *fRecord, scratchBounds, pictList, saveLayerData); |
+ } |
+ |
+ size_t subPictureBytes = 0; |
+ for (int i = 0; pictList && i < pictList->count(); i++) { |
+ subPictureBytes += SkPictureUtils::ApproximateBytesUsed(pictList->begin()[i]); |
+ } |
+ // 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()), |
+ saveLayerData.release(), 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. |
+ SkRect clipBounds; |
+ pictureRecord.getClipBounds(&clipBounds); |
+ SkBBoxHierarchy* bbh; |
+ if (clipBounds.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, false); |
+ pictureData.flatten(buffer); |
+} |
+ |
+sk_sp<SkFlattenable> SkRecordedDrawable::CreateProc(SkReadBuffer& buffer) { |
+ // Read the bounds. |
+ SkRect bounds; |
+ buffer.readRect(&bounds); |
+ |
+ // Unflatten into a SkPictureData. |
+ SkPictInfo info; |
+ info.fCullRect = bounds; |
+ SkAutoTDelete<SkPictureData> pictureData(SkPictureData::CreateFromBuffer(buffer, info)); |
+ if (!pictureData) { |
+ return nullptr; |
+ } |
+ |
+ // Create a drawable. |
+ SkPicturePlayback playback(pictureData); |
+ SkPictureRecorder recorder; |
+ playback.draw(recorder.beginRecording(bounds), nullptr, &buffer); |
+ return recorder.finishRecordingAsDrawable(); |
+} |