blob: c2929568f44bd9492ea62c32d2ed6f3f29b3d3cd [file] [log] [blame]
Robert Phillipsdeaf5682017-09-06 13:07:21 -04001/*
2 * Copyright 2017 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 <memory>
9
10#include "Model.h"
11
12#include "SkBitmap.h"
13#include "SkCanvas.h"
14#include "SkDebugCanvas.h"
15#include "SkPicture.h"
16#include "SkStream.h"
17
18Model::Model() : fCurOp(0) {
19 SkImageInfo ii = SkImageInfo::MakeN32Premul(1024, 1024);
20 fBM.allocPixels(ii, 0);
21}
22
23Model::~Model() {
24 this->resetOpList();
25}
26
27Model::ErrorCode Model::load(const char* filename) {
28 std::unique_ptr<SkStream> stream = SkStream::MakeFromFile(filename);
29 if (!stream) {
30 return ErrorCode::kCouldntOpenFile;
31 }
32 sk_sp<SkPicture> pic(SkPicture::MakeFromStream(stream.get()));
33 if (!pic) {
34 return ErrorCode::kCouldntDecodeSKP;
35 }
36
37 {
38 std::unique_ptr<SkDebugCanvas> temp(new SkDebugCanvas(
39 SkScalarCeilToInt(pic->cullRect().width()),
40 SkScalarCeilToInt(pic->cullRect().height())));
41
42 temp->setPicture(pic.get());
43 pic->playback(temp.get());
44 temp->setPicture(nullptr);
45 this->resetOpList();
46 temp->detachCommands(&fOps);
47 }
48
49 this->setCurOp(fOps.count()-1);
50
51 return ErrorCode::kOK;
52}
53
54const char* Model::ErrorString(ErrorCode err) {
55 static const char* kStrings[] = {
56 "OK",
57 "Couldn't read file",
58 "Couldn't decode picture"
59 };
60
61 return kStrings[(int)err];
62}
63
Robert Phillips276066b2017-09-06 17:17:44 -040064const char* Model::getOpName(int index) const {
Robert Phillipsdeaf5682017-09-06 13:07:21 -040065 return SkDrawCommand::GetCommandString(fOps[index]->getType());
66}
67
Robert Phillips276066b2017-09-06 17:17:44 -040068bool Model::isHierarchyPush(int index) const {
69 SkDrawCommand::OpType type = fOps[index]->getType();
70
71 return SkDrawCommand::kSave_OpType == type ||
72 SkDrawCommand::kSaveLayer_OpType == type ||
73 SkDrawCommand::kBeginDrawPicture_OpType == type;
74}
75
76bool Model::isHierarchyPop(int index) const {
77 SkDrawCommand::OpType type = fOps[index]->getType();
78
79 return SkDrawCommand::kRestore_OpType == type ||
80 SkDrawCommand::kEndDrawPicture_OpType == type;
81}
82
Robert Phillipsdeaf5682017-09-06 13:07:21 -040083void Model::setCurOp(int curOp) {
84 SkASSERT(curOp < fOps.count());
85
86 if (curOp == fCurOp) {
87 return; // the render state is already up to date
88 }
89
90 fCurOp = curOp;
91 this->drawTo(fCurOp);
92}
93
94void Model::drawTo(int index) {
95 SkASSERT(index < fOps.count());
96
97 SkCanvas canvas(fBM);
98
99 int saveCount = canvas.save();
100
101 for (int i = 0; i <= index; ++i) {
102 if (fOps[i]->isVisible()) {
103 fOps[i]->execute(&canvas);
104 }
105 }
106
107 canvas.restoreToCount(saveCount);
108}
109
110void Model::resetOpList() {
111 for (int i = 0; i < fOps.count(); ++i) {
112 delete fOps[i];
113 }
Robert Phillips276066b2017-09-06 17:17:44 -0400114 fOps.reset();
Robert Phillipsdeaf5682017-09-06 13:07:21 -0400115 fCurOp = 0;
116}