(video_thread_wrapper) For threaded/audio video wrapper we will use

bools instead of flags
This commit is contained in:
libretroadmin 2022-11-18 20:42:47 +01:00
parent 63a080af3f
commit 8976a179df
2 changed files with 71 additions and 113 deletions

View File

@ -96,28 +96,24 @@ static void video_thread_send_and_wait_user_to_thread(thread_video_t *thr, threa
static void thread_update_driver_state(thread_video_t *thr) static void thread_update_driver_state(thread_video_t *thr)
{ {
#ifdef HAVE_MENU #ifdef HAVE_MENU
if (thr->flags & THR_FLAG_TEXTURE_FRAME_UPDATED) if (thr->texture.frame_updated)
{ {
if (thr->driver_data && thr->poke && thr->poke->set_texture_frame) if (thr->driver_data && thr->poke && thr->poke->set_texture_frame)
thr->poke->set_texture_frame(thr->driver_data, thr->poke->set_texture_frame(thr->driver_data,
thr->texture.frame, thr->texture.frame, thr->texture.rgb32,
thr->flags & THR_FLAG_TEXTURE_RGB32, thr->texture.width, thr->texture.height,
thr->texture.width,
thr->texture.height,
thr->texture.alpha); thr->texture.alpha);
thr->flags &= ~THR_FLAG_TEXTURE_FRAME_UPDATED; thr->texture.frame_updated = false;
} }
if (thr->driver_data && thr->poke && thr->poke->set_texture_enable) if (thr->driver_data && thr->poke && thr->poke->set_texture_enable)
thr->poke->set_texture_enable( thr->poke->set_texture_enable(thr->driver_data,
thr->driver_data, thr->texture.enable, thr->texture.full_screen);
thr->flags & THR_FLAG_TEXTURE_ENABLE,
thr->flags & THR_FLAG_TEXTURE_FULLSCREEN);
#endif #endif
#ifdef HAVE_OVERLAY #ifdef HAVE_OVERLAY
slock_lock(thr->alpha_lock); slock_lock(thr->alpha_lock);
if (thr->flags & THR_FLAG_ALPHA_UPDATE) if (thr->alpha_update)
{ {
if (thr->driver_data && thr->overlay && thr->overlay->set_alpha) if (thr->driver_data && thr->overlay && thr->overlay->set_alpha)
{ {
@ -125,16 +121,16 @@ static void thread_update_driver_state(thread_video_t *thr)
for (i = 0; i < (int)thr->alpha_mods; i++) for (i = 0; i < (int)thr->alpha_mods; i++)
thr->overlay->set_alpha(thr->driver_data, i, thr->alpha_mod[i]); thr->overlay->set_alpha(thr->driver_data, i, thr->alpha_mod[i]);
} }
thr->flags &= ~THR_FLAG_ALPHA_UPDATE; thr->alpha_update = false;
} }
slock_unlock(thr->alpha_lock); slock_unlock(thr->alpha_lock);
#endif #endif
if (thr->flags & THR_FLAG_APPLY_STATE_CHANGES) if (thr->apply_state_changes)
{ {
if (thr->driver_data && thr->poke && thr->poke->apply_state_changes) if (thr->driver_data && thr->poke && thr->poke->apply_state_changes)
thr->poke->apply_state_changes(thr->driver_data); thr->poke->apply_state_changes(thr->driver_data);
thr->flags &= ~THR_FLAG_APPLY_STATE_CHANGES; thr->apply_state_changes = false;
} }
} }
@ -202,12 +198,10 @@ static bool video_thread_handle_packet(
* *
* To avoid this, set a flag so wrapper can see if * To avoid this, set a flag so wrapper can see if
* it's called in this "special" way. */ * it's called in this "special" way. */
thr->flags |= THR_FLAG_FRAME_WITHIN_THREAD; thr->frame.within_thread = true;
pkt.data.b = thr->driver->read_viewport( pkt.data.b = thr->driver->read_viewport(thr->driver_data,
thr->driver_data, (uint8_t*)pkt.data.v, thr->is_idle);
(uint8_t*)pkt.data.v, thr->frame.within_thread = false;
thr->flags & THR_FLAG_IS_IDLE);
thr->flags &= ~THR_FLAG_FRAME_WITHIN_THREAD;
} }
else else
{ {
@ -424,11 +418,10 @@ static void video_thread_loop(void *data)
for (;;) for (;;)
{ {
slock_lock(thr->lock); slock_lock(thr->lock);
while ( thr->send_cmd == CMD_VIDEO_NONE while (thr->send_cmd == CMD_VIDEO_NONE && !thr->frame.updated)
&& (!(thr->flags & THR_FLAG_FRAME_UPDATED)))
scond_wait(thr->cond_thread, thr->lock); scond_wait(thr->cond_thread, thr->lock);
updated = ((thr->flags & THR_FLAG_FRAME_UPDATED) > 0); updated = thr->frame.updated;
/* To avoid race condition where send_cmd is updated /* To avoid race condition where send_cmd is updated
* right after the switch is checked. */ * right after the switch is checked. */
@ -496,20 +489,11 @@ static void video_thread_loop(void *data)
slock_unlock(thr->frame.lock); slock_unlock(thr->frame.lock);
slock_lock(thr->lock); slock_lock(thr->lock);
thr->alive = alive;
thr->focus = focus;
thr->has_windowed = has_windowed;
thr->vp = vp; thr->vp = vp;
if (alive) thr->frame.updated = false;
thr->flags |= THR_FLAG_ALIVE;
else
thr->flags &= ~THR_FLAG_ALIVE;
if (focus)
thr->flags |= THR_FLAG_FOCUS;
else
thr->flags &= ~THR_FLAG_FOCUS;
if (has_windowed)
thr->flags |= THR_FLAG_HAS_WINDOWED;
else
thr->flags &= ~THR_FLAG_HAS_WINDOWED;
thr->flags &= ~THR_FLAG_FRAME_UPDATED;
scond_signal(thr->cond_cmd); scond_signal(thr->cond_cmd);
slock_unlock(thr->lock); slock_unlock(thr->lock);
} }
@ -518,8 +502,8 @@ static void video_thread_loop(void *data)
static bool video_thread_alive(void *data) static bool video_thread_alive(void *data)
{ {
bool ret;
uint32_t runloop_flags; uint32_t runloop_flags;
bool ret = false;
thread_video_t *thr = (thread_video_t*)data; thread_video_t *thr = (thread_video_t*)data;
if (!thr) if (!thr)
@ -538,8 +522,7 @@ static bool video_thread_alive(void *data)
} }
slock_lock(thr->lock); slock_lock(thr->lock);
if (thr->flags & THR_FLAG_ALIVE) ret = thr->alive;
ret = true;
slock_unlock(thr->lock); slock_unlock(thr->lock);
return ret; return ret;
@ -547,15 +530,14 @@ static bool video_thread_alive(void *data)
static bool video_thread_focus(void *data) static bool video_thread_focus(void *data)
{ {
bool ret = false; bool ret;
thread_video_t *thr = (thread_video_t*)data; thread_video_t *thr = (thread_video_t*)data;
if (!thr) if (!thr)
return false; return false;
slock_lock(thr->lock); slock_lock(thr->lock);
if (thr->flags & THR_FLAG_FOCUS) ret = thr->focus;
ret = true;
slock_unlock(thr->lock); slock_unlock(thr->lock);
return ret; return ret;
@ -563,15 +545,14 @@ static bool video_thread_focus(void *data)
static bool video_thread_suppress_screensaver(void *data, bool enable) static bool video_thread_suppress_screensaver(void *data, bool enable)
{ {
bool ret = false; bool ret;
thread_video_t *thr = (thread_video_t*)data; thread_video_t *thr = (thread_video_t*)data;
if (!thr) if (!thr)
return false; return false;
slock_lock(thr->lock); slock_lock(thr->lock);
if (thr->flags & THR_FLAG_SUPPRESS_SCREENSAVER) ret = thr->suppress_screensaver;
ret = true;
slock_unlock(thr->lock); slock_unlock(thr->lock);
return ret; return ret;
@ -579,15 +560,14 @@ static bool video_thread_suppress_screensaver(void *data, bool enable)
static bool video_thread_has_windowed(void *data) static bool video_thread_has_windowed(void *data)
{ {
bool ret = false; bool ret;
thread_video_t *thr = (thread_video_t*)data; thread_video_t *thr = (thread_video_t*)data;
if (!thr) if (!thr)
return false; return false;
slock_lock(thr->lock); slock_lock(thr->lock);
if (thr->flags & THR_FLAG_HAS_WINDOWED) ret = thr->has_windowed;
ret = true;
slock_unlock(thr->lock); slock_unlock(thr->lock);
return ret; return ret;
@ -604,7 +584,7 @@ static bool video_thread_frame(void *data, const void *frame_,
/* If called from within read_viewport, we're actually in the /* If called from within read_viewport, we're actually in the
* driver thread, so just render directly. */ * driver thread, so just render directly. */
if (thr->flags & THR_FLAG_FRAME_WITHIN_THREAD) if (thr->frame.within_thread)
{ {
thread_update_driver_state(thr); thread_update_driver_state(thr);
@ -617,14 +597,14 @@ static bool video_thread_frame(void *data, const void *frame_,
slock_lock(thr->lock); slock_lock(thr->lock);
if ((!(thr->flags & THR_FLAG_NONBLOCK))) if (!thr->nonblock)
{ {
retro_time_t target_frame_time = retro_time_t target_frame_time =
(retro_time_t)roundf(1000000 / video_info->refresh_rate); (retro_time_t)roundf(1000000 / video_info->refresh_rate);
retro_time_t target = thr->last_time + target_frame_time; retro_time_t target = thr->last_time + target_frame_time;
/* Ideally, use absolute time, but that is only a good idea on POSIX. */ /* Ideally, use absolute time, but that is only a good idea on POSIX. */
while (thr->flags & THR_FLAG_FRAME_UPDATED) while (thr->frame.updated)
{ {
retro_time_t current = cpu_features_get_time_usec(); retro_time_t current = cpu_features_get_time_usec();
retro_time_t delta = target - current; retro_time_t delta = target - current;
@ -639,7 +619,7 @@ static bool video_thread_frame(void *data, const void *frame_,
/* Drop frame if updated flag is still set, as thread is /* Drop frame if updated flag is still set, as thread is
* still working on last frame. */ * still working on last frame. */
if (!(thr->flags & THR_FLAG_FRAME_UPDATED)) if (!thr->frame.updated)
{ {
const uint8_t *src = (const uint8_t*)frame_; const uint8_t *src = (const uint8_t*)frame_;
uint8_t *dst = thr->frame.buffer; uint8_t *dst = thr->frame.buffer;
@ -653,11 +633,11 @@ static bool video_thread_frame(void *data, const void *frame_,
memcpy(dst, src, copy_stride); memcpy(dst, src, copy_stride);
} }
thr->frame.updated = true;
thr->frame.width = width; thr->frame.width = width;
thr->frame.height = height; thr->frame.height = height;
thr->frame.count = frame_count; thr->frame.count = frame_count;
thr->frame.pitch = copy_stride; thr->frame.pitch = copy_stride;
thr->flags |= THR_FLAG_FRAME_UPDATED;
if (msg) if (msg)
strlcpy(thr->frame.msg, msg, sizeof(thr->frame.msg)); strlcpy(thr->frame.msg, msg, sizeof(thr->frame.msg));
@ -667,12 +647,12 @@ static bool video_thread_frame(void *data, const void *frame_,
scond_signal(thr->cond_thread); scond_signal(thr->cond_thread);
#ifdef HAVE_MENU #ifdef HAVE_MENU
if (thr->flags & THR_FLAG_TEXTURE_ENABLE) if (thr->texture.enable)
{ {
do do
{ {
scond_wait(thr->cond_cmd, thr->lock); scond_wait(thr->cond_cmd, thr->lock);
} while (thr->flags & THR_FLAG_FRAME_UPDATED); } while (thr->frame.updated);
} }
#endif #endif
thr->hit_count++; thr->hit_count++;
@ -694,12 +674,7 @@ static void video_thread_set_nonblock_state(void *data, bool state,
thread_video_t *thr = (thread_video_t*)data; thread_video_t *thr = (thread_video_t*)data;
if (thr) if (thr)
{ thr->nonblock = state;
if (state)
thr->flags |= THR_FLAG_NONBLOCK;
else
thr->flags &= ~THR_FLAG_NONBLOCK;
}
} }
static bool video_thread_init(thread_video_t *thr, static bool video_thread_init(thread_video_t *thr,
@ -739,11 +714,11 @@ static bool video_thread_init(thread_video_t *thr,
thr->input = input; thr->input = input;
thr->input_data = input_data; thr->input_data = input_data;
thr->info = info; thr->info = info;
thr->alive = true;
thr->focus = true;
thr->has_windowed = true;
thr->suppress_screensaver = true;
thr->last_time = cpu_features_get_time_usec(); thr->last_time = cpu_features_get_time_usec();
thr->flags |= THR_FLAG_ALIVE
| THR_FLAG_FOCUS
| THR_FLAG_HAS_WINDOWED
| THR_FLAG_SUPPRESS_SCREENSAVER;
if (!(thr->thread = sthread_create(video_thread_loop, thr))) if (!(thr->thread = sthread_create(video_thread_loop, thr)))
return false; return false;
@ -794,8 +769,8 @@ static void video_thread_set_rotation(void *data, unsigned rotation)
if (thr) if (thr)
{ {
thread_packet_t pkt; thread_packet_t pkt;
pkt.type = CMD_SET_ROTATION; pkt.type = CMD_SET_ROTATION;
pkt.data.i = rotation; pkt.data.i = rotation;
video_thread_send_and_wait_user_to_thread(thr, &pkt); video_thread_send_and_wait_user_to_thread(thr, &pkt);
} }
@ -834,10 +809,7 @@ static bool video_thread_read_viewport(void *data,
pkt.type = CMD_READ_VIEWPORT; pkt.type = CMD_READ_VIEWPORT;
pkt.data.v = buffer; pkt.data.v = buffer;
if (is_idle) thr->is_idle = is_idle;
thr->flags |= THR_FLAG_IS_IDLE;
else
thr->flags &= ~THR_FLAG_IS_IDLE;
video_thread_send_and_wait_user_to_thread(thr, &pkt); video_thread_send_and_wait_user_to_thread(thr, &pkt);
@ -983,7 +955,7 @@ static void thread_overlay_set_alpha(void *data, unsigned idx, float mod)
{ {
slock_lock(thr->alpha_lock); slock_lock(thr->alpha_lock);
thr->alpha_mod[idx] = mod; thr->alpha_mod[idx] = mod;
thr->flags |= THR_FLAG_ALPHA_UPDATE; thr->alpha_update = true;
slock_unlock(thr->alpha_lock); slock_unlock(thr->alpha_lock);
} }
} }
@ -1170,34 +1142,25 @@ static void thread_set_texture_frame(void *data, const void *frame,
memcpy(thr->texture.frame, frame, required); memcpy(thr->texture.frame, frame, required);
thr->texture.width = width; thr->texture.rgb32 = rgb32;
thr->texture.height = height; thr->texture.width = width;
thr->texture.alpha = alpha; thr->texture.height = height;
if (rgb32) thr->texture.alpha = alpha;
thr->flags |= THR_FLAG_TEXTURE_RGB32; thr->texture.frame_updated = true;
else
thr->flags &= ~THR_FLAG_TEXTURE_RGB32;
thr->flags |= THR_FLAG_TEXTURE_FRAME_UPDATED;
end: end:
slock_unlock(thr->frame.lock); slock_unlock(thr->frame.lock);
} }
static void thread_set_texture_enable(void *data, bool state, bool fullscreen) static void thread_set_texture_enable(void *data, bool state, bool full_screen)
{ {
thread_video_t *thr = (thread_video_t*)data; thread_video_t *thr = (thread_video_t*)data;
if (thr) if (thr)
{ {
slock_lock(thr->frame.lock); slock_lock(thr->frame.lock);
if (state) thr->texture.enable = state;
thr->flags |= THR_FLAG_TEXTURE_ENABLE; thr->texture.full_screen = full_screen;
else
thr->flags &= ~THR_FLAG_TEXTURE_ENABLE;
if (fullscreen)
thr->flags |= THR_FLAG_TEXTURE_FULLSCREEN;
else
thr->flags &= ~THR_FLAG_TEXTURE_FULLSCREEN;
slock_unlock(thr->frame.lock); slock_unlock(thr->frame.lock);
} }
} }
@ -1268,7 +1231,7 @@ static void thread_apply_state_changes(void *data)
if (thr) if (thr)
{ {
slock_lock(thr->frame.lock); slock_lock(thr->frame.lock);
thr->flags |= THR_FLAG_APPLY_STATE_CHANGES; thr->apply_state_changes = true;
slock_unlock(thr->frame.lock); slock_unlock(thr->frame.lock);
} }
} }
@ -1343,10 +1306,8 @@ static bool video_thread_wrapper_gfx_widgets_enabled(void *data)
{ {
thread_video_t *thr = (thread_video_t*)data; thread_video_t *thr = (thread_video_t*)data;
if ( thr if (thr && thr->driver_data &&
&& thr->driver_data thr->driver && thr->driver->gfx_widgets_enabled)
&& thr->driver
&& thr->driver->gfx_widgets_enabled)
return thr->driver->gfx_widgets_enabled(thr->driver_data); return thr->driver->gfx_widgets_enabled(thr->driver_data);
return false; return false;

View File

@ -166,24 +166,6 @@ typedef struct thread_packet
enum thread_cmd type; enum thread_cmd type;
} thread_packet_t; } thread_packet_t;
enum thread_video_flags
{
THR_FLAG_APPLY_STATE_CHANGES = (1 << 0),
THR_FLAG_ALIVE = (1 << 1),
THR_FLAG_FOCUS = (1 << 2),
THR_FLAG_SUPPRESS_SCREENSAVER = (1 << 3),
THR_FLAG_HAS_WINDOWED = (1 << 4),
THR_FLAG_NONBLOCK = (1 << 5),
THR_FLAG_IS_IDLE = (1 << 6),
THR_FLAG_ALPHA_UPDATE = (1 << 7),
THR_FLAG_FRAME_WITHIN_THREAD = (1 << 8),
THR_FLAG_FRAME_UPDATED = (1 << 9),
THR_FLAG_TEXTURE_FRAME_UPDATED = (1 << 10),
THR_FLAG_TEXTURE_RGB32 = (1 << 11),
THR_FLAG_TEXTURE_ENABLE = (1 << 12),
THR_FLAG_TEXTURE_FULLSCREEN = (1 << 13)
};
typedef struct thread_video typedef struct thread_video
{ {
retro_time_t last_time; retro_time_t last_time;
@ -215,6 +197,10 @@ typedef struct thread_video
unsigned width; unsigned width;
unsigned height; unsigned height;
float alpha; float alpha;
bool frame_updated;
bool rgb32;
bool enable;
bool full_screen;
} texture; } texture;
unsigned hit_count; unsigned hit_count;
@ -230,7 +216,7 @@ typedef struct thread_video
enum thread_cmd send_cmd; enum thread_cmd send_cmd;
enum thread_cmd reply_cmd; enum thread_cmd reply_cmd;
uint16_t flags; bool alpha_update;
struct struct
{ {
@ -241,7 +227,18 @@ typedef struct thread_video
unsigned height; unsigned height;
unsigned pitch; unsigned pitch;
char msg[NAME_MAX_LENGTH]; char msg[NAME_MAX_LENGTH];
bool updated;
bool within_thread;
} frame; } frame;
bool apply_state_changes;
bool alive;
bool focus;
bool suppress_screensaver;
bool has_windowed;
bool nonblock;
bool is_idle;
} thread_video_t; } thread_video_t;
/** /**