font_data_t *font_driver_init_first( void *video_data, const char *font_path, float font_size, bool threading_hint, enum font_driver_render_api api) { const void *font_driver; void *font_handle; bool ok = false; #ifdef HAVE_THREADS settings_t *settings = config_get_ptr(); if (threading_hint && settings->video.threaded && !video_driver_is_hw_context()) ok = video_thread_font_init(&font_driver, &font_handle, video_data, font_path, font_size, api, font_init_first); else #endif ok = font_init_first(&font_driver, &font_handle, video_data, font_path, font_size, api); if (ok) { font_data_t *font = (font_data_t*)calloc(1, sizeof(*font)); font->renderer = (const font_renderer_t*)font_driver; font->renderer_data = font_handle; font->size = font_size; return font; } return NULL; }
/** * recording_init: * * Initializes recording. * * Returns: true (1) if successful, otherwise false (0). **/ bool recording_init(void) { char recording_file[PATH_MAX_LENGTH]; struct ffemu_params params = {0}; struct retro_system_av_info *av_info = video_viewport_get_system_av_info(); bool *recording_enabled = recording_is_enabled(); settings_t *settings = config_get_ptr(); global_t *global = global_get_ptr(); if (!*recording_enabled) return false; recording_file[0] = '\0'; if (rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL)) { RARCH_WARN("%s\n", msg_hash_to_str(MSG_USING_LIBRETRO_DUMMY_CORE_RECORDING_SKIPPED)); return false; } if (!settings->bools.video_gpu_record && video_driver_is_hw_context()) { RARCH_WARN("%s.\n", msg_hash_to_str(MSG_HW_RENDERED_MUST_USE_POSTSHADED_RECORDING)); return false; } RARCH_LOG("%s: FPS: %.4f, Sample rate: %.4f\n", msg_hash_to_str(MSG_CUSTOM_TIMING_GIVEN), (float)av_info->timing.fps, (float)av_info->timing.sample_rate); strlcpy(recording_file, global->record.path, sizeof(recording_file)); if (recording_use_output_dir) fill_pathname_join(recording_file, global->record.output_dir, global->record.path, sizeof(recording_file)); params.out_width = av_info->geometry.base_width; params.out_height = av_info->geometry.base_height; params.fb_width = av_info->geometry.max_width; params.fb_height = av_info->geometry.max_height; params.channels = 2; params.filename = recording_file; params.fps = av_info->timing.fps; params.samplerate = av_info->timing.sample_rate; params.pix_fmt = (video_driver_get_pixel_format() == RETRO_PIXEL_FORMAT_XRGB8888) ? FFEMU_PIX_ARGB8888 : FFEMU_PIX_RGB565; params.config = NULL; if (!string_is_empty(global->record.config)) params.config = global->record.config; if (video_driver_supports_recording()) { unsigned gpu_size; struct video_viewport vp; vp.x = 0; vp.y = 0; vp.width = 0; vp.height = 0; vp.full_width = 0; vp.full_height = 0; video_driver_get_viewport_info(&vp); if (!vp.width || !vp.height) { RARCH_ERR("Failed to get viewport information from video driver. " "Cannot start recording ...\n"); return false; } params.out_width = vp.width; params.out_height = vp.height; params.fb_width = next_pow2(vp.width); params.fb_height = next_pow2(vp.height); if (settings->bools.video_force_aspect && (video_driver_get_aspect_ratio() > 0.0f)) params.aspect_ratio = video_driver_get_aspect_ratio(); else params.aspect_ratio = (float)vp.width / vp.height; params.pix_fmt = FFEMU_PIX_BGR24; recording_gpu_width = vp.width; recording_gpu_height = vp.height; RARCH_LOG("%s %u x %u\n", msg_hash_to_str(MSG_DETECTED_VIEWPORT_OF), vp.width, vp.height); gpu_size = vp.width * vp.height * 3; if (!video_driver_gpu_record_init(gpu_size)) return false; } else { if (recording_width || recording_height) { params.out_width = recording_width; params.out_height = recording_height; } if (settings->bools.video_force_aspect && (video_driver_get_aspect_ratio() > 0.0f)) params.aspect_ratio = video_driver_get_aspect_ratio(); else params.aspect_ratio = (float)params.out_width / params.out_height; if (settings->bools.video_post_filter_record && video_driver_frame_filter_alive()) { unsigned max_width = 0; unsigned max_height = 0; params.pix_fmt = FFEMU_PIX_RGB565; if (video_driver_frame_filter_is_32bit()) params.pix_fmt = FFEMU_PIX_ARGB8888; rarch_softfilter_get_max_output_size( video_driver_frame_filter_get_ptr(), &max_width, &max_height); params.fb_width = next_pow2(max_width); params.fb_height = next_pow2(max_height); } } RARCH_LOG("%s %s @ %ux%u. (FB size: %ux%u pix_fmt: %u)\n", msg_hash_to_str(MSG_RECORDING_TO), global->record.path, params.out_width, params.out_height, params.fb_width, params.fb_height, (unsigned)params.pix_fmt); if (!record_driver_init_first(&recording_driver, &recording_data, ¶ms)) { RARCH_ERR("%s\n", msg_hash_to_str(MSG_FAILED_TO_START_RECORDING)); command_event(CMD_EVENT_GPU_RECORD_DEINIT, NULL); return false; } return true; }