macOS: fix flash of red upon resize.
Previous to this change, we suffered from a flash-of-red followed by a flash-with-wrong-projection every time we resized an OpenGL window. SDL throttles the window resize events, so FilamentApp updates the View only on the final low-level resize event. However we were calling Cocoa's update method on every low-level resize event. Thus we were showing uninitialized content during the resize. FilamentApp recreates the SwapChain after the final resize event; one reason for this is the fact that Vulkan swap chains must be recreated. The fix is to defer the Cocoa update until the swap chain gets recreated. This is the perfect time because FilamentApp has already set the new Viewport at this point.
This commit is contained in:
@@ -36,7 +36,6 @@ using namespace backend;
|
||||
struct PlatformCocoaGLImpl {
|
||||
NSOpenGLContext* mGLContext = nullptr;
|
||||
NSView* mCurrentView = nullptr;
|
||||
id<NSObject> mObserver = nullptr;
|
||||
std::vector<NSView*> mHeadlessSwapChains;
|
||||
};
|
||||
|
||||
@@ -75,7 +74,6 @@ Driver* PlatformCocoaGL::createDriver(void* sharedContext) noexcept {
|
||||
}
|
||||
|
||||
void PlatformCocoaGL::terminate() noexcept {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver: pImpl->mObserver];
|
||||
pImpl->mGLContext = nil;
|
||||
bluegl::unbind();
|
||||
}
|
||||
@@ -83,6 +81,15 @@ void PlatformCocoaGL::terminate() noexcept {
|
||||
Platform::SwapChain* PlatformCocoaGL::createSwapChain(void* nativewindow, uint64_t& flags) noexcept {
|
||||
// Transparent SwapChain is not supported
|
||||
flags &= ~backend::SWAP_CHAIN_CONFIG_TRANSPARENT;
|
||||
NSView* nsView = (__bridge NSView*)nativewindow;
|
||||
|
||||
// If the SwapChain is being recreated (e.g. if the underlying surface has been resized),
|
||||
// then we need to force an update to occur in the subsequent makeCurrent, which can be done by
|
||||
// simply resetting the current view. In multi-window situations, this happens automatically.
|
||||
if (pImpl->mCurrentView == nsView) {
|
||||
pImpl->mCurrentView = nullptr;
|
||||
}
|
||||
|
||||
return (SwapChain*) nativewindow;
|
||||
}
|
||||
|
||||
@@ -116,23 +123,9 @@ void PlatformCocoaGL::makeCurrent(Platform::SwapChain* drawSwapChain,
|
||||
// arrival of macOS 10.15 (Catalina). If we were to call these methods from the GL thread,
|
||||
// we would see EXC_BAD_INSTRUCTION.
|
||||
|
||||
// Remove the old observer because this might be a multi-window app.
|
||||
[[NSNotificationCenter defaultCenter] removeObserver: pImpl->mObserver];
|
||||
|
||||
// Create a copy of the current GL context pointer for the closure.
|
||||
NSOpenGLContext* glContext = pImpl->mGLContext;
|
||||
|
||||
pImpl->mObserver = [
|
||||
[NSNotificationCenter defaultCenter] addObserverForName: NSViewGlobalFrameDidChangeNotification
|
||||
object: nil
|
||||
queue: nil
|
||||
usingBlock: ^ (NSNotification* note) {
|
||||
if (note.object == nsView) {
|
||||
[glContext update];
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
dispatch_sync(dispatch_get_main_queue(), ^(void) {
|
||||
[glContext setView:nsView];
|
||||
[glContext update];
|
||||
|
||||
Reference in New Issue
Block a user