vtkCocoaRenderWindow crashes when initialized from outside main thread
Goal: Spawn a separate thread, construct a render window and call Render in this new thread.
Problem: It crashes on mac OS. Runs fine on Linux and windows though.
Turning on OffScreenBuffers also doesn't work. The solution might be to really work with offscreen OpenGL context without ever using Cocoa.
The test code:
int Start(int argc, char* argv[])
{
vtkLogger::SetThreadName("Render Thread");
std::hash<std::thread::id> tid_hash{};
uint32_t tid = tid_hash(std::this_thread::get_id());
vtkLog(INFO, << "Rendering on " << tid);
vtkNew<vtkRenderer> renderer;
vtkNew<vtkRenderWindow> renWin;
renWin->AddRenderer(renderer);
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin);
renderer->SetBackground(0.2, 0.3, 0.4);
renWin->SetSize(300, 300);
// interact with data
renWin->Render();
int retVal = vtkRegressionTestImage(renWin);
if (retVal == vtkRegressionTester::DO_INTERACTOR)
{
iren->Start();
}
return !retVal;
}
int TestRenderWindowDifferentThread(int argc, char* argv[])
{
std::launch policy = std::launch::deferred;
for (int i = 0; i < argc; ++i)
{
if (std::string(argv[i]) == "-async")
{
policy = std::launch::async;
break;
}
}
vtkLogger::SetStderrVerbosity(vtkLogger::VERBOSITY_INFO);
std::future<int> fut = std::async(policy, &Start, argc, argv);
std::hash<std::thread::id> tid_hash{};
uint32_t tid = tid_hash(std::this_thread::get_id());
vtkLog(INFO, << "Main thread " << tid);
int result = vtkRegressionTester::FAILED;
result = fut.get();
vtkLog(INFO, << "result=" << result);
return result;
}
Error:
./bin/vtkRenderingOpenGL2CxxTests TestRenderWindowDifferentThread -I -async
( 0.019s) [main thread ]TestRenderWindowDiffere:102 INFO| Main thread 3325499587
( 0.019s) [Render Thread ]TestRenderWindowDiffere:39 INFO| Rendering on 1198912523
2022-09-08 18:17:50.488 vtkRenderingOpenGL2CxxTests[41301:170884] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'NSWindow drag regions should only be invalidated on the Main Thread!'
*** First throw call stack:
(
0 CoreFoundation 0x00000001818e11a8 __exceptionPreprocess + 240
1 libobjc.A.dylib 0x000000018162be04 objc_exception_throw + 60
2 CoreFoundation 0x000000018190c128 _CFBundleGetValueForInfoKey + 0
3 AppKit 0x00000001843ef930 -[NSWindow(NSWindow_Theme) _postWindowNeedsToResetDragMarginsUnlessPostingDisabled] + 372
4 AppKit 0x00000001843da92c -[NSWindow _initContent:styleMask:backing:defer:contentView:] + 948
5 AppKit 0x00000001843da56c -[NSWindow initWithContentRect:styleMask:backing:defer:] + 56
6 libvtkRenderingOpenGL2-9.1.9.1.0.dy 0x000000010385520c _ZN20vtkCocoaRenderWindow13CreateAWindowEv + 1136
7 libvtkRenderingOpenGL2-9.1.9.1.0.dy 0x00000001038562cc _ZN20vtkCocoaRenderWindow10InitializeEv + 60
8 libvtkRenderingOpenGL2-9.1.9.1.0.dy 0x00000001039e3b00 _ZN21vtkOpenGLRenderWindow5StartEv + 52
9 libvtkRenderingOpenGL2-9.1.9.1.0.dy 0x00000001038561e4 _ZN20vtkCocoaRenderWindow5StartEv + 28
10 libvtkRenderingUI-9.1.9.1.0.dylib 0x0000000100c6d180 _ZN30vtkCocoaRenderWindowInteractor10InitializeEv + 444
11 libvtkRenderingCore-9.1.9.1.0.dylib 0x0000000106bba7d0 _ZN15vtkRenderWindow6RenderEv + 588
12 libvtkRenderingOpenGL2-9.1.9.1.0.dy 0x00000001039e75bc _ZN21vtkOpenGLRenderWindow6RenderEv + 112
13 vtkRenderingOpenGL2CxxTests 0x0000000100717434 _Z5StartiPPc + 1188
14 vtkRenderingOpenGL2CxxTests 0x0000000100719fd0 _ZNSt3__1L8__invokeIPFiiPPcEJiS2_EEEDTclscT_fp_spscT0_fp0_EEOS5_DpOS6_ + 52
15 vtkRenderingOpenGL2CxxTests 0x0000000100719f90 _ZNSt3__112__async_funcIPFiiPPcEJiS2_EE9__executeIJLm1ELm2EEEEiNS_15__tuple_indicesIJXspT_EEEE + 88
16 vtkRenderingOpenGL2CxxTests 0x0000000100719b74 _ZNSt3__112__async_funcIPFiiPPcEJiS2_EEclEv + 24
17 vtkRenderingOpenGL2CxxTests 0x00000001007196b0 _ZNSt3__119__async_assoc_stateIiNS_12__async_funcIPFiiPPcEJiS3_EEEE9__executeEv + 32
18 vtkRenderingOpenGL2CxxTests 0x000000010071af44 _ZNSt3__1L8__invokeIMNS_19__async_assoc_stateIiNS_12__async_funcIPFiiPPcEJiS4_EEEEEFvvEPS8_JEvEEDTcldsdescT0_fp0_fp_spscT1_fp1_EEOT_OSC_DpOSD_ + 112
19 vtkRenderingOpenGL2CxxTests 0x000000010071ae88 _ZNSt3__1L16__thread_executeINS_10unique_ptrINS_15__thread_structENS_14default_deleteIS2_EEEEMNS_19__async_assoc_stateIiNS_12__async_funcIPFiiPPcEJiS9_EEEEEFvvEJPSD_EJLm2EEEEvRNS_5tupleIJT_T0_DpT1_EEENS_15__tuple_indicesIJXspT2_EEEE + 56
20 vtkRenderingOpenGL2CxxTests 0x000000010071a5d4 _ZNSt3__1L14__thread_proxyINS_5tupleIJNS_10unique_ptrINS_15__thread_structENS_14default_deleteIS3_EEEEMNS_19__async_assoc_stateIiNS_12__async_funcIPFiiPPcEJiSA_EEEEEFvvEPSE_EEEEEPvSJ_ + 84
21 libsystem_pthread.dylib 0x000000018179426c _pthread_start + 148
22 libsystem_pthread.dylib 0x000000018178f08c thread_start + 8
)
Assertion failed: (NSViewIsCurrentlyBuildingLayerTreeForDisplay() != currentlyBuildingLayerTree), function NSViewSetCurrentlyBuildingLayerTreeForDisplay, file NSView.m, line 13477.
libc++abi: terminating with uncaught exception of type NSException
Loguru caught a signal: SIGABRT
Stack trace:
12 0x100b8108c 16 dyld 0x0000000100b8108c start + 520
11 0x100695480 main + 2476
10 0x1007179d8 TestRenderWindowDifferentThread(int, char**) + 516
9 0x100717da4 std::future<int>::get() + 60
8 0x10071c028 std::__assoc_state<int>::move() + 152
7 0x18174de40 std::terminate() + 64
6 0x18174dea4 std::__terminate(void (*)()) + 20
5 0x181634320 _objc_terminate() + 144
4 0x18173e950 demangling_unexpected_handler() + 0
3 0x18174eb08 __cxxabiv1::__aligned_malloc_with_fallback(unsigned long) + 0
2 0x1816ce340 abort + 168
1 0x181793ee0 pthread_kill + 288
0 0x1817ab4a4 _sigtramp + 56
( 0.110s) [main thread ] :0 FATL| Signal: SIGABRT
zsh: abort ./bin/vtkRenderingOpenGL2CxxTests TestRenderWindowDifferentThread -I -async
Edited by Jaswant Panchumarti (Kitware)