Fix frame pacing issues (#3032)

This commit is contained in:
Adrian Cojocaru
2024-11-26 18:53:41 +02:00
committed by GitHub
parent e394fcd4a4
commit 1a38075a1c
8 changed files with 32 additions and 12 deletions

View File

@@ -47,6 +47,8 @@ public:
void runOnce();
void stop();
void updateTime();
/// Platform integration callback for platforms that do not have full
/// run loop integration or don't want to block at the Mapbox GL Native
/// loop. It will be called from any thread and is up to the platform

View File

@@ -34,12 +34,13 @@ protected:
class SurfaceRenderableResource : public RenderableResource {
protected:
explicit SurfaceRenderableResource(RendererBackend& backend_)
: RenderableResource(backend_) {}
explicit SurfaceRenderableResource(RendererBackend& backend_, vk::PresentModeKHR mode = vk::PresentModeKHR::eFifo)
: RenderableResource(backend_),
presentMode(mode) {}
~SurfaceRenderableResource() override;
void initColor(uint32_t w, uint32_t h);
void initSwapchain(uint32_t w, uint32_t h, vk::PresentModeKHR presentMode = vk::PresentModeKHR::eFifo);
void initSwapchain(uint32_t w, uint32_t h);
void initDepthStencil();
@@ -73,6 +74,8 @@ public:
protected:
vk::UniqueSurfaceKHR surface;
vk::UniqueSwapchainKHR swapchain;
vk::PresentModeKHR presentMode;
vk::SurfaceCapabilitiesKHR capabilities;
uint32_t acquiredImageIndex{0};

View File

@@ -149,6 +149,12 @@ void RunLoop::stop() {
invoke([&] { uv_unref(impl->holderHandle()); });
}
void RunLoop::updateTime() {
MBGL_VERIFY_THREAD(tid);
uv_update_time(impl->loop);
}
void RunLoop::waitForEmpty([[maybe_unused]] const mbgl::util::SimpleIdentity tag) {
while (true) {
std::size_t remaining;

View File

@@ -1100,6 +1100,10 @@ void GLFWView::run() {
}
render();
#ifndef __APPLE__
runLoop.updateTime();
#endif
};
// Cap frame rate to 60hz if benchmark mode is disabled

View File

@@ -13,8 +13,9 @@
class GLFWVulkanRenderableResource final : public mbgl::vulkan::SurfaceRenderableResource {
public:
explicit GLFWVulkanRenderableResource(GLFWVulkanBackend& backend_)
: SurfaceRenderableResource(backend_) {}
explicit GLFWVulkanRenderableResource(GLFWVulkanBackend& backend_, bool capFrameRate)
: SurfaceRenderableResource(backend_,
capFrameRate ? vk::PresentModeKHR::eFifo : vk::PresentModeKHR::eImmediate) {}
std::vector<const char*> getDeviceExtensions() override { return {VK_KHR_SWAPCHAIN_EXTENSION_NAME}; }
@@ -34,7 +35,7 @@ public:
void bind() override {}
};
GLFWVulkanBackend::GLFWVulkanBackend(GLFWwindow* window_, const bool)
GLFWVulkanBackend::GLFWVulkanBackend(GLFWwindow* window_, const bool capFrameRate)
: mbgl::vulkan::RendererBackend(mbgl::gfx::ContextMode::Unique),
mbgl::vulkan::Renderable(
[window_] {
@@ -43,7 +44,7 @@ GLFWVulkanBackend::GLFWVulkanBackend(GLFWwindow* window_, const bool)
glfwGetFramebufferSize(window_, &fbWidth, &fbHeight);
return mbgl::Size{static_cast<uint32_t>(fbWidth), static_cast<uint32_t>(fbHeight)};
}(),
std::make_unique<GLFWVulkanRenderableResource>(*this)),
std::make_unique<GLFWVulkanRenderableResource>(*this, capFrameRate)),
window(window_) {
init();
}

View File

@@ -74,7 +74,7 @@ BufferResource::BufferResource(
VmaAllocationCreateInfo allocationInfo = {};
allocationInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_HOST;
allocationInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
allocationInfo.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
allocationInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT;

View File

@@ -71,7 +71,7 @@ void SurfaceRenderableResource::initColor(uint32_t w, uint32_t h) {
}
}
void SurfaceRenderableResource::initSwapchain(uint32_t w, uint32_t h, vk::PresentModeKHR presentMode) {
void SurfaceRenderableResource::initSwapchain(uint32_t w, uint32_t h) {
const auto& physicalDevice = backend.getPhysicalDevice();
const auto& device = backend.getDevice();

View File

@@ -97,7 +97,11 @@ std::unique_ptr<gfx::Context> RendererBackend::createContext() {
std::vector<const char*> RendererBackend::getLayers() {
return {
#ifdef ENABLE_VULKAN_VALIDATION
"VK_LAYER_KHRONOS_validation"
"VK_LAYER_KHRONOS_validation",
#endif
#ifdef _WIN32
"VK_LAYER_LUNARG_monitor",
#endif
};
}
@@ -561,9 +565,9 @@ void RendererBackend::initSwapchain() {
auto& renderableResource = renderable.getResource<SurfaceRenderableResource>();
const auto& size = renderable.getSize();
// use triple buffering if rendering to a surface
// buffer resources if rendering to a surface
// no buffering when using headless
maxFrames = renderableResource.getPlatformSurface() ? 3 : 1;
maxFrames = renderableResource.getPlatformSurface() ? 2 : 1;
renderableResource.init(size.width, size.height);