Integrated GLEW; began migration to Xlib

This commit is contained in:
Jack Andersen
2015-10-30 18:28:21 -10:00
parent b73ecde4aa
commit d013f1e25c
19 changed files with 42193 additions and 486 deletions

View File

@@ -1,6 +1,5 @@
#include "boo/graphicsdev/GLES3.hpp"
#include "boo/graphicsdev/GL.hpp"
#include "boo/IGraphicsContext.hpp"
#include <GLES3/gl3ext.h>
#include <vector>
#include <thread>
#include <mutex>
@@ -10,7 +9,7 @@
namespace boo
{
static LogVisor::LogModule Log("boo::GLES3");
static LogVisor::LogModule Log("boo::GL");
struct GLES3Data : IGraphicsData
{
@@ -247,7 +246,6 @@ public:
glEnable(GL_DEPTH_TEST);
else
glDisable(GL_DEPTH_TEST);
glDepthMask(m_depthWrite);
if (m_backfaceCulling)
@@ -275,6 +273,7 @@ static const GLenum BLEND_FACTOR_TABLE[] =
const IShaderPipeline* GLES3DataFactory::newShaderPipeline
(const char* vertSource, const char* fragSource,
size_t texCount, const char** texNames,
BlendFactor srcFac, BlendFactor dstFac,
bool depthTest, bool depthWrite, bool backfaceCulling)
{
@@ -332,6 +331,14 @@ const IShaderPipeline* GLES3DataFactory::newShaderPipeline
return nullptr;
}
glUseProgram(shader.m_prog);
for (size_t i=0 ; i<texCount ; ++i)
{
GLint loc;
if ((loc = glGetUniformLocation(shader.m_prog, texNames[i])) >= 0)
glUniform1i(loc, i);
}
GLES3ShaderPipeline* retval = new GLES3ShaderPipeline(std::move(shader));
static_cast<GLES3Data*>(m_deferredData.get())->m_SPs.emplace_back(retval);
return retval;
@@ -460,7 +467,8 @@ struct GLES3CommandQueue : IGraphicsCommandQueue
OpDraw,
OpDrawIndexed,
OpDrawInstances,
OpDrawInstancesIndexed
OpDrawInstancesIndexed,
OpPresent
} m_op;
union
{
@@ -483,9 +491,12 @@ struct GLES3CommandQueue : IGraphicsCommandQueue
size_t m_completeBuf = 0;
size_t m_drawBuf = 0;
bool m_running = true;
std::thread m_thr;
std::mutex m_mt;
std::condition_variable m_cv;
std::unique_lock<std::mutex> m_initlk;
std::condition_variable m_initcv;
std::thread m_thr;
/* These members are locked for multithreaded access */
std::vector<GLES3VertexFormat*> m_pendingFmtAdds;
@@ -537,7 +548,14 @@ struct GLES3CommandQueue : IGraphicsCommandQueue
static void RenderingWorker(GLES3CommandQueue* self)
{
self->m_parent->makeCurrent();
{
std::unique_lock<std::mutex> lk(self->m_mt);
self->m_parent->makeCurrent();
if (glewInit() != GLEW_OK)
Log.report(LogVisor::FatalError, "unable to init glew");
self->m_parent->postInit();
}
self->m_initcv.notify_one();
while (self->m_running)
{
{
@@ -603,6 +621,9 @@ struct GLES3CommandQueue : IGraphicsCommandQueue
case Command::OpDrawInstancesIndexed:
glDrawElementsInstanced(prim, cmd.count, GL_UNSIGNED_INT, (void*)cmd.start, cmd.instCount);
break;
case Command::OpPresent:
self->m_parent->present();
break;
default: break;
}
}
@@ -612,7 +633,12 @@ struct GLES3CommandQueue : IGraphicsCommandQueue
GLES3CommandQueue(IGraphicsContext* parent)
: m_parent(parent),
m_thr(RenderingWorker, this) {}
m_initlk(m_mt),
m_thr(RenderingWorker, this)
{
m_initcv.wait(m_initlk);
m_initlk.unlock();
}
~GLES3CommandQueue()
{
@@ -694,6 +720,12 @@ struct GLES3CommandQueue : IGraphicsCommandQueue
cmds.back().instCount = instCount;
}
void present()
{
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
cmds.emplace_back(Command::OpPresent);
}
void addVertexFormat(GLES3VertexFormat* fmt)
{
std::unique_lock<std::mutex> lk(m_mt);
@@ -718,7 +750,6 @@ struct GLES3CommandQueue : IGraphicsCommandQueue
m_pendingFboDels.push_back(tex->m_fbo);
}
void execute()
{
std::unique_lock<std::mutex> lk(m_mt);

34
lib/graphicsdev/GLX.cpp Normal file
View File

@@ -0,0 +1,34 @@
#include "boo/graphicsdev/glxew.h"
#include <LogVisor/LogVisor.hpp>
namespace boo
{
static LogVisor::LogModule Log("boo::GLX");
void GLXExtensionCheck()
{
if (!GLXEW_SGI_video_sync)
Log.report(LogVisor::FatalError, "GLX_SGI_video_sync not available");
if (!GLXEW_EXT_swap_control && !GLXEW_MESA_swap_control && !GLXEW_SGI_swap_control)
Log.report(LogVisor::FatalError, "swap_control not available");
}
void GLXWaitForVSync()
{
unsigned int sync;
int err = glXWaitVideoSyncSGI(1, 0, &sync);
if (err)
Log.report(LogVisor::FatalError, "wait err");
}
void GLXEnableVSync(Display* disp, GLXWindow drawable)
{
if (GLXEW_EXT_swap_control)
glXSwapIntervalEXT(disp, drawable, 1);
else if (GLXEW_MESA_swap_control)
glXSwapIntervalMESA(1);
else if (GLXEW_SGI_swap_control)
glXSwapIntervalSGI(1);
}
}

18607
lib/graphicsdev/glew.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -90,8 +90,7 @@ class HIDListenerUdev final : public IHIDListener
{
const char* interfacesStr = udev_list_entry_get_value(devInterfaces);
if (strstr(interfacesStr, ":030104") || /* HID / GenericDesktop / Joystick */
strstr(interfacesStr, ":030105") || /* HID / GenericDesktop / Gamepad */
strstr(interfacesStr, ":090000")) /* HID / Sony / Dualshock */
strstr(interfacesStr, ":030105")) /* HID / GenericDesktop / Gamepad */
{
udev_enumerate* hidEnum = udev_enumerate_new(UDEV_INST);
udev_enumerate_add_match_parent(hidEnum, device);

View File

@@ -4,114 +4,83 @@
#include "boo/IApplication.hpp"
#define explicit explicit_c
#include <xcb/xcb.h>
#include <xcb/xcb_event.h>
#include <xkbcommon/xkbcommon-x11.h>
#include <xcb/xkb.h>
#include <xcb/xinput.h>
#include <xcb/glx.h>
#undef explicit
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
#include <X11/extensions/XInput2.h>
#include <GL/glx.h>
#include <GL/glxext.h>
#include <dbus/dbus.h>
DBusConnection* RegisterDBus(const char* appName, bool& isFirst);
#include <LogVisor/LogVisor.hpp>
#include <sys/param.h>
#include <thread>
namespace boo
{
PFNGLXGETVIDEOSYNCSGIPROC FglXGetVideoSyncSGI = nullptr;
PFNGLXWAITVIDEOSYNCSGIPROC FglXWaitVideoSyncSGI = nullptr;
static LogVisor::LogModule Log("boo::ApplicationXCB");
int XCB_GLX_EVENT_BASE = 0;
int XINPUT_OPCODE = 0;
static xcb_window_t GetWindowOfEvent(xcb_generic_event_t* event, bool& windowEvent)
static Window GetWindowOfEvent(XEvent* event, bool& windowEvent)
{
switch (XCB_EVENT_RESPONSE_TYPE(event))
switch (event->type)
{
case XCB_CLIENT_MESSAGE:
case ClientMessage:
{
xcb_client_message_event_t* ev = (xcb_client_message_event_t*)event;
windowEvent = true;
return ev->window;
return event->xclient.window;
}
case XCB_EXPOSE:
case Expose:
{
xcb_expose_event_t* ev = (xcb_expose_event_t*)event;
windowEvent = true;
return ev->window;
return event->xexpose.window;
}
case XCB_CONFIGURE_NOTIFY:
case ConfigureNotify:
{
xcb_configure_notify_event_t* ev = (xcb_configure_notify_event_t*)event;
windowEvent = true;
return ev->window;
return event->xconfigure.window;
}
case XCB_KEY_PRESS:
case KeyPress:
{
xcb_key_press_event_t* ev = (xcb_key_press_event_t*)event;
windowEvent = true;
return ev->event;
return event->xkey.window;
}
case XCB_KEY_RELEASE:
case KeyRelease:
{
xcb_key_release_event_t* ev = (xcb_key_release_event_t*)event;
windowEvent = true;
return ev->event;
return event->xkey.window;
}
case XCB_BUTTON_PRESS:
case ButtonPress:
{
xcb_button_press_event_t* ev = (xcb_button_press_event_t*)event;
windowEvent = true;
return ev->event;
return event->xbutton.window;
}
case XCB_BUTTON_RELEASE:
case ButtonRelease:
{
xcb_button_release_event_t* ev = (xcb_button_release_event_t*)event;
windowEvent = true;
return ev->event;
return event->xbutton.window;;
}
case XCB_MOTION_NOTIFY:
case MotionNotify:
{
xcb_motion_notify_event_t* ev = (xcb_motion_notify_event_t*)event;
windowEvent = true;
return ev->event;
return event->xmotion.window;
}
case XCB_GE_GENERIC:
case GenericEvent:
{
xcb_ge_event_t* gev = (xcb_ge_event_t*)event;
if (gev->pad0 == XINPUT_OPCODE)
if (event->xgeneric.extension == XINPUT_OPCODE)
{
switch (gev->event_type)
switch (event->xgeneric.evtype)
{
case XCB_INPUT_MOTION:
case XI_Motion:
case XI_TouchBegin:
case XI_TouchUpdate:
case XI_TouchEnd:
{
xcb_input_motion_event_t* ev = (xcb_input_motion_event_t*)event;
windowEvent = true;
return ev->event;
}
case XCB_INPUT_TOUCH_BEGIN:
{
xcb_input_touch_begin_event_t* ev = (xcb_input_touch_begin_event_t*)event;
windowEvent = true;
return ev->event;
}
case XCB_INPUT_TOUCH_UPDATE:
{
xcb_input_touch_update_event_t* ev = (xcb_input_touch_update_event_t*)event;
windowEvent = true;
return ev->event;
}
case XCB_INPUT_TOUCH_END:
{
xcb_input_touch_end_event_t* ev = (xcb_input_touch_end_event_t*)event;
XIDeviceEvent* ev = (XIDeviceEvent*)event;
windowEvent = true;
return ev->event;
}
@@ -123,8 +92,9 @@ static xcb_window_t GetWindowOfEvent(xcb_generic_event_t* event, bool& windowEve
return 0;
}
IWindow* _WindowXCBNew(const std::string& title, xcb_connection_t* conn,
xcb_glx_context_t lastCtx);
IWindow* _WindowXCBNew(const std::string& title,
Display* display, int defaultScreen,
GLXContext lastCtx);
class ApplicationXCB final : public IApplication
{
@@ -136,17 +106,18 @@ class ApplicationXCB final : public IApplication
/* DBus single-instance */
bool m_singleInstance;
DBusConnection* m_dbus = NULL;
DBusConnection* m_dbus = nullptr;
/* All windows */
std::unordered_map<xcb_window_t, IWindow*> m_windows;
std::unordered_map<Window, IWindow*> m_windows;
xcb_connection_t* m_xcbConn = NULL;
Display* m_xDisp = nullptr;
int m_xDefaultScreen = 0;
int m_xcbFd, m_dbusFd, m_maxFd;
void _deletedWindow(IWindow* window)
{
m_windows.erase((xcb_window_t)window->getPlatformHandle());
m_windows.erase((Window)window->getPlatformHandle());
}
public:
@@ -206,43 +177,39 @@ public:
}
}
/* Open X connection */
m_xcbConn = xcb_connect(NULL, NULL);
if (!XInitThreads())
{
Log.report(LogVisor::FatalError, "X doesn't support multithreading");
return;
}
/* Open Xlib Display */
m_xDisp = XOpenDisplay(0);
if (!m_xDisp)
{
Log.report(LogVisor::FatalError, "Can't open X display");
return;
}
m_xDefaultScreen = DefaultScreen(m_xDisp);
/* GLX extension data */
const xcb_query_extension_reply_t* glxExtData =
xcb_get_extension_data(m_xcbConn, &xcb_glx_id);
XCB_GLX_EVENT_BASE = glxExtData->first_event;
FglXGetVideoSyncSGI = PFNGLXGETVIDEOSYNCSGIPROC(glXGetProcAddress((GLubyte*)"glXGetVideoSyncSGI"));
FglXWaitVideoSyncSGI = PFNGLXWAITVIDEOSYNCSGIPROC(glXGetProcAddress((GLubyte*)"glXWaitVideoSyncSGI"));
/* The xkb extension requests that the X server does not
* send repeated keydown events when a key is held */
xkb_x11_setup_xkb_extension(m_xcbConn,
XKB_X11_MIN_MAJOR_XKB_VERSION,
XKB_X11_MIN_MINOR_XKB_VERSION,
XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS,
NULL, NULL, NULL, NULL);
xcb_xkb_per_client_flags(m_xcbConn, XCB_XKB_ID_USE_CORE_KBD,
XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT,
XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT, 0, 0, 0);
/* Xinput major opcode */
const xcb_query_extension_reply_t* xiReply =
xcb_get_extension_data(m_xcbConn, &xcb_input_id);
XINPUT_OPCODE = xiReply->major_opcode;
XkbQueryExtension(m_xDisp, &XINPUT_OPCODE, nullptr, nullptr, nullptr, nullptr);
XkbSetDetectableAutoRepeat(m_xDisp, True, nullptr);
/* Get file descriptors of xcb and dbus interfaces */
m_xcbFd = xcb_get_file_descriptor(m_xcbConn);
m_xcbFd = ConnectionNumber(m_xDisp);
dbus_connection_get_unix_fd(m_dbus, &m_dbusFd);
m_maxFd = MAX(m_xcbFd, m_dbusFd);
xcb_flush(m_xcbConn);
XFlush(m_xDisp);
}
~ApplicationXCB()
{
xcb_disconnect(m_xcbConn);
XCloseDisplay(m_xDisp);
}
EPlatformType getPlatformType() const
@@ -252,7 +219,7 @@ public:
int run()
{
if (!m_xcbConn)
if (!m_xDisp)
return 1;
/* Spawn client thread */
@@ -263,7 +230,6 @@ public:
/* Begin application event loop */
while (true)
{
xcb_generic_event_t* event;
fd_set fds;
FD_ZERO(&fds);
FD_SET(m_xcbFd, &fds);
@@ -272,19 +238,19 @@ public:
if (FD_ISSET(m_xcbFd, &fds))
{
event = xcb_poll_for_event(m_xcbConn);
if (event)
while (XPending(m_xDisp))
{
XEvent event;
XNextEvent(m_xDisp, &event);
bool windowEvent;
xcb_window_t evWindow = GetWindowOfEvent(event, windowEvent);
Window evWindow = GetWindowOfEvent(&event, windowEvent);
//fprintf(stderr, "EVENT %d\n", XCB_EVENT_RESPONSE_TYPE(event));
if (windowEvent)
{
auto window = m_windows.find(evWindow);
if (window != m_windows.end())
window->second->_incomingEvent(event);
window->second->_incomingEvent(&event);
}
free(event);
}
}
@@ -342,16 +308,16 @@ public:
std::unique_ptr<IWindow> newWindow(const std::string& title)
{
IWindow* newWindow = _WindowXCBNew(title, m_xcbConn, m_lastGlxCtx);
m_windows[(xcb_window_t)newWindow->getPlatformHandle()] = newWindow;
IWindow* newWindow = _WindowXCBNew(title, m_xDisp, m_xDefaultScreen, m_lastGlxCtx);
m_windows[(Window)newWindow->getPlatformHandle()] = newWindow;
return std::unique_ptr<IWindow>(newWindow);
}
/* Last GLX context */
xcb_glx_context_t m_lastGlxCtx = 0;
GLXContext m_lastGlxCtx = nullptr;
};
void _XCBUpdateLastGlxCtx(xcb_glx_context_t lastGlxCtx)
void _XCBUpdateLastGlxCtx(GLXContext lastGlxCtx)
{
static_cast<ApplicationXCB*>(APP)->m_lastGlxCtx = lastGlxCtx;
}

View File

@@ -2,14 +2,9 @@
#include "boo/IGraphicsContext.hpp"
#include <X11/Xlib.h>
#include <GL/glx.h>
#include <GL/glxext.h>
namespace boo
{
extern PFNGLXGETVIDEOSYNCSGIPROC FglXGetVideoSyncSGI;
extern PFNGLXWAITVIDEOSYNCSGIPROC FglXWaitVideoSyncSGI;
struct GraphicsContextWayland : IGraphicsContext
{
@@ -63,6 +58,10 @@ public:
{
}
void postInit()
{
}
IGraphicsCommandQueue* getCommandQueue()
{
return nullptr;
@@ -78,6 +77,10 @@ public:
return nullptr;
}
void present()
{
}
};
struct WindowWayland : IWindow
@@ -150,11 +153,8 @@ struct WindowWayland : IWindow
}
size_t waitForRetrace(size_t count)
void waitForRetrace()
{
unsigned int sync;
FglXWaitVideoSyncSGI(1, 0, &sync);
return 0;
}
uintptr_t getPlatformHandle() const

File diff suppressed because it is too large Load Diff