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 "include/core/SkMatrix.h"
9#include "include/core/SkPictureRecorder.h"
10#include "src/core/SkPictureData.h"
11#include "src/core/SkPicturePlayback.h"
12#include "src/core/SkPictureRecord.h"
13#include "src/core/SkRecordDraw.h"
14#include "src/core/SkRecordedDrawable.h"
15
16void 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
26SkPicture* SkRecordedDrawable::onNewPictureSnapshot() {
27 // TODO: should we plumb-down the BBHFactory and recordFlags from our host
28 // PictureRecorder?
29 std::unique_ptr<SkBigPicture::SnapshotArray> pictList{
30 fDrawableList ? fDrawableList->newDrawableSnapshot() : nullptr
31 };
32
33 size_t subPictureBytes = 0;
34 for (int i = 0; pictList && i < pictList->count(); i++) {
35 subPictureBytes += pictList->begin()[i]->approximateBytesUsed();
36 }
37 return new SkBigPicture(fBounds, fRecord, std::move(pictList), fBBH, subPictureBytes);
38}
39
40void SkRecordedDrawable::flatten(SkWriteBuffer& buffer) const {
41 // Write the bounds.
42 buffer.writeRect(fBounds);
43
44 // Create an SkPictureRecord to record the draw commands.
45 SkPictInfo info;
46 SkPictureRecord pictureRecord(SkISize::Make(fBounds.width(), fBounds.height()), 0);
47
48 // If the query contains the whole picture, don't bother with the bounding box hierarchy.
49 SkBBoxHierarchy* bbh;
50 if (pictureRecord.getLocalClipBounds().contains(fBounds)) {
51 bbh = nullptr;
52 } else {
53 bbh = fBBH.get();
54 }
55
56 // Record the draw commands.
57 pictureRecord.beginRecording();
58 SkRecordDraw(*fRecord, &pictureRecord, nullptr, fDrawableList->begin(), fDrawableList->count(),
59 bbh, nullptr);
60 pictureRecord.endRecording();
61
62 // Flatten the recorded commands and drawables.
63 SkPictureData pictureData(pictureRecord, info);
64 pictureData.flatten(buffer);
65}
66
67sk_sp<SkFlattenable> SkRecordedDrawable::CreateProc(SkReadBuffer& buffer) {
68 // Read the bounds.
69 SkRect bounds;
70 buffer.readRect(&bounds);
71
72 // Unflatten into a SkPictureData.
73 SkPictInfo info;
74 info.setVersion(buffer.getVersion());
75 info.fCullRect = bounds;
76 std::unique_ptr<SkPictureData> pictureData(SkPictureData::CreateFromBuffer(buffer, info));
77 if (!pictureData) {
78 return nullptr;
79 }
80
81 // Create a drawable.
82 SkPicturePlayback playback(pictureData.get());
83 SkPictureRecorder recorder;
84 playback.draw(recorder.beginRecording(bounds), nullptr, &buffer);
85 return recorder.finishRecordingAsDrawable();
86}
87