sk_sp<SkDrawable> SkPictureRecorder::finishRecordingAsDrawable(uint32_t finishFlags) { fActivelyRecording = false; fRecorder->flushMiniRecorder(); fRecorder->restoreToCount(1); // If we were missing any restores, add them now. SkRecordOptimize(fRecord); if (fRecord->count() == 0) { if (finishFlags & kReturnNullForEmpty_FinishFlag) { return nullptr; } } if (fBBH.get()) { SkAutoTMalloc<SkRect> bounds(fRecord->count()); SkRecordFillBounds(fCullRect, *fRecord, bounds); fBBH->insert(bounds, fRecord->count()); } sk_sp<SkDrawable> drawable = sk_make_sp<SkRecordedDrawable>(fRecord, fBBH, fRecorder->detachDrawableList(), fCullRect, SkToBool(fFlags & kComputeSaveLayerInfo_RecordFlag)); // release our refs now, so only the drawable will be the owner. fRecord.reset(nullptr); fBBH.reset(nullptr); return drawable; }
int tool_main(int argc, char** argv) { SkCommandLineFlags::Parse(argc, argv); for (int i = 0; i < FLAGS_skps.count(); i++) { if (SkCommandLineFlags::ShouldSkip(FLAGS_match, FLAGS_skps[i])) { continue; } SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(FLAGS_skps[i])); if (!stream) { SkDebugf("Could not read %s.\n", FLAGS_skps[i]); return 1; } sk_sp<SkPicture> src(SkPicture::MakeFromStream(stream)); if (!src) { SkDebugf("Could not read %s as an SkPicture.\n", FLAGS_skps[i]); return 1; } if (FLAGS_defer) { SkPictureRecorder recorder; SkDeferredCanvas deferred(recorder.beginRecording(src->cullRect())); src->playback(&deferred); src = recorder.finishRecordingAsPicture(); } const int w = SkScalarCeilToInt(src->cullRect().width()); const int h = SkScalarCeilToInt(src->cullRect().height()); SkRecord record; SkRecorder canvas(&record, w, h); src->playback(&canvas); if (FLAGS_optimize) { SkRecordOptimize(&record); } if (FLAGS_optimize2) { SkRecordOptimize2(&record); } dump(FLAGS_skps[i], w, h, record); if (FLAGS_write.count() > 0) { SkPictureRecorder r; SkRecordDraw(record, r.beginRecording(SkRect::MakeIWH(w, h)), nullptr, nullptr, 0, nullptr, nullptr); sk_sp<SkPicture> dst(r.finishRecordingAsPicture()); SkFILEWStream ostream(FLAGS_write[0]); dst->serialize(&ostream); } } return 0; }
sk_sp<SkPicture> SkPictureRecorder::finishRecordingAsPicture(uint32_t finishFlags) { fActivelyRecording = false; fRecorder->restoreToCount(1); // If we were missing any restores, add them now. if (fRecord->count() == 0) { if (finishFlags & kReturnNullForEmpty_FinishFlag) { return nullptr; } return fMiniRecorder.detachAsPicture(fCullRect); } // TODO: delay as much of this work until just before first playback? SkRecordOptimize(fRecord); if (fRecord->count() == 0) { if (finishFlags & kReturnNullForEmpty_FinishFlag) { return nullptr; } } SkAutoTUnref<SkLayerInfo> saveLayerData; if (fBBH && (fFlags & kComputeSaveLayerInfo_RecordFlag)) { saveLayerData.reset(new SkLayerInfo); } SkDrawableList* drawableList = fRecorder->getDrawableList(); SkBigPicture::SnapshotArray* pictList = drawableList ? drawableList->newDrawableSnapshot() : nullptr; if (fBBH.get()) { SkAutoTMalloc<SkRect> bounds(fRecord->count()); if (saveLayerData) { SkRecordComputeLayers(fCullRect, *fRecord, bounds, pictList, saveLayerData); } else { SkRecordFillBounds(fCullRect, *fRecord, bounds); } fBBH->insert(bounds, fRecord->count()); // Now that we've calculated content bounds, we can update fCullRect, often trimming it. // TODO: get updated fCullRect from bounds instead of forcing the BBH to return it? SkRect bbhBound = fBBH->getRootBound(); SkASSERT((bbhBound.isEmpty() || fCullRect.contains(bbhBound)) || (bbhBound.isEmpty() && fCullRect.isEmpty())); fCullRect = bbhBound; } size_t subPictureBytes = fRecorder->approxBytesUsedBySubPictures(); for (int i = 0; pictList && i < pictList->count(); i++) { subPictureBytes += SkPictureUtils::ApproximateBytesUsed(pictList->begin()[i]); } return sk_make_sp<SkBigPicture>(fCullRect, fRecord.release(), pictList, fBBH.release(), saveLayerData.release(), subPictureBytes); }
SkPicture* SkPictureRecorder::endRecordingAsPicture() { fActivelyRecording = false; fRecorder->restoreToCount(1); // If we were missing any restores, add them now. if (fRecord->count() == 0) { return fMiniRecorder.detachAsPicture(fCullRect); } // TODO: delay as much of this work until just before first playback? SkRecordOptimize(fRecord); SkAutoTUnref<SkLayerInfo> saveLayerData; if (fBBH && (fFlags & kComputeSaveLayerInfo_RecordFlag)) { saveLayerData.reset(SkNEW(SkLayerInfo)); } SkDrawableList* drawableList = fRecorder->getDrawableList(); SkBigPicture::SnapshotArray* pictList = drawableList ? drawableList->newDrawableSnapshot() : NULL; if (fBBH.get()) { if (saveLayerData) { SkRecordComputeLayers(fCullRect, *fRecord, pictList, fBBH.get(), saveLayerData); } else { SkRecordFillBounds(fCullRect, *fRecord, fBBH.get()); } SkRect bbhBound = fBBH->getRootBound(); SkASSERT((bbhBound.isEmpty() || fCullRect.contains(bbhBound)) || (bbhBound.isEmpty() && fCullRect.isEmpty())); fCullRect = bbhBound; } size_t subPictureBytes = fRecorder->approxBytesUsedBySubPictures(); for (int i = 0; pictList && i < pictList->count(); i++) { subPictureBytes += SkPictureUtils::ApproximateBytesUsed(pictList->begin()[i]); } return SkNEW_ARGS(SkBigPicture, (fCullRect, fRecord.detach(), pictList, fBBH.detach(), saveLayerData.detach(), subPictureBytes)); }
SkDrawable* SkPictureRecorder::endRecordingAsDrawable() { fActivelyRecording = false; fRecorder->flushMiniRecorder(); fRecorder->restoreToCount(1); // If we were missing any restores, add them now. // TODO: delay as much of this work until just before first playback? SkRecordOptimize(fRecord); if (fBBH.get()) { SkRecordFillBounds(fCullRect, *fRecord, fBBH.get()); } SkDrawable* drawable = new SkRecordedDrawable(fRecord, fBBH, fRecorder->detachDrawableList(), fCullRect, SkToBool(fFlags & kComputeSaveLayerInfo_RecordFlag)); // release our refs now, so only the drawable will be the owner. fRecord.reset(NULL); fBBH.reset(NULL); return drawable; }
SkPlayback* SkRecording::releasePlayback() { SkASSERT(fRecorder->unique()); fRecorder->forgetRecord(); SkRecordOptimize(fRecord.get()); return SkNEW_ARGS(SkPlayback, (fRecord.detach())); }