- Setup EGL context for Wayland. Test window now opens as black rectangle.

This commit is contained in:
2025-12-15 13:20:08 -05:00
parent 5dcb58f53c
commit 1acf00138a
36 changed files with 992 additions and 80 deletions

View File

@@ -0,0 +1,48 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \file version.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_CORE_VERSION_H
#define FENNEC_CORE_VERSION_H
#include <fennec/lang/types.h>
#include <fennec/string/string.h>
namespace fennec
{
struct version {
uint32_t major, minor, patch;
string str;
};
}
#endif // FENNEC_CORE_VERSION_H

View File

@@ -133,6 +133,13 @@ namespace fennec::detail
template<typename T>
auto _is_mappable(...) -> false_type;
template<typename B> auto _ptr_conv(const volatile B*) -> true_type;
template<typename> auto _ptr_conv(const volatile void*) -> false_type;
template<typename B, typename D> auto _is_base_of(int) -> decltype(detail::_ptr_conv<B>(static_cast<D*>(nullptr)));
template<typename, typename> auto _is_base_of(...) -> false_type;
}
#endif // FENNEC_LANG_DETAIL_TYPE_TRAITS_H

View File

@@ -790,6 +790,25 @@ template<typename T> struct is_same<T, T> : true_type {};
/// \tparam T1 second type to check
template<typename T0, typename T1> constexpr bool_t is_same_v = is_same<T0, T1> {};
// fennec::is_base_of =====================================================================================================
///
/// \brief Check if `Derived` has a base type of `Base`
///
/// \details Checks if `Base` is a base type of `Derived` and stores it in `is_base_of::value`
/// \tparam Base base type to check
/// \tparam Derived derived type to check
template<typename Base, typename Derived> struct is_base_of : bool_constant<
is_class_v<Base> and is_class_v<Derived> and decltype(detail::_is_base_of<Base, Derived>(0))::value
> {};
///
/// \brief Shorthand for ```is_base_of<T0, T1>::value```
/// \tparam Base base type to check
/// \tparam Derived derived type to check
template<typename Base, typename Derived> constexpr bool_t is_base_of_v = is_base_of<Base, Derived> {};
// fennec::is_complete ==============================================================================================
///

View File

@@ -128,7 +128,7 @@ public:
///
/// \brief Default Constructor, if it owns a resource, it deletes it using `delete_t`
constexpr ~unique_ptr() {
if(_handle) _delete(_handle);
reset();
}
constexpr unique_ptr& operator=(const unique_ptr&) = delete;
@@ -140,6 +140,20 @@ public:
return *this;
}
void reset(pointer_t ptr) {
if(_handle) {
_delete(_handle);
_handle = ptr;
}
}
void reset(nullptr_t = nullptr) {
if(_handle) {
_delete(_handle);
_handle = nullptr;
}
}
pointer_t release() {
pointer_t retval = _handle;
_handle = nullptr;

View File

@@ -40,6 +40,16 @@
namespace fennec
{
class display_server;
///
/// \brief Interface resembling the API for a display server of an operating system, e.g. Linux X11/Wayland
///
/// \details An implementation for a display server should inherit `display_server_base` and note the following:
///
/// For a server type `DisplayT`; any `gfxcontext` implementation that wishes to implement `DisplayT`
/// must provide a constructor that accepts a `DisplayT*`. `DisplayT::ctx_registry::register_type` must then be
/// called for the `gfxcontext` implementation.
class display_server : public type_registry<display_server, platform*> {
// Typedefs/Constants/Enums ============================================================================================
public:
@@ -99,6 +109,9 @@ enum feature_ : uint32_t {
return features.test(feature);
}
gfxcontext* get_gfx_context() {
return gfx_context;
}
virtual window* create_window(const window::config& conf) = 0;
@@ -110,16 +123,31 @@ enum feature_ : uint32_t {
virtual void disconnect() = 0;
virtual bool connected() const = 0;
virtual void dispatch() = 0;
virtual void* get_native_handle() = 0;
protected:
featureset_t features;
object_pool<window*> windows;
gfxcontext* gfx_context;
FENNEC_RTTI_CLASS_ENABLE() {
}
};
template<typename DisplayT, typename WindowT>
class display_server_base : public display_server, public type_registry<gfxcontext, DisplayT*> {
public:
display_server_base(fennec::platform* p)
: display_server(p) {
}
using ctx_registry = type_registry<gfxcontext, DisplayT*>;
using window_t = WindowT;
};
}
#endif // FENNEC_PLATFORM_INTERFACE_DISPLAY_SERVER_H

View File

@@ -25,7 +25,9 @@ namespace fennec
class platform;
class display_server; // The display server used by the OS, e.g. WDM, Wayland, X11, etc.
class gfxcontext; // Handles the GFX API context of a display server, e.g. OpenGL, Vulkan, etc.
class window; // Handles window surfaces of the display protocol
class gfxsurface; // Handles the GFX surface of a window for a specific gfxcontext
}

View File

@@ -105,6 +105,10 @@ public:
window* get_parent() const;
const ivec2& get_size() const { return cfg.size; }
int get_width() const { return cfg.size.x; }
int get_height() const { return cfg.size.y; }
bool get_flag(uint8_t flag) const { return cfg.flags.test(flag); }
bool is_always_on_top() const { return get_flag(flag_always_on_top); }
@@ -120,6 +124,7 @@ public:
bool is_running() const { return get_flag(flag_running); }
bool is_no_focus() const { return get_flag(flag_no_focus); }
virtual bool set_flag(uint8_t flag, bool val) = 0;
bool set_always_on_top(bool val) { return set_flag(flag_always_on_top, val); }
@@ -135,13 +140,27 @@ public:
virtual void show() = 0;
virtual void hide() = 0;
virtual void dispatch() = 0;
virtual void begin_frame();
virtual void end_frame();
virtual void* get_native_handle() = 0;
protected:
display_server* const server;
const size_t id;
config cfg;
window* root;
gfxsurface* gfx_surface;
};
template<typename DisplayT>
class window_base : public window {
public:
window_base(display_server* display, size_t id, const config& conf)
: window(display, id, conf) {
}
using display_t = DisplayT;
};
}

View File

@@ -0,0 +1,55 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \file context.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_EGL_CONTEXT_H
#define FENNEC_PLATFORM_LINUX_WAYLAND_EGL_CONTEXT_H
#include <fennec/platform/opengl/egl/context.h>
namespace fennec
{
class wayland_eglcontext : public eglcontext {
public:
explicit wayland_eglcontext(display_server* display);
~wayland_eglcontext();
gfxsurface* create_surface(window* window) override;
private:
FENNEC_RTTI_CLASS_ENABLE(eglcontext) {
wayland_server::ctx_registry::register_type<wayland_eglcontext>();
}
};
}
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_EGL_CONTEXT_H

View File

@@ -0,0 +1,53 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \file surface.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef LATFORM_LINUX_WAYLAND_EGL_SURFACE_H
#define LATFORM_LINUX_WAYLAND_EGL_SURFACE_H
#include <fennec/platform/opengl/egl/surface.h>
#include <fennec/platform/linux/wayland/fwd.h>
namespace fennec
{
class wayland_eglsurface : public eglsurface {
public:
wayland_eglsurface(wayland_window* win, eglcontext* ctx);
~wayland_eglsurface();
void resize(const ivec2& size) override;
private:
};
}
#endif // LATFORM_LINUX_WAYLAND_EGL_SURFACE_H

View File

@@ -0,0 +1,43 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \file fwd.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_FWD_H
#define FENNEC_PLATFORM_LINUX_WAYLAND_FWD_H
namespace fennec
{
class wayland_server;
class wayland_window;
}
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_FWD_H

View File

@@ -31,6 +31,7 @@
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_SERVER_H
#define FENNEC_PLATFORM_LINUX_WAYLAND_SERVER_H
#include <fennec/platform/linux/wayland/fwd.h>
#include <fennec/platform/interface/display_server.h>
// forward defs to avoid flooding global namespace
@@ -46,7 +47,9 @@ struct xdg_wm_base;
namespace fennec
{
class wayland_server : public display_server {
///
/// \brief Class for handling the Wayland Display Server
class wayland_server : public display_server_base<wayland_server, wayland_window> {
public:
explicit wayland_server(fennec::platform* p);
~wayland_server() override;
@@ -55,8 +58,12 @@ public:
void disconnect() override;
bool connected() const override;
void dispatch() override;
window* create_window(const window::config& conf) override;
void* get_native_handle() override { return display; }
private:
wl_display* display;
wl_registry* registry;

View File

@@ -31,6 +31,7 @@
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_WINDOW_H
#define FENNEC_PLATFORM_LINUX_WAYLAND_WINDOW_H
#include <fennec/platform/linux/wayland/fwd.h>
#include <fennec/platform/interface/window.h>
struct wl_array;
@@ -44,7 +45,7 @@ struct xdg_toplevel;
namespace fennec
{
class wayland_window : public window {
class wayland_window : public window_base<wayland_server> {
public:
wayland_window(display_server* server, uint32_t id, const config& cfg);
~wayland_window();
@@ -52,7 +53,7 @@ public:
void show() override;
void hide() override;
void dispatch() override;
void* get_native_handle() override;
bool set_flag(uint8_t flag, bool val) override;

View File

@@ -0,0 +1,65 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \file context.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_OPENGL_EGLCONTEXT_H
#define FENNEC_PLATFORM_LINUX_WAYLAND_OPENGL_EGLCONTEXT_H
#include <EGL/egl.h>
#include <fennec/platform/linux/wayland/server.h>
#include <fennec/renderers/opengl/glcontext.h>
namespace fennec
{
class eglcontext : public glcontext {
public:
eglcontext(display_server* display);
~eglcontext();
bool is_valid() override;
private:
EGLDisplay _egldisplay;
EGLContext _eglcontext;
EGLConfig _eglconfig;
EGLint _eglvmajor, _eglvminor, _eglctype;
cstring _extensions;
FENNEC_RTTI_CLASS_ENABLE(glcontext) {
}
friend class eglsurface;
};
}
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_OPENGL_EGLCONTEXT_H

View File

@@ -0,0 +1,43 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \file fwd.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_PLATFORM_OPENGL_EGL_FWD_H
#define FENNEC_PLATFORM_OPENGL_EGL_FWD_H
namespace fennec
{
class eglcontext;
class eglsurface;
}
#endif // FENNEC_PLATFORM_OPENGL_EGL_FWD_H

View File

@@ -0,0 +1,58 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \file surface.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_PLATFORM_OPENGL_EGL_SURFACE_H
#define FENNEC_PLATFORM_OPENGL_EGL_SURFACE_H
#include <EGL/egl.h>
#include <fennec/platform/opengl/egl/fwd.h>
#include <fennec/renderers/interface/gfxsurface.h>
namespace fennec
{
class eglsurface : public gfxsurface {
public:
eglsurface(fennec::window* win, eglcontext* ctx, EGLNativeWindowType eglwindow);
~eglsurface();
void make_current() override;
void swap() override;
protected:
EGLNativeWindowType _eglwindow;
EGLSurface _eglsurface;
};
} // fennec
#endif // FENNEC_PLATFORM_OPENGL_EGL_SURFACE_H

View File

@@ -31,7 +31,9 @@
#ifndef FENNEC_RENDERERS_INTERFACE_GFXCONTEXT_H
#define FENNEC_RENDERERS_INTERFACE_GFXCONTEXT_H
#include <fennec/core/version.h>
#include <fennec/lang/types.h>
#include <fennec/platform/interface/display_server.h>
#include <fennec/string/string.h>
#include <fennec/renderers/interface/forward.h>
#include <fennec/renderers/interface/gfxresourcepool.h>
@@ -55,22 +57,31 @@ public:
using handle_t = uint32_t;
struct version_t {
uint8_t major, minor, patch;
string str;
};
const version_t version;
gfxresourcepool resources;
gfxcontext(display_server* display)
: display(display)
, version(0, 0, 0, string("")) {
}
virtual ~gfxcontext() = default;
gfxcontext& operator=(const gfxcontext&) = delete;
gfxcontext& operator=(gfxcontext&&) = delete;
virtual gfxpass* create_pass() = 0;
virtual bool is_valid() = 0;
virtual gfxsurface* create_surface(window* window) = 0;
virtual gfxpass* create_pass() = 0;
virtual const version& get_version() const { return version; };
protected:
display_server* display;
version version;
private:
FENNEC_RTTI_CLASS_ENABLE() {
}
};
}

View File

@@ -0,0 +1,60 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \file gfxcontext.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_RENDERERS_INTERFACE_GFXSURFACE_H
#define FENNEC_RENDERERS_INTERFACE_GFXSURFACE_H
#include <fennec/platform/interface/window.h>
namespace fennec
{
class gfxsurface {
public:
virtual ~gfxsurface() = default;
gfxsurface(window* win, gfxcontext* ctx)
: window(win), context(ctx) {
}
virtual void make_current() = 0;
virtual void swap() = 0;
virtual void resize(const ivec2& size) = 0;
protected:
window* window;
gfxcontext* context;
};
}
#endif // FENNEC_RENDERERS_INTERFACE_GFXSURFACE_H

View File

@@ -0,0 +1,54 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \file glcontext.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_RENDERERS_OPENGL_GLCONTEXT_H
#define FENNEC_RENDERERS_OPENGL_GLCONTEXT_H
#include <fennec/renderers/interface/gfxcontext.h>
namespace fennec
{
class glcontext : public gfxcontext {
public:
explicit glcontext(display_server* display)
: gfxcontext(display) {
}
gfxpass* create_pass() override;
private:
FENNEC_RTTI_CLASS_ENABLE(gfxcontext) {
}
};
}
#endif // FENNEC_RENDERERS_OPENGL_GLCONTEXT_H

View File

@@ -30,7 +30,11 @@
#ifndef FENNEC_RTTI_TYPE_REGISTRY_H
#define FENNEC_RTTI_TYPE_REGISTRY_H
#include <fennec/containers/priority_queue.h>
#include <fennec/lang/type_traits.h>
#include <fennec/rtti/type.h>
namespace fennec
@@ -89,12 +93,12 @@ public:
using entrylist_t = priority_queue<entry, compare>;
template<typename T>
template<typename DerivedT> requires(is_base_of_v<BaseT, DerivedT>)
static void register_type(size_t priority = 0) {
_global_list().emplace(
priority,
type::get<T>(),
_constructor_helper<T>
type::get<DerivedT>(),
_constructor_helper<DerivedT>
);
}

View File

@@ -84,6 +84,9 @@ public:
/// \brief Buffer Constructor, wraps the provided C-Style string, appending a null-terminator if not present
/// \param str the buffer to wrap
/// \tparam n the number of characters in the buffer including the null-terminator, if present
///
/// \details This constructor is explicit because we want to be explicit about when we are allocating memory for
/// a string.
template<size_t n>
explicit constexpr _string(const char (&str)[n])
: _str(str[n - 1] != '\0' ? n + 1 : n) {