port to pika os 4
Some checks failed
PikaOS Package Build Only (Canary) (amd64-v3) / build (push) Failing after 1m8s
PikaOS Package Build Only (amd64-v3) / build (push) Failing after 1s
PikaOS Package Build & Release (Canary) (amd64-v3) / build (push) Failing after 1m7s
PikaOS Package Build & Release (amd64-v3) / build (push) Failing after 1s

This commit is contained in:
Ward from fusion-voyager-3 2024-07-28 20:28:08 +03:00
parent 44f9485335
commit 4d380903fe
28 changed files with 2970 additions and 75 deletions

1
.github/build-canary-v3 vendored Normal file
View File

@ -0,0 +1 @@
1

1
.github/build-nest-v3 vendored Normal file
View File

@ -0,0 +1 @@
1

1
.github/release-canary-v3 vendored Normal file
View File

@ -0,0 +1 @@
1

1
.github/release-nest-v3 vendored Normal file
View File

@ -0,0 +1 @@
1

37
.github/workflows/build-canaryv3.yml vendored Normal file
View File

@ -0,0 +1,37 @@
name: PikaOS Package Build Only (Canary) (amd64-v3)
on:
push:
branches:
- main
paths:
- '.github/build-canary-v3'
jobs:
build:
runs-on: ubuntu-latest
container:
image: ghcr.io/pikaos-linux/pikaos-builder:canaryv3
volumes:
- /proc:/proc
options: --privileged -it
steps:
- uses: actions/checkout@v3
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.SSH_KEY }}
name: id_rsa
known_hosts: ${{ secrets.KNOWN_HOSTS }}
if_key_exists: replace
- name: Update APT Cache
run: apt-get update -y
- name: Set Build Config
run: cp -vf ./pika-build-config/amd64-v3.sh ./pika-build-config.sh
- name: Build Package
run: ./main.sh

37
.github/workflows/build-nestv3.yml vendored Normal file
View File

@ -0,0 +1,37 @@
name: PikaOS Package Build Only (amd64-v3)
on:
push:
branches:
- main
paths:
- '.github/build-nest-v3'
jobs:
build:
runs-on: ubuntu-latest
container:
image: ghcr.io/pikaos-linux/pikaos-builder:nestv3
volumes:
- /proc:/proc
options: --privileged -it
steps:
- uses: actions/checkout@v3
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.SSH_KEY }}
name: id_rsa
known_hosts: ${{ secrets.KNOWN_HOSTS }}
if_key_exists: replace
- name: Update APT Cache
run: apt-get update -y
- name: Set Build Config
run: cp -vf ./pika-build-config/amd64-v3.sh ./pika-build-config.sh
- name: Build Package
run: ./main.sh

40
.github/workflows/release-canaryv3.yml vendored Normal file
View File

@ -0,0 +1,40 @@
name: PikaOS Package Build & Release (Canary) (amd64-v3)
on:
push:
branches:
- main
paths:
- '.github/release-canary-v3'
jobs:
build:
runs-on: ubuntu-latest
container:
image: ghcr.io/pikaos-linux/pikaos-builder:canaryv3
volumes:
- /proc:/proc
options: --privileged -it
steps:
- uses: actions/checkout@v3
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.SSH_KEY }}
name: id_rsa
known_hosts: ${{ secrets.KNOWN_HOSTS }}
if_key_exists: replace
- name: Update APT Cache
run: apt-get update -y
- name: Set Build Config
run: cp -vf ./pika-build-config/amd64-v3.sh ./pika-build-config.sh
- name: Build Package
run: ./main.sh
- name: Release Package
run: ./release.sh

40
.github/workflows/release-nestv3.yml vendored Normal file
View File

@ -0,0 +1,40 @@
name: PikaOS Package Build & Release (amd64-v3)
on:
push:
branches:
- main
paths:
- '.github/release-nest-v3'
jobs:
build:
runs-on: ubuntu-latest
container:
image: ghcr.io/pikaos-linux/pikaos-builder:nestv3
volumes:
- /proc:/proc
options: --privileged -it
steps:
- uses: actions/checkout@v3
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.SSH_KEY }}
name: id_rsa
known_hosts: ${{ secrets.KNOWN_HOSTS }}
if_key_exists: replace
- name: Update APT Cache
run: apt-get update -y
- name: Set Build Config
run: cp -vf ./pika-build-config/amd64-v3.sh ./pika-build-config.sh
- name: Build Package
run: ./main.sh
- name: Release Package
run: ./release.sh

View File

@ -1,49 +0,0 @@
name: PikaOS Package Release
on:
workflow_dispatch
jobs:
build:
runs-on: self-hosted
container:
image: ghcr.io/pikaos-linux/pika-package-container:latest
volumes:
- /proc:/proc
options: --privileged -it
steps:
- uses: actions/checkout@v3
- name: Import GPG key
id: import_gpg
uses: crazy-max/ghaction-import-gpg@v5
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.PASSPHRASE }}
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.SSH_KEY }}
name: id_rsa
known_hosts: ${{ secrets.KNOWN_HOSTS }}
if_key_exists: replace
- name: Update apt cache
run: apt update -y
- name: Build Package
run: ./main.sh
- name: Release Package
run: ./release.sh
- name: Purge cache
uses: strrife/cloudflare-chunked-purge-action@master
env:
# Zone is required by both authentication methods
CLOUDFLARE_ZONE: ${{ secrets.CLOUDFLARE_ZONE }}
CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN }}
PURGE_URLS: ${{ vars.PURGE_URLS }}

24
LICENSE.md Normal file
View File

@ -0,0 +1,24 @@
MIT License (With DPKG packaging compatibility)
Copyright (c) 2024 PikaOS
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.
Notes:
The files covered by this license are any files and directories in the root of this repository (including but not limited to: `main.sh`, `release.sh`, and `.github`), with the exception of the `debian` directory and its contents if `debian/copyright` exists, and declares any files or directories as a different LICENSE/COPYRIGHT.

1
debian/files vendored
View File

@ -1 +0,0 @@
gamescope_3.11.58.d6c1df4.openvr-99pika15_source.buildinfo games optional

4
debian/gbp.conf vendored
View File

@ -1,4 +0,0 @@
[DEFAULT]
upstream-branch = upstream/latest
debian-branch = debian/latest
pristine-tar = True

3
debian/salsa-ci.yml vendored
View File

@ -1,3 +0,0 @@
---
include:
- https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/recipes/debian.yml

View File

@ -1,4 +0,0 @@
Bug-Database: https://github.com/Plagman/gamescope/issues
Bug-Submit: https://github.com/Plagman/gamescope/issues/new
Repository-Browse: https://github.com/Plagman/gamescope
Repository: https://github.com/Plagman/gamescope.git

2
debian/watch vendored
View File

@ -1,2 +0,0 @@
version=4
https://github.com/Plagman/gamescope/tags (?:.*?/)?v?@ANY_VERSION@@ARCHIVE_EXT@

21
main.sh
View File

@ -1,14 +1,25 @@
#! /bin/bash
set -e
VERSION="3.14.24"
source ./pika-build-config.sh
echo "$PIKA_BUILD_ARCH" > pika-build-arch
# Clone Upstream # Clone Upstream
git clone https://github.com/Plagman/gamescope -b 3.12.5 git clone --recurse-submodules https://github.com/Plagman/gamescope
cp -rvf ./debian ./gamescope cp -rvf ./debian ./gamescope/
cd ./gamescope cd ./gamescope
git submodule update --init git reset --hard 7ae5e0d2a75de06e267c47ca3cd3cddedd1d7416
for i in $(cat ../patches/series) ; do echo "Applying Patch: $i" && patch -Np1 -i ../patches/$i || echo "Applying Patch $i Failed!"; done
# Get build deps # Get build deps
apt-get update -y
apt-get build-dep ./ -y apt-get build-dep ./ -y
# Build package # Build package
LOGNAME=root dh_make --createorig -y -l -p gamescope_3.12.5 LOGNAME=root dh_make --createorig -y -l -p gamescope_"$VERSION" || echo "dh-make: Ignoring Last Error"
dpkg-buildpackage --no-sign dpkg-buildpackage --no-sign
# Move the debs to output # Move the debs to output

239
patches/1231.patch Normal file
View File

@ -0,0 +1,239 @@
From ab115896be1a448bde0eb7673c26300ea4ca5040 Mon Sep 17 00:00:00 2001
From: sharkautarch <128002472+sharkautarch@users.noreply.github.com>
Date: Sun, 19 May 2024 20:15:36 -0400
Subject: [PATCH 1/2] QueuePresent: canBypassXWayland(): fetch multiple xcb
cookies initially before waiting on any of them
---
layer/VkLayer_FROG_gamescope_wsi.cpp | 1 +
layer/xcb_helpers.hpp | 105 +++++++++++++++++++++++----
2 files changed, 93 insertions(+), 13 deletions(-)
diff --git a/layer/VkLayer_FROG_gamescope_wsi.cpp b/layer/VkLayer_FROG_gamescope_wsi.cpp
index 5844c2a63..ca44849f2 100644
--- a/layer/VkLayer_FROG_gamescope_wsi.cpp
+++ b/layer/VkLayer_FROG_gamescope_wsi.cpp
@@ -975,6 +975,7 @@ namespace GamescopeWSILayer {
continue;
}
+ xcb::Prefetcher prefetcher(gamescopeSurface->connection, gamescopeSurface->window);
const bool canBypass = gamescopeSurface->canBypassXWayland();
if (canBypass != gamescopeSwapchain->isBypassingXWayland)
UpdateSwapchainResult(canBypass ? VK_SUBOPTIMAL_KHR : VK_ERROR_OUT_OF_DATE_KHR);
diff --git a/layer/xcb_helpers.hpp b/layer/xcb_helpers.hpp
index 8fac5635b..72d0ec092 100644
--- a/layer/xcb_helpers.hpp
+++ b/layer/xcb_helpers.hpp
@@ -4,22 +4,106 @@
#include <xcb/composite.h>
#include <cstdio>
#include <optional>
+#include <pthread.h>
namespace xcb {
+ inline static constinit pthread_t g_cache_tid; //incase g_cache could otherwise be accessed by one thread, while it is being deleted by another thread
+ inline static constinit struct cookie_cache_t {
+ xcb_window_t window;
+ std::tuple<xcb_get_geometry_cookie_t, xcb_query_tree_cookie_t> cached_cookies;
+ std::tuple<xcb_get_geometry_reply_t*, xcb_query_tree_reply_t*> cached_replies;
+ } g_cache = {};
+
+ //Note: this class is currently only meant to be used within GamescopeWSILayer::VkDeviceOverrides::QueuePresentKHR:
+ struct Prefetcher {
+ explicit Prefetcher(xcb_connection_t* connection, const xcb_window_t window) {
+ g_cache = {
+ .window = window,
+ .cached_cookies = {
+ xcb_get_geometry(connection, window),
+ xcb_query_tree(connection, window)
+ }
+ };
+ g_cache_tid = pthread_self();
+ }
+ ~Prefetcher() {
+ g_cache_tid = {};
+ free(std::get<0>(g_cache.cached_replies));
+ free(std::get<1>(g_cache.cached_replies));
+ g_cache.cached_replies = {nullptr,nullptr};
+ }
+ };
+
struct ReplyDeleter {
+ const bool m_bOwning = true;
+ consteval ReplyDeleter(bool bOwning = true) : m_bOwning{bOwning} {}
template <typename T>
void operator()(T* ptr) const {
- free(const_cast<std::remove_const_t<T>*>(ptr));
+ if (m_bOwning)
+ free(const_cast<std::remove_const_t<T>*>(ptr));
}
};
template <typename T>
using Reply = std::unique_ptr<T, ReplyDeleter>;
+
+ template <typename Cookie_RetType, typename Reply_RetType, typename XcbConn=xcb_connection_t*, typename... Args>
+ class XcbFetch {
+ using cookie_f_ptr_t = Cookie_RetType (*)(XcbConn, Args...);
+ using reply_f_ptr_t = Reply_RetType* (*)(XcbConn, Cookie_RetType, xcb_generic_error_t**);
+
+ const cookie_f_ptr_t m_cookieFunc;
+ const reply_f_ptr_t m_replyFunc;
+
+ public:
+ consteval XcbFetch(cookie_f_ptr_t cookieFunc, reply_f_ptr_t replyFunc) : m_cookieFunc{cookieFunc}, m_replyFunc{replyFunc} {}
+
+ inline Reply<Reply_RetType> operator()(XcbConn conn, auto... args) { //have to use auto for argsTwo, since otherwise there'd be a type deduction conflict
+ return Reply<Reply_RetType> { m_replyFunc(conn, m_cookieFunc(conn, args...), nullptr) };
+ }
+ };
+
+ template <typename CookieType>
+ concept CacheableCookie = std::is_same<CookieType, xcb_get_geometry_cookie_t>::value
+ || std::is_same<CookieType, xcb_query_tree_cookie_t>::value;
+
+ template <CacheableCookie Cookie_RetType, typename Reply_RetType>
+ class XcbFetch<Cookie_RetType, Reply_RetType, xcb_connection_t*, xcb_window_t> {
+ using cookie_f_ptr_t = Cookie_RetType (*)(xcb_connection_t*, xcb_window_t);
+ using reply_f_ptr_t = Reply_RetType* (*)(xcb_connection_t*, Cookie_RetType, xcb_generic_error_t**);
+
+ const cookie_f_ptr_t m_cookieFunc;
+ const reply_f_ptr_t m_replyFunc;
+
+ inline Reply<Reply_RetType> getCachedReply(xcb_connection_t* connection) {
+ if (std::get<Reply_RetType*>(g_cache.cached_replies) == nullptr) {
+ std::get<Reply_RetType*>(g_cache.cached_replies) = m_replyFunc(connection, std::get<Cookie_RetType>(g_cache.cached_cookies), nullptr);
+ }
+ return Reply<Reply_RetType>{std::get<Reply_RetType*>(g_cache.cached_replies), ReplyDeleter{false}}; // return 'non-owning' unique_ptr
+ }
+
+ public:
+ consteval XcbFetch(cookie_f_ptr_t cookieFunc, reply_f_ptr_t replyFunc) : m_cookieFunc{cookieFunc}, m_replyFunc{replyFunc} {}
+
+ inline Reply<Reply_RetType> operator()(xcb_connection_t* conn, xcb_window_t window) {
+ const bool tryCached = pthread_equal(g_cache_tid, pthread_self())
+ && g_cache.window == window;
+ if (!tryCached) [[unlikely]]
+ return Reply<Reply_RetType> { m_replyFunc(conn, m_cookieFunc(conn, window), nullptr) };
+
+ auto ret = getCachedReply(conn);
+ #if !defined(NDEBUG) || NDEBUG == 0
+ if (!ret)
+ fprintf(stderr, "[Gamescope WSI] getCachedReply() failed.\n");
+ #endif
+ return ret;
+ }
+ };
+
static std::optional<xcb_atom_t> getAtom(xcb_connection_t* connection, std::string_view name) {
- xcb_intern_atom_cookie_t cookie = xcb_intern_atom(connection, false, name.length(), name.data());
- auto reply = Reply<xcb_intern_atom_reply_t>{ xcb_intern_atom_reply(connection, cookie, nullptr) };
+ auto reply = XcbFetch{xcb_intern_atom, xcb_intern_atom_reply}(connection, false, name.length(), name.data());
if (!reply) {
fprintf(stderr, "[Gamescope WSI] Failed to get xcb atom.\n");
return std::nullopt;
@@ -34,8 +118,7 @@ namespace xcb {
xcb_screen_t* screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data;
- xcb_get_property_cookie_t cookie = xcb_get_property(connection, false, screen->root, atom, XCB_ATOM_CARDINAL, 0, sizeof(T) / sizeof(uint32_t));
- auto reply = Reply<xcb_get_property_reply_t>{ xcb_get_property_reply(connection, cookie, nullptr) };
+ auto reply = XcbFetch{xcb_get_property, xcb_get_property_reply}(connection, false, screen->root, atom, XCB_ATOM_CARDINAL, 0, sizeof(T) / sizeof(uint32_t));
if (!reply) {
fprintf(stderr, "[Gamescope WSI] Failed to read T root window property.\n");
return std::nullopt;
@@ -61,8 +144,7 @@ namespace xcb {
static std::optional<xcb_window_t> getToplevelWindow(xcb_connection_t* connection, xcb_window_t window) {
for (;;) {
- xcb_query_tree_cookie_t cookie = xcb_query_tree(connection, window);
- auto reply = Reply<xcb_query_tree_reply_t>{ xcb_query_tree_reply(connection, cookie, nullptr) };
+ auto reply = XcbFetch{xcb_query_tree, xcb_query_tree_reply}(connection, window);
if (!reply) {
fprintf(stderr, "[Gamescope WSI] getToplevelWindow: xcb_query_tree failed for window 0x%x.\n", window);
@@ -77,8 +159,7 @@ namespace xcb {
}
static std::optional<VkRect2D> getWindowRect(xcb_connection_t* connection, xcb_window_t window) {
- xcb_get_geometry_cookie_t cookie = xcb_get_geometry(connection, window);
- auto reply = Reply<xcb_get_geometry_reply_t>{ xcb_get_geometry_reply(connection, cookie, nullptr) };
+ auto reply = XcbFetch{xcb_get_geometry, xcb_get_geometry_reply}(connection, window);
if (!reply) {
fprintf(stderr, "[Gamescope WSI] getWindowRect: xcb_get_geometry failed for window 0x%x.\n", window);
return std::nullopt;
@@ -112,8 +193,7 @@ namespace xcb {
static std::optional<VkExtent2D> getLargestObscuringChildWindowSize(xcb_connection_t* connection, xcb_window_t window) {
VkExtent2D largestExtent = {};
- xcb_query_tree_cookie_t cookie = xcb_query_tree(connection, window);
- auto reply = Reply<xcb_query_tree_reply_t>{ xcb_query_tree_reply(connection, cookie, nullptr) };
+ auto reply = XcbFetch{xcb_query_tree, xcb_query_tree_reply}(connection, window);
if (!reply) {
fprintf(stderr, "[Gamescope WSI] getLargestObscuringWindowSize: xcb_query_tree failed for window 0x%x.\n", window);
@@ -130,8 +210,7 @@ namespace xcb {
for (uint32_t i = 0; i < reply->children_len; i++) {
xcb_window_t child = children[i];
- xcb_get_window_attributes_cookie_t attributeCookie = xcb_get_window_attributes(connection, child);
- auto attributeReply = Reply<xcb_get_window_attributes_reply_t>{ xcb_get_window_attributes_reply(connection, attributeCookie, nullptr) };
+ auto attributeReply = XcbFetch{xcb_get_window_attributes, xcb_get_window_attributes_reply}(connection, child);
const bool obscuring =
attributeReply &&
From 1b59621f4de5c05096d1f279cba2e04264124154 Mon Sep 17 00:00:00 2001
From: sharkautarch <128002472+sharkautarch@users.noreply.github.com>
Date: Tue, 18 Jun 2024 22:21:23 -0400
Subject: [PATCH 2/2] WSI: prefetcher: fix issue w/ attempting to prefetch xcb
stuff for pure wayland surfaces
---
layer/VkLayer_FROG_gamescope_wsi.cpp | 2 +-
layer/xcb_helpers.hpp | 9 ++++++++-
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/layer/VkLayer_FROG_gamescope_wsi.cpp b/layer/VkLayer_FROG_gamescope_wsi.cpp
index f26819a60..ce011dcd7 100644
--- a/layer/VkLayer_FROG_gamescope_wsi.cpp
+++ b/layer/VkLayer_FROG_gamescope_wsi.cpp
@@ -1234,7 +1234,7 @@ namespace GamescopeWSILayer {
continue;
}
- xcb::Prefetcher prefetcher(gamescopeSurface->connection, gamescopeSurface->window);
+ auto prefetcher = xcb::Prefetcher::GetPrefetcherIf(!gamescopeSurface->isWayland(), gamescopeSurface->connection, gamescopeSurface->window);
const bool canBypass = gamescopeSurface->canBypassXWayland();
if (canBypass != gamescopeSwapchain->isBypassingXWayland)
UpdateSwapchainResult(canBypass ? VK_SUBOPTIMAL_KHR : VK_ERROR_OUT_OF_DATE_KHR);
diff --git a/layer/xcb_helpers.hpp b/layer/xcb_helpers.hpp
index 72d0ec092..f26aef38b 100644
--- a/layer/xcb_helpers.hpp
+++ b/layer/xcb_helpers.hpp
@@ -16,6 +16,13 @@ namespace xcb {
//Note: this class is currently only meant to be used within GamescopeWSILayer::VkDeviceOverrides::QueuePresentKHR:
struct Prefetcher {
+ static std::optional<Prefetcher> GetPrefetcherIf(bool bCond, xcb_connection_t* connection, const xcb_window_t window) {
+ if (bCond)
+ return std::optional<Prefetcher>(std::in_place_t{}, connection, window);
+
+ return std::nullopt;
+ }
+
explicit Prefetcher(xcb_connection_t* connection, const xcb_window_t window) {
g_cache = {
.window = window,
@@ -90,7 +97,7 @@ namespace xcb {
inline Reply<Reply_RetType> operator()(xcb_connection_t* conn, xcb_window_t window) {
const bool tryCached = pthread_equal(g_cache_tid, pthread_self())
&& g_cache.window == window;
- if (!tryCached) [[unlikely]]
+ if (!tryCached)
return Reply<Reply_RetType> { m_replyFunc(conn, m_cookieFunc(conn, window), nullptr) };
auto ret = getCachedReply(conn);

127
patches/1335.patch Normal file
View File

@ -0,0 +1,127 @@
From 35f5ba8bb9297d06b7d8238295ae3601367d91ad Mon Sep 17 00:00:00 2001
From: sharkautarch <128002472+sharkautarch@users.noreply.github.com>
Date: Fri, 24 May 2024 15:43:09 -0400
Subject: [PATCH 1/2] sdlwindow.cpp: close m_thread w/o std::terminate being
called
---
src/Backends/SDLBackend.cpp | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/src/Backends/SDLBackend.cpp b/src/Backends/SDLBackend.cpp
index d7456b6a4..5420683a3 100644
--- a/src/Backends/SDLBackend.cpp
+++ b/src/Backends/SDLBackend.cpp
@@ -53,6 +53,7 @@ namespace gamescope
GAMESCOPE_SDL_EVENT_CURSOR,
GAMESCOPE_SDL_EVENT_COUNT,
+ GAMESCOPE_SDL_EVENT_REQ_EXIT,
};
class CSDLConnector final : public IBackendConnector
@@ -111,6 +112,7 @@ namespace gamescope
{
public:
CSDLBackend();
+ ~CSDLBackend();
/////////////
// IBackend
@@ -548,7 +550,12 @@ namespace gamescope
{
// Do nothing.
}
-
+
+ CSDLBackend::~CSDLBackend() {
+ PushUserEvent(GAMESCOPE_SDL_EVENT_REQ_EXIT);
+ m_SDLThread.join();
+ }
+
void CSDLBackend::SDLThreadFunc()
{
pthread_setname_np( pthread_self(), "gamescope-sdl" );
@@ -944,6 +951,9 @@ namespace gamescope
SDL_SetCursor( m_pCursor );
}
+ else if ( event.type == GetUserEventIndex( GAMESCOPE_SDL_EVENT_REQ_EXIT ) ) {
+ return;
+ }
}
break;
}
From 61392a9e545e0a3341c0d510aaa453c08826cc5b Mon Sep 17 00:00:00 2001
From: sharkautarch <128002472+sharkautarch@users.noreply.github.com>
Date: Thu, 30 May 2024 14:02:00 -0400
Subject: [PATCH 2/2] steamcompmgr, rendervulkan: prevent segfault that occured
when closing gamescope, due to a race condition between present thread @
present_wait_thread_func & compositor thread @ steamcompmgr_exit
---
src/rendervulkan.cpp | 7 ++++++-
src/rendervulkan.hpp | 4 ++++
src/steamcompmgr.cpp | 8 ++++++++
3 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/src/rendervulkan.cpp b/src/rendervulkan.cpp
index ffd0783da..094141839 100644
--- a/src/rendervulkan.cpp
+++ b/src/rendervulkan.cpp
@@ -2669,7 +2669,8 @@ bool acquire_next_image( void )
}
-static std::atomic<uint64_t> g_currentPresentWaitId = {0u};
+inline std::atomic<uint64_t> g_currentPresentWaitId = {0u};
+inline std::atomic<bool> g_presentThreadShouldExit = {false};
static std::mutex present_wait_lock;
extern void mangoapp_output_update( uint64_t vblanktime );
@@ -2693,6 +2694,10 @@ static void present_wait_thread_func( void )
uint64_t vblanktime = get_time_in_nanos();
GetVBlankTimer().MarkVBlank( vblanktime, true );
mangoapp_output_update( vblanktime );
+ } else if ( g_presentThreadShouldExit.load(std::memory_order_acquire)) {
+ g_presentThreadShouldExit = 0;
+ g_presentThreadShouldExit.notify_all();
+ return;
}
}
}
diff --git a/src/rendervulkan.hpp b/src/rendervulkan.hpp
index 177468228..a2e0dd972 100644
--- a/src/rendervulkan.hpp
+++ b/src/rendervulkan.hpp
@@ -74,6 +74,10 @@ enum EStreamColorspace : int
#include <vulkan/vulkan.h>
#include <drm_fourcc.h>
+extern std::atomic<uint64_t> g_currentPresentWaitId;
+
+extern std::atomic<bool> g_presentThreadShouldExit;
+
struct VulkanRenderer_t
{
struct wlr_renderer base;
diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp
index 910ed3912..f6539829e 100644
--- a/src/steamcompmgr.cpp
+++ b/src/steamcompmgr.cpp
@@ -5840,6 +5840,14 @@ steamcompmgr_exit(void)
}
}
+ //request the present_wait thread to exit
+ //needed to avoid getting a segfault at exit due to race condition:
+ g_presentThreadShouldExit.store(true, std::memory_order_release);
+ g_currentPresentWaitId = 0; //present thread will check if it should exit if this is zero
+ g_currentPresentWaitId.notify_all();
+ g_presentThreadShouldExit.wait(true); //present thread will toggle this atomic when it sees the exit request
+ //this allows us to wait for present thread to close before deleting the backend
+
gamescope::IBackend::Set( nullptr );
wlserver_lock();

2027
patches/chimeraos.patch Normal file

File diff suppressed because it is too large Load Diff

136
patches/deckhd.patch Normal file
View File

@ -0,0 +1,136 @@
diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp
index 85e5126..be418b4 100644
--- a/src/Backends/DRMBackend.cpp
+++ b/src/Backends/DRMBackend.cpp
@@ -2149,6 +2149,7 @@ namespace gamescope
( m_Mutable.szMakePNP == "WLC"sv && m_Mutable.szModel == "ANX7530 U"sv ) ||
( m_Mutable.szMakePNP == "ANX"sv && m_Mutable.szModel == "ANX7530 U"sv ) ||
( m_Mutable.szMakePNP == "VLV"sv && m_Mutable.szModel == "ANX7530 U"sv ) ||
+ ( m_Mutable.szMakePNP == "DHD"sv && m_Mutable.szModel == "DeckHD-1200p"sv ) ||
( m_Mutable.szMakePNP == "VLV"sv && m_Mutable.szModel == "Jupiter"sv ) ||
( m_Mutable.szMakePNP == "VLV"sv && m_Mutable.szModel == "Galileo"sv );
@@ -2160,6 +2161,7 @@ namespace gamescope
{
static constexpr uint32_t kPIDGalileoSDC = 0x3003;
static constexpr uint32_t kPIDGalileoBOE = 0x3004;
+ static constexpr uint32_t kPIDJupiterDHD = 0x4001;
if ( pProduct->product == kPIDGalileoSDC )
{
@@ -2171,6 +2173,10 @@ namespace gamescope
m_Mutable.eKnownDisplay = GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_BOE;
m_Mutable.ValidDynamicRefreshRates = std::span( s_kSteamDeckOLEDRates );
}
+ else if (pProduct-> product == kPIDJupiterDHD ) {
+ m_Mutable.eKnownDisplay = GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD_DHD;
+ m_Mutable.ValidDynamicRefreshRates = std::span( s_kSteamDeckLCDRates );
+ }
else
{
m_Mutable.eKnownDisplay = GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD;
@@ -2200,7 +2206,8 @@ namespace gamescope
drm_log.infof( "[colorimetry]: Steam Deck LCD detected. Using known colorimetry" );
m_Mutable.DisplayColorimetry = displaycolorimetry_steamdeck_measured;
}
- else
+ else if (m_Mutable.eKnownDisplay == GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_BOE ||
+ m_Mutable.eKnownDisplay == GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_SDC )
{
// Steam Deck OLED has calibrated chromaticity coordinates in the EDID
// for each unit.
@@ -2330,7 +2337,7 @@ namespace gamescope
.uMinContentLightLevel = nits_to_u16_dark( 0 ),
};
}
- else if ( eKnownDisplay == GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD )
+ else if ( eKnownDisplay == GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD || eKnownDisplay == GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD_DHD )
{
// Set up some HDR fallbacks for undocking
return BackendConnectorHDRInfo
diff --git a/src/gamescope_shared.h b/src/gamescope_shared.h
index ed30d8c..3b60774 100644
--- a/src/gamescope_shared.h
+++ b/src/gamescope_shared.h
@@ -8,6 +8,7 @@ namespace gamescope
{
GAMESCOPE_KNOWN_DISPLAY_UNKNOWN,
GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD, // Jupiter
+ GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD_DHD, // Jupiter Deck HD
GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_SDC, // Galileo SDC
GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_BOE, // Galileo BOE
};
diff --git a/src/modegen.cpp b/src/modegen.cpp
index d174c2d..5dd1136 100644
--- a/src/modegen.cpp
+++ b/src/modegen.cpp
@@ -293,13 +293,32 @@ unsigned int galileo_boe_vfp[] =
172,152,136,120,100,84,68,52,36,20,8
};
-#define GALILEO_MIN_REFRESH 45
+//SD LCD Stock Timings
+#define JUPITER_BOE_PID 0x3001
+#define JUPITER_B_PID 0x3002
+#define JUPITER_HFP 40
+#define JUPITER_HSYNC 4
+#define JUPITER_HBP 40
+#define JUPITER_VFP 30
+#define JUPITER_VSYNC 4
+#define JUPITER_VBP 8
+//SD LCD DeckHD Timings
+#define JUPITER_DHD_PID 0x4001
+#define JUPITER_DHD_HFP 40
+#define JUPITER_DHD_HSYNC 20
+#define JUPITER_DHD_HBP 40
+#define JUPITER_DHD_VFP 18
+#define JUPITER_DHD_VSYNC 2
+#define JUPITER_DHD_VBP 20
+//SD OLED SDC Timings
#define GALILEO_SDC_PID 0x3003
#define GALILEO_SDC_VSYNC 1
#define GALILEO_SDC_VBP 22
+//SD OLED BOE Timings
#define GALILEO_BOE_PID 0x3004
#define GALILEO_BOE_VSYNC 2
#define GALILEO_BOE_VBP 30
+#define GALILEO_MIN_REFRESH 45
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
unsigned int get_galileo_vfp( int vrefresh, unsigned int * vfp_array, unsigned int num_rates )
@@ -344,17 +363,28 @@ void generate_fixed_mode(drmModeModeInfo *mode, const drmModeModeInfo *base, int
mode->vsync_end = mode->vsync_start + vsync;
mode->vtotal = mode->vsync_end + vbp;
} else {
- if ( eKnownDisplay == gamescope::GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD )
+ if ( eKnownDisplay == gamescope::GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD_DHD ) {
+ mode->hdisplay = 1200;
+ mode->hsync_start = mode->hdisplay + JUPITER_DHD_HFP;
+ mode->hsync_end = mode->hsync_start + JUPITER_DHD_HSYNC;
+ mode->htotal = mode->hsync_end + JUPITER_DHD_HBP;
+
+ mode->vdisplay = 1920;
+ mode->vsync_start = mode->vdisplay + JUPITER_DHD_VFP;
+ mode->vsync_end = mode->vsync_start + JUPITER_DHD_VSYNC;
+ mode->vtotal = mode->vsync_end + JUPITER_DHD_VBP;
+ }
+ else if ( eKnownDisplay == gamescope::GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD )
{
mode->hdisplay = 800;
- mode->hsync_start = 840;
- mode->hsync_end = 844;
- mode->htotal = 884;
+ mode->hsync_start = mode->hdisplay + JUPITER_HFP;
+ mode->hsync_end = mode->hsync_start + JUPITER_HSYNC;
+ mode->htotal = mode->hsync_end + JUPITER_HBP;
mode->vdisplay = 1280;
- mode->vsync_start = 1310;
- mode->vsync_end = 1314;
- mode->vtotal = 1322;
+ mode->vsync_start = mode->vdisplay + JUPITER_VFP;
+ mode->vsync_end = mode->vsync_start + JUPITER_VSYNC;
+ mode->vtotal = mode->vsync_end + JUPITER_VBP;
}
mode->clock = ( ( mode->htotal * mode->vtotal * vrefresh ) + 999 ) / 1000;

View File

@ -0,0 +1,51 @@
diff --git a/src/main.cpp b/src/main.cpp
index 119e043..6c46d97 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -148,6 +148,8 @@ const struct option *gamescope_options = (struct option[]){
{ "reshade-effect", required_argument, nullptr, 0 },
{ "reshade-technique-idx", required_argument, nullptr, 0 },
+ { "disable-touch-click", no_argument, nullptr, 0 },
+
// Steam Deck options
{ "mura-map", required_argument, nullptr, 0 },
@@ -193,6 +195,7 @@ const char usage[] =
" -e, --steam enable Steam integration\n"
" --bypass-steam-resolution bypass Steam's default 720p/800p default resolution\n"
" --touch-gestures enable touch gestures for Steam menus\n"
+ " --disable-touch-click disable touchscreen tap acting as a click\n"
" --xwayland-count create N xwayland servers\n"
" --prefer-vk-device prefer Vulkan device for compositing (ex: 1002:7300)\n"
" --force-orientation rotate the internal display (left, right, normal, upsidedown)\n"
diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp
index 92bf617..d7498e5 100644
--- a/src/steamcompmgr.cpp
+++ b/src/steamcompmgr.cpp
@@ -347,6 +347,7 @@ bool g_bHDRItmEnable = false;
int g_nCurrentRefreshRate_CachedValue = 0;
gamescope::ConVar<bool> cv_bypass_steam_resolution{ "bypass_steam_resolution", false, "Workaround the 720p/800p limits Steam uses for games" };
+gamescope::ConVar<bool> cv_disable_touch_click{ "disable_touch_click", false, "Prevents touchscreen taps acting as clicks" };
static void
update_color_mgmt()
@@ -5128,7 +5129,7 @@ handle_property_notify(xwayland_ctx_t *ctx, XPropertyEvent *ev)
MakeFocusDirty();
}
}
- if (ev->atom == ctx->atoms.steamTouchClickModeAtom )
+ if (ev->atom == ctx->atoms.steamTouchClickModeAtom && !cv_disable_touch_click)
{
gamescope::cv_touch_click_mode = (gamescope::TouchClickMode) get_prop(ctx, ctx->root, ctx->atoms.steamTouchClickModeAtom, 0u );
}
@@ -7301,6 +7302,8 @@ steamcompmgr_main(int argc, char **argv)
g_reshade_technique_idx = atoi(optarg);
} else if (strcmp(opt_name, "mura-map") == 0) {
set_mura_overlay(optarg);
+ } else if (strcmp(opt_name, "disable-touch-click") == 0) {
+ cv_disable_touch_click = true;
}
break;
case '?':

View File

@ -0,0 +1,63 @@
From 2e4d7ad1bf2cb98eb67ff8f9385cf6657cf2e912 Mon Sep 17 00:00:00 2001
From: Matthew Schwartz <njtransit215@gmail.com>
Date: Wed, 3 Jul 2024 15:20:08 -0700
Subject: [PATCH] drm: Separate BOE and SDC OLED Deck panel valid refresh rates
OLED Decks with BOE panels seem to struggle with a few different
specific modesets (51hz/55hz/65hz) that SDC panels have no issues with.
To work around this, let's make use of Gamescope recognizing each
display manufacturer to correct the bad modesets while leaving
SDC panel units alone. This can be reverted if an underlying cause can
be found in the kernel in the future.
---
src/Backends/DRMBackend.cpp | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp
index 97ef446..9f93c7f 100644
--- a/src/Backends/DRMBackend.cpp
+++ b/src/Backends/DRMBackend.cpp
@@ -554,7 +554,7 @@ static constexpr uint32_t s_kSteamDeckLCDRates[] =
60,
};
-static constexpr uint32_t s_kSteamDeckOLEDRates[] =
+static constexpr uint32_t s_kSteamDeckOLEDSDCRates[] =
{
45, 47, 48, 49,
50, 51, 53, 55, 56, 59,
@@ -564,6 +564,16 @@ static constexpr uint32_t s_kSteamDeckOLEDRates[] =
90,
};
+static constexpr uint32_t s_kSteamDeckOLEDBOERates[] =
+{
+ 45, 47, 48, 49,
+ 50, 53, 56, 59,
+ 60, 62, 64, 66, 68,
+ 72, 73, 76, 77, 78,
+ 80, 81, 82, 84, 85, 86, 87, 88,
+ 90,
+};
+
static void update_connector_display_info_wl(struct drm_t *drm)
{
wlserver_lock();
@@ -2128,12 +2138,12 @@ namespace gamescope
if ( pProduct->product == kPIDGalileoSDC )
{
m_Mutable.eKnownDisplay = GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_SDC;
- m_Mutable.ValidDynamicRefreshRates = std::span( s_kSteamDeckOLEDRates );
+ m_Mutable.ValidDynamicRefreshRates = std::span( s_kSteamDeckOLEDSDCRates );
}
else if ( pProduct->product == kPIDGalileoBOE )
{
m_Mutable.eKnownDisplay = GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_BOE;
- m_Mutable.ValidDynamicRefreshRates = std::span( s_kSteamDeckOLEDRates );
+ m_Mutable.ValidDynamicRefreshRates = std::span( s_kSteamDeckOLEDBOERates );
}
else
{
--
2.45.2

View File

@ -0,0 +1,65 @@
diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp
index d7498e5..d1800a8 100644
--- a/src/steamcompmgr.cpp
+++ b/src/steamcompmgr.cpp
@@ -3271,7 +3271,7 @@ found:;
if ( window_has_commits( focus ) )
out->focusWindow = focus;
else
- focus->outdatedInteractiveFocus = true;
+ out->outdatedInteractiveFocus = true;
// Always update X's idea of focus, but still dirty
// the it being outdated so we can resolve that globally later.
@@ -5995,28 +5995,37 @@ bool handle_done_commit( steamcompmgr_win_t *w, xwayland_ctx_t *ctx, uint64_t co
// Window just got a new available commit, determine if that's worth a repaint
// If this is an overlay that we're presenting, repaint
- if ( w == global_focus.overlayWindow && w->opacity != TRANSLUCENT )
+ if ( gameFocused )
{
- hasRepaintNonBasePlane = true;
- }
+ if ( w == global_focus.overlayWindow && w->opacity != TRANSLUCENT )
+ {
+ hasRepaintNonBasePlane = true;
+ }
- if ( w == global_focus.notificationWindow && w->opacity != TRANSLUCENT )
- {
- hasRepaintNonBasePlane = true;
+ if ( w == global_focus.notificationWindow && w->opacity != TRANSLUCENT )
+ {
+ hasRepaintNonBasePlane = true;
+ }
}
-
- // If this is an external overlay, repaint
- if ( w == global_focus.externalOverlayWindow && w->opacity != TRANSLUCENT )
+ if ( ctx )
{
- hasRepaintNonBasePlane = true;
+ if ( ctx->focus.outdatedInteractiveFocus )
+ {
+ MakeFocusDirty();
+ ctx->focus.outdatedInteractiveFocus = false;
+ }
}
-
- if ( w->outdatedInteractiveFocus )
+ if ( global_focus.outdatedInteractiveFocus )
{
MakeFocusDirty();
- w->outdatedInteractiveFocus = false;
- }
+ global_focus.outdatedInteractiveFocus = false;
+ // If this is an external overlay, repaint
+ if ( w == global_focus.externalOverlayWindow && w->opacity != TRANSLUCENT )
+ {
+ hasRepaintNonBasePlane = true;
+ }
+ }
// If this is the main plane, repaint
if ( w == global_focus.focusWindow && !w->isSteamStreamingClient )
{

8
patches/series Executable file
View File

@ -0,0 +1,8 @@
chimeraos.patch
disable-steam-touch-click-atom.patch
deckhd.patch
drm-Separate-BOE-and-SDC-OLED-Deck-panel-rates.patch
revert-299bc34.patch
1335.patch
1231.patch
v2-0001-always-send-ctrl-1-2-to-steam-s-wayland-session.patch

View File

@ -0,0 +1,40 @@
From 35e001dc59a44227d670c667a85a6ef5472eee58 Mon Sep 17 00:00:00 2001
From: antheas <git@antheas.dev>
Date: Sat, 20 Jul 2024 01:23:19 +0300
Subject: [PATCH v2] always send ctrl+1/2 to steam's wayland session
---
src/wlserver.cpp | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/src/wlserver.cpp b/src/wlserver.cpp
index 1852be9..7de737d 100644
--- a/src/wlserver.cpp
+++ b/src/wlserver.cpp
@@ -369,7 +369,12 @@ static void wlserver_handle_key(struct wl_listener *listener, void *data)
keysym == XKB_KEY_XF86AudioLowerVolume ||
keysym == XKB_KEY_XF86AudioRaiseVolume ||
keysym == XKB_KEY_XF86PowerOff;
- if ( ( event->state == WL_KEYBOARD_KEY_STATE_PRESSED || event->state == WL_KEYBOARD_KEY_STATE_RELEASED ) && forbidden_key )
+
+ // Check for steam keys (ctrl + 1/2)
+ bool is_steamshortcut = (keyboard->wlr->modifiers.depressed & WLR_MODIFIER_CTRL) && (keysym == XKB_KEY_1 ||
+ keysym == XKB_KEY_2);
+
+ if ( ( event->state == WL_KEYBOARD_KEY_STATE_PRESSED || event->state == WL_KEYBOARD_KEY_STATE_RELEASED ) && (forbidden_key || is_steamshortcut) )
{
// Always send volume+/- to root server only, to avoid it reaching the game.
struct wlr_surface *old_kb_surf = wlserver.kb_focus_surface;
@@ -378,6 +383,9 @@ static void wlserver_handle_key(struct wl_listener *listener, void *data)
{
wlserver_keyboardfocus( new_kb_surf, false );
wlr_seat_set_keyboard( wlserver.wlr.seat, keyboard->wlr );
+ // Send modifiers to steam for it to work
+ if (is_steamshortcut)
+ wlr_seat_keyboard_notify_modifiers(wlserver.wlr.seat, &keyboard->wlr->modifiers);
wlr_seat_keyboard_notify_key( wlserver.wlr.seat, event->time_msec, event->keycode, event->state );
wlserver_keyboardfocus( old_kb_surf, false );
return;
--
2.45.2

10
pika-build-config/amd64-v3.sh Executable file
View File

@ -0,0 +1,10 @@
#! /bin/bash
export PIKA_BUILD_ARCH="amd64-v3"
export DEBIAN_FRONTEND="noninteractive"
export DEB_BUILD_MAINT_OPTIONS="optimize=+lto -march=x86-64-v3 -O3 -flto -fuse-linker-plugin -falign-functions=32"
export DEB_CFLAGS_MAINT_APPEND="-march=x86-64-v3 -O3 -flto -fuse-linker-plugin -falign-functions=32"
export DEB_CPPFLAGS_MAINT_APPEND="-march=x86-64-v3 -O3 -flto -fuse-linker-plugin -falign-functions=32"
export DEB_CXXFLAGS_MAINT_APPEND="-march=x86-64-v3 -O3 -flto -fuse-linker-plugin -falign-functions=32"
export DEB_LDFLAGS_MAINT_APPEND="-march=x86-64-v3 -O3 -flto -fuse-linker-plugin -falign-functions=32"
export DEB_BUILD_OPTIONS="nocheck notest terse"
export DPKG_GENSYMBOLS_CHECK_LEVEL=0

5
pika-build-config/i386.sh Executable file
View File

@ -0,0 +1,5 @@
#! /bin/bash
export PIKA_BUILD_ARCH="i386"
export DEBIAN_FRONTEND="noninteractive"
export DEB_BUILD_OPTIONS="nocheck notest terse"
export DPKG_GENSYMBOLS_CHECK_LEVEL=0

View File

@ -1,8 +1,2 @@
# send debs to server # send debs to server
rsync -azP --include './' --include '*.deb' --exclude '*' ./output/ ferreo@direct.pika-os.com:/srv/www/incoming/ rsync -azP --include './' --include '*.deb' --exclude '*' ./output/ ferreo@direct.pika-os.com:/srv/www/cockatiel-incoming/
# add debs to repo
ssh ferreo@direct.pika-os.com 'aptly repo add -force-replace -remove-files pikauwu-main /srv/www/incoming/'
# publish the repo
ssh ferreo@direct.pika-os.com 'aptly publish update -batch -skip-contents -force-overwrite pikauwu filesystem:pikarepo:'