| /* |
| * Copyright 2017 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include <memory> |
| |
| #include "tools/mdbviz/Model.h" |
| |
| #include "include/core/SkBitmap.h" |
| #include "include/core/SkCanvas.h" |
| #include "include/core/SkPicture.h" |
| #include "include/core/SkStream.h" |
| #include "tools/debugger/DebugCanvas.h" |
| |
| Model::Model() : fCurOp(0) { |
| SkImageInfo ii = SkImageInfo::MakeN32Premul(1024, 1024); |
| fBM.allocPixels(ii, 0); |
| } |
| |
| Model::~Model() { |
| this->resetOpsTask(); |
| } |
| |
| Model::ErrorCode Model::load(const char* filename) { |
| std::unique_ptr<SkStream> stream = SkStream::MakeFromFile(filename); |
| if (!stream) { |
| return ErrorCode::kCouldntOpenFile; |
| } |
| sk_sp<SkPicture> pic(SkPicture::MakeFromStream(stream.get())); |
| if (!pic) { |
| return ErrorCode::kCouldntDecodeSKP; |
| } |
| |
| { |
| std::unique_ptr<DebugCanvas> temp( |
| new DebugCanvas(SkScalarCeilToInt(pic->cullRect().width()), |
| SkScalarCeilToInt(pic->cullRect().height()))); |
| |
| temp->setPicture(pic.get()); |
| pic->playback(temp.get()); |
| temp->setPicture(nullptr); |
| this->resetOpsTask(); |
| temp->detachCommands(&fOps); |
| } |
| |
| this->setCurOp(fOps.count()-1); |
| |
| return ErrorCode::kOK; |
| } |
| |
| const char* Model::ErrorString(ErrorCode err) { |
| static const char* kStrings[] = { |
| "OK", |
| "Couldn't read file", |
| "Couldn't decode picture" |
| }; |
| |
| return kStrings[(int)err]; |
| } |
| |
| const char* Model::getOpName(int index) const { |
| return DrawCommand::GetCommandString(fOps[index]->getType()); |
| } |
| |
| bool Model::isHierarchyPush(int index) const { |
| DrawCommand::OpType type = fOps[index]->getType(); |
| |
| return DrawCommand::kSave_OpType == type || DrawCommand::kSaveLayer_OpType == type || |
| DrawCommand::kBeginDrawPicture_OpType == type; |
| } |
| |
| bool Model::isHierarchyPop(int index) const { |
| DrawCommand::OpType type = fOps[index]->getType(); |
| |
| return DrawCommand::kRestore_OpType == type || DrawCommand::kEndDrawPicture_OpType == type; |
| } |
| |
| void Model::setCurOp(int curOp) { |
| SkASSERT(curOp < fOps.count()); |
| |
| if (curOp == fCurOp) { |
| return; // the render state is already up to date |
| } |
| |
| fCurOp = curOp; |
| this->drawTo(fCurOp); |
| } |
| |
| void Model::drawTo(int index) { |
| SkASSERT(index < fOps.count()); |
| |
| SkCanvas canvas(fBM); |
| |
| int saveCount = canvas.save(); |
| |
| for (int i = 0; i <= index; ++i) { |
| if (fOps[i]->isVisible()) { |
| fOps[i]->execute(&canvas); |
| } |
| } |
| |
| canvas.restoreToCount(saveCount); |
| } |
| |
| void Model::resetOpsTask() { |
| for (int i = 0; i < fOps.count(); ++i) { |
| delete fOps[i]; |
| } |
| fOps.reset(); |
| fCurOp = 0; |
| } |