Commit eac64633 by Corentin Wallez

Add a basic GLX EGL implementation

BUG=angleproject:892 Change-Id: Ife9955a457d4a6fb3adce17757ccb0de7d0dd274 Reviewed-on: https://chromium-review.googlesource.com/269413Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent f229cb9b
......@@ -9,7 +9,11 @@
#ifndef LIBANGLE_RENDERER_GL_GLX_DISPLAYGLX_H_
#define LIBANGLE_RENDERER_GL_GLX_DISPLAYGLX_H_
#include <string>
#include <vector>
#include "libANGLE/renderer/gl/DisplayGL.h"
#include "libANGLE/renderer/gl/glx/FunctionsGLX.h"
namespace rx
{
......@@ -55,7 +59,22 @@ class DisplayGLX : public DisplayGL
void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
void generateCaps(egl::Caps *outCaps) const override;
int getGLXFBConfigAttrib(GLXFBConfig config, int attrib) const;
FunctionsGL *mFunctionsGL;
//TODO(cwallez) yuck, change generateConfigs to be non-const or add a userdata member to egl::Config?
mutable std::map<int, GLXFBConfig> configIdToGLXConfig;
// The ID of the visual used to create the context
int mContextVisualId;
GLXContext mContext;
// A pbuffer the context is current on during ANGLE initialization
GLXPbuffer mDummyPbuffer;
FunctionsGLX mGLX;
egl::Display *mEGLDisplay;
Display *mXDisplay;
};
}
......
......@@ -10,33 +10,97 @@
#include "common/debug.h"
#include "libANGLE/renderer/gl/glx/FunctionsGLX.h"
namespace rx
{
WindowSurfaceGLX::WindowSurfaceGLX()
: SurfaceGL()
WindowSurfaceGLX::WindowSurfaceGLX(const FunctionsGLX &glx, EGLNativeWindowType window, Display* display, GLXContext context, GLXFBConfig fbConfig)
: SurfaceGL(),
mGLX(glx),
mParent(window),
mDisplay(display),
mContext(context),
mFBConfig(fbConfig),
mWindow(0),
mGLXWindow(0)
{
}
WindowSurfaceGLX::~WindowSurfaceGLX()
{
if (mWindow)
{
XDestroyWindow(mDisplay, mWindow);
}
if (mGLXWindow)
{
mGLX.destroyWindow(mDisplay, mGLXWindow);
}
}
egl::Error WindowSurfaceGLX::initialize()
{
UNIMPLEMENTED();
// The visual of the X window, GLX window and GLX context must match,
// however we received a user-created window that can have any visual
// and wouldn't work with our GLX context. To work in all cases, we
// create a child window with the right visual that covers all of its
// parent.
XVisualInfo* visualInfo = mGLX.getVisualFromFBConfig(mDisplay, mFBConfig);
if (!visualInfo)
{
return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to get the XVisualInfo for the child window.");
}
Visual* visual = visualInfo->visual;
XWindowAttributes parentAttribs;
XGetWindowAttributes(mDisplay, mParent, &parentAttribs);
// The depth, colormap and visual must match otherwise we get a X error
// so we specify the colormap attribute. Also we do not want the window
// to be taken into account for input so we specify the event and
// do-not-propagate masks to 0 (the defaults).
XSetWindowAttributes attributes;
unsigned long attributeMask = CWColormap;
Colormap colormap = XCreateColormap(mDisplay, mParent, visual, AllocNone);
if(!colormap)
{
XFree(visualInfo);
return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to create the Colormap for the child window.");
}
attributes.colormap = colormap;
//TODO(cwallez) set up our own error handler to see if the call failed
mWindow = XCreateWindow(mDisplay, mParent, 0, 0, parentAttribs.width, parentAttribs.height,
0, visualInfo->depth, InputOutput, visual, attributeMask, &attributes);
mGLXWindow = mGLX.createWindow(mDisplay, mFBConfig, mWindow, nullptr);
XMapWindow(mDisplay, mWindow);
XFlush(mDisplay);
XFree(visualInfo);
XFreeColormap(mDisplay, colormap);
return egl::Error(EGL_SUCCESS);
}
egl::Error WindowSurfaceGLX::makeCurrent()
{
UNIMPLEMENTED();
if (mGLX.makeCurrent(mDisplay, mGLXWindow, mContext) != True)
{
return egl::Error(EGL_BAD_DISPLAY);
}
return egl::Error(EGL_SUCCESS);
}
egl::Error WindowSurfaceGLX::swap()
{
UNIMPLEMENTED();
//TODO(cwallez) resize support
//TODO(cwallez) set up our own error handler to see if the call failed
mGLX.swapBuffers(mDisplay, mGLXWindow);
return egl::Error(EGL_SUCCESS);
}
......@@ -66,19 +130,31 @@ egl::Error WindowSurfaceGLX::releaseTexImage(EGLint buffer)
void WindowSurfaceGLX::setSwapInterval(EGLint interval)
{
UNIMPLEMENTED();
// TODO(cwallez) WGL has this, implement it
}
EGLint WindowSurfaceGLX::getWidth() const
{
UNIMPLEMENTED();
return 0;
Window root;
int x, y;
unsigned width, height, border, depth;
if (!XGetGeometry(mDisplay, mParent, &root, &x, &y, &width, &height, &border, &depth))
{
return 0;
}
return width;
}
EGLint WindowSurfaceGLX::getHeight() const
{
UNIMPLEMENTED();
return 0;
Window root;
int x, y;
unsigned width, height, border, depth;
if (!XGetGeometry(mDisplay, mParent, &root, &x, &y, &width, &height, &border, &depth))
{
return 0;
}
return height;
}
EGLint WindowSurfaceGLX::isPostSubBufferSupported() const
......
......@@ -15,10 +15,12 @@
namespace rx
{
class FunctionsGLX;
class WindowSurfaceGLX : public SurfaceGL
{
public:
WindowSurfaceGLX();
WindowSurfaceGLX(const FunctionsGLX &glx, Window window, Display* display, GLXContext context, GLXFBConfig fbConfig);
~WindowSurfaceGLX() override;
egl::Error initialize();
......@@ -35,6 +37,14 @@ class WindowSurfaceGLX : public SurfaceGL
EGLint getHeight() const override;
EGLint isPostSubBufferSupported() const override;
private:
const FunctionsGLX &mGLX;
Window mParent;
Display *mDisplay;
GLXContext mContext;
GLXFBConfig mFBConfig;
Window mWindow;
GLXWindow mGLXWindow;
};
}
......
......@@ -15,4 +15,8 @@
#include <GL/glx.h>
#undef __glext_h_
#include <X11/Xlib.h>
#include <X11/Xresource.h>
#include <X11/Xutil.h>
#endif // LIBANGLE_RENDERER_GL_GLX_PLATFORMGLX_H_
......@@ -742,6 +742,17 @@
{
'msvs_enable_winphone' : '1',
}],
['OS=="linux"',
{
'link_settings': {
'ldflags': [
'<!@(pkg-config --libs-only-L --libs-only-other x11 xi)',
],
'libraries': [
'<!@(pkg-config --libs-only-l x11 xi)',
],
},
}],
],
},
],
......
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