From 7ce1a9ffed442285bd2d94340258a0fd2a965ed2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Derzsi=20D=C3=A1niel?= Date: Fri, 20 Mar 2020 02:03:08 +0200 Subject: [PATCH 1/6] direct: Fix RuntimeError during ControlManager deletion Closes #884 --- direct/src/controls/ControlManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/direct/src/controls/ControlManager.py b/direct/src/controls/ControlManager.py index 6c11f619f6..db5d6654fb 100755 --- a/direct/src/controls/ControlManager.py +++ b/direct/src/controls/ControlManager.py @@ -144,7 +144,7 @@ class ControlManager: def delete(self): assert self.notify.debugCall(id(self)) self.disable() - for controls in self.controls.keys(): + for controls in list(self.controls.keys()): self.remove(controls) del self.controls del self.currentControls From 69296585a4b0381bb60e3e2b3b7dcdb0f7874497 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 2 Apr 2020 22:31:13 +0200 Subject: [PATCH 2/6] dist: make config.prc handling a bit more robust Strip comments after value, don't look for variable names mid-string, and sort the prc files deterministically. --- direct/src/dist/commands.py | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/direct/src/dist/commands.py b/direct/src/dist/commands.py index 1a8f51602d..5d2aaa8f2d 100644 --- a/direct/src/dist/commands.py +++ b/direct/src/dist/commands.py @@ -574,15 +574,19 @@ class build_apps(setuptools.Command): libdir = os.path.dirname(dtool_fn.to_os_specific()) etcdir = os.path.join(libdir, '..', 'etc') - for fn in os.listdir(etcdir): + etcfiles = os.listdir(etcdir) + etcfiles.sort(reverse=True) + for fn in etcfiles: if fn.lower().endswith('.prc'): with open(os.path.join(etcdir, fn)) as f: prcstring += f.read() else: etcfiles = [i for i in p3dwhl.namelist() if i.endswith('.prc')] + etcfiles.sort(reverse=True) for fn in etcfiles: with p3dwhl.open(fn) as f: prcstring += f.read().decode('utf8') + user_prcstring = self.extra_prc_data for fn in self.extra_prc_files: with open(fn) as f: @@ -601,12 +605,26 @@ class build_apps(setuptools.Command): for ln in prcstr.split('\n'): ln = ln.strip() useline = True + if ln.startswith('#') or not ln: continue - if 'model-cache-dir' in ln: - ln = ln.replace('/panda3d', '/{}'.format(self.distribution.get_name())) + + words = ln.split(None, 1) + if not words: + continue + var = words[0] + value = words[1] if len(words) > 1 else '' + + # Strip comment after value. + c = value.find(' #') + if c > 0: + value = value[:c].rstrip() + + if var == 'model-cache-dir' and value: + value = value.replace('/panda3d', '/{}'.format(self.distribution.get_name())) + for plugin in check_plugins: - if plugin in ln and plugin not in self.plugins: + if plugin in value and plugin not in self.plugins: useline = False if warn_on_missing_plugin: self.warn( @@ -614,7 +632,10 @@ class build_apps(setuptools.Command): ) break if useline: - out.append(ln) + if value: + out.append(var + ' ' + value) + else: + out.append(var) return out prcexport = parse_prc(prcstring, 0) + parse_prc(user_prcstring, 1) From 9e80282affb4ce19430fdd3e16d4b3ec4d49e2b8 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 2 Apr 2020 22:34:04 +0200 Subject: [PATCH 3/6] dist: replace p3fmod_audio with p3openal_audio if former is missing This helps when deploying to macOS, where p3fmod_audio is the default for 1.10 builds, a fact that is very easy to overlook when deploying to macOS and only including the p3openal_audio plug-in. --- direct/src/dist/commands.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/direct/src/dist/commands.py b/direct/src/dist/commands.py index 5d2aaa8f2d..632d9c9859 100644 --- a/direct/src/dist/commands.py +++ b/direct/src/dist/commands.py @@ -623,6 +623,13 @@ class build_apps(setuptools.Command): if var == 'model-cache-dir' and value: value = value.replace('/panda3d', '/{}'.format(self.distribution.get_name())) + if var == 'audio-library-name': + # We have the default set to p3fmod_audio on macOS in 1.10, + # but this can be unexpected as other platforms use OpenAL + # by default. Switch it up if FMOD is not included. + if value not in self.plugins and value == 'p3fmod_audio' and 'p3openal_audio' in self.plugins: + self.warn("Missing audio plugin p3fmod_audio referenced in PRC data, replacing with p3openal_audio") + for plugin in check_plugins: if plugin in value and plugin not in self.plugins: useline = False From f2e67169bc8f9385ddee54c8943c0ec66413bdaf Mon Sep 17 00:00:00 2001 From: Joel Stienlet Date: Tue, 7 Apr 2020 16:59:15 +0200 Subject: [PATCH 4/6] corrects bug: wrong case entered in MultiplexStreamBuf::Output::write_string() in panda/src/downloader/multiplexStreamBuf.cxx Closes #902 --- panda/src/downloader/multiplexStream.I | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda/src/downloader/multiplexStream.I b/panda/src/downloader/multiplexStream.I index aff3d4a064..e360df6922 100644 --- a/panda/src/downloader/multiplexStream.I +++ b/panda/src/downloader/multiplexStream.I @@ -37,7 +37,7 @@ add_ostream(std::ostream *out, bool delete_later) { INLINE bool MultiplexStream:: add_stdio_file(FILE *fout, bool close_when_done) { _msb.add_output(MultiplexStreamBuf::BT_line, - MultiplexStreamBuf::OT_ostream, + MultiplexStreamBuf::OT_stdio, nullptr, fout, close_when_done); return true; } From 80ab6a28c4e765ab75491b150093efd28f16acb8 Mon Sep 17 00:00:00 2001 From: Ashwini Date: Wed, 8 Apr 2020 21:59:21 +0530 Subject: [PATCH 5/6] pnmimage: Added offset to add_sub_image and mult_sub_image Closes #903 --- panda/src/pnmimage/pnmImage.cxx | 8 +++---- tests/pnmimage/test_pnmimage.py | 37 +++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/panda/src/pnmimage/pnmImage.cxx b/panda/src/pnmimage/pnmImage.cxx index a8deae0b6b..a39ef5c61e 100644 --- a/panda/src/pnmimage/pnmImage.cxx +++ b/panda/src/pnmimage/pnmImage.cxx @@ -1176,7 +1176,7 @@ add_sub_image(const PNMImage ©, int xto, int yto, if (has_alpha() && copy.has_alpha()) { for (y = ymin; y < ymax; y++) { for (x = xmin; x < xmax; x++) { - set_alpha(x, y, get_alpha(x, y) + copy.get_alpha(x, y) * pixel_scale); + set_alpha(x, y, get_alpha(x, y) + copy.get_alpha(x - xmin + xfrom, y - ymin + yfrom) * pixel_scale); } } } @@ -1184,7 +1184,7 @@ add_sub_image(const PNMImage ©, int xto, int yto, for (y = ymin; y < ymax; y++) { for (x = xmin; x < xmax; x++) { LRGBColorf rgb1 = get_xel(x, y); - LRGBColorf rgb2 = copy.get_xel(x, y); + LRGBColorf rgb2 = copy.get_xel(x - xmin + xfrom, y - ymin + yfrom); set_xel(x, y, rgb1[0] + rgb2[0] * pixel_scale, rgb1[1] + rgb2[1] * pixel_scale, @@ -1210,7 +1210,7 @@ mult_sub_image(const PNMImage ©, int xto, int yto, if (has_alpha() && copy.has_alpha()) { for (y = ymin; y < ymax; y++) { for (x = xmin; x < xmax; x++) { - set_alpha(x, y, get_alpha(x, y) * copy.get_alpha(x, y) * pixel_scale); + set_alpha(x, y, get_alpha(x, y) * copy.get_alpha(x - xmin + xfrom, y - ymin + yfrom) * pixel_scale); } } } @@ -1218,7 +1218,7 @@ mult_sub_image(const PNMImage ©, int xto, int yto, for (y = ymin; y < ymax; y++) { for (x = xmin; x < xmax; x++) { LRGBColorf rgb1 = get_xel(x, y); - LRGBColorf rgb2 = copy.get_xel(x, y); + LRGBColorf rgb2 = copy.get_xel(x - xmin + xfrom, y - ymin + yfrom); set_xel(x, y, rgb1[0] * rgb2[0] * pixel_scale, rgb1[1] * rgb2[1] * pixel_scale, diff --git a/tests/pnmimage/test_pnmimage.py b/tests/pnmimage/test_pnmimage.py index 40d8a88683..7148cbf89c 100644 --- a/tests/pnmimage/test_pnmimage.py +++ b/tests/pnmimage/test_pnmimage.py @@ -70,3 +70,40 @@ def test_pnmimage_quantize(): assert col.b in (0, 1) assert max_dist < 0.1 ** 2 + +def test_pnmimage_add_sub_image(): + dst = PNMImage(2, 2) + dst.fill(0.5, 0, 0) #adding color to dst + #dst_color will store rgb values at each pixel of dst + dst_color = ((dst.get_xel(0, 0), dst.get_xel(0, 1)), (dst.get_xel(1, 0), dst.get_xel(1, 1))) + + src = PNMImage(1, 1) + src.fill(0, 0.7, 0) #adding color to src + #src_color will store rgb values at each pixel of src + src_color = src.get_xel(0, 0) + + dst.add_sub_image(src, 1, 1, 0, 0, 1, 1) + final_color = ((dst.get_xel(0, 0), dst.get_xel(0, 1)), (dst.get_xel(1, 0), dst.get_xel(1, 1))) + assert final_color[0][0] == dst_color[0][0] + assert final_color[0][1] == dst_color[0][1] + assert final_color[1][0] == dst_color[1][0] + assert final_color[1][1] == dst_color[1][1] + src_color + + +def test_pnmimage_mult_sub_image(): + dst = PNMImage(2, 2) + dst.fill(0.5, 0, 0) #adding color to dst + #dst_color will store rgb values at each pixel of dst + dst_color = ((dst.get_xel(0, 0), dst.get_xel(0, 1)), (dst.get_xel(1, 0), dst.get_xel(1, 1))) + + src = PNMImage(1, 1) + src.fill(0, 0.7, 0) #adding color to src + #src_color will store rgb values at each pixel of src + src_color = src.get_xel(0, 0) + + dst.mult_sub_image(src, 1, 1, 0, 0, 1, 1) + final_color = ((dst.get_xel(0, 0), dst.get_xel(0, 1)), (dst.get_xel(1, 0), dst.get_xel(1, 1))) + assert final_color[0][0] == dst_color[0][0] + assert final_color[0][1] == dst_color[0][1] + assert final_color[1][0] == dst_color[1][0] + assert final_color[1][1][0] == dst_color[1][1][0] * src_color[0] and final_color[1][1][1] == dst_color[1][1][1] * src_color[1] and final_color[1][1][2] == dst_color[1][1][2] * src_color[2] From c59a039fa8b8b78848c64889e85ed91b9070a336 Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 25 Apr 2020 23:38:19 +0200 Subject: [PATCH 6/6] pgraph: fix RenderState/TransformState count in PStats exploding This was a regression in 1.10.6 that caused PStats to misreport the amount of RenderState/TransformStates in the application. --- panda/src/pgraph/renderState.I | 30 +++++++++++++++++++++++++++++- panda/src/pgraph/renderState.h | 5 +++++ panda/src/pgraph/transformState.I | 30 +++++++++++++++++++++++++++++- panda/src/pgraph/transformState.h | 5 +++++ 4 files changed, 68 insertions(+), 2 deletions(-) diff --git a/panda/src/pgraph/renderState.I b/panda/src/pgraph/renderState.I index d232ecb00a..b722a4cc07 100644 --- a/panda/src/pgraph/renderState.I +++ b/panda/src/pgraph/renderState.I @@ -481,6 +481,34 @@ flush_level() { _cache_counter.flush_level(); } +/** + * Overrides this method to update PStats appropriately. + */ +INLINE void RenderState:: +cache_ref_only() const { +#ifdef DO_PSTATS + int old_referenced_bits = get_referenced_bits(); + NodeCachedReferenceCount::cache_ref_only(); + consider_update_pstats(old_referenced_bits); +#else // DO_PSTATS + NodeCachedReferenceCount::cache_ref_only(); +#endif // DO_PSTATS +} + +/** + * Overrides this method to update PStats appropriately. + */ +INLINE void RenderState:: +cache_unref_only() const { +#ifdef DO_PSTATS + int old_referenced_bits = get_referenced_bits(); + NodeCachedReferenceCount::cache_unref_only(); + consider_update_pstats(old_referenced_bits); +#else // DO_PSTATS + NodeCachedReferenceCount::cache_unref_only(); +#endif // DO_PSTATS +} + #ifndef CPPPARSER /** * Handy templated version of get_attrib that casts to the right type. @@ -533,7 +561,7 @@ check_hash() const { */ INLINE bool RenderState:: do_cache_unref() const { - cache_unref_only(); + NodeCachedReferenceCount::cache_unref_only(); return unref(); } diff --git a/panda/src/pgraph/renderState.h b/panda/src/pgraph/renderState.h index c9e3719082..03f4b01ca4 100644 --- a/panda/src/pgraph/renderState.h +++ b/panda/src/pgraph/renderState.h @@ -169,6 +169,11 @@ public: INLINE void get_attrib_def(CPT(AttribType) &attrib) const; #endif // CPPPARSER + INLINE void cache_ref_only() const; + +protected: + INLINE void cache_unref_only() const; + private: INLINE void check_hash() const; bool validate_filled_slots() const; diff --git a/panda/src/pgraph/transformState.I b/panda/src/pgraph/transformState.I index 474b78891f..fe83edc991 100644 --- a/panda/src/pgraph/transformState.I +++ b/panda/src/pgraph/transformState.I @@ -753,6 +753,34 @@ flush_level() { _cache_counter.flush_level(); } +/** + * Overrides this method to update PStats appropriately. + */ +INLINE void TransformState:: +cache_ref_only() const { +#ifdef DO_PSTATS + int old_referenced_bits = get_referenced_bits(); + NodeCachedReferenceCount::cache_ref_only(); + consider_update_pstats(old_referenced_bits); +#else // DO_PSTATS + NodeCachedReferenceCount::cache_ref_only(); +#endif // DO_PSTATS +} + +/** + * Overrides this method to update PStats appropriately. + */ +INLINE void TransformState:: +cache_unref_only() const { +#ifdef DO_PSTATS + int old_referenced_bits = get_referenced_bits(); + NodeCachedReferenceCount::cache_unref_only(); + consider_update_pstats(old_referenced_bits); +#else // DO_PSTATS + NodeCachedReferenceCount::cache_unref_only(); +#endif // DO_PSTATS +} + /** * Reimplements NodeReferenceCount::node_unref(). We do this because we have * a non-virtual unref() method. @@ -769,7 +797,7 @@ do_node_unref() const { */ INLINE bool TransformState:: do_cache_unref() const { - cache_unref_only(); + NodeCachedReferenceCount::cache_unref_only(); return unref(); } diff --git a/panda/src/pgraph/transformState.h b/panda/src/pgraph/transformState.h index 75b4fedb0e..59a47daec7 100644 --- a/panda/src/pgraph/transformState.h +++ b/panda/src/pgraph/transformState.h @@ -213,6 +213,11 @@ public: INLINE static void flush_level(); + INLINE void cache_ref_only() const; + +protected: + INLINE void cache_unref_only() const; + private: INLINE bool do_cache_unref() const; INLINE bool do_node_unref() const;