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()
|
||||
|
||||
if(BACKEND_PLATFORM MATCHES "X11")
|
||||
target_link_libraries(CSE2 PRIVATE "-lX11")
|
||||
target_link_libraries(CSE2 PRIVATE "-lXext -lX11")
|
||||
endif()
|
||||
|
||||
if(BACKEND_PLATFORM MATCHES "SDL2" OR BACKEND_AUDIO MATCHES "SDL2")
|
||||
|
|
|
@ -8,19 +8,55 @@
|
|||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <X11/extensions/XShm.h>
|
||||
|
||||
static Window window;
|
||||
static XImage* framebufferImage;
|
||||
static unsigned char* framebufferPixels;
|
||||
static int framebufferPitch;
|
||||
static unsigned char* xfriendlyFB;
|
||||
static char* xfriendlyFB;
|
||||
static GC gc;
|
||||
static int screenWidth;
|
||||
static int screenHeight;
|
||||
static Pixmap intermediate;
|
||||
static bool useShmP = false;
|
||||
static XShmSegmentInfo seginfo;
|
||||
|
||||
extern Display* xDisplay;
|
||||
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) {
|
||||
screenWidth = screen_width;
|
||||
screenHeight = screen_height;
|
||||
|
@ -28,8 +64,14 @@ bool WindowBackend_Software_CreateWindow(const char *window_title, size_t screen
|
|||
int screen = DefaultScreen(xDisplay);
|
||||
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 = XCreateSimpleWindow(xDisplay, rootWindow, 0, 0, screen_width, screen_height, 1, 0, 0);
|
||||
XSelectInput(xDisplay, window, ExposureMask | KeyPressMask | KeyReleaseMask);
|
||||
XMapRaised(xDisplay, window);
|
||||
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);
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
|
@ -64,10 +94,16 @@ unsigned char* WindowBackend_Software_GetFramebuffer(size_t *pitch)
|
|||
{
|
||||
*pitch = framebufferPitch;
|
||||
|
||||
return (unsigned char*)framebufferPixels;
|
||||
return (unsigned char*)xfriendlyFB;
|
||||
}
|
||||
|
||||
void WindowBackend_Software_DestroyWindow(void) {
|
||||
if(useShmP) {
|
||||
XShmDetach(xDisplay, &seginfo);
|
||||
XDestroyImage(framebufferImage);
|
||||
shmdt(seginfo.shmaddr);
|
||||
shmctl(seginfo.shmid, IPC_RMID, 0);
|
||||
}
|
||||
XDestroyWindow(xDisplay, window);
|
||||
}
|
||||
|
||||
|
@ -92,5 +128,9 @@ void WindowBackend_Software_Display(void) {
|
|||
// srci += 4;
|
||||
// }
|
||||
//memcpy(xfriendlyFB, framebufferPixels, screenWidth * screenHeight * 4);
|
||||
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