From 9698c3d600be15d0de70541bcde66819ab7225f8 Mon Sep 17 00:00:00 2001 From: erwincoumans Date: Sun, 9 Sep 2018 21:08:47 -0700 Subject: [PATCH] PyBullet setup.py: only enable BT_USE_EGL on Linux, but allow to run the eglPlugin on Windows and Mac as well (using their default opengl window). postpone the 'loadPlugin' for static eglPlugin, so that the init and exit happen in the same thread. When you don't call unloadPlugin, the program may crash when exiting in SHARED_MEMORY_SERVER mode. --- .../PhysicsServerCommandProcessor.cpp | 8 +++-- examples/SharedMemory/b3PluginManager.cpp | 30 +++++++++++++++++-- examples/SharedMemory/b3PluginManager.h | 2 +- .../eglRendererVisualShapeConverter.cpp | 17 ++++++++++- .../TinyRendererVisualShapeConverter.cpp | 4 +++ setup.py | 11 +++---- 6 files changed, 59 insertions(+), 13 deletions(-) diff --git a/examples/SharedMemory/PhysicsServerCommandProcessor.cpp b/examples/SharedMemory/PhysicsServerCommandProcessor.cpp index 3a837f508..9f09d8dfd 100644 --- a/examples/SharedMemory/PhysicsServerCommandProcessor.cpp +++ b/examples/SharedMemory/PhysicsServerCommandProcessor.cpp @@ -1715,16 +1715,18 @@ struct PhysicsServerCommandProcessorInternalData #endif //ENABLE_STATIC_GRPC_PLUGIN #ifdef STATIC_EGLRENDERER_PLUGIN -{ - int renderPluginId = m_pluginManager.registerStaticLinkedPlugin("eglRendererPlugin", initPlugin_eglRendererPlugin, exitPlugin_eglRendererPlugin, executePluginCommand_eglRendererPlugin,0,0,getRenderInterface_eglRendererPlugin,0); + { + bool initPlugin = false; + int renderPluginId = m_pluginManager.registerStaticLinkedPlugin("eglRendererPlugin", initPlugin_eglRendererPlugin, exitPlugin_eglRendererPlugin, executePluginCommand_eglRendererPlugin,0,0,getRenderInterface_eglRendererPlugin,0, initPlugin); m_pluginManager.selectPluginRenderer(renderPluginId); -} + } #endif//STATIC_EGLRENDERER_PLUGIN #ifndef SKIP_STATIC_TINYRENDERER_PLUGIN { + int renderPluginId = m_pluginManager.registerStaticLinkedPlugin("tinyRendererPlugin", initPlugin_tinyRendererPlugin, exitPlugin_tinyRendererPlugin, executePluginCommand_tinyRendererPlugin,0,0,getRenderInterface_tinyRendererPlugin,0); m_pluginManager.selectPluginRenderer(renderPluginId); } diff --git a/examples/SharedMemory/b3PluginManager.cpp b/examples/SharedMemory/b3PluginManager.cpp index 8e076c92f..b5a34bb37 100644 --- a/examples/SharedMemory/b3PluginManager.cpp +++ b/examples/SharedMemory/b3PluginManager.cpp @@ -34,6 +34,7 @@ struct b3Plugin { B3_DYNLIB_HANDLE m_pluginHandle; bool m_ownsPluginHandle; + bool m_isInitialized; std::string m_pluginPath; int m_pluginUniqueId; PFN_INIT m_initFunc; @@ -52,6 +53,7 @@ struct b3Plugin b3Plugin() :m_pluginHandle(0), m_ownsPluginHandle(false), + m_isInitialized(false), m_pluginUniqueId(-1), m_initFunc(0), m_exitFunc(0), @@ -80,6 +82,7 @@ struct b3Plugin m_processClientCommandsFunc = 0; m_getRendererFunc = 0; m_userPointer = 0; + m_isInitialized = false; } }; @@ -171,8 +174,20 @@ int b3PluginManager::loadPlugin(const char* pluginPath, const char* postFixStr) int* pluginUidPtr = m_data->m_pluginMap.find(pluginPath); if (pluginUidPtr) { + //already loaded pluginUniqueId = *pluginUidPtr; + b3PluginHandle* plugin = m_data->m_plugins.getHandle(pluginUniqueId); + if (!plugin->m_isInitialized) + { + b3PluginContext context = {0}; + context.m_userPointer = 0; + context.m_physClient = (b3PhysicsClientHandle) m_data->m_physicsDirect; + context.m_rpcCommandProcessorInterface = m_data->m_rpcCommandProcessorInterface; + int result = plugin->m_initFunc(&context); + plugin->m_isInitialized = true; + plugin->m_userPointer = context.m_userPointer; + } } else { @@ -211,16 +226,18 @@ int b3PluginManager::loadPlugin(const char* pluginPath, const char* postFixStr) if (plugin->m_initFunc && plugin->m_exitFunc && plugin->m_executeCommandFunc) { - + b3PluginContext context; context.m_userPointer = plugin->m_userPointer; context.m_physClient = (b3PhysicsClientHandle) m_data->m_physicsDirect; context.m_rpcCommandProcessorInterface = m_data->m_rpcCommandProcessorInterface; int version = plugin->m_initFunc(&context); + plugin->m_isInitialized = true; //keep the user pointer persistent plugin->m_userPointer = context.m_userPointer; if (version == SHARED_MEMORY_MAGIC_NUMBER) { + ok = true; plugin->m_ownsPluginHandle = true; plugin->m_pluginHandle = pluginHandle; @@ -286,7 +303,12 @@ void b3PluginManager::unloadPlugin(int pluginUniqueId) context.m_userPointer = plugin->m_userPointer; context.m_physClient = (b3PhysicsClientHandle) m_data->m_physicsDirect; - plugin->m_exitFunc(&context); + if (plugin->m_isInitialized) + { + plugin->m_exitFunc(&context); + plugin->m_userPointer = 0; + plugin->m_isInitialized = false; + } m_data->m_pluginMap.remove(plugin->m_pluginPath.c_str()); m_data->m_plugins.freeHandle(pluginUniqueId); } @@ -411,7 +433,7 @@ int b3PluginManager::executePluginCommand(int pluginUniqueId, const b3PluginArgu } -int b3PluginManager::registerStaticLinkedPlugin(const char* pluginPath, PFN_INIT initFunc,PFN_EXIT exitFunc, PFN_EXECUTE executeCommandFunc, PFN_TICK preTickFunc, PFN_TICK postTickFunc, PFN_GET_RENDER_INTERFACE getRendererFunc, PFN_TICK processClientCommandsFunc) +int b3PluginManager::registerStaticLinkedPlugin(const char* pluginPath, PFN_INIT initFunc,PFN_EXIT exitFunc, PFN_EXECUTE executeCommandFunc, PFN_TICK preTickFunc, PFN_TICK postTickFunc, PFN_GET_RENDER_INTERFACE getRendererFunc, PFN_TICK processClientCommandsFunc, bool initPlugin) { b3Plugin orgPlugin; @@ -440,12 +462,14 @@ int b3PluginManager::registerStaticLinkedPlugin(const char* pluginPath, PFN_INIT m_data->m_pluginMap.insert(pluginPath, pluginUniqueId); + if (initPlugin) { b3PluginContext context = {0}; context.m_userPointer = 0; context.m_physClient = (b3PhysicsClientHandle) m_data->m_physicsDirect; context.m_rpcCommandProcessorInterface = m_data->m_rpcCommandProcessorInterface; int result = pluginHandle->m_initFunc(&context); + pluginHandle->m_isInitialized = true; pluginHandle->m_userPointer = context.m_userPointer; } return pluginUniqueId; diff --git a/examples/SharedMemory/b3PluginManager.h b/examples/SharedMemory/b3PluginManager.h index 3beb64b54..b1eb592f5 100644 --- a/examples/SharedMemory/b3PluginManager.h +++ b/examples/SharedMemory/b3PluginManager.h @@ -30,7 +30,7 @@ class b3PluginManager void tickPlugins(double timeStep, b3PluginManagerTickMode tickMode); - int registerStaticLinkedPlugin(const char* pluginPath, PFN_INIT initFunc, PFN_EXIT exitFunc, PFN_EXECUTE executeCommandFunc, PFN_TICK preTickFunc, PFN_TICK postTickFunc, PFN_GET_RENDER_INTERFACE getRendererFunc, PFN_TICK processClientCommandsFunc); + int registerStaticLinkedPlugin(const char* pluginPath, PFN_INIT initFunc, PFN_EXIT exitFunc, PFN_EXECUTE executeCommandFunc, PFN_TICK preTickFunc, PFN_TICK postTickFunc, PFN_GET_RENDER_INTERFACE getRendererFunc, PFN_TICK processClientCommandsFunc, bool initPlugin=true); void selectPluginRenderer(int pluginUniqueId); UrdfRenderingInterface* getRenderInterface(); }; diff --git a/examples/SharedMemory/plugins/eglPlugin/eglRendererVisualShapeConverter.cpp b/examples/SharedMemory/plugins/eglPlugin/eglRendererVisualShapeConverter.cpp index 2e764d187..893440b0c 100644 --- a/examples/SharedMemory/plugins/eglPlugin/eglRendererVisualShapeConverter.cpp +++ b/examples/SharedMemory/plugins/eglPlugin/eglRendererVisualShapeConverter.cpp @@ -161,6 +161,8 @@ struct EGLRendererVisualShapeConverterInternalData glClearColor(.7f, .7f, .8f, 1.f); m_window->startRendering(); + + b3Assert(glGetError() ==GL_NO_ERROR); @@ -170,21 +172,34 @@ struct EGLRendererVisualShapeConverterInternalData int maxNumObjectCapacity = 128 * 1024; int maxShapeCapacityInBytes = 128 * 1024 * 1024; m_instancingRenderer = new GLInstancingRenderer(maxNumObjectCapacity, maxShapeCapacityInBytes); + b3Assert(glGetError() ==GL_NO_ERROR); m_instancingRenderer->init(); + b3Assert(glGetError() ==GL_NO_ERROR); m_instancingRenderer->resize(m_swWidth,m_swHeight); m_instancingRenderer->InitShaders(); + b3Assert(glGetError() ==GL_NO_ERROR); m_instancingRenderer->setActiveCamera(&m_camera); + b3Assert(glGetError() ==GL_NO_ERROR); m_instancingRenderer->updateCamera(); + b3Assert(glGetError() ==GL_NO_ERROR); m_instancingRenderer->setLightPosition(m_lightDirection); + m_window->endRendering(); } + virtual ~EGLRendererVisualShapeConverterInternalData() + { + delete m_instancingRenderer; + m_window->closeWindow(); + delete m_window; + } + }; EGLRendererVisualShapeConverter::EGLRendererVisualShapeConverter() { - m_data = new EGLRendererVisualShapeConverterInternalData(); + m_data = new EGLRendererVisualShapeConverterInternalData(); float dist = 1.5; float pitch = -10; diff --git a/examples/SharedMemory/plugins/tinyRendererPlugin/TinyRendererVisualShapeConverter.cpp b/examples/SharedMemory/plugins/tinyRendererPlugin/TinyRendererVisualShapeConverter.cpp index d1403f2fc..708565e58 100644 --- a/examples/SharedMemory/plugins/tinyRendererPlugin/TinyRendererVisualShapeConverter.cpp +++ b/examples/SharedMemory/plugins/tinyRendererPlugin/TinyRendererVisualShapeConverter.cpp @@ -120,6 +120,10 @@ struct TinyRendererVisualShapeConverterInternalData m_segmentationMaskBuffer.resize(m_swWidth*m_swHeight,-1); } + virtual ~TinyRendererVisualShapeConverterInternalData() + { + printf("~TinyRendererVisualShapeConverterInternalData()\n"); + } }; diff --git a/setup.py b/setup.py index 3a6a5193a..2f08290b9 100644 --- a/setup.py +++ b/setup.py @@ -43,7 +43,7 @@ CXX_FLAGS += '-DBT_ENABLE_ENET ' CXX_FLAGS += '-DBT_ENABLE_CLSOCKET ' CXX_FLAGS += '-DB3_DUMP_PYTHON_VERSION ' CXX_FLAGS += '-DSTATIC_EGLRENDERER_PLUGIN ' #comment to disable static egl plugin -CXX_FLAGS += '-DBT_USE_EGL ' # uncomment for EGL (old EGL versions fail) + @@ -412,9 +412,10 @@ if 'STATIC_EGLRENDERER_PLUGIN' in CXX_FLAGS: sources += ['examples/SharedMemory/plugins/eglPlugin/eglRendererPlugin.cpp']\ + ['examples/SharedMemory/plugins/eglPlugin/eglRendererVisualShapeConverter.cpp'] - if _platform == "linux" or _platform == "linux2": + print("linux!") libraries += ['dl','pthread'] + CXX_FLAGS += '-DBT_USE_EGL ' CXX_FLAGS += '-D_LINUX ' CXX_FLAGS += '-DGLEW_STATIC ' CXX_FLAGS += '-DGLEW_INIT_OPENGL11_FUNCTIONS=1 ' @@ -430,8 +431,8 @@ if _platform == "linux" or _platform == "linux2": if 'BT_USE_EGL' in CXX_FLAGS: # linking with bullet's Glew libraries causes segfault # for some reason. - sources += ['examples/ThirdPartyLibs/glad/egl.c'] - sources += ['examples/OpenGLWindow/EGLOpenGLWindow.cpp'] + sources += ['examples/ThirdPartyLibs/glad/egl.c']\ + + ['examples/OpenGLWindow/EGLOpenGLWindow.cpp'] elif _platform == "win32": print("win32!") @@ -503,7 +504,7 @@ setup( sources = sources, libraries = libraries, extra_compile_args=CXX_FLAGS.split(), - include_dirs = include_dirs + ["src","examples/ThirdPartyLibs","examples/ThirdPartyLibs/glad", "examples/ThirdPartyLibs/enet/include","examples/ThirdPartyLibs/clsocket/src"] + include_dirs = include_dirs + ["src","examples", "examples/ThirdPartyLibs","examples/ThirdPartyLibs/glad", "examples/ThirdPartyLibs/enet/include","examples/ThirdPartyLibs/clsocket/src"] ) ], classifiers=['Development Status :: 5 - Production/Stable', 'License :: OSI Approved :: zlib/libpng License',