/* * Copyright 2015 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "SkBBoxHierarchy.h" #include "SkBigPicture.h" #include "SkPictureCommon.h" #include "SkRecord.h" #include "SkRecordDraw.h" #include "SkTraceEvent.h" SkBigPicture::SkBigPicture(const SkRect& cull, SkRecord* record, SnapshotArray* drawablePicts, SkBBoxHierarchy* bbh, AccelData* accelData, size_t approxBytesUsedBySubPictures) : fCullRect(cull) , fApproxBytesUsedBySubPictures(approxBytesUsedBySubPictures) , fRecord(record) // Take ownership of caller's ref. , fDrawablePicts(drawablePicts) // Take ownership. , fBBH(bbh) // Take ownership of caller's ref. , fAccelData(accelData) // Take ownership of caller's ref. {} void SkBigPicture::playback(SkCanvas* canvas, AbortCallback* callback) const { SkASSERT(canvas); // If the query contains the whole picture, don't bother with the BBH. SkRect clipBounds = { 0, 0, 0, 0 }; (void)canvas->getClipBounds(&clipBounds); const bool useBBH = !clipBounds.contains(this->cullRect()); SkRecordDraw(*fRecord, canvas, this->drawablePicts(), nullptr, this->drawableCount(), useBBH ? fBBH.get() : nullptr, callback); } void SkBigPicture::partialPlayback(SkCanvas* canvas, int start, int stop, const SkMatrix& initialCTM) const { SkASSERT(canvas); SkRecordPartialDraw(*fRecord, canvas, this->drawablePicts(), this->drawableCount(), start, stop, initialCTM); } const SkBigPicture::Analysis& SkBigPicture::analysis() const { return *fAnalysis.get([&]{ return new Analysis(*fRecord); }); } SkRect SkBigPicture::cullRect() const { return fCullRect; } bool SkBigPicture::hasText() const { return this->analysis().fHasText; } bool SkBigPicture::willPlayBackBitmaps() const { return this->analysis().fWillPlaybackBitmaps; } int SkBigPicture::numSlowPaths() const { return this->analysis().fNumSlowPathsAndDashEffects; } int SkBigPicture::approximateOpCount() const { return fRecord->count(); } size_t SkBigPicture::approximateBytesUsed() const { size_t bytes = sizeof(*this) + fRecord->bytesUsed() + fApproxBytesUsedBySubPictures; if (fBBH) { bytes += fBBH->bytesUsed(); } return bytes; } int SkBigPicture::drawableCount() const { return fDrawablePicts ? fDrawablePicts->count() : 0; } SkPicture const* const* SkBigPicture::drawablePicts() const { return fDrawablePicts ? fDrawablePicts->begin() : nullptr; } SkBigPicture::Analysis::Analysis(const SkRecord& record) { TRACE_EVENT0("disabled-by-default-skia", "SkBigPicture::Analysis::Analysis()"); SkTextHunter text; SkBitmapHunter bitmap; SkPathCounter path; bool hasText = false, hasBitmap = false; for (int i = 0; i < record.count(); i++) { hasText = hasText || record.visit<bool>(i, text); hasBitmap = hasBitmap || record.visit<bool>(i, bitmap); record.visit<void>(i, path); } fHasText = hasText; fWillPlaybackBitmaps = hasBitmap; fNumSlowPathsAndDashEffects = SkTMin<int>(path.fNumSlowPathsAndDashEffects, 255); }