1 /* 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 "tools/mdbviz/Model.h" 11 12 #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" 17 Model()18Model::Model() : fCurOp(0) { 19 SkImageInfo ii = SkImageInfo::MakeN32Premul(1024, 1024); 20 fBM.allocPixels(ii, 0); 21 } 22 ~Model()23Model::~Model() { 24 this->resetOpsTask(); 25 } 26 load(const char * filename)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<DebugCanvas> temp( 39 new DebugCanvas(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->resetOpsTask(); 46 temp->detachCommands(&fOps); 47 } 48 49 this->setCurOp(fOps.count()-1); 50 51 return ErrorCode::kOK; 52 } 53 ErrorString(ErrorCode err)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 getOpName(int index) const64const char* Model::getOpName(int index) const { 65 return DrawCommand::GetCommandString(fOps[index]->getType()); 66 } 67 isHierarchyPush(int index) const68bool Model::isHierarchyPush(int index) const { 69 DrawCommand::OpType type = fOps[index]->getType(); 70 71 return DrawCommand::kSave_OpType == type || DrawCommand::kSaveLayer_OpType == type || 72 DrawCommand::kBeginDrawPicture_OpType == type; 73 } 74 isHierarchyPop(int index) const75bool Model::isHierarchyPop(int index) const { 76 DrawCommand::OpType type = fOps[index]->getType(); 77 78 return DrawCommand::kRestore_OpType == type || DrawCommand::kEndDrawPicture_OpType == type; 79 } 80 setCurOp(int curOp)81void 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 drawTo(int index)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 resetOpsTask()108void Model::resetOpsTask() { 109 for (int i = 0; i < fOps.count(); ++i) { 110 delete fOps[i]; 111 } 112 fOps.reset(); 113 fCurOp = 0; 114 } 115