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 @@ ...@@ -15,9 +15,11 @@
#include "FrameBufferX11.hpp" #include "FrameBufferX11.hpp"
#include "libX11.hpp"
#include <sys/ipc.h> #include <sys/ipc.h>
#include <sys/shm.h> #include <sys/shm.h>
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
namespace sw namespace sw
...@@ -43,31 +45,31 @@ namespace sw ...@@ -43,31 +45,31 @@ namespace sw
{ {
if(!x_display) if(!x_display)
{ {
x_display = XOpenDisplay(0); x_display = libX11->XOpenDisplay(0);
} }
int screen = DefaultScreen(x_display); int screen = DefaultScreen(x_display);
x_gc = XDefaultGC(x_display, screen); x_gc = libX11->XDefaultGC(x_display, screen);
int depth = XDefaultDepth(x_display, screen); int depth = libX11->XDefaultDepth(x_display, screen);
Status status = XMatchVisualInfo(x_display, screen, 32, TrueColor, &x_visual); Status status = libX11->XMatchVisualInfo(x_display, screen, 32, TrueColor, &x_visual);
bool match = (status != 0 && x_visual.blue_mask == 0xFF); // Prefer X8R8G8B8 bool match = (status != 0 && x_visual.blue_mask == 0xFF); // Prefer X8R8G8B8
Visual *visual = match ? x_visual.visual : XDefaultVisual(x_display, screen); 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) 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.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.shmaddr = x_image->data = buffer = (char*)shmat(shminfo.shmid, 0, 0);
shminfo.readOnly = False; shminfo.readOnly = False;
PreviousXErrorHandler = XSetErrorHandler(XShmErrorHandler); PreviousXErrorHandler = libX11->XSetErrorHandler(XShmErrorHandler);
XShmAttach(x_display, &shminfo); // May produce a BadAccess error libX11->XShmAttach(x_display, &shminfo); // May produce a BadAccess error
XSync(x_display, False); libX11->XSync(x_display, False);
XSetErrorHandler(PreviousXErrorHandler); libX11->XSetErrorHandler(PreviousXErrorHandler);
if(shmBadAccess) if(shmBadAccess)
{ {
...@@ -84,7 +86,7 @@ namespace sw ...@@ -84,7 +86,7 @@ namespace sw
if(!mit_shm) if(!mit_shm)
{ {
buffer = new char[width * height * 4]; 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 ...@@ -100,7 +102,7 @@ namespace sw
} }
else else
{ {
XShmDetach(x_display, &shminfo); libX11->XShmDetach(x_display, &shminfo);
XDestroyImage(x_image); XDestroyImage(x_image);
shmdt(shminfo.shmaddr); shmdt(shminfo.shmaddr);
shmctl(shminfo.shmid, IPC_RMID, 0); shmctl(shminfo.shmid, IPC_RMID, 0);
...@@ -108,7 +110,7 @@ namespace sw ...@@ -108,7 +110,7 @@ namespace sw
if(ownX11) if(ownX11)
{ {
XCloseDisplay(x_display); libX11->XCloseDisplay(x_display);
} }
} }
...@@ -131,14 +133,14 @@ namespace sw ...@@ -131,14 +133,14 @@ namespace sw
if(!mit_shm) 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 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 @@ ...@@ -20,6 +20,10 @@
#include "libEGL/Context.hpp" #include "libEGL/Context.hpp"
#include "common/debug.h" #include "common/debug.h"
#if defined(__unix__) && !defined(__ANDROID__)
#include "Main/libX11.hpp"
#endif
#ifdef __ANDROID__ #ifdef __ANDROID__
#include <system/window.h> #include <system/window.h>
#include <GceFrameBufferConfig.h> #include <GceFrameBufferConfig.h>
...@@ -49,7 +53,14 @@ egl::Display *Display::getPlatformDisplay(EGLenum platform, EGLNativeDisplayType ...@@ -49,7 +53,14 @@ egl::Display *Display::getPlatformDisplay(EGLenum platform, EGLNativeDisplayType
if(platform == EGL_PLATFORM_X11_EXT) if(platform == EGL_PLATFORM_X11_EXT)
{ {
#if defined(__unix__) #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 #else
return error(EGL_BAD_PARAMETER, (egl::Display*)EGL_NO_DISPLAY); return error(EGL_BAD_PARAMETER, (egl::Display*)EGL_NO_DISPLAY);
#endif #endif
...@@ -507,7 +518,7 @@ bool Display::isValidWindow(EGLNativeWindowType window) ...@@ -507,7 +518,7 @@ bool Display::isValidWindow(EGLNativeWindowType window)
if(platform == EGL_PLATFORM_X11_EXT) if(platform == EGL_PLATFORM_X11_EXT)
{ {
XWindowAttributes windowAttributes; XWindowAttributes windowAttributes;
Status status = XGetWindowAttributes(displayId, window, &windowAttributes); Status status = libX11->XGetWindowAttributes(displayId, window, &windowAttributes);
return status == True; return status == True;
} }
...@@ -573,10 +584,10 @@ DisplayMode Display::getDisplayMode() const ...@@ -573,10 +584,10 @@ DisplayMode Display::getDisplayMode() const
#else #else
if(platform == EGL_PLATFORM_X11_EXT) if(platform == EGL_PLATFORM_X11_EXT)
{ {
Screen *screen = XDefaultScreenOfDisplay(displayId); Screen *screen = libX11->XDefaultScreenOfDisplay(displayId);
displayMode.width = XWidthOfScreen(screen); displayMode.width = libX11->XWidthOfScreen(screen);
displayMode.height = XHeightOfScreen(screen); displayMode.height = libX11->XHeightOfScreen(screen);
unsigned int bpp = XPlanesOfScreen(screen); unsigned int bpp = libX11->XPlanesOfScreen(screen);
switch(bpp) switch(bpp)
{ {
......
...@@ -23,6 +23,10 @@ ...@@ -23,6 +23,10 @@
#include "common/debug.h" #include "common/debug.h"
#include "Main/FrameBuffer.hpp" #include "Main/FrameBuffer.hpp"
#if defined(__unix__) && !defined(__ANDROID__)
#include "Main/libX11.hpp"
#endif
#if defined(_WIN32) #if defined(_WIN32)
#include <tchar.h> #include <tchar.h>
#endif #endif
...@@ -82,7 +86,7 @@ bool Surface::initialize() ...@@ -82,7 +86,7 @@ bool Surface::initialize()
} }
void Surface::deleteResources() void Surface::deleteResources()
{ {
if(mDepthStencil) if(mDepthStencil)
{ {
mDepthStencil->release(); mDepthStencil->release();
...@@ -122,8 +126,8 @@ bool Surface::reset() ...@@ -122,8 +126,8 @@ bool Surface::reset()
return reset(ANativeWindow_getWidth(mWindow), ANativeWindow_getHeight(mWindow)); return reset(ANativeWindow_getWidth(mWindow), ANativeWindow_getHeight(mWindow));
#else #else
XWindowAttributes windowAttributes; XWindowAttributes windowAttributes;
XGetWindowAttributes(mDisplay->getNativeDisplay(), mWindow, &windowAttributes); libX11->XGetWindowAttributes(mDisplay->getNativeDisplay(), mWindow, &windowAttributes);
return reset(windowAttributes.width, windowAttributes.height); return reset(windowAttributes.width, windowAttributes.height);
#endif #endif
} }
...@@ -219,7 +223,7 @@ void Surface::setSwapInterval(EGLint interval) ...@@ -219,7 +223,7 @@ void Surface::setSwapInterval(EGLint interval)
{ {
return; return;
} }
mSwapInterval = interval; mSwapInterval = interval;
mSwapInterval = std::max(mSwapInterval, mDisplay->getMinSwapInterval()); mSwapInterval = std::max(mSwapInterval, mDisplay->getMinSwapInterval());
mSwapInterval = std::min(mSwapInterval, mDisplay->getMaxSwapInterval()); mSwapInterval = std::min(mSwapInterval, mDisplay->getMaxSwapInterval());
...@@ -302,7 +306,7 @@ bool Surface::checkForResize() ...@@ -302,7 +306,7 @@ bool Surface::checkForResize()
int clientHeight = ANativeWindow_getHeight(mWindow); int clientHeight = ANativeWindow_getHeight(mWindow);
#else #else
XWindowAttributes windowAttributes; XWindowAttributes windowAttributes;
XGetWindowAttributes(mDisplay->getNativeDisplay(), mWindow, &windowAttributes); libX11->XGetWindowAttributes(mDisplay->getNativeDisplay(), mWindow, &windowAttributes);
int clientWidth = windowAttributes.width; int clientWidth = windowAttributes.width;
int clientHeight = windowAttributes.height; int clientHeight = windowAttributes.height;
......
...@@ -107,10 +107,13 @@ ...@@ -107,10 +107,13 @@
<Linker> <Linker>
<Add option="-Wl,--version-script=./exports.map" /> <Add option="-Wl,--version-script=./exports.map" />
<Add option="-Wl,--hash-style=both" /> <Add option="-Wl,--hash-style=both" />
<Add option="-Wl,--no-undefined" />
<Add library="pthread" /> <Add library="pthread" />
<Add library="X11" /> <Add library="dl" />
</Linker> </Linker>
<Unit filename="../../Common/SharedLibrary.hpp" /> <Unit filename="../../Common/SharedLibrary.hpp" />
<Unit filename="../../Main/libX11.cpp" />
<Unit filename="../../Main/libX11.hpp" />
<Unit filename="../common/Object.cpp" /> <Unit filename="../common/Object.cpp" />
<Unit filename="../common/Object.hpp" /> <Unit filename="../common/Object.hpp" />
<Unit filename="../common/debug.cpp" /> <Unit filename="../common/debug.cpp" />
......
...@@ -131,9 +131,9 @@ ...@@ -131,9 +131,9 @@
<Linker> <Linker>
<Add option="-Wl,--version-script=./exports.map" /> <Add option="-Wl,--version-script=./exports.map" />
<Add option="-Wl,--hash-style=both" /> <Add option="-Wl,--hash-style=both" />
<Add option="-Wl,--no-undefined" />
<Add library="pthread" /> <Add library="pthread" />
<Add library="X11" /> <Add library="dl" />
<Add library="Xext" />
</Linker> </Linker>
<Unit filename="../../Common/CPUID.cpp" /> <Unit filename="../../Common/CPUID.cpp" />
<Unit filename="../../Common/CPUID.hpp" /> <Unit filename="../../Common/CPUID.hpp" />
...@@ -174,6 +174,8 @@ ...@@ -174,6 +174,8 @@
<Unit filename="../../Main/SwiftConfig.hpp" /> <Unit filename="../../Main/SwiftConfig.hpp" />
<Unit filename="../../Main/crc.cpp" /> <Unit filename="../../Main/crc.cpp" />
<Unit filename="../../Main/crc.h" /> <Unit filename="../../Main/crc.h" />
<Unit filename="../../Main/libX11.cpp" />
<Unit filename="../../Main/libX11.hpp" />
<Unit filename="../../Main/serialcommon.h" /> <Unit filename="../../Main/serialcommon.h" />
<Unit filename="../../Main/serialvalid.cpp" /> <Unit filename="../../Main/serialvalid.cpp" />
<Unit filename="../../Main/serialvalid.h" /> <Unit filename="../../Main/serialvalid.h" />
...@@ -247,6 +249,8 @@ ...@@ -247,6 +249,8 @@
<Unit filename="../../Shader/VertexRoutine.hpp" /> <Unit filename="../../Shader/VertexRoutine.hpp" />
<Unit filename="../../Shader/VertexShader.cpp" /> <Unit filename="../../Shader/VertexShader.cpp" />
<Unit filename="../../Shader/VertexShader.hpp" /> <Unit filename="../../Shader/VertexShader.hpp" />
<Unit filename="../common/MatrixStack.cpp" />
<Unit filename="../common/MatrixStack.hpp" />
<Unit filename="../common/NameSpace.cpp" /> <Unit filename="../common/NameSpace.cpp" />
<Unit filename="../common/NameSpace.hpp" /> <Unit filename="../common/NameSpace.hpp" />
<Unit filename="../common/Object.cpp" /> <Unit filename="../common/Object.cpp" />
...@@ -272,8 +276,6 @@ ...@@ -272,8 +276,6 @@
<Unit filename="Image.hpp" /> <Unit filename="Image.hpp" />
<Unit filename="IndexDataManager.cpp" /> <Unit filename="IndexDataManager.cpp" />
<Unit filename="IndexDataManager.h" /> <Unit filename="IndexDataManager.h" />
<Unit filename="../common/MatrixStack.cpp" />
<Unit filename="../common/MatrixStack.hpp" />
<Unit filename="Renderbuffer.cpp" /> <Unit filename="Renderbuffer.cpp" />
<Unit filename="Renderbuffer.h" /> <Unit filename="Renderbuffer.h" />
<Unit filename="ResourceManager.cpp" /> <Unit filename="ResourceManager.cpp" />
......
...@@ -131,9 +131,9 @@ ...@@ -131,9 +131,9 @@
<Linker> <Linker>
<Add option="-Wl,--version-script=./exports.map" /> <Add option="-Wl,--version-script=./exports.map" />
<Add option="-Wl,--hash-style=both" /> <Add option="-Wl,--hash-style=both" />
<Add option="-Wl,--no-undefined" />
<Add library="pthread" /> <Add library="pthread" />
<Add library="X11" /> <Add library="dl" />
<Add library="Xext" />
</Linker> </Linker>
<Unit filename="../../Common/CPUID.cpp" /> <Unit filename="../../Common/CPUID.cpp" />
<Unit filename="../../Common/CPUID.hpp" /> <Unit filename="../../Common/CPUID.hpp" />
...@@ -174,6 +174,8 @@ ...@@ -174,6 +174,8 @@
<Unit filename="../../Main/SwiftConfig.hpp" /> <Unit filename="../../Main/SwiftConfig.hpp" />
<Unit filename="../../Main/crc.cpp" /> <Unit filename="../../Main/crc.cpp" />
<Unit filename="../../Main/crc.h" /> <Unit filename="../../Main/crc.h" />
<Unit filename="../../Main/libX11.cpp" />
<Unit filename="../../Main/libX11.hpp" />
<Unit filename="../../Main/serialcommon.h" /> <Unit filename="../../Main/serialcommon.h" />
<Unit filename="../../Main/serialvalid.cpp" /> <Unit filename="../../Main/serialvalid.cpp" />
<Unit filename="../../Main/serialvalid.h" /> <Unit filename="../../Main/serialvalid.h" />
......
...@@ -153,6 +153,8 @@ ...@@ -153,6 +153,8 @@
<Unit filename="../../Main/SwiftConfig.hpp" /> <Unit filename="../../Main/SwiftConfig.hpp" />
<Unit filename="../../Main/crc.cpp" /> <Unit filename="../../Main/crc.cpp" />
<Unit filename="../../Main/crc.h" /> <Unit filename="../../Main/crc.h" />
<Unit filename="../../Main/libX11.cpp" />
<Unit filename="../../Main/libX11.hpp" />
<Unit filename="../../Main/serialcommon.h" /> <Unit filename="../../Main/serialcommon.h" />
<Unit filename="../../Main/serialvalid.cpp" /> <Unit filename="../../Main/serialvalid.cpp" />
<Unit filename="../../Main/serialvalid.h" /> <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