aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools
diff options
context:
space:
mode:
authorGravatar Robert Phillips <robertphillips@google.com>2017-09-06 13:07:21 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-09-06 20:46:01 +0000
commitdeaf568e07f0b63c84c5909f14e2b7261b1653ae (patch)
tree6c4e8023f34d2019772c22edff65fe9afb45949b /tools
parent2880421c724e7b45ed13b784a36aa81a09fe62e5 (diff)
Solidify Model/View split
Change-Id: Iecf034feaa009002b5f09c47052c915d22aec0e4 Reviewed-on: https://skia-review.googlesource.com/43040 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/debugger/SkDebugCanvas.h6
-rw-r--r--tools/mdbviz/Model.cpp100
-rw-r--r--tools/mdbviz/Model.h54
-rw-r--r--tools/mdbviz/mainwindow.cpp58
-rw-r--r--tools/mdbviz/mainwindow.h7
5 files changed, 185 insertions, 40 deletions
diff --git a/tools/debugger/SkDebugCanvas.h b/tools/debugger/SkDebugCanvas.h
index 9b944f7d5d..72d65d7da7 100644
--- a/tools/debugger/SkDebugCanvas.h
+++ b/tools/debugger/SkDebugCanvas.h
@@ -184,6 +184,10 @@ public:
return SkIRect::MakeWH(this->imageInfo().width(), this->imageInfo().height());
}
+ void detachCommands(SkTDArray<SkDrawCommand*>* dst) {
+ fCommandVector.swap(*dst);
+ }
+
protected:
void willSave() override;
@@ -266,7 +270,7 @@ private:
SkTDArray<SkDrawCommand*> fActiveLayers;
/**
- Adds the command to the classes vector of commands.
+ Adds the command to the class' vector of commands.
@param command The draw command for execution
*/
void addDrawCommand(SkDrawCommand* command);
diff --git a/tools/mdbviz/Model.cpp b/tools/mdbviz/Model.cpp
new file mode 100644
index 0000000000..a3f8e1ae87
--- /dev/null
+++ b/tools/mdbviz/Model.cpp
@@ -0,0 +1,100 @@
+/*
+ * 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 "Model.h"
+
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkDebugCanvas.h"
+#include "SkPicture.h"
+#include "SkStream.h"
+
+Model::Model() : fCurOp(0) {
+ SkImageInfo ii = SkImageInfo::MakeN32Premul(1024, 1024);
+ fBM.allocPixels(ii, 0);
+}
+
+Model::~Model() {
+ this->resetOpList();
+}
+
+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<SkDebugCanvas> temp(new SkDebugCanvas(
+ SkScalarCeilToInt(pic->cullRect().width()),
+ SkScalarCeilToInt(pic->cullRect().height())));
+
+ temp->setPicture(pic.get());
+ pic->playback(temp.get());
+ temp->setPicture(nullptr);
+ this->resetOpList();
+ 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) {
+ return SkDrawCommand::GetCommandString(fOps[index]->getType());
+}
+
+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::resetOpList() {
+ for (int i = 0; i < fOps.count(); ++i) {
+ delete fOps[i];
+ }
+ fCurOp = 0;
+}
diff --git a/tools/mdbviz/Model.h b/tools/mdbviz/Model.h
new file mode 100644
index 0000000000..773c148c3f
--- /dev/null
+++ b/tools/mdbviz/Model.h
@@ -0,0 +1,54 @@
+/*
+ * 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 "SkBitmap.h"
+#include "SkTDArray.h"
+
+class SkDrawCommand;
+
+// This class encapsulates the both the in-memory representation of the draw ops
+// and the state of Skia/Ganesh's rendering. It should never have any Qt intrusions.
+class Model {
+public:
+ enum class ErrorCode {
+ kOK,
+ kCouldntOpenFile,
+ kCouldntDecodeSKP
+ };
+
+ Model();
+ ~Model();
+
+ static const char* ErrorString(ErrorCode);
+
+ // Replace the list of draw ops by reading the provided skp filename and
+ // reset the Skia draw state. It is up to the view portion to update itself
+ // after this call (i.e., rebuild the opList view).
+ ErrorCode load(const char* filename);
+
+ // Update the rendering state to the provided op
+ void setCurOp(int curOp);
+ int curOp() const { return fCurOp; }
+
+ int numOps() const { return fOps.count(); }
+ const char* getOpName(int index);
+
+ // Get the bits visually representing the current rendering state
+ void* getPixels() const { return fBM.getPixels(); }
+ int width() const { return fBM.width(); }
+ int height() const { return fBM.height(); }
+
+protected:
+ // draw the ops up to (and including) the index-th op
+ void drawTo(int index);
+ void resetOpList();
+
+private:
+ SkTDArray<SkDrawCommand*> fOps;
+ int fCurOp; // The current op the rendering state is at
+ SkBitmap fBM;
+};
diff --git a/tools/mdbviz/mainwindow.cpp b/tools/mdbviz/mainwindow.cpp
index 5fb1e7e344..c09ad091fa 100644
--- a/tools/mdbviz/mainwindow.cpp
+++ b/tools/mdbviz/mainwindow.cpp
@@ -9,11 +9,6 @@
#include "MainWindow.h"
-#include "SkBitmap.h"
-#include "SkCanvas.h"
-#include "SkPicture.h"
-#include "SkStream.h"
-
MainWindow::MainWindow() {
this->createActions();
this->createStatusBar();
@@ -35,16 +30,21 @@ void MainWindow::openFile() {
void MainWindow::setupOpListWidget() {
fOpListWidget->clear();
- for (int i = 0; i < fDebugCanvas->getSize(); i++) {
+ for (int i = 0; i < fModel.numOps(); i++) {
QListWidgetItem *item = new QListWidgetItem();
- const SkDrawCommand* command = fDebugCanvas->getDrawCommandAt(i);
-
- SkString commandString = command->toString();
- item->setData(Qt::DisplayRole, commandString.c_str());
+ item->setData(Qt::DisplayRole, fModel.getOpName(i));
fOpListWidget->addItem(item);
}
+
+ fOpListWidget->setCurrentRow(fModel.numOps()-1);
+}
+
+void MainWindow::presentCurrentRenderState() {
+ fImage = QImage((uchar*)fModel.getPixels(), fModel.width(), fModel.height(),
+ QImage::Format_RGBA8888);
+ fImageLabel->setPixmap(QPixmap::fromImage(fImage));
}
void MainWindow::loadFile(const QString &fileName) {
@@ -63,37 +63,14 @@ void MainWindow::loadFile(const QString &fileName) {
std::string str = file.fileName().toLocal8Bit().constData();
- std::unique_ptr<SkStream> stream = SkStream::MakeFromFile(str.c_str());
- if (!stream) {
- this->statusBar()->showMessage(tr("Couldn't read file"));
- return;
- }
- sk_sp<SkPicture> pic(SkPicture::MakeFromStream(stream.get()));
- if (!pic) {
- this->statusBar()->showMessage(tr("Couldn't decode picture"));
+ Model::ErrorCode err = fModel.load(str.c_str());
+ if (Model::ErrorCode::kOK != err) {
+ this->statusBar()->showMessage(Model::ErrorString(err));
return;
}
- fDebugCanvas.reset(new SkDebugCanvas(SkScalarCeilToInt(pic->cullRect().width()),
- SkScalarCeilToInt(pic->cullRect().height())));
-
- fDebugCanvas->setPicture(pic.get());
- pic->playback(fDebugCanvas.get());
- fDebugCanvas->setPicture(nullptr);
-
this->setupOpListWidget();
-
- SkBitmap bm;
-
- SkImageInfo ii = SkImageInfo::MakeN32Premul(1024, 1024);
- bm.allocPixels(ii, 0);
-
- SkCanvas canvas(bm);
-
- fDebugCanvas->draw(&canvas);
-
- fImage = QImage((uchar*)bm.getPixels(), bm.width(), bm.height(), QImage::Format_RGBA8888);
- fImageLabel->setPixmap(QPixmap::fromImage(fImage));
+ this->presentCurrentRenderState();
#ifndef QT_NO_CURSOR
QApplication::restoreOverrideCursor();
@@ -138,6 +115,11 @@ void MainWindow::createActions() {
aboutAct->setStatusTip(tr("Show the application's About box"));
}
+void MainWindow::onCurrentRowChanged(int currentRow) {
+ fModel.setCurOp(currentRow);
+ this->presentCurrentRenderState();
+}
+
void MainWindow::createStatusBar() {
this->statusBar()->showMessage(tr("Ready"));
}
@@ -155,6 +137,8 @@ void MainWindow::createDockWindows() {
this->addDockWidget(Qt::LeftDockWidgetArea, opListDock);
fViewMenu->addAction(opListDock->toggleViewAction());
+
+ connect(fOpListWidget, SIGNAL(currentRowChanged(int)), this, SLOT(onCurrentRowChanged(int)));
}
// Main canvas Window
diff --git a/tools/mdbviz/mainwindow.h b/tools/mdbviz/mainwindow.h
index 80c86b0471..59e7b98c38 100644
--- a/tools/mdbviz/mainwindow.h
+++ b/tools/mdbviz/mainwindow.h
@@ -11,7 +11,7 @@
#include <memory>
#include <QMainWindow>
-#include "SkDebugCanvas.h"
+#include "Model.h"
class QLabel;
class QListWidget;
@@ -27,10 +27,13 @@ public:
private slots:
void openFile();
void about();
+ void onCurrentRowChanged(int currentRow);
private:
void loadFile(const QString &fileName);
void setupOpListWidget();
+ void presentCurrentRenderState();
+
void createActions();
void createStatusBar();
@@ -46,7 +49,7 @@ private:
QMenu* fViewMenu;
- std::unique_ptr<SkDebugCanvas> fDebugCanvas;
+ Model fModel;
};
#endif