Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix frame pacing issues #3032

Merged
merged 5 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/mbgl/util/run_loop.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class RunLoop : public Scheduler, private util::noncopyable {
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
Expand Down
9 changes: 6 additions & 3 deletions include/mbgl/vulkan/renderable_resource.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,13 @@ class RenderableResource : public gfx::RenderableResource {

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();

Expand Down Expand Up @@ -73,6 +74,8 @@ class SurfaceRenderableResource : public RenderableResource {
protected:
vk::UniqueSurfaceKHR surface;
vk::UniqueSwapchainKHR swapchain;
vk::PresentModeKHR presentMode;

vk::SurfaceCapabilitiesKHR capabilities;

uint32_t acquiredImageIndex{0};
Expand Down
6 changes: 6 additions & 0 deletions platform/default/src/mbgl/util/run_loop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions platform/glfw/glfw_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,10 @@ void GLFWView::run() {
}

render();

#ifndef __APPLE__
runLoop.updateTime();
#endif
};

// Cap frame rate to 60hz if benchmark mode is disabled
Expand Down
9 changes: 5 additions & 4 deletions platform/glfw/glfw_vulkan_backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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}; }

Expand All @@ -34,7 +35,7 @@ class GLFWVulkanRenderableResource final : public mbgl::vulkan::SurfaceRenderabl
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_] {
Expand All @@ -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();
}
Expand Down
2 changes: 1 addition & 1 deletion src/mbgl/vulkan/buffer_resource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion src/mbgl/vulkan/renderable_resource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
10 changes: 7 additions & 3 deletions src/mbgl/vulkan/renderer_backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
};
}
Expand Down Expand Up @@ -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);

Expand Down
Loading