use OpenGL legacy API for X11 (faster than draw XImages)

This commit is contained in:
Carlos Aragones
2020-09-18 15:05:39 +02:00
parent 09338014d1
commit 41e087433a
6 changed files with 192 additions and 39 deletions

View File

@ -3,7 +3,9 @@
#include <MiniFB_enums.h>
#include <stdint.h>
#include <X11/Xlib.h>
#if defined(USE_OPENGL_API)
#include <GL/glx.h>
#endif
typedef struct {
Window window;
@ -11,12 +13,16 @@ typedef struct {
Display *display;
int screen;
GC gc;
#if defined(USE_OPENGL_API)
GLXContext context;
uint32_t text_id;
#else
XImage *image;
void *image_buffer;
XImage *image_scaler;
uint32_t image_scaler_width;
uint32_t image_scaler_height;
#endif
struct mfb_timer *timer;
} SWindowData_X11;

View File

@ -13,6 +13,10 @@
#include "WindowData.h"
#include "WindowData_X11.h"
#if defined(USE_OPENGL_API)
#include <gl/MiniFB_GL.h>
#endif
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void init_keycodes(SWindowData_X11 *window_data_x11);
@ -176,6 +180,15 @@ mfb_open_ex(const char *title, unsigned width, unsigned height, unsigned flags)
sizeHints.max_height = height;
}
#if defined(USE_OPENGL_API)
if(create_GL_context(window_data) == false) {
return 0x0;
}
#else
window_data_x11->image = XCreateImage(window_data_x11->display, CopyFromParent, depth, ZPixmap, 0, 0x0, width, height, 32, width * 4);
#endif
XSetWMNormalHints(window_data_x11->display, window_data_x11->window, &sizeHints);
XClearWindow(window_data_x11->display, window_data_x11->window);
XMapRaised(window_data_x11->display, window_data_x11->window);
@ -183,8 +196,6 @@ mfb_open_ex(const char *title, unsigned width, unsigned height, unsigned flags)
window_data_x11->gc = DefaultGC(window_data_x11->display, window_data_x11->screen);
window_data_x11->image = XCreateImage(window_data_x11->display, CopyFromParent, depth, ZPixmap, 0, 0x0, width, height, 32, width * 4);
window_data_x11->timer = mfb_timer_create();
mfb_set_keyboard_callback((struct mfb_window *) window_data, keyboard_default);
@ -264,6 +275,9 @@ processEvent(SWindowData *window_data, XEvent *event) {
window_data->window_height = event->xconfigure.height;
resize_dst(window_data, event->xconfigure.width, event->xconfigure.height);
#if defined(USE_OPENGL_API)
resize_GL(window_data);
#else
SWindowData_X11 *window_data_x11 = (SWindowData_X11 *) window_data->specific;
if(window_data_x11->image_scaler != 0x0) {
window_data_x11->image_scaler->data = 0x0;
@ -272,8 +286,8 @@ processEvent(SWindowData *window_data, XEvent *event) {
window_data_x11->image_scaler_width = 0;
window_data_x11->image_scaler_height = 0;
}
XClearWindow(window_data_x11->display, window_data_x11->window);
#endif
kCall(resize_func, window_data->window_width, window_data->window_height);
}
break;
@ -330,16 +344,22 @@ mfb_update_ex(struct mfb_window *window, void *buffer, unsigned width, unsigned
return STATE_INVALID_BUFFER;
}
#if !defined(USE_OPENGL_API)
SWindowData_X11 *window_data_x11 = (SWindowData_X11 *) window_data->specific;
bool different_size = false;
#endif
if(window_data->buffer_width != width || window_data->buffer_height != height) {
window_data->buffer_width = width;
window_data->buffer_stride = width * 4;
window_data->buffer_height = height;
#if !defined(USE_OPENGL_API)
different_size = true;
#endif
}
#if !defined(USE_OPENGL_API)
if (different_size || window_data->buffer_width != window_data->dst_width || window_data->buffer_height != window_data->dst_height) {
if (window_data_x11->image_scaler_width != window_data->dst_width || window_data_x11->image_scaler_height != window_data->dst_height) {
if (window_data_x11->image_scaler != 0x0) {
@ -372,6 +392,13 @@ mfb_update_ex(struct mfb_window *window, void *buffer, unsigned width, unsigned
XPutImage(window_data_x11->display, window_data_x11->window, window_data_x11->gc, window_data_x11->image, 0, 0, window_data->dst_offset_x, window_data->dst_offset_y, window_data->dst_width, window_data->dst_height);
}
XFlush(window_data_x11->display);
#else
redraw_GL(window_data, buffer);
#endif
processEvents(window_data);
return STATE_OK;
@ -453,12 +480,18 @@ destroy_window_data(SWindowData *window_data) {
if (window_data != 0x0) {
if (window_data->specific != 0x0) {
SWindowData_X11 *window_data_x11 = (SWindowData_X11 *) window_data->specific;
#if defined(USE_OPENGL_API)
destroy_GL_context(window_data);
#else
if (window_data_x11->image != 0x0) {
window_data_x11->image->data = 0x0;
XDestroyImage(window_data_x11->image);
XDestroyWindow(window_data_x11->display, window_data_x11->window);
XCloseDisplay(window_data_x11->display);
}
#endif
mfb_timer_destroy(window_data_x11->timer);
memset(window_data_x11, 0, sizeof(SWindowData_X11));
free(window_data_x11);