From 3d6ed3ae75e45b36f92d7555893953f519c2a63d Mon Sep 17 00:00:00 2001 From: jvanverth Date: Thu, 7 Apr 2016 11:09:51 -0700 Subject: Some more improvements/fixes to the VulkanViewer * display GM name in title bar * add ms timer for update loop * add ms/frame meter * fix vsync * add some notes for later GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1873453002 Review URL: https://codereview.chromium.org/1873453002 --- tools/vulkan/Application.h | 2 +- tools/vulkan/VulkanTestContext.cpp | 14 ++++---- tools/vulkan/Window.cpp | 2 ++ tools/vulkan/Window.h | 4 +-- tools/vulkan/viewer/VulkanViewer.cpp | 68 ++++++++++++++++++++++++++++++++---- tools/vulkan/viewer/VulkanViewer.h | 8 ++++- tools/vulkan/win/Window_win.cpp | 2 +- tools/vulkan/win/Window_win.h | 2 +- tools/vulkan/win/main_win.cpp | 11 +++++- 9 files changed, 94 insertions(+), 19 deletions(-) (limited to 'tools') diff --git a/tools/vulkan/Application.h b/tools/vulkan/Application.h index 623496d502..4504d177e4 100644 --- a/tools/vulkan/Application.h +++ b/tools/vulkan/Application.h @@ -14,7 +14,7 @@ public: virtual ~Application() {} - virtual void onIdle(float dt) = 0; + virtual void onIdle(double ms) = 0; }; #endif diff --git a/tools/vulkan/VulkanTestContext.cpp b/tools/vulkan/VulkanTestContext.cpp index f9f037daec..05ebfe770d 100644 --- a/tools/vulkan/VulkanTestContext.cpp +++ b/tools/vulkan/VulkanTestContext.cpp @@ -66,7 +66,7 @@ void VulkanTestContext::initializeContext(void* platformData) { break; } } - SkASSERT(0 <= fPresentQueueIndex && fPresentQueueIndex < queueCount); + SkASSERT(fPresentQueueIndex < queueCount); VkBool32 supported; VkResult res = GR_VK_CALL(fBackendContext->fInterface, @@ -184,13 +184,14 @@ bool VulkanTestContext::createSwapchain(uint32_t width, uint32_t height) VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR : VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; - // FIFO is the only mode universally supported + // If mailbox mode is available, use it, as it is the lowest-latency non- + // tearing mode. If not, fall back to FIFO which is always available. VkPresentModeKHR mode = VK_PRESENT_MODE_FIFO_KHR; - bool vsync = false; for (uint32_t i = 0; i < presentModeCount; ++i) { - if ((vsync && VK_PRESENT_MODE_MAILBOX_KHR == presentModes[i]) || - (!vsync && VK_PRESENT_MODE_IMMEDIATE_KHR == presentModes[i])) { + // use mailbox + if (VK_PRESENT_MODE_MAILBOX_KHR == presentModes[i]) { mode = presentModes[i]; + break; } } @@ -447,9 +448,10 @@ SkSurface* VulkanTestContext::getBackbufferSurface() { &backbuffer->fImageIndex)); if (VK_ERROR_SURFACE_LOST_KHR == res) { // need to figure out how to create a new vkSurface without the platformData* + // maybe use attach somehow? but need a Window return nullptr; } - if (VK_ERROR_OUT_OF_DATE_KHR == res || VK_ERROR_SURFACE_LOST_KHR == res) { + if (VK_ERROR_OUT_OF_DATE_KHR == res) { // tear swapchain down and try again if (!this->createSwapchain(0, 0)) { return nullptr; diff --git a/tools/vulkan/Window.cpp b/tools/vulkan/Window.cpp index 86f181496d..2741f4da4c 100644 --- a/tools/vulkan/Window.cpp +++ b/tools/vulkan/Window.cpp @@ -61,6 +61,8 @@ void Window::onPaint() { canvas->flush(); fTestContext->swapBuffers(); + } else { + // try recreating testcontext } } diff --git a/tools/vulkan/Window.h b/tools/vulkan/Window.h index dbfe4e1e71..f7b4f132ad 100644 --- a/tools/vulkan/Window.h +++ b/tools/vulkan/Window.h @@ -27,12 +27,12 @@ public: int fStencilBits; }; - enum BackEndTypes { + enum BackEndType { kNativeGL_BackendType, kVulkan_BackendType }; - virtual bool attach(BackEndTypes attachType, int msaaSampleCount, AttachmentInfo*) = 0; + virtual bool attach(BackEndType attachType, int msaaSampleCount, AttachmentInfo*) = 0; void detach(); // input handling diff --git a/tools/vulkan/viewer/VulkanViewer.cpp b/tools/vulkan/viewer/VulkanViewer.cpp index 27e7b1c082..5c6e780f95 100644 --- a/tools/vulkan/viewer/VulkanViewer.cpp +++ b/tools/vulkan/viewer/VulkanViewer.cpp @@ -31,8 +31,10 @@ 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()){ +VulkanViewer::VulkanViewer(int argc, char** argv, void* platformData) + : fGMs(skiagm::GMRegistry::Head()) + , fCurrentMeasurement(0) { + memset(fMeasurements, 0, sizeof(fMeasurements)); fWindow = Window::CreateNativeWindow(platformData); fWindow->attach(Window::kVulkan_BackendType, 0, nullptr); @@ -41,7 +43,10 @@ VulkanViewer::VulkanViewer(int argc, char** argv, void* platformData) : fWindow->registerKeyFunc(on_key_handler, this); fWindow->registerPaintFunc(on_paint_handler, this); - fWindow->setTitle("VulkanViewer"); + SkAutoTDelete gm(fGMs->factory()(nullptr)); + SkString title("VulkanViewer: "); + title.append(gm->getName()); + fWindow->setTitle(title.c_str()); fWindow->show(); } @@ -54,7 +59,11 @@ bool VulkanViewer::onKey(Window::Key key, Window::InputState state, uint32_t mod if (Window::kDown_InputState == state && (modifiers & Window::kFirstPress_ModifierKey) && key == Window::kRight_Key) { fGMs = fGMs->next(); - } + SkAutoTDelete gm(fGMs->factory()(nullptr)); + SkString title("VulkanViewer: "); + title.append(gm->getName()); + fWindow->setTitle(title.c_str()); + } return true; } @@ -63,12 +72,59 @@ void VulkanViewer::onPaint(SkCanvas* canvas) { SkAutoTDelete gm(fGMs->factory()(nullptr)); canvas->save(); - gm->draw(canvas); + canvas->restore(); + + drawStats(canvas); +} + +void VulkanViewer::drawStats(SkCanvas* canvas) { + static const float kPixelPerMS = 2.0f; + static const int kDisplayWidth = 130; + static const int kDisplayHeight = 100; + static const int kDisplayPadding = 10; + static const int kGraphPadding = 3; + static const SkScalar kBaseMS = 1000.f / 60.f; // ms/frame to hit 60 fps + + SkISize canvasSize = canvas->getDeviceSize(); + SkRect rect = SkRect::MakeXYWH(SkIntToScalar(canvasSize.fWidth-kDisplayWidth-kDisplayPadding), + SkIntToScalar(kDisplayPadding), + SkIntToScalar(kDisplayWidth), SkIntToScalar(kDisplayHeight)); + SkPaint paint; + canvas->save(); + + canvas->clipRect(rect); + paint.setColor(SK_ColorBLACK); + canvas->drawRect(rect, paint); + // draw the 16ms line + paint.setColor(SK_ColorLTGRAY); + canvas->drawLine(rect.fLeft, rect.fBottom - kBaseMS*kPixelPerMS, + rect.fRight, rect.fBottom - kBaseMS*kPixelPerMS, paint); + paint.setColor(SK_ColorRED); + paint.setStyle(SkPaint::kStroke_Style); + canvas->drawRect(rect, paint); + + int x = SkScalarTruncToInt(rect.fLeft) + kGraphPadding; + const int xStep = 2; + const int startY = SkScalarTruncToInt(rect.fBottom); + int i = fCurrentMeasurement; + do { + int endY = startY - (int)(fMeasurements[i] * kPixelPerMS + 0.5); // round to nearest value + canvas->drawLine(SkIntToScalar(x), SkIntToScalar(startY), + SkIntToScalar(x), SkIntToScalar(endY), paint); + i++; + i &= (kMeasurementCount - 1); // fast mod + x += xStep; + } while (i != fCurrentMeasurement); canvas->restore(); } -void VulkanViewer::onIdle(float dt) { +void VulkanViewer::onIdle(double ms) { + // Record measurements + fMeasurements[fCurrentMeasurement++] = ms; + fCurrentMeasurement &= (kMeasurementCount - 1); // fast mod + SkASSERT(fCurrentMeasurement < kMeasurementCount); + fWindow->onPaint(); } diff --git a/tools/vulkan/viewer/VulkanViewer.h b/tools/vulkan/viewer/VulkanViewer.h index 29cbbef16e..b012cf1cdd 100644 --- a/tools/vulkan/viewer/VulkanViewer.h +++ b/tools/vulkan/viewer/VulkanViewer.h @@ -22,11 +22,17 @@ public: bool onKey(Window::Key key, Window::InputState state, uint32_t modifiers); void onPaint(SkCanvas* canvas); - void onIdle(float dt) override; + void onIdle(double ms) override; private: + void drawStats(SkCanvas* canvas); + Window* fWindow; + static const int kMeasurementCount = 64; // should be power of 2 for fast mod + double fMeasurements[kMeasurementCount]; + int fCurrentMeasurement; + const skiagm::GMRegistry* fGMs; }; diff --git a/tools/vulkan/win/Window_win.cpp b/tools/vulkan/win/Window_win.cpp index 0c9e80227e..06238393dd 100644 --- a/tools/vulkan/win/Window_win.cpp +++ b/tools/vulkan/win/Window_win.cpp @@ -262,7 +262,7 @@ void Window_win::show() { } -bool Window_win::attach(BackEndTypes attachType, int msaaSampleCount, AttachmentInfo*) { +bool Window_win::attach(BackEndType attachType, int msaaSampleCount, AttachmentInfo*) { if (kVulkan_BackendType != attachType) { return false; } diff --git a/tools/vulkan/win/Window_win.h b/tools/vulkan/win/Window_win.h index 4a5b7ff608..6b95b56d2c 100644 --- a/tools/vulkan/win/Window_win.h +++ b/tools/vulkan/win/Window_win.h @@ -21,7 +21,7 @@ public: void setTitle(const char*) override; void show() override; - bool attach(BackEndTypes attachType, int msaaSampleCount, AttachmentInfo*) override; + bool attach(BackEndType attachType, int msaaSampleCount, AttachmentInfo*) override; private: HINSTANCE fHInstance; diff --git a/tools/vulkan/win/main_win.cpp b/tools/vulkan/win/main_win.cpp index 34e522a952..883b96df9b 100644 --- a/tools/vulkan/win/main_win.cpp +++ b/tools/vulkan/win/main_win.cpp @@ -9,6 +9,7 @@ #include #include "SkTypes.h" +#include "Timer.h" #include "Window_win.h" #include "../Application.h" @@ -24,6 +25,8 @@ static char* tchar_to_utf8(const TCHAR* str) { #endif } +static double now_ms() { return SkTime::GetNSecs() * 1e-6; } + // This file can work with GUI or CONSOLE subsystem types since we define _tWinMain and main(). static int main_common(HINSTANCE hInstance, int show, int argc, char**argv); @@ -60,6 +63,10 @@ static int main_common(HINSTANCE hInstance, int show, int argc, char**argv) { Application* app = Application::Create(argc, argv, (void*)hInstance); MSG msg = { 0 }; + + double currentTime = 0.0; + double previousTime = 0.0; + // Main message loop while (WM_QUIT != msg.message) { if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) { @@ -67,7 +74,9 @@ static int main_common(HINSTANCE hInstance, int show, int argc, char**argv) { DispatchMessage(&msg); } - app->onIdle(0.0f); + previousTime = currentTime; + currentTime = now_ms(); + app->onIdle(currentTime - previousTime); } delete app; -- cgit v1.2.3