Remove XVFB From Dedicated Server

This commit is contained in:
TheBrokenRail 2020-10-30 18:25:08 -04:00
parent 151e404aab
commit d3e0310a60
7 changed files with 106 additions and 71 deletions

View File

@ -8,7 +8,6 @@ RUN \
apt-get install -y libglvnd-dev:armhf libsdl1.2-dev:armhf libx11-dev:armhf build-essential zlib1g-dev:armhf git cmake curl gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libfreeimage-dev:armhf libglfw3-dev:armhf xinput:armhf libxfixes-dev:armhf apt-get install -y libglvnd-dev:armhf libsdl1.2-dev:armhf libx11-dev:armhf build-essential zlib1g-dev:armhf git cmake curl gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libfreeimage-dev:armhf libglfw3-dev:armhf xinput:armhf libxfixes-dev:armhf
RUN ln -s /usr/lib/arm-linux-gnueabihf/libGLESv2.so.2 /usr/lib/libGLESv2.so RUN ln -s /usr/lib/arm-linux-gnueabihf/libGLESv2.so.2 /usr/lib/libGLESv2.so
RUN ln -s /usr/lib/arm-linux-gnueabihf/libEGL.so.1 /usr/lib/libEGL.so
ADD ./build /app/build ADD ./build /app/build

View File

@ -1,7 +1,3 @@
FROM thebrokenrail/minecraft-pi:client FROM thebrokenrail/minecraft-pi:client
ENV MCPI_MODE=server ENV MCPI_MODE=server
RUN apt-get install -y xvfb
ENTRYPOINT xvfb-run ./launcher

View File

@ -4,6 +4,7 @@ project(core)
add_compile_options(-Wall -Wextra -Werror) add_compile_options(-Wall -Wextra -Werror)
add_library(bcm_host SHARED src/bcm_host.c) add_library(bcm_host SHARED src/stubs/bcm_host.c)
add_library(EGL SHARED src/stubs/EGL.c)
add_executable(launcher src/launcher.c) add_executable(launcher src/launcher.c)

37
core/src/stubs/EGL.c Normal file
View File

@ -0,0 +1,37 @@
#include <EGL/egl.h>
// EGL/SDL Is Replaced With GLFW
EGLDisplay eglGetDisplay(__attribute__((unused)) NativeDisplayType native_display) {
return 0;
}
EGLBoolean eglInitialize(__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLint *major, __attribute__((unused)) EGLint *minor) {
return EGL_TRUE;
}
EGLBoolean eglChooseConfig(__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLint const *attrib_list, __attribute__((unused)) EGLConfig *configs, __attribute__((unused)) EGLint config_size, __attribute__((unused)) EGLint *num_config) {
return EGL_TRUE;
}
EGLBoolean eglBindAPI(__attribute__((unused)) EGLenum api) {
return EGL_TRUE;
}
EGLContext eglCreateContext(__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLConfig config, __attribute__((unused)) EGLContext share_context, __attribute__((unused)) EGLint const *attrib_list) {
return 0;
}
EGLSurface eglCreateWindowSurface(__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLConfig config, __attribute__((unused)) NativeWindowType native_window, __attribute__((unused)) EGLint const *attrib_list) {
return 0;
}
EGLBoolean eglMakeCurrent(__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLSurface draw, __attribute__((unused)) EGLSurface read, __attribute__((unused)) EGLContext context) {
return EGL_TRUE;
}
EGLBoolean eglDestroySurface(__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLSurface surface) {
return EGL_TRUE;
}
EGLBoolean eglDestroyContext(__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLContext context) {
return EGL_TRUE;
}
EGLBoolean eglTerminate(__attribute__((unused)) EGLDisplay display) {
return EGL_TRUE;
}
EGLBoolean eglSwapBuffers(__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLSurface surface) {
return EGL_TRUE;
}

View File

@ -22,7 +22,7 @@ target_link_libraries(extra core dl server)
find_package(glfw3 3.3 REQUIRED) find_package(glfw3 3.3 REQUIRED)
add_library(compat SHARED src/compat.c) add_library(compat SHARED src/compat.c)
target_link_libraries(compat core extra SDL EGL GLESv1_CM GLESv2 X11 dl freeimage glfw Xfixes) target_link_libraries(compat core extra SDL GLESv1_CM GLESv2 X11 dl freeimage glfw Xfixes)
# Force GLESv1 Link # Force GLESv1 Link
target_link_options(compat PRIVATE "-Wl,--no-as-needed") target_link_options(compat PRIVATE "-Wl,--no-as-needed")

View File

@ -14,7 +14,6 @@
#include <SDL/SDL.h> #include <SDL/SDL.h>
#include <SDL/SDL_syswm.h> #include <SDL/SDL_syswm.h>
#include <EGL/egl.h>
#include <GLES/gl.h> #include <GLES/gl.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
@ -182,6 +181,8 @@ static void glfw_scroll(__attribute__((unused)) GLFWwindow *window, __attribute_
HOOK(SDL_WM_SetCaption, void, (const char *title, __attribute__((unused)) const char *icon)) { HOOK(SDL_WM_SetCaption, void, (const char *title, __attribute__((unused)) const char *icon)) {
FreeImage_Initialise(0); FreeImage_Initialise(0);
// Don't Enable GLFW In Server Mode
if (!is_server) {
glfwSetErrorCallback(glfw_error); glfwSetErrorCallback(glfw_error);
if (!glfwInit()) { if (!glfwInit()) {
@ -189,17 +190,11 @@ HOOK(SDL_WM_SetCaption, void, (const char *title, __attribute__((unused)) const
exit(1); exit(1);
} }
if (is_server) {
// Don't Show Window In Server Mode
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
} else {
// Create OpenGL ES 1.1 Context // Create OpenGL ES 1.1 Context
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 1); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 1);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
}
glfw_window = glfwCreateWindow(840, 480, title, NULL, NULL); glfw_window = glfwCreateWindow(840, 480, title, NULL, NULL);
if (!glfw_window) { if (!glfw_window) {
@ -207,22 +202,20 @@ HOOK(SDL_WM_SetCaption, void, (const char *title, __attribute__((unused)) const
exit(1); exit(1);
} }
if (!is_server) {
// Don't Process Events In Server Mode // Don't Process Events In Server Mode
glfwSetKeyCallback(glfw_window, glfw_key); glfwSetKeyCallback(glfw_window, glfw_key);
glfwSetCharCallback(glfw_window, glfw_char); glfwSetCharCallback(glfw_window, glfw_char);
glfwSetCursorPosCallback(glfw_window, glfw_motion); glfwSetCursorPosCallback(glfw_window, glfw_motion);
glfwSetMouseButtonCallback(glfw_window, glfw_click); glfwSetMouseButtonCallback(glfw_window, glfw_click);
glfwSetScrollCallback(glfw_window, glfw_scroll); glfwSetScrollCallback(glfw_window, glfw_scroll);
}
store_x11_window(); store_x11_window();
if (!is_server) {
glfwMakeContextCurrent(glfw_window); glfwMakeContextCurrent(glfw_window);
} }
} }
#include <EGL/egl.h>
HOOK(eglSwapBuffers, EGLBoolean, (__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLSurface surface)) { HOOK(eglSwapBuffers, EGLBoolean, (__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLSurface surface)) {
if (!is_server) { if (!is_server) {
// Don't Swap Buffers In A Context-Less Window // Don't Swap Buffers In A Context-Less Window
@ -321,8 +314,8 @@ HOOK(SDL_PollEvent, int, (SDL_Event *event)) {
// Process GLFW Events // Process GLFW Events
glfwPollEvents(); glfwPollEvents();
// Close Window // Close Window (Ignore In Server Mode)
if (glfwWindowShouldClose(glfw_window)) { if (!is_server && glfwWindowShouldClose(glfw_window)) {
SDL_Event event; SDL_Event event;
event.type = SDL_QUIT; event.type = SDL_QUIT;
SDL_PushEvent(&event); SDL_PushEvent(&event);
@ -361,16 +354,19 @@ HOOK(SDL_Quit, void, ()) {
ensure_SDL_Quit(); ensure_SDL_Quit();
(*real_SDL_Quit)(); (*real_SDL_Quit)();
// GLFW Is Disabled In Server Mode
if (!is_server) {
glfwDestroyWindow(glfw_window); glfwDestroyWindow(glfw_window);
glfwTerminate(); glfwTerminate();
} }
}
static SDL_GrabMode fake_grab_mode = SDL_GRAB_OFF; static SDL_GrabMode fake_grab_mode = SDL_GRAB_OFF;
// Fix SDL Cursor Visibility/Grabbing // Fix SDL Cursor Visibility/Grabbing
HOOK(SDL_WM_GrabInput, SDL_GrabMode, (SDL_GrabMode mode)) { HOOK(SDL_WM_GrabInput, SDL_GrabMode, (SDL_GrabMode mode)) {
if (is_server) { if (is_server) {
// Don't Grab Input In Server/Headless Mode // Don't Grab Input In Server Mode
if (mode != SDL_GRAB_QUERY) { if (mode != SDL_GRAB_QUERY) {
fake_grab_mode = mode; fake_grab_mode = mode;
} }
@ -410,54 +406,56 @@ HOOK(SDL_SetVideoMode, SDL_Surface *, (__attribute__((unused)) int width, __attr
} }
HOOK(XTranslateCoordinates, int, (Display *display, Window src_w, Window dest_w, int src_x, int src_y, int *dest_x_return, int *dest_y_return, Window *child_return)) { HOOK(XTranslateCoordinates, int, (Display *display, Window src_w, Window dest_w, int src_x, int src_y, int *dest_x_return, int *dest_y_return, Window *child_return)) {
if (!is_server) {
ensure_XTranslateCoordinates(); ensure_XTranslateCoordinates();
if (window_loaded) { if (window_loaded) {
return (*real_XTranslateCoordinates)(x11_display, x11_window, x11_root_window, src_x, src_y, dest_x_return, dest_y_return, child_return); return (*real_XTranslateCoordinates)(x11_display, x11_window, x11_root_window, src_x, src_y, dest_x_return, dest_y_return, child_return);
} else { } else {
return (*real_XTranslateCoordinates)(display, src_w, dest_w, src_x, src_y, dest_x_return, dest_y_return, child_return); return (*real_XTranslateCoordinates)(display, src_w, dest_w, src_x, src_y, dest_x_return, dest_y_return, child_return);
} }
} else {
// No X11
*dest_x_return = src_x;
*dest_y_return = src_y;
return 1;
}
} }
HOOK(XGetWindowAttributes, int, (Display *display, Window w, XWindowAttributes *window_attributes_return)) { HOOK(XGetWindowAttributes, int, (Display *display, Window w, XWindowAttributes *window_attributes_return)) {
if (!is_server) {
ensure_XGetWindowAttributes(); ensure_XGetWindowAttributes();
if (window_loaded) { if (window_loaded) {
return (*real_XGetWindowAttributes)(x11_display, x11_window, window_attributes_return); return (*real_XGetWindowAttributes)(x11_display, x11_window, window_attributes_return);
} else { } else {
return (*real_XGetWindowAttributes)(display, w, window_attributes_return); return (*real_XGetWindowAttributes)(display, w, window_attributes_return);
} }
} else {
// No X11
XWindowAttributes attributes;
attributes.x = 0;
attributes.y = 0;
attributes.width = 640;
attributes.height = 480;
*window_attributes_return = attributes;
return 1;
}
} }
// EGL Stubs static void x11_nop() {
// NOP
HOOK(eglGetDisplay, EGLDisplay, (__attribute__((unused)) NativeDisplayType native_display)) {
return 0;
} }
HOOK(eglInitialize, EGLBoolean, (__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLint *major, __attribute__((unused)) EGLint *minor)) { HOOK(SDL_GetWMInfo, int, (SDL_SysWMinfo *info)) {
return EGL_TRUE; if (!is_server) {
ensure_SDL_GetWMInfo();
return (*real_SDL_GetWMInfo)(info);
} else {
// Return Fake Lock Functions In Server Mode Since X11 Is Disabled
SDL_SysWMinfo ret;
ret.info.x11.lock_func = x11_nop;
ret.info.x11.unlock_func = x11_nop;
*info = ret;
return 1;
} }
HOOK(eglChooseConfig, EGLBoolean, (__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLint const *attrib_list, __attribute__((unused)) EGLConfig *configs, __attribute__((unused)) EGLint config_size, __attribute__((unused)) EGLint *num_config)) {
return EGL_TRUE;
}
HOOK(eglBindAPI, EGLBoolean, (__attribute__((unused)) EGLenum api)) {
return EGL_TRUE;
}
HOOK(eglCreateContext, EGLContext, (__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLConfig config, __attribute__((unused)) EGLContext share_context, __attribute__((unused)) EGLint const *attrib_list)) {
return 0;
}
HOOK(eglCreateWindowSurface, EGLSurface, (__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLConfig config, __attribute__((unused)) NativeWindowType native_window, __attribute__((unused)) EGLint const *attrib_list)) {
return 0;
}
HOOK(eglMakeCurrent, EGLBoolean, (__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLSurface draw, __attribute__((unused)) EGLSurface read, __attribute__((unused)) EGLContext context)) {
return EGL_TRUE;
}
HOOK(eglDestroySurface, EGLBoolean, (__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLSurface surface)) {
return EGL_TRUE;
}
HOOK(eglDestroyContext, EGLBoolean, (__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLContext context)) {
return EGL_TRUE;
}
HOOK(eglTerminate, EGLBoolean, (__attribute__((unused)) EGLDisplay display)) {
return EGL_TRUE;
} }
#include <stdlib.h> #include <stdlib.h>
@ -466,10 +464,14 @@ HOOK(eglTerminate, EGLBoolean, (__attribute__((unused)) EGLDisplay display)) {
__attribute__((constructor)) static void init() { __attribute__((constructor)) static void init() {
int mode = extra_get_mode(); int mode = extra_get_mode();
if (mode != 1) { if (mode != 1) {
// Force Software Rendering When Not In Native Mode
setenv("LIBGL_ALWAYS_SOFTWARE", "1", 1); setenv("LIBGL_ALWAYS_SOFTWARE", "1", 1);
} }
if (mode == 0) { if (mode == 0) {
// Use VirGL When In VirGL Mode
setenv("GALLIUM_DRIVER", "virpipe", 1); setenv("GALLIUM_DRIVER", "virpipe", 1);
} }
is_server = mode == 2; is_server = mode == 2;
// Disable X11 When In Server Mode
setenv("SDL_VIDEODRIVER", is_server ? "dummy" : "x11", 1);
} }