mirror of
https://github.com/AxioDL/boo.git
synced 2025-12-09 21:47:57 +00:00
Integrated GLEW; began migration to Xlib
This commit is contained in:
@@ -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
34
lib/graphicsdev/GLX.cpp
Normal 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
18607
lib/graphicsdev/glew.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user