Commit ceefcca7 authored by Zhiyi Zhang's avatar Zhiyi Zhang Committed by Alexandre Julliard

winemac.drv: Update OpenGL context immediately after the window content view is visible.

Fix errors such as GL_FRAMEBUFFER_UNDEFINED and GL_INVALID_FRAMEBUFFER_OPERATION for OpenGL functions when the default framebuffer 0 is bound on macOS. These errors happen because the NSOpenGLContext doesn't have a view bound at the time of an OpenGL call. The view could not be set for the NSOpenGLContext because the window or view can still be invisible. Setting an invisible view for the NSOpenGLContext can generate invalid drawable messages as 682ed910 has shown. Thus setting the view could be deferred because the NSOpenGLContext needs a visible view. However, right after the window becomes visible, an OpenGL function that involves the default framebuffer can be called. And when the view is still not set at the time of the OpenGL call, errors such as GL_FRAMEBUFFER_UNDEFINED and GL_INVALID_FRAMEBUFFER_OPERATION could happen and result in rendering errors such as black screen. So we need to set the view for the NSOpenGLContext as soon as the view becomes visible. It's possible that the window and view are still invisible when OpenGL functions involving the default framebuffer get called. In such cases, I think errors like GL_FRAMEBUFFER_UNDEFINED are justified on macOS. Fix Active Trader Pro black screen at launch on macOS. The application creates a d3d9 device with an invisible window. And then it shows the window before calling d3d9_swapchain_Present(). So all the [NSOpenGLContext setView] opportunities are missed and no view is set. Then when glBlitFramebuffer() gets called, GL_FRAMEBUFFER_UNDEFINED happens and so nothing is rendered. The application only renders one frame before login so the window remains black.
parent 1cbc85c4
...@@ -1415,7 +1415,6 @@ static void test_framebuffer(void) ...@@ -1415,7 +1415,6 @@ static void test_framebuffer(void)
pglBindFramebuffer(GL_FRAMEBUFFER, 0); pglBindFramebuffer(GL_FRAMEBUFFER, 0);
status = pglCheckFramebufferStatus(GL_FRAMEBUFFER); status = pglCheckFramebufferStatus(GL_FRAMEBUFFER);
todo_wine_if(status == GL_FRAMEBUFFER_UNDEFINED) /* macOS */
ok(status == GL_FRAMEBUFFER_COMPLETE, "Expected %#x, got %#x.\n", GL_FRAMEBUFFER_COMPLETE, status); ok(status == GL_FRAMEBUFFER_COMPLETE, "Expected %#x, got %#x.\n", GL_FRAMEBUFFER_COMPLETE, status);
ret = wglMakeCurrent(NULL, NULL); ret = wglMakeCurrent(NULL, NULL);
......
...@@ -83,7 +83,12 @@ ...@@ -83,7 +83,12 @@
macdrv_set_view_backing_size((macdrv_view)self.view, view_backing); macdrv_set_view_backing_size((macdrv_view)self.view, view_backing);
NSView* save = self.view; NSView* save = self.view;
OnMainThread(^{ if ([NSThread isMainThread])
{
[super clearDrawable];
[super setView:save];
}
else OnMainThread(^{
[super clearDrawable]; [super clearDrawable];
[super setView:save]; [super setView:save];
}); });
......
...@@ -570,6 +570,7 @@ static CVReturn WineDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTi ...@@ -570,6 +570,7 @@ static CVReturn WineDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTi
clearedGlSurface = TRUE; clearedGlSurface = TRUE;
} }
context.needsUpdate = TRUE; context.needsUpdate = TRUE;
macdrv_update_opengl_context(context);
} }
[glContexts addObjectsFromArray:pendingGlContexts]; [glContexts addObjectsFromArray:pendingGlContexts];
[pendingGlContexts removeAllObjects]; [pendingGlContexts removeAllObjects];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment