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 "SkBBoxHierarchyRecord.h"
9#include "SkPicturePlayback.h"
10#include "SkPictureRecord.h"
11#include "SkPictureRecorder.h"
12#include "SkRecord.h"
13#include "SkRecordDraw.h"
14#include "SkRecorder.h"
15#include "SkTypes.h"
16
17SkPictureRecorder::~SkPictureRecorder() {
18    this->reset();
19}
20
21void SkPictureRecorder::reset() {
22    SkSafeSetNull(fPictureRecord);
23    SkSafeSetNull(fRecorder);
24    SkDELETE(fRecord);
25    fRecord = NULL;
26}
27
28SkCanvas* SkPictureRecorder::beginRecording(int width, int height,
29                                            SkBBHFactory* bbhFactory /* = NULL */,
30                                            uint32_t recordFlags /* = 0 */) {
31    this->reset();  // terminate any prior recording(s)
32    fWidth = width;
33    fHeight = height;
34
35    const SkISize size = SkISize::Make(width, height);
36
37    if (NULL != bbhFactory) {
38        SkAutoTUnref<SkBBoxHierarchy> tree((*bbhFactory)(width, height));
39        SkASSERT(NULL != tree);
40        fPictureRecord = SkNEW_ARGS(SkBBoxHierarchyRecord, (size, recordFlags, tree.get()));
41    } else {
42        fPictureRecord = SkNEW_ARGS(SkPictureRecord, (size, recordFlags));
43    }
44
45    fPictureRecord->beginRecording();
46    return this->getRecordingCanvas();
47}
48
49SkCanvas* SkPictureRecorder::EXPERIMENTAL_beginRecording(int width, int height,
50                                                         SkBBHFactory* bbhFactory /* = NULL */) {
51    this->reset();
52    fWidth = width;
53    fHeight = height;
54
55    // TODO: plumb bbhFactory through
56    fRecord   = SkNEW(SkRecord);
57    fRecorder = SkNEW_ARGS(SkRecorder, (fRecord, width, height));
58    return this->getRecordingCanvas();
59}
60
61SkCanvas* SkPictureRecorder::getRecordingCanvas() {
62    if (NULL != fRecorder) {
63        return fRecorder;
64    }
65    return fPictureRecord;
66}
67
68SkPicture* SkPictureRecorder::endRecording() {
69    SkPicture* picture = NULL;
70
71    if (NULL != fRecorder) {
72        // TODO: picture = SkNEW_ARGS(SkPicture, (fWidth, fHeight, fRecord));
73        //       fRecord = NULL;
74    }
75
76    if (NULL != fPictureRecord) {
77        fPictureRecord->endRecording();
78        const bool deepCopyOps = false;
79        picture = SkNEW_ARGS(SkPicture, (fWidth, fHeight, *fPictureRecord, deepCopyOps));
80    }
81
82    this->reset();
83    return picture;
84}
85
86void SkPictureRecorder::internalOnly_EnableOpts(bool enableOpts) {
87    if (NULL != fPictureRecord) {
88        fPictureRecord->internalOnly_EnableOpts(enableOpts);
89    }
90}
91
92void SkPictureRecorder::partialReplay(SkCanvas* canvas) const {
93    if (NULL == canvas) {
94        return;
95    }
96
97    if (NULL != fRecorder) {
98        SkRecordDraw(*fRecord, canvas);
99    }
100
101    if (NULL != fPictureRecord) {
102        const bool deepCopyOps = true;
103        SkPicture picture(fWidth, fHeight, *fPictureRecord, deepCopyOps);
104        picture.draw(canvas);
105    }
106}
107