Home | History | Annotate | Download | only in core
      1 /*
      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 
      8 #include "SkBigPicture.h"
      9 #include "SkData.h"
     10 #include "SkDrawable.h"
     11 #include "SkPictureRecorder.h"
     12 #include "SkRecord.h"
     13 #include "SkRecordDraw.h"
     14 #include "SkRecordOpts.h"
     15 #include "SkRecordedDrawable.h"
     16 #include "SkRecorder.h"
     17 #include "SkTypes.h"
     18 
     19 SkPictureRecorder::SkPictureRecorder() {
     20     fActivelyRecording = false;
     21     fRecorder.reset(new SkRecorder(nullptr, SkRect::MakeEmpty(), &fMiniRecorder));
     22 }
     23 
     24 SkPictureRecorder::~SkPictureRecorder() {}
     25 
     26 SkCanvas* SkPictureRecorder::beginRecording(const SkRect& userCullRect,
     27                                             SkBBHFactory* bbhFactory /* = nullptr */,
     28                                             uint32_t recordFlags /* = 0 */) {
     29     const SkRect cullRect = userCullRect.isEmpty() ? SkRect::MakeEmpty() : userCullRect;
     30 
     31     fCullRect = cullRect;
     32     fFlags = recordFlags;
     33 
     34     if (bbhFactory) {
     35         fBBH.reset((*bbhFactory)(cullRect));
     36         SkASSERT(fBBH.get());
     37     }
     38 
     39     if (!fRecord) {
     40         fRecord.reset(new SkRecord);
     41     }
     42     SkRecorder::DrawPictureMode dpm = (recordFlags & kPlaybackDrawPicture_RecordFlag)
     43         ? SkRecorder::Playback_DrawPictureMode
     44         : SkRecorder::Record_DrawPictureMode;
     45     fRecorder->reset(fRecord.get(), cullRect, dpm, &fMiniRecorder);
     46     fActivelyRecording = true;
     47     return this->getRecordingCanvas();
     48 }
     49 
     50 SkCanvas* SkPictureRecorder::getRecordingCanvas() {
     51     return fActivelyRecording ? fRecorder.get() : nullptr;
     52 }
     53 
     54 sk_sp<SkPicture> SkPictureRecorder::finishRecordingAsPicture(uint32_t finishFlags) {
     55     fActivelyRecording = false;
     56     fRecorder->restoreToCount(1);  // If we were missing any restores, add them now.
     57 
     58     if (fRecord->count() == 0) {
     59         if (finishFlags & kReturnNullForEmpty_FinishFlag) {
     60             return nullptr;
     61         }
     62         return fMiniRecorder.detachAsPicture(fCullRect);
     63     }
     64 
     65     // TODO: delay as much of this work until just before first playback?
     66     SkRecordOptimize(fRecord.get());
     67 
     68     if (fRecord->count() == 0) {
     69         if (finishFlags & kReturnNullForEmpty_FinishFlag) {
     70             return nullptr;
     71         }
     72     }
     73 
     74     SkDrawableList* drawableList = fRecorder->getDrawableList();
     75     SkBigPicture::SnapshotArray* pictList =
     76         drawableList ? drawableList->newDrawableSnapshot() : nullptr;
     77 
     78     if (fBBH.get()) {
     79         SkAutoTMalloc<SkRect> bounds(fRecord->count());
     80         SkRecordFillBounds(fCullRect, *fRecord, bounds);
     81         fBBH->insert(bounds, fRecord->count());
     82 
     83         // Now that we've calculated content bounds, we can update fCullRect, often trimming it.
     84         // TODO: get updated fCullRect from bounds instead of forcing the BBH to return it?
     85         SkRect bbhBound = fBBH->getRootBound();
     86         SkASSERT((bbhBound.isEmpty() || fCullRect.contains(bbhBound))
     87             || (bbhBound.isEmpty() && fCullRect.isEmpty()));
     88         fCullRect = bbhBound;
     89     }
     90 
     91     size_t subPictureBytes = fRecorder->approxBytesUsedBySubPictures();
     92     for (int i = 0; pictList && i < pictList->count(); i++) {
     93         subPictureBytes += pictList->begin()[i]->approximateBytesUsed();
     94     }
     95     return sk_make_sp<SkBigPicture>(fCullRect, fRecord.release(), pictList, fBBH.release(),
     96                                     subPictureBytes);
     97 }
     98 
     99 sk_sp<SkPicture> SkPictureRecorder::finishRecordingAsPictureWithCull(const SkRect& cullRect,
    100                                                                      uint32_t finishFlags) {
    101     fCullRect = cullRect;
    102     return this->finishRecordingAsPicture(finishFlags);
    103 }
    104 
    105 
    106 void SkPictureRecorder::partialReplay(SkCanvas* canvas) const {
    107     if (nullptr == canvas) {
    108         return;
    109     }
    110 
    111     int drawableCount = 0;
    112     SkDrawable* const* drawables = nullptr;
    113     SkDrawableList* drawableList = fRecorder->getDrawableList();
    114     if (drawableList) {
    115         drawableCount = drawableList->count();
    116         drawables = drawableList->begin();
    117     }
    118     SkRecordDraw(*fRecord, canvas, nullptr, drawables, drawableCount, nullptr/*bbh*/, nullptr/*callback*/);
    119 }
    120 
    121 sk_sp<SkDrawable> SkPictureRecorder::finishRecordingAsDrawable(uint32_t finishFlags) {
    122     fActivelyRecording = false;
    123     fRecorder->flushMiniRecorder();
    124     fRecorder->restoreToCount(1);  // If we were missing any restores, add them now.
    125 
    126     SkRecordOptimize(fRecord.get());
    127 
    128     if (fRecord->count() == 0) {
    129         if (finishFlags & kReturnNullForEmpty_FinishFlag) {
    130             return nullptr;
    131         }
    132     }
    133 
    134     if (fBBH.get()) {
    135         SkAutoTMalloc<SkRect> bounds(fRecord->count());
    136         SkRecordFillBounds(fCullRect, *fRecord, bounds);
    137         fBBH->insert(bounds, fRecord->count());
    138     }
    139 
    140     sk_sp<SkDrawable> drawable =
    141          sk_make_sp<SkRecordedDrawable>(std::move(fRecord), std::move(fBBH),
    142                                         fRecorder->detachDrawableList(), fCullRect);
    143 
    144     return drawable;
    145 }
    146