diff --git a/CMakeLists.txt b/CMakeLists.txt index eb5d2edfe3..37c2ba2197 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ set(DISTRIBUTOR "None" CACHE STRING "Name of the distributor.") if(UNIX AND NOT APPLE AND NOT ANDROID) option(ENABLE_X11 "Enables X11 Support" ON) endif() -if(NOT WIN32 AND NOT APPLE) +if(NOT WIN32 AND NOT APPLE AND NOT HAIKU) option(ENABLE_EGL "Enables EGL OpenGL Interface" ON) endif() diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt index 543c4cf9bb..7656fd1f58 100644 --- a/Source/Core/Common/CMakeLists.txt +++ b/Source/Core/Common/CMakeLists.txt @@ -168,6 +168,8 @@ elseif (ANDROID) PRIVATE androidcommon ) +elseif(HAIKU) + target_link_libraries(common PRIVATE be GL) endif() if(ANDROID) @@ -256,6 +258,11 @@ elseif(APPLE) GL/GLInterface/AGL.h GL/GLInterface/AGL.mm ) +elseif(HAIKU) + target_sources(common PRIVATE + GL/GLInterface/BGL.h + GL/GLInterface/BGL.cpp + ) elseif(ENABLE_X11 AND X11_FOUND) target_sources(common PRIVATE GL/GLX11Window.cpp diff --git a/Source/Core/Common/GL/GLContext.cpp b/Source/Core/Common/GL/GLContext.cpp index 2f72204af8..945008538f 100644 --- a/Source/Core/Common/GL/GLContext.cpp +++ b/Source/Core/Common/GL/GLContext.cpp @@ -12,6 +12,9 @@ #if defined(_WIN32) #include "Common/GL/GLInterface/WGL.h" #endif +#if defined(__HAIKU__) +#include "Common/GL/GLInterface/BGL.h" +#endif #if HAVE_X11 #include "Common/GL/GLInterface/GLX.h" #endif @@ -92,6 +95,10 @@ std::unique_ptr GLContext::Create(const WindowSystemInfo& wsi, bool s if (wsi.type == WindowSystemType::Android) context = std::make_unique(); #endif +#if defined(__HAIKU__) + if (wsi.type == WindowSystemType::Haiku) + context = std::make_unique(); +#endif #if HAVE_X11 if (wsi.type == WindowSystemType::X11) { diff --git a/Source/Core/Common/GL/GLInterface/BGL.cpp b/Source/Core/Common/GL/GLInterface/BGL.cpp new file mode 100644 index 0000000000..84ab6dda6f --- /dev/null +++ b/Source/Core/Common/GL/GLInterface/BGL.cpp @@ -0,0 +1,96 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "Common/GL/GLInterface/BGL.h" + +#include +#include +#include + +#include "Common/Assert.h" + +BGLView* GLContextBGL::s_current = nullptr; + +GLContextBGL::~GLContextBGL() +{ + if (!m_window) + delete m_gl; +} + +bool GLContextBGL::Initialize(const WindowSystemInfo& wsi, bool stereo, bool core) +{ + m_window = static_cast(wsi.render_window); + + m_gl = new BGLView(m_window ? m_window->Bounds() : BRect(), "GLContextBGL", B_FOLLOW_ALL_SIDES, 0, + BGL_RGB | BGL_DOUBLE | BGL_ALPHA); + if (m_window) + m_window->AddChild(m_gl); + + m_opengl_mode = Mode::OpenGL; + + m_gl->LockLooper(); + BRect size = m_gl->Frame(); + m_gl->UnlockLooper(); + + m_backbuffer_width = size.IntegerWidth(); + m_backbuffer_height = size.IntegerHeight(); + + MakeCurrent(); + + return true; +} + +bool GLContextBGL::IsHeadless() const +{ + return m_window == nullptr; +} + +bool GLContextBGL::MakeCurrent() +{ + if (s_current) + s_current->UnlockGL(); + m_gl->LockGL(); + s_current = m_gl; + return true; +} + +bool GLContextBGL::ClearCurrent() +{ + if (!s_current) + return true; + + ASSERT(m_gl == s_current); + s_current->UnlockGL(); + s_current = nullptr; + return true; +} + +void GLContextBGL::Swap() +{ + m_gl->SwapBuffers(); +} + +void GLContextBGL::Update() +{ + m_gl->LockLooper(); + BRect size = m_gl->Frame(); + if (m_backbuffer_width == size.IntegerWidth() && m_backbuffer_height == size.IntegerHeight()) + { + m_gl->UnlockLooper(); + return; + } + + ClearCurrent(); + m_gl->FrameResized(size.Width(), size.Height()); + MakeCurrent(); + m_gl->UnlockLooper(); + + m_backbuffer_width = size.IntegerWidth(); + m_backbuffer_height = size.IntegerHeight(); +} + +void* GLContextBGL::GetFuncAddress(const std::string& name) +{ + return m_gl->GetGLProcAddress(name.c_str()); +} diff --git a/Source/Core/Common/GL/GLInterface/BGL.h b/Source/Core/Common/GL/GLInterface/BGL.h new file mode 100644 index 0000000000..e4e32c1a30 --- /dev/null +++ b/Source/Core/Common/GL/GLInterface/BGL.h @@ -0,0 +1,36 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include "Common/GL/GLContext.h" + +class BWindow; +class BGLView; + +class GLContextBGL final : public GLContext +{ +public: + ~GLContextBGL() override; + + bool IsHeadless() const override; + + bool MakeCurrent() override; + bool ClearCurrent() override; + + void Update() override; + + void Swap() override; + + void* GetFuncAddress(const std::string& name) override; + +protected: + bool Initialize(const WindowSystemInfo& wsi, bool stereo, bool core) override; + +private: + static BGLView* s_current; + + BWindow* m_window; + BGLView* m_gl; +}; diff --git a/Source/Core/Common/WindowSystemInfo.h b/Source/Core/Common/WindowSystemInfo.h index 244a985cdf..ff2bebabed 100644 --- a/Source/Core/Common/WindowSystemInfo.h +++ b/Source/Core/Common/WindowSystemInfo.h @@ -13,6 +13,7 @@ enum class WindowSystemType X11, Wayland, FBDev, + Haiku, }; struct WindowSystemInfo diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceEthernet.h b/Source/Core/Core/HW/EXI/EXI_DeviceEthernet.h index 38970ff0fc..28149128e5 100644 --- a/Source/Core/Core/HW/EXI/EXI_DeviceEthernet.h +++ b/Source/Core/Core/HW/EXI/EXI_DeviceEthernet.h @@ -402,7 +402,7 @@ private: bool m_bba_link_up = false; bool m_bba_failure_notified = false; #if defined(WIN32) || defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \ - defined(__OpenBSD__) || defined(__NetBSD__) + defined(__OpenBSD__) || defined(__NetBSD__) || defined(__HAIKU__) sf::UdpSocket m_sf_socket; sf::IpAddress m_sf_recipient_ip; char m_in_frame[9004]; diff --git a/Source/Core/DolphinQt/MainWindow.cpp b/Source/Core/DolphinQt/MainWindow.cpp index b54687828d..8bd3988f45 100644 --- a/Source/Core/DolphinQt/MainWindow.cpp +++ b/Source/Core/DolphinQt/MainWindow.cpp @@ -154,6 +154,8 @@ static WindowSystemType GetWindowSystemType() return WindowSystemType::X11; else if (platform_name == QStringLiteral("wayland")) return WindowSystemType::Wayland; + else if (platform_name == QStringLiteral("haiku")) + return WindowSystemType::Haiku; ModalMessageBox::critical( nullptr, QStringLiteral("Error"), @@ -167,7 +169,7 @@ static WindowSystemInfo GetWindowSystemInfo(QWindow* window) wsi.type = GetWindowSystemType(); // Our Win32 Qt external doesn't have the private API. -#if defined(WIN32) || defined(__APPLE__) +#if defined(WIN32) || defined(__APPLE__) || defined(__HAIKU__) wsi.render_window = window ? reinterpret_cast(window->winId()) : nullptr; wsi.render_surface = wsi.render_window; #else diff --git a/Source/Core/VideoCommon/DriverDetails.cpp b/Source/Core/VideoCommon/DriverDetails.cpp index 9f5b06ccdd..64ca6dff7f 100644 --- a/Source/Core/VideoCommon/DriverDetails.cpp +++ b/Source/Core/VideoCommon/DriverDetails.cpp @@ -37,6 +37,8 @@ constexpr u32 m_os = OS_ALL | OS_FREEBSD; constexpr u32 m_os = OS_ALL | OS_OPENBSD; #elif __NetBSD__ constexpr u32 m_os = OS_ALL | OS_NETBSD; +#elif __HAIKU__ +constexpr u32 m_os = OS_ALL | OS_HAIKU; #endif static API m_api = API_OPENGL; diff --git a/Source/Core/VideoCommon/DriverDetails.h b/Source/Core/VideoCommon/DriverDetails.h index 2e25b2a79b..8ea6d40c9c 100644 --- a/Source/Core/VideoCommon/DriverDetails.h +++ b/Source/Core/VideoCommon/DriverDetails.h @@ -28,6 +28,7 @@ enum OS OS_FREEBSD = (1 << 5), OS_OPENBSD = (1 << 6), OS_NETBSD = (1 << 7), + OS_HAIKU = (1 << 8), }; // Enum of known vendors // Tegra and Nvidia are separated out due to such substantial differences