Fix a rare crash when running simulate on macOS.
The bug was introduced in 2f0fb1e4ef. The glfwSwapBuffers call should occur on the main UI thread, not the CoreVideo DisplayLink thread.
PiperOrigin-RevId: 517172202
Change-Id: I2491f2194765019748198cd0cc61ca9263331b01
This commit is contained in:
committed by
Copybara-Service
parent
230e2780de
commit
81ba9ec54a
@@ -175,14 +175,10 @@ bool GlfwAdapter::ShouldCloseWindow() const {
|
|||||||
void GlfwAdapter::SwapBuffers() {
|
void GlfwAdapter::SwapBuffers() {
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
if (core_video_.has_value()) {
|
if (core_video_.has_value()) {
|
||||||
core_video_->EnqueueSwap();
|
core_video_->WaitForDisplayRefresh();
|
||||||
core_video_->WaitForSwap();
|
|
||||||
} else {
|
|
||||||
Glfw().glfwSwapBuffers(window_);
|
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
Glfw().glfwSwapBuffers(window_);
|
|
||||||
#endif
|
#endif
|
||||||
|
Glfw().glfwSwapBuffers(window_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlfwAdapter::ToggleFullscreen() {
|
void GlfwAdapter::ToggleFullscreen() {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#error "This header only works on macOS."
|
#error "This header only works on macOS."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
@@ -37,8 +38,8 @@ class GlfwCoreVideo {
|
|||||||
public:
|
public:
|
||||||
GlfwCoreVideo(GLFWwindow* window);
|
GlfwCoreVideo(GLFWwindow* window);
|
||||||
~GlfwCoreVideo();
|
~GlfwCoreVideo();
|
||||||
void EnqueueSwap();
|
|
||||||
void WaitForSwap();
|
void WaitForDisplayRefresh();
|
||||||
int DisplayLinkCallback();
|
int DisplayLinkCallback();
|
||||||
void UpdateDisplayLink();
|
void UpdateDisplayLink();
|
||||||
|
|
||||||
@@ -46,7 +47,7 @@ class GlfwCoreVideo {
|
|||||||
GLFWwindow* window_;
|
GLFWwindow* window_;
|
||||||
CVDisplayLinkRef display_link_;
|
CVDisplayLinkRef display_link_;
|
||||||
|
|
||||||
bool second_buffer_has_content_;
|
std::atomic_bool waiting_;
|
||||||
std::mutex mu_;
|
std::mutex mu_;
|
||||||
std::condition_variable cond_;
|
std::condition_variable cond_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -45,23 +45,16 @@ GlfwCoreVideo::~GlfwCoreVideo() {
|
|||||||
CVDisplayLinkRelease(display_link_);
|
CVDisplayLinkRelease(display_link_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlfwCoreVideo::EnqueueSwap() {
|
void GlfwCoreVideo::WaitForDisplayRefresh() {
|
||||||
std::unique_lock lock(mu_);
|
std::unique_lock lock(mu_);
|
||||||
second_buffer_has_content_ = true;
|
waiting_.store(true);
|
||||||
}
|
cond_.wait(lock, [this]() { return !this->waiting_; });
|
||||||
|
|
||||||
void GlfwCoreVideo::WaitForSwap() {
|
|
||||||
if (second_buffer_has_content_) {
|
|
||||||
std::unique_lock lock(mu_);
|
|
||||||
cond_.wait(lock, [this]() { return !this->second_buffer_has_content_; });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int GlfwCoreVideo::DisplayLinkCallback() {
|
int GlfwCoreVideo::DisplayLinkCallback() {
|
||||||
if (second_buffer_has_content_) {
|
if (waiting_.load()) {
|
||||||
std::unique_lock lock(mu_);
|
std::unique_lock lock(mu_);
|
||||||
Glfw().glfwSwapBuffers(window_);
|
waiting_.store(false);
|
||||||
second_buffer_has_content_ = false;
|
|
||||||
cond_.notify_one();
|
cond_.notify_one();
|
||||||
}
|
}
|
||||||
return kCVReturnSuccess;
|
return kCVReturnSuccess;
|
||||||
|
|||||||
Reference in New Issue
Block a user