blob: 3cb01f006f322bba76f1de3992ff5c820630b72c [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "tools/mdbviz/Model.h"
Robert Phillipsdeaf5682017-09-06 13:07:21 -040011
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "include/core/SkBitmap.h"
13#include "include/core/SkCanvas.h"
14#include "include/core/SkPicture.h"
15#include "include/core/SkStream.h"
16#include "tools/debugger/DebugCanvas.h"
Robert Phillipsdeaf5682017-09-06 13:07:21 -040017
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 {
Mike Klein8f4e2242019-03-20 11:59:00 -050038 std::unique_ptr<DebugCanvas> temp(
39 new DebugCanvas(SkScalarCeilToInt(pic->cullRect().width()),
40 SkScalarCeilToInt(pic->cullRect().height())));
Robert Phillipsdeaf5682017-09-06 13:07:21 -040041
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 {
Mike Klein8f4e2242019-03-20 11:59:00 -050065 return DrawCommand::GetCommandString(fOps[index]->getType());
Robert Phillipsdeaf5682017-09-06 13:07:21 -040066}
67
Robert Phillips276066b2017-09-06 17:17:44 -040068bool Model::isHierarchyPush(int index) const {
Mike Klein8f4e2242019-03-20 11:59:00 -050069 DrawCommand::OpType type = fOps[index]->getType();
Robert Phillips276066b2017-09-06 17:17:44 -040070
Mike Klein8f4e2242019-03-20 11:59:00 -050071 return DrawCommand::kSave_OpType == type || DrawCommand::kSaveLayer_OpType == type ||
72 DrawCommand::kBeginDrawPicture_OpType == type;
Robert Phillips276066b2017-09-06 17:17:44 -040073}
74
75bool Model::isHierarchyPop(int index) const {
Mike Klein8f4e2242019-03-20 11:59:00 -050076 DrawCommand::OpType type = fOps[index]->getType();
Robert Phillips276066b2017-09-06 17:17:44 -040077
Mike Klein8f4e2242019-03-20 11:59:00 -050078 return DrawCommand::kRestore_OpType == type || DrawCommand::kEndDrawPicture_OpType == type;
Robert Phillips276066b2017-09-06 17:17:44 -040079}
80
Robert Phillipsdeaf5682017-09-06 13:07:21 -040081void Model::setCurOp(int curOp) {
82 SkASSERT(curOp < fOps.count());
83
84 if (curOp == fCurOp) {
85 return; // the render state is already up to date
86 }
87
88 fCurOp = curOp;
89 this->drawTo(fCurOp);
90}
91
92void Model::drawTo(int index) {
93 SkASSERT(index < fOps.count());
94
95 SkCanvas canvas(fBM);
96
97 int saveCount = canvas.save();
98
99 for (int i = 0; i <= index; ++i) {
100 if (fOps[i]->isVisible()) {
101 fOps[i]->execute(&canvas);
102 }
103 }
104
105 canvas.restoreToCount(saveCount);
106}
107
108void Model::resetOpList() {
109 for (int i = 0; i < fOps.count(); ++i) {
110 delete fOps[i];
111 }
Robert Phillips276066b2017-09-06 17:17:44 -0400112 fOps.reset();
Robert Phillipsdeaf5682017-09-06 13:07:21 -0400113 fCurOp = 0;
114}