aboutsummaryrefslogtreecommitdiff
path: root/src/capture/kms_cuda.c
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2024-02-10 02:47:01 +0100
committerdec05eba <dec05eba@protonmail.com>2024-02-10 03:48:43 +0100
commitb8843395acd03520b7630b6a1dc19f151f42382d (patch)
treef8da6cf22229ba44916de608c9bb46bfddcd8e79 /src/capture/kms_cuda.c
parentac73d9cb13ea7e4694b6b013de426cefddae4ca7 (diff)
Add screen rotation support (tested on amd/intel)
screen rotation in wayland is best effort, wayland doesn't give the necessary information to make it robust.
Diffstat (limited to 'src/capture/kms_cuda.c')
-rw-r--r--src/capture/kms_cuda.c64
1 files changed, 59 insertions, 5 deletions
diff --git a/src/capture/kms_cuda.c b/src/capture/kms_cuda.c
index f5b96a8..f9a6a11 100644
--- a/src/capture/kms_cuda.c
+++ b/src/capture/kms_cuda.c
@@ -50,6 +50,8 @@ typedef struct {
unsigned int target_texture;
gsr_color_conversion color_conversion;
+
+ gsr_monitor_rotation monitor_rotation;
} gsr_capture_kms_cuda;
static int max_int(int a, int b) {
@@ -162,8 +164,16 @@ static int gsr_capture_kms_cuda_start(gsr_capture *cap, AVCodecContext *video_co
return -1;
}
+ monitor.name = cap_kms->params.display_to_capture;
+ cap_kms->monitor_rotation = drm_monitor_get_display_server_rotation(cap_kms->params.egl, &monitor);
+
cap_kms->capture_pos = monitor.pos;
- cap_kms->capture_size = monitor.size;
+ if(cap_kms->monitor_rotation == GSR_MONITOR_ROT_90 || cap_kms->monitor_rotation == GSR_MONITOR_ROT_270) {
+ cap_kms->capture_size.x = monitor.size.y;
+ cap_kms->capture_size.y = monitor.size.x;
+ } else {
+ cap_kms->capture_size = monitor.size;
+ }
video_codec_context->width = max_int(2, cap_kms->capture_size.x & ~1);
video_codec_context->height = max_int(2, cap_kms->capture_size.y & ~1);
@@ -316,6 +326,16 @@ static bool gsr_capture_kms_cuda_should_stop(gsr_capture *cap, bool *err) {
return false;
}
+static float monitor_rotation_to_radians(gsr_monitor_rotation rot) {
+ switch(rot) {
+ case GSR_MONITOR_ROT_0: return 0.0f;
+ case GSR_MONITOR_ROT_90: return M_PI_2;
+ case GSR_MONITOR_ROT_180: return M_PI;
+ case GSR_MONITOR_ROT_270: return M_PI + M_PI_2;
+ }
+ return 0.0f;
+}
+
/* Prefer non combined planes */
static gsr_kms_response_fd* find_drm_by_connector_id(gsr_kms_response *kms_response, uint32_t connector_id) {
int index_combined = -1;
@@ -381,6 +401,13 @@ static gsr_kms_response_fd* find_cursor_drm(gsr_kms_response *kms_response) {
return NULL;
}
+static vec2i swap_vec2i(vec2i value) {
+ int tmp = value.x;
+ value.x = value.y;
+ value.y = tmp;
+ return value;
+}
+
static int gsr_capture_kms_cuda_capture(gsr_capture *cap, AVFrame *frame) {
(void)frame;
gsr_capture_kms_cuda *cap_kms = cap->priv;
@@ -457,12 +484,40 @@ static int gsr_capture_kms_cuda_capture(gsr_capture *cap, AVFrame *frame) {
if(!capture_is_combined_plane)
capture_pos = (vec2i){drm_fd->x, drm_fd->y};
+ const float texture_rotation = monitor_rotation_to_radians(cap_kms->monitor_rotation);
+
gsr_color_conversion_draw(&cap_kms->color_conversion, cap_kms->input_texture,
(vec2i){0, 0}, cap_kms->capture_size,
capture_pos, cap_kms->capture_size,
- 0.0f, false);
+ texture_rotation, false);
if(cursor_drm_fd) {
+ const vec2i cursor_size = {cursor_drm_fd->width, cursor_drm_fd->height};
+ vec2i cursor_pos = {cursor_drm_fd->x, cursor_drm_fd->y};
+ switch(cap_kms->monitor_rotation) {
+ case GSR_MONITOR_ROT_0:
+ break;
+ case GSR_MONITOR_ROT_90:
+ cursor_pos = swap_vec2i(cursor_pos);
+ cursor_pos.x = cap_kms->capture_size.x - cursor_pos.x;
+ // TODO: Remove this horrible hack
+ cursor_pos.x -= cursor_size.x;
+ break;
+ case GSR_MONITOR_ROT_180:
+ cursor_pos.x = cap_kms->capture_size.x - cursor_pos.x;
+ cursor_pos.y = cap_kms->capture_size.y - cursor_pos.y;
+ // TODO: Remove this horrible hack
+ cursor_pos.x -= cursor_size.x;
+ cursor_pos.y -= cursor_size.y;
+ break;
+ case GSR_MONITOR_ROT_270:
+ cursor_pos = swap_vec2i(cursor_pos);
+ cursor_pos.y = cap_kms->capture_size.y - cursor_pos.y;
+ // TODO: Remove this horrible hack
+ cursor_pos.y -= cursor_size.y;
+ break;
+ }
+
const intptr_t img_attr_cursor[] = {
EGL_LINUX_DRM_FOURCC_EXT, cursor_drm_fd->pixel_format,
EGL_WIDTH, cursor_drm_fd->width,
@@ -481,11 +536,10 @@ static int gsr_capture_kms_cuda_capture(gsr_capture *cap, AVFrame *frame) {
cap_kms->params.egl->eglDestroyImage(cap_kms->params.egl->egl_display, cursor_image);
cap_kms->params.egl->glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
- vec2i cursor_size = {cursor_drm_fd->width, cursor_drm_fd->height};
gsr_color_conversion_draw(&cap_kms->color_conversion, cap_kms->cursor_texture,
- (vec2i){cursor_drm_fd->x, cursor_drm_fd->y}, cursor_size,
+ cursor_pos, cursor_size,
(vec2i){0, 0}, cursor_size,
- 0.0f, true);
+ texture_rotation, true);
}
cap_kms->params.egl->eglSwapBuffers(cap_kms->params.egl->egl_display, cap_kms->params.egl->egl_surface);