Commit 9d55dc20 authored by Vincent Cheng's avatar Vincent Cheng

Imported Upstream version 0~20150328

parent b83d6351
lib
lib32
lib64
......@@ -30,4 +30,4 @@ CXXFLAGS += -DPRIMUS_libGLd='"$(PRIMUS_libGLd)"'
$(LIBDIR)/libGL.so.1: libglfork.cpp
mkdir -p $(LIBDIR)
$(CXX) $(CXXFLAGS) -fvisibility=hidden -fPIC -shared -Wl,-Bsymbolic -o $@ $< -lX11 -lpthread -lrt
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -fvisibility=hidden -fPIC -shared -Wl,-Bsymbolic -o $@ $< -lX11 -lpthread -lrt
......@@ -167,13 +167,12 @@ struct EarlyInitializer {
{
#ifdef BUMBLEBEE_SOCKET
// Signal the Bumblebee daemon to bring up secondary X
errno = 0;
int sock = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
struct sockaddr_un addr;
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, getconf(BUMBLEBEE_SOCKET), sizeof(addr.sun_path));
connect(sock, (struct sockaddr *)&addr, sizeof(addr));
die_if(errno, "failed to connect to Bumblebee daemon: %s\n", strerror(errno));
die_if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0,
"failed to connect to Bumblebee daemon: %s\n", strerror(errno));
static char c[256];
if (!getenv("PRIMUS_DISPLAY"))
{
......@@ -239,7 +238,6 @@ static struct PrimusInfo {
// FIXME: there are race conditions in accesses to these
DrawablesInfo drawables;
ContextsInfo contexts;
GLXFBConfig *dconfigs;
PrimusInfo():
adpy_str(getconf(PRIMUS_DISPLAY)),
......@@ -258,9 +256,6 @@ static struct PrimusInfo {
die_if(!adpy, "failed to open secondary X display\n");
die_if(!ddpy, "failed to open main X display\n");
die_if(!needed_global, "failed to load PRIMUS_LOAD_GLOBAL\n");
int ncfg, attrs[] = {GLX_DOUBLEBUFFER, GL_TRUE, None};
dconfigs = dfns.glXChooseFBConfig(ddpy, 0, attrs, &ncfg);
die_if(!ncfg, "broken GLX on main X display\n");
}
} primus;
......@@ -339,11 +334,20 @@ static void note_geometry(Display *dpy, Drawable draw, int *width, int *height)
XGetGeometry(dpy, draw, &root, &x, &y, (unsigned *)width, (unsigned *)height, &bw, &d);
}
static bool test_drawpixels_fast(Display *dpy, GLXContext ctx)
static GLXFBConfig* get_dconfigs(Display *dpy)
{
static const int attrs[] = {GLX_DOUBLEBUFFER, GL_TRUE, None};
int ncfg;
GLXFBConfig *dconfigs = primus.dfns.glXChooseFBConfig(dpy, 0, attrs, &ncfg);
die_if(!dconfigs, "broken GLX on main X display\n");
return dconfigs;
}
static bool test_drawpixels_fast(Display *dpy, GLXContext ctx, GLXFBConfig dconfig)
{
int width = 1920, height = 1080;
int pbattrs[] = {GLX_PBUFFER_WIDTH, width, GLX_PBUFFER_HEIGHT, height, GLX_PRESERVED_CONTENTS, True, None};
GLXPbuffer pbuffer = primus.dfns.glXCreatePbuffer(dpy, primus.dconfigs[0], pbattrs);
GLXPbuffer pbuffer = primus.dfns.glXCreatePbuffer(dpy, dconfig, pbattrs);
primus.dfns.glXMakeCurrent(dpy, pbuffer, ctx);
GLuint pbo;
primus.dfns.glGenBuffers(1, &pbo);
......@@ -381,15 +385,22 @@ static void* display_work(void *vd)
static const char *state_names[] = {"wait", "upload", "draw+swap", NULL};
Profiler profiler("display", state_names);
Display *ddpy = XOpenDisplay(NULL);
if (!ddpy) // Chromium sandbox prevents opening new connections
{
ddpy = primus.ddpy;
primus_warn("reusing initial X connection for display thread\n");
}
assert(di.kind == di.XWindow || di.kind == di.Window);
XSelectInput(ddpy, di.window, StructureNotifyMask);
note_geometry(ddpy, di.window, &width, &height);
di.update_geometry(width, height);
GLXContext context = primus.dfns.glXCreateNewContext(ddpy, primus.dconfigs[0], GLX_RGBA_TYPE, NULL, True);
GLXFBConfig *dconfigs = get_dconfigs(ddpy);
GLXContext context = primus.dfns.glXCreateNewContext(ddpy, *dconfigs, GLX_RGBA_TYPE, NULL, True);
die_if(!primus.dfns.glXIsDirect(ddpy, context),
"failed to acquire direct rendering context for display thread\n");
if (!primus.dispmethod)
primus.dispmethod = test_drawpixels_fast(ddpy, context) ? 2 : 1;
primus.dispmethod = test_drawpixels_fast(ddpy, context, *dconfigs) ? 2 : 1;
XFree(dconfigs);
primus.dfns.glXMakeCurrent(ddpy, di.window, context);
bool use_textures = (primus.dispmethod == 1);
if (use_textures)
......@@ -417,7 +428,8 @@ static void* display_work(void *vd)
primus.dfns.glDeleteBuffers(2, pbos);
primus.dfns.glXMakeCurrent(ddpy, 0, NULL);
primus.dfns.glXDestroyContext(ddpy, context);
XCloseDisplay(ddpy);
if (ddpy != primus.ddpy)
XCloseDisplay(ddpy);
sem_post(&di.d.relsem);
return NULL;
}
......@@ -571,7 +583,7 @@ static void* readback_work(void *vd)
}
// Find appropriate FBConfigs on adpy for a given Visual on ddpy
static GLXFBConfig* match_fbconfig(XVisualInfo *vis)
static GLXFBConfig* match_fbconfig(Display *dpy, XVisualInfo *vis)
{
int ncfg, attrs[] = {
GLX_DOUBLEBUFFER, 0, GLX_STEREO, 0, GLX_AUX_BUFFERS, 0,
......@@ -581,13 +593,13 @@ static GLXFBConfig* match_fbconfig(XVisualInfo *vis)
GLX_SAMPLE_BUFFERS, 0, GLX_SAMPLES, 0, None
};
for (int i = 0; attrs[i] != None; i += 2)
primus.dfns.glXGetConfig(primus.ddpy, vis, attrs[i], &attrs[i+1]);
primus.dfns.glXGetConfig(dpy, vis, attrs[i], &attrs[i+1]);
return primus.afns.glXChooseFBConfig(primus.adpy, 0, attrs, &ncfg);
}
GLXContext glXCreateContext(Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct)
{
GLXFBConfig *acfgs = match_fbconfig(vis);
GLXFBConfig *acfgs = match_fbconfig(dpy, vis);
GLXContext actx = primus.afns.glXCreateNewContext(primus.adpy, *acfgs, GLX_RGBA_TYPE, shareList, direct);
primus.contexts.record(actx, *acfgs, shareList);
return actx;
......@@ -644,7 +656,7 @@ static GLXPbuffer lookup_pbuffer(Display *dpy, GLXDrawable draw, GLXContext ctx)
XVisualInfo tmpl = {0}, *vis;
tmpl.visualid = XVisualIDFromVisual(attrs.visual);
die_if(!(vis = XGetVisualInfo(dpy, VisualIDMask, &tmpl, &nvis)), "no visuals");
di.fbconfig = *match_fbconfig(vis);
di.fbconfig = *match_fbconfig(dpy, vis);
XFree(vis);
}
di.kind = di.XWindow;
......@@ -728,7 +740,9 @@ void glXSwapBuffers(Display *dpy, GLXDrawable drawable)
GLXWindow glXCreateWindow(Display *dpy, GLXFBConfig config, Window win, const int *attribList)
{
GLXWindow glxwin = primus.dfns.glXCreateWindow(dpy, primus.dconfigs[0], win, attribList);
GLXFBConfig *dconfigs = get_dconfigs(dpy);
GLXWindow glxwin = primus.dfns.glXCreateWindow(dpy, *dconfigs, win, attribList);
XFree(dconfigs);
DrawableInfo &di = primus.drawables[glxwin];
di.kind = di.Window;
di.fbconfig = config;
......@@ -753,7 +767,9 @@ void glXDestroyWindow(Display *dpy, GLXWindow window)
GLXPbuffer glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attribList)
{
GLXPbuffer pbuffer = primus.dfns.glXCreatePbuffer(dpy, primus.dconfigs[0], attribList);
GLXFBConfig *dconfigs = get_dconfigs(dpy);
GLXPbuffer pbuffer = primus.dfns.glXCreatePbuffer(dpy, *dconfigs, attribList);
XFree(dconfigs);
DrawableInfo &di = primus.drawables[pbuffer];
di.kind = di.Pbuffer;
di.fbconfig = config;
......@@ -774,7 +790,9 @@ void glXDestroyPbuffer(Display *dpy, GLXPbuffer pbuf)
GLXPixmap glXCreatePixmap(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attribList)
{
GLXPixmap glxpix = primus.dfns.glXCreatePixmap(dpy, primus.dconfigs[0], pixmap, attribList);
GLXFBConfig *dconfigs = get_dconfigs(dpy);
GLXPixmap glxpix = primus.dfns.glXCreatePixmap(dpy, *dconfigs, pixmap, attribList);
XFree(dconfigs);
DrawableInfo &di = primus.drawables[glxpix];
di.kind = di.Pixmap;
di.fbconfig = config;
......@@ -795,7 +813,7 @@ GLXPixmap glXCreateGLXPixmap(Display *dpy, XVisualInfo *visual, Pixmap pixmap)
DrawableInfo &di = primus.drawables[glxpix];
di.kind = di.Pixmap;
note_geometry(dpy, pixmap, &di.width, &di.height);
GLXFBConfig *acfgs = match_fbconfig(visual);
GLXFBConfig *acfgs = match_fbconfig(dpy, visual);
di.fbconfig = *acfgs;
return glxpix;
}
......@@ -805,13 +823,13 @@ void glXDestroyGLXPixmap(Display *dpy, GLXPixmap pixmap)
glXDestroyPixmap(dpy, pixmap);
}
static XVisualInfo *match_visual(int attrs[])
static XVisualInfo *match_visual(Display *dpy, int attrs[])
{
XVisualInfo *vis = glXChooseVisual(primus.ddpy, 0, attrs);
XVisualInfo *vis = glXChooseVisual(dpy, 0, attrs);
for (int i = 2; attrs[i] != None && vis; i += 2)
{
int tmp = attrs[i+1];
primus.dfns.glXGetConfig(primus.ddpy, vis, attrs[i], &attrs[i+1]);
primus.dfns.glXGetConfig(dpy, vis, attrs[i], &attrs[i+1]);
if (tmp != attrs[i+1])
vis = NULL;
}
......@@ -833,7 +851,7 @@ XVisualInfo *glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config)
XVisualInfo *vis = NULL;
for (i -= 2; i >= 0 && !vis; i -= 2)
{
vis = match_visual(attrs);
vis = match_visual(dpy, attrs);
attrs[i] = None;
}
return vis;
......@@ -843,7 +861,7 @@ int glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config, int attribute, int *v
{
int r = primus.afns.glXGetFBConfigAttrib(primus.adpy, config, attribute, value);
if (attribute == GLX_VISUAL_ID && *value)
return primus.dfns.glXGetConfig(primus.ddpy, glXGetVisualFromFBConfig(dpy, config), attribute, value);
return primus.dfns.glXGetConfig(dpy, glXGetVisualFromFBConfig(dpy, config), attribute, value);
return r;
}
......@@ -855,9 +873,10 @@ void glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute, unsigned in
void glXUseXFont(Font font, int first, int count, int list)
{
unsigned long prop;
XFontStruct *fs = XQueryFont(primus.ddpy, font);
Display *dpy = glXGetCurrentDisplay();
XFontStruct *fs = XQueryFont(dpy, font);
XGetFontProperty(fs, XA_FONT, &prop);
char *xlfd = XGetAtomName(primus.ddpy, prop);
char *xlfd = XGetAtomName(dpy, prop);
Font afont = XLoadFont(primus.adpy, xlfd);
primus.afns.glXUseXFont(afont, first, count, list);
XUnloadFont(primus.adpy, afont);
......@@ -913,12 +932,12 @@ ret name par \
// OpenGL forwarders
#define DEF_GLX_PROTO(ret, name, par, ...) \
void ifunc_##name(void) asm(#name) __attribute__((visibility("default"),ifunc("i" #name))); \
extern "C" { \
static ret l##name par \
{ return primus.afns.name(__VA_ARGS__); } \
asm(".type " #name ", @gnu_indirect_function"); \
void *ifunc_##name(void) asm(#name) __attribute__((visibility("default"))); \
void *ifunc_##name(void) \
{ return primus.afns.handle ? real_dlsym(primus.afns.handle, #name) : (void*)l##name; }
static void *i##name(void) \
{ return primus.afns.handle ? real_dlsym(primus.afns.handle, #name) : (void*)l##name; } }
#include "gl-passthru.def"
#undef DEF_GLX_PROTO
......@@ -994,7 +1013,7 @@ const char *glXQueryExtensionsString(Display *dpy, int screen)
static std::string exts
(std::string(glxext_clientside)
+ intersect_exts(glxext_adpy, primus.afns.glXQueryExtensionsString(primus.adpy, 0))
+ intersect_exts(glxext_ddpy, primus.dfns.glXQueryExtensionsString(primus.ddpy, 0)));
+ intersect_exts(glxext_ddpy, primus.dfns.glXQueryExtensionsString(dpy, 0)));
return exts.c_str();
}
......@@ -1006,10 +1025,9 @@ const char *glXQueryExtensionsString(Display *dpy, int screen)
// OpenGL extension forwarders
#define P(name) \
asm(".type " #name ", @gnu_indirect_function"); \
void *ifunc_##name(void) asm(#name) __attribute__((visibility("default"))); \
void *ifunc_##name(void) \
{ return primus.afns.handle ? real_dlsym(primus.afns.handle, #name) : NULL; }
void ifunc_##name(void) asm(#name) __attribute__((visibility("default"),ifunc("i" #name))); \
extern "C" { static void *i##name(void) \
{ return primus.afns.handle ? real_dlsym(primus.afns.handle, #name) : NULL; } }
#include "glext-passthru.def"
#undef P
#endif
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