1 /* 2 * Copyright 2016 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkMatrix.h" 9 #include "SkPictureData.h" 10 #include "SkPicturePlayback.h" 11 #include "SkPictureRecord.h" 12 #include "SkPictureRecorder.h" 13 #include "SkRecordedDrawable.h" 14 #include "SkRecordDraw.h" 15 16 void SkRecordedDrawable::onDraw(SkCanvas* canvas) { 17 SkDrawable* const* drawables = nullptr; 18 int drawableCount = 0; 19 if (fDrawableList) { 20 drawables = fDrawableList->begin(); 21 drawableCount = fDrawableList->count(); 22 } 23 SkRecordDraw(*fRecord, canvas, nullptr, drawables, drawableCount, fBBH.get(), nullptr); 24 } 25 26 SkPicture* SkRecordedDrawable::onNewPictureSnapshot() { 27 SkBigPicture::SnapshotArray* pictList = nullptr; 28 if (fDrawableList) { 29 // TODO: should we plumb-down the BBHFactory and recordFlags from our host 30 // PictureRecorder? 31 pictList = fDrawableList->newDrawableSnapshot(); 32 } 33 34 size_t subPictureBytes = 0; 35 for (int i = 0; pictList && i < pictList->count(); i++) { 36 subPictureBytes += pictList->begin()[i]->approximateBytesUsed(); 37 } 38 // SkBigPicture will take ownership of a ref on both fRecord and fBBH. 39 // We're not willing to give up our ownership, so we must ref them for SkPicture. 40 return new SkBigPicture(fBounds, SkRef(fRecord.get()), pictList, SkSafeRef(fBBH.get()), 41 subPictureBytes); 42 } 43 44 void SkRecordedDrawable::flatten(SkWriteBuffer& buffer) const { 45 // Write the bounds. 46 buffer.writeRect(fBounds); 47 48 // Create an SkPictureRecord to record the draw commands. 49 SkPictInfo info; 50 SkPictureRecord pictureRecord(SkISize::Make(fBounds.width(), fBounds.height()), 0); 51 52 // If the query contains the whole picture, don't bother with the bounding box hierarchy. 53 SkBBoxHierarchy* bbh; 54 if (pictureRecord.getLocalClipBounds().contains(fBounds)) { 55 bbh = nullptr; 56 } else { 57 bbh = fBBH.get(); 58 } 59 60 // Record the draw commands. 61 pictureRecord.beginRecording(); 62 SkRecordDraw(*fRecord, &pictureRecord, nullptr, fDrawableList->begin(), fDrawableList->count(), 63 bbh, nullptr); 64 pictureRecord.endRecording(); 65 66 // Flatten the recorded commands and drawables. 67 SkPictureData pictureData(pictureRecord, info); 68 pictureData.flatten(buffer); 69 } 70 71 sk_sp<SkFlattenable> SkRecordedDrawable::CreateProc(SkReadBuffer& buffer) { 72 // Read the bounds. 73 SkRect bounds; 74 buffer.readRect(&bounds); 75 76 // Unflatten into a SkPictureData. 77 SkPictInfo info; 78 info.setVersion(buffer.getVersion()); 79 info.fCullRect = bounds; 80 std::unique_ptr<SkPictureData> pictureData(SkPictureData::CreateFromBuffer(buffer, info)); 81 if (!pictureData) { 82 return nullptr; 83 } 84 85 // Create a drawable. 86 SkPicturePlayback playback(pictureData.get()); 87 SkPictureRecorder recorder; 88 playback.draw(recorder.beginRecording(bounds), nullptr, &buffer); 89 return recorder.finishRecordingAsDrawable(); 90 } 91