blob: 877314ccafd98bca89c89a19e97f3f5bcad3acef [file] [log] [blame]
robertphillips@google.com770963f2014-04-18 18:04:41 +00001/*
2 * Copyright 2014 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
mtklein9db912c2015-05-19 11:11:26 -07008#include "SkBigPicture.h"
reed6be2aa92014-11-18 11:08:05 -08009#include "SkData.h"
reed3cb38402015-02-06 08:36:15 -080010#include "SkDrawable.h"
robertphillips82365912014-11-12 09:32:34 -080011#include "SkLayerInfo.h"
robertphillips@google.com770963f2014-04-18 18:04:41 +000012#include "SkPictureRecorder.h"
mtklein98b84852015-04-21 15:23:59 -070013#include "SkPictureUtils.h"
mtklein887f3972014-06-17 12:08:15 -070014#include "SkRecord.h"
15#include "SkRecordDraw.h"
robertphillips81f71b62014-11-11 04:54:49 -080016#include "SkRecordOpts.h"
mtklein98b84852015-04-21 15:23:59 -070017#include "SkRecorder.h"
mtklein887f3972014-06-17 12:08:15 -070018#include "SkTypes.h"
robertphillips643b8bd2014-06-08 05:55:05 -070019
mtkleinfeaadee2015-04-08 11:25:48 -070020SkPictureRecorder::SkPictureRecorder() {
21 fActivelyRecording = false;
mtklein9db912c2015-05-19 11:11:26 -070022 fRecorder.reset(SkNEW_ARGS(SkRecorder, (nullptr, SkRect::MakeWH(0,0), &fMiniRecorder)));
mtkleinfeaadee2015-04-08 11:25:48 -070023}
mtklein887f3972014-06-17 12:08:15 -070024
Mike Kleinf22b6b52014-06-23 13:29:10 -040025SkPictureRecorder::~SkPictureRecorder() {}
robertphillips@google.com770963f2014-04-18 18:04:41 +000026
reed78e27682014-11-19 08:04:34 -080027SkCanvas* SkPictureRecorder::beginRecording(const SkRect& cullRect,
robertphillips@google.com770963f2014-04-18 18:04:41 +000028 SkBBHFactory* bbhFactory /* = NULL */,
29 uint32_t recordFlags /* = 0 */) {
reed78e27682014-11-19 08:04:34 -080030 fCullRect = cullRect;
robertphillips81f71b62014-11-11 04:54:49 -080031 fFlags = recordFlags;
mtklein887f3972014-06-17 12:08:15 -070032
bsalomon49f085d2014-09-05 13:34:00 -070033 if (bbhFactory) {
reed78e27682014-11-19 08:04:34 -080034 fBBH.reset((*bbhFactory)(cullRect));
bsalomon49f085d2014-09-05 13:34:00 -070035 SkASSERT(fBBH.get());
mtklein5ad6ee12014-08-11 08:08:43 -070036 }
37
mtklein9db912c2015-05-19 11:11:26 -070038 if (!fRecord) {
39 fRecord.reset(SkNEW(SkRecord));
40 }
mtkleind711d112015-07-01 07:04:37 -070041 SkRecorder::DrawPictureMode dpm = (recordFlags & kPlaybackDrawPicture_RecordFlag)
42 ? SkRecorder::Playback_DrawPictureMode
43 : SkRecorder::Record_DrawPictureMode;
44 fRecorder->reset(fRecord.get(), cullRect, dpm, &fMiniRecorder);
mtkleinfeaadee2015-04-08 11:25:48 -070045 fActivelyRecording = true;
mtklein887f3972014-06-17 12:08:15 -070046 return this->getRecordingCanvas();
robertphillips643b8bd2014-06-08 05:55:05 -070047}
48
49SkCanvas* SkPictureRecorder::getRecordingCanvas() {
mtkleinfeaadee2015-04-08 11:25:48 -070050 return fActivelyRecording ? fRecorder.get() : nullptr;
robertphillips643b8bd2014-06-08 05:55:05 -070051}
52
reed1bdfd3f2014-11-24 14:41:51 -080053SkPicture* SkPictureRecorder::endRecordingAsPicture() {
mtkleinfeaadee2015-04-08 11:25:48 -070054 fActivelyRecording = false;
55 fRecorder->restoreToCount(1); // If we were missing any restores, add them now.
mtklein9db912c2015-05-19 11:11:26 -070056
57 if (fRecord->count() == 0) {
58 return fMiniRecorder.detachAsPicture(fCullRect);
59 }
60
robertphillips81f71b62014-11-11 04:54:49 -080061 // TODO: delay as much of this work until just before first playback?
62 SkRecordOptimize(fRecord);
63
robertphillips82365912014-11-12 09:32:34 -080064 SkAutoTUnref<SkLayerInfo> saveLayerData;
robertphillips81f71b62014-11-11 04:54:49 -080065
66 if (fBBH && (fFlags & kComputeSaveLayerInfo_RecordFlag)) {
mtklein9db912c2015-05-19 11:11:26 -070067 saveLayerData.reset(SkNEW(SkLayerInfo));
robertphillips81f71b62014-11-11 04:54:49 -080068 }
robertphillips81f71b62014-11-11 04:54:49 -080069
reed3cb38402015-02-06 08:36:15 -080070 SkDrawableList* drawableList = fRecorder->getDrawableList();
mtklein9db912c2015-05-19 11:11:26 -070071 SkBigPicture::SnapshotArray* pictList =
72 drawableList ? drawableList->newDrawableSnapshot() : NULL;
reed1bdfd3f2014-11-24 14:41:51 -080073
robertphillips81f71b62014-11-11 04:54:49 -080074 if (fBBH.get()) {
robertphillips81f71b62014-11-11 04:54:49 -080075 if (saveLayerData) {
reed1bdfd3f2014-11-24 14:41:51 -080076 SkRecordComputeLayers(fCullRect, *fRecord, pictList, fBBH.get(), saveLayerData);
robertphillips81f71b62014-11-11 04:54:49 -080077 } else {
reed78e27682014-11-19 08:04:34 -080078 SkRecordFillBounds(fCullRect, *fRecord, fBBH.get());
robertphillips81f71b62014-11-11 04:54:49 -080079 }
schenney23d85932015-03-06 16:20:28 -080080 SkRect bbhBound = fBBH->getRootBound();
81 SkASSERT((bbhBound.isEmpty() || fCullRect.contains(bbhBound))
82 || (bbhBound.isEmpty() && fCullRect.isEmpty()));
83 fCullRect = bbhBound;
robertphillips81f71b62014-11-11 04:54:49 -080084 }
85
mtklein98b84852015-04-21 15:23:59 -070086 size_t subPictureBytes = fRecorder->approxBytesUsedBySubPictures();
87 for (int i = 0; pictList && i < pictList->count(); i++) {
88 subPictureBytes += SkPictureUtils::ApproximateBytesUsed(pictList->begin()[i]);
89 }
mtklein9db912c2015-05-19 11:11:26 -070090 return SkNEW_ARGS(SkBigPicture, (fCullRect,
91 fRecord.detach(),
92 pictList,
93 fBBH.detach(),
94 saveLayerData.detach(),
95 subPictureBytes));
robertphillips643b8bd2014-06-08 05:55:05 -070096}
97
commit-bot@chromium.org2246e322014-05-29 15:57:11 +000098void SkPictureRecorder::partialReplay(SkCanvas* canvas) const {
mtklein887f3972014-06-17 12:08:15 -070099 if (NULL == canvas) {
commit-bot@chromium.org6d3eaea2014-05-27 23:41:45 +0000100 return;
101 }
reed6be2aa92014-11-18 11:08:05 -0800102
103 int drawableCount = 0;
reed3cb38402015-02-06 08:36:15 -0800104 SkDrawable* const* drawables = NULL;
105 SkDrawableList* drawableList = fRecorder->getDrawableList();
reed1bdfd3f2014-11-24 14:41:51 -0800106 if (drawableList) {
107 drawableCount = drawableList->count();
108 drawables = drawableList->begin();
109 }
110 SkRecordDraw(*fRecord, canvas, NULL, drawables, drawableCount, NULL/*bbh*/, NULL/*callback*/);
111}
112
113///////////////////////////////////////////////////////////////////////////////////////////////////
114
reed3cb38402015-02-06 08:36:15 -0800115class SkRecordedDrawable : public SkDrawable {
116 SkAutoTUnref<SkRecord> fRecord;
117 SkAutoTUnref<SkBBoxHierarchy> fBBH;
118 SkAutoTDelete<SkDrawableList> fDrawableList;
119 const SkRect fBounds;
120 const bool fDoSaveLayerInfo;
reed1bdfd3f2014-11-24 14:41:51 -0800121
122public:
reed3cb38402015-02-06 08:36:15 -0800123 SkRecordedDrawable(SkRecord* record, SkBBoxHierarchy* bbh, SkDrawableList* drawableList,
reed1bdfd3f2014-11-24 14:41:51 -0800124 const SkRect& bounds, bool doSaveLayerInfo)
125 : fRecord(SkRef(record))
126 , fBBH(SkSafeRef(bbh))
127 , fDrawableList(drawableList) // we take ownership
128 , fBounds(bounds)
129 , fDoSaveLayerInfo(doSaveLayerInfo)
130 {}
131
132protected:
mtklein36352bf2015-03-25 18:17:31 -0700133 SkRect onGetBounds() override { return fBounds; }
reed1bdfd3f2014-11-24 14:41:51 -0800134
mtklein36352bf2015-03-25 18:17:31 -0700135 void onDraw(SkCanvas* canvas) override {
reed3cb38402015-02-06 08:36:15 -0800136 SkDrawable* const* drawables = NULL;
reed1bdfd3f2014-11-24 14:41:51 -0800137 int drawableCount = 0;
138 if (fDrawableList) {
139 drawables = fDrawableList->begin();
140 drawableCount = fDrawableList->count();
141 }
142 SkRecordDraw(*fRecord, canvas, NULL, drawables, drawableCount, fBBH, NULL/*callback*/);
143 }
144
mtklein36352bf2015-03-25 18:17:31 -0700145 SkPicture* onNewPictureSnapshot() override {
mtklein9db912c2015-05-19 11:11:26 -0700146 SkBigPicture::SnapshotArray* pictList = NULL;
reed1bdfd3f2014-11-24 14:41:51 -0800147 if (fDrawableList) {
148 // TODO: should we plumb-down the BBHFactory and recordFlags from our host
149 // PictureRecorder?
150 pictList = fDrawableList->newDrawableSnapshot();
151 }
152
153 SkAutoTUnref<SkLayerInfo> saveLayerData;
154
155 if (fBBH && fDoSaveLayerInfo) {
mtklein9db912c2015-05-19 11:11:26 -0700156 saveLayerData.reset(SkNEW(SkLayerInfo));
reed1bdfd3f2014-11-24 14:41:51 -0800157
158 SkBBoxHierarchy* bbh = NULL; // we've already computed fBBH (received in constructor)
159 // TODO: update saveLayer info computation to reuse the already computed
160 // bounds in 'fBBH'
161 SkRecordComputeLayers(fBounds, *fRecord, pictList, bbh, saveLayerData);
162 }
163
mtklein98b84852015-04-21 15:23:59 -0700164 size_t subPictureBytes = 0;
165 for (int i = 0; pictList && i < pictList->count(); i++) {
166 subPictureBytes += SkPictureUtils::ApproximateBytesUsed(pictList->begin()[i]);
167 }
mtklein9db912c2015-05-19 11:11:26 -0700168 // SkBigPicture will take ownership of a ref on both fRecord and fBBH.
mtklein00c2af82015-04-27 08:54:23 -0700169 // We're not willing to give up our ownership, so we must ref them for SkPicture.
mtklein9db912c2015-05-19 11:11:26 -0700170 return SkNEW_ARGS(SkBigPicture, (fBounds,
171 SkRef(fRecord.get()),
172 pictList,
173 SkSafeRef(fBBH.get()),
174 saveLayerData.detach(),
175 subPictureBytes));
reed1bdfd3f2014-11-24 14:41:51 -0800176 }
177};
178
reed3cb38402015-02-06 08:36:15 -0800179SkDrawable* SkPictureRecorder::endRecordingAsDrawable() {
mtkleinfeaadee2015-04-08 11:25:48 -0700180 fActivelyRecording = false;
mtklein9db912c2015-05-19 11:11:26 -0700181 fRecorder->flushMiniRecorder();
mtkleinfeaadee2015-04-08 11:25:48 -0700182 fRecorder->restoreToCount(1); // If we were missing any restores, add them now.
mtklein9db912c2015-05-19 11:11:26 -0700183
reed1bdfd3f2014-11-24 14:41:51 -0800184 // TODO: delay as much of this work until just before first playback?
185 SkRecordOptimize(fRecord);
186
187 if (fBBH.get()) {
188 SkRecordFillBounds(fCullRect, *fRecord, fBBH.get());
189 }
190
reed3cb38402015-02-06 08:36:15 -0800191 SkDrawable* drawable = SkNEW_ARGS(SkRecordedDrawable,
192 (fRecord, fBBH, fRecorder->detachDrawableList(),
193 fCullRect,
194 SkToBool(fFlags & kComputeSaveLayerInfo_RecordFlag)));
reed26a6bf62014-11-24 19:59:22 -0800195
196 // release our refs now, so only the drawable will be the owner.
reed26a6bf62014-11-24 19:59:22 -0800197 fRecord.reset(NULL);
198 fBBH.reset(NULL);
199
200 return drawable;
commit-bot@chromium.org6d3eaea2014-05-27 23:41:45 +0000201}