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 @@ ...@@ -9,7 +9,11 @@
#ifndef LIBANGLE_RENDERER_GL_GLX_DISPLAYGLX_H_ #ifndef LIBANGLE_RENDERER_GL_GLX_DISPLAYGLX_H_
#define 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/DisplayGL.h"
#include "libANGLE/renderer/gl/glx/FunctionsGLX.h"
namespace rx namespace rx
{ {
...@@ -55,7 +59,22 @@ class DisplayGLX : public DisplayGL ...@@ -55,7 +59,22 @@ class DisplayGLX : public DisplayGL
void generateExtensions(egl::DisplayExtensions *outExtensions) const override; void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
void generateCaps(egl::Caps *outCaps) const override; void generateCaps(egl::Caps *outCaps) const override;
int getGLXFBConfigAttrib(GLXFBConfig config, int attrib) const;
FunctionsGL *mFunctionsGL; 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 @@ ...@@ -10,33 +10,97 @@
#include "common/debug.h" #include "common/debug.h"
#include "libANGLE/renderer/gl/glx/FunctionsGLX.h"
namespace rx namespace rx
{ {
WindowSurfaceGLX::WindowSurfaceGLX() WindowSurfaceGLX::WindowSurfaceGLX(const FunctionsGLX &glx, EGLNativeWindowType window, Display* display, GLXContext context, GLXFBConfig fbConfig)
: SurfaceGL() : SurfaceGL(),
mGLX(glx),
mParent(window),
mDisplay(display),
mContext(context),
mFBConfig(fbConfig),
mWindow(0),
mGLXWindow(0)
{ {
} }
WindowSurfaceGLX::~WindowSurfaceGLX() WindowSurfaceGLX::~WindowSurfaceGLX()
{ {
if (mWindow)
{
XDestroyWindow(mDisplay, mWindow);
}
if (mGLXWindow)
{
mGLX.destroyWindow(mDisplay, mGLXWindow);
}
} }
egl::Error WindowSurfaceGLX::initialize() 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); return egl::Error(EGL_SUCCESS);
} }
egl::Error WindowSurfaceGLX::makeCurrent() egl::Error WindowSurfaceGLX::makeCurrent()
{ {
UNIMPLEMENTED(); if (mGLX.makeCurrent(mDisplay, mGLXWindow, mContext) != True)
{
return egl::Error(EGL_BAD_DISPLAY);
}
return egl::Error(EGL_SUCCESS); return egl::Error(EGL_SUCCESS);
} }
egl::Error WindowSurfaceGLX::swap() 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); return egl::Error(EGL_SUCCESS);
} }
...@@ -66,19 +130,31 @@ egl::Error WindowSurfaceGLX::releaseTexImage(EGLint buffer) ...@@ -66,19 +130,31 @@ egl::Error WindowSurfaceGLX::releaseTexImage(EGLint buffer)
void WindowSurfaceGLX::setSwapInterval(EGLint interval) void WindowSurfaceGLX::setSwapInterval(EGLint interval)
{ {
UNIMPLEMENTED(); // TODO(cwallez) WGL has this, implement it
} }
EGLint WindowSurfaceGLX::getWidth() const EGLint WindowSurfaceGLX::getWidth() const
{ {
UNIMPLEMENTED(); Window root;
return 0; 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 EGLint WindowSurfaceGLX::getHeight() const
{ {
UNIMPLEMENTED(); Window root;
return 0; 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 EGLint WindowSurfaceGLX::isPostSubBufferSupported() const
......
...@@ -15,10 +15,12 @@ ...@@ -15,10 +15,12 @@
namespace rx namespace rx
{ {
class FunctionsGLX;
class WindowSurfaceGLX : public SurfaceGL class WindowSurfaceGLX : public SurfaceGL
{ {
public: public:
WindowSurfaceGLX(); WindowSurfaceGLX(const FunctionsGLX &glx, Window window, Display* display, GLXContext context, GLXFBConfig fbConfig);
~WindowSurfaceGLX() override; ~WindowSurfaceGLX() override;
egl::Error initialize(); egl::Error initialize();
...@@ -35,6 +37,14 @@ class WindowSurfaceGLX : public SurfaceGL ...@@ -35,6 +37,14 @@ class WindowSurfaceGLX : public SurfaceGL
EGLint getHeight() const override; EGLint getHeight() const override;
EGLint isPostSubBufferSupported() 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 @@ ...@@ -15,4 +15,8 @@
#include <GL/glx.h> #include <GL/glx.h>
#undef __glext_h_ #undef __glext_h_
#include <X11/Xlib.h>
#include <X11/Xresource.h>
#include <X11/Xutil.h>
#endif // LIBANGLE_RENDERER_GL_GLX_PLATFORMGLX_H_ #endif // LIBANGLE_RENDERER_GL_GLX_PLATFORMGLX_H_
...@@ -742,6 +742,17 @@ ...@@ -742,6 +742,17 @@
{ {
'msvs_enable_winphone' : '1', '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