fix-3.13.9-crash-windows-angle-context-frameBuffer
MixinNetwork/flutter-plugins#283
Crash description
SuerfaceFrame::Submit()requiresframebufferto be notnullptr.
Framebuffer *framebuffer = state.getDrawFramebuffer();
ASSERT(framebuffer);
if (context->getLimitations().noSeparateStencilRefsAndMasks ||
extensions.webglCompatibilityANGLE)
{
ASSERT(framebuffer);
const FramebufferAttachment *dsAttachment =
framebuffer->getStencilOrDepthStencilAttachment();
const GLuint stencilBits = dsAttachment ? dsAttachment->getStencilSize() : 0;
ASSERT(stencilBits <= 8);
...FlutterViewControllerwill resetframeBufferby callingState::setDrawFramebufferBinding()
Crash case
SurfaceFrame::Submit() -> OpsTask::onExecute() -> [ renderPass->begin(); chain.head()->execute(flushState, chain.bounds()); ]
renderPass->begin(); will prepare the framebuffer, then chain.head()->execute(flushState, chain.bounds()); will execute with no error.
But there's no guarantee that no other threads call State::setDrawFramebufferBinding() between the two calls.
No crash case
If State::setDrawFramebufferBinding() is not executed between renderPass->begin(); and chain.head()->execute(flushState, chain.bounds());
Thread 1 | Thread2
-------------------------------------------------------------------------------------------------------------------------
OpsTask::onExecute() |
|
renderPass->begin(); |
|
chain.head()->execute(flushState, chain.bounds()); |
|
| State::setDrawFramebufferBinding() from FlutterViewController()
Crash case
Thread 1 | Thread2
-------------------------------------------------------------------------------------------------------------------------
OpsTask::onExecute() |
|
renderPass->begin(); |
|
| State::setDrawFramebufferBinding() from FlutterViewController()
|
chain.head()->execute(flushState, chain.bounds()); |
|
Crash
https://github.com/google/angle/blob/eebf069c1d98952c9cde6f4e5f81383736b10163/src/libANGLE/validationES.cpp#L4124
Callstacks
Crash callstack
See the image attached in MixinNetwork/flutter-plugins#283.
Reset frameBuffer
Creating FlutterViewController will cause the global render context to reset the framebuffer by calling EGL_MakeCurrent then ANGLE_TRY(unsetDefaultFramebuffer());
State::setDrawFramebufferBinding 15424, 000001EA9A854AB0, framebuffer: 0000000000000000
[0] gl::State::setDrawFramebufferBinding
[1] gl::Context::unsetDefaultFramebuffer
[2] gl::Context::unMakeCurrent
[3] egl::Display::makeCurrent
[4] egl::MakeCurrent
[5] EGL_MakeCurrent
[6] flutter::AngleSurfaceManager::SetVSyncEnabled
[7] flutter::AngleSurfaceManager::CreateSurface
[8] flutter::FlutterWindowsView::CreateRenderSurface
[9] FlutterDesktopViewControllerCreate
[10] DesktopMultiWindowSetWindowCreatedCallback
[11] DesktopMultiWindowPluginRegisterWithRegistrar
[12] DesktopMultiWindowPluginRegisterWithRegistrar
[13] DesktopMultiWindowPluginRegisterWithRegistrar
[14] DesktopMultiWindowPluginRegisterWithRegistrar
[15] DesktopMultiWindowPluginRegisterWithRegistrar
[16] DesktopMultiWindowPluginRegisterWithRegistrar
[17] DesktopMultiWindowSetWindowCreatedCallback
[18] flutter::IncomingMessageDispatcher::HandleMessage
[19] flutter::FlutterWindowsEngine::HandlePlatformMessage
[20] std::_Func_impl_no_alloc<`lambda at ../../flutter/shell/platform/embedder/embedder.cc:1874:9',void,std::unique_ptr<flutter::PlatformMessage,std::default_delete<flutter::PlatformMessage> > >::_Do_call
[21] std::_Func_class<void,std::unique_ptr<flutter::PlatformMessage,std::default_delete<flutter::PlatformMessage> > >::operator()
[22] flutter::PlatformViewEmbedder::HandlePlatformMessage
[23] fml::internal::CopyableLambda<`lambda at ../../flutter/shell/platform/embedder/platform_view_embedder.cc:24:9'>::operator()<>
[24] flutter::EmbedderTaskRunner::PostTask
[25] flutter::EmbedderThreadHost::PostTask
[26] FlutterEngineRunTask
[27] std::_Func_impl_no_alloc<`lambda at ../../flutter/shell/platform/windows/flutter_windows_engine.cc:171:41',void,const FlutterTask *>::_Do_call
[28] flutter::TaskRunner::ProcessTasks
[29] flutter::TaskRunnerWindow::ProcessTasks
[30] flutter::TaskRunnerWindow::HandleMessage
[31] CallWindowProcW
[32] DispatchMessageW
[33] DispatchMessageW
[34] DispatchMessageW
[35] BaseThreadInitThunk
[36] RtlUserThreadStart