mirror of
https://github.com/libretro/RetroArch
synced 2025-02-06 09:40:06 +00:00
Remove unprotected access to cmd_data and rewrite message passing mechanism
This commit is contained in:
parent
b363060262
commit
bb2f181386
@ -91,6 +91,7 @@ unsigned video_texture_load(void *data,
|
|||||||
{
|
{
|
||||||
driver_t *driver = driver_get_ptr();
|
driver_t *driver = driver_get_ptr();
|
||||||
thread_video_t *thr = (thread_video_t*)driver->video_data;
|
thread_video_t *thr = (thread_video_t*)driver->video_data;
|
||||||
|
thread_packet_t pkt = { CMD_CUSTOM_COMMAND };
|
||||||
|
|
||||||
if (!thr)
|
if (!thr)
|
||||||
return 0;
|
return 0;
|
||||||
@ -100,22 +101,21 @@ unsigned video_texture_load(void *data,
|
|||||||
case TEXTURE_BACKEND_OPENGL:
|
case TEXTURE_BACKEND_OPENGL:
|
||||||
if (filter_type == TEXTURE_FILTER_MIPMAP_LINEAR ||
|
if (filter_type == TEXTURE_FILTER_MIPMAP_LINEAR ||
|
||||||
filter_type == TEXTURE_FILTER_MIPMAP_NEAREST)
|
filter_type == TEXTURE_FILTER_MIPMAP_NEAREST)
|
||||||
thr->cmd_data.custom_command.method = video_texture_png_load_wrap_gl_mipmap;
|
pkt.data.custom_command.method = video_texture_png_load_wrap_gl_mipmap;
|
||||||
else
|
else
|
||||||
thr->cmd_data.custom_command.method = video_texture_png_load_wrap_gl;
|
pkt.data.custom_command.method = video_texture_png_load_wrap_gl;
|
||||||
break;
|
break;
|
||||||
case TEXTURE_BACKEND_DEFAULT:
|
case TEXTURE_BACKEND_DEFAULT:
|
||||||
default:
|
default:
|
||||||
thr->cmd_data.custom_command.method = video_texture_png_load_wrap;
|
pkt.data.custom_command.method = video_texture_png_load_wrap;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
thr->cmd_data.custom_command.data = (void*)data;
|
pkt.data.custom_command.data = (void*)data;
|
||||||
|
|
||||||
thr->send_cmd_func(thr, CMD_CUSTOM_COMMAND);
|
thr->send_and_wait(thr, &pkt);
|
||||||
thr->wait_reply_func(thr, CMD_CUSTOM_COMMAND);
|
|
||||||
|
|
||||||
return thr->cmd_data.custom_command.return_value;
|
return pkt.data.custom_command.return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return video_texture_png_load(data, type, filter_type);
|
return video_texture_png_load(data, type, filter_type);
|
||||||
|
@ -32,15 +32,55 @@ static void *thread_init_never_call(const video_info_t *video,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void thread_reply(thread_video_t *thr, enum thread_cmd cmd)
|
/* thread -> user */
|
||||||
|
static void thread_reply(thread_video_t *thr, const thread_packet_t *pkt)
|
||||||
{
|
{
|
||||||
slock_lock(thr->lock);
|
slock_lock(thr->lock);
|
||||||
thr->reply_cmd = cmd;
|
|
||||||
|
thr->cmd_data = *pkt;
|
||||||
|
|
||||||
|
thr->reply_cmd = pkt->type;
|
||||||
thr->send_cmd = CMD_NONE;
|
thr->send_cmd = CMD_NONE;
|
||||||
|
|
||||||
scond_signal(thr->cond_cmd);
|
scond_signal(thr->cond_cmd);
|
||||||
slock_unlock(thr->lock);
|
slock_unlock(thr->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* user -> thread */
|
||||||
|
static void thread_send_packet(thread_video_t *thr, const thread_packet_t *pkt)
|
||||||
|
{
|
||||||
|
slock_lock(thr->lock);
|
||||||
|
|
||||||
|
thr->cmd_data = *pkt;
|
||||||
|
|
||||||
|
thr->send_cmd = pkt->type;
|
||||||
|
thr->reply_cmd = CMD_NONE;
|
||||||
|
|
||||||
|
scond_signal(thr->cond_thread);
|
||||||
|
slock_unlock(thr->lock);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* user -> thread */
|
||||||
|
static void thread_wait_reply(thread_video_t *thr, thread_packet_t *pkt)
|
||||||
|
{
|
||||||
|
slock_lock(thr->lock);
|
||||||
|
|
||||||
|
while (pkt->type != thr->reply_cmd)
|
||||||
|
scond_wait(thr->cond_cmd, thr->lock);
|
||||||
|
|
||||||
|
*pkt = thr->cmd_data;
|
||||||
|
|
||||||
|
slock_unlock(thr->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* user -> thread */
|
||||||
|
static void thread_send_and_wait(thread_video_t *thr, thread_packet_t *pkt)
|
||||||
|
{
|
||||||
|
thread_send_packet(thr, pkt);
|
||||||
|
thread_wait_reply(thr, pkt);
|
||||||
|
}
|
||||||
|
|
||||||
static void thread_update_driver_state(thread_video_t *thr)
|
static void thread_update_driver_state(thread_video_t *thr)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_MENU)
|
#if defined(HAVE_MENU)
|
||||||
@ -90,6 +130,7 @@ static void thread_loop(void *data)
|
|||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
thread_packet_t pkt;
|
||||||
enum thread_cmd send_cmd;
|
enum thread_cmd send_cmd;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
bool updated = false;
|
bool updated = false;
|
||||||
@ -102,8 +143,9 @@ static void thread_loop(void *data)
|
|||||||
|
|
||||||
/* 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. */
|
||||||
|
|
||||||
send_cmd = thr->send_cmd;
|
send_cmd = thr->send_cmd;
|
||||||
|
pkt = thr->cmd_data;
|
||||||
|
|
||||||
slock_unlock(thr->lock);
|
slock_unlock(thr->lock);
|
||||||
|
|
||||||
switch (send_cmd)
|
switch (send_cmd)
|
||||||
@ -111,9 +153,9 @@ static void thread_loop(void *data)
|
|||||||
case CMD_INIT:
|
case CMD_INIT:
|
||||||
thr->driver_data = thr->driver->init(&thr->info,
|
thr->driver_data = thr->driver->init(&thr->info,
|
||||||
thr->input, thr->input_data);
|
thr->input, thr->input_data);
|
||||||
thr->cmd_data.b = thr->driver_data;
|
pkt.data.b = thr->driver_data;
|
||||||
thr->driver->viewport_info(thr->driver_data, &thr->vp);
|
thr->driver->viewport_info(thr->driver_data, &thr->vp);
|
||||||
thread_reply(thr, CMD_INIT);
|
thread_reply(thr, &pkt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_FREE:
|
case CMD_FREE:
|
||||||
@ -123,13 +165,13 @@ static void thread_loop(void *data)
|
|||||||
thr->driver->free(thr->driver_data);
|
thr->driver->free(thr->driver_data);
|
||||||
}
|
}
|
||||||
thr->driver_data = NULL;
|
thr->driver_data = NULL;
|
||||||
thread_reply(thr, CMD_FREE);
|
thread_reply(thr, &pkt);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CMD_SET_ROTATION:
|
case CMD_SET_ROTATION:
|
||||||
if (thr->driver && thr->driver->set_rotation)
|
if (thr->driver && thr->driver->set_rotation)
|
||||||
thr->driver->set_rotation(thr->driver_data, thr->cmd_data.i);
|
thr->driver->set_rotation(thr->driver_data, pkt.data.i);
|
||||||
thread_reply(thr, CMD_SET_ROTATION);
|
thread_reply(thr, &pkt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_READ_VIEWPORT:
|
case CMD_READ_VIEWPORT:
|
||||||
@ -156,55 +198,55 @@ static void thread_loop(void *data)
|
|||||||
|
|
||||||
if (thr->driver && thr->driver->read_viewport)
|
if (thr->driver && thr->driver->read_viewport)
|
||||||
ret = thr->driver->read_viewport(thr->driver_data,
|
ret = thr->driver->read_viewport(thr->driver_data,
|
||||||
(uint8_t*)thr->cmd_data.v);
|
(uint8_t*)pkt.data.v);
|
||||||
|
|
||||||
thr->cmd_data.b = ret;
|
pkt.data.b = ret;
|
||||||
thr->frame.within_thread = false;
|
thr->frame.within_thread = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Viewport dimensions changed right after main
|
/* Viewport dimensions changed right after main
|
||||||
* thread read the async value. Cannot read safely. */
|
* thread read the async value. Cannot read safely. */
|
||||||
thr->cmd_data.b = false;
|
pkt.data.b = false;
|
||||||
}
|
}
|
||||||
thread_reply(thr, CMD_READ_VIEWPORT);
|
thread_reply(thr, &pkt);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CMD_SET_SHADER:
|
case CMD_SET_SHADER:
|
||||||
if (thr->driver && thr->driver->set_shader)
|
if (thr->driver && thr->driver->set_shader)
|
||||||
ret = thr->driver->set_shader(thr->driver_data,
|
ret = thr->driver->set_shader(thr->driver_data,
|
||||||
thr->cmd_data.set_shader.type,
|
pkt.data.set_shader.type,
|
||||||
thr->cmd_data.set_shader.path);
|
pkt.data.set_shader.path);
|
||||||
|
|
||||||
thr->cmd_data.b = ret;
|
pkt.data.b = ret;
|
||||||
thread_reply(thr, CMD_SET_SHADER);
|
thread_reply(thr, &pkt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_ALIVE:
|
case CMD_ALIVE:
|
||||||
if (thr->driver && thr->driver->alive)
|
if (thr->driver && thr->driver->alive)
|
||||||
ret = thr->driver->alive(thr->driver_data);
|
ret = thr->driver->alive(thr->driver_data);
|
||||||
|
|
||||||
thr->cmd_data.b = ret;
|
pkt.data.b = ret;
|
||||||
thread_reply(thr, CMD_ALIVE);
|
thread_reply(thr, &pkt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef HAVE_OVERLAY
|
#ifdef HAVE_OVERLAY
|
||||||
case CMD_OVERLAY_ENABLE:
|
case CMD_OVERLAY_ENABLE:
|
||||||
if (thr->overlay && thr->overlay->enable)
|
if (thr->overlay && thr->overlay->enable)
|
||||||
thr->overlay->enable(thr->driver_data, thr->cmd_data.b);
|
thr->overlay->enable(thr->driver_data, pkt.data.b);
|
||||||
thread_reply(thr, CMD_OVERLAY_ENABLE);
|
thread_reply(thr, &pkt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_OVERLAY_LOAD:
|
case CMD_OVERLAY_LOAD:
|
||||||
|
|
||||||
if (thr->overlay && thr->overlay->load)
|
if (thr->overlay && thr->overlay->load)
|
||||||
ret = thr->overlay->load(thr->driver_data,
|
ret = thr->overlay->load(thr->driver_data,
|
||||||
thr->cmd_data.image.data,
|
pkt.data.image.data,
|
||||||
thr->cmd_data.image.num);
|
pkt.data.image.num);
|
||||||
|
|
||||||
thr->cmd_data.b = ret;
|
pkt.data.b = ret;
|
||||||
thr->alpha_mods = thr->cmd_data.image.num;
|
thr->alpha_mods = pkt.data.image.num;
|
||||||
thr->alpha_mod = (float*)realloc(thr->alpha_mod,
|
thr->alpha_mod = (float*)realloc(thr->alpha_mod,
|
||||||
thr->alpha_mods * sizeof(float));
|
thr->alpha_mods * sizeof(float));
|
||||||
|
|
||||||
@ -213,118 +255,117 @@ static void thread_loop(void *data)
|
|||||||
/* Avoid temporary garbage data. */
|
/* Avoid temporary garbage data. */
|
||||||
thr->alpha_mod[i] = 1.0f;
|
thr->alpha_mod[i] = 1.0f;
|
||||||
}
|
}
|
||||||
thread_reply(thr, CMD_OVERLAY_LOAD);
|
|
||||||
|
|
||||||
|
thread_reply(thr, &pkt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_OVERLAY_TEX_GEOM:
|
case CMD_OVERLAY_TEX_GEOM:
|
||||||
if (thr->overlay && thr->overlay->tex_geom)
|
if (thr->overlay && thr->overlay->tex_geom)
|
||||||
thr->overlay->tex_geom(thr->driver_data,
|
thr->overlay->tex_geom(thr->driver_data,
|
||||||
thr->cmd_data.rect.index,
|
pkt.data.rect.index,
|
||||||
thr->cmd_data.rect.x,
|
pkt.data.rect.x,
|
||||||
thr->cmd_data.rect.y,
|
pkt.data.rect.y,
|
||||||
thr->cmd_data.rect.w,
|
pkt.data.rect.w,
|
||||||
thr->cmd_data.rect.h);
|
pkt.data.rect.h);
|
||||||
thread_reply(thr, CMD_OVERLAY_TEX_GEOM);
|
thread_reply(thr, &pkt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_OVERLAY_VERTEX_GEOM:
|
case CMD_OVERLAY_VERTEX_GEOM:
|
||||||
if (thr->overlay && thr->overlay->vertex_geom)
|
if (thr->overlay && thr->overlay->vertex_geom)
|
||||||
thr->overlay->vertex_geom(thr->driver_data,
|
thr->overlay->vertex_geom(thr->driver_data,
|
||||||
thr->cmd_data.rect.index,
|
pkt.data.rect.index,
|
||||||
thr->cmd_data.rect.x,
|
pkt.data.rect.x,
|
||||||
thr->cmd_data.rect.y,
|
pkt.data.rect.y,
|
||||||
thr->cmd_data.rect.w,
|
pkt.data.rect.w,
|
||||||
thr->cmd_data.rect.h);
|
pkt.data.rect.h);
|
||||||
thread_reply(thr, CMD_OVERLAY_VERTEX_GEOM);
|
thread_reply(thr, &pkt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_OVERLAY_FULL_SCREEN:
|
case CMD_OVERLAY_FULL_SCREEN:
|
||||||
if (thr->overlay && thr->overlay->full_screen)
|
if (thr->overlay && thr->overlay->full_screen)
|
||||||
thr->overlay->full_screen(thr->driver_data,
|
thr->overlay->full_screen(thr->driver_data,
|
||||||
thr->cmd_data.b);
|
pkt.data.b);
|
||||||
thread_reply(thr, CMD_OVERLAY_FULL_SCREEN);
|
thread_reply(thr, &pkt);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case CMD_POKE_SET_VIDEO_MODE:
|
case CMD_POKE_SET_VIDEO_MODE:
|
||||||
if (thr->poke && thr->poke->set_video_mode)
|
if (thr->poke && thr->poke->set_video_mode)
|
||||||
thr->poke->set_video_mode(thr->driver_data,
|
thr->poke->set_video_mode(thr->driver_data,
|
||||||
thr->cmd_data.new_mode.width,
|
pkt.data.new_mode.width,
|
||||||
thr->cmd_data.new_mode.height,
|
pkt.data.new_mode.height,
|
||||||
thr->cmd_data.new_mode.fullscreen);
|
pkt.data.new_mode.fullscreen);
|
||||||
thread_reply(thr, CMD_POKE_SET_VIDEO_MODE);
|
thread_reply(thr, &pkt);
|
||||||
break;
|
break;
|
||||||
case CMD_POKE_SET_FILTERING:
|
case CMD_POKE_SET_FILTERING:
|
||||||
if (thr->poke && thr->poke->set_filtering)
|
if (thr->poke && thr->poke->set_filtering)
|
||||||
thr->poke->set_filtering(thr->driver_data,
|
thr->poke->set_filtering(thr->driver_data,
|
||||||
thr->cmd_data.filtering.index,
|
pkt.data.filtering.index,
|
||||||
thr->cmd_data.filtering.smooth);
|
pkt.data.filtering.smooth);
|
||||||
thread_reply(thr, CMD_POKE_SET_FILTERING);
|
thread_reply(thr, &pkt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_POKE_GET_VIDEO_OUTPUT_SIZE:
|
case CMD_POKE_GET_VIDEO_OUTPUT_SIZE:
|
||||||
if (thr->poke && thr->poke->get_video_output_size)
|
if (thr->poke && thr->poke->get_video_output_size)
|
||||||
thr->poke->get_video_output_size(thr->driver_data,
|
thr->poke->get_video_output_size(thr->driver_data,
|
||||||
&thr->cmd_data.output.width,
|
&pkt.data.output.width,
|
||||||
&thr->cmd_data.output.height);
|
&pkt.data.output.height);
|
||||||
thread_reply(thr, CMD_POKE_GET_VIDEO_OUTPUT_SIZE);
|
thread_reply(thr, &pkt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_POKE_GET_VIDEO_OUTPUT_PREV:
|
case CMD_POKE_GET_VIDEO_OUTPUT_PREV:
|
||||||
if (thr->poke && thr->poke->get_video_output_prev)
|
if (thr->poke && thr->poke->get_video_output_prev)
|
||||||
thr->poke->get_video_output_prev(thr->driver_data);
|
thr->poke->get_video_output_prev(thr->driver_data);
|
||||||
thread_reply(thr, CMD_POKE_GET_VIDEO_OUTPUT_PREV);
|
thread_reply(thr, &pkt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_POKE_GET_VIDEO_OUTPUT_NEXT:
|
case CMD_POKE_GET_VIDEO_OUTPUT_NEXT:
|
||||||
if (thr->poke && thr->poke->get_video_output_next)
|
if (thr->poke && thr->poke->get_video_output_next)
|
||||||
thr->poke->get_video_output_next(thr->driver_data);
|
thr->poke->get_video_output_next(thr->driver_data);
|
||||||
thread_reply(thr, CMD_POKE_GET_VIDEO_OUTPUT_NEXT);
|
thread_reply(thr, &pkt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_POKE_SET_ASPECT_RATIO:
|
case CMD_POKE_SET_ASPECT_RATIO:
|
||||||
thr->poke->set_aspect_ratio(thr->driver_data,
|
thr->poke->set_aspect_ratio(thr->driver_data,
|
||||||
thr->cmd_data.i);
|
pkt.data.i);
|
||||||
thread_reply(thr, CMD_POKE_SET_ASPECT_RATIO);
|
thread_reply(thr, &pkt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_POKE_SET_OSD_MSG:
|
case CMD_POKE_SET_OSD_MSG:
|
||||||
if (thr->poke && thr->poke->set_osd_msg)
|
if (thr->poke && thr->poke->set_osd_msg)
|
||||||
thr->poke->set_osd_msg(thr->driver_data,
|
thr->poke->set_osd_msg(thr->driver_data,
|
||||||
thr->cmd_data.osd_message.msg,
|
pkt.data.osd_message.msg,
|
||||||
&thr->cmd_data.osd_message.params, NULL);
|
&pkt.data.osd_message.params, NULL);
|
||||||
thread_reply(thr, CMD_POKE_SET_OSD_MSG);
|
thread_reply(thr, &pkt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_FONT_INIT:
|
case CMD_FONT_INIT:
|
||||||
if (thr->cmd_data.font_init.method)
|
if (pkt.data.font_init.method)
|
||||||
thr->cmd_data.font_init.return_value =
|
pkt.data.font_init.return_value =
|
||||||
thr->cmd_data.font_init.method
|
pkt.data.font_init.method
|
||||||
(thr->cmd_data.font_init.font_driver,
|
(pkt.data.font_init.font_driver,
|
||||||
thr->cmd_data.font_init.font_handle,
|
pkt.data.font_init.font_handle,
|
||||||
thr->cmd_data.font_init.video_data,
|
pkt.data.font_init.video_data,
|
||||||
thr->cmd_data.font_init.font_path,
|
pkt.data.font_init.font_path,
|
||||||
thr->cmd_data.font_init.font_size,
|
pkt.data.font_init.font_size,
|
||||||
thr->cmd_data.font_init.api);
|
pkt.data.font_init.api);
|
||||||
thread_reply(thr, CMD_FONT_INIT);
|
thread_reply(thr, &pkt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_CUSTOM_COMMAND:
|
case CMD_CUSTOM_COMMAND:
|
||||||
if (thr->cmd_data.custom_command.method)
|
if (pkt.data.custom_command.method)
|
||||||
thr->cmd_data.custom_command.return_value =
|
pkt.data.custom_command.return_value =
|
||||||
thr->cmd_data.custom_command.method
|
pkt.data.custom_command.method
|
||||||
(thr->cmd_data.custom_command.data);
|
(pkt.data.custom_command.data);
|
||||||
thread_reply(thr, CMD_CUSTOM_COMMAND);
|
thread_reply(thr, &pkt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_NONE:
|
case CMD_NONE:
|
||||||
/* Never reply on no command. Possible deadlock if
|
/* Never reply on no command. Possible deadlock if
|
||||||
* thread sends command right after frame update. */
|
* thread sends command right after frame update. */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
thread_reply(thr, send_cmd);
|
thread_reply(thr, &pkt);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,22 +412,8 @@ static void thread_loop(void *data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void thread_send_cmd(thread_video_t *thr, enum thread_cmd cmd)
|
|
||||||
{
|
|
||||||
slock_lock(thr->lock);
|
|
||||||
thr->send_cmd = cmd;
|
|
||||||
thr->reply_cmd = CMD_NONE;
|
|
||||||
scond_signal(thr->cond_thread);
|
|
||||||
slock_unlock(thr->lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void thread_wait_reply(thread_video_t *thr, enum thread_cmd cmd)
|
|
||||||
{
|
|
||||||
slock_lock(thr->lock);
|
|
||||||
while (cmd != thr->reply_cmd)
|
|
||||||
scond_wait(thr->cond_cmd, thr->lock);
|
|
||||||
slock_unlock(thr->lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool thread_alive(void *data)
|
static bool thread_alive(void *data)
|
||||||
{
|
{
|
||||||
@ -396,9 +423,9 @@ static bool thread_alive(void *data)
|
|||||||
|
|
||||||
if (runloop->is_paused)
|
if (runloop->is_paused)
|
||||||
{
|
{
|
||||||
thread_send_cmd(thr, CMD_ALIVE);
|
thread_packet_t pkt = { CMD_ALIVE };
|
||||||
thread_wait_reply(thr, CMD_ALIVE);
|
thread_send_and_wait(thr, &pkt);
|
||||||
return thr->cmd_data.b;
|
return pkt.data.b;
|
||||||
}
|
}
|
||||||
|
|
||||||
slock_lock(thr->lock);
|
slock_lock(thr->lock);
|
||||||
@ -551,6 +578,7 @@ static bool thread_init(thread_video_t *thr, const video_info_t *info,
|
|||||||
const input_driver_t **input, void **input_data)
|
const input_driver_t **input, void **input_data)
|
||||||
{
|
{
|
||||||
size_t max_size;
|
size_t max_size;
|
||||||
|
thread_packet_t pkt = {CMD_INIT};
|
||||||
|
|
||||||
thr->lock = slock_new();
|
thr->lock = slock_new();
|
||||||
thr->alpha_lock = slock_new();
|
thr->alpha_lock = slock_new();
|
||||||
@ -580,52 +608,42 @@ static bool thread_init(thread_video_t *thr, const video_info_t *info,
|
|||||||
if (!thr->thread)
|
if (!thr->thread)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
thread_send_cmd(thr, CMD_INIT);
|
thread_send_and_wait(thr, &pkt);
|
||||||
thread_wait_reply(thr, CMD_INIT);
|
|
||||||
|
|
||||||
thr->send_cmd_func = thread_send_cmd;
|
// thr->send_cmd_func = thread_send_cmd;
|
||||||
thr->wait_reply_func = thread_wait_reply;
|
// thr->wait_reply_func = thread_wait_reply;
|
||||||
|
|
||||||
return thr->cmd_data.b;
|
thr->send_and_wait = thread_send_and_wait;
|
||||||
|
return pkt.data.b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool thread_set_shader(void *data,
|
static bool thread_set_shader(void *data,
|
||||||
enum rarch_shader_type type, const char *path)
|
enum rarch_shader_type type, const char *path)
|
||||||
{
|
{
|
||||||
thread_video_t *thr = (thread_video_t*)data;
|
thread_video_t *thr = (thread_video_t*)data;
|
||||||
|
thread_packet_t pkt = {CMD_SET_SHADER};
|
||||||
if (!thr)
|
if (!thr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
thr->cmd_data.set_shader.type = type;
|
pkt.data.set_shader.type = type;
|
||||||
thr->cmd_data.set_shader.path = path;
|
pkt.data.set_shader.path = path;
|
||||||
thread_send_cmd(thr, CMD_SET_SHADER);
|
thread_send_and_wait(thr, &pkt);
|
||||||
thread_wait_reply(thr, CMD_SET_SHADER);
|
|
||||||
|
|
||||||
return thr->cmd_data.b;
|
return pkt.data.b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void thread_set_viewport(void *data, unsigned width,
|
static void thread_set_viewport(void *data, unsigned width,
|
||||||
unsigned height, bool force_full, bool allow_rotate)
|
unsigned height, bool force_full, bool allow_rotate)
|
||||||
{
|
{
|
||||||
thread_video_t *thr = (thread_video_t*)data;
|
thread_video_t *thr = (thread_video_t*)data;
|
||||||
|
|
||||||
if (!thr)
|
if (!thr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
slock_lock(thr->lock);
|
slock_lock(thr->lock);
|
||||||
|
|
||||||
thr->cmd_data.set_viewport.width = width;
|
|
||||||
thr->cmd_data.set_viewport.height = height;
|
|
||||||
thr->cmd_data.set_viewport.force_full = force_full;
|
|
||||||
thr->cmd_data.set_viewport.allow_rotate = allow_rotate;
|
|
||||||
|
|
||||||
if (thr->driver && thr->driver->set_viewport)
|
if (thr->driver && thr->driver->set_viewport)
|
||||||
thr->driver->set_viewport(thr->driver_data,
|
thr->driver->set_viewport(thr->driver_data, width, height,
|
||||||
thr->cmd_data.set_viewport.width,
|
force_full, allow_rotate);
|
||||||
thr->cmd_data.set_viewport.height,
|
|
||||||
thr->cmd_data.set_viewport.force_full,
|
|
||||||
thr->cmd_data.set_viewport.allow_rotate);
|
|
||||||
|
|
||||||
slock_unlock(thr->lock);
|
slock_unlock(thr->lock);
|
||||||
}
|
}
|
||||||
@ -633,13 +651,13 @@ static void thread_set_viewport(void *data, unsigned width,
|
|||||||
static void thread_set_rotation(void *data, unsigned rotation)
|
static void thread_set_rotation(void *data, unsigned rotation)
|
||||||
{
|
{
|
||||||
thread_video_t *thr = (thread_video_t*)data;
|
thread_video_t *thr = (thread_video_t*)data;
|
||||||
|
thread_packet_t pkt = { CMD_SET_ROTATION };
|
||||||
|
|
||||||
if (!thr)
|
if (!thr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
thr->cmd_data.i = rotation;
|
pkt.data.i = rotation;
|
||||||
thread_send_cmd(thr, CMD_SET_ROTATION);
|
thread_send_and_wait(thr, &pkt);
|
||||||
thread_wait_reply(thr, CMD_SET_ROTATION);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This value is set async as stalling on the video driver for
|
/* This value is set async as stalling on the video driver for
|
||||||
@ -665,24 +683,27 @@ static void thread_viewport_info(void *data, struct video_viewport *vp)
|
|||||||
static bool thread_read_viewport(void *data, uint8_t *buffer)
|
static bool thread_read_viewport(void *data, uint8_t *buffer)
|
||||||
{
|
{
|
||||||
thread_video_t *thr = (thread_video_t*)data;
|
thread_video_t *thr = (thread_video_t*)data;
|
||||||
|
thread_packet_t pkt = { CMD_READ_VIEWPORT };
|
||||||
|
|
||||||
if (!thr)
|
if (!thr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
thr->cmd_data.v = buffer;
|
pkt.data.v = buffer;
|
||||||
thread_send_cmd(thr, CMD_READ_VIEWPORT);
|
thread_send_and_wait(thr, &pkt);
|
||||||
thread_wait_reply(thr, CMD_READ_VIEWPORT);
|
|
||||||
|
|
||||||
return thr->cmd_data.b;
|
return pkt.data.b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void thread_free(void *data)
|
static void thread_free(void *data)
|
||||||
{
|
{
|
||||||
thread_video_t *thr = (thread_video_t*)data;
|
thread_video_t *thr = (thread_video_t*)data;
|
||||||
|
thread_packet_t pkt = { CMD_FREE };
|
||||||
|
|
||||||
if (!thr)
|
if (!thr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
thread_send_cmd(thr, CMD_FREE);
|
thread_send_and_wait(thr, &pkt);
|
||||||
thread_wait_reply(thr, CMD_FREE);
|
|
||||||
sthread_join(thr->thread);
|
sthread_join(thr->thread);
|
||||||
|
|
||||||
#if defined(HAVE_MENU)
|
#if defined(HAVE_MENU)
|
||||||
@ -707,69 +728,73 @@ static void thread_free(void *data)
|
|||||||
static void thread_overlay_enable(void *data, bool state)
|
static void thread_overlay_enable(void *data, bool state)
|
||||||
{
|
{
|
||||||
thread_video_t *thr = (thread_video_t*)data;
|
thread_video_t *thr = (thread_video_t*)data;
|
||||||
|
thread_packet_t pkt = { CMD_OVERLAY_ENABLE };
|
||||||
|
|
||||||
if (!thr)
|
if (!thr)
|
||||||
return;
|
return;
|
||||||
thr->cmd_data.b = state;
|
|
||||||
thread_send_cmd(thr, CMD_OVERLAY_ENABLE);
|
pkt.data.b = state;
|
||||||
thread_wait_reply(thr, CMD_OVERLAY_ENABLE);
|
thread_send_and_wait(thr, &pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool thread_overlay_load(void *data,
|
static bool thread_overlay_load(void *data,
|
||||||
const struct texture_image *images, unsigned num_images)
|
const struct texture_image *images, unsigned num_images)
|
||||||
{
|
{
|
||||||
thread_video_t *thr = (thread_video_t*)data;
|
thread_video_t *thr = (thread_video_t*)data;
|
||||||
|
thread_packet_t pkt = { CMD_OVERLAY_LOAD };
|
||||||
|
|
||||||
if (!thr)
|
if (!thr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
thr->cmd_data.image.data = images;
|
pkt.data.image.data = images;
|
||||||
thr->cmd_data.image.num = num_images;
|
pkt.data.image.num = num_images;
|
||||||
thread_send_cmd(thr, CMD_OVERLAY_LOAD);
|
thread_send_and_wait(thr, &pkt);
|
||||||
thread_wait_reply(thr, CMD_OVERLAY_LOAD);
|
|
||||||
|
|
||||||
return thr->cmd_data.b;
|
return pkt.data.b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void thread_overlay_tex_geom(void *data,
|
static void thread_overlay_tex_geom(void *data,
|
||||||
unsigned idx, float x, float y, float w, float h)
|
unsigned idx, float x, float y, float w, float h)
|
||||||
{
|
{
|
||||||
thread_video_t *thr = (thread_video_t*)data;
|
thread_video_t *thr = (thread_video_t*)data;
|
||||||
|
thread_packet_t pkt = { CMD_OVERLAY_TEX_GEOM };
|
||||||
|
|
||||||
if (!thr)
|
if (!thr)
|
||||||
return;
|
return;
|
||||||
thr->cmd_data.rect.index = idx;
|
pkt.data.rect.index = idx;
|
||||||
thr->cmd_data.rect.x = x;
|
pkt.data.rect.x = x;
|
||||||
thr->cmd_data.rect.y = y;
|
pkt.data.rect.y = y;
|
||||||
thr->cmd_data.rect.w = w;
|
pkt.data.rect.w = w;
|
||||||
thr->cmd_data.rect.h = h;
|
pkt.data.rect.h = h;
|
||||||
thread_send_cmd(thr, CMD_OVERLAY_TEX_GEOM);
|
|
||||||
thread_wait_reply(thr, CMD_OVERLAY_TEX_GEOM);
|
thread_send_and_wait(thr, &pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void thread_overlay_vertex_geom(void *data,
|
static void thread_overlay_vertex_geom(void *data,
|
||||||
unsigned idx, float x, float y, float w, float h)
|
unsigned idx, float x, float y, float w, float h)
|
||||||
{
|
{
|
||||||
thread_video_t *thr = (thread_video_t*)data;
|
thread_video_t *thr = (thread_video_t*)data;
|
||||||
|
thread_packet_t pkt = { CMD_OVERLAY_VERTEX_GEOM };
|
||||||
|
|
||||||
if (!thr)
|
if (!thr)
|
||||||
return;
|
return;
|
||||||
thr->cmd_data.rect.index = idx;
|
|
||||||
thr->cmd_data.rect.x = x;
|
pkt.data.rect.index = idx;
|
||||||
thr->cmd_data.rect.y = y;
|
pkt.data.rect.x = x;
|
||||||
thr->cmd_data.rect.w = w;
|
pkt.data.rect.y = y;
|
||||||
thr->cmd_data.rect.h = h;
|
pkt.data.rect.w = w;
|
||||||
thread_send_cmd(thr, CMD_OVERLAY_VERTEX_GEOM);
|
pkt.data.rect.h = h;
|
||||||
thread_wait_reply(thr, CMD_OVERLAY_VERTEX_GEOM);
|
|
||||||
|
thread_send_and_wait(thr, &pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void thread_overlay_full_screen(void *data, bool enable)
|
static void thread_overlay_full_screen(void *data, bool enable)
|
||||||
{
|
{
|
||||||
thread_video_t *thr = (thread_video_t*)data;
|
thread_video_t *thr = (thread_video_t*)data;
|
||||||
|
thread_packet_t pkt = { CMD_OVERLAY_FULL_SCREEN };
|
||||||
|
|
||||||
thr->cmd_data.b = enable;
|
pkt.data.b = enable;
|
||||||
thread_send_cmd(thr, CMD_OVERLAY_FULL_SCREEN);
|
thread_send_and_wait(thr, &pkt);
|
||||||
thread_wait_reply(thr, CMD_OVERLAY_FULL_SCREEN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We cannot wait for this to complete. Totally blocks the main thread. */
|
/* We cannot wait for this to complete. Totally blocks the main thread. */
|
||||||
@ -809,70 +834,73 @@ static void thread_set_video_mode(void *data, unsigned width, unsigned height,
|
|||||||
bool fullscreen)
|
bool fullscreen)
|
||||||
{
|
{
|
||||||
thread_video_t *thr = (thread_video_t*)data;
|
thread_video_t *thr = (thread_video_t*)data;
|
||||||
|
thread_packet_t pkt = { CMD_POKE_SET_VIDEO_MODE };
|
||||||
|
|
||||||
if (!thr)
|
if (!thr)
|
||||||
return;
|
return;
|
||||||
thr->cmd_data.new_mode.width = width;
|
|
||||||
thr->cmd_data.new_mode.height = height;
|
pkt.data.new_mode.width = width;
|
||||||
thr->cmd_data.new_mode.fullscreen = fullscreen;
|
pkt.data.new_mode.height = height;
|
||||||
thread_send_cmd(thr, CMD_POKE_SET_VIDEO_MODE);
|
pkt.data.new_mode.fullscreen = fullscreen;
|
||||||
thread_wait_reply(thr, CMD_POKE_SET_VIDEO_MODE);
|
thread_send_and_wait(thr, &pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void thread_set_filtering(void *data, unsigned idx, bool smooth)
|
static void thread_set_filtering(void *data, unsigned idx, bool smooth)
|
||||||
{
|
{
|
||||||
thread_video_t *thr = (thread_video_t*)data;
|
thread_video_t *thr = (thread_video_t*)data;
|
||||||
|
thread_packet_t pkt = { CMD_POKE_SET_FILTERING };
|
||||||
|
|
||||||
if (!thr)
|
if (!thr)
|
||||||
return;
|
return;
|
||||||
thr->cmd_data.filtering.index = idx;
|
pkt.data.filtering.index = idx;
|
||||||
thr->cmd_data.filtering.smooth = smooth;
|
pkt.data.filtering.smooth = smooth;
|
||||||
thread_send_cmd(thr, CMD_POKE_SET_FILTERING);
|
thread_send_and_wait(thr, &pkt);
|
||||||
thread_wait_reply(thr, CMD_POKE_SET_FILTERING);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void thread_get_video_output_size(void *data,
|
static void thread_get_video_output_size(void *data,
|
||||||
unsigned *width, unsigned *height)
|
unsigned *width, unsigned *height)
|
||||||
{
|
{
|
||||||
thread_video_t *thr = (thread_video_t*)data;
|
thread_video_t *thr = (thread_video_t*)data;
|
||||||
|
thread_packet_t pkt = { CMD_POKE_GET_VIDEO_OUTPUT_SIZE };
|
||||||
|
|
||||||
if (!thr)
|
if (!thr)
|
||||||
return;
|
return;
|
||||||
thread_send_cmd(thr, CMD_POKE_GET_VIDEO_OUTPUT_SIZE);
|
|
||||||
thread_wait_reply(thr, CMD_POKE_GET_VIDEO_OUTPUT_SIZE);
|
thread_send_and_wait(thr, &pkt);
|
||||||
*width = thr->cmd_data.output.width;
|
|
||||||
*height = thr->cmd_data.output.height;
|
*width = pkt.data.output.width;
|
||||||
|
*height = pkt.data.output.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void thread_get_video_output_prev(void *data)
|
static void thread_get_video_output_prev(void *data)
|
||||||
{
|
{
|
||||||
thread_video_t *thr = (thread_video_t*)data;
|
thread_video_t *thr = (thread_video_t*)data;
|
||||||
|
thread_packet_t pkt = { CMD_POKE_GET_VIDEO_OUTPUT_PREV };
|
||||||
|
|
||||||
if (!thr)
|
if (!thr)
|
||||||
return;
|
return;
|
||||||
thread_send_cmd(thr, CMD_POKE_GET_VIDEO_OUTPUT_PREV);
|
thread_send_and_wait(thr, &pkt);
|
||||||
thread_wait_reply(thr, CMD_POKE_GET_VIDEO_OUTPUT_PREV);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void thread_get_video_output_next(void *data)
|
static void thread_get_video_output_next(void *data)
|
||||||
{
|
{
|
||||||
thread_video_t *thr = (thread_video_t*)data;
|
thread_video_t *thr = (thread_video_t*)data;
|
||||||
|
thread_packet_t pkt = { CMD_POKE_GET_VIDEO_OUTPUT_NEXT };
|
||||||
|
|
||||||
if (!thr)
|
if (!thr)
|
||||||
return;
|
return;
|
||||||
thread_send_cmd(thr, CMD_POKE_GET_VIDEO_OUTPUT_NEXT);
|
thread_send_and_wait(thr, &pkt);
|
||||||
thread_wait_reply(thr, CMD_POKE_GET_VIDEO_OUTPUT_NEXT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void thread_set_aspect_ratio(void *data, unsigned aspectratio_idx)
|
static void thread_set_aspect_ratio(void *data, unsigned aspectratio_idx)
|
||||||
{
|
{
|
||||||
thread_video_t *thr = (thread_video_t*)data;
|
thread_video_t *thr = (thread_video_t*)data;
|
||||||
|
thread_packet_t pkt = { CMD_POKE_SET_ASPECT_RATIO };
|
||||||
|
|
||||||
if (!thr)
|
if (!thr)
|
||||||
return;
|
return;
|
||||||
thr->cmd_data.i = aspectratio_idx;
|
pkt.data.i = aspectratio_idx;
|
||||||
thread_send_cmd(thr, CMD_POKE_SET_ASPECT_RATIO);
|
thread_send_and_wait(thr, &pkt);
|
||||||
thread_wait_reply(thr, CMD_POKE_SET_ASPECT_RATIO);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_MENU)
|
#if defined(HAVE_MENU)
|
||||||
|
@ -59,60 +59,9 @@ enum thread_cmd
|
|||||||
CMD_DUMMY = INT_MAX
|
CMD_DUMMY = INT_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct thread_video
|
typedef struct
|
||||||
{
|
{
|
||||||
slock_t *lock;
|
enum thread_cmd type;
|
||||||
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;
|
|
||||||
const input_driver_t **input;
|
|
||||||
void **input_data;
|
|
||||||
|
|
||||||
#if defined(HAVE_MENU)
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
void *frame;
|
|
||||||
size_t frame_cap;
|
|
||||||
unsigned width;
|
|
||||||
unsigned height;
|
|
||||||
float alpha;
|
|
||||||
bool frame_updated;
|
|
||||||
bool rgb32;
|
|
||||||
bool enable;
|
|
||||||
bool full_screen;
|
|
||||||
} texture;
|
|
||||||
#endif
|
|
||||||
bool apply_state_changes;
|
|
||||||
|
|
||||||
bool alive;
|
|
||||||
bool focus;
|
|
||||||
bool suppress_screensaver;
|
|
||||||
bool has_windowed;
|
|
||||||
bool nonblock;
|
|
||||||
|
|
||||||
retro_time_t last_time;
|
|
||||||
unsigned hit_count;
|
|
||||||
unsigned miss_count;
|
|
||||||
|
|
||||||
float *alpha_mod;
|
|
||||||
unsigned alpha_mods;
|
|
||||||
bool alpha_update;
|
|
||||||
slock_t *alpha_lock;
|
|
||||||
|
|
||||||
void (*send_cmd_func)(struct thread_video *, enum thread_cmd);
|
|
||||||
void (*wait_reply_func)(struct thread_video *, enum thread_cmd);
|
|
||||||
enum thread_cmd send_cmd;
|
|
||||||
enum thread_cmd reply_cmd;
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
bool b;
|
bool b;
|
||||||
@ -192,8 +141,65 @@ typedef struct thread_video
|
|||||||
bool return_value;
|
bool return_value;
|
||||||
enum font_driver_render_api api;
|
enum font_driver_render_api api;
|
||||||
} font_init;
|
} font_init;
|
||||||
|
} data;
|
||||||
|
} thread_packet_t;
|
||||||
|
|
||||||
} cmd_data;
|
typedef struct thread_video
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
const input_driver_t **input;
|
||||||
|
void **input_data;
|
||||||
|
|
||||||
|
#if defined(HAVE_MENU)
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
void *frame;
|
||||||
|
size_t frame_cap;
|
||||||
|
unsigned width;
|
||||||
|
unsigned height;
|
||||||
|
float alpha;
|
||||||
|
bool frame_updated;
|
||||||
|
bool rgb32;
|
||||||
|
bool enable;
|
||||||
|
bool full_screen;
|
||||||
|
} texture;
|
||||||
|
#endif
|
||||||
|
bool apply_state_changes;
|
||||||
|
|
||||||
|
bool alive;
|
||||||
|
bool focus;
|
||||||
|
bool suppress_screensaver;
|
||||||
|
bool has_windowed;
|
||||||
|
bool nonblock;
|
||||||
|
|
||||||
|
retro_time_t last_time;
|
||||||
|
unsigned hit_count;
|
||||||
|
unsigned miss_count;
|
||||||
|
|
||||||
|
float *alpha_mod;
|
||||||
|
unsigned alpha_mods;
|
||||||
|
bool alpha_update;
|
||||||
|
slock_t *alpha_lock;
|
||||||
|
|
||||||
|
// void (*send_cmd_func)(struct thread_video *, enum thread_cmd);
|
||||||
|
// void (*wait_reply_func)(struct thread_video *, enum thread_cmd);
|
||||||
|
void (*send_and_wait)(struct thread_video *, thread_packet_t*);
|
||||||
|
enum thread_cmd send_cmd;
|
||||||
|
enum thread_cmd reply_cmd;
|
||||||
|
thread_packet_t cmd_data;
|
||||||
|
|
||||||
struct video_viewport vp;
|
struct video_viewport vp;
|
||||||
struct video_viewport read_vp; /* Last viewport reported to caller. */
|
struct video_viewport read_vp; /* Last viewport reported to caller. */
|
||||||
|
@ -141,22 +141,23 @@ bool menu_display_font_init_first(const void **font_driver,
|
|||||||
{
|
{
|
||||||
driver_t *driver = driver_get_ptr();
|
driver_t *driver = driver_get_ptr();
|
||||||
thread_video_t *thr = (thread_video_t*)driver->video_data;
|
thread_video_t *thr = (thread_video_t*)driver->video_data;
|
||||||
|
thread_packet_t pkt;
|
||||||
|
|
||||||
if (!thr)
|
if (!thr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
thr->cmd_data.font_init.method = font_init_first;
|
pkt.type = CMD_FONT_INIT;
|
||||||
thr->cmd_data.font_init.font_driver = (const void**)font_driver;
|
pkt.data.font_init.method = font_init_first;
|
||||||
thr->cmd_data.font_init.font_handle = font_handle;
|
pkt.data.font_init.font_driver = (const void**)font_driver;
|
||||||
thr->cmd_data.font_init.video_data = video_data;
|
pkt.data.font_init.font_handle = font_handle;
|
||||||
thr->cmd_data.font_init.font_path = font_path;
|
pkt.data.font_init.video_data = video_data;
|
||||||
thr->cmd_data.font_init.font_size = font_size;
|
pkt.data.font_init.font_path = font_path;
|
||||||
thr->cmd_data.font_init.api = FONT_DRIVER_RENDER_OPENGL_API;
|
pkt.data.font_init.font_size = font_size;
|
||||||
|
pkt.data.font_init.api = FONT_DRIVER_RENDER_OPENGL_API;
|
||||||
|
|
||||||
thr->send_cmd_func(thr, CMD_FONT_INIT);
|
thr->send_and_wait(thr, &pkt);
|
||||||
thr->wait_reply_func(thr, CMD_FONT_INIT);
|
|
||||||
|
|
||||||
return thr->cmd_data.font_init.return_value;
|
return pkt.data.font_init.return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return font_init_first(font_driver, font_handle, video_data,
|
return font_init_first(font_driver, font_handle, video_data,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user