From 6cb074e5c855806eae0f9951047e629db5b164b3 Mon Sep 17 00:00:00 2001 From: Disyer Date: Sun, 8 Jan 2023 17:58:30 +0200 Subject: [PATCH 1/5] distributed: Fix segfault when ConnectionRepository is verbose by holding GIL Also removes obsolete USE_PYTHON_2_2_OR_EARLIER macro Closes #1430 --- .../src/distributed/cConnectionRepository.cxx | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/direct/src/distributed/cConnectionRepository.cxx b/direct/src/distributed/cConnectionRepository.cxx index 16aea6e8dd..f04f280936 100644 --- a/direct/src/distributed/cConnectionRepository.cxx +++ b/direct/src/distributed/cConnectionRepository.cxx @@ -693,11 +693,7 @@ handle_update_field() { PyObject_GetAttrString(_python_repository, "doId2do"); nassertr(doId2do != nullptr, false); - #ifdef USE_PYTHON_2_2_OR_EARLIER - PyObject *doId = PyInt_FromLong(do_id); - #else PyObject *doId = PyLong_FromUnsignedLong(do_id); - #endif PyObject *distobj = PyDict_GetItem(doId2do, doId); Py_DECREF(doId); Py_DECREF(doId2do); @@ -784,11 +780,7 @@ handle_update_field_owner() { PyObject_GetAttrString(_python_repository, "doId2ownerView"); nassertr(doId2ownerView != nullptr, false); - #ifdef USE_PYTHON_2_2_OR_EARLIER - PyObject *doId = PyInt_FromLong(do_id); - #else PyObject *doId = PyLong_FromUnsignedLong(do_id); - #endif // pass the update to the owner view first PyObject *distobjOV = PyDict_GetItem(doId2ownerView, doId); @@ -893,7 +885,7 @@ describe_message(std::ostream &out, const string &prefix, packer.set_unpack_data((const char *)dg.get_data(), dg.get_length(), false); CHANNEL_TYPE do_id; - int msg_type; + unsigned int msg_type; bool is_update = false; string full_prefix = "CR::" + prefix; @@ -919,7 +911,12 @@ describe_message(std::ostream &out, const string &prefix, #ifdef HAVE_PYTHON if (_python_repository != nullptr) { - PyObject *msgId = PyLong_FromLong(msg_type); +#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS) + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); +#endif + + PyObject *msgId = PyLong_FromUnsignedLong(msg_type); nassertv(msgId != nullptr); #if PY_MAJOR_VERSION >= 3 PyObject *methodName = PyUnicode_FromString("_getMsgName"); @@ -941,6 +938,10 @@ describe_message(std::ostream &out, const string &prefix, Py_DECREF(methodName); Py_DECREF(msgId); Py_DECREF(result); + +#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS) + PyGILState_Release(gstate); +#endif } #endif if (msgName.length() == 0) { @@ -959,15 +960,16 @@ describe_message(std::ostream &out, const string &prefix, #ifdef HAVE_PYTHON if (_python_repository != nullptr) { +#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS) + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); +#endif + PyObject *doId2do = PyObject_GetAttrString(_python_repository, "doId2do"); nassertv(doId2do != nullptr); - #ifdef USE_PYTHON_2_2_OR_EARLIER - PyObject *doId = PyInt_FromLong(do_id); - #else PyObject *doId = PyLong_FromUnsignedLong(do_id); - #endif PyObject *distobj = PyDict_GetItem(doId2do, doId); Py_DECREF(doId); Py_DECREF(doId2do); @@ -983,6 +985,10 @@ describe_message(std::ostream &out, const string &prefix, dclass = (DCClass *)PyLong_AsVoidPtr(dclass_this); Py_DECREF(dclass_this); } + +#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS) + PyGILState_Release(gstate); +#endif } #endif // HAVE_PYTHON From 4b992105e117c28319b3de63433ec5d27ac7daab Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 16 Jan 2023 19:31:58 +0100 Subject: [PATCH 2/5] ShaderGenerator: Fix support for hardware point sprites In gp5fp and glslf profiles, we can rely on per-fragment point coordinates to be available, otherwise we have to emulate support by calculating it from the fragment pixel coordinates --- panda/src/display/graphicsStateGuardian.cxx | 2 +- panda/src/pgraphnodes/shaderGenerator.cxx | 63 ++++++++++++++++++++- panda/src/pgraphnodes/shaderGenerator.h | 6 +- 3 files changed, 68 insertions(+), 3 deletions(-) diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 1a39fd4ca6..7352afc85c 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -3679,7 +3679,7 @@ ensure_generated_shader(const RenderState *state) { if (!_supports_basic_shaders) { return; } - _shader_generator = new ShaderGenerator(this); + _shader_generator = new ShaderGenerator(_shader_caps, _supports_shadow_filter); } if (state->_generated_shader == nullptr || state->_generated_shader_seq != _generated_shader_seq) { diff --git a/panda/src/pgraphnodes/shaderGenerator.cxx b/panda/src/pgraphnodes/shaderGenerator.cxx index 5c9acef6d4..ed13b05a34 100644 --- a/panda/src/pgraphnodes/shaderGenerator.cxx +++ b/panda/src/pgraphnodes/shaderGenerator.cxx @@ -73,13 +73,33 @@ pack_combine(TextureStage::CombineSource src0, TextureStage::CombineOperand op0, static PStatCollector lookup_collector("*:Munge:ShaderGen:Lookup"); static PStatCollector synthesize_collector("*:Munge:ShaderGen:Synthesize"); +/** + * Create a ShaderGenerator. This has no state, except possibly to cache + * certain results. The given parameters contain information about the + * capabilities of the target for which the shader will be compiled. + */ +ShaderGenerator:: +ShaderGenerator(const Shader::ShaderCaps &caps, bool use_shadow_filter) : + _use_shadow_filter(use_shadow_filter) { + +#ifdef _WIN32 + // Check matches all OpenGL profiles + _use_generic_attr = (caps._active_vprofile <= 6151 || caps._active_vprofile >= 7000); +#else + _use_generic_attr = true; +#endif + + // Matches gp5fp and glslf profiles + _use_pointcoord = (caps._active_fprofile == 7017 || caps._active_fprofile == 7008); +} + /** * Create a ShaderGenerator. This has no state, except possibly to cache * certain results. The parameter that must be passed is the GSG to which the * shader generator belongs. */ ShaderGenerator:: -ShaderGenerator(const GraphicsStateGuardianBase *gsg) { +ShaderGenerator(const GraphicsStateGuardianBase *gsg) : _use_pointcoord(false) { // The ATTR# input semantics seem to map to generic vertex attributes in // both arbvp1 and glslv, which behave more consistently. However, they // don't exist in Direct3D 9. Use this silly little check for now. @@ -717,6 +737,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { const char *eye_position_freg = nullptr; const char *eye_normal_freg = nullptr; const char *hpos_freg = nullptr; + const char *pointcoord_freg = nullptr; const char *position_vreg; const char *transform_weight_vreg = nullptr; @@ -762,6 +783,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { bool need_eye_normal = !key._lights.empty() || ((key._outputs & AuxBitplaneAttrib::ABO_aux_normal) != 0); bool need_tangents = ((key._texture_flags & ShaderKey::TF_map_normal) != 0); bool need_point_size = (key._fog_mode & 0x10000) != 0; + bool need_point_coord = false; // If we have binormal/tangent and eye position, we can pack eye normal in // the w channels of the others. @@ -817,6 +839,9 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { case TexGenAttrib::M_eye_position: need_eye_position = true; break; + case TexGenAttrib::M_point_sprite: + need_point_coord = true; + break; default: break; } @@ -947,6 +972,13 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { text << "\t uniform float3 attr_pointparams,\n"; text << "\t out float l_point_size : PSIZE,\n"; } + if (need_point_coord && !_use_pointcoord) { + if (!need_point_size) { + text << "\t uniform float3 attr_pointparams,\n"; + } + pointcoord_freg = alloc_freg(); + text << "\t out float3 l_pointcoord : " << pointcoord_freg << ",\n"; + } text << "\t in float4 vtx_position : " << position_vreg << ",\n"; text << "\t out float4 l_position : POSITION,\n"; text << "\t uniform float4x4 mat_modelproj\n"; @@ -996,6 +1028,14 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { if (need_point_size) { text << "\t l_point_size = attr_pointparams.y + attr_pointparams.z / length(l_eye_position.xyz);\n"; } + if (need_point_coord && !_use_pointcoord) { + if (need_point_size) { + text << "\t l_pointcoord = float3(l_position.xy / (2.0f * l_position.w) + float2(0.5f, 0.5f), 1.0f / l_point_size);\n"; + } else { + // Static point size (non-perspective points) + text << "\t l_pointcoord = float3(l_position.xy / (2.0f * l_position.w) + float2(0.5f, 0.5f), 1.0f / attr_pointparams.x);\n"; + } + } pmap::const_iterator it; for (it = texcoord_fregs.begin(); it != texcoord_fregs.end(); ++it) { @@ -1047,6 +1087,17 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { text << "\t in uniform float4 attr_fog,\n"; text << "\t in uniform float4 attr_fogcolor,\n"; } + if (need_point_coord) { + if (_use_pointcoord) { + // In OpenGL, we have point coordinates available in glslf and gp5fp. + text << "\t in float2 l_pointcoord : POINTCOORD,\n"; + } else { + // In DirectX 9, we need to calculate them from the fragment coordinates. + text << "\t in float3 l_pointcoord : " << pointcoord_freg << ",\n"; + text << "\t in float2 l_fragcoord : WPOS,\n"; + text << "\t in uniform float2 sys_windowsize,\n"; + } + } if (need_world_position) { text << "\t in float4 l_world_position : " << world_position_freg << ",\n"; } @@ -1207,6 +1258,16 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { case TexGenAttrib::M_eye_position: text << "\t float4 texcoord" << i << " = float4(l_eye_position.xyz, 1.0f);\n"; break; + case TexGenAttrib::M_point_sprite: + if (_use_pointcoord) { + text << "\t float4 texcoord" << i << " = float4(l_pointcoord, 0.0f, 1.0f);\n"; + } else { + if (!_use_generic_attr) { + text << "\t l_fragcoord.y = sys_windowsize.y - l_fragcoord.y;\n"; + } + text << "\t float4 texcoord" << i << " = float4((l_fragcoord - l_pointcoord.xy * sys_windowsize) * l_pointcoord.z * float2(1.0f, -1.0f) - float2(0.5f, 0.5f), 0.0f, 1.0f);\n"; + } + break; case TexGenAttrib::M_constant: text << "\t float4 texcoord" << i << " = texconst_" << i << ";\n"; break; diff --git a/panda/src/pgraphnodes/shaderGenerator.h b/panda/src/pgraphnodes/shaderGenerator.h index 749f25a35d..0cae67dc7e 100644 --- a/panda/src/pgraphnodes/shaderGenerator.h +++ b/panda/src/pgraphnodes/shaderGenerator.h @@ -64,6 +64,9 @@ class GeomVertexAnimationSpec; * */ class EXPCL_PANDA_PGRAPHNODES ShaderGenerator : public TypedReferenceCount { +public: + ShaderGenerator(const Shader::ShaderCaps &caps, bool use_shadow_filter); + PUBLISHED: ShaderGenerator(const GraphicsStateGuardianBase *gsg); virtual ~ShaderGenerator(); @@ -76,7 +79,8 @@ PUBLISHED: protected: // Shader register allocation: - bool _use_generic_attr; + bool _use_generic_attr : 1; + bool _use_pointcoord : 1; int _vcregs_used; int _fcregs_used; int _vtregs_used; From 518ee0fb8ebdd744630849228e132f7e64f9e825 Mon Sep 17 00:00:00 2001 From: LD Date: Fri, 20 Jan 2023 18:16:43 +0100 Subject: [PATCH 3/5] cocoadisplay: Capture display before switching to fullscreen mode --- panda/src/cocoadisplay/cocoaGraphicsWindow.mm | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/panda/src/cocoadisplay/cocoaGraphicsWindow.mm b/panda/src/cocoadisplay/cocoaGraphicsWindow.mm index f65e97a0cc..f0388a7ada 100644 --- a/panda/src/cocoadisplay/cocoaGraphicsWindow.mm +++ b/panda/src/cocoadisplay/cocoaGraphicsWindow.mm @@ -1417,7 +1417,11 @@ do_switch_fullscreen(CFDictionaryRef mode) { #else CGDisplaySwitchToMode(_display, _windowed_mode); #endif - CGDisplayRelease(_display); + if (CGDisplayIsMain(_display)) { + CGReleaseAllDisplays(); + } else { + CGDisplayRelease(_display); + } _windowed_mode = NULL; _context_needs_update = true; @@ -1436,7 +1440,21 @@ do_switch_fullscreen(CFDictionaryRef mode) { _fullscreen_mode = mode; _context_needs_update = true; + // Display must be captured by the application before switching mode. + // If not, the change of mode and resolution will be applied on all the other applications, + // although they are no longer visible. + // This also leads to weird bugs when switching back to the desktop mode. CGError err; + if (CGDisplayIsMain(_display)) { + // In multidisplay setup, all the displays must be captured or the switch will be notified anyway. + err = CGCaptureAllDisplays(); + } else { + err = CGDisplayCapture(_display); + } + if (err != kCGErrorSuccess) { + return false; + } + #if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 err = CGDisplaySetDisplayMode(_display, _fullscreen_mode, NULL); #else @@ -1444,11 +1462,14 @@ do_switch_fullscreen(CFDictionaryRef mode) { #endif if (err != kCGErrorSuccess) { + if (CGDisplayIsMain(_display)) { + CGReleaseAllDisplays(); + } else { + CGDisplayRelease(_display); + } return false; } - CGDisplayCapture(_display); - NSRect frame = [[[_view window] screen] frame]; if (cocoadisplay_cat.is_debug()) { NSString *str = NSStringFromRect(frame); From e14d43ebe50045bf57e4e842c07f9217be22c868 Mon Sep 17 00:00:00 2001 From: Fireclaw Date: Mon, 23 Jan 2023 20:19:59 +0100 Subject: [PATCH 4/5] dmodels: Fixed broken minusnode icon Closes #1449 --- dmodels/src/icons/minusnode.gif | Bin 76 -> 75 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/dmodels/src/icons/minusnode.gif b/dmodels/src/icons/minusnode.gif index 24b7e916f7c05561c5d171bbbe528d29fc45a51c..22587539adda2c31b1f2cb5ea96ede26ea1ace35 100644 GIT binary patch literal 75 zcmZ?wbhEHb_4N!43 Date: Fri, 27 Jan 2023 10:40:47 +0100 Subject: [PATCH 5/5] vision: Fix another use of wrong delete operator in ARToolKit code --- panda/src/vision/arToolKit.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda/src/vision/arToolKit.cxx b/panda/src/vision/arToolKit.cxx index ed7d019680..cf328a2afd 100644 --- a/panda/src/vision/arToolKit.cxx +++ b/panda/src/vision/arToolKit.cxx @@ -475,7 +475,7 @@ analyze(Texture *tex, bool do_flip_texture) { } } - delete data; + delete[] data; } #endif // HAVE_ARTOOLKIT