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 "SkPictureRecord.h"
10#include "SkPictureRecorder.h"
11#include "SkRecord.h"
12#include "SkRecordDraw.h"
13#include "SkRecorder.h"
14#include "SkTypes.h"
15
16SkPictureRecorder::SkPictureRecorder() {}
17
18SkPictureRecorder::~SkPictureRecorder() {}
19
20SkCanvas* SkPictureRecorder::beginRecording(SkScalar width, SkScalar height,
21                                            SkBBHFactory* bbhFactory /* = NULL */,
22                                            uint32_t recordFlags /* = 0 */) {
23#ifdef SK_PICTURE_USE_SK_RECORD
24    return EXPERIMENTAL_beginRecording(width, height, bbhFactory);
25#else
26    return DEPRECATED_beginRecording(width, height, bbhFactory, recordFlags);
27#endif
28}
29
30SkCanvas* SkPictureRecorder::DEPRECATED_beginRecording(SkScalar width, SkScalar height,
31                                                       SkBBHFactory* bbhFactory /* = NULL */,
32                                                       uint32_t recordFlags /* = 0 */) {
33    fCullWidth = width;
34    fCullHeight = height;
35
36    const SkISize size = SkISize::Make(width, height);
37
38    if (bbhFactory) {
39        // We don't need to hold a ref on the BBH ourselves, but might as well for
40        // consistency with EXPERIMENTAL_beginRecording(), which does need to.
41        fBBH.reset((*bbhFactory)(width, height));
42        SkASSERT(fBBH.get());
43        fPictureRecord.reset(SkNEW_ARGS(SkBBoxHierarchyRecord, (size, recordFlags, fBBH.get())));
44    } else {
45        fPictureRecord.reset(SkNEW_ARGS(SkPictureRecord, (size, recordFlags)));
46    }
47
48    fPictureRecord->beginRecording();
49    return this->getRecordingCanvas();
50}
51
52SkCanvas* SkPictureRecorder::EXPERIMENTAL_beginRecording(SkScalar width, SkScalar height,
53                                                         SkBBHFactory* bbhFactory /* = NULL */) {
54    fCullWidth = width;
55    fCullHeight = height;
56
57    if (bbhFactory) {
58        fBBH.reset((*bbhFactory)(width, height));
59        SkASSERT(fBBH.get());
60    }
61
62    fRecord.reset(SkNEW(SkRecord));
63    fRecorder.reset(SkNEW_ARGS(SkRecorder, (fRecord.get(), width, height)));
64    return this->getRecordingCanvas();
65}
66
67SkCanvas* SkPictureRecorder::getRecordingCanvas() {
68    if (fRecorder.get()) {
69        return fRecorder.get();
70    }
71    return fPictureRecord.get();
72}
73
74SkPicture* SkPictureRecorder::endRecording() {
75    SkPicture* picture = NULL;
76
77    if (fRecord.get()) {
78        picture = SkNEW_ARGS(SkPicture, (fCullWidth, fCullHeight,
79                                         fRecord.detach(), fBBH.get()));
80    }
81
82    if (fPictureRecord.get()) {
83        fPictureRecord->endRecording();
84        const bool deepCopyOps = false;
85        picture = SkNEW_ARGS(SkPicture, (fCullWidth, fCullHeight,
86                                         *fPictureRecord.get(), deepCopyOps));
87    }
88
89    return picture;
90}
91
92void SkPictureRecorder::internalOnly_EnableOpts(bool enableOpts) {
93    if (fPictureRecord.get()) {
94        fPictureRecord->internalOnly_EnableOpts(enableOpts);
95    }
96}
97
98void SkPictureRecorder::partialReplay(SkCanvas* canvas) const {
99    if (NULL == canvas) {
100        return;
101    }
102
103    if (fRecord.get()) {
104        SkRecordDraw(*fRecord, canvas, NULL/*bbh*/, NULL/*callback*/);
105    }
106
107    if (fPictureRecord.get()) {
108        const bool deepCopyOps = true;
109        SkPicture picture(fCullWidth, fCullHeight,
110                          *fPictureRecord.get(), deepCopyOps);
111        picture.playback(canvas);
112    }
113}
114