From b5d615b2231d15d22a9943be28d617740cb26a1d Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 17 May 2022 10:10:45 +0200 Subject: [PATCH 1/9] mathutil: Fix broken docstrings --- panda/src/mathutil/frustum_src.I | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/panda/src/mathutil/frustum_src.I b/panda/src/mathutil/frustum_src.I index f884b29f45..a0f1a8f9d9 100644 --- a/panda/src/mathutil/frustum_src.I +++ b/panda/src/mathutil/frustum_src.I @@ -66,12 +66,7 @@ make_ortho(FLOATTYPE fnear, FLOATTYPE ffar, FLOATTYPE l, FLOATTYPE r, } /** - * Behaves like gluPerspective (Aspect = width/height, Yfov in degrees) aspect - * +------------+ | | 1 | | yfov | | - * +------------+ - * - * -------+------ \ | \ | \ | \ | \ | \| W yfov - * + * Behaves like gluPerspective (Aspect = width/height, Yfov in degrees) */ INLINE_MATHUTIL void FLOATNAME(LFrustum):: make_perspective_hfov(FLOATTYPE hfov, FLOATTYPE aspect, FLOATTYPE fnear, @@ -84,7 +79,9 @@ make_perspective_hfov(FLOATTYPE hfov, FLOATTYPE aspect, FLOATTYPE fnear, _b = -_t; } - +/** + * + */ INLINE_MATHUTIL void FLOATNAME(LFrustum):: make_perspective_vfov(FLOATTYPE yfov, FLOATTYPE aspect, FLOATTYPE fnear, FLOATTYPE ffar) { @@ -96,7 +93,9 @@ make_perspective_vfov(FLOATTYPE yfov, FLOATTYPE aspect, FLOATTYPE fnear, _l = -_r; } - +/** + * + */ INLINE_MATHUTIL void FLOATNAME(LFrustum):: make_perspective(FLOATTYPE xfov, FLOATTYPE yfov, FLOATTYPE fnear, FLOATTYPE ffar) { From 29c25a541c8a8d642766e63aba12d263843c6de4 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 17 May 2022 11:52:19 +0200 Subject: [PATCH 2/9] egl: Add egl-device-index config var for selecting EGL device Fixes #1306 --- panda/src/egldisplay/eglGraphicsPipe.cxx | 113 +++++++++++++++++------ 1 file changed, 83 insertions(+), 30 deletions(-) diff --git a/panda/src/egldisplay/eglGraphicsPipe.cxx b/panda/src/egldisplay/eglGraphicsPipe.cxx index a75aec5170..6d4a58adc5 100644 --- a/panda/src/egldisplay/eglGraphicsPipe.cxx +++ b/panda/src/egldisplay/eglGraphicsPipe.cxx @@ -21,6 +21,12 @@ #include +static ConfigVariableInt egl_device_index +("egl-device-index", -1, + PRC_DESC("Selects which EGL device index is used to create the EGL display in " + "a headless configuration. The special value -1 selects the default " + "device.")); + TypeHandle eglGraphicsPipe::_type_handle; /** @@ -30,6 +36,8 @@ eglGraphicsPipe:: eglGraphicsPipe() { // Check for client extensions. vector_string extensions; + bool supports_platform_device = false; + bool supports_device_enumeration = false; const char *ext_ptr = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); if (ext_ptr != nullptr) { extract_words(ext_ptr, extensions); @@ -42,6 +50,13 @@ eglGraphicsPipe() { out << " " << extension << "\n"; } } + + if (std::find(extensions.begin(), extensions.end(), "EGL_EXT_platform_device") != extensions.end()) { + supports_platform_device = true; + } + if (std::find(extensions.begin(), extensions.end(), "EGL_EXT_device_enumeration") != extensions.end()) { + supports_device_enumeration = true; + } } else if (egldisplay_cat.is_debug()) { eglGetError(); @@ -51,23 +66,10 @@ eglGraphicsPipe() { EGLint major, minor; - //NB. if the X11 display failed to open, _display will be 0, which is a valid - // input to eglGetDisplay - it means to open the default display. -#ifdef USE_X11 - _egl_display = eglGetDisplay((NativeDisplayType) _display); -#else - _egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); -#endif - if (_egl_display && !eglInitialize(_egl_display, &major, &minor)) { - egldisplay_cat.warning() - << "Couldn't initialize the default EGL display: " - << get_egl_error_string(eglGetError()) << "\n"; - _egl_display = EGL_NO_DISPLAY; - } - - if (!_egl_display && - std::find(extensions.begin(), extensions.end(), "EGL_EXT_platform_device") != extensions.end() && - std::find(extensions.begin(), extensions.end(), "EGL_EXT_device_enumeration") != extensions.end()) { + int index = egl_device_index.get_value(); + if (index >= 0 && supports_platform_device && supports_device_enumeration) { + PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = + (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT"); PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT = (PFNEGLQUERYDEVICESEXTPROC)eglGetProcAddress("eglQueryDevicesEXT"); @@ -79,23 +81,74 @@ eglGraphicsPipe() { EGLDeviceEXT *devices = (EGLDeviceEXT *)alloca(sizeof(EGLDeviceEXT) * num_devices); eglQueryDevicesEXT(num_devices, devices, &num_devices); - if (egldisplay_cat.is_debug()) { - egldisplay_cat.debug() - << "Found " << num_devices << " EGL devices.\n"; + if (index >= num_devices) { + egldisplay_cat.error() + << "Requested EGL device index " << index << " does not exist (" + << "there are only " << num_devices << " devices)\n"; + _is_valid = false; + return; } - PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = - (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT"); + if (egldisplay_cat.is_debug()) { + egldisplay_cat.debug() + << "Found " << num_devices << " EGL devices, using device index " + << index << ".\n"; + } - if (eglGetPlatformDisplayEXT != nullptr) { - for (EGLint i = 0; i < num_devices && !_egl_display; ++i) { - _egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, devices[i], nullptr); + _egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, devices[index], nullptr); - if (_egl_display && !eglInitialize(_egl_display, &major, &minor)) { - egldisplay_cat.warning() - << "Couldn't initialize EGL platform display " << i << ": " - << get_egl_error_string(eglGetError()) << "\n"; - _egl_display = EGL_NO_DISPLAY; + if (_egl_display && !eglInitialize(_egl_display, &major, &minor)) { + egldisplay_cat.error() + << "Couldn't initialize EGL platform display " << index << ": " + << get_egl_error_string(eglGetError()) << "\n"; + _egl_display = EGL_NO_DISPLAY; + } + } + } + else { + //NB. if the X11 display failed to open, _display will be 0, which is a valid + // input to eglGetDisplay - it means to open the default display. + #ifdef USE_X11 + _egl_display = eglGetDisplay((NativeDisplayType) _display); + #else + _egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + #endif + if (_egl_display && !eglInitialize(_egl_display, &major, &minor)) { + egldisplay_cat.warning() + << "Couldn't initialize the default EGL display: " + << get_egl_error_string(eglGetError()) << "\n"; + _egl_display = EGL_NO_DISPLAY; + } + + if (!_egl_display && supports_platform_device && supports_device_enumeration) { + PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT = + (PFNEGLQUERYDEVICESEXTPROC)eglGetProcAddress("eglQueryDevicesEXT"); + + EGLint num_devices = 0; + if (eglQueryDevicesEXT != nullptr && + eglQueryDevicesEXT(0, nullptr, &num_devices) && + num_devices > 0) { + EGLDeviceEXT *devices = (EGLDeviceEXT *)alloca(sizeof(EGLDeviceEXT) * num_devices); + eglQueryDevicesEXT(num_devices, devices, &num_devices); + + if (egldisplay_cat.is_debug()) { + egldisplay_cat.debug() + << "Found " << num_devices << " EGL devices.\n"; + } + + PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = + (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT"); + + if (eglGetPlatformDisplayEXT != nullptr) { + for (EGLint i = 0; i < num_devices && !_egl_display; ++i) { + _egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, devices[i], nullptr); + + if (_egl_display && !eglInitialize(_egl_display, &major, &minor)) { + egldisplay_cat.warning() + << "Couldn't initialize EGL platform display " << i << ": " + << get_egl_error_string(eglGetError()) << "\n"; + _egl_display = EGL_NO_DISPLAY; + } } } } From c24a15ed408287a0eafa036d6252aa207049f882 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 29 Jun 2022 15:12:06 +0200 Subject: [PATCH 3/9] task: Fix missing `taskMgr` reference when using managed tasks --- direct/src/showbase/DirectObject.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/direct/src/showbase/DirectObject.py b/direct/src/showbase/DirectObject.py index 0833b1890a..261fc3049c 100644 --- a/direct/src/showbase/DirectObject.py +++ b/direct/src/showbase/DirectObject.py @@ -44,16 +44,18 @@ class DirectObject: #This function must be used if you want a managed task def addTask(self, *args, **kwargs): - if(not hasattr(self,"_taskList")): + from direct.task.TaskManagerGlobal import taskMgr + if not hasattr(self, "_taskList"): self._taskList = {} - kwargs['owner']=self + kwargs['owner'] = self task = taskMgr.add(*args, **kwargs) return task def doMethodLater(self, *args, **kwargs): - if(not hasattr(self,"_taskList")): - self._taskList ={} - kwargs['owner']=self + from direct.task.TaskManagerGlobal import taskMgr + if not hasattr(self, "_taskList"): + self._taskList = {} + kwargs['owner'] = self task = taskMgr.doMethodLater(*args, **kwargs) return task @@ -69,7 +71,7 @@ class DirectObject: taskOrName.remove() def removeAllTasks(self): - if hasattr(self,'_taskList'): + if hasattr(self, '_taskList'): for task in list(self._taskList.values()): task.remove() From 9ab460c9009804b31e24ea7688fe0065a1dff9ae Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 29 Jun 2022 15:13:57 +0200 Subject: [PATCH 4/9] event: Fix memory leak in debug check of `task.set_owner(...)` Fixes #1328 --- panda/src/event/pythonTask.cxx | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/panda/src/event/pythonTask.cxx b/panda/src/event/pythonTask.cxx index 07fca8bd38..f214ee73d6 100644 --- a/panda/src/event/pythonTask.cxx +++ b/panda/src/event/pythonTask.cxx @@ -209,10 +209,22 @@ set_owner(PyObject *owner) { #ifndef NDEBUG if (owner != Py_None) { PyObject *add = PyObject_GetAttrString(owner, "_addTask"); + PyErr_Clear(); PyObject *clear = PyObject_GetAttrString(owner, "_clearTask"); + PyErr_Clear(); - if (add == nullptr || !PyCallable_Check(add) || - clear == nullptr || !PyCallable_Check(clear)) { + bool valid_add = false; + if (add != nullptr) { + valid_add = PyCallable_Check(add); + Py_DECREF(add); + } + bool valid_clear = false; + if (clear != nullptr) { + valid_clear = PyCallable_Check(clear); + Py_DECREF(clear); + } + + if (!valid_add || !valid_clear) { Dtool_Raise_TypeError("owner object should have _addTask and _clearTask methods"); return; } From c325eabb9d4a0a7f903843e1f51b1ed6c170323d Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 29 Jun 2022 15:15:02 +0200 Subject: [PATCH 5/9] glgsg: Fix texture format selection when using `T_half_float` component type --- .../src/glstuff/glGraphicsStateGuardian_src.cxx | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index c536ed6747..43982312f0 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -10249,7 +10249,8 @@ get_internal_image_format(Texture *tex, bool force_sized) const { case Texture::F_rgba: case Texture::F_rgbm: #ifndef OPENGLES_1 - if (component_type == Texture::T_float) { + if (component_type == Texture::T_float || + component_type == Texture::T_half_float) { return GL_RGBA16F; } else #endif @@ -10315,7 +10316,8 @@ get_internal_image_format(Texture *tex, bool force_sized) const { #endif // OPENGLES #ifndef OPENGLES case Texture::F_rgba16: - if (component_type == Texture::T_float) { + if (component_type == Texture::T_float || + component_type == Texture::T_half_float) { return GL_RGBA16F; } else if (Texture::is_unsigned(component_type)) { return GL_RGBA16; @@ -10335,6 +10337,7 @@ get_internal_image_format(Texture *tex, bool force_sized) const { case Texture::F_rgb: switch (component_type) { case Texture::T_float: return GL_RGB16F; + case Texture::T_half_float: return GL_RGB16F; #ifndef OPENGLES case Texture::T_unsigned_short: return GL_RGB16; case Texture::T_short: return GL_RGB16_SNORM; @@ -10371,7 +10374,8 @@ get_internal_image_format(Texture *tex, bool force_sized) const { case Texture::F_rgb12: return GL_RGB12; case Texture::F_rgb16: - if (component_type == Texture::T_float) { + if (component_type == Texture::T_float || + component_type == Texture::T_half_float) { return GL_RGB16F; } else if (Texture::is_unsigned(component_type)) { return GL_RGB16; @@ -10394,7 +10398,8 @@ get_internal_image_format(Texture *tex, bool force_sized) const { return GL_RG16F_EXT; #elif !defined(OPENGLES_1) case Texture::F_r16: - if (component_type == Texture::T_float) { + if (component_type == Texture::T_float || + component_type == Texture::T_half_float) { return GL_R16F; } else if (Texture::is_unsigned(component_type)) { return GL_R16; @@ -10402,7 +10407,8 @@ get_internal_image_format(Texture *tex, bool force_sized) const { return GL_R16_SNORM; } case Texture::F_rg16: - if (component_type == Texture::T_float) { + if (component_type == Texture::T_float || + component_type == Texture::T_half_float) { return GL_RG16F; } else if (Texture::is_unsigned(component_type)) { return GL_RG16; From 91dd802de682f17089f995dfb146516b23d0b36e Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 29 Jun 2022 16:07:48 +0200 Subject: [PATCH 6/9] dist: Include `_sysconfigdata` module properly Fixes #1326 --- direct/src/dist/FreezeTool.py | 12 ++++++++++++ makepanda/makewheel.py | 15 +++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/direct/src/dist/FreezeTool.py b/direct/src/dist/FreezeTool.py index 1e5554afa9..6c9d382a5d 100644 --- a/direct/src/dist/FreezeTool.py +++ b/direct/src/dist/FreezeTool.py @@ -1215,6 +1215,18 @@ class Freezer: else: self.__loadModule(self.ModuleDef(modname, implicit = True)) + # Special case for sysconfig, which depends on a platform-specific + # sysconfigdata module on POSIX systems. + if 'sysconfig' in self.mf.modules: + if sys.version_info >= (3, 6): + if 'linux' in self.platform: + arch = self.platform.split('_', 1)[1] + self.__loadModule(self.ModuleDef('_sysconfigdata__linux_' + arch + '-linux-gnu', implicit=True)) + elif 'mac' in self.platform: + self.__loadModule(self.ModuleDef('_sysconfigdata__darwin_darwin', implicit=True)) + elif 'linux' in self.platform or 'mac' in self.platform: + self.__loadModule(self.ModuleDef('_sysconfigdata', implicit=True)) + # Now, any new modules we found get added to the export list. for origName in list(self.mf.modules.keys()): if origName not in origToNewName: diff --git a/makepanda/makewheel.py b/makepanda/makewheel.py index 2e1b18ec45..fbcace6b56 100644 --- a/makepanda/makewheel.py +++ b/makepanda/makewheel.py @@ -687,6 +687,21 @@ __version__ = '{0}' whl.write_file(target_path, source_path) + # Include the special sysconfigdata module. + if os.name == 'posix': + import sysconfig + + if hasattr(sysconfig, '_get_sysconfigdata_name'): + modname = sysconfig._get_sysconfigdata_name() + '.py' + else: + modname = '_sysconfigdata.py' + + for entry in sys.path: + source_path = os.path.join(entry, modname) + if os.path.isfile(source_path): + whl.write_file('deploy_libs/' + modname, source_path) + break + # Add plug-ins. for lib in PLUGIN_LIBS: plugin_name = 'lib' + lib From 5493a0d5fc055439f3452fba8fe785f4cf7d5d0e Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 29 Jun 2022 16:39:35 +0200 Subject: [PATCH 7/9] glgsg: Fix PStats GPU timing not working with newer NVIDIA drivers Fixes #1320 --- .../glstuff/glGraphicsStateGuardian_src.cxx | 3 +++ .../src/glstuff/glGraphicsStateGuardian_src.h | 4 ++++ .../src/glstuff/glLatencyQueryContext_src.cxx | 22 ++----------------- panda/src/glstuff/glLatencyQueryContext_src.h | 4 ---- panda/src/glstuff/glTimerQueryContext_src.I | 3 ++- panda/src/glstuff/glTimerQueryContext_src.cxx | 2 +- panda/src/glstuff/glTimerQueryContext_src.h | 1 + 7 files changed, 13 insertions(+), 26 deletions(-) diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 43982312f0..fc304d8a96 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -2717,6 +2717,8 @@ reset() { _glGetInteger64v = (PFNGLGETINTEGER64VPROC) get_extension_func("glGetInteger64v"); + + _glGetInteger64v(GL_TIMESTAMP, &_timer_query_epoch); } #endif @@ -6889,6 +6891,7 @@ issue_timer_query(int pstats_index) { query = new CLP(LatencyQueryContext)(this, pstats_index); } else { query = new CLP(TimerQueryContext)(this, pstats_index); + query->_epoch = _timer_query_epoch; } if (_deleted_queries.size() >= 1) { diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 6457cc920c..b56cbf1774 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -1139,6 +1139,10 @@ public: BufferResidencyTracker _renderbuffer_residency; +#ifndef OPENGLES + GLint64 _timer_query_epoch = 0; +#endif + static PStatCollector _load_display_list_pcollector; static PStatCollector _primitive_batches_display_list_pcollector; static PStatCollector _vertices_display_list_pcollector; diff --git a/panda/src/glstuff/glLatencyQueryContext_src.cxx b/panda/src/glstuff/glLatencyQueryContext_src.cxx index a08ab74517..183f508c65 100644 --- a/panda/src/glstuff/glLatencyQueryContext_src.cxx +++ b/panda/src/glstuff/glLatencyQueryContext_src.cxx @@ -21,27 +21,9 @@ TypeHandle CLP(LatencyQueryContext)::_type_handle; CLP(LatencyQueryContext):: CLP(LatencyQueryContext)(CLP(GraphicsStateGuardian) *glgsg, int pstats_index) : - CLP(TimerQueryContext)(glgsg, pstats_index), - _timestamp(0) + CLP(TimerQueryContext)(glgsg, pstats_index) { - glgsg->_glGetInteger64v(GL_TIMESTAMP, &_timestamp); -} - -/** - * Returns the timestamp that is the result of this timer query. There's no - * guarantee about which clock this uses, the only guarantee is that - * subtracting a start time from an end time should yield a time in seconds. - * If is_answer_ready() did not return true, this function may block before it - * returns. - * - * It is only valid to call this from the draw thread. - */ -double CLP(LatencyQueryContext):: -get_timestamp() const { - GLint64 time_ns; - _glgsg->_glGetQueryObjecti64v(_index, GL_QUERY_RESULT, &time_ns); - - return (time_ns - _timestamp) * 0.000000001; + glgsg->_glGetInteger64v(GL_TIMESTAMP, &_epoch); } #endif // OPENGLES diff --git a/panda/src/glstuff/glLatencyQueryContext_src.h b/panda/src/glstuff/glLatencyQueryContext_src.h index 7c255cb5df..a3ee025641 100644 --- a/panda/src/glstuff/glLatencyQueryContext_src.h +++ b/panda/src/glstuff/glLatencyQueryContext_src.h @@ -26,10 +26,6 @@ public: ALLOC_DELETED_CHAIN(CLP(LatencyQueryContext)); - virtual double get_timestamp() const; - - GLint64 _timestamp; - public: static TypeHandle get_class_type() { return _type_handle; diff --git a/panda/src/glstuff/glTimerQueryContext_src.I b/panda/src/glstuff/glTimerQueryContext_src.I index c898c30261..2d89904b68 100644 --- a/panda/src/glstuff/glTimerQueryContext_src.I +++ b/panda/src/glstuff/glTimerQueryContext_src.I @@ -19,6 +19,7 @@ CLP(TimerQueryContext)(CLP(GraphicsStateGuardian) *glgsg, int pstats_index) : TimerQueryContext(pstats_index), _glgsg(glgsg), - _index(0) + _index(0), + _epoch(0) { } diff --git a/panda/src/glstuff/glTimerQueryContext_src.cxx b/panda/src/glstuff/glTimerQueryContext_src.cxx index a7b4ecb612..22712f7f50 100644 --- a/panda/src/glstuff/glTimerQueryContext_src.cxx +++ b/panda/src/glstuff/glTimerQueryContext_src.cxx @@ -90,7 +90,7 @@ get_timestamp() const { _glgsg->_glGetQueryObjectui64v(_index, GL_QUERY_RESULT, &time_ns); - return time_ns * 0.000000001; + return (time_ns - _epoch) * 0.000000001; } #endif // OPENGLES diff --git a/panda/src/glstuff/glTimerQueryContext_src.h b/panda/src/glstuff/glTimerQueryContext_src.h index 07709bc7af..8591b55cc0 100644 --- a/panda/src/glstuff/glTimerQueryContext_src.h +++ b/panda/src/glstuff/glTimerQueryContext_src.h @@ -39,6 +39,7 @@ public: GLuint _index; WPT(CLP(GraphicsStateGuardian)) _glgsg; + GLint64 _epoch; public: static TypeHandle get_class_type() { From 3fc579c7d4b6db1c2ea4f35dec66d9e9842a5bad Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 29 Jun 2022 17:03:44 +0200 Subject: [PATCH 8/9] tinydisplay: Implement resizeability of offscreen buffers Fixes #1322 --- panda/src/tinydisplay/tinyGraphicsBuffer.cxx | 9 +++++++++ panda/src/tinydisplay/tinyGraphicsBuffer.h | 2 ++ 2 files changed, 11 insertions(+) diff --git a/panda/src/tinydisplay/tinyGraphicsBuffer.cxx b/panda/src/tinydisplay/tinyGraphicsBuffer.cxx index ea8e8241a6..47c0327f1b 100644 --- a/panda/src/tinydisplay/tinyGraphicsBuffer.cxx +++ b/panda/src/tinydisplay/tinyGraphicsBuffer.cxx @@ -89,6 +89,15 @@ end_frame(FrameMode mode, Thread *current_thread) { } } +/** + * + */ +void TinyGraphicsBuffer:: +set_size(int x, int y) { + GraphicsBuffer::set_size(x, y); + create_frame_buffer(); +} + /** * Closes the buffer right now. Called from the buffer thread. */ diff --git a/panda/src/tinydisplay/tinyGraphicsBuffer.h b/panda/src/tinydisplay/tinyGraphicsBuffer.h index 79c6e8c5e5..e1fe665959 100644 --- a/panda/src/tinydisplay/tinyGraphicsBuffer.h +++ b/panda/src/tinydisplay/tinyGraphicsBuffer.h @@ -35,6 +35,8 @@ public: virtual bool begin_frame(FrameMode mode, Thread *current_thread); virtual void end_frame(FrameMode mode, Thread *current_thread); + virtual void set_size(int x, int y); + INLINE ZBuffer *get_frame_buffer(); protected: From 33691d72ecc04d450b9a8a5e6114b8341fafe77a Mon Sep 17 00:00:00 2001 From: "Stephen A. Imhoff" Date: Wed, 29 Jun 2022 17:06:19 +0200 Subject: [PATCH 9/9] bullet: Fix assertion when reconstructing BulletConvexHullShape from bam Fixes #1251 Closes #1252 --- panda/src/bullet/bulletConvexHullShape.cxx | 2 +- tests/bullet/test_bullet_bam.py | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/panda/src/bullet/bulletConvexHullShape.cxx b/panda/src/bullet/bulletConvexHullShape.cxx index b61722e773..89ec5b2034 100644 --- a/panda/src/bullet/bulletConvexHullShape.cxx +++ b/panda/src/bullet/bulletConvexHullShape.cxx @@ -194,7 +194,7 @@ make_from_bam(const FactoryParams ¶ms) { void BulletConvexHullShape:: fillin(DatagramIterator &scan, BamReader *manager) { BulletShape::fillin(scan, manager); - nassertv(_shape == nullptr); + nassertv(_shape); _shape->setMargin(scan.get_stdfloat()); unsigned int num_points = scan.get_uint32(); diff --git a/tests/bullet/test_bullet_bam.py b/tests/bullet/test_bullet_bam.py index ae20f2d47a..d26a6c4117 100644 --- a/tests/bullet/test_bullet_bam.py +++ b/tests/bullet/test_bullet_bam.py @@ -133,6 +133,26 @@ def test_sphere_shape(): assert shape.radius == shape2.radius +def test_convex_shape(): + shape = bullet.BulletConvexHullShape() + shape.add_array([ + (-1.0, -1.0, -1.0), + (1.0, -1.0, -1.0), + (-1.0, 1.0, -1.0), + (-1.0, -1.0, 1.0), + (1.0, 1.0, -1.0), + (1.0, -1.0, 1.0), + (-1.0, 1.0, 1.0), + (1.0, 1.0, 1.0), + ]) + shape.margin = 0.5 + + shape2 = reconstruct(shape) + + assert type(shape) is type(shape2) + assert shape.margin == shape2.margin + + def test_ghost(): node = bullet.BulletGhostNode("some ghost node")