1 /* 2 * Copyright 2015 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 "SkBBoxHierarchy.h" 9 #include "SkBigPicture.h" 10 #include "SkPictureCommon.h" 11 #include "SkRecord.h" 12 #include "SkRecordDraw.h" 13 #include "SkTraceEvent.h" 14 15 SkBigPicture::SkBigPicture(const SkRect& cull, 16 SkRecord* record, 17 SnapshotArray* drawablePicts, 18 SkBBoxHierarchy* bbh, 19 AccelData* accelData, 20 size_t approxBytesUsedBySubPictures) 21 : fCullRect(cull) 22 , fApproxBytesUsedBySubPictures(approxBytesUsedBySubPictures) 23 , fRecord(record) // Take ownership of caller's ref. 24 , fDrawablePicts(drawablePicts) // Take ownership. 25 , fBBH(bbh) // Take ownership of caller's ref. 26 , fAccelData(accelData) // Take ownership of caller's ref. 27 {} 28 29 void SkBigPicture::playback(SkCanvas* canvas, AbortCallback* callback) const { 30 SkASSERT(canvas); 31 32 // If the query contains the whole picture, don't bother with the BBH. 33 SkRect clipBounds = { 0, 0, 0, 0 }; 34 (void)canvas->getClipBounds(&clipBounds); 35 const bool useBBH = !clipBounds.contains(this->cullRect()); 36 37 SkRecordDraw(*fRecord, 38 canvas, 39 this->drawablePicts(), 40 nullptr, 41 this->drawableCount(), 42 useBBH ? fBBH.get() : nullptr, 43 callback); 44 } 45 46 void SkBigPicture::partialPlayback(SkCanvas* canvas, 47 int start, 48 int stop, 49 const SkMatrix& initialCTM) const { 50 SkASSERT(canvas); 51 SkRecordPartialDraw(*fRecord, 52 canvas, 53 this->drawablePicts(), 54 this->drawableCount(), 55 start, 56 stop, 57 initialCTM); 58 } 59 60 const SkBigPicture::Analysis& SkBigPicture::analysis() const { 61 return *fAnalysis.get([&]{ return new Analysis(*fRecord); }); 62 } 63 64 SkRect SkBigPicture::cullRect() const { return fCullRect; } 65 bool SkBigPicture::hasText() const { return this->analysis().fHasText; } 66 bool SkBigPicture::willPlayBackBitmaps() const { return this->analysis().fWillPlaybackBitmaps; } 67 int SkBigPicture::numSlowPaths() const { return this->analysis().fNumSlowPathsAndDashEffects; } 68 int SkBigPicture::approximateOpCount() const { return fRecord->count(); } 69 size_t SkBigPicture::approximateBytesUsed() const { 70 size_t bytes = sizeof(*this) + fRecord->bytesUsed() + fApproxBytesUsedBySubPictures; 71 if (fBBH) { bytes += fBBH->bytesUsed(); } 72 return bytes; 73 } 74 75 int SkBigPicture::drawableCount() const { 76 return fDrawablePicts ? fDrawablePicts->count() : 0; 77 } 78 79 SkPicture const* const* SkBigPicture::drawablePicts() const { 80 return fDrawablePicts ? fDrawablePicts->begin() : nullptr; 81 } 82 83 SkBigPicture::Analysis::Analysis(const SkRecord& record) { 84 TRACE_EVENT0("disabled-by-default-skia", "SkBigPicture::Analysis::Analysis()"); 85 SkTextHunter text; 86 SkBitmapHunter bitmap; 87 SkPathCounter path; 88 89 bool hasText = false, hasBitmap = false; 90 for (int i = 0; i < record.count(); i++) { 91 hasText = hasText || record.visit<bool>(i, text); 92 hasBitmap = hasBitmap || record.visit<bool>(i, bitmap); 93 record.visit<void>(i, path); 94 } 95 96 fHasText = hasText; 97 fWillPlaybackBitmaps = hasBitmap; 98 fNumSlowPathsAndDashEffects = SkTMin<int>(path.fNumSlowPathsAndDashEffects, 255); 99 } 100