added new clang format and fixed window creation endless loops + implemented missing functions

dev
keldu.magnus 2020-10-27 05:04:44 +01:00
parent 04d4e2a02f
commit c43377a5a1
14 changed files with 536 additions and 371 deletions

121
.clang-format Normal file
View File

@ -0,0 +1,121 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: false
IndentPPDirectives: None
IndentWidth: 4
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 4
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 4
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 4
UseTab: ForContinuationAndIndentation
...

View File

@ -5,110 +5,109 @@
#include "window_xcb.h" #include "window_xcb.h"
namespace gin { namespace gin {
XcbDevice::XcbDevice(::Display* display, int screen, XcbDevice::XcbDevice(::Display *display, int screen,
xcb_connection_t* xcb_connection, xcb_screen_t* xcb_screen, xcb_connection_t *xcb_connection, xcb_screen_t *xcb_screen,
Own<InputStream>&& an) Own<InputStream> &&an)
: display{display}, : display{display}, screen{screen}, xcb_connection{xcb_connection},
screen{screen}, xcb_screen{xcb_screen}, async_notifier{std::move(an)},
xcb_connection{xcb_connection}, async_conveyor{async_notifier->readReady()
xcb_screen{xcb_screen}, .then([this]() { handleEvents(); })
async_notifier{std::move(an)}, .buffer(1)} {}
async_conveyor{async_notifier->readReady()
.then([this]() { handleEvents(); })
.buffer(1)} {}
XcbDevice::~XcbDevice() { XcbDevice::~XcbDevice() {
if (display) { if (display) {
xcb_flush(xcb_connection); xcb_flush(xcb_connection);
::XCloseDisplay(display); ::XCloseDisplay(display);
} }
} }
void XcbDevice::windowDestroyed(xcb_window_t window_id) { void XcbDevice::windowDestroyed(xcb_window_t window_id) {
windows.erase(window_id); windows.erase(window_id);
} }
Own<XcbWindow> XcbDevice::createXcbWindow(const VideoMode& video_mode, void XcbDevice::handleEvents() {}
std::string_view title_view,
int visual_id) {
assert(xcb_screen);
assert(xcb_connection);
xcb_colormap_t xcb_colormap = xcb_generate_id(xcb_connection); Own<XcbWindow> XcbDevice::createXcbWindow(const VideoMode &video_mode,
xcb_window_t xcb_window = xcb_generate_id(xcb_connection); std::string_view title_view,
int visual_id) {
assert(xcb_screen);
assert(xcb_connection);
xcb_create_colormap(xcb_connection, XCB_COLORMAP_ALLOC_NONE, xcb_colormap, xcb_colormap_t xcb_colormap = xcb_generate_id(xcb_connection);
xcb_screen->root, visual_id); xcb_window_t xcb_window = xcb_generate_id(xcb_connection);
uint32_t eventmask = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS; xcb_create_colormap(xcb_connection, XCB_COLORMAP_ALLOC_NONE, xcb_colormap,
uint32_t valuelist[] = {eventmask, xcb_colormap, 0}; xcb_screen->root, visual_id);
uint32_t valuemask = XCB_CW_EVENT_MASK | XCB_CW_COLORMAP;
xcb_create_window(xcb_connection, XCB_COPY_FROM_PARENT, xcb_window, uint32_t eventmask = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS;
xcb_screen->root, 0, 0, video_mode.width, video_mode.height, uint32_t valuelist[] = {eventmask, xcb_colormap, 0};
0, XCB_WINDOW_CLASS_INPUT_OUTPUT, visual_id, valuemask, uint32_t valuemask = XCB_CW_EVENT_MASK | XCB_CW_COLORMAP;
valuelist);
xcb_change_property(xcb_connection, XCB_PROP_MODE_REPLACE, xcb_window, xcb_create_window(xcb_connection, XCB_COPY_FROM_PARENT, xcb_window,
XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, title_view.size(), xcb_screen->root, 0, 0, video_mode.width,
title_view.data()); video_mode.height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
visual_id, valuemask, valuelist);
xcb_flush(xcb_connection); xcb_change_property(xcb_connection, XCB_PROP_MODE_REPLACE, xcb_window,
XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, title_view.size(),
title_view.data());
return heap<XcbWindow>(*this, xcb_window, xcb_colormap, video_mode, xcb_flush(xcb_connection);
title_view);
return heap<XcbWindow>(*this, xcb_window, xcb_colormap, video_mode,
title_view);
} }
Own<Window> XcbDevice::createWindow(const VideoMode& video_mode, Own<Window> XcbDevice::createWindow(const VideoMode &video_mode,
std::string_view title_view) { std::string_view title_view) {
assert(xcb_screen); assert(xcb_screen);
return createXcbWindow(video_mode, title_view, xcb_screen->root_visual); return createXcbWindow(video_mode, title_view, xcb_screen->root_visual);
} }
void XcbDevice::flush() { void XcbDevice::flush() {
assert(xcb_connection); assert(xcb_connection);
xcb_flush(xcb_connection); xcb_flush(xcb_connection);
} }
Own<XcbDevice> createXcbDevice(AsyncIoProvider& provider) { Own<XcbDevice> createXcbDevice(AsyncIoProvider &provider) {
::Display* display = ::XOpenDisplay(nullptr); ::Display *display = ::XOpenDisplay(nullptr);
if (!display) { if (!display) {
/// @todo log errors /// @todo log errors
return nullptr; return nullptr;
} }
int screen = ::XDefaultScreen(display); int screen = ::XDefaultScreen(display);
xcb_connection_t* xcb_connection = ::XGetXCBConnection(display); xcb_connection_t *xcb_connection = ::XGetXCBConnection(display);
if (!xcb_connection) { if (!xcb_connection) {
/// @todo log errors /// @todo log errors
::XCloseDisplay(display); ::XCloseDisplay(display);
return nullptr; return nullptr;
} }
int fd = xcb_get_file_descriptor(xcb_connection); int fd = xcb_get_file_descriptor(xcb_connection);
Own<InputStream> fd_wrapped = provider.wrapInputFd(fd); Own<InputStream> fd_wrapped = provider.wrapInputFd(fd);
if (!fd_wrapped) { if (!fd_wrapped) {
::XCloseDisplay(display); ::XCloseDisplay(display);
return nullptr; return nullptr;
} }
::XSetEventQueueOwner(display, XCBOwnsEventQueue); ::XSetEventQueueOwner(display, XCBOwnsEventQueue);
xcb_screen_iterator_t screen_iter = xcb_screen_iterator_t screen_iter =
xcb_setup_roots_iterator(xcb_get_setup(xcb_connection)); xcb_setup_roots_iterator(xcb_get_setup(xcb_connection));
for (int screen_i = screen; screen_iter.rem && screen_i > 0; for (int screen_i = screen; screen_iter.rem && screen_i > 0;
--screen_i, xcb_screen_next(&screen_iter)) --screen_i, xcb_screen_next(&screen_iter))
; ;
xcb_screen_t* xcb_screen = screen_iter.data; xcb_screen_t *xcb_screen = screen_iter.data;
return heap<XcbDevice>(display, screen, xcb_connection, xcb_screen, return heap<XcbDevice>(display, screen, xcb_connection, xcb_screen,
std::move(fd_wrapped)); std::move(fd_wrapped));
} }
Own<Device> createDevice(AsyncIoProvider& provider) { Own<Device> createDevice(AsyncIoProvider &provider) {
return createXcbDevice(provider); return createXcbDevice(provider);
} }
} // namespace gin } // namespace gin

View File

@ -12,33 +12,33 @@
namespace gin { namespace gin {
class XcbDevice final : public Device { class XcbDevice final : public Device {
public: public:
::Display* display; ::Display *display;
int screen; int screen;
xcb_connection_t* xcb_connection; xcb_connection_t *xcb_connection;
xcb_screen_t* xcb_screen; xcb_screen_t *xcb_screen;
Own<InputStream> async_notifier; Own<InputStream> async_notifier;
Conveyor<void> async_conveyor; Conveyor<void> async_conveyor;
std::map<xcb_window_t, XcbWindow*> windows; std::map<xcb_window_t, XcbWindow *> windows;
public: public:
XcbDevice(::Display* display, int screen, xcb_connection_t* xcb_connection, XcbDevice(::Display *display, int screen, xcb_connection_t *xcb_connection,
xcb_screen_t* xcb_screen, Own<InputStream>&& an); xcb_screen_t *xcb_screen, Own<InputStream> &&an);
~XcbDevice(); ~XcbDevice();
void windowDestroyed(xcb_window_t window_id); void windowDestroyed(xcb_window_t window_id);
void handleEvents(); void handleEvents();
Own<XcbWindow> createXcbWindow(const VideoMode& mode, Own<XcbWindow> createXcbWindow(const VideoMode &mode,
std::string_view title_view, int visual_id); std::string_view title_view, int visual_id);
Own<Window> createWindow(const VideoMode& video_mode, Own<Window> createWindow(const VideoMode &video_mode,
std::string_view title_view) override; std::string_view title_view) override;
void flush() override; void flush() override;
}; };
Own<XcbDevice> createXcbDevice(AsyncIoProvider& provider); Own<XcbDevice> createXcbDevice(AsyncIoProvider &provider);
} // namespace gin } // namespace gin

View File

@ -7,178 +7,195 @@
#include <string_view> #include <string_view>
#include <vector> #include <vector>
#include "device_xcb.h" #include "../device_xcb.h"
#include "gl_window_xcb.h"
namespace gin { namespace gin {
namespace { namespace {
GlxLibraryExtensions glxLibraryExtensions(const char* extension_string) { GlxLibraryExtensions glxLibraryExtensions(const char *extension_string) {
std::string_view extensions_view{extension_string}; std::string_view extensions_view{extension_string};
std::set<std::string_view> extensions; std::set<std::string_view> extensions;
while (1) { while (1) {
size_t n = extensions_view.find_first_not_of(' '); size_t n = extensions_view.find_first_of(' ');
if (n != extensions_view.npos && n < extensions_view.size()) { if (n != extensions_view.npos && n < extensions_view.size()) {
std::string_view sub_glx_ext = extensions_view.substr(0, n); std::string_view sub_glx_ext = extensions_view.substr(0, n);
extensions.insert(sub_glx_ext); extensions.insert(sub_glx_ext);
} else { extensions_view.remove_prefix(n + 1);
break; } else {
} break;
} }
}
auto find = extensions.find("glXCreateContextAttribsARB"); auto find = extensions.find("GLX_ARB_create_context");
GLXContext (*glXCreateContextAttribsARB)(Display*, GLXFBConfig, GLXContext, GLXContext (*glXCreateContextAttribsARB)(Display *, GLXFBConfig, GLXContext,
Bool, const int*) = nullptr; Bool, const int *) = nullptr;
if (find != extensions.end()) { if (find != extensions.end()) {
glXCreateContextAttribsARB = reinterpret_cast<GLXContext (*)( glXCreateContextAttribsARB = reinterpret_cast<GLXContext (*)(
Display*, GLXFBConfig, GLXContext, Bool, const int*)>( Display *, GLXFBConfig, GLXContext, Bool, const int *)>(
glXGetProcAddress( glXGetProcAddress(reinterpret_cast<const GLubyte *>(
reinterpret_cast<const GLubyte*>("glXCreateContextAttribsARB"))); "glXCreateContextAttribsARB")));
} }
return {extensions_view, glXCreateContextAttribsARB}; return {extensions_view, glXCreateContextAttribsARB};
} }
int translateRenderTypeSetting(GlSettings::RenderType cmp) { int translateRenderTypeSetting(GlSettings::RenderType cmp) {
switch (cmp) { switch (cmp) {
case GlSettings::RenderType::RGBA: case GlSettings::RenderType::RGBA:
return GLX_RGBA_BIT; return GLX_RGBA_BIT;
break; break;
} }
return 0; return 0;
} }
int translateDrawableTypeSetting(GlSettings::DrawableType cmp) { int translateDrawableTypeSetting(GlSettings::DrawableType cmp) {
int i = 0; int i = 0;
if (static_cast<int32_t>(cmp) & if (static_cast<int32_t>(cmp) &
static_cast<int32_t>(GlSettings::DrawableType::WindowBit)) { static_cast<int32_t>(GlSettings::DrawableType::WindowBit)) {
i |= static_cast<int32_t>(GLX_WINDOW_BIT); i |= static_cast<int32_t>(GLX_WINDOW_BIT);
} }
if (static_cast<int32_t>(cmp) & if (static_cast<int32_t>(cmp) &
static_cast<int32_t>(GlSettings::DrawableType::PixMapBit)) { static_cast<int32_t>(GlSettings::DrawableType::PixMapBit)) {
i |= static_cast<int32_t>(GLX_PIXMAP_BIT); i |= static_cast<int32_t>(GLX_PIXMAP_BIT);
} }
if (static_cast<int32_t>(cmp) & if (static_cast<int32_t>(cmp) &
static_cast<int32_t>(GlSettings::DrawableType::PBufferBit)) { static_cast<int32_t>(GlSettings::DrawableType::PBufferBit)) {
i |= static_cast<int32_t>(GLX_PBUFFER_BIT); i |= static_cast<int32_t>(GLX_PBUFFER_BIT);
} }
return i; return i;
} }
} // namespace } // namespace
XcbGlContext::XcbGlContext(const GlxLibraryExtensions& ext_lib, XcbGlContext::XcbGlContext(const GlxLibraryExtensions &ext_lib,
Own<XcbDevice>&& dev, int visual_id, Own<XcbDevice> &&dev, int visual_id,
GLXContext context, GLXFBConfig fb_config) GLXContext context, GLXFBConfig fb_config)
: ext_lib{ext_lib}, : ext_lib{ext_lib}, device{std::move(dev)}, visual_id{visual_id},
device{std::move(dev)}, context{context}, fb_config{fb_config} {}
visual_id{visual_id},
context{context},
fb_config{fb_config} {}
XcbGlContext::~XcbGlContext() { XcbGlContext::~XcbGlContext() {
assert(device); assert(device);
assert(device->display); assert(device->display);
if (context) { if (context) {
::glXMakeContextCurrent(device->display, None, None, nullptr); ::glXMakeContextCurrent(device->display, None, None, nullptr);
::glXDestroyContext(device->display, context); ::glXDestroyContext(device->display, context);
} }
device->flush(); device->flush();
} }
void XcbGlContext::bind() {} void XcbGlContext::bind() {}
Own<GlWindow> XcbGlContext::createWindow(const VideoMode& video_mode, Own<GlWindow> XcbGlContext::createWindow(const VideoMode &video_mode,
std::string_view title_view) { std::string_view title_view) {
return nullptr; assert(device);
if (!device) {
return nullptr;
}
gin::Own<XcbWindow> window =
device->createXcbWindow(video_mode, title_view, visual_id);
if (!window) {
return nullptr;
}
::GLXWindow glx_window = glXCreateWindow(device->display, fb_config,
window->xcb_window, nullptr);
return gin::heap<XcbGlWindow>(std::move(window), *this, glx_window);
} }
void XcbGlContext::flush() {} void XcbGlContext::flush() {
assert(device);
Own<GlContext> createGlContext(AsyncIoProvider& provider, if (device) {
const GlSettings& settings) { device->flush();
Own<XcbDevice> device = createXcbDevice(provider); }
if (!device) {
return nullptr;
}
/*
* Translate all attributes
*/
std::vector<int> attributes;
attributes.reserve(33);
attributes.push_back(GLX_X_RENDERABLE);
attributes.push_back(settings.renderable ? True : False);
attributes.push_back(GLX_RENDER_TYPE);
attributes.push_back(translateRenderTypeSetting(settings.render_type));
attributes.push_back(GLX_RED_SIZE);
attributes.push_back(settings.red_bits);
attributes.push_back(GLX_GREEN_SIZE);
attributes.push_back(settings.green_bits);
attributes.push_back(GLX_BLUE_SIZE);
attributes.push_back(settings.blue_bits);
attributes.push_back(GLX_ALPHA_SIZE);
attributes.push_back(settings.alpha_bits);
attributes.push_back(GLX_DEPTH_SIZE);
attributes.push_back(settings.depth_bits);
attributes.push_back(GLX_STENCIL_SIZE);
attributes.push_back(settings.stencil_bits);
attributes.push_back(GLX_DOUBLEBUFFER);
attributes.push_back(settings.double_buffer ? True : False);
attributes.push_back(GLX_DRAWABLE_TYPE);
attributes.push_back(translateDrawableTypeSetting(settings.drawable_type));
attributes.push_back(GLX_X_VISUAL_TYPE);
attributes.push_back(GLX_TRUE_COLOR);
attributes.push_back(None);
int num_fb_configs = 0;
GlxLibraryExtensions lib_ext = glxLibraryExtensions(
glXQueryExtensionsString(device->display, device->screen));
GLXFBConfig* fb_configs = glXChooseFBConfig(device->display, device->screen,
&attributes[0], &num_fb_configs);
if (!fb_configs || num_fb_configs == 0) {
/// @todo log errors
return nullptr;
}
::GLXFBConfig fb_config = fb_configs[0];
::XFree(fb_configs);
::GLXContext context;
if (lib_ext.glXCreateContextAttribsARB) {
std::vector<int> glx_attribs;
glx_attribs.reserve(11);
glx_attribs.push_back(GLX_CONTEXT_MAJOR_VERSION_ARB);
glx_attribs.push_back(settings.gl_major);
glx_attribs.push_back(GLX_CONTEXT_MINOR_VERSION_ARB);
glx_attribs.push_back(settings.gl_minor);
glx_attribs.push_back(GLX_CONTEXT_PROFILE_MASK_ARB);
glx_attribs.push_back(settings.core_profile
? GLX_CONTEXT_CORE_PROFILE_BIT_ARB
: GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB);
glx_attribs.push_back(None);
context = lib_ext.glXCreateContextAttribsARB(device->display, fb_config,
NULL, True, &glx_attribs[0]);
if (!context) {
return nullptr;
}
} else {
return nullptr;
}
int visual_id = 0;
glXGetFBConfigAttrib(device->display, fb_config, GLX_VISUAL_ID, &visual_id);
return heap<XcbGlContext>(lib_ext, std::move(device), visual_id, context,
fb_config);
} }
} // namespace gin
Own<GlContext> createGlContext(AsyncIoProvider &provider,
const GlSettings &settings) {
Own<XcbDevice> device = createXcbDevice(provider);
if (!device) {
return nullptr;
}
/*
* Translate all attributes
*/
std::vector<int> attributes;
attributes.reserve(33);
attributes.push_back(GLX_X_RENDERABLE);
attributes.push_back(settings.renderable ? True : False);
attributes.push_back(GLX_RENDER_TYPE);
attributes.push_back(translateRenderTypeSetting(settings.render_type));
attributes.push_back(GLX_RED_SIZE);
attributes.push_back(settings.red_bits);
attributes.push_back(GLX_GREEN_SIZE);
attributes.push_back(settings.green_bits);
attributes.push_back(GLX_BLUE_SIZE);
attributes.push_back(settings.blue_bits);
attributes.push_back(GLX_ALPHA_SIZE);
attributes.push_back(settings.alpha_bits);
attributes.push_back(GLX_DEPTH_SIZE);
attributes.push_back(settings.depth_bits);
attributes.push_back(GLX_STENCIL_SIZE);
attributes.push_back(settings.stencil_bits);
attributes.push_back(GLX_DOUBLEBUFFER);
attributes.push_back(settings.double_buffer ? True : False);
attributes.push_back(GLX_DRAWABLE_TYPE);
attributes.push_back(translateDrawableTypeSetting(settings.drawable_type));
attributes.push_back(GLX_X_VISUAL_TYPE);
attributes.push_back(GLX_TRUE_COLOR);
attributes.push_back(None);
int num_fb_configs = 0;
GlxLibraryExtensions lib_ext = glxLibraryExtensions(
glXQueryExtensionsString(device->display, device->screen));
GLXFBConfig *fb_configs = glXChooseFBConfig(
device->display, device->screen, &attributes[0], &num_fb_configs);
if (!fb_configs || num_fb_configs == 0) {
/// @todo log errors
return nullptr;
}
::GLXFBConfig fb_config = fb_configs[0];
::XFree(fb_configs);
::GLXContext context;
if (lib_ext.glXCreateContextAttribsARB) {
std::vector<int> glx_attribs;
glx_attribs.reserve(11);
glx_attribs.push_back(GLX_CONTEXT_MAJOR_VERSION_ARB);
glx_attribs.push_back(settings.gl_major);
glx_attribs.push_back(GLX_CONTEXT_MINOR_VERSION_ARB);
glx_attribs.push_back(settings.gl_minor);
glx_attribs.push_back(GLX_CONTEXT_PROFILE_MASK_ARB);
glx_attribs.push_back(settings.core_profile
? GLX_CONTEXT_CORE_PROFILE_BIT_ARB
: GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB);
glx_attribs.push_back(None);
context = lib_ext.glXCreateContextAttribsARB(
device->display, fb_config, NULL, True, &glx_attribs[0]);
if (!context) {
return nullptr;
}
} else {
return nullptr;
}
int visual_id = 0;
glXGetFBConfigAttrib(device->display, fb_config, GLX_VISUAL_ID, &visual_id);
return heap<XcbGlContext>(lib_ext, std::move(device), visual_id, context,
fb_config);
}
} // namespace gin

View File

@ -9,30 +9,30 @@
namespace gin { namespace gin {
struct GlxLibraryExtensions { struct GlxLibraryExtensions {
public: public:
std::string_view raw_extension_string; std::string_view raw_extension_string;
GLXContext (*glXCreateContextAttribsARB)(Display*, GLXFBConfig, GLXContext, GLXContext (*glXCreateContextAttribsARB)(Display *, GLXFBConfig, GLXContext,
Bool, const int*) = nullptr; Bool, const int *) = nullptr;
}; };
class XcbDevice; class XcbDevice;
class XcbGlContext final : public GlContext { class XcbGlContext final : public GlContext {
private: public:
GlxLibraryExtensions ext_lib; GlxLibraryExtensions ext_lib;
Own<XcbDevice> device; Own<XcbDevice> device;
int visual_id; int visual_id;
GLXContext context; GLXContext context;
GLXFBConfig fb_config; GLXFBConfig fb_config;
public: public:
XcbGlContext(const GlxLibraryExtensions&, Own<XcbDevice>&&, int, GLXContext, XcbGlContext(const GlxLibraryExtensions &, Own<XcbDevice> &&, int,
GLXFBConfig); GLXContext, GLXFBConfig);
~XcbGlContext(); ~XcbGlContext();
void bind() override; void bind() override;
Own<GlWindow> createWindow(const VideoMode&, std::string_view) override; Own<GlWindow> createWindow(const VideoMode &, std::string_view) override;
void flush() override; void flush() override;
}; };
} // namespace gin } // namespace gin

View File

@ -1,5 +1,32 @@
#include "gl_window_xcb.h" #include "gl_window_xcb.h"
#include "window_xcb.h" #include "gl_context_xcb.h"
namespace gin {} #include "../device_xcb.h"
#include "../window_xcb.h"
#include <cassert>
namespace gin {
XcbGlWindow::XcbGlWindow(Own<XcbWindow> &&win, XcbGlContext &ctx,
::GLXWindow glx_win)
: window{std::move(win)}, context{ctx}, glx_window{glx_win} {}
XcbGlWindow::~XcbGlWindow() {
assert(context.device);
if (context.device) {
glXDestroyWindow(context.device->display, glx_window);
}
}
void XcbGlWindow::bind() {}
void XcbGlWindow::show() {
assert(window);
if (window) {
window->show();
}
}
void XcbGlWindow::swap() {}
} // namespace gin

View File

@ -9,14 +9,18 @@ namespace gin {
class XcbWindow; class XcbWindow;
class XcbGlContext; class XcbGlContext;
class XcbGlWindow final : public GlWindow { class XcbGlWindow final : public GlWindow {
public: public:
Own<XcbWindow> window; Own<XcbWindow> window;
XcbGlContext& context; XcbGlContext &context;
::GLXWindow glx_window; ::GLXWindow glx_window;
public: public:
XcbGlWindow(Own<XcbWindow>&&, XcbGlContext&, ::GLXWindow); XcbGlWindow(Own<XcbWindow> &&, XcbGlContext &, ::GLXWindow);
~XcbGlWindow(); ~XcbGlWindow();
void bind() override;
void swap() override;
void show() override;
}; };
} // namespace gin } // namespace gin

View File

@ -5,32 +5,29 @@
#include "device_xcb.h" #include "device_xcb.h"
namespace gin { namespace gin {
XcbWindow::XcbWindow(XcbDevice& device, xcb_window_t xcb_window, XcbWindow::XcbWindow(XcbDevice &device, xcb_window_t xcb_window,
xcb_colormap_t xcb_colormap, const VideoMode& video_mode, xcb_colormap_t xcb_colormap, const VideoMode &video_mode,
std::string_view title_view) std::string_view title_view)
: device{device}, : device{device}, xcb_window{xcb_window}, xcb_colormap{xcb_colormap},
xcb_window{xcb_window}, video_mode{video_mode}, window_title{title_view} {}
xcb_colormap{xcb_colormap},
video_mode{video_mode},
window_title{title_view} {}
XcbWindow::~XcbWindow() { XcbWindow::~XcbWindow() {
device.windowDestroyed(xcb_window); device.windowDestroyed(xcb_window);
xcb_destroy_window(device.xcb_connection, xcb_window); xcb_destroy_window(device.xcb_connection, xcb_window);
device.flush(); device.flush();
} }
void XcbWindow::show() { void XcbWindow::show() {
assert(device.xcb_connection); assert(device.xcb_connection);
xcb_map_window(device.xcb_connection, xcb_window); xcb_map_window(device.xcb_connection, xcb_window);
} }
void XcbWindow::hide() { void XcbWindow::hide() {
assert(device.xcb_connection); assert(device.xcb_connection);
xcb_unmap_window(device.xcb_connection, xcb_window); xcb_unmap_window(device.xcb_connection, xcb_window);
} }
const VideoMode& XcbWindow::videoMode() const { return video_mode; } const VideoMode &XcbWindow::videoMode() const { return video_mode; }
const std::string_view XcbWindow::title() const { return window_title; } const std::string_view XcbWindow::title() const { return window_title; }
} // namespace gin } // namespace gin

View File

@ -11,25 +11,25 @@
namespace gin { namespace gin {
class XcbDevice; class XcbDevice;
class XcbWindow final : public Window { class XcbWindow final : public Window {
public: public:
XcbDevice& device; XcbDevice &device;
xcb_window_t xcb_window; xcb_window_t xcb_window;
xcb_colormap_t xcb_colormap; xcb_colormap_t xcb_colormap;
VideoMode video_mode; VideoMode video_mode;
std::string window_title; std::string window_title;
public: public:
XcbWindow(XcbDevice& device, xcb_window_t xcb_window, XcbWindow(XcbDevice &device, xcb_window_t xcb_window,
xcb_colormap_t xcb_colormap, const VideoMode& video_mode, xcb_colormap_t xcb_colormap, const VideoMode &video_mode,
std::string_view title_view); std::string_view title_view);
~XcbWindow(); ~XcbWindow();
void show() override; void show() override;
void hide() override; void hide() override;
const VideoMode& videoMode() const override; const VideoMode &videoMode() const override;
const std::string_view title() const override; const std::string_view title() const override;
}; };
} // namespace gin } // namespace gin

View File

@ -8,14 +8,14 @@
namespace gin { namespace gin {
class Device { class Device {
public: public:
virtual ~Device() = default; virtual ~Device() = default;
virtual Own<Window> createWindow(const VideoMode& mode, virtual Own<Window> createWindow(const VideoMode &mode,
std::string_view title_view) = 0; std::string_view title_view) = 0;
virtual void flush() = 0; virtual void flush() = 0;
}; };
class AsyncIoProvider; class AsyncIoProvider;
Own<Device> createDevice(AsyncIoProvider& provider); Own<Device> createDevice(AsyncIoProvider &provider);
} // namespace gin } // namespace gin

View File

@ -8,55 +8,55 @@
namespace gin { namespace gin {
class GlSettings { class GlSettings {
public: public:
uint8_t gl_major = 3; uint8_t gl_major = 3;
uint8_t gl_minor = 3; uint8_t gl_minor = 3;
enum class RenderType : int32_t { RGBA }; enum class RenderType : int32_t { RGBA };
RenderType render_type = RenderType::RGBA; RenderType render_type = RenderType::RGBA;
bool renderable = true; bool renderable = true;
// gl drawable // gl drawable
bool window_type = true; bool window_type = true;
// Pix and PBuffer are currently ignored. // Pix and PBuffer are currently ignored.
/// @hint don't change this unless you want to change the static cast in /// @hint don't change this unless you want to change the static cast in
/// glcontext-xcb.cpp and other occurences /// glcontext-xcb.cpp and other occurences
/// Alternatively implement bitwise operations & and | /// Alternatively implement bitwise operations & and |
enum class DrawableType : int32_t { enum class DrawableType : int32_t {
WindowBit = 0x01, WindowBit = 0x01,
PixMapBit = 0x02, PixMapBit = 0x02,
PBufferBit = 0x04 PBufferBit = 0x04
}; };
DrawableType drawable_type = DrawableType::WindowBit; DrawableType drawable_type = DrawableType::WindowBit;
bool double_buffer = true; bool double_buffer = true;
int red_bits = 8; int red_bits = 8;
int green_bits = 8; int green_bits = 8;
int blue_bits = 8; int blue_bits = 8;
int alpha_bits = 8; int alpha_bits = 8;
int depth_bits = 24; int depth_bits = 24;
int stencil_bits = 8; int stencil_bits = 8;
bool core_profile = true; bool core_profile = true;
}; };
class GlContext { class GlContext {
public: public:
virtual ~GlContext() = default; virtual ~GlContext() = default;
virtual void bind() = 0; virtual void bind() = 0;
virtual Own<GlWindow> createWindow(const VideoMode&, std::string_view) = 0; virtual Own<GlWindow> createWindow(const VideoMode &, std::string_view) = 0;
virtual void flush() = 0; virtual void flush() = 0;
}; };
class AsyncIoProvider; class AsyncIoProvider;
Own<GlContext> createGlContext(AsyncIoProvider&, const GlSettings&); Own<GlContext> createGlContext(AsyncIoProvider &, const GlSettings &);
} // namespace gin } // namespace gin

View File

@ -1,14 +1,14 @@
#pragma once #pragma once
#include "video_mode.h" #include "../video_mode.h"
namespace gin { namespace gin {
class GlWindow { class GlWindow {
public: public:
virtual ~GlWindow() = default; virtual ~GlWindow() = default;
virtual void bind() = 0; virtual void bind() = 0;
virtual void show() = 0; virtual void show() = 0;
virtual void swap() = 0; virtual void swap() = 0;
}; };
} // namespace gin } // namespace gin

View File

@ -4,8 +4,8 @@
namespace gin { namespace gin {
class VideoMode { class VideoMode {
public: public:
size_t height = 128; size_t height = 128;
size_t width = 128; size_t width = 128;
}; };
} // namespace gin } // namespace gin

View File

@ -8,13 +8,13 @@
namespace gin { namespace gin {
class Window { class Window {
public: public:
virtual ~Window() = default; virtual ~Window() = default;
virtual void show() = 0; virtual void show() = 0;
virtual void hide() = 0; virtual void hide() = 0;
virtual const VideoMode& videoMode() const = 0; virtual const VideoMode &videoMode() const = 0;
virtual const std::string_view title() const = 0; virtual const std::string_view title() const = 0;
}; };
} // namespace gin } // namespace gin