RetroArch/gfx/video_thread_wrapper.h
Viačasłaŭ Chalikin 9ad2cc2bc6
Fix crash when using threaded video (#16518)
for Mesa 23.2 and later
2024-05-13 07:24:51 -07:00

279 lines
6.0 KiB
C

/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef RARCH_VIDEO_THREAD_H__
#define RARCH_VIDEO_THREAD_H__
#include <limits.h>
#include <boolean.h>
#include <retro_common_api.h>
#include <rthreads/rthreads.h>
#include <retro_miscellaneous.h>
#include "font_driver.h"
RETRO_BEGIN_DECLS
enum thread_cmd
{
CMD_VIDEO_NONE = 0,
CMD_INIT,
CMD_SET_SHADER,
CMD_FREE,
CMD_ALIVE, /* Blocking alive check. Used when paused. */
CMD_SET_VIEWPORT,
CMD_SET_ROTATION,
CMD_READ_VIEWPORT,
CMD_OVERLAY_ENABLE,
CMD_OVERLAY_LOAD,
CMD_OVERLAY_TEX_GEOM,
CMD_OVERLAY_VERTEX_GEOM,
CMD_OVERLAY_FULL_SCREEN,
CMD_POKE_SET_VIDEO_MODE,
CMD_POKE_SET_FILTERING,
CMD_POKE_SET_FBO_STATE,
CMD_POKE_GET_FBO_STATE,
CMD_POKE_SET_ASPECT_RATIO,
CMD_FONT_INIT,
CMD_CUSTOM_COMMAND,
CMD_POKE_SHOW_MOUSE,
CMD_POKE_GRAB_MOUSE_TOGGLE,
CMD_POKE_SET_HDR_MAX_NITS,
CMD_POKE_SET_HDR_PAPER_WHITE_NITS,
CMD_POKE_SET_HDR_CONTRAST,
CMD_POKE_SET_HDR_EXPAND_GAMUT,
CMD_DUMMY = INT_MAX
};
typedef int (*custom_command_method_t)(void*);
typedef bool (*custom_font_command_method_t)(const void **font_driver,
void **font_handle, void *video_data, const char *font_path,
float font_size, enum font_driver_render_api api,
bool is_threaded);
typedef struct thread_packet
{
union
{
const char *str;
void *v;
int i;
float f;
bool b;
struct
{
enum rarch_shader_type type;
const char *path;
} set_shader;
struct
{
unsigned width;
unsigned height;
bool force_full;
bool allow_rotate;
} set_viewport;
struct
{
unsigned index;
float x, y, w, h;
} rect;
struct
{
const struct texture_image *data;
unsigned num;
} image;
struct
{
unsigned width;
unsigned height;
} output;
struct
{
unsigned width;
unsigned height;
bool fullscreen;
} new_mode;
struct
{
unsigned index;
bool smooth;
bool ctx_scaling;
} filtering;
struct
{
char msg[128];
struct font_params params;
} osd_message;
struct
{
custom_command_method_t method;
void* data;
int return_value;
} custom_command;
struct
{
custom_font_command_method_t method;
const void **font_driver;
void **font_handle;
void *video_data;
const char *font_path;
float font_size;
bool return_value;
bool is_threaded;
enum font_driver_render_api api;
} font_init;
struct
{
float max_nits;
float paper_white_nits;
float contrast;
bool expand_gamut;
} hdr;
} data;
enum thread_cmd type;
} thread_packet_t;
typedef struct thread_video
{
retro_time_t last_time;
slock_t *lock;
scond_t *cond_cmd;
scond_t *cond_thread;
sthread_t *thread;
video_info_t info;
const video_driver_t *driver;
#ifdef HAVE_OVERLAY
const video_overlay_interface_t *overlay;
#endif
const video_poke_interface_t *poke;
void *driver_data;
input_driver_t **input;
void **input_data;
float *alpha_mod;
slock_t *alpha_lock;
struct
{
void *frame;
size_t frame_cap;
unsigned width;
unsigned height;
float alpha;
bool frame_updated;
bool rgb32;
bool enable;
bool full_screen;
} texture;
unsigned hit_count;
unsigned miss_count;
unsigned alpha_mods;
struct video_viewport vp;
struct video_viewport read_vp; /* Last viewport reported to caller. */
thread_packet_t cmd_data;
video_driver_t video_thread;
enum thread_cmd send_cmd;
enum thread_cmd reply_cmd;
bool alpha_update;
struct
{
uint64_t count;
slock_t *lock;
uint8_t *buffer;
unsigned width;
unsigned height;
unsigned pitch;
char msg[NAME_MAX_LENGTH];
bool updated;
bool within_thread;
} frame;
bool apply_state_changes;
bool alive;
bool focus;
bool suppress_screensaver;
bool has_windowed;
bool nonblock;
bool is_idle;
} thread_video_t;
/**
* video_init_thread:
* @out_driver : Output video driver
* @out_data : Output video data
* @input : Input input driver
* @input_data : Input input data
* @driver : Input Video driver
* @info : Video info handle.
*
* Creates, initializes and starts a video driver in a new thread.
* Access to video driver will be mediated through this driver.
*
* Returns: true (1) if successful, otherwise false (0).
**/
bool video_init_thread(
const video_driver_t **out_driver, void **out_data,
input_driver_t **input, void **input_data,
const video_driver_t *driver, const video_info_t info);
bool video_thread_font_init(
const void **font_driver,
void **font_handle,
void *data,
const char *font_path,
float font_size,
enum font_driver_render_api api,
custom_font_command_method_t func,
bool is_threaded);
unsigned video_thread_texture_handle(void *data,
custom_command_method_t func);
RETRO_END_DECLS
#endif