More cleanup in the Vulkan viewer
* add animation support for GMs * don't load all SkPictures at start, only as needed * don't update constantly, only for animation or stats * hide/show stats * scale slides up/down BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1873733003 Review URL: https://codereview.chromium.org/1873733003
This commit is contained in:
parent
377add7426
commit
c265a92741
@ -73,6 +73,7 @@ protected:
|
||||
|
||||
canvas->translate(80.0f, 0.0f);
|
||||
}
|
||||
canvas->restore();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -67,7 +67,8 @@ void Window::onPaint() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Window::onResize(uint32_t w, uint32_t h) {
|
||||
fWidth = w;
|
||||
fHeight = h;
|
||||
fTestContext->resize(w, h);
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ public:
|
||||
|
||||
virtual void setTitle(const char*) = 0;
|
||||
virtual void show() = 0;
|
||||
virtual void inval() = 0;
|
||||
|
||||
struct AttachmentInfo {
|
||||
int fSampleCount;
|
||||
@ -122,9 +123,15 @@ public:
|
||||
void onPaint();
|
||||
void onResize(uint32_t width, uint32_t height);
|
||||
|
||||
uint32_t width() { return fWidth; }
|
||||
uint32_t height() { return fHeight; }
|
||||
|
||||
protected:
|
||||
Window();
|
||||
|
||||
uint32_t fWidth;
|
||||
uint32_t fHeight;
|
||||
|
||||
OnCharFunc fCharFunc;
|
||||
void* fCharUserData;
|
||||
OnKeyFunc fKeyFunc;
|
||||
|
@ -26,3 +26,7 @@ void GMSlide::draw(SkCanvas* canvas) {
|
||||
fGM->drawBackground(canvas);
|
||||
fGM->drawContent(canvas);
|
||||
}
|
||||
|
||||
bool GMSlide::animate(const SkAnimTimer& timer) {
|
||||
return fGM->animate(timer);
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ public:
|
||||
~GMSlide() override;
|
||||
|
||||
void draw(SkCanvas* canvas) override;
|
||||
bool animate(const SkAnimTimer&) override;
|
||||
|
||||
private:
|
||||
skiagm::GM* fGM;
|
||||
|
@ -8,25 +8,51 @@
|
||||
#include "SKPSlide.h"
|
||||
|
||||
#include "SkCanvas.h"
|
||||
#include "SkCommonFlags.h"
|
||||
#include "SkOSFile.h"
|
||||
#include "SkStream.h"
|
||||
|
||||
SKPSlide::SKPSlide(const char* name, sk_sp<const SkPicture> pic)
|
||||
: fPic(pic)
|
||||
, fCullRect(fPic->cullRect().roundOut()) {
|
||||
SKPSlide::SKPSlide(const SkString& name, const SkString& path) : fPath(path) {
|
||||
fName = name;
|
||||
}
|
||||
|
||||
SKPSlide::~SKPSlide() {}
|
||||
|
||||
void SKPSlide::draw(SkCanvas* canvas) {
|
||||
bool isOffset = SkToBool(fCullRect.left() | fCullRect.top());
|
||||
if (isOffset) {
|
||||
canvas->save();
|
||||
canvas->translate(SkIntToScalar(-fCullRect.left()), SkIntToScalar(-fCullRect.top()));
|
||||
}
|
||||
if (fPic.get()) {
|
||||
bool isOffset = SkToBool(fCullRect.left() | fCullRect.top());
|
||||
if (isOffset) {
|
||||
canvas->save();
|
||||
canvas->translate(SkIntToScalar(-fCullRect.left()), SkIntToScalar(-fCullRect.top()));
|
||||
}
|
||||
|
||||
canvas->drawPicture(fPic.get());
|
||||
canvas->drawPicture(fPic.get());
|
||||
|
||||
if (isOffset) {
|
||||
canvas->restore();
|
||||
if (isOffset) {
|
||||
canvas->restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static sk_sp<SkPicture> read_picture(const char path[]) {
|
||||
SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path));
|
||||
if (stream.get() == nullptr) {
|
||||
SkDebugf("Could not read %s.\n", path);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto pic = SkPicture::MakeFromStream(stream.get());
|
||||
if (!pic) {
|
||||
SkDebugf("Could not read %s as an SkPicture.\n", path);
|
||||
}
|
||||
return pic;
|
||||
}
|
||||
|
||||
void SKPSlide::load() {
|
||||
fPic = read_picture(fPath.c_str());
|
||||
fCullRect = fPic->cullRect().roundOut();
|
||||
}
|
||||
|
||||
void SKPSlide::unload() {
|
||||
fPic.reset(nullptr);
|
||||
}
|
||||
|
@ -13,12 +13,15 @@
|
||||
|
||||
class SKPSlide : public Slide {
|
||||
public:
|
||||
SKPSlide(const char* name, sk_sp<const SkPicture> pic);
|
||||
SKPSlide(const SkString& name, const SkString& path);
|
||||
~SKPSlide() override;
|
||||
|
||||
void draw(SkCanvas* canvas) override;
|
||||
void load() override;
|
||||
void unload() override;
|
||||
|
||||
private:
|
||||
SkString fPath;
|
||||
sk_sp<const SkPicture> fPic;
|
||||
SkIRect fCullRect;
|
||||
};
|
||||
|
@ -12,12 +12,17 @@
|
||||
#include "SkString.h"
|
||||
|
||||
class SkCanvas;
|
||||
class SkAnimTimer;
|
||||
|
||||
class Slide : public SkRefCnt {
|
||||
public:
|
||||
virtual ~Slide() {}
|
||||
|
||||
virtual void draw(SkCanvas* canvas) = 0;
|
||||
virtual bool animate(const SkAnimTimer&) { return false; }
|
||||
virtual void load() {}
|
||||
virtual void unload() {}
|
||||
|
||||
SkString getName() { return fName; }
|
||||
|
||||
protected:
|
||||
|
@ -27,6 +27,12 @@ static bool on_key_handler(Window::Key key, Window::InputState state, uint32_t m
|
||||
return vv->onKey(key, state, modifiers);
|
||||
}
|
||||
|
||||
static bool on_char_handler(SkUnichar c, uint32_t modifiers, void* userData) {
|
||||
VulkanViewer* vv = reinterpret_cast<VulkanViewer*>(userData);
|
||||
|
||||
return vv->onChar(c, modifiers);
|
||||
}
|
||||
|
||||
static void on_paint_handler(SkCanvas* canvas, void* userData) {
|
||||
VulkanViewer* vv = reinterpret_cast<VulkanViewer*>(userData);
|
||||
|
||||
@ -46,12 +52,10 @@ DEFINE_string2(match, m, nullptr,
|
||||
"it is skipped unless some list entry starts with ~");
|
||||
DEFINE_string(skps, "skps", "Directory to read skps from.");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
VulkanViewer::VulkanViewer(int argc, char** argv, void* platformData) : fCurrentMeasurement(0) {
|
||||
VulkanViewer::VulkanViewer(int argc, char** argv, void* platformData)
|
||||
: fCurrentMeasurement(0)
|
||||
, fDisplayStats(false)
|
||||
{
|
||||
memset(fMeasurements, 0, sizeof(fMeasurements));
|
||||
|
||||
SkDebugf("Command line arguments: ");
|
||||
@ -67,48 +71,20 @@ VulkanViewer::VulkanViewer(int argc, char** argv, void* platformData) : fCurrent
|
||||
|
||||
// register callbacks
|
||||
fWindow->registerKeyFunc(on_key_handler, this);
|
||||
fWindow->registerCharFunc(on_char_handler, this);
|
||||
fWindow->registerPaintFunc(on_paint_handler, this);
|
||||
|
||||
// set up slides
|
||||
this->initSlides();
|
||||
|
||||
// set up first frame
|
||||
SkString title("VulkanViewer: ");
|
||||
title.append(fSlides[0]->getName());
|
||||
fCurrentSlide = 0;
|
||||
fWindow->setTitle(title.c_str());
|
||||
setupCurrentSlide(-1);
|
||||
fLocalMatrix.reset();
|
||||
|
||||
fWindow->show();
|
||||
}
|
||||
|
||||
static sk_sp<SkPicture> read_picture(const char path[]) {
|
||||
if (SkCommandLineFlags::ShouldSkip(FLAGS_match, path)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path));
|
||||
if (stream.get() == nullptr) {
|
||||
SkDebugf("Could not read %s.\n", path);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto pic = SkPicture::MakeFromStream(stream.get());
|
||||
if (!pic) {
|
||||
SkDebugf("Could not read %s as an SkPicture.\n", path);
|
||||
}
|
||||
return pic;
|
||||
}
|
||||
|
||||
|
||||
static sk_sp<SKPSlide> loadSKP(const SkString& path) {
|
||||
sk_sp<SkPicture> pic = read_picture(path.c_str());
|
||||
if (!pic) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SkString name = SkOSPath::Basename(path.c_str());
|
||||
return sk_sp<SKPSlide>(new SKPSlide(name.c_str(), pic));
|
||||
}
|
||||
|
||||
void VulkanViewer::initSlides() {
|
||||
const skiagm::GMRegistry* gms(skiagm::GMRegistry::Head());
|
||||
while (gms) {
|
||||
@ -132,17 +108,25 @@ void VulkanViewer::initSlides() {
|
||||
// SKPs
|
||||
for (int i = 0; i < FLAGS_skps.count(); i++) {
|
||||
if (SkStrEndsWith(FLAGS_skps[i], ".skp")) {
|
||||
if (SkCommandLineFlags::ShouldSkip(FLAGS_match, FLAGS_skps[i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SkString path(FLAGS_skps[i]);
|
||||
sk_sp<SKPSlide> slide = loadSKP(path);
|
||||
sk_sp<SKPSlide> slide(new SKPSlide(SkOSPath::Basename(path.c_str()), path));
|
||||
if (slide) {
|
||||
fSlides.push_back(slide);
|
||||
}
|
||||
} else {
|
||||
SkOSFile::Iter it(FLAGS_skps[i], ".skp");
|
||||
SkString path;
|
||||
while (it.next(&path)) {
|
||||
SkString skpName = SkOSPath::Join(FLAGS_skps[i], path.c_str());
|
||||
sk_sp<SKPSlide> slide = loadSKP(skpName);
|
||||
SkString skpName;
|
||||
while (it.next(&skpName)) {
|
||||
if (SkCommandLineFlags::ShouldSkip(FLAGS_match, skpName.c_str())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SkString path = SkOSPath::Join(FLAGS_skps[i], skpName.c_str());
|
||||
sk_sp<SKPSlide> slide(new SKPSlide(skpName, path));
|
||||
if (slide) {
|
||||
fSlides.push_back(slide);
|
||||
}
|
||||
@ -157,39 +141,124 @@ VulkanViewer::~VulkanViewer() {
|
||||
delete fWindow;
|
||||
}
|
||||
|
||||
void VulkanViewer::setupCurrentSlide(int previousSlide) {
|
||||
SkString title("VulkanViewer: ");
|
||||
title.append(fSlides[fCurrentSlide]->getName());
|
||||
fSlides[fCurrentSlide]->load();
|
||||
if (previousSlide >= 0) {
|
||||
fSlides[previousSlide]->unload();
|
||||
}
|
||||
fWindow->setTitle(title.c_str());
|
||||
fWindow->inval();
|
||||
}
|
||||
|
||||
#define MAX_ZOOM_LEVEL 8
|
||||
#define MIN_ZOOM_LEVEL -8
|
||||
|
||||
void VulkanViewer::changeZoomLevel(float delta) {
|
||||
fZoomLevel += delta;
|
||||
if (fZoomLevel > 0) {
|
||||
fZoomLevel = SkMinScalar(fZoomLevel, MAX_ZOOM_LEVEL);
|
||||
fZoomScale = fZoomLevel + SK_Scalar1;
|
||||
} else if (fZoomLevel < 0) {
|
||||
fZoomLevel = SkMaxScalar(fZoomLevel, MIN_ZOOM_LEVEL);
|
||||
fZoomScale = SK_Scalar1 / (SK_Scalar1 - fZoomLevel);
|
||||
} else {
|
||||
fZoomScale = SK_Scalar1;
|
||||
}
|
||||
this->updateMatrix();
|
||||
}
|
||||
|
||||
void VulkanViewer::updateMatrix(){
|
||||
SkMatrix m;
|
||||
m.reset();
|
||||
|
||||
if (fZoomLevel) {
|
||||
SkPoint center;
|
||||
//m = this->getLocalMatrix();//.invert(&m);
|
||||
m.mapXY(fZoomCenterX, fZoomCenterY, ¢er);
|
||||
SkScalar cx = center.fX;
|
||||
SkScalar cy = center.fY;
|
||||
|
||||
m.setTranslate(-cx, -cy);
|
||||
m.postScale(fZoomScale, fZoomScale);
|
||||
m.postTranslate(cx, cy);
|
||||
}
|
||||
|
||||
// TODO: add gesture support
|
||||
// Apply any gesture matrix
|
||||
//m.preConcat(fGesture.localM());
|
||||
//m.preConcat(fGesture.globalM());
|
||||
|
||||
fLocalMatrix = m;
|
||||
}
|
||||
|
||||
bool VulkanViewer::onKey(Window::Key key, Window::InputState state, uint32_t modifiers) {
|
||||
if (Window::kDown_InputState == state && (modifiers & Window::kFirstPress_ModifierKey)) {
|
||||
if (key == Window::kRight_Key) {
|
||||
fCurrentSlide++;
|
||||
if (fCurrentSlide >= fSlides.count()) {
|
||||
fCurrentSlide = 0;
|
||||
if (Window::kDown_InputState == state) {
|
||||
switch (key) {
|
||||
case Window::kRight_Key: {
|
||||
int previousSlide = fCurrentSlide;
|
||||
fCurrentSlide++;
|
||||
if (fCurrentSlide >= fSlides.count()) {
|
||||
fCurrentSlide = 0;
|
||||
}
|
||||
setupCurrentSlide(previousSlide);
|
||||
return true;
|
||||
}
|
||||
SkString title("VulkanViewer: ");
|
||||
title.append(fSlides[fCurrentSlide]->getName());
|
||||
fWindow->setTitle(title.c_str());
|
||||
} else if (key == Window::kLeft_Key) {
|
||||
fCurrentSlide--;
|
||||
if (fCurrentSlide < 0) {
|
||||
fCurrentSlide = fSlides.count()-1;
|
||||
|
||||
case Window::kLeft_Key: {
|
||||
int previousSlide = fCurrentSlide;
|
||||
fCurrentSlide--;
|
||||
if (fCurrentSlide < 0) {
|
||||
fCurrentSlide = fSlides.count() - 1;
|
||||
}
|
||||
SkString title("VulkanViewer: ");
|
||||
title.append(fSlides[fCurrentSlide]->getName());
|
||||
fWindow->setTitle(title.c_str());
|
||||
setupCurrentSlide(previousSlide);
|
||||
return true;
|
||||
}
|
||||
SkString title("VulkanViewer: ");
|
||||
title.append(fSlides[fCurrentSlide]->getName());
|
||||
fWindow->setTitle(title.c_str());
|
||||
|
||||
case Window::kUp_Key: {
|
||||
this->changeZoomLevel(1.f / 32.f);
|
||||
return true;
|
||||
}
|
||||
|
||||
case Window::kDown_Key: {
|
||||
this->changeZoomLevel(-1.f / 32.f);
|
||||
return true;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VulkanViewer::onChar(SkUnichar c, uint32_t modifiers) {
|
||||
if ('s' == c) {
|
||||
fDisplayStats = !fDisplayStats;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void VulkanViewer::onPaint(SkCanvas* canvas) {
|
||||
|
||||
canvas->clear(SK_ColorWHITE);
|
||||
|
||||
canvas->save();
|
||||
fSlides[fCurrentSlide]->draw(canvas);
|
||||
canvas->restore();
|
||||
int count = canvas->save();
|
||||
canvas->setMatrix(fLocalMatrix);
|
||||
|
||||
drawStats(canvas);
|
||||
fSlides[fCurrentSlide]->draw(canvas);
|
||||
canvas->restoreToCount(count);
|
||||
|
||||
if (fDisplayStats) {
|
||||
drawStats(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanViewer::drawStats(SkCanvas* canvas) {
|
||||
@ -240,5 +309,8 @@ void VulkanViewer::onIdle(double ms) {
|
||||
fCurrentMeasurement &= (kMeasurementCount - 1); // fast mod
|
||||
SkASSERT(fCurrentMeasurement < kMeasurementCount);
|
||||
|
||||
fWindow->onPaint();
|
||||
fAnimTimer.updateTime();
|
||||
if (fDisplayStats || fSlides[fCurrentSlide]->animate(fAnimTimer)) {
|
||||
fWindow->inval();
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "../Application.h"
|
||||
#include "../Window.h"
|
||||
#include "gm.h"
|
||||
#include "SkAnimTimer.h"
|
||||
#include "Slide.h"
|
||||
|
||||
class SkCanvas;
|
||||
@ -21,23 +22,38 @@ public:
|
||||
~VulkanViewer() override;
|
||||
|
||||
bool onKey(Window::Key key, Window::InputState state, uint32_t modifiers);
|
||||
bool onChar(SkUnichar, uint32_t modifiers);
|
||||
void onPaint(SkCanvas* canvas);
|
||||
|
||||
void onIdle(double ms) override;
|
||||
|
||||
private:
|
||||
void initSlides();
|
||||
void setupCurrentSlide(int previousSlide);
|
||||
|
||||
void drawStats(SkCanvas* canvas);
|
||||
|
||||
void changeZoomLevel(float delta);
|
||||
void updateMatrix();
|
||||
|
||||
Window* fWindow;
|
||||
|
||||
static const int kMeasurementCount = 64; // should be power of 2 for fast mod
|
||||
double fMeasurements[kMeasurementCount];
|
||||
int fCurrentMeasurement;
|
||||
|
||||
SkAnimTimer fAnimTimer;
|
||||
SkTArray<sk_sp<Slide>> fSlides;
|
||||
int fCurrentSlide;
|
||||
|
||||
bool fDisplayStats;
|
||||
|
||||
// transform data
|
||||
SkMatrix fLocalMatrix;
|
||||
SkScalar fZoomCenterX;
|
||||
SkScalar fZoomCenterY;
|
||||
SkScalar fZoomLevel;
|
||||
SkScalar fZoomScale;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -275,3 +275,7 @@ bool Window_win::attach(BackEndType attachType, int msaaSampleCount, AttachmentI
|
||||
|
||||
return (SkToBool(fTestContext));
|
||||
}
|
||||
|
||||
void Window_win::inval() {
|
||||
InvalidateRect(fHWnd, nullptr, false);
|
||||
}
|
||||
|
@ -23,6 +23,8 @@ public:
|
||||
|
||||
bool attach(BackEndType attachType, int msaaSampleCount, AttachmentInfo*) override;
|
||||
|
||||
void inval() override;
|
||||
|
||||
private:
|
||||
HINSTANCE fHInstance;
|
||||
HWND fHWnd;
|
||||
|
@ -72,11 +72,11 @@ static int main_common(HINSTANCE hInstance, int show, int argc, char**argv) {
|
||||
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
previousTime = currentTime;
|
||||
currentTime = now_ms();
|
||||
app->onIdle(currentTime - previousTime);
|
||||
} else {
|
||||
previousTime = currentTime;
|
||||
currentTime = now_ms();
|
||||
app->onIdle(currentTime - previousTime);
|
||||
}
|
||||
}
|
||||
|
||||
delete app;
|
||||
|
Loading…
Reference in New Issue
Block a user