1
1
Fork 0
mirror of https://github.com/QB64-Phoenix-Edition/QB64pe.git synced 2024-07-06 19:50:22 +00:00

Fix slowdown of _ScreenX and _ScreenY

The commands _ScreenX and _ScreenY got significantly slower due to the
need to wait for the GLUT thread to wake up and execute the glutGet()
command for them. We've already seen a few programs (including the IDE)
where this behavior completely grinds the program to a halt, so we
definitely can't keep it.

The simple solution here is to not call glutGet() on every _ScreenX/Y
command. Instead every time the idle/timer function runs we get the
current values for the relevant glutGet() variables and store them.
libqb_glut_get() then checks if the value being read is one of the ones
we read in the idle/timer functionand if so just returns the last read
value. By doing it this way the commands no longer has to wait on the
GLUT thread for the result.
This commit is contained in:
Matthew Kilgore 2022-11-30 17:23:47 -05:00
parent f7fabda198
commit 7ac2eefcb8

View file

@ -4,6 +4,14 @@
#include <unistd.h>
#include <queue>
// note: MacOSX uses Apple's GLUT not FreeGLUT
#ifdef QB64_MACOSX
# include <GLUT/glut.h>
#else
# define CORE_FREEGLUT
# include "freeglut.h"
#endif
#include "mutex.h"
#include "glut-message.h"
#include "glut-thread.h"
@ -11,6 +19,15 @@
static libqb_mutex *glut_msg_queue_lock = libqb_mutex_new();
static std::queue<glut_message *> glut_msg_queue;
// These values from GLUT are read on every process of the msg queue. Calls to
// libqb_glut_get() can then read from these values directly rather than wait
// for the GLUT thread to process the command.
static int glut_window_x, glut_window_y;
#ifdef CORE_FREEGLUT
static int glut_window_border_width, glut_window_header_height;
#endif
bool libqb_queue_glut_message(glut_message *msg) {
if (!libqb_is_glut_up()) {
msg->finish();
@ -27,6 +44,14 @@ bool libqb_queue_glut_message(glut_message *msg) {
void libqb_process_glut_queue() {
libqb_mutex_guard guard(glut_msg_queue_lock);
glut_window_x = glutGet(GLUT_WINDOW_X);
glut_window_y = glutGet(GLUT_WINDOW_Y);
#ifdef CORE_FREEGLUT
glut_window_border_width = glutGet(GLUT_WINDOW_BORDER_WIDTH);
glut_window_header_height = glutGet(GLUT_WINDOW_HEADER_HEIGHT);
#endif
while (!glut_msg_queue.empty()) {
glut_message *msg = glut_msg_queue.front();
glut_msg_queue.pop();
@ -45,7 +70,34 @@ void libqb_glut_warp_pointer(int x, int y) {
libqb_queue_glut_message(new glut_message_warp_pointer(x, y));
}
static bool is_static_glut_value(int id) {
return id == GLUT_WINDOW_Y
|| id == GLUT_WINDOW_X
#ifdef CORE_FREEGLUT
|| id == GLUT_WINDOW_BORDER_WIDTH
|| id == GLUT_WINDOW_HEADER_HEIGHT
#endif
;
}
static int __get_static_glut_value(int id) {
switch (id) {
case GLUT_WINDOW_Y: return glut_window_y;
case GLUT_WINDOW_X: return glut_window_x;
#ifdef CORE_FREEGLUT
case GLUT_WINDOW_BORDER_WIDTH: return glut_window_border_width;
case GLUT_WINDOW_HEADER_HEIGHT: return glut_window_header_height;
#endif
default: return -1;
}
}
int libqb_glut_get(int id) {
if (is_static_glut_value(id)) {
libqb_mutex_guard guard(glut_msg_queue_lock);
return __get_static_glut_value(id);
}
glut_message_get msg(id);
libqb_queue_glut_message(&msg);