Pipewire: support alpha textures again, do alpha blending and clear

background if fourcc is alpha.
This commit is contained in:
dec05eba
2025-07-20 22:04:54 +02:00
parent 4fb0dad3df
commit 1e62e654e2
5 changed files with 38 additions and 22 deletions

View File

@@ -9,7 +9,7 @@
#include <spa/param/video/format.h> #include <spa/param/video/format.h>
#define GSR_PIPEWIRE_VIDEO_MAX_MODIFIERS 1024 #define GSR_PIPEWIRE_VIDEO_MAX_MODIFIERS 1024
#define GSR_PIPEWIRE_VIDEO_MAX_VIDEO_FORMATS 6 #define GSR_PIPEWIRE_VIDEO_MAX_VIDEO_FORMATS 12
#define GSR_PIPEWIRE_VIDEO_DMABUF_MAX_PLANES 4 #define GSR_PIPEWIRE_VIDEO_DMABUF_MAX_PLANES 4
typedef struct gsr_egl gsr_egl; typedef struct gsr_egl gsr_egl;

View File

@@ -1,4 +1,4 @@
project('gpu-screen-recorder', ['c', 'cpp'], version : '5.6.1', default_options : ['warning_level=2']) project('gpu-screen-recorder', ['c', 'cpp'], version : '5.6.2', default_options : ['warning_level=2'])
add_project_arguments('-Wshadow', language : ['c', 'cpp']) add_project_arguments('-Wshadow', language : ['c', 'cpp'])
if get_option('buildtype') == 'debug' if get_option('buildtype') == 'debug'

View File

@@ -1,7 +1,7 @@
[package] [package]
name = "gpu-screen-recorder" name = "gpu-screen-recorder"
type = "executable" type = "executable"
version = "5.6.1" version = "5.6.2"
platforms = ["posix"] platforms = ["posix"]
[config] [config]

View File

@@ -319,6 +319,15 @@ static bool gsr_capture_portal_capture_has_synchronous_task(gsr_capture *cap) {
return gsr_pipewire_video_should_restart(&self->pipewire); return gsr_pipewire_video_should_restart(&self->pipewire);
} }
static bool fourcc_has_alpha(uint32_t fourcc) {
const uint8_t *p = (const uint8_t*)&fourcc;
for(int i = 0; i < 4; ++i) {
if(p[i] == 'A')
return true;
}
return false;
}
static int gsr_capture_portal_capture(gsr_capture *cap, gsr_capture_metadata *capture_metadata, gsr_color_conversion *color_conversion) { static int gsr_capture_portal_capture(gsr_capture *cap, gsr_capture_metadata *capture_metadata, gsr_color_conversion *color_conversion) {
(void)color_conversion; (void)color_conversion;
gsr_capture_portal *self = cap->priv; gsr_capture_portal *self = cap->priv;
@@ -361,10 +370,14 @@ static int gsr_capture_portal_capture(gsr_capture *cap, gsr_capture_metadata *ca
// TODO: Handle region crop // TODO: Handle region crop
const bool fourcc_alpha = fourcc_has_alpha(self->pipewire_fourcc);
if(fourcc_alpha)
gsr_color_conversion_clear(color_conversion);
gsr_color_conversion_draw(color_conversion, self->using_external_image ? self->texture_map.external_texture_id : self->texture_map.texture_id, gsr_color_conversion_draw(color_conversion, self->using_external_image ? self->texture_map.external_texture_id : self->texture_map.texture_id,
target_pos, output_size, target_pos, output_size,
(vec2i){self->region.x, self->region.y}, self->capture_size, self->capture_size, (vec2i){self->region.x, self->region.y}, self->capture_size, self->capture_size,
GSR_ROT_0, GSR_SOURCE_COLOR_RGB, self->using_external_image, false); GSR_ROT_0, GSR_SOURCE_COLOR_RGB, self->using_external_image, fourcc_alpha);
if(self->params.record_cursor && self->texture_map.cursor_texture_id > 0 && self->cursor_region.width > 0) { if(self->params.record_cursor && self->texture_map.cursor_texture_id > 0 && self->cursor_region.width > 0) {
const vec2d scale = { const vec2d scale = {

View File

@@ -354,17 +354,17 @@ static int64_t spa_video_format_to_drm_format(const enum spa_video_format format
switch(format) { switch(format) {
case SPA_VIDEO_FORMAT_RGBx: return DRM_FORMAT_XBGR8888; case SPA_VIDEO_FORMAT_RGBx: return DRM_FORMAT_XBGR8888;
case SPA_VIDEO_FORMAT_BGRx: return DRM_FORMAT_XRGB8888; case SPA_VIDEO_FORMAT_BGRx: return DRM_FORMAT_XRGB8888;
// case SPA_VIDEO_FORMAT_RGBA: return DRM_FORMAT_ABGR8888; case SPA_VIDEO_FORMAT_RGBA: return DRM_FORMAT_ABGR8888;
//case SPA_VIDEO_FORMAT_BGRA: return DRM_FORMAT_ARGB8888; case SPA_VIDEO_FORMAT_BGRA: return DRM_FORMAT_ARGB8888;
case SPA_VIDEO_FORMAT_RGB: return DRM_FORMAT_XBGR8888; case SPA_VIDEO_FORMAT_RGB: return DRM_FORMAT_XBGR8888;
case SPA_VIDEO_FORMAT_BGR: return DRM_FORMAT_XRGB8888; case SPA_VIDEO_FORMAT_BGR: return DRM_FORMAT_XRGB8888;
//case SPA_VIDEO_FORMAT_ARGB: return DRM_FORMAT_XRGB8888; case SPA_VIDEO_FORMAT_ARGB: return DRM_FORMAT_BGRA8888;
//case SPA_VIDEO_FORMAT_ABGR: return DRM_FORMAT_XRGB8888; case SPA_VIDEO_FORMAT_ABGR: return DRM_FORMAT_RGBA8888;
#if PW_CHECK_VERSION(0, 3, 41) #if PW_CHECK_VERSION(0, 3, 41)
case SPA_VIDEO_FORMAT_xRGB_210LE: return DRM_FORMAT_XRGB2101010; case SPA_VIDEO_FORMAT_xRGB_210LE: return DRM_FORMAT_XRGB2101010;
case SPA_VIDEO_FORMAT_xBGR_210LE: return DRM_FORMAT_XBGR2101010; case SPA_VIDEO_FORMAT_xBGR_210LE: return DRM_FORMAT_XBGR2101010;
// case SPA_VIDEO_FORMAT_ARGB_210LE: return DRM_FORMAT_ARGB2101010; case SPA_VIDEO_FORMAT_ARGB_210LE: return DRM_FORMAT_ARGB2101010;
// case SPA_VIDEO_FORMAT_ABGR_210LE: return DRM_FORMAT_ABGR2101010; case SPA_VIDEO_FORMAT_ABGR_210LE: return DRM_FORMAT_ABGR2101010;
#endif #endif
default: break; default: break;
} }
@@ -374,24 +374,24 @@ static int64_t spa_video_format_to_drm_format(const enum spa_video_format format
#if PW_CHECK_VERSION(0, 3, 41) #if PW_CHECK_VERSION(0, 3, 41)
#define GSR_PIPEWIRE_VIDEO_NUM_VIDEO_FORMATS GSR_PIPEWIRE_VIDEO_MAX_VIDEO_FORMATS #define GSR_PIPEWIRE_VIDEO_NUM_VIDEO_FORMATS GSR_PIPEWIRE_VIDEO_MAX_VIDEO_FORMATS
#else #else
#define GSR_PIPEWIRE_VIDEO_NUM_VIDEO_FORMATS 4 #define GSR_PIPEWIRE_VIDEO_NUM_VIDEO_FORMATS 8
#endif #endif
static const enum spa_video_format video_formats[GSR_PIPEWIRE_VIDEO_MAX_VIDEO_FORMATS] = { static const enum spa_video_format video_formats[GSR_PIPEWIRE_VIDEO_MAX_VIDEO_FORMATS] = {
// SPA_VIDEO_FORMAT_BGRA,
SPA_VIDEO_FORMAT_BGRx, SPA_VIDEO_FORMAT_BGRx,
SPA_VIDEO_FORMAT_BGR, SPA_VIDEO_FORMAT_BGR,
SPA_VIDEO_FORMAT_RGBx, SPA_VIDEO_FORMAT_RGBx,
// SPA_VIDEO_FORMAT_RGBA,
SPA_VIDEO_FORMAT_RGB, SPA_VIDEO_FORMAT_RGB,
// SPA_VIDEO_FORMAT_ARGB,
// SPA_VIDEO_FORMAT_ABGR,
#if PW_CHECK_VERSION(0, 3, 41) #if PW_CHECK_VERSION(0, 3, 41)
SPA_VIDEO_FORMAT_xRGB_210LE, SPA_VIDEO_FORMAT_xRGB_210LE,
SPA_VIDEO_FORMAT_xBGR_210LE, SPA_VIDEO_FORMAT_xBGR_210LE,
// SPA_VIDEO_FORMAT_ARGB_210LE, SPA_VIDEO_FORMAT_ARGB_210LE,
// SPA_VIDEO_FORMAT_ABGR_210LE SPA_VIDEO_FORMAT_ABGR_210LE,
#endif #endif
SPA_VIDEO_FORMAT_RGBA,
SPA_VIDEO_FORMAT_BGRA,
SPA_VIDEO_FORMAT_ARGB,
SPA_VIDEO_FORMAT_ABGR,
}; };
static bool gsr_pipewire_video_build_format_params(gsr_pipewire_video *self, struct spa_pod_builder *pod_builder, struct spa_pod **params, uint32_t *num_params) { static bool gsr_pipewire_video_build_format_params(gsr_pipewire_video *self, struct spa_pod_builder *pod_builder, struct spa_pod **params, uint32_t *num_params) {
@@ -446,6 +446,8 @@ static bool spa_video_format_get_modifiers(gsr_pipewire_video *self, const enum
//modifiers[0] = DRM_FORMAT_MOD_LINEAR; //modifiers[0] = DRM_FORMAT_MOD_LINEAR;
//modifiers[1] = DRM_FORMAT_MOD_INVALID; //modifiers[1] = DRM_FORMAT_MOD_INVALID;
//*num_modifiers = 2; //*num_modifiers = 2;
modifiers[0] = DRM_FORMAT_MOD_INVALID;
*num_modifiers = 1;
return false; return false;
} }
@@ -460,7 +462,8 @@ static bool spa_video_format_get_modifiers(gsr_pipewire_video *self, const enum
//modifiers[0] = DRM_FORMAT_MOD_LINEAR; //modifiers[0] = DRM_FORMAT_MOD_LINEAR;
//modifiers[1] = DRM_FORMAT_MOD_INVALID; //modifiers[1] = DRM_FORMAT_MOD_INVALID;
//*num_modifiers = 2; //*num_modifiers = 2;
*num_modifiers = 0; modifiers[0] = DRM_FORMAT_MOD_INVALID;
*num_modifiers = 1;
return false; return false;
} }
@@ -730,9 +733,9 @@ static EGLImage gsr_pipewire_video_create_egl_image_with_fallback(gsr_pipewire_v
if(self->no_modifiers_fallback) { if(self->no_modifiers_fallback) {
image = gsr_pipewire_video_create_egl_image(self, fds, offsets, pitches, modifiers, false); image = gsr_pipewire_video_create_egl_image(self, fds, offsets, pitches, modifiers, false);
} else { } else {
image = gsr_pipewire_video_create_egl_image(self, fds, offsets, pitches, modifiers, self->format.info.raw.modifier != 0); image = gsr_pipewire_video_create_egl_image(self, fds, offsets, pitches, modifiers, true);
if(!image) { if(!image) {
if(self->renegotiated) { if(self->renegotiated || self->format.info.raw.modifier == DRM_FORMAT_MOD_INVALID) {
fprintf(stderr, "gsr error: gsr_pipewire_video_create_egl_image_with_fallback: failed to create egl image with modifiers, trying without modifiers\n"); fprintf(stderr, "gsr error: gsr_pipewire_video_create_egl_image_with_fallback: failed to create egl image with modifiers, trying without modifiers\n");
self->no_modifiers_fallback = true; self->no_modifiers_fallback = true;
image = gsr_pipewire_video_create_egl_image(self, fds, offsets, pitches, modifiers, false); image = gsr_pipewire_video_create_egl_image(self, fds, offsets, pitches, modifiers, false);