Add use of XShm for faster transfer speeds between game and X server
This commit is contained in:
parent
e14d3f59f2
commit
2c93c071d1
2 changed files with 59 additions and 19 deletions
|
@ -572,7 +572,7 @@ if(BACKEND_PLATFORM MATCHES "GLFW3")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(BACKEND_PLATFORM MATCHES "X11")
|
if(BACKEND_PLATFORM MATCHES "X11")
|
||||||
target_link_libraries(CSE2 PRIVATE "-lX11")
|
target_link_libraries(CSE2 PRIVATE "-lXext -lX11")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(BACKEND_PLATFORM MATCHES "SDL2" OR BACKEND_AUDIO MATCHES "SDL2")
|
if(BACKEND_PLATFORM MATCHES "SDL2" OR BACKEND_AUDIO MATCHES "SDL2")
|
||||||
|
|
|
@ -8,19 +8,55 @@
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
|
#include <sys/ipc.h>
|
||||||
|
#include <sys/shm.h>
|
||||||
|
#include <X11/extensions/XShm.h>
|
||||||
|
|
||||||
static Window window;
|
static Window window;
|
||||||
static XImage* framebufferImage;
|
static XImage* framebufferImage;
|
||||||
static unsigned char* framebufferPixels;
|
static unsigned char* framebufferPixels;
|
||||||
static int framebufferPitch;
|
static int framebufferPitch;
|
||||||
static unsigned char* xfriendlyFB;
|
static char* xfriendlyFB;
|
||||||
static GC gc;
|
static GC gc;
|
||||||
static int screenWidth;
|
static int screenWidth;
|
||||||
static int screenHeight;
|
static int screenHeight;
|
||||||
static Pixmap intermediate;
|
static bool useShmP = false;
|
||||||
|
static XShmSegmentInfo seginfo;
|
||||||
|
|
||||||
extern Display* xDisplay;
|
extern Display* xDisplay;
|
||||||
extern Visual* xVisual;
|
extern Visual* xVisual;
|
||||||
|
|
||||||
|
static bool CheckShm() {
|
||||||
|
bool exists = XShmQueryExtension(xDisplay);
|
||||||
|
return exists;
|
||||||
|
}
|
||||||
|
|
||||||
|
void createFramebuffer() {
|
||||||
|
gc = DefaultGC(xDisplay, DefaultScreen(xDisplay));
|
||||||
|
|
||||||
|
int depth = DefaultDepth(xDisplay, DefaultScreen(xDisplay));
|
||||||
|
|
||||||
|
// Setting up the framebuffer
|
||||||
|
xfriendlyFB = NULL;
|
||||||
|
|
||||||
|
if(useShmP) {
|
||||||
|
framebufferImage = XShmCreateImage(xDisplay, xVisual,
|
||||||
|
depth, ZPixmap, NULL,
|
||||||
|
&seginfo, screenWidth, screenHeight);
|
||||||
|
seginfo.shmid = shmget(IPC_PRIVATE,
|
||||||
|
framebufferImage->bytes_per_line * framebufferImage->height,
|
||||||
|
IPC_CREAT | 0777);
|
||||||
|
seginfo.shmaddr = xfriendlyFB = framebufferImage->data = (char*)shmat(seginfo.shmid, NULL, 0);
|
||||||
|
XShmAttach(xDisplay, &seginfo);
|
||||||
|
} else {
|
||||||
|
xfriendlyFB = (char*)malloc(screenWidth * screenHeight * 4);
|
||||||
|
framebufferImage = XCreateImage(xDisplay, xVisual,
|
||||||
|
depth, ZPixmap, 0,
|
||||||
|
(char*)xfriendlyFB, screenWidth, screenHeight,
|
||||||
|
32, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool WindowBackend_Software_CreateWindow(const char *window_title, size_t screen_width, size_t screen_height, bool fullscreen) {
|
bool WindowBackend_Software_CreateWindow(const char *window_title, size_t screen_width, size_t screen_height, bool fullscreen) {
|
||||||
screenWidth = screen_width;
|
screenWidth = screen_width;
|
||||||
screenHeight = screen_height;
|
screenHeight = screen_height;
|
||||||
|
@ -28,8 +64,14 @@ bool WindowBackend_Software_CreateWindow(const char *window_title, size_t screen
|
||||||
int screen = DefaultScreen(xDisplay);
|
int screen = DefaultScreen(xDisplay);
|
||||||
Window rootWindow = RootWindow(xDisplay, screen);
|
Window rootWindow = RootWindow(xDisplay, screen);
|
||||||
|
|
||||||
|
useShmP = CheckShm();
|
||||||
|
if(useShmP) {
|
||||||
|
Backend_PrintInfo("Using X shared memory extension for higher image transfer speeds.\n");
|
||||||
|
} else {
|
||||||
|
Backend_PrintInfo("Unable to use X shared memory extension. Expect lower performance.\n");
|
||||||
|
}
|
||||||
|
|
||||||
window = XCreateWindow(xDisplay, rootWindow, 0, 0, screen_width, screen_height, 0, 24, InputOutput, xVisual, 0, NULL);
|
window = XCreateWindow(xDisplay, rootWindow, 0, 0, screen_width, screen_height, 0, 24, InputOutput, xVisual, 0, NULL);
|
||||||
//window = XCreateSimpleWindow(xDisplay, rootWindow, 0, 0, screen_width, screen_height, 1, 0, 0);
|
|
||||||
XSelectInput(xDisplay, window, ExposureMask | KeyPressMask | KeyReleaseMask);
|
XSelectInput(xDisplay, window, ExposureMask | KeyPressMask | KeyReleaseMask);
|
||||||
XMapRaised(xDisplay, window);
|
XMapRaised(xDisplay, window);
|
||||||
XStoreName(xDisplay, window, window_title);
|
XStoreName(xDisplay, window, window_title);
|
||||||
|
@ -39,20 +81,8 @@ bool WindowBackend_Software_CreateWindow(const char *window_title, size_t screen
|
||||||
Atom WM_DELETE_WINDOW = XInternAtom(xDisplay, "WM_DELETE_WINDOW", false);
|
Atom WM_DELETE_WINDOW = XInternAtom(xDisplay, "WM_DELETE_WINDOW", false);
|
||||||
XSetWMProtocols(xDisplay, window, &WM_DELETE_WINDOW, 1);
|
XSetWMProtocols(xDisplay, window, &WM_DELETE_WINDOW, 1);
|
||||||
|
|
||||||
gc = DefaultGC(xDisplay, DefaultScreen(xDisplay));
|
createFramebuffer();
|
||||||
|
|
||||||
int depth = DefaultDepth(xDisplay, DefaultScreen(xDisplay));
|
|
||||||
|
|
||||||
intermediate = XCreatePixmap(xDisplay, window, screenWidth, screenHeight, depth);
|
|
||||||
|
|
||||||
// Setting up the framebuffer
|
|
||||||
framebufferPixels = (unsigned char*)malloc(screen_width * screen_height * 4);
|
|
||||||
//xfriendlyFB = (unsigned char*)malloc(screen_width * screen_height * 4);
|
|
||||||
xfriendlyFB = framebufferPixels;
|
|
||||||
framebufferImage = XCreateImage(xDisplay, xVisual,//DefaultVisual(xDisplay, DefaultScreen(xDisplay)),
|
|
||||||
depth, ZPixmap, 0,
|
|
||||||
(char*)xfriendlyFB, screen_width, screen_height,
|
|
||||||
32, 0);
|
|
||||||
if(framebufferImage == 0) {
|
if(framebufferImage == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -64,10 +94,16 @@ unsigned char* WindowBackend_Software_GetFramebuffer(size_t *pitch)
|
||||||
{
|
{
|
||||||
*pitch = framebufferPitch;
|
*pitch = framebufferPitch;
|
||||||
|
|
||||||
return (unsigned char*)framebufferPixels;
|
return (unsigned char*)xfriendlyFB;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowBackend_Software_DestroyWindow(void) {
|
void WindowBackend_Software_DestroyWindow(void) {
|
||||||
|
if(useShmP) {
|
||||||
|
XShmDetach(xDisplay, &seginfo);
|
||||||
|
XDestroyImage(framebufferImage);
|
||||||
|
shmdt(seginfo.shmaddr);
|
||||||
|
shmctl(seginfo.shmid, IPC_RMID, 0);
|
||||||
|
}
|
||||||
XDestroyWindow(xDisplay, window);
|
XDestroyWindow(xDisplay, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,5 +128,9 @@ void WindowBackend_Software_Display(void) {
|
||||||
// srci += 4;
|
// srci += 4;
|
||||||
// }
|
// }
|
||||||
//memcpy(xfriendlyFB, framebufferPixels, screenWidth * screenHeight * 4);
|
//memcpy(xfriendlyFB, framebufferPixels, screenWidth * screenHeight * 4);
|
||||||
XPutImage(xDisplay, window, gc, framebufferImage, 0, 0, 0, 0, screenWidth, screenHeight);
|
if(useShmP) {
|
||||||
|
XShmPutImage(xDisplay, window, gc, framebufferImage, 0, 0, 0, 0, screenWidth, screenHeight, 0);
|
||||||
|
} else {
|
||||||
|
XPutImage(xDisplay, window, gc, framebufferImage, 0, 0, 0, 0, screenWidth, screenHeight);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue