Add slides to VulkanViewer
authorjvanverth <jvanverth@google.com>
Fri, 8 Apr 2016 14:24:09 +0000 (07:24 -0700)
committerCommit bot <commit-bot@chromium.org>
Fri, 8 Apr 2016 14:24:09 +0000 (07:24 -0700)
Adds SKP loading, matching, and moving backwards as well as forwards
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1873543003

Review URL: https://codereview.chromium.org/1873543003

src/gpu/vk/GrVkGpu.cpp
tools/vulkan/viewer/GMSlide.cpp [new file with mode: 0644]
tools/vulkan/viewer/GMSlide.h [new file with mode: 0644]
tools/vulkan/viewer/SKPSlide.cpp [new file with mode: 0644]
tools/vulkan/viewer/SKPSlide.h [new file with mode: 0644]
tools/vulkan/viewer/Slide.h [new file with mode: 0644]
tools/vulkan/viewer/VulkanViewer.cpp
tools/vulkan/viewer/VulkanViewer.h

index 6b49360..428c2ff 100644 (file)
@@ -644,7 +644,6 @@ void GrVkGpu::bindGeometry(const GrPrimitiveProcessor& primProc,
 GrStencilAttachment* GrVkGpu::createStencilAttachmentForRenderTarget(const GrRenderTarget* rt,
                                                                      int width,
                                                                      int height) {
-    SkASSERT(rt->asTexture());
     SkASSERT(width >= rt->width());
     SkASSERT(height >= rt->height());
 
diff --git a/tools/vulkan/viewer/GMSlide.cpp b/tools/vulkan/viewer/GMSlide.cpp
new file mode 100644 (file)
index 0000000..59a00cf
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+/*
+* Copyright 2014 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#include "GMSlide.h"
+#include "SkCanvas.h"
+
+GMSlide::GMSlide(skiagm::GM* gm) : fGM(gm) {
+    fName.printf("GM_%s", gm->getName());
+}
+
+GMSlide::~GMSlide() { delete fGM; }
+
+void GMSlide::draw(SkCanvas* canvas) {
+    // Do we care about timing the draw of the background (once)?
+    // Does the GM ever rely on drawBackground to lazily compute something?
+    fGM->drawBackground(canvas);
+    fGM->drawContent(canvas);
+}
diff --git a/tools/vulkan/viewer/GMSlide.h b/tools/vulkan/viewer/GMSlide.h
new file mode 100644 (file)
index 0000000..e827287
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#ifndef GMSlide_DEFINED
+#define GMSlide_DEFINED
+
+#include "Slide.h"
+#include "gm.h"
+
+class GMSlide : public Slide {
+public:
+    GMSlide(skiagm::GM* gm);
+    ~GMSlide() override;
+
+    void draw(SkCanvas* canvas) override;
+
+private:
+    skiagm::GM* fGM;
+};
+
+
+#endif
diff --git a/tools/vulkan/viewer/SKPSlide.cpp b/tools/vulkan/viewer/SKPSlide.cpp
new file mode 100644 (file)
index 0000000..72f68b5
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#include "SKPSlide.h"
+
+#include "SkCanvas.h"
+
+SKPSlide::SKPSlide(const char* name, sk_sp<const SkPicture> pic)
+    : fPic(pic)
+    , fCullRect(fPic->cullRect().roundOut()) {
+    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()));
+    }
+
+    canvas->drawPicture(fPic.get());
+
+    if (isOffset) {
+        canvas->restore();
+    }
+}
diff --git a/tools/vulkan/viewer/SKPSlide.h b/tools/vulkan/viewer/SKPSlide.h
new file mode 100644 (file)
index 0000000..60be9d8
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#ifndef SKPSlide_DEFINED
+#define SKPSlide_DEFINED
+
+#include "Slide.h"
+#include "SkPicture.h"
+
+class SKPSlide : public Slide {
+public:
+    SKPSlide(const char* name, sk_sp<const SkPicture> pic);
+    ~SKPSlide() override;
+
+    void draw(SkCanvas* canvas) override;
+
+private:
+    sk_sp<const SkPicture> fPic;
+    SkIRect                fCullRect;
+};
+
+#endif
diff --git a/tools/vulkan/viewer/Slide.h b/tools/vulkan/viewer/Slide.h
new file mode 100644 (file)
index 0000000..742a345
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#ifndef Slide_DEFINED
+#define Slide_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkString.h"
+
+class SkCanvas;
+
+class Slide : public SkRefCnt {
+public:
+    virtual ~Slide() {}
+
+    virtual void draw(SkCanvas* canvas) = 0;
+    SkString getName() { return fName; }
+
+protected:
+    SkString    fName;
+};
+
+
+#endif
index 5c6e780..55da554 100644 (file)
@@ -7,12 +7,14 @@
 
 #include "VulkanViewer.h"
 
+#include "GMSlide.h"
+#include "SKPSlide.h"
+
 #include "SkCanvas.h"
-#include "SkRandom.h"
 #include "SkCommonFlags.h"
-
-DEFINE_string(key, "",
-              "Space-separated key/value pairs to add to JSON identifying this builder.");
+#include "SkOSFile.h"
+#include "SkRandom.h"
+#include "SkStream.h"
 
 Application* Application::Create(int argc, char** argv, void* platformData) {
     return new VulkanViewer(argc, argv, platformData);
@@ -31,11 +33,35 @@ static void on_paint_handler(SkCanvas* canvas, void* userData) {
     return vv->onPaint(canvas);
 }
 
-VulkanViewer::VulkanViewer(int argc, char** argv, void* platformData)
-    : fGMs(skiagm::GMRegistry::Head())
-    , fCurrentMeasurement(0) {
+DEFINE_bool2(fullscreen, f, true, "Run fullscreen.");
+DEFINE_string(key, "", "Space-separated key/value pairs to add to JSON identifying this builder.");
+DEFINE_string2(match, m, nullptr,
+               "[~][^]substring[$] [...] of bench name to run.\n"
+               "Multiple matches may be separated by spaces.\n"
+               "~ causes a matching bench to always be skipped\n"
+               "^ requires the start of the bench to match\n"
+               "$ requires the end of the bench to match\n"
+               "^ and $ requires an exact match\n"
+               "If a bench does not match any list entry,\n"
+               "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) {
     memset(fMeasurements, 0, sizeof(fMeasurements));
 
+    SkDebugf("Command line arguments: ");
+    for (int i = 1; i < argc; ++i) {
+        SkDebugf("%s ", argv[i]);
+    }
+    SkDebugf("\n");
+
+    SkCommandLineFlags::Parse(argc, argv);
+
     fWindow = Window::CreateNativeWindow(platformData);
     fWindow->attach(Window::kVulkan_BackendType, 0, nullptr);
 
@@ -43,36 +69,124 @@ VulkanViewer::VulkanViewer(int argc, char** argv, void* platformData)
     fWindow->registerKeyFunc(on_key_handler, this);
     fWindow->registerPaintFunc(on_paint_handler, this);
 
-    SkAutoTDelete<skiagm::GM> gm(fGMs->factory()(nullptr));
+    // set up slides
+    this->initSlides();
+
+    // set up first frame
     SkString title("VulkanViewer: ");
-    title.append(gm->getName());
+    title.append(fSlides[0]->getName());
+    fCurrentSlide = 0;
     fWindow->setTitle(title.c_str());
     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) {
+        SkAutoTDelete<skiagm::GM> gm(gms->factory()(nullptr));
+
+        if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, gm->getName())) {
+            sk_sp<Slide> slide(new GMSlide(gm.release()));
+            fSlides.push_back(slide);
+        }
+
+        gms = gms->next();
+    }
+
+    // reverse array
+    for (int i = 0; i < fSlides.count()/2; ++i) {
+        sk_sp<Slide> temp = fSlides[i];
+        fSlides[i] = fSlides[fSlides.count() - i - 1];
+        fSlides[fSlides.count() - i - 1] = temp;
+    }
+
+    // SKPs
+    for (int i = 0; i < FLAGS_skps.count(); i++) {
+        if (SkStrEndsWith(FLAGS_skps[i], ".skp")) {
+            SkString path(FLAGS_skps[i]);
+            sk_sp<SKPSlide> slide = loadSKP(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);
+                if (slide) {
+                    fSlides.push_back(slide);
+                }
+            }
+        }
+    }
+}
+
+
 VulkanViewer::~VulkanViewer() {
     fWindow->detach();
     delete fWindow;
 }
 
 bool VulkanViewer::onKey(Window::Key key, Window::InputState state, uint32_t modifiers) {
-    if (Window::kDown_InputState == state && (modifiers & Window::kFirstPress_ModifierKey) &&
-        key == Window::kRight_Key) {
-        fGMs = fGMs->next();
-        SkAutoTDelete<skiagm::GM> gm(fGMs->factory()(nullptr));
-        SkString title("VulkanViewer: ");
-        title.append(gm->getName());
-        fWindow->setTitle(title.c_str());
+    if (Window::kDown_InputState == state && (modifiers & Window::kFirstPress_ModifierKey)) {
+        if (key == Window::kRight_Key) {
+            fCurrentSlide++;
+            if (fCurrentSlide >= fSlides.count()) {
+                fCurrentSlide = 0;
+            }
+            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;
+            }
+            SkString title("VulkanViewer: ");
+            title.append(fSlides[fCurrentSlide]->getName());
+            fWindow->setTitle(title.c_str());
+        }
     }
 
     return true;
 }
 
 void VulkanViewer::onPaint(SkCanvas* canvas) {
-    SkAutoTDelete<skiagm::GM> gm(fGMs->factory()(nullptr));
+
+    canvas->clear(SK_ColorWHITE);
 
     canvas->save();
-    gm->draw(canvas);
+    fSlides[fCurrentSlide]->draw(canvas);
     canvas->restore();
 
     drawStats(canvas);
index b012cf1..649cb22 100644 (file)
@@ -11,6 +11,7 @@
 #include "../Application.h"
 #include "../Window.h"
 #include "gm.h"
+#include "Slide.h"
 
 class SkCanvas;
 
@@ -25,6 +26,8 @@ public:
     void onIdle(double ms) override;
 
 private:
+    void initSlides();
+
     void drawStats(SkCanvas* canvas);
 
     Window*      fWindow;
@@ -33,7 +36,8 @@ private:
     double fMeasurements[kMeasurementCount];
     int fCurrentMeasurement;
 
-    const skiagm::GMRegistry* fGMs;
+    SkTArray<sk_sp<Slide>> fSlides;
+    int                    fCurrentSlide;
 };