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

@ -19,7 +19,8 @@ if(WIN32)
lib/inputdev/HIDDeviceWinUSB.cpp lib/inputdev/HIDDeviceWinUSB.cpp
lib/graphicsdev/D3D11.cpp lib/graphicsdev/D3D11.cpp
lib/graphicsdev/D3D12.cpp lib/graphicsdev/D3D12.cpp
lib/graphicsdev/GLES3.cpp) lib/graphicsdev/GL.cpp
lib/graphicsdev/glew.c)
list(APPEND _BOO_SYS_LIBS Winusb) list(APPEND _BOO_SYS_LIBS Winusb)
elseif(APPLE) elseif(APPLE)
list(APPEND PLAT_SRCS list(APPEND PLAT_SRCS
@ -28,7 +29,8 @@ elseif(APPLE)
lib/mac/GLViewCocoa.mm lib/mac/GLViewCocoa.mm
lib/inputdev/HIDListenerIOKit.cpp lib/inputdev/HIDListenerIOKit.cpp
lib/inputdev/HIDDeviceIOKit.cpp lib/inputdev/HIDDeviceIOKit.cpp
lib/graphicsdev/GLES3.cpp) lib/graphicsdev/GL.cpp
lib/graphicsdev/glew.c)
find_library(APPKIT_LIBRARY AppKit) find_library(APPKIT_LIBRARY AppKit)
find_library(IOKIT_LIBRARY IOKit) find_library(IOKIT_LIBRARY IOKit)
find_library(OPENGL_LIBRARY OpenGL) find_library(OPENGL_LIBRARY OpenGL)
@ -42,7 +44,9 @@ else()
lib/x11/WindowWayland.cpp lib/x11/WindowWayland.cpp
lib/inputdev/HIDListenerUdev.cpp lib/inputdev/HIDListenerUdev.cpp
lib/inputdev/HIDDeviceUdev.cpp lib/inputdev/HIDDeviceUdev.cpp
lib/graphicsdev/GLES3.cpp) lib/graphicsdev/GL.cpp
lib/graphicsdev/GLX.cpp
lib/graphicsdev/glew.c)
find_package(PkgConfig) find_package(PkgConfig)
if(PKG_CONFIG_FOUND) if(PKG_CONFIG_FOUND)
@ -85,10 +89,15 @@ else()
endif() endif()
include_directories(${DBUS_INCLUDE_DIR} ${DBUS_ARCH_INCLUDE_DIR}) include_directories(${DBUS_INCLUDE_DIR} ${DBUS_ARCH_INCLUDE_DIR})
list(APPEND _BOO_SYS_LIBS xcb xcb-glx xcb-xinput xcb-xkb xcb-keysyms xkbcommon xkbcommon-x11 GL ${DBUS_LIBRARY} udev pthread) list(APPEND _BOO_SYS_LIBS X11 Xi xkbcommon xkbcommon-x11 GL ${DBUS_LIBRARY} udev pthread)
endif() endif()
# For some reason, clang takes forever if glew.c is not built with -Os
if(CMAKE_BUILD_TYPE STREQUAL "Release")
set_source_files_properties(lib/graphicsdev/glew.c PROPERTIES COMPILE_FLAGS -Os)
endif()
set(BOO_SYS_LIBS ${_BOO_SYS_LIBS} CACHE PATH "Boo System Libraries" FORCE) set(BOO_SYS_LIBS ${_BOO_SYS_LIBS} CACHE PATH "Boo System Libraries" FORCE)
include_directories(include) include_directories(include)
@ -106,7 +115,7 @@ add_library(Boo
include/boo/IGraphicsContext.hpp include/boo/IGraphicsContext.hpp
include/boo/graphicsdev/IGraphicsDataFactory.hpp include/boo/graphicsdev/IGraphicsDataFactory.hpp
include/boo/graphicsdev/IGraphicsCommandQueue.hpp include/boo/graphicsdev/IGraphicsCommandQueue.hpp
include/boo/graphicsdev/GLES3.hpp include/boo/graphicsdev/GL.hpp
include/boo/graphicsdev/D3D11.hpp include/boo/graphicsdev/D3D11.hpp
include/boo/graphicsdev/D3D12.hpp include/boo/graphicsdev/D3D12.hpp
include/boo/graphicsdev/Metal.hpp include/boo/graphicsdev/Metal.hpp

74
GLEW-LICENSE Normal file
View File

@ -0,0 +1,74 @@
The OpenGL Extension Wrangler Library
Copyright (C) 2002-2007, Milan Ikits <milan ikits[]ieee org>
Copyright (C) 2002-2007, Marcelo E. Magallon <mmagallo[]debian org>
Copyright (C) 2002, Lev Povalahev
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* The name of the author may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
Mesa 3-D graphics library
Version: 7.0
Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Copyright (c) 2007 The Khronos Group Inc.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and/or associated documentation files (the
"Materials"), to deal in the Materials without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Materials, and to
permit persons to whom the Materials are furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Materials.
THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.

22
LICENSE Normal file
View File

@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015
Jack Andersen and Phillip "Antidote" Stephens
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -46,6 +46,8 @@ public:
virtual void setPixelFormat(EPixelFormat pf)=0; virtual void setPixelFormat(EPixelFormat pf)=0;
virtual void initializeContext()=0; virtual void initializeContext()=0;
virtual void makeCurrent()=0; virtual void makeCurrent()=0;
virtual void postInit()=0;
virtual void present()=0;
virtual IGraphicsCommandQueue* getCommandQueue()=0; virtual IGraphicsCommandQueue* getCommandQueue()=0;
virtual IGraphicsDataFactory* getDataFactory()=0; virtual IGraphicsDataFactory* getDataFactory()=0;

View File

@ -136,7 +136,7 @@ public:
virtual bool isFullscreen() const=0; virtual bool isFullscreen() const=0;
virtual void setFullscreen(bool fs)=0; virtual void setFullscreen(bool fs)=0;
virtual size_t waitForRetrace(size_t lastCount)=0; virtual void waitForRetrace()=0;
virtual uintptr_t getPlatformHandle() const=0; virtual uintptr_t getPlatformHandle() const=0;
virtual void _incomingEvent(void* event) {(void)event;} virtual void _incomingEvent(void* event) {(void)event;}

View File

@ -4,7 +4,7 @@
#include "IGraphicsDataFactory.hpp" #include "IGraphicsDataFactory.hpp"
#include "IGraphicsCommandQueue.hpp" #include "IGraphicsCommandQueue.hpp"
#include "boo/IGraphicsContext.hpp" #include "boo/IGraphicsContext.hpp"
#include <GLES3/gl3.h> #include "glew.h"
#include <vector> #include <vector>
namespace boo namespace boo
@ -30,6 +30,7 @@ public:
const IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements); const IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements);
const IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource, const IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource,
size_t texCount, const char** texNames,
BlendFactor srcFac, BlendFactor dstFac, BlendFactor srcFac, BlendFactor dstFac,
bool depthTest, bool depthWrite, bool backfaceCulling); bool depthTest, bool depthWrite, bool backfaceCulling);

View File

@ -31,6 +31,7 @@ struct IGraphicsCommandQueue
virtual void drawInstances(size_t start, size_t count, size_t instCount)=0; virtual void drawInstances(size_t start, size_t count, size_t instCount)=0;
virtual void drawInstancesIndexed(size_t start, size_t count, size_t instCount)=0; virtual void drawInstancesIndexed(size_t start, size_t count, size_t instCount)=0;
virtual void present()=0;
virtual void execute()=0; virtual void execute()=0;
}; };

19753
include/boo/graphicsdev/glew.h Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -55,7 +55,8 @@ private:
} }
inline bool _insertToken(DeviceToken&& token) inline bool _insertToken(DeviceToken&& token)
{ {
if (DeviceSignature::DeviceMatchToken(token, m_types)) { if (DeviceSignature::DeviceMatchToken(token, m_types))
{
m_tokensLock.lock(); m_tokensLock.lock();
TInsertedDeviceToken inseredTok = TInsertedDeviceToken inseredTok =
m_tokens.insert(std::make_pair(token.getDevicePath(), std::move(token))); m_tokens.insert(std::make_pair(token.getDevicePath(), std::move(token)));

View File

@ -1,6 +1,5 @@
#include "boo/graphicsdev/GLES3.hpp" #include "boo/graphicsdev/GL.hpp"
#include "boo/IGraphicsContext.hpp" #include "boo/IGraphicsContext.hpp"
#include <GLES3/gl3ext.h>
#include <vector> #include <vector>
#include <thread> #include <thread>
#include <mutex> #include <mutex>
@ -10,7 +9,7 @@
namespace boo namespace boo
{ {
static LogVisor::LogModule Log("boo::GLES3"); static LogVisor::LogModule Log("boo::GL");
struct GLES3Data : IGraphicsData struct GLES3Data : IGraphicsData
{ {
@ -247,7 +246,6 @@ public:
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
else else
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
glDepthMask(m_depthWrite); glDepthMask(m_depthWrite);
if (m_backfaceCulling) if (m_backfaceCulling)
@ -275,6 +273,7 @@ static const GLenum BLEND_FACTOR_TABLE[] =
const IShaderPipeline* GLES3DataFactory::newShaderPipeline const IShaderPipeline* GLES3DataFactory::newShaderPipeline
(const char* vertSource, const char* fragSource, (const char* vertSource, const char* fragSource,
size_t texCount, const char** texNames,
BlendFactor srcFac, BlendFactor dstFac, BlendFactor srcFac, BlendFactor dstFac,
bool depthTest, bool depthWrite, bool backfaceCulling) bool depthTest, bool depthWrite, bool backfaceCulling)
{ {
@ -332,6 +331,14 @@ const IShaderPipeline* GLES3DataFactory::newShaderPipeline
return nullptr; 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)); GLES3ShaderPipeline* retval = new GLES3ShaderPipeline(std::move(shader));
static_cast<GLES3Data*>(m_deferredData.get())->m_SPs.emplace_back(retval); static_cast<GLES3Data*>(m_deferredData.get())->m_SPs.emplace_back(retval);
return retval; return retval;
@ -460,7 +467,8 @@ struct GLES3CommandQueue : IGraphicsCommandQueue
OpDraw, OpDraw,
OpDrawIndexed, OpDrawIndexed,
OpDrawInstances, OpDrawInstances,
OpDrawInstancesIndexed OpDrawInstancesIndexed,
OpPresent
} m_op; } m_op;
union union
{ {
@ -483,9 +491,12 @@ struct GLES3CommandQueue : IGraphicsCommandQueue
size_t m_completeBuf = 0; size_t m_completeBuf = 0;
size_t m_drawBuf = 0; size_t m_drawBuf = 0;
bool m_running = true; bool m_running = true;
std::thread m_thr;
std::mutex m_mt; std::mutex m_mt;
std::condition_variable m_cv; 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 */ /* These members are locked for multithreaded access */
std::vector<GLES3VertexFormat*> m_pendingFmtAdds; std::vector<GLES3VertexFormat*> m_pendingFmtAdds;
@ -537,7 +548,14 @@ struct GLES3CommandQueue : IGraphicsCommandQueue
static void RenderingWorker(GLES3CommandQueue* self) 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) while (self->m_running)
{ {
{ {
@ -603,6 +621,9 @@ struct GLES3CommandQueue : IGraphicsCommandQueue
case Command::OpDrawInstancesIndexed: case Command::OpDrawInstancesIndexed:
glDrawElementsInstanced(prim, cmd.count, GL_UNSIGNED_INT, (void*)cmd.start, cmd.instCount); glDrawElementsInstanced(prim, cmd.count, GL_UNSIGNED_INT, (void*)cmd.start, cmd.instCount);
break; break;
case Command::OpPresent:
self->m_parent->present();
break;
default: break; default: break;
} }
} }
@ -612,7 +633,12 @@ struct GLES3CommandQueue : IGraphicsCommandQueue
GLES3CommandQueue(IGraphicsContext* parent) GLES3CommandQueue(IGraphicsContext* parent)
: m_parent(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() ~GLES3CommandQueue()
{ {
@ -694,6 +720,12 @@ struct GLES3CommandQueue : IGraphicsCommandQueue
cmds.back().instCount = instCount; cmds.back().instCount = instCount;
} }
void present()
{
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
cmds.emplace_back(Command::OpPresent);
}
void addVertexFormat(GLES3VertexFormat* fmt) void addVertexFormat(GLES3VertexFormat* fmt)
{ {
std::unique_lock<std::mutex> lk(m_mt); std::unique_lock<std::mutex> lk(m_mt);
@ -718,7 +750,6 @@ struct GLES3CommandQueue : IGraphicsCommandQueue
m_pendingFboDels.push_back(tex->m_fbo); m_pendingFboDels.push_back(tex->m_fbo);
} }
void execute() void execute()
{ {
std::unique_lock<std::mutex> lk(m_mt); 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); const char* interfacesStr = udev_list_entry_get_value(devInterfaces);
if (strstr(interfacesStr, ":030104") || /* HID / GenericDesktop / Joystick */ if (strstr(interfacesStr, ":030104") || /* HID / GenericDesktop / Joystick */
strstr(interfacesStr, ":030105") || /* HID / GenericDesktop / Gamepad */ strstr(interfacesStr, ":030105")) /* HID / GenericDesktop / Gamepad */
strstr(interfacesStr, ":090000")) /* HID / Sony / Dualshock */
{ {
udev_enumerate* hidEnum = udev_enumerate_new(UDEV_INST); udev_enumerate* hidEnum = udev_enumerate_new(UDEV_INST);
udev_enumerate_add_match_parent(hidEnum, device); udev_enumerate_add_match_parent(hidEnum, device);

View File

@ -4,114 +4,83 @@
#include "boo/IApplication.hpp" #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/Xlib.h>
#include <X11/XKBlib.h>
#include <X11/extensions/XInput2.h>
#include <GL/glx.h> #include <GL/glx.h>
#include <GL/glxext.h> #include <GL/glxext.h>
#include <dbus/dbus.h> #include <dbus/dbus.h>
DBusConnection* RegisterDBus(const char* appName, bool& isFirst); DBusConnection* RegisterDBus(const char* appName, bool& isFirst);
#include <LogVisor/LogVisor.hpp>
#include <sys/param.h> #include <sys/param.h>
#include <thread> #include <thread>
namespace boo namespace boo
{ {
static LogVisor::LogModule Log("boo::ApplicationXCB");
PFNGLXGETVIDEOSYNCSGIPROC FglXGetVideoSyncSGI = nullptr;
PFNGLXWAITVIDEOSYNCSGIPROC FglXWaitVideoSyncSGI = nullptr;
int XCB_GLX_EVENT_BASE = 0; int XCB_GLX_EVENT_BASE = 0;
int XINPUT_OPCODE = 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; 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; 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; 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; 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; 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; 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; 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; 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 (event->xgeneric.extension == XINPUT_OPCODE)
if (gev->pad0 == 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; XIDeviceEvent* ev = (XIDeviceEvent*)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;
windowEvent = true; windowEvent = true;
return ev->event; return ev->event;
} }
@ -123,8 +92,9 @@ static xcb_window_t GetWindowOfEvent(xcb_generic_event_t* event, bool& windowEve
return 0; return 0;
} }
IWindow* _WindowXCBNew(const std::string& title, xcb_connection_t* conn, IWindow* _WindowXCBNew(const std::string& title,
xcb_glx_context_t lastCtx); Display* display, int defaultScreen,
GLXContext lastCtx);
class ApplicationXCB final : public IApplication class ApplicationXCB final : public IApplication
{ {
@ -136,17 +106,18 @@ class ApplicationXCB final : public IApplication
/* DBus single-instance */ /* DBus single-instance */
bool m_singleInstance; bool m_singleInstance;
DBusConnection* m_dbus = NULL; DBusConnection* m_dbus = nullptr;
/* All windows */ /* 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; int m_xcbFd, m_dbusFd, m_maxFd;
void _deletedWindow(IWindow* window) void _deletedWindow(IWindow* window)
{ {
m_windows.erase((xcb_window_t)window->getPlatformHandle()); m_windows.erase((Window)window->getPlatformHandle());
} }
public: public:
@ -206,43 +177,39 @@ public:
} }
} }
/* Open X connection */ if (!XInitThreads())
m_xcbConn = xcb_connect(NULL, NULL); {
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 /* The xkb extension requests that the X server does not
* send repeated keydown events when a key is held */ * send repeated keydown events when a key is held */
xkb_x11_setup_xkb_extension(m_xcbConn, XkbQueryExtension(m_xDisp, &XINPUT_OPCODE, nullptr, nullptr, nullptr, nullptr);
XKB_X11_MIN_MAJOR_XKB_VERSION, XkbSetDetectableAutoRepeat(m_xDisp, True, nullptr);
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;
/* Get file descriptors of xcb and dbus interfaces */ /* 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); dbus_connection_get_unix_fd(m_dbus, &m_dbusFd);
m_maxFd = MAX(m_xcbFd, m_dbusFd); m_maxFd = MAX(m_xcbFd, m_dbusFd);
xcb_flush(m_xcbConn); XFlush(m_xDisp);
} }
~ApplicationXCB() ~ApplicationXCB()
{ {
xcb_disconnect(m_xcbConn); XCloseDisplay(m_xDisp);
} }
EPlatformType getPlatformType() const EPlatformType getPlatformType() const
@ -252,7 +219,7 @@ public:
int run() int run()
{ {
if (!m_xcbConn) if (!m_xDisp)
return 1; return 1;
/* Spawn client thread */ /* Spawn client thread */
@ -263,7 +230,6 @@ public:
/* Begin application event loop */ /* Begin application event loop */
while (true) while (true)
{ {
xcb_generic_event_t* event;
fd_set fds; fd_set fds;
FD_ZERO(&fds); FD_ZERO(&fds);
FD_SET(m_xcbFd, &fds); FD_SET(m_xcbFd, &fds);
@ -272,19 +238,19 @@ public:
if (FD_ISSET(m_xcbFd, &fds)) if (FD_ISSET(m_xcbFd, &fds))
{ {
event = xcb_poll_for_event(m_xcbConn); while (XPending(m_xDisp))
if (event)
{ {
XEvent event;
XNextEvent(m_xDisp, &event);
bool windowEvent; bool windowEvent;
xcb_window_t evWindow = GetWindowOfEvent(event, windowEvent); Window evWindow = GetWindowOfEvent(&event, windowEvent);
//fprintf(stderr, "EVENT %d\n", XCB_EVENT_RESPONSE_TYPE(event)); //fprintf(stderr, "EVENT %d\n", XCB_EVENT_RESPONSE_TYPE(event));
if (windowEvent) if (windowEvent)
{ {
auto window = m_windows.find(evWindow); auto window = m_windows.find(evWindow);
if (window != m_windows.end()) 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) std::unique_ptr<IWindow> newWindow(const std::string& title)
{ {
IWindow* newWindow = _WindowXCBNew(title, m_xcbConn, m_lastGlxCtx); IWindow* newWindow = _WindowXCBNew(title, m_xDisp, m_xDefaultScreen, m_lastGlxCtx);
m_windows[(xcb_window_t)newWindow->getPlatformHandle()] = newWindow; m_windows[(Window)newWindow->getPlatformHandle()] = newWindow;
return std::unique_ptr<IWindow>(newWindow); return std::unique_ptr<IWindow>(newWindow);
} }
/* Last GLX context */ /* 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; static_cast<ApplicationXCB*>(APP)->m_lastGlxCtx = lastGlxCtx;
} }

View File

@ -2,14 +2,9 @@
#include "boo/IGraphicsContext.hpp" #include "boo/IGraphicsContext.hpp"
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <GL/glx.h>
#include <GL/glxext.h>
namespace boo namespace boo
{ {
extern PFNGLXGETVIDEOSYNCSGIPROC FglXGetVideoSyncSGI;
extern PFNGLXWAITVIDEOSYNCSGIPROC FglXWaitVideoSyncSGI;
struct GraphicsContextWayland : IGraphicsContext struct GraphicsContextWayland : IGraphicsContext
{ {
@ -63,6 +58,10 @@ public:
{ {
} }
void postInit()
{
}
IGraphicsCommandQueue* getCommandQueue() IGraphicsCommandQueue* getCommandQueue()
{ {
return nullptr; return nullptr;
@ -78,6 +77,10 @@ public:
return nullptr; return nullptr;
} }
void present()
{
}
}; };
struct WindowWayland : IWindow 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 uintptr_t getPlatformHandle() const

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,11 @@
#include <stdio.h> #include <stdio.h>
#include <math.h>
#include <boo/boo.hpp> #include <boo/boo.hpp>
#include <boo/graphicsdev/GLES3.hpp> #include <boo/graphicsdev/GL.hpp>
#include <thread> #include <thread>
#include <mutex> #include <mutex>
#include <condition_variable> #include <condition_variable>
#include <LogVisor/LogVisor.hpp>
namespace boo namespace boo
{ {
@ -226,19 +228,20 @@ struct TestApplicationCallback : IApplicationCallback
/* Make shader pipeline */ /* Make shader pipeline */
static const char* VS = static const char* VS =
"#version 300\n" "#version 300 es\n"
"layout(location=0) in vec3 in_pos;\n" "layout(location=0) in vec3 in_pos;\n"
"layout(location=1) in vec2 in_uv;\n" "layout(location=1) in vec2 in_uv;\n"
"out vec2 out_uv;\n" "out vec2 out_uv;\n"
"void main()\n" "void main()\n"
"{\n" "{\n"
" gl_Position = in_pos;\n" " gl_Position = vec4(in_pos, 1.0);\n"
" out_uv = in_uv;\n" " out_uv = in_uv;\n"
"}\n"; "}\n";
static const char* FS = static const char* FS =
"#version 300\n" "#version 300 es\n"
"layout(binding=0) uniform sampler2D tex;\n" "precision highp float;\n"
"uniform sampler2D tex;\n"
"layout(location=0) out vec4 out_frag;\n" "layout(location=0) out vec4 out_frag;\n"
"in vec2 out_uv;\n" "in vec2 out_uv;\n"
"void main()\n" "void main()\n"
@ -246,8 +249,10 @@ struct TestApplicationCallback : IApplicationCallback
" out_frag = texture(tex, out_uv);\n" " out_frag = texture(tex, out_uv);\n"
"}\n"; "}\n";
static const char* TexNames[] = {"tex"};
const IShaderPipeline* pipeline = const IShaderPipeline* pipeline =
factory->newShaderPipeline(VS, FS, BlendFactorOne, BlendFactorZero, true, true, false); factory->newShaderPipeline(VS, FS, 1, TexNames, BlendFactorOne, BlendFactorZero, true, true, false);
/* Make shader data binding */ /* Make shader data binding */
self->m_binding = self->m_binding =
@ -278,18 +283,23 @@ struct TestApplicationCallback : IApplicationCallback
IGraphicsCommandQueue* gfxQ = mainWindow->getCommandQueue(); IGraphicsCommandQueue* gfxQ = mainWindow->getCommandQueue();
std::thread loaderThread(LoaderProc, this); std::thread loaderThread(LoaderProc, this);
size_t retraceCount = 0; size_t frameIdx = 0;
while (running) while (running)
{ {
retraceCount = mainWindow->waitForRetrace(retraceCount); mainWindow->waitForRetrace();
float rgba[] = {sinf(frameIdx / 60.0), cosf(frameIdx / 60.0), 0.0, 1.0};
gfxQ->setClearColor(rgba);
gfxQ->clearTarget();
if (m_binding) if (m_binding)
{ {
gfxQ->setDrawPrimitive(PrimitiveTriStrips); gfxQ->setDrawPrimitive(PrimitiveTriStrips);
gfxQ->clearTarget();
gfxQ->setShaderDataBinding(m_binding); gfxQ->setShaderDataBinding(m_binding);
gfxQ->draw(0, 4); gfxQ->draw(0, 4);
gfxQ->execute();
} }
gfxQ->present();
gfxQ->execute();
fprintf(stderr, "%zu\n", frameIdx++);
} }
m_cv.notify_one(); m_cv.notify_one();
@ -323,6 +333,7 @@ int wmain(int argc, const wchar_t** argv)
int main(int argc, const char** argv) int main(int argc, const char** argv)
#endif #endif
{ {
LogVisor::RegisterConsoleLogger();
boo::TestApplicationCallback appCb; boo::TestApplicationCallback appCb;
std::unique_ptr<boo::IApplication> app = std::unique_ptr<boo::IApplication> app =
ApplicationBootstrap(boo::IApplication::PLAT_AUTO, ApplicationBootstrap(boo::IApplication::PLAT_AUTO,