diff --git a/dtool/src/dtoolbase/dtoolbase.cxx b/dtool/src/dtoolbase/dtoolbase.cxx index a45a1de4e0..3bd34815c9 100644 --- a/dtool/src/dtoolbase/dtoolbase.cxx +++ b/dtool/src/dtoolbase/dtoolbase.cxx @@ -62,4 +62,12 @@ default_thread_consider_yield() { void (*global_thread_yield)() = default_thread_yield; void (*global_thread_consider_yield)() = default_thread_consider_yield; +#ifdef HAVE_PYTHON +static PyThreadState * +default_thread_state_swap(PyThreadState *state) { + return nullptr; +} +PyThreadState *(*global_thread_state_swap)(PyThreadState *tstate) = default_thread_state_swap; +#endif // HAVE_PYTHON + #endif // HAVE_THREADS && SIMPLE_THREADS diff --git a/dtool/src/dtoolbase/dtoolbase_cc.h b/dtool/src/dtoolbase/dtoolbase_cc.h index 36da6b2b0b..8894469422 100644 --- a/dtool/src/dtoolbase/dtoolbase_cc.h +++ b/dtool/src/dtoolbase/dtoolbase_cc.h @@ -233,6 +233,15 @@ INLINE void thread_consider_yield() { (*global_thread_consider_yield)(); } +#ifdef HAVE_PYTHON +typedef struct _ts PyThreadState; +extern EXPCL_DTOOL_DTOOLBASE PyThreadState *(*global_thread_state_swap)(PyThreadState *tstate); + +INLINE PyThreadState *thread_state_swap(PyThreadState *tstate) { + return (*global_thread_state_swap)(tstate); +} +#endif // HAVE_PYTHON + #else INLINE void thread_yield() { diff --git a/dtool/src/dtoolutil/textEncoder.I b/dtool/src/dtoolutil/textEncoder.I index c9eeb0ec66..aa6b42fdb5 100644 --- a/dtool/src/dtoolutil/textEncoder.I +++ b/dtool/src/dtoolutil/textEncoder.I @@ -316,7 +316,7 @@ unicode_ispunct(char32_t character) { const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character); if (entry == nullptr) { // Some punctuation marks aren't listed in the map. - return (character >= 0 && character < 128 && ispunct(character)); + return (character < 128 && ispunct(character)); } return entry->_char_type == UnicodeLatinMap::CT_punct; } diff --git a/dtool/src/interrogatedb/py_panda.cxx b/dtool/src/interrogatedb/py_panda.cxx index 38e774eb88..b2fa4ba3a1 100644 --- a/dtool/src/interrogatedb/py_panda.cxx +++ b/dtool/src/interrogatedb/py_panda.cxx @@ -754,6 +754,11 @@ PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) { PyErr_Clear(); } initialized_main_dir = true; + + // Also, while we are at it, initialize the thread swap hook. +#if defined(HAVE_THREADS) && defined(SIMPLE_THREADS) + global_thread_state_swap = PyThreadState_Swap; +#endif } PyModule_AddIntConstant(module, "Dtool_PyNativeInterface", 1); diff --git a/dtool/src/parser-inc/Python.h b/dtool/src/parser-inc/Python.h index ddd660072d..5f1a98a825 100644 --- a/dtool/src/parser-inc/Python.h +++ b/dtool/src/parser-inc/Python.h @@ -28,7 +28,7 @@ typedef _typeobject PyTypeObject; typedef struct {} PyStringObject; typedef struct {} PyUnicodeObject; -class PyThreadState; +typedef struct _ts PyThreadState; typedef int Py_ssize_t; typedef struct bufferinfo Py_buffer; diff --git a/panda/src/glstuff/glGraphicsBuffer_src.cxx b/panda/src/glstuff/glGraphicsBuffer_src.cxx index eab850bdba..d5a8763fc8 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.cxx +++ b/panda/src/glstuff/glGraphicsBuffer_src.cxx @@ -1097,6 +1097,15 @@ bind_slot_multisample(bool rb_resize, Texture **attach, RenderTexturePlane slot, #endif glgsg->_glBindRenderbuffer(GL_RENDERBUFFER_EXT, _rbm[slot]); GLuint format = GL_DEPTH_COMPONENT; +#ifndef OPENGLES + if (_fb_properties.get_float_depth()) { + if (!glgsg->_use_remapped_depth_range) { + format = GL_DEPTH_COMPONENT32F; + } else { + format = GL_DEPTH_COMPONENT32F_NV; + } + } else +#endif if (tex) { switch (tex->get_format()) { case Texture::F_depth_component16: diff --git a/panda/src/gobj/preparedGraphicsObjects.cxx b/panda/src/gobj/preparedGraphicsObjects.cxx index 4f6ecea1ed..96fcd80269 100644 --- a/panda/src/gobj/preparedGraphicsObjects.cxx +++ b/panda/src/gobj/preparedGraphicsObjects.cxx @@ -1619,8 +1619,8 @@ begin_frame(GraphicsStateGuardianBase *gsg, Thread *current_thread) { ++qsi) { Shader *shader = qsi->first; ShaderContext *sc = shader->prepare_now(this, gsg); - if (qti->second != nullptr) { - qti->second->set_result(sc); + if (qsi->second != nullptr) { + qsi->second->set_result(sc); } } diff --git a/panda/src/gobj/textureReloadRequest.cxx b/panda/src/gobj/textureReloadRequest.cxx index 4c17b550b7..b63acb6090 100644 --- a/panda/src/gobj/textureReloadRequest.cxx +++ b/panda/src/gobj/textureReloadRequest.cxx @@ -40,7 +40,7 @@ do_task() { // become a kind of a leak (if the texture is never rendered again on // this GSG, we'll just end up carrying the texture memory in RAM // forever, instead of dumping it as soon as it gets prepared). - _texture->prepare(_pgo); + _pgo->enqueue_texture(_texture); } } diff --git a/panda/src/net/connection.cxx b/panda/src/net/connection.cxx index aecfc111ac..27f5c8bb24 100644 --- a/panda/src/net/connection.cxx +++ b/panda/src/net/connection.cxx @@ -445,7 +445,7 @@ do_flush() { if (data_sent > 0) { total_sent += data_sent; } - double last_report = 0; + while (!okflag && tcp->Active() && (data_sent > 0 || tcp->GetLastError() == LOCAL_BLOCKING_ERROR)) { if (data_sent == 0) { diff --git a/panda/src/pipeline/blockerSimple.I b/panda/src/pipeline/blockerSimple.I index 0188281728..89be34a412 100644 --- a/panda/src/pipeline/blockerSimple.I +++ b/panda/src/pipeline/blockerSimple.I @@ -11,14 +11,6 @@ * @date 2007-06-20 */ -/** - * - */ -INLINE BlockerSimple:: -BlockerSimple() { - _flags = 0; -} - /** * */ diff --git a/panda/src/pipeline/blockerSimple.h b/panda/src/pipeline/blockerSimple.h index 71ae25c41d..d375d5dc16 100644 --- a/panda/src/pipeline/blockerSimple.h +++ b/panda/src/pipeline/blockerSimple.h @@ -28,7 +28,7 @@ */ class EXPCL_PANDA_PIPELINE BlockerSimple { protected: - INLINE BlockerSimple(); + constexpr BlockerSimple() = default; INLINE ~BlockerSimple(); protected: @@ -38,7 +38,7 @@ protected: F_has_waiters = 0x40000000, }; - unsigned int _flags; + unsigned int _flags = 0; friend class ThreadSimpleManager; }; diff --git a/panda/src/pipeline/contextSwitch_longjmp_src.c b/panda/src/pipeline/contextSwitch_longjmp_src.c index c3640b8f1f..5dec92804a 100644 --- a/panda/src/pipeline/contextSwitch_longjmp_src.c +++ b/panda/src/pipeline/contextSwitch_longjmp_src.c @@ -1,8 +1,4 @@ -/* Filename: contextSwitch_longjmp_src.c - * Created by: drose (15Apr10) - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * +/** * PANDA 3D SOFTWARE * Copyright (c) Carnegie Mellon University. All rights reserved. * @@ -10,7 +6,10 @@ * license. You should have received a copy of this license along * with this source code in a file named "LICENSE." * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + * @file contextSwitch_longjmp_src.c + * @author drose + * @date 2010-04-15 + */ /* This is the implementation of user-space context switching using setmp() / longjmp(). This is the hackier implementation, @@ -90,14 +89,14 @@ void cs_longjmp(cs_jmp_buf env) { _asm { mov eax, env; - + mov ebx, [eax + 0]; mov edi, [eax + 4]; mov esi, [eax + 8]; mov ebp, [eax + 12]; mov esp, [eax + 16]; mov edx, [eax + 20]; - + frstor [eax + 24]; /* restore floating-point state */ mov eax, 1; /* return 1 from setjmp: pass 2 return */ @@ -251,7 +250,7 @@ setup_context_1(void) { } void -init_thread_context(struct ThreadContext *context, +init_thread_context(struct ThreadContext *context, unsigned char *stack, size_t stack_size, ThreadFunction *thread_func, void *data) { /* Copy all of the input parameters to static variables, then begin @@ -263,7 +262,7 @@ init_thread_context(struct ThreadContext *context, st_data = data; setup_context_1(); -} +} void save_thread_context(struct ThreadContext *context, diff --git a/panda/src/pipeline/contextSwitch_posix_src.c b/panda/src/pipeline/contextSwitch_posix_src.c index 6f5df46445..f553cefc45 100644 --- a/panda/src/pipeline/contextSwitch_posix_src.c +++ b/panda/src/pipeline/contextSwitch_posix_src.c @@ -1,8 +1,4 @@ -/* Filename: contextSwitch_posix_src.c - * Created by: drose (15Apr10) - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * +/** * PANDA 3D SOFTWARE * Copyright (c) Carnegie Mellon University. All rights reserved. * @@ -10,7 +6,10 @@ * license. You should have received a copy of this license along * with this source code in a file named "LICENSE." * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + * @file contextSwitch_posix_src.c + * @author drose + * @date 2010-04-15 + */ /* This is the implementation of user-space context switching using posix threads to manage the different execution contexts. This @@ -44,7 +43,7 @@ struct ThreadContext { pthread_mutex_t _ready_mutex; pthread_cond_t _ready_cvar; int _ready_flag; - + /* This is set FALSE while the thread is alive, and TRUE if the thread is to be terminated when it next wakes up. */ int _terminated; @@ -83,19 +82,19 @@ thread_main(void *data) { } void -init_thread_context(struct ThreadContext *context, +init_thread_context(struct ThreadContext *context, unsigned char *stack, size_t stack_size, ThreadFunction *thread_func, void *data) { context->_thread_func = thread_func; context->_data = data; - pthread_attr_t attr; - pthread_attr_init(&attr); + pthread_attr_t attr; + pthread_attr_init(&attr); pthread_attr_setstacksize(&attr, stack_size); - pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); + pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); - pthread_create(&(context->_thread), &attr, thread_main, context); - pthread_attr_destroy(&attr); + pthread_create(&(context->_thread), &attr, thread_main, context); + pthread_attr_destroy(&attr); } void @@ -142,7 +141,7 @@ switch_to_thread_context(struct ThreadContext *from_context, /* We've been rudely terminated. Exit gracefully. */ pthread_exit(NULL); } - + /* Now we have been signaled again, and we're ready to resume the thread. */ longjmp(from_context->_jmp_context, 1); @@ -164,7 +163,7 @@ alloc_thread_context() { pthread_mutexattr_init(&attr); // The symbol PTHREAD_MUTEX_DEFAULT isn't always available? // pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_DEFAULT); - int result = pthread_mutex_init(&context->_ready_mutex, &attr); + pthread_mutex_init(&context->_ready_mutex, &attr); pthread_mutexattr_destroy(&attr); pthread_cond_init(&context->_ready_cvar, NULL); diff --git a/panda/src/pipeline/contextSwitch_ucontext_src.c b/panda/src/pipeline/contextSwitch_ucontext_src.c index f589dbb5bf..f08c6d9afe 100644 --- a/panda/src/pipeline/contextSwitch_ucontext_src.c +++ b/panda/src/pipeline/contextSwitch_ucontext_src.c @@ -1,8 +1,4 @@ -/* Filename: contextSwitch_ucontext_src.c - * Created by: drose (15Apr10) - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * +/** * PANDA 3D SOFTWARE * Copyright (c) Carnegie Mellon University. All rights reserved. * @@ -10,7 +6,10 @@ * license. You should have received a copy of this license along * with this source code in a file named "LICENSE." * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + * @file contextSwitch_ucontext_src.c + * @author drose + * @date 2010-04-15 + */ /* This is the implementation of user-space context switching using getcontext() / setcontext(). This is the preferred implementation, @@ -43,7 +42,7 @@ begin_context(ThreadFunction *thread_func, void *data) { } void -init_thread_context(struct ThreadContext *context, +init_thread_context(struct ThreadContext *context, unsigned char *stack, size_t stack_size, ThreadFunction *thread_func, void *data) { if (getcontext(&context->_ucontext) != 0) { diff --git a/panda/src/pipeline/contextSwitch_windows_src.c b/panda/src/pipeline/contextSwitch_windows_src.c index 9f157d8eec..727eef43b9 100644 --- a/panda/src/pipeline/contextSwitch_windows_src.c +++ b/panda/src/pipeline/contextSwitch_windows_src.c @@ -1,8 +1,4 @@ -/* Filename: contextSwitch_windows_src.c - * Created by: drose (15Apr10) - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * +/** * PANDA 3D SOFTWARE * Copyright (c) Carnegie Mellon University. All rights reserved. * @@ -10,7 +6,10 @@ * license. You should have received a copy of this license along * with this source code in a file named "LICENSE." * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + * @file contextSwitch_windows_src.c + * @author drose + * @date 2010-04-15 + */ /* This is the implementation of user-space context switching using native Windows threading constructs to manage the different @@ -37,7 +36,7 @@ struct ThreadContext { /* This event is in the signaled state when the thread is ready to roll. */ HANDLE _ready; - + /* This is set FALSE while the thread is alive, and TRUE if the thread is to be terminated when it next wakes up. */ int _terminated; @@ -71,13 +70,13 @@ thread_main(LPVOID data) { } void -init_thread_context(struct ThreadContext *context, +init_thread_context(struct ThreadContext *context, unsigned char *stack, size_t stack_size, ThreadFunction *thread_func, void *data) { context->_thread_func = thread_func; context->_data = data; - context->_thread = CreateThread(NULL, stack_size, + context->_thread = CreateThread(NULL, stack_size, thread_main, context, 0, NULL); } @@ -117,7 +116,7 @@ switch_to_thread_context(struct ThreadContext *from_context, /* We've been rudely terminated. Exit gracefully. */ ExitThread(1); } - + /* Now we have been signaled again, and we're ready to resume the thread. */ longjmp(from_context->_jmp_context, 1); diff --git a/panda/src/pipeline/pythonThread.cxx b/panda/src/pipeline/pythonThread.cxx index ab41070fb8..53a811401e 100644 --- a/panda/src/pipeline/pythonThread.cxx +++ b/panda/src/pipeline/pythonThread.cxx @@ -225,7 +225,7 @@ call_python_func(PyObject *function, PyObject *args) { } else { // No exception. Restore the thread state normally. - PyThreadState *state = PyThreadState_Swap(orig_thread_state); + PyThreadState_Swap(orig_thread_state); thread_states.push_back(new_thread_state); // PyThreadState_Clear(new_thread_state); // PyThreadState_Delete(new_thread_state); diff --git a/panda/src/pipeline/threadSimpleImpl.I b/panda/src/pipeline/threadSimpleImpl.I index 001f3037d4..d712892883 100644 --- a/panda/src/pipeline/threadSimpleImpl.I +++ b/panda/src/pipeline/threadSimpleImpl.I @@ -51,14 +51,6 @@ is_threading_supported() { return true; } -/** - * - */ -INLINE bool ThreadSimpleImpl:: -is_true_threads() { - return (is_os_threads != 0); -} - /** * */ diff --git a/panda/src/pipeline/threadSimpleImpl.cxx b/panda/src/pipeline/threadSimpleImpl.cxx index a631421503..14d6f7561f 100644 --- a/panda/src/pipeline/threadSimpleImpl.cxx +++ b/panda/src/pipeline/threadSimpleImpl.cxx @@ -141,8 +141,8 @@ start(ThreadPriority priority, bool joinable) { #ifdef HAVE_PYTHON // Query the current Python thread state. - _python_state = PyThreadState_Swap(nullptr); - PyThreadState_Swap(_python_state); + _python_state = thread_state_swap(nullptr); + thread_state_swap(_python_state); #endif // HAVE_PYTHON init_thread_context(_context, _stack, _stack_size, st_begin_thread, this); @@ -201,6 +201,14 @@ prepare_for_exit() { manager->prepare_for_exit(); } +/** + * + */ +bool ThreadSimpleImpl:: +is_true_threads() { + return (is_os_threads != 0); +} + /** * */ @@ -238,7 +246,7 @@ st_begin_thread(void *data) { void ThreadSimpleImpl:: begin_thread() { #ifdef HAVE_PYTHON - PyThreadState_Swap(_python_state); + thread_state_swap(_python_state); #endif // HAVE_PYTHON #ifdef HAVE_POSIX_THREADS diff --git a/panda/src/pipeline/threadSimpleImpl.h b/panda/src/pipeline/threadSimpleImpl.h index c552dd1357..5bd6af3fdc 100644 --- a/panda/src/pipeline/threadSimpleImpl.h +++ b/panda/src/pipeline/threadSimpleImpl.h @@ -63,7 +63,7 @@ public: INLINE static void bind_thread(Thread *thread); INLINE static bool is_threading_supported(); - INLINE static bool is_true_threads(); + static bool is_true_threads(); INLINE static bool is_simple_threads(); INLINE static void sleep(double seconds); INLINE static void yield(); diff --git a/panda/src/pipeline/threadSimpleManager.cxx b/panda/src/pipeline/threadSimpleManager.cxx index 4d9890dfd4..861e19cd77 100644 --- a/panda/src/pipeline/threadSimpleManager.cxx +++ b/panda/src/pipeline/threadSimpleManager.cxx @@ -20,7 +20,9 @@ #include "mainThread.h" #ifdef WIN32 -#define WIN32_LEAN_AND_MEAN +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif #include #endif @@ -235,7 +237,7 @@ next_context() { #ifdef HAVE_PYTHON // Save the current Python thread state. - _current_thread->_python_state = PyThreadState_Swap(nullptr); + _current_thread->_python_state = thread_state_swap(nullptr); #endif // HAVE_PYTHON #ifdef DO_PSTATS @@ -256,7 +258,7 @@ next_context() { #endif // DO_PSTATS #ifdef HAVE_PYTHON - PyThreadState_Swap(_current_thread->_python_state); + thread_state_swap(_current_thread->_python_state); #endif // HAVE_PYTHON } @@ -468,16 +470,6 @@ init_pointers() { _pointers_initialized = true; _global_ptr = new ThreadSimpleManager; Thread::get_main_thread(); - -#ifdef HAVE_PYTHON - // Ensure that the Python threading system is initialized and ready to go. - -#if PY_VERSION_HEX >= 0x03020000 - Py_Initialize(); -#endif - - PyEval_InitThreads(); -#endif } } diff --git a/panda/src/windisplay/winGraphicsWindow.cxx b/panda/src/windisplay/winGraphicsWindow.cxx index b42ee43992..703aba0149 100644 --- a/panda/src/windisplay/winGraphicsWindow.cxx +++ b/panda/src/windisplay/winGraphicsWindow.cxx @@ -293,13 +293,29 @@ set_properties_now(WindowProperties &properties) { _properties.set_fixed_size(properties.get_fixed_size()); properties.clear_fixed_size(); } + // When switching undecorated mode, Windows will keep the window at the + // current outer size, whereas we want to keep it with the configured + // inner size. Store the current size and origin. + LPoint2i top_left = _properties.get_origin(); + LPoint2i bottom_right = top_left + _properties.get_size(); + DWORD window_style = make_style(_properties); SetWindowLong(_hWnd, GWL_STYLE, window_style); + // Now calculate the proper size and origin with the new window style. + RECT view_rect; + SetRect(&view_rect, top_left[0], top_left[1], + bottom_right[0], bottom_right[1]); + WINDOWINFO wi; + GetWindowInfo(_hWnd, &wi); + AdjustWindowRectEx(&view_rect, wi.dwStyle, FALSE, wi.dwExStyle); + // We need to call this to ensure that the style change takes effect. - SetWindowPos(_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, - SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | - SWP_FRAMECHANGED | SWP_NOSENDCHANGING | SWP_SHOWWINDOW); + SetWindowPos(_hWnd, HWND_NOTOPMOST, view_rect.left, view_rect.top, + view_rect.right - view_rect.left, + view_rect.bottom - view_rect.top, + SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED | + SWP_NOSENDCHANGING | SWP_SHOWWINDOW); } if (properties.has_title()) {