static void opengl_swap_synchronous(void) { if (g_sync_method == SYNC_SWAP) { swap_opengl_buffers(); } else if (g_sync_method == SYNC_SWAP_FINISH) { swap_opengl_buffers(); gl_finish(); } else if (g_sync_method == SYNC_FINISH_SWAP_FINISH) { gl_finish(); swap_opengl_buffers(); gl_finish(); } else if (g_sync_method == SYNC_SLEEP_SWAP_FINISH) { sleep_until_vsync(); swap_opengl_buffers(); gl_finish(); } else if (g_sync_method == SYNC_FINISH_SLEEP_SWAP_FINISH) { gl_finish(); sleep_until_vsync(); swap_opengl_buffers(); gl_finish(); } else if (g_sync_method == SYNC_SWAP_FENCE) { swap_opengl_buffers(); opengl_fence(FENCE_SET); glFlush(); opengl_fence(FENCE_WAIT); } else if (g_sync_method == SYNC_SWAP_SLEEP_FENCE) { swap_opengl_buffers(); sleep_until_vsync(); opengl_fence(FENCE_SET); glFlush(); opengl_fence(FENCE_WAIT); } }
void fs_ml_render_iteration() { static int first = 1; if (first) { first = 0; initialize_opengl_sync(); } if (g_fs_ml_vblank_sync) { render_iteration_vsync(); } else if (g_fs_ml_benchmarking) { update_frame(); render_frame(); swap_opengl_buffers(); } else { // when vsync is off, we wait until a new frame is ready and // then we display it immediately if (fs_ml_is_quitting()) { // but when the emulation is quitting, we can't expect any new // frames so there's no point waiting for them. Instead, we just // sleep a bit to throttle the frame rate for the quit animation fs_ml_usleep(10000); } else { // wait max 33 ms to allow the user interface to work even if // the emu hangs // int64_t dest_time = fs_get_real_time() + 33 * 1000; int64_t end_time = fs_condition_get_wait_end_time(33 * 1000); int64_t check_time = 0; fs_mutex_lock(g_frame_available_mutex); // fs_log("cond wait until %lld\n", end_time); while (g_rendered_frame == g_available_frame) { fs_condition_wait_until( g_frame_available_cond, g_frame_available_mutex, end_time); check_time = fs_condition_get_wait_end_time(0); if (check_time >= end_time) { // fs_log("timed out at %lld\n", check_time); break; } else { // fs_log("wake-up at %lld (end_time = %lld)\n", check_time, end_time); } } fs_mutex_unlock(g_frame_available_mutex); } update_frame(); render_frame(); swap_opengl_buffers(); //gl_finish(); } if (g_fs_ml_video_screenshot_path) { fs_mutex_lock(g_fs_ml_video_screenshot_mutex); if (g_fs_ml_video_screenshot_path) { save_screenshot_of_opengl_framebuffer( g_fs_ml_video_screenshot_path); g_free(g_fs_ml_video_screenshot_path); g_fs_ml_video_screenshot_path = NULL; } fs_mutex_unlock(g_fs_ml_video_screenshot_mutex); } if (g_fs_ml_video_post_render_function) { g_fs_ml_video_post_render_function(); } }