Commit a36c990c by Nicolas Capens Committed by Nicolas Capens

Manually load X11 and resolve its symbols when needed.

This removes the static dependency on X11 on Linux, allowing for headless rendering on systems without it. Bug 20104157 Change-Id: I463c8b3340c3ad16cd0f0d1d0f8804ee31012dd0 Reviewed-on: https://swiftshader-review.googlesource.com/2832Reviewed-by: 's avatarNicolas Capens <capn@google.com> Tested-by: 's avatarNicolas Capens <capn@google.com>
parent 83083ecf
......@@ -15,9 +15,11 @@
#include "FrameBufferX11.hpp"
#include "libX11.hpp"
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <string.h>
#include <assert.h>
namespace sw
......@@ -43,31 +45,31 @@ namespace sw
{
if(!x_display)
{
x_display = XOpenDisplay(0);
x_display = libX11->XOpenDisplay(0);
}
int screen = DefaultScreen(x_display);
x_gc = XDefaultGC(x_display, screen);
int depth = XDefaultDepth(x_display, screen);
Status status = XMatchVisualInfo(x_display, screen, 32, TrueColor, &x_visual);
bool match = (status != 0 && x_visual.blue_mask == 0xFF); // Prefer X8R8G8B8
Visual *visual = match ? x_visual.visual : XDefaultVisual(x_display, screen);
x_gc = libX11->XDefaultGC(x_display, screen);
int depth = libX11->XDefaultDepth(x_display, screen);
Status status = libX11->XMatchVisualInfo(x_display, screen, 32, TrueColor, &x_visual);
bool match = (status != 0 && x_visual.blue_mask == 0xFF); // Prefer X8R8G8B8
Visual *visual = match ? x_visual.visual : libX11->XDefaultVisual(x_display, screen);
mit_shm = (XShmQueryExtension(x_display) == True);
mit_shm = (libX11->XShmQueryExtension && libX11->XShmQueryExtension(x_display) == True);
if(mit_shm)
{
x_image = XShmCreateImage(x_display, visual, depth, ZPixmap, 0, &shminfo, width, height);
x_image = libX11->XShmCreateImage(x_display, visual, depth, ZPixmap, 0, &shminfo, width, height);
shminfo.shmid = shmget(IPC_PRIVATE, x_image->bytes_per_line * x_image->height, IPC_CREAT | SHM_R | SHM_W);
shminfo.shmaddr = x_image->data = buffer = (char*)shmat(shminfo.shmid, 0, 0);
shminfo.readOnly = False;
PreviousXErrorHandler = XSetErrorHandler(XShmErrorHandler);
XShmAttach(x_display, &shminfo); // May produce a BadAccess error
XSync(x_display, False);
XSetErrorHandler(PreviousXErrorHandler);
PreviousXErrorHandler = libX11->XSetErrorHandler(XShmErrorHandler);
libX11->XShmAttach(x_display, &shminfo); // May produce a BadAccess error
libX11->XSync(x_display, False);
libX11->XSetErrorHandler(PreviousXErrorHandler);
if(shmBadAccess)
{
......@@ -84,7 +86,7 @@ namespace sw
if(!mit_shm)
{
buffer = new char[width * height * 4];
x_image = XCreateImage(x_display, visual, depth, ZPixmap, 0, buffer, width, height, 32, width * 4);
x_image = libX11->XCreateImage(x_display, visual, depth, ZPixmap, 0, buffer, width, height, 32, width * 4);
}
}
......@@ -100,7 +102,7 @@ namespace sw
}
else
{
XShmDetach(x_display, &shminfo);
libX11->XShmDetach(x_display, &shminfo);
XDestroyImage(x_image);
shmdt(shminfo.shmaddr);
shmctl(shminfo.shmid, IPC_RMID, 0);
......@@ -108,7 +110,7 @@ namespace sw
if(ownX11)
{
XCloseDisplay(x_display);
libX11->XCloseDisplay(x_display);
}
}
......@@ -131,14 +133,14 @@ namespace sw
if(!mit_shm)
{
XPutImage(x_display, x_window, x_gc, x_image, 0, 0, 0, 0, width, height);
libX11->XPutImage(x_display, x_window, x_gc, x_image, 0, 0, 0, 0, width, height);
}
else
{
XShmPutImage(x_display, x_window, x_gc, x_image, 0, 0, 0, 0, width, height, False);
libX11->XShmPutImage(x_display, x_window, x_gc, x_image, 0, 0, 0, 0, width, height, False);
}
XSync(x_display, False);
libX11->XSync(x_display, False);
}
}
......
#include "libX11.hpp"
#include "Common/SharedLibrary.hpp"
#define Bool int
LibX11exports::LibX11exports(void *libX11, void *libXext)
{
XOpenDisplay = (Display *(*)(char*))getProcAddress(libX11, "XOpenDisplay");
XGetWindowAttributes = (Status (*)(Display*, Window, XWindowAttributes*))getProcAddress(libX11, "XGetWindowAttributes");
XDefaultScreenOfDisplay = (Screen *(*)(Display*))getProcAddress(libX11, "XDefaultScreenOfDisplay");
XWidthOfScreen = (int (*)(Screen*))getProcAddress(libX11, "XWidthOfScreen");
XHeightOfScreen = (int (*)(Screen*))getProcAddress(libX11, "XHeightOfScreen");
XPlanesOfScreen = (int (*)(Screen*))getProcAddress(libX11, "XPlanesOfScreen");
XDefaultGC = (GC (*)(Display*, int))getProcAddress(libX11, "XDefaultGC");
XDefaultDepth = (int (*)(Display*, int))getProcAddress(libX11, "XDefaultDepth");
XMatchVisualInfo = (Status (*)(Display*, int, int, int, XVisualInfo*))getProcAddress(libX11, "XMatchVisualInfo");
XDefaultVisual = (Visual *(*)(Display*, int screen_number))getProcAddress(libX11, "XDefaultVisual");
XSetErrorHandler = (int (*(*)(int (*)(Display*, XErrorEvent*)))(Display*, XErrorEvent*))getProcAddress(libX11, "XSetErrorHandler");
XSync = (int (*)(Display*, Bool))getProcAddress(libX11, "XSync");
XCreateImage = (XImage *(*)(Display*, Visual*, unsigned int, int, int, char*, unsigned int, unsigned int, int, int))getProcAddress(libX11, "XCreateImage");
XCloseDisplay = (int (*)(Display*))getProcAddress(libX11, "XCloseDisplay");
XPutImage = (int (*)(Display*, Drawable, GC, XImage*, int, int, int, int, unsigned int, unsigned int))getProcAddress(libX11, "XPutImage");
XShmQueryExtension = (Bool (*)(Display*))getProcAddress(libXext, "XShmQueryExtension");
XShmCreateImage = (XImage *(*)(Display*, Visual*, unsigned int, int, char*, XShmSegmentInfo*, unsigned int, unsigned int))getProcAddress(libXext, "XShmCreateImage");
XShmAttach = (Bool (*)(Display*, XShmSegmentInfo*))getProcAddress(libXext, "XShmAttach");
XShmDetach = (Bool (*)(Display*, XShmSegmentInfo*))getProcAddress(libXext, "XShmDetach");
XShmPutImage = (int (*)(Display*, Drawable, GC, XImage*, int, int, int, int, unsigned int, unsigned int, bool))getProcAddress(libXext, "XShmPutImage");
}
LibX11exports *LibX11::operator->()
{
static void *libX11 = nullptr;
static void *libXext = nullptr;
static LibX11exports *libX11exports = nullptr;
if(!libX11)
{
libX11 = loadLibrary("libX11.so");
libXext = loadLibrary("libXext.so");
libX11exports = new LibX11exports(libX11, libXext);
}
return libX11exports;
}
LibX11 libX11;
#ifndef libX11_hpp
#define libX11_hpp
#define Bool int
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/XShm.h>
struct LibX11exports
{
LibX11exports(void *libX11, void *libXext);
Display *(*XOpenDisplay)(char *display_name);
Status (*XGetWindowAttributes)(Display *display, Window w, XWindowAttributes *window_attributes_return);
Screen *(*XDefaultScreenOfDisplay)(Display *display);
int (*XWidthOfScreen)(Screen *screen);
int (*XHeightOfScreen)(Screen *screen);
int (*XPlanesOfScreen)(Screen *screen);
GC (*XDefaultGC)(Display *display, int screen_number);
int (*XDefaultDepth)(Display *display, int screen_number);
Status (*XMatchVisualInfo)(Display *display, int screen, int depth, int screen_class, XVisualInfo *vinfo_return);
Visual *(*XDefaultVisual)(Display *display, int screen_number);
int (*(*XSetErrorHandler)(int (*handler)(Display*, XErrorEvent*)))(Display*, XErrorEvent*);
int (*XSync)(Display *display, Bool discard);
XImage *(*XCreateImage)(Display *display, Visual *visual, unsigned int depth, int format, int offset, char *data, unsigned int width, unsigned int height, int bitmap_pad, int bytes_per_line);
int (*XCloseDisplay)(Display *display);
int (*XPutImage)(Display *display, Drawable d, GC gc, XImage *image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height);
Bool (*XShmQueryExtension)(Display *display);
XImage *(*XShmCreateImage)(Display *display, Visual *visual, unsigned int depth, int format, char *data, XShmSegmentInfo *shminfo, unsigned int width, unsigned int height);
Bool (*XShmAttach)(Display *display, XShmSegmentInfo *shminfo);
Bool (*XShmDetach)(Display *display, XShmSegmentInfo *shminfo);
int (*XShmPutImage)(Display *display, Drawable d, GC gc, XImage *image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height, bool send_event);
};
#undef Bool
class LibX11
{
public:
LibX11exports *operator->();
};
extern LibX11 libX11;
#endif // libX11_hpp
......@@ -20,6 +20,10 @@
#include "libEGL/Context.hpp"
#include "common/debug.h"
#if defined(__unix__) && !defined(__ANDROID__)
#include "Main/libX11.hpp"
#endif
#ifdef __ANDROID__
#include <system/window.h>
#include <GceFrameBufferConfig.h>
......@@ -49,7 +53,14 @@ egl::Display *Display::getPlatformDisplay(EGLenum platform, EGLNativeDisplayType
if(platform == EGL_PLATFORM_X11_EXT)
{
#if defined(__unix__)
displayId = XOpenDisplay(NULL);
if(libX11->XOpenDisplay)
{
displayId = libX11->XOpenDisplay(NULL);
}
else
{
return error(EGL_BAD_PARAMETER, (egl::Display*)EGL_NO_DISPLAY);
}
#else
return error(EGL_BAD_PARAMETER, (egl::Display*)EGL_NO_DISPLAY);
#endif
......@@ -507,7 +518,7 @@ bool Display::isValidWindow(EGLNativeWindowType window)
if(platform == EGL_PLATFORM_X11_EXT)
{
XWindowAttributes windowAttributes;
Status status = XGetWindowAttributes(displayId, window, &windowAttributes);
Status status = libX11->XGetWindowAttributes(displayId, window, &windowAttributes);
return status == True;
}
......@@ -573,10 +584,10 @@ DisplayMode Display::getDisplayMode() const
#else
if(platform == EGL_PLATFORM_X11_EXT)
{
Screen *screen = XDefaultScreenOfDisplay(displayId);
displayMode.width = XWidthOfScreen(screen);
displayMode.height = XHeightOfScreen(screen);
unsigned int bpp = XPlanesOfScreen(screen);
Screen *screen = libX11->XDefaultScreenOfDisplay(displayId);
displayMode.width = libX11->XWidthOfScreen(screen);
displayMode.height = libX11->XHeightOfScreen(screen);
unsigned int bpp = libX11->XPlanesOfScreen(screen);
switch(bpp)
{
......
......@@ -23,6 +23,10 @@
#include "common/debug.h"
#include "Main/FrameBuffer.hpp"
#if defined(__unix__) && !defined(__ANDROID__)
#include "Main/libX11.hpp"
#endif
#if defined(_WIN32)
#include <tchar.h>
#endif
......@@ -82,7 +86,7 @@ bool Surface::initialize()
}
void Surface::deleteResources()
{
{
if(mDepthStencil)
{
mDepthStencil->release();
......@@ -122,8 +126,8 @@ bool Surface::reset()
return reset(ANativeWindow_getWidth(mWindow), ANativeWindow_getHeight(mWindow));
#else
XWindowAttributes windowAttributes;
XGetWindowAttributes(mDisplay->getNativeDisplay(), mWindow, &windowAttributes);
libX11->XGetWindowAttributes(mDisplay->getNativeDisplay(), mWindow, &windowAttributes);
return reset(windowAttributes.width, windowAttributes.height);
#endif
}
......@@ -219,7 +223,7 @@ void Surface::setSwapInterval(EGLint interval)
{
return;
}
mSwapInterval = interval;
mSwapInterval = std::max(mSwapInterval, mDisplay->getMinSwapInterval());
mSwapInterval = std::min(mSwapInterval, mDisplay->getMaxSwapInterval());
......@@ -302,7 +306,7 @@ bool Surface::checkForResize()
int clientHeight = ANativeWindow_getHeight(mWindow);
#else
XWindowAttributes windowAttributes;
XGetWindowAttributes(mDisplay->getNativeDisplay(), mWindow, &windowAttributes);
libX11->XGetWindowAttributes(mDisplay->getNativeDisplay(), mWindow, &windowAttributes);
int clientWidth = windowAttributes.width;
int clientHeight = windowAttributes.height;
......
......@@ -107,10 +107,13 @@
<Linker>
<Add option="-Wl,--version-script=./exports.map" />
<Add option="-Wl,--hash-style=both" />
<Add option="-Wl,--no-undefined" />
<Add library="pthread" />
<Add library="X11" />
<Add library="dl" />
</Linker>
<Unit filename="../../Common/SharedLibrary.hpp" />
<Unit filename="../../Main/libX11.cpp" />
<Unit filename="../../Main/libX11.hpp" />
<Unit filename="../common/Object.cpp" />
<Unit filename="../common/Object.hpp" />
<Unit filename="../common/debug.cpp" />
......
......@@ -131,9 +131,9 @@
<Linker>
<Add option="-Wl,--version-script=./exports.map" />
<Add option="-Wl,--hash-style=both" />
<Add option="-Wl,--no-undefined" />
<Add library="pthread" />
<Add library="X11" />
<Add library="Xext" />
<Add library="dl" />
</Linker>
<Unit filename="../../Common/CPUID.cpp" />
<Unit filename="../../Common/CPUID.hpp" />
......@@ -174,6 +174,8 @@
<Unit filename="../../Main/SwiftConfig.hpp" />
<Unit filename="../../Main/crc.cpp" />
<Unit filename="../../Main/crc.h" />
<Unit filename="../../Main/libX11.cpp" />
<Unit filename="../../Main/libX11.hpp" />
<Unit filename="../../Main/serialcommon.h" />
<Unit filename="../../Main/serialvalid.cpp" />
<Unit filename="../../Main/serialvalid.h" />
......@@ -247,6 +249,8 @@
<Unit filename="../../Shader/VertexRoutine.hpp" />
<Unit filename="../../Shader/VertexShader.cpp" />
<Unit filename="../../Shader/VertexShader.hpp" />
<Unit filename="../common/MatrixStack.cpp" />
<Unit filename="../common/MatrixStack.hpp" />
<Unit filename="../common/NameSpace.cpp" />
<Unit filename="../common/NameSpace.hpp" />
<Unit filename="../common/Object.cpp" />
......@@ -272,8 +276,6 @@
<Unit filename="Image.hpp" />
<Unit filename="IndexDataManager.cpp" />
<Unit filename="IndexDataManager.h" />
<Unit filename="../common/MatrixStack.cpp" />
<Unit filename="../common/MatrixStack.hpp" />
<Unit filename="Renderbuffer.cpp" />
<Unit filename="Renderbuffer.h" />
<Unit filename="ResourceManager.cpp" />
......
......@@ -131,9 +131,9 @@
<Linker>
<Add option="-Wl,--version-script=./exports.map" />
<Add option="-Wl,--hash-style=both" />
<Add option="-Wl,--no-undefined" />
<Add library="pthread" />
<Add library="X11" />
<Add library="Xext" />
<Add library="dl" />
</Linker>
<Unit filename="../../Common/CPUID.cpp" />
<Unit filename="../../Common/CPUID.hpp" />
......@@ -174,6 +174,8 @@
<Unit filename="../../Main/SwiftConfig.hpp" />
<Unit filename="../../Main/crc.cpp" />
<Unit filename="../../Main/crc.h" />
<Unit filename="../../Main/libX11.cpp" />
<Unit filename="../../Main/libX11.hpp" />
<Unit filename="../../Main/serialcommon.h" />
<Unit filename="../../Main/serialvalid.cpp" />
<Unit filename="../../Main/serialvalid.h" />
......
......@@ -153,6 +153,8 @@
<Unit filename="../../Main/SwiftConfig.hpp" />
<Unit filename="../../Main/crc.cpp" />
<Unit filename="../../Main/crc.h" />
<Unit filename="../../Main/libX11.cpp" />
<Unit filename="../../Main/libX11.hpp" />
<Unit filename="../../Main/serialcommon.h" />
<Unit filename="../../Main/serialvalid.cpp" />
<Unit filename="../../Main/serialvalid.h" />
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment