diff --git a/dtool/src/dtoolbase/patomic.cxx b/dtool/src/dtoolbase/patomic.cxx index 47da5a01768..15fef9a1e2e 100644 --- a/dtool/src/dtoolbase/patomic.cxx +++ b/dtool/src/dtoolbase/patomic.cxx @@ -128,7 +128,13 @@ initialize_wait(volatile VOID *addr, PVOID cmp, SIZE_T size, DWORD timeout) { #elif !defined(CPPPARSER) && !defined(__linux__) && !defined(__APPLE__) && !defined(__FreeBSD__) && defined(HAVE_POSIX_THREADS) // Same as above, but using pthreads. -struct alignas(64) WaitTableEntry { +struct +#ifdef __APPLE__ && defined(__arm64__) +alignas(128) +#else +alignas(64) +#endif +WaitTableEntry { pthread_mutex_t _lock = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t _cvar = PTHREAD_COND_INITIALIZER; unsigned int _waiters = 0; diff --git a/panda/src/grutil/cardMaker.I b/panda/src/grutil/cardMaker.I index bc329f8291a..270eaa0f071 100644 --- a/panda/src/grutil/cardMaker.I +++ b/panda/src/grutil/cardMaker.I @@ -19,20 +19,17 @@ CardMaker(std::string name) : Namable(std::move(name)) { reset(); } -/** - * - */ -INLINE CardMaker:: -~CardMaker() { -} - /** * Sets the flag indicating whether vertices will be generated with UV's or * not. */ INLINE void CardMaker:: set_has_uvs(bool flag) { - _has_uvs = flag; + if (flag) { + _flags |= F_has_uvs; + } else { + _flags &= ~F_has_uvs; + } } /** @@ -42,7 +39,11 @@ set_has_uvs(bool flag) { */ INLINE void CardMaker:: set_has_3d_uvs(bool flag) { - _has_3d_uvs = flag; + if (flag) { + _flags |= F_has_3d_uvs; + } else { + _flags &= ~F_has_3d_uvs; + } } /** @@ -50,10 +51,10 @@ set_has_3d_uvs(bool flag) { */ INLINE void CardMaker:: set_frame(PN_stdfloat left, PN_stdfloat right, PN_stdfloat bottom, PN_stdfloat top) { - _ll_pos = LVector3::rfu(left, 0.0f, bottom); - _lr_pos = LVector3::rfu(right, 0.0f, bottom); - _ur_pos = LVector3::rfu(right, 0.0f, top); - _ul_pos = LVector3::rfu(left, 0.0f, top); + _ll_pos = LVertex::rfu(left, 0.0f, bottom); + _lr_pos = LVertex::rfu(right, 0.0f, bottom); + _ur_pos = LVertex::rfu(right, 0.0f, top); + _ul_pos = LVertex::rfu(left, 0.0f, top); } /** @@ -98,7 +99,7 @@ set_color(PN_stdfloat r, PN_stdfloat g, PN_stdfloat b, PN_stdfloat a) { INLINE void CardMaker:: set_color(const LVecBase4 &color) { _color = color; - _has_color = true; + _flags |= F_has_color; } /** @@ -106,7 +107,7 @@ set_color(const LVecBase4 &color) { */ INLINE void CardMaker:: clear_color() { - _has_color = false; + _flags &= ~F_has_color; _color.set(1.0f, 1.0f, 1.0f, 1.0f); } @@ -119,7 +120,11 @@ clear_color() { */ INLINE void CardMaker:: set_has_normals(bool flag) { - _has_normals = flag; + if (flag) { + _flags |= F_has_normals; + } else { + _flags &= ~F_has_normals; + } } /** diff --git a/panda/src/grutil/cardMaker.cxx b/panda/src/grutil/cardMaker.cxx index 33f6fc88ad1..bbab02cc739 100644 --- a/panda/src/grutil/cardMaker.cxx +++ b/panda/src/grutil/cardMaker.cxx @@ -26,13 +26,13 @@ */ void CardMaker:: reset() { + _flags = F_has_normals; + set_frame(0.0f, 1.0f, 0.0f, 1.0f); set_uv_range(LTexCoord(0.0f, 0.0f), LTexCoord(1.0f, 1.0f)); - _has_color = false; _color.set(1.0f, 1.0f, 1.0f, 1.0f); - _has_normals = true; _source_geometry = nullptr; _source_frame.set(0.0f, 0.0f, 0.0f, 0.0f); } @@ -50,9 +50,9 @@ generate() { PT(GeomNode) gnode = new GeomNode(get_name()); CPT(GeomVertexFormat) format; - if (_has_normals) { - if (_has_uvs) { - if (_has_3d_uvs) { + if (_flags & F_has_normals) { + if (_flags & F_has_uvs) { + if (_flags & F_has_3d_uvs) { format = GeomVertexFormat::register_format (new GeomVertexArrayFormat (InternalName::get_vertex(), 3, @@ -68,8 +68,8 @@ generate() { format = GeomVertexFormat::get_v3n3(); } } else { - if (_has_uvs) { - if (_has_3d_uvs) { + if (_flags & F_has_uvs) { + if (_flags & F_has_3d_uvs) { format = GeomVertexFormat::register_format (new GeomVertexArrayFormat (InternalName::get_vertex(), 3, @@ -86,36 +86,37 @@ generate() { PT(GeomVertexData) vdata = new GeomVertexData ("card", format, Geom::UH_static); + vdata->unclean_set_num_rows(4); GeomVertexWriter vertex(vdata, InternalName::get_vertex()); - vertex.add_data3(_ul_pos); - vertex.add_data3(_ll_pos); - vertex.add_data3(_ur_pos); - vertex.add_data3(_lr_pos); + vertex.set_data3(_ul_pos); + vertex.set_data3(_ll_pos); + vertex.set_data3(_ur_pos); + vertex.set_data3(_lr_pos); - if (_has_uvs) { + if (_flags & F_has_uvs) { GeomVertexWriter texcoord(vdata, InternalName::get_texcoord()); - texcoord.add_data3(_ul_tex); - texcoord.add_data3(_ll_tex); - texcoord.add_data3(_ur_tex); - texcoord.add_data3(_lr_tex); + texcoord.set_data3(_ul_tex); + texcoord.set_data3(_ll_tex); + texcoord.set_data3(_ur_tex); + texcoord.set_data3(_lr_tex); } - if (_has_normals) { + if (_flags & F_has_normals) { GeomVertexWriter normal(vdata, InternalName::get_normal()); LVector3 n; n = (_ll_pos - _ul_pos).cross(_ur_pos - _ul_pos); n.normalize(); - normal.add_data3(n); + normal.set_data3(n); n = (_lr_pos - _ll_pos).cross(_ul_pos - _ll_pos); n.normalize(); - normal.add_data3(n); + normal.set_data3(n); n = (_ul_pos - _ur_pos).cross(_lr_pos - _ur_pos); n.normalize(); - normal.add_data3(n); + normal.set_data3(n); n = (_ur_pos - _lr_pos).cross(_ll_pos - _lr_pos); n.normalize(); - normal.add_data3(n); + normal.set_data3(n); } PT(GeomTristrips) strip = new GeomTristrips(Geom::UH_static); @@ -127,7 +128,7 @@ generate() { geom->add_primitive(strip); CPT(RenderState) state = RenderState::make_empty(); - if (_has_color) { + if (_flags & F_has_color) { state = RenderState::make(ColorAttrib::make_flat(_color)); } @@ -148,8 +149,7 @@ set_uv_range(const LTexCoord3 &ll, const LTexCoord3 &lr, const LTexCoord3 &ur, c _lr_tex = lr; _ur_tex = ur; _ul_tex = ul; - _has_uvs = true; - _has_3d_uvs = true; + _flags |= F_has_uvs | F_has_3d_uvs; } /** @@ -164,8 +164,7 @@ set_uv_range(const LTexCoord &ll, const LTexCoord &lr, const LTexCoord &ur, cons _lr_tex.set(lr[0], lr[1], 0.0f); _ur_tex.set(ur[0], ur[1], 0.0f); _ul_tex.set(ul[0], ul[1], 0.0f); - _has_uvs = true; - _has_3d_uvs = false; + _flags = (_flags | F_has_uvs) & ~F_has_3d_uvs; } /** @@ -180,8 +179,7 @@ set_uv_range(const LTexCoord &ll, const LTexCoord &ur) { _lr_tex.set(ur[0], ll[1], 0.0f); _ur_tex.set(ur[0], ur[1], 0.0f); _ul_tex.set(ll[0], ur[1], 0.0f); - _has_uvs = true; - _has_3d_uvs = false; + _flags = (_flags | F_has_uvs) & ~F_has_3d_uvs; } /** @@ -196,8 +194,7 @@ set_uv_range(const LVector4 &x, const LVector4 &y, const LVector4 &z) { _lr_tex.set(x[1], y[1], z[1]); _ur_tex.set(x[2], y[2], z[2]); _ul_tex.set(x[3], y[3], z[3]); - _has_uvs = true; - _has_3d_uvs = true; + _flags |= F_has_uvs | F_has_3d_uvs; } /** @@ -259,7 +256,7 @@ rescale_source_geometry() { TransformState::make_pos_hpr_scale(trans, LPoint3(0.0f, 0.0f, 0.0f), scale); root->set_transform(transform); - if (_has_color) { + if (_flags & F_has_color) { root->set_attrib(ColorAttrib::make_flat(_color)); } diff --git a/panda/src/grutil/cardMaker.h b/panda/src/grutil/cardMaker.h index d930ac70392..435f0803b6d 100644 --- a/panda/src/grutil/cardMaker.h +++ b/panda/src/grutil/cardMaker.h @@ -29,7 +29,7 @@ class EXPCL_PANDA_GRUTIL CardMaker : public Namable { PUBLISHED: INLINE explicit CardMaker(std::string name); - INLINE ~CardMaker(); + ~CardMaker() = default; void reset(); void set_uv_range(const LTexCoord &ll, const LTexCoord &ur); @@ -61,14 +61,19 @@ class EXPCL_PANDA_GRUTIL CardMaker : public Namable { private: PT(PandaNode) rescale_source_geometry(); - bool _has_uvs, _has_3d_uvs; - LVertex _ul_tex, _ll_tex, _lr_tex, _ur_tex; - LTexCoord3 _ul_pos, _ll_pos, _lr_pos, _ur_pos; + enum Flags { + F_has_uvs = 1, + F_has_3d_uvs = 2, + F_has_color = 4, + F_has_normals = 8, + }; - bool _has_color; - LColor _color; + int _flags; + + LVertex _ul_pos, _ll_pos, _lr_pos, _ur_pos; + LTexCoord3 _ul_tex, _ll_tex, _lr_tex, _ur_tex; - bool _has_normals; + LColor _color; PT(PandaNode) _source_geometry; LVecBase4 _source_frame; diff --git a/tests/prc/test_assert_guard.cxx b/tests/prc/test_assert_guard.cxx new file mode 100644 index 00000000000..1bf85d29d3c --- /dev/null +++ b/tests/prc/test_assert_guard.cxx @@ -0,0 +1,51 @@ +/** + * PANDA 3D SOFTWARE + * Copyright (c) Carnegie Mellon University. All rights reserved. + * + * All use of this software is subject to the terms of the revised BSD + * license. You should have received a copy of this license along + * with this source code in a file named "LICENSE." + * + * @file test_assert_guard.cxx + * @author rdb + * @date 2026-07-19 + */ + +#include "pnotify.h" + +#include "catch_amalgamated.hpp" + +/** + * Routes a Panda assertion failure (nassertr and friends) into Catch2 as a + * test failure at the point where it fired, rather than letting the test + * pass with only a line on the notify output. Returning true preserves the + * normal no-abort behavior: the asserting function bails out with its + * default return value. + */ +static bool +catch2_assert_handler(const char *expression, int line, const char *source_file) { + FAIL_CHECK("Assertion failed: " << expression << " at line " << line << " of " << source_file); + return true; +} + +/** + * Installs the assert handler for the duration of each test case, so that a + * test that trips an assertion fails even if all of its CHECKs pass. A test + * that intentionally provokes an assertion can temporarily install its own + * handler; this listener reinstates the guard for the next test case. + */ +class PandaAssertListener final : public Catch::EventListenerBase { +public: + using Catch::EventListenerBase::EventListenerBase; + + void testCaseStarting(const Catch::TestCaseInfo &) override { + Notify::ptr()->set_assert_handler(&catch2_assert_handler); + } + + void testCaseEnded(const Catch::TestCaseStats &) override { + Notify::ptr()->clear_assert_handler(); + Notify::ptr()->clear_assert_failed(); + } +}; + +CATCH_REGISTER_LISTENER(PandaAssertListener)