Home | History | Annotate | Download | only in core
      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