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
This commit is contained in:
parent
312398159c
commit
3d6ed3ae75
@ -24,6 +24,7 @@
|
|||||||
'../src/gpu',
|
'../src/gpu',
|
||||||
'../src/images',
|
'../src/images',
|
||||||
'../src/image',
|
'../src/image',
|
||||||
|
'../tools/timer',
|
||||||
],
|
],
|
||||||
'sources': [
|
'sources': [
|
||||||
'../gm/gm.cpp',
|
'../gm/gm.cpp',
|
||||||
|
@ -14,7 +14,7 @@ public:
|
|||||||
|
|
||||||
virtual ~Application() {}
|
virtual ~Application() {}
|
||||||
|
|
||||||
virtual void onIdle(float dt) = 0;
|
virtual void onIdle(double ms) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -66,7 +66,7 @@ void VulkanTestContext::initializeContext(void* platformData) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SkASSERT(0 <= fPresentQueueIndex && fPresentQueueIndex < queueCount);
|
SkASSERT(fPresentQueueIndex < queueCount);
|
||||||
|
|
||||||
VkBool32 supported;
|
VkBool32 supported;
|
||||||
VkResult res = GR_VK_CALL(fBackendContext->fInterface,
|
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_INHERIT_BIT_KHR :
|
||||||
VK_COMPOSITE_ALPHA_OPAQUE_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;
|
VkPresentModeKHR mode = VK_PRESENT_MODE_FIFO_KHR;
|
||||||
bool vsync = false;
|
|
||||||
for (uint32_t i = 0; i < presentModeCount; ++i) {
|
for (uint32_t i = 0; i < presentModeCount; ++i) {
|
||||||
if ((vsync && VK_PRESENT_MODE_MAILBOX_KHR == presentModes[i]) ||
|
// use mailbox
|
||||||
(!vsync && VK_PRESENT_MODE_IMMEDIATE_KHR == presentModes[i])) {
|
if (VK_PRESENT_MODE_MAILBOX_KHR == presentModes[i]) {
|
||||||
mode = presentModes[i];
|
mode = presentModes[i];
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,9 +448,10 @@ SkSurface* VulkanTestContext::getBackbufferSurface() {
|
|||||||
&backbuffer->fImageIndex));
|
&backbuffer->fImageIndex));
|
||||||
if (VK_ERROR_SURFACE_LOST_KHR == res) {
|
if (VK_ERROR_SURFACE_LOST_KHR == res) {
|
||||||
// need to figure out how to create a new vkSurface without the platformData*
|
// need to figure out how to create a new vkSurface without the platformData*
|
||||||
|
// maybe use attach somehow? but need a Window
|
||||||
return nullptr;
|
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
|
// tear swapchain down and try again
|
||||||
if (!this->createSwapchain(0, 0)) {
|
if (!this->createSwapchain(0, 0)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -61,6 +61,8 @@ void Window::onPaint() {
|
|||||||
canvas->flush();
|
canvas->flush();
|
||||||
|
|
||||||
fTestContext->swapBuffers();
|
fTestContext->swapBuffers();
|
||||||
|
} else {
|
||||||
|
// try recreating testcontext
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -27,12 +27,12 @@ public:
|
|||||||
int fStencilBits;
|
int fStencilBits;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BackEndTypes {
|
enum BackEndType {
|
||||||
kNativeGL_BackendType,
|
kNativeGL_BackendType,
|
||||||
kVulkan_BackendType
|
kVulkan_BackendType
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual bool attach(BackEndTypes attachType, int msaaSampleCount, AttachmentInfo*) = 0;
|
virtual bool attach(BackEndType attachType, int msaaSampleCount, AttachmentInfo*) = 0;
|
||||||
void detach();
|
void detach();
|
||||||
|
|
||||||
// input handling
|
// input handling
|
||||||
|
@ -31,8 +31,10 @@ static void on_paint_handler(SkCanvas* canvas, void* userData) {
|
|||||||
return vv->onPaint(canvas);
|
return vv->onPaint(canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
VulkanViewer::VulkanViewer(int argc, char** argv, void* platformData) :
|
VulkanViewer::VulkanViewer(int argc, char** argv, void* platformData)
|
||||||
fGMs(skiagm::GMRegistry::Head()){
|
: fGMs(skiagm::GMRegistry::Head())
|
||||||
|
, fCurrentMeasurement(0) {
|
||||||
|
memset(fMeasurements, 0, sizeof(fMeasurements));
|
||||||
|
|
||||||
fWindow = Window::CreateNativeWindow(platformData);
|
fWindow = Window::CreateNativeWindow(platformData);
|
||||||
fWindow->attach(Window::kVulkan_BackendType, 0, nullptr);
|
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->registerKeyFunc(on_key_handler, this);
|
||||||
fWindow->registerPaintFunc(on_paint_handler, this);
|
fWindow->registerPaintFunc(on_paint_handler, this);
|
||||||
|
|
||||||
fWindow->setTitle("VulkanViewer");
|
SkAutoTDelete<skiagm::GM> gm(fGMs->factory()(nullptr));
|
||||||
|
SkString title("VulkanViewer: ");
|
||||||
|
title.append(gm->getName());
|
||||||
|
fWindow->setTitle(title.c_str());
|
||||||
fWindow->show();
|
fWindow->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,6 +59,10 @@ bool VulkanViewer::onKey(Window::Key key, Window::InputState state, uint32_t mod
|
|||||||
if (Window::kDown_InputState == state && (modifiers & Window::kFirstPress_ModifierKey) &&
|
if (Window::kDown_InputState == state && (modifiers & Window::kFirstPress_ModifierKey) &&
|
||||||
key == Window::kRight_Key) {
|
key == Window::kRight_Key) {
|
||||||
fGMs = fGMs->next();
|
fGMs = fGMs->next();
|
||||||
|
SkAutoTDelete<skiagm::GM> gm(fGMs->factory()(nullptr));
|
||||||
|
SkString title("VulkanViewer: ");
|
||||||
|
title.append(gm->getName());
|
||||||
|
fWindow->setTitle(title.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -63,12 +72,59 @@ void VulkanViewer::onPaint(SkCanvas* canvas) {
|
|||||||
SkAutoTDelete<skiagm::GM> gm(fGMs->factory()(nullptr));
|
SkAutoTDelete<skiagm::GM> gm(fGMs->factory()(nullptr));
|
||||||
|
|
||||||
canvas->save();
|
canvas->save();
|
||||||
|
|
||||||
gm->draw(canvas);
|
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();
|
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();
|
fWindow->onPaint();
|
||||||
}
|
}
|
||||||
|
@ -22,11 +22,17 @@ public:
|
|||||||
bool onKey(Window::Key key, Window::InputState state, uint32_t modifiers);
|
bool onKey(Window::Key key, Window::InputState state, uint32_t modifiers);
|
||||||
void onPaint(SkCanvas* canvas);
|
void onPaint(SkCanvas* canvas);
|
||||||
|
|
||||||
void onIdle(float dt) override;
|
void onIdle(double ms) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void drawStats(SkCanvas* canvas);
|
||||||
|
|
||||||
Window* fWindow;
|
Window* fWindow;
|
||||||
|
|
||||||
|
static const int kMeasurementCount = 64; // should be power of 2 for fast mod
|
||||||
|
double fMeasurements[kMeasurementCount];
|
||||||
|
int fCurrentMeasurement;
|
||||||
|
|
||||||
const skiagm::GMRegistry* fGMs;
|
const skiagm::GMRegistry* fGMs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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) {
|
if (kVulkan_BackendType != attachType) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ public:
|
|||||||
void setTitle(const char*) override;
|
void setTitle(const char*) override;
|
||||||
void show() override;
|
void show() override;
|
||||||
|
|
||||||
bool attach(BackEndTypes attachType, int msaaSampleCount, AttachmentInfo*) override;
|
bool attach(BackEndType attachType, int msaaSampleCount, AttachmentInfo*) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HINSTANCE fHInstance;
|
HINSTANCE fHInstance;
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
|
|
||||||
#include "SkTypes.h"
|
#include "SkTypes.h"
|
||||||
|
#include "Timer.h"
|
||||||
#include "Window_win.h"
|
#include "Window_win.h"
|
||||||
#include "../Application.h"
|
#include "../Application.h"
|
||||||
|
|
||||||
@ -24,6 +25,8 @@ static char* tchar_to_utf8(const TCHAR* str) {
|
|||||||
#endif
|
#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().
|
// 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);
|
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);
|
Application* app = Application::Create(argc, argv, (void*)hInstance);
|
||||||
|
|
||||||
MSG msg = { 0 };
|
MSG msg = { 0 };
|
||||||
|
|
||||||
|
double currentTime = 0.0;
|
||||||
|
double previousTime = 0.0;
|
||||||
|
|
||||||
// Main message loop
|
// Main message loop
|
||||||
while (WM_QUIT != msg.message) {
|
while (WM_QUIT != msg.message) {
|
||||||
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
|
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);
|
DispatchMessage(&msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
app->onIdle(0.0f);
|
previousTime = currentTime;
|
||||||
|
currentTime = now_ms();
|
||||||
|
app->onIdle(currentTime - previousTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete app;
|
delete app;
|
||||||
|
Loading…
Reference in New Issue
Block a user