diff options
Diffstat (limited to 'src/utils.c')
-rw-r--r-- | src/utils.c | 185 |
1 files changed, 76 insertions, 109 deletions
diff --git a/src/utils.c b/src/utils.c index be5e58b..f053eed 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1,4 +1,5 @@ #include "../include/utils.h" +#include "../include/window/window.h" #include <time.h> #include <string.h> @@ -47,16 +48,6 @@ bool generate_random_characters_standard_alphabet(char *buffer, int buffer_size) return generate_random_characters(buffer, buffer_size, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 62); } -static gsr_monitor_rotation wayland_transform_to_gsr_rotation(int32_t rot) { - switch(rot) { - case 0: return GSR_MONITOR_ROT_0; - case 1: return GSR_MONITOR_ROT_90; - case 2: return GSR_MONITOR_ROT_180; - case 3: return GSR_MONITOR_ROT_270; - } - return GSR_MONITOR_ROT_0; -} - static const XRRModeInfo* get_mode_info(const XRRScreenResources *sr, RRMode id) { for(int i = 0; i < sr->nmode; ++i) { if(sr->modes[i].id == id) @@ -146,31 +137,22 @@ void for_each_active_monitor_output_x11_not_cached(Display *display, active_moni XRRFreeScreenResources(screen_res); } -void for_each_active_monitor_output_x11(const gsr_egl *egl, active_monitor_callback callback, void *userdata) { - for(int i = 0; i < egl->x11.num_outputs; ++i) { - const gsr_x11_output *output = &egl->x11.outputs[i]; - const gsr_monitor monitor = { - .name = output->name, - .name_len = strlen(output->name), - .pos = output->pos, - .size = output->size, - .connector_id = output->connector_id, - .rotation = output->rotation, - .monitor_identifier = output->monitor_identifier - }; - callback(&monitor, userdata); - } +/* TODO: Support more connector types */ +int get_connector_type_by_name(const char *name) { + int len = strlen(name); + if(len >= 5 && strncmp(name, "HDMI-", 5) == 0) + return 1; + else if(len >= 3 && strncmp(name, "DP-", 3) == 0) + return 2; + else if(len >= 12 && strncmp(name, "DisplayPort-", 12) == 0) + return 3; + else if(len >= 4 && strncmp(name, "eDP-", 4) == 0) + return 4; + else + return -1; } -typedef struct { - int type; - int count; - int count_active; -} drm_connector_type_count; - -#define CONNECTOR_TYPE_COUNTS 32 - -static drm_connector_type_count* drm_connector_types_get_index(drm_connector_type_count *type_counts, int *num_type_counts, int connector_type) { +drm_connector_type_count* drm_connector_types_get_index(drm_connector_type_count *type_counts, int *num_type_counts, int connector_type) { for(int i = 0; i < *num_type_counts; ++i) { if(type_counts[i].type == connector_type) return &type_counts[i]; @@ -187,6 +169,10 @@ static drm_connector_type_count* drm_connector_types_get_index(drm_connector_typ return &type_counts[index]; } +uint32_t monitor_identifier_from_type_and_count(int monitor_type_index, int monitor_type_count) { + return ((uint32_t)monitor_type_index << 16) | ((uint32_t)monitor_type_count); +} + static bool connector_get_property_by_name(int drmfd, drmModeConnectorPtr props, const char *name, uint64_t *result) { for(int i = 0; i < props->count_props; ++i) { drmModePropertyPtr prop = drmModeGetProperty(drmfd, props->props[i]); @@ -202,61 +188,12 @@ static bool connector_get_property_by_name(int drmfd, drmModeConnectorPtr props, return false; } -/* TODO: Support more connector types */ -static int get_connector_type_by_name(const char *name) { - int len = strlen(name); - if(len >= 5 && strncmp(name, "HDMI-", 5) == 0) - return 1; - else if(len >= 3 && strncmp(name, "DP-", 3) == 0) - return 2; - else if(len >= 12 && strncmp(name, "DisplayPort-", 12) == 0) - return 3; - else if(len >= 4 && strncmp(name, "eDP-", 4) == 0) - return 4; - else - return -1; -} - -static uint32_t monitor_identifier_from_type_and_count(int monitor_type_index, int monitor_type_count) { - return ((uint32_t)monitor_type_index << 16) | ((uint32_t)monitor_type_count); -} - -static void for_each_active_monitor_output_wayland(const gsr_egl *egl, active_monitor_callback callback, void *userdata) { - drm_connector_type_count type_counts[CONNECTOR_TYPE_COUNTS]; - int num_type_counts = 0; - - for(int i = 0; i < egl->wayland.num_outputs; ++i) { - const gsr_wayland_output *output = &egl->wayland.outputs[i]; - if(!output->name) - continue; - - const int connector_type_index = get_connector_type_by_name(output->name); - drm_connector_type_count *connector_type = NULL; - if(connector_type_index != -1) - connector_type = drm_connector_types_get_index(type_counts, &num_type_counts, connector_type_index); - - if(connector_type) { - ++connector_type->count; - ++connector_type->count_active; - } - - const gsr_monitor monitor = { - .name = output->name, - .name_len = strlen(output->name), - .pos = { .x = output->pos.x, .y = output->pos.y }, - .size = { .x = output->size.x, .y = output->size.y }, - .connector_id = 0, - .rotation = wayland_transform_to_gsr_rotation(output->transform), - .monitor_identifier = connector_type ? monitor_identifier_from_type_and_count(connector_type_index, connector_type->count_active) : 0 - }; - callback(&monitor, userdata); - } -} - -static void for_each_active_monitor_output_drm(const gsr_egl *egl, active_monitor_callback callback, void *userdata) { - int fd = open(egl->card_path, O_RDONLY); - if(fd == -1) +static void for_each_active_monitor_output_drm(const char *card_path, active_monitor_callback callback, void *userdata) { + int fd = open(card_path, O_RDONLY); + if(fd == -1) { + fprintf(stderr, "gsr error: for_each_active_monitor_output_drm failed, failed to open \"%s\", error: %s\n", card_path, strerror(errno)); return; + } drmSetClientCap(fd, DRM_CLIENT_CAP_ATOMIC, 1); @@ -315,16 +252,14 @@ static void for_each_active_monitor_output_drm(const gsr_egl *egl, active_monito close(fd); } -void for_each_active_monitor_output(const gsr_egl *egl, gsr_connection_type connection_type, active_monitor_callback callback, void *userdata) { +void for_each_active_monitor_output(const gsr_window *window, const char *card_path, gsr_connection_type connection_type, active_monitor_callback callback, void *userdata) { switch(connection_type) { case GSR_CONNECTION_X11: - for_each_active_monitor_output_x11(egl, callback, userdata); - break; case GSR_CONNECTION_WAYLAND: - for_each_active_monitor_output_wayland(egl, callback, userdata); + gsr_window_for_each_active_monitor_output_cached(window, callback, userdata); break; case GSR_CONNECTION_DRM: - for_each_active_monitor_output_drm(egl, callback, userdata); + for_each_active_monitor_output_drm(card_path, callback, userdata); break; } } @@ -347,13 +282,14 @@ bool get_monitor_by_name(const gsr_egl *egl, gsr_connection_type connection_type userdata.name_len = strlen(name); userdata.monitor = monitor; userdata.found_monitor = false; - for_each_active_monitor_output(egl, connection_type, get_monitor_by_name_callback, &userdata); + for_each_active_monitor_output(egl->window, egl->card_path, connection_type, get_monitor_by_name_callback, &userdata); return userdata.found_monitor; } typedef struct { const gsr_monitor *monitor; gsr_monitor_rotation rotation; + vec2i position; bool match_found; } get_monitor_by_connector_id_userdata; @@ -365,6 +301,7 @@ static void get_monitor_by_name_and_size_callback(const gsr_monitor *monitor, vo get_monitor_by_connector_id_userdata *data = (get_monitor_by_connector_id_userdata*)userdata; if(monitor->name && data->monitor->name && strcmp(monitor->name, data->monitor->name) == 0 && vec2i_eql(monitor->size, data->monitor->size)) { data->rotation = monitor->rotation; + data->position = monitor->pos; data->match_found = true; } } @@ -375,39 +312,51 @@ static void get_monitor_by_connector_id_callback(const gsr_monitor *monitor, voi (!monitor->connector_id && monitor->monitor_identifier == data->monitor->monitor_identifier)) { data->rotation = monitor->rotation; + data->position = monitor->pos; data->match_found = true; } } -gsr_monitor_rotation drm_monitor_get_display_server_rotation(const gsr_egl *egl, const gsr_monitor *monitor) { - if(gsr_egl_get_display_server(egl) == GSR_DISPLAY_SERVER_WAYLAND) { +bool drm_monitor_get_display_server_data(const gsr_window *window, const gsr_monitor *monitor, gsr_monitor_rotation *monitor_rotation, vec2i *monitor_position) { + *monitor_rotation = GSR_MONITOR_ROT_0; + *monitor_position = (vec2i){0, 0}; + + if(gsr_window_get_display_server(window) == GSR_DISPLAY_SERVER_WAYLAND) { { get_monitor_by_connector_id_userdata userdata; userdata.monitor = monitor; userdata.rotation = GSR_MONITOR_ROT_0; + userdata.position = (vec2i){0, 0}; userdata.match_found = false; - for_each_active_monitor_output_wayland(egl, get_monitor_by_name_and_size_callback, &userdata); - if(userdata.match_found) - return userdata.rotation; + gsr_window_for_each_active_monitor_output_cached(window, get_monitor_by_name_and_size_callback, &userdata); + if(userdata.match_found) { + *monitor_rotation = userdata.rotation; + *monitor_position = userdata.position; + return true; + } } { get_monitor_by_connector_id_userdata userdata; userdata.monitor = monitor; userdata.rotation = GSR_MONITOR_ROT_0; + userdata.position = (vec2i){0, 0}; userdata.match_found = false; - for_each_active_monitor_output_wayland(egl, get_monitor_by_connector_id_callback, &userdata); - return userdata.rotation; + gsr_window_for_each_active_monitor_output_cached(window, get_monitor_by_connector_id_callback, &userdata); + *monitor_rotation = userdata.rotation; + *monitor_position = userdata.position; + return userdata.match_found; } } else { get_monitor_by_connector_id_userdata userdata; userdata.monitor = monitor; userdata.rotation = GSR_MONITOR_ROT_0; + userdata.position = (vec2i){0, 0}; userdata.match_found = false; - for_each_active_monitor_output_x11(egl, get_monitor_by_connector_id_callback, &userdata); - return userdata.rotation; + gsr_window_for_each_active_monitor_output_cached(window, get_monitor_by_connector_id_callback, &userdata); + *monitor_rotation = userdata.rotation; + *monitor_position = userdata.position; + return userdata.match_found; } - - return GSR_MONITOR_ROT_0; } bool gl_get_gpu_info(gsr_egl *egl, gsr_gpu_info *info) { @@ -478,15 +427,15 @@ bool gl_get_gpu_info(gsr_egl *egl, gsr_gpu_info *info) { return supported; } -static bool version_greater_than(int major, int minor, int patch, int other_major, int other_minor, int other_patch) { +bool version_greater_than(int major, int minor, int patch, int other_major, int other_minor, int other_patch) { return (major > other_major) || (major == other_major && minor > other_minor) || (major == other_major && minor == other_minor && patch > other_patch); } -bool gl_driver_version_greater_than(const gsr_egl *egl, int major, int minor, int patch) { - return version_greater_than(egl->gpu_info.driver_major, egl->gpu_info.driver_minor, egl->gpu_info.driver_patch, major, minor, patch); +bool gl_driver_version_greater_than(const gsr_gpu_info *gpu_info, int major, int minor, int patch) { + return version_greater_than(gpu_info->driver_major, gpu_info->driver_minor, gpu_info->driver_patch, major, minor, patch); } -static bool try_card_has_valid_plane(const char *card_path) { +bool try_card_has_valid_plane(const char *card_path) { drmVersion *ver = NULL; drmModePlaneResPtr planes = NULL; bool found_screen_card = false; @@ -700,9 +649,12 @@ static VADisplay video_codec_context_get_vaapi_display(AVCodecContext *video_cod } bool video_codec_context_is_vaapi(AVCodecContext *video_codec_context) { + if(!video_codec_context) + return false; + AVBufferRef *hw_frames_ctx = video_codec_context->hw_frames_ctx; if(!hw_frames_ctx) - return NULL; + return false; AVHWFramesContext *hw_frame_context = (AVHWFramesContext*)hw_frames_ctx->data; AVHWDeviceContext *device_context = (AVHWDeviceContext*)hw_frame_context->device_ctx; @@ -960,3 +912,18 @@ vec2i scale_keep_aspect_ratio(vec2i from, vec2i to) { return from; } + +unsigned int gl_create_texture(gsr_egl *egl, int width, int height, int internal_format, unsigned int format, int filter) { + unsigned int texture_id = 0; + egl->glGenTextures(1, &texture_id); + egl->glBindTexture(GL_TEXTURE_2D, texture_id); + egl->glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, format, GL_UNSIGNED_BYTE, NULL); + + egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); + egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); + + egl->glBindTexture(GL_TEXTURE_2D, 0); + return texture_id; +} |