static void sdl_refresh_viewport(sdl2_video_t *vid) { int win_w, win_h; settings_t *settings = config_get_ptr(); SDL_GetWindowSize(vid->window, &win_w, &win_h); vid->vp.x = 0; vid->vp.y = 0; vid->vp.width = win_w; vid->vp.height = win_h; vid->vp.full_width = win_w; vid->vp.full_height = win_h; if (settings->video.scale_integer) video_viewport_get_scaled_integer(&vid->vp, win_w, win_h, video_driver_get_aspect_ratio(), vid->video.force_aspect); else if (settings->video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM) { const struct video_viewport *custom = (const struct video_viewport*)video_viewport_get_custom(); if (custom) { vid->vp.x = custom->x; vid->vp.y = custom->y; vid->vp.width = custom->width; vid->vp.height = custom->height; } } else if (vid->video.force_aspect) { float delta; float device_aspect = (float)win_w / win_h; float desired_aspect = video_driver_get_aspect_ratio(); if (fabsf(device_aspect - desired_aspect) < 0.0001f) { /* If the aspect ratios of screen and desired aspect ratio are * sufficiently equal (floating point stuff), assume they are * actually equal. */ } else if (device_aspect > desired_aspect) { delta = (desired_aspect / device_aspect - 1.0f) / 2.0f + 0.5f; vid->vp.x = (int)roundf(win_w * (0.5f - delta)); vid->vp.width = (unsigned)roundf(2.0f * win_w * delta); } else { delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f; vid->vp.y = (int)roundf(win_h * (0.5f - delta)); vid->vp.height = (unsigned)roundf(2.0f * win_h * delta); } } vid->should_resize = false; sdl_refresh_renderer(vid); }
static bool dispmanx_gfx_frame(void *data, const void *frame, unsigned width, unsigned height, unsigned pitch, const char *msg) { struct dispmanx_video *_dispvars = data; if (width != _dispvars->surfaces[MAIN_SURFACE].width || height != _dispvars->surfaces[MAIN_SURFACE].height) { /* Sanity check. */ if (width == 0 || height == 0) return true; if (_dispvars->surfaces[MAIN_SURFACE].setup) dispmanx_surface_free(_dispvars, &_dispvars->surfaces[MAIN_SURFACE]); float aspect = video_driver_get_aspect_ratio(); /* Reconfiguring internal dimensions of the main surface is needed. */ dispmanx_surface_setup(_dispvars, width, height, pitch, aspect, &_dispvars->surfaces[MAIN_SURFACE]); } if (_dispvars->menu_active) { char buf[128]; video_monitor_get_fps(buf, sizeof(buf), NULL, 0); } /* Update main surface: locate free page, blit and flip. */ dispmanx_surface_update(_dispvars, frame, &_dispvars->surfaces[MAIN_SURFACE]); _dispvars->frame_count++; return true; }
void crt_switch_res_core(unsigned width, unsigned height, float hz, unsigned crt_mode, int crt_switch_center_adjust, int monitor_index, bool dynamic) { /* ra_core_hz float passed from within * void video_driver_monitor_adjust_system_rates(void) */ if (width == 4 ) { width = 320; height = 240; } ra_core_height = height; ra_core_hz = hz; if (dynamic == true) ra_core_width = crt_compute_dynamic_width(width); else ra_core_width = width; crt_center_adjust = crt_switch_center_adjust; crt_index = monitor_index; if (crt_mode == 2) { if (hz > 53) ra_core_hz = hz * 2; if (hz <= 53) ra_core_hz = 120.0f; } crt_check_first_run(); /* Detect resolution change and switch */ if ( (ra_tmp_height != ra_core_height) || (ra_core_width != ra_tmp_width) || (crt_center_adjust != crt_tmp_center_adjust) ) crt_screen_setup_aspect(ra_core_width, ra_core_height); ra_tmp_height = ra_core_height; ra_tmp_width = ra_core_width; crt_tmp_center_adjust = crt_center_adjust; /* Check if aspect is correct, if not change */ if (video_driver_get_aspect_ratio() != fly_aspect) { video_driver_set_aspect_ratio_value((float)fly_aspect); video_driver_apply_state_changes(); } }
static void vg_calculate_quad(vg_t *vg) { unsigned width, height; video_driver_get_size(&width, &height); /* set viewport for aspect ratio, taken from the OpenGL driver. */ if (vg->keep_aspect) { float desired_aspect = video_driver_get_aspect_ratio(); /* If the aspect ratios of screen and desired aspect ratio * are sufficiently equal (floating point stuff), * assume they are actually equal. */ if (fabs(vg->mScreenAspect - desired_aspect) < 0.0001) { vg->x1 = 0; vg->y1 = 0; vg->x2 = width; vg->y2 = height; } else if (vg->mScreenAspect > desired_aspect) { float delta = (desired_aspect / vg->mScreenAspect - 1.0) / 2.0 + 0.5; vg->x1 = width * (0.5 - delta); vg->y1 = 0; vg->x2 = 2.0 * width * delta + vg->x1; vg->y2 = height + vg->y1; } else { float delta = (vg->mScreenAspect / desired_aspect - 1.0) / 2.0 + 0.5; vg->x1 = 0; vg->y1 = height * (0.5 - delta); vg->x2 = width + vg->x1; vg->y2 = 2.0 * height * delta + vg->y1; } } else { vg->x1 = 0; vg->y1 = 0; vg->x2 = width; vg->y2 = height; } vg->scissor[0] = vg->x1; vg->scissor[1] = vg->y1; vg->scissor[2] = vg->x2 - vg->x1; vg->scissor[3] = vg->y2 - vg->y1; vgSetiv(VG_SCISSOR_RECTS, 4, vg->scissor); }
static void *drm_gfx_init(const video_info_t *video, const input_driver_t **input, void **input_data) { struct drm_video *_drmvars = (struct drm_video*) calloc(1, sizeof(struct drm_video)); if (!_drmvars) return NULL; /* Setup surface parameters */ _drmvars->menu_active = false; _drmvars->rgb32 = video->rgb32; /* It's very important that we set aspect here because the * call seq when a core is loaded is gfx_init()->set_aspect()->gfx_frame() * and we don't want the main surface to be setup in set_aspect() * before we get to gfx_frame(). */ _drmvars->current_aspect = video_driver_get_aspect_ratio(); /* Initialize the rest of the mutexes and conditions. */ _drmvars->vsync_condition = scond_new(); _drmvars->vsync_cond_mutex = slock_new(); _drmvars->pending_mutex = slock_new(); _drmvars->core_width = 0; _drmvars->core_height = 0; _drmvars->main_surface = NULL; _drmvars->menu_surface = NULL; if (input && input_data) *input = NULL; /* DRM Init */ if (!init_drm()) { RARCH_ERR ("DRM: Failed to initialize DRM\n"); return NULL; } else RARCH_LOG ("DRM: Init succesful.\n"); _drmvars->kms_width = drm.current_mode->hdisplay; _drmvars->kms_height = drm.current_mode->vdisplay; return _drmvars; }
/** * recording_init: * * Initializes recording. * * Returns: true (1) if successful, otherwise false (0). **/ bool recording_init(void) { char recording_file[PATH_MAX_LENGTH] = {0}; struct ffemu_params params = {0}; global_t *global = global_get_ptr(); settings_t *settings = config_get_ptr(); struct retro_system_av_info *av_info = video_viewport_get_system_av_info(); const struct retro_hw_render_callback *hw_render = (const struct retro_hw_render_callback*)video_driver_callback(); bool *recording_enabled = recording_is_enabled(); if (!*recording_enabled) return false; if (global->inited.core.type == CORE_TYPE_DUMMY) { RARCH_WARN("%s\n", msg_hash_to_str(MSG_USING_LIBRETRO_DUMMY_CORE_RECORDING_SKIPPED)); return false; } if (!settings->video.gpu_record && hw_render->context_type) { 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 (global->record.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 (*global->record.config) params.config = global->record.config; if (video_driver_ctl(RARCH_DISPLAY_CTL_SUPPORTS_RECORDING, NULL)) { unsigned gpu_size; struct video_viewport vp = {0}; video_driver_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->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; global->record.gpu_width = vp.width; global->record.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_ctl(RARCH_DISPLAY_CTL_GPU_RECORD_INIT, &gpu_size)) return false; } else { if (global->record.width || global->record.height) { params.out_width = global->record.width; params.out_height = global->record.height; } if (settings->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->video.post_filter_record && video_driver_ctl(RARCH_DISPLAY_CTL_FRAME_FILTER_ALIVE, NULL)) { unsigned max_width = 0; unsigned max_height = 0; params.pix_fmt = FFEMU_PIX_RGB565; if (video_driver_ctl(RARCH_DISPLAY_CTL_FRAME_FILTER_IS_32BIT, NULL)) 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)); event_command(EVENT_CMD_GPU_RECORD_DEINIT); return false; } return true; }
static void d3d_calculate_rect(void *data, unsigned *width, unsigned *height, int *x, int *y, bool force_full, bool allow_rotate) { float device_aspect = (float)*width / *height; d3d_video_t *d3d = (d3d_video_t*)data; settings_t *settings = config_get_ptr(); video_driver_get_size(width, height); gfx_ctx_translate_aspect(&device_aspect, *width, *height); *x = 0; *y = 0; if (settings->video.scale_integer && !force_full) { struct video_viewport vp = {0}; video_viewport_get_scaled_integer(&vp, *width, *height, video_driver_get_aspect_ratio(), d3d->keep_aspect); *x = vp.x; *y = vp.y; *width = vp.width; *height = vp.height; } else if (d3d->keep_aspect && !force_full) { float desired_aspect = video_driver_get_aspect_ratio(); #if defined(HAVE_MENU) if (settings->video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM) { video_viewport_t *custom = video_viewport_get_custom(); if (custom) { *x = custom->x; *y = custom->y; *width = custom->width; *height = custom->height; } } else #endif { float delta; if (fabsf(device_aspect - desired_aspect) < 0.0001f) { /* If the aspect ratios of screen and desired aspect * ratio are sufficiently equal (floating point stuff), * assume they are actually equal. */ } else if (device_aspect > desired_aspect) { delta = (desired_aspect / device_aspect - 1.0f) / 2.0f + 0.5f; *x = int(roundf(*width * (0.5f - delta))); *width = unsigned(roundf(2.0f * (*width) * delta)); } else { delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f; *y = int(roundf(*height * (0.5f - delta))); *height = unsigned(roundf(2.0f * (*height) * delta)); } } } }
static void vita2d_gfx_set_viewport(void *data, unsigned viewport_width, unsigned viewport_height, bool force_full, bool allow_rotate) { gfx_ctx_aspect_t aspect_data; unsigned width, height; int x = 0; int y = 0; float device_aspect = (float)viewport_width / viewport_height; struct video_ortho ortho = {0, 1, 1, 0, -1, 1}; settings_t *settings = config_get_ptr(); vita_video_t *vita = (vita_video_t*)data; video_driver_get_size(&width, &height); aspect_data.aspect = &device_aspect; aspect_data.width = viewport_width; aspect_data.height = viewport_height; video_context_driver_translate_aspect(&aspect_data); if (settings->video.scale_integer && !force_full) { video_viewport_get_scaled_integer(&vita->vp, viewport_width, viewport_height, video_driver_get_aspect_ratio(), vita->keep_aspect); viewport_width = vita->vp.width; viewport_height = vita->vp.height; } else if (vita->keep_aspect && !force_full) { float desired_aspect = video_driver_get_aspect_ratio(); #if defined(HAVE_MENU) if (settings->video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM) { const struct video_viewport *custom = video_viewport_get_custom(); /* Vukan has top-left origin viewport. */ x = custom->x; y = custom->y; viewport_width = custom->width; viewport_height = custom->height; } else #endif { float delta; if (fabsf(device_aspect - desired_aspect) < 0.0001f) { /* If the aspect ratios of screen and desired aspect * ratio are sufficiently equal (floating point stuff), * assume they are actually equal. */ } else if (device_aspect > desired_aspect) { delta = (desired_aspect / device_aspect - 1.0f) / 2.0f + 0.5f; x = (int)roundf(viewport_width * (0.5f - delta)); viewport_width = (unsigned)roundf(2.0f * viewport_width * delta); } else { delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f; y = (int)roundf(viewport_height * (0.5f - delta)); viewport_height = (unsigned)roundf(2.0f * viewport_height * delta); } } vita->vp.x = x; vita->vp.y = y; vita->vp.width = viewport_width; vita->vp.height = viewport_height; } else { vita->vp.x = 0; vita->vp.y = 0; vita->vp.width = viewport_width; vita->vp.height = viewport_height; } vita2d_set_projection(vita, &ortho, allow_rotate); /* Set last backbuffer viewport. */ if (!force_full) { vita->vp.width = viewport_width; vita->vp.height = viewport_height; } #if 0 vita->vp.x = (float)vita->vp.x; vita->vp.y = (float)vita->vp.y; vita->vp.width = (float)vita->vp.width; vita->vp.height = (float)vita->vp.height; vita->vp.minDepth = 0.0f; vita->vp.maxDepth = 1.0f; RARCH_LOG("Setting viewport @ %ux%u\n", viewport_width, viewport_height); #endif }
static void vita2d_gfx_update_viewport(vita_video_t* vita) { int x = 0; int y = 0; float device_aspect = ((float)PSP_FB_WIDTH) / PSP_FB_HEIGHT; float width = PSP_FB_WIDTH; float height = PSP_FB_HEIGHT; settings_t *settings = config_get_ptr(); if (settings->video.scale_integer) { video_viewport_get_scaled_integer(&vita->vp, PSP_FB_WIDTH, PSP_FB_HEIGHT, video_driver_get_aspect_ratio(), vita->keep_aspect); width = vita->vp.width; height = vita->vp.height; } else if (vita->keep_aspect) { float desired_aspect = video_driver_get_aspect_ratio(); if ( (vita->rotation == ORIENTATION_VERTICAL) || (vita->rotation == ORIENTATION_FLIPPED_ROTATED)) { device_aspect = 1.0 / device_aspect; width = PSP_FB_HEIGHT; height = PSP_FB_WIDTH; } #if defined(HAVE_MENU) if (settings->video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM) { struct video_viewport *custom = video_viewport_get_custom(); if (custom) { x = custom->x; y = custom->y; width = custom->width; height = custom->height; } } else #endif { float delta; if ((fabsf(device_aspect - desired_aspect) < 0.0001f)) { /* If the aspect ratios of screen and desired aspect * ratio are sufficiently equal (floating point stuff), * assume they are actually equal. */ } else if (device_aspect > desired_aspect) { delta = (desired_aspect / device_aspect - 1.0f) / 2.0f + 0.5f; x = (int)roundf(width * (0.5f - delta)); width = (unsigned)roundf(2.0f * width * delta); } else { delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f; y = (int)roundf(height * (0.5f - delta)); height = (unsigned)roundf(2.0f * height * delta); } if ( (vita->rotation == ORIENTATION_VERTICAL) || (vita->rotation == ORIENTATION_FLIPPED_ROTATED) ) { x = (PSP_FB_WIDTH - width) * 0.5f; y = (PSP_FB_HEIGHT - height) * 0.5f; } } vita->vp.x = x; vita->vp.y = y; vita->vp.width = width; vita->vp.height = height; } else { vita->vp.x = vita->vp.y = 0; vita->vp.width = width; vita->vp.height = height; } vita->vp.width += vita->vp.width&0x1; vita->vp.height += vita->vp.height&0x1; vita->should_resize = false; }
void init_video(void) { unsigned max_dim, scale, width, height; video_viewport_t *custom_vp = NULL; const input_driver_t *tmp = NULL; const struct retro_game_geometry *geom = NULL; video_info_t video = {0}; static uint16_t dummy_pixels[32] = {0}; driver_t *driver = driver_get_ptr(); global_t *global = global_get_ptr(); settings_t *settings = config_get_ptr(); struct retro_system_av_info *av_info = video_viewport_get_system_av_info(); init_video_filter(video_state.pix_fmt); event_command(EVENT_CMD_SHADER_DIR_INIT); if (av_info) geom = (const struct retro_game_geometry*)&av_info->geometry; max_dim = max(geom->max_width, geom->max_height); scale = next_pow2(max_dim) / RARCH_SCALE_BASE; scale = max(scale, 1); if (video_state.filter.filter) scale = video_state.filter.scale; /* Update core-dependent aspect ratio values. */ video_viewport_set_square_pixel(geom->base_width, geom->base_height); video_viewport_set_core(); video_viewport_set_config(); /* Update CUSTOM viewport. */ custom_vp = video_viewport_get_custom(); if (settings->video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM) { float default_aspect = aspectratio_lut[ASPECT_RATIO_CORE].value; aspectratio_lut[ASPECT_RATIO_CUSTOM].value = (custom_vp->width && custom_vp->height) ? (float)custom_vp->width / custom_vp->height : default_aspect; } video_driver_set_aspect_ratio_value( aspectratio_lut[settings->video.aspect_ratio_idx].value); if (settings->video.fullscreen) { width = settings->video.fullscreen_x; height = settings->video.fullscreen_y; } else { if (settings->video.force_aspect) { /* Do rounding here to simplify integer scale correctness. */ unsigned base_width = roundf(geom->base_height * video_driver_get_aspect_ratio()); width = roundf(base_width * settings->video.scale); } else width = roundf(geom->base_width * settings->video.scale); height = roundf(geom->base_height * settings->video.scale); } if (width && height) RARCH_LOG("Video @ %ux%u\n", width, height); else RARCH_LOG("Video @ fullscreen\n"); driver->display_type = RARCH_DISPLAY_NONE; driver->video_display = 0; driver->video_window = 0; if (!init_video_pixel_converter(RARCH_SCALE_BASE * scale)) { RARCH_ERR("Failed to initialize pixel converter.\n"); rarch_fail(1, "init_video()"); } video.width = width; video.height = height; video.fullscreen = settings->video.fullscreen; video.vsync = settings->video.vsync && !global->system.force_nonblock; video.force_aspect = settings->video.force_aspect; #ifdef GEKKO video.viwidth = settings->video.viwidth; video.vfilter = settings->video.vfilter; #endif video.smooth = settings->video.smooth; video.input_scale = scale; video.rgb32 = video_state.filter.filter ? video_state.filter.out_rgb32 : (video_state.pix_fmt == RETRO_PIXEL_FORMAT_XRGB8888); tmp = (const input_driver_t*)driver->input; /* Need to grab the "real" video driver interface on a reinit. */ find_video_driver(); #ifdef HAVE_THREADS if (settings->video.threaded && !video_state.hw_render_callback.context_type) { /* Can't do hardware rendering with threaded driver currently. */ RARCH_LOG("Starting threaded video driver ...\n"); if (!rarch_threaded_video_init(&driver->video, &driver->video_data, &driver->input, &driver->input_data, driver->video, &video)) { RARCH_ERR("Cannot open threaded video driver ... Exiting ...\n"); rarch_fail(1, "init_video()"); } } else #endif driver->video_data = driver->video->init(&video, &driver->input, &driver->input_data); if (!driver->video_data) { RARCH_ERR("Cannot open video driver ... Exiting ...\n"); rarch_fail(1, "init_video()"); } driver->video_poke = NULL; if (driver->video->poke_interface) driver->video->poke_interface(driver->video_data, &driver->video_poke); if (driver->video->viewport_info && (!custom_vp->width || !custom_vp->height)) { /* Force custom viewport to have sane parameters. */ custom_vp->width = width; custom_vp->height = height; video_driver_viewport_info(custom_vp); } video_driver_set_rotation( (settings->video.rotation + global->system.rotation) % 4); video_driver_suppress_screensaver(settings->ui.suspend_screensaver_enable); if (!driver->input) init_video_input(tmp); event_command(EVENT_CMD_OVERLAY_DEINIT); event_command(EVENT_CMD_OVERLAY_INIT); video_driver_cached_frame_set(&dummy_pixels, 4, 4, 8); #if defined(PSP) video_driver_set_texture_frame(&dummy_pixels, false, 1, 1, 1.0f); #endif }
static void psp_update_viewport(psp1_video_t* psp) { int x = 0; int y = 0; float device_aspect = ((float)SCEGU_SCR_WIDTH) / SCEGU_SCR_HEIGHT; float width = SCEGU_SCR_WIDTH; float height = SCEGU_SCR_HEIGHT; settings_t *settings = config_get_ptr(); if (settings->video.scale_integer) { video_viewport_get_scaled_integer(&psp->vp, SCEGU_SCR_WIDTH, SCEGU_SCR_HEIGHT, video_driver_get_aspect_ratio(), psp->keep_aspect); width = psp->vp.width; height = psp->vp.height; } else if (psp->keep_aspect) { float delta; float desired_aspect = video_driver_get_aspect_ratio(); #if defined(HAVE_MENU) if (settings->video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM) { struct video_viewport *custom = video_viewport_get_custom(); if (custom) { x = custom->x; y = custom->y; width = custom->width; height = custom->height; } } else #endif { if ((fabsf(device_aspect - desired_aspect) < 0.0001f) || (fabsf((16.0/9.0) - desired_aspect) < 0.02f)) { /* If the aspect ratios of screen and desired aspect * ratio are sufficiently equal (floating point stuff), * assume they are actually equal. */ } else if (device_aspect > desired_aspect) { delta = (desired_aspect / device_aspect - 1.0f) / 2.0f + 0.5f; x = (int)roundf(width * (0.5f - delta)); width = (unsigned)roundf(2.0f * width * delta); } else { delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f; y = (int)roundf(height * (0.5f - delta)); height = (unsigned)roundf(2.0f * height * delta); } } psp->vp.x = x; psp->vp.y = y; psp->vp.width = width; psp->vp.height = height; } else { psp->vp.x = psp->vp.y = 0; psp->vp.width = width; psp->vp.height = height; } psp->vp.width += psp->vp.width&0x1; psp->vp.height += psp->vp.height&0x1; psp_set_screen_coords(psp->frame_coords, psp->vp.x, psp->vp.y, psp->vp.width, psp->vp.height, psp->rotation); psp->should_resize = false; }
static void wiiu_gfx_update_viewport(wiiu_video_t* wiiu) { int x = 0; int y = 0; float width = wiiu->vp.full_width; float height = wiiu->vp.full_height; settings_t *settings = config_get_ptr(); float desired_aspect = video_driver_get_aspect_ratio(); if(wiiu->rotation & 0x1) desired_aspect = 1.0 / desired_aspect; if (settings->video.scale_integer) { video_viewport_get_scaled_integer(&wiiu->vp, wiiu->vp.full_width, wiiu->vp.full_height, desired_aspect, wiiu->keep_aspect); } else if (wiiu->keep_aspect) { #if defined(HAVE_MENU) if (settings->video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM) { struct video_viewport *custom = video_viewport_get_custom(); if (custom) { x = custom->x; y = custom->y; width = custom->width; height = custom->height; } } else #endif { float delta; float device_aspect = ((float)wiiu->vp.full_width) / wiiu->vp.full_height; if (fabsf(device_aspect - desired_aspect) < 0.0001f) { /* If the aspect ratios of screen and desired aspect * ratio are sufficiently equal (floating point stuff), * assume they are actually equal. */ } else if (device_aspect > desired_aspect) { delta = (desired_aspect / device_aspect - 1.0f) / 2.0f + 0.5f; x = (int)roundf(width * (0.5f - delta)); width = (unsigned)roundf(2.0f * width * delta); } else { delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f; y = (int)roundf(height * (0.5f - delta)); height = (unsigned)roundf(2.0f * height * delta); } } wiiu->vp.x = x; wiiu->vp.y = y; wiiu->vp.width = width; wiiu->vp.height = height; } else { wiiu->vp.x = wiiu->vp.y = 0; wiiu->vp.width = width; wiiu->vp.height = height; } float scale_w = wiiu->color_buffer.surface.width / 854.0; float scale_h = wiiu->color_buffer.surface.height / 480.0; wiiu_set_position(wiiu->position, &wiiu->color_buffer, wiiu->vp.x * scale_w, wiiu->vp.y * scale_h, (wiiu->vp.x + wiiu->vp.width) * scale_w, (wiiu->vp.y + wiiu->vp.height) * scale_h); wiiu->should_resize = false; DEBUG_LINE(); }
/** * recording_init: * * Initializes recording. * * Returns: true (1) if successful, otherwise false (0). **/ bool recording_init(void) { char recording_file[PATH_MAX_LENGTH] = {0}; struct ffemu_params params = {0}; global_t *global = global_get_ptr(); driver_t *driver = driver_get_ptr(); settings_t *settings = config_get_ptr(); struct retro_system_av_info *av_info = video_viewport_get_system_av_info(); const struct retro_hw_render_callback *hw_render = (const struct retro_hw_render_callback*)video_driver_callback(); if (!global->record.enable) return false; if (global->libretro_dummy) { RARCH_WARN(RETRO_LOG_INIT_RECORDING_SKIPPED); return false; } if (!settings->video.gpu_record && hw_render->context_type) { RARCH_WARN("Libretro core is hardware rendered. Must use post-shaded recording as well.\n"); return false; } RARCH_LOG("Custom timing given: FPS: %.4f, Sample rate: %.4f\n", (float)av_info->timing.fps, (float)av_info->timing.sample_rate); strlcpy(recording_file, global->record.path, sizeof(recording_file)); if (global->record.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 (*global->record.config) params.config = global->record.config; if (settings->video.gpu_record && driver->video->read_viewport) { struct video_viewport vp = {0}; video_driver_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->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; global->record.gpu_width = vp.width; global->record.gpu_height = vp.height; RARCH_LOG("Detected viewport of %u x %u\n", vp.width, vp.height); global->record.gpu_buffer = (uint8_t*)malloc(vp.width * vp.height * 3); if (!global->record.gpu_buffer) { RARCH_ERR("Failed to allocate GPU record buffer.\n"); return false; } } else { if (global->record.width || global->record.height) { params.out_width = global->record.width; params.out_height = global->record.height; } if (settings->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->video.post_filter_record && video_driver_frame_filter_alive()) { unsigned max_width = 0; unsigned max_height = 0; if (video_driver_frame_filter_is_32bit()) params.pix_fmt = FFEMU_PIX_ARGB8888; else params.pix_fmt = FFEMU_PIX_RGB565; 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("Recording to %s @ %ux%u. (FB size: %ux%u pix_fmt: %u)\n", global->record.path, params.out_width, params.out_height, params.fb_width, params.fb_height, (unsigned)params.pix_fmt); if (!record_driver_init_first(&driver->recording, &driver->recording_data, ¶ms)) { RARCH_ERR(RETRO_LOG_INIT_RECORDING_FAILED); event_command(EVENT_CMD_GPU_RECORD_DEINIT); return false; } return true; }
void gl1_gfx_set_viewport(gl1_t *gl1, video_frame_info_t *video_info, unsigned viewport_width, unsigned viewport_height, bool force_full, bool allow_rotate) { gfx_ctx_aspect_t aspect_data; int x = 0; int y = 0; float device_aspect = (float)viewport_width / viewport_height; unsigned height = video_info->height; aspect_data.aspect = &device_aspect; aspect_data.width = viewport_width; aspect_data.height = viewport_height; video_context_driver_translate_aspect(&aspect_data); if (video_info->scale_integer && !force_full) { video_viewport_get_scaled_integer(&gl1->vp, viewport_width, viewport_height, video_driver_get_aspect_ratio(), gl1->keep_aspect); viewport_width = gl1->vp.width; viewport_height = gl1->vp.height; } else if (gl1->keep_aspect && !force_full) { float desired_aspect = video_driver_get_aspect_ratio(); #if defined(HAVE_MENU) if (video_info->aspect_ratio_idx == ASPECT_RATIO_CUSTOM) { /* GL has bottom-left origin viewport. */ x = video_info->custom_vp_x; y = height - video_info->custom_vp_y - video_info->custom_vp_height; viewport_width = video_info->custom_vp_width; viewport_height = video_info->custom_vp_height; } else #endif { float delta; if (fabsf(device_aspect - desired_aspect) < 0.0001f) { /* If the aspect ratios of screen and desired aspect * ratio are sufficiently equal (floating point stuff), * assume they are actually equal. */ } else if (device_aspect > desired_aspect) { delta = (desired_aspect / device_aspect - 1.0f) / 2.0f + 0.5f; x = (int)roundf(viewport_width * (0.5f - delta)); viewport_width = (unsigned)roundf(2.0f * viewport_width * delta); } else { delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f; y = (int)roundf(viewport_height * (0.5f - delta)); viewport_height = (unsigned)roundf(2.0f * viewport_height * delta); } } gl1->vp.x = x; gl1->vp.y = y; gl1->vp.width = viewport_width; gl1->vp.height = viewport_height; } else { gl1->vp.x = gl1->vp.y = 0; gl1->vp.width = viewport_width; gl1->vp.height = viewport_height; } #if defined(RARCH_MOBILE) /* In portrait mode, we want viewport to gravitate to top of screen. */ if (device_aspect < 1.0f) gl1->vp.y *= 2; #endif glViewport(gl1->vp.x, gl1->vp.y, gl1->vp.width, gl1->vp.height); gl1_set_projection(gl1, &gl1_default_ortho, allow_rotate); /* Set last backbuffer viewport. */ if (!force_full) { gl1->vp_out_width = viewport_width; gl1->vp_out_height = viewport_height; } #if 0 RARCH_LOG("Setting viewport @ %ux%u\n", viewport_width, viewport_height); #endif }
static void *sunxi_gfx_init(const video_info_t *video, const input_driver_t **input, void **input_data) { struct sunxi_video *_dispvars = (struct sunxi_video*) calloc(1, sizeof(struct sunxi_video)); if (!_dispvars) return NULL; _dispvars->src_bytes_per_pixel = video->rgb32 ? 4 : 2; _dispvars->sunxi_disp = sunxi_disp_init("/dev/fb0"); /* Blank text console and disable cursor blinking. */ sunxi_blank_console(_dispvars); _dispvars->pages = (struct sunxi_page*)calloc(NUMPAGES, sizeof (struct sunxi_page)); if (!_dispvars->pages) goto error; _dispvars->dst_pitch = _dispvars->sunxi_disp->xres * _dispvars->sunxi_disp->bits_per_pixel / 8; /* Considering 4 bytes per pixel since we will be in 32bpp on the CB/CB2/CT for hw scalers to work. */ _dispvars->dst_pixels_per_line = _dispvars->dst_pitch / 4; _dispvars->pageflip_pending = false; _dispvars->nextPage = &_dispvars->pages[0]; _dispvars->keep_vsync = true; _dispvars->menu_active = false; _dispvars->bytes_per_pixel = video->rgb32 ? 4 : 2; /* It's very important that we set aspect here because the * call seq when a core is loaded is gfx_init()->set_aspect()->gfx_frame() * and we don't want the main surface to be setup in set_aspect() * before we get to gfx_frame(). */ _dispvars->aspect_ratio = video_driver_get_aspect_ratio(); switch (_dispvars->bytes_per_pixel) { case 2: pixman_blit = pixman_composite_src_0565_8888_asm_neon; break; case 4: pixman_blit = pixman_composite_src_8888_8888_asm_neon; break; default: goto error; } _dispvars->pending_mutex = slock_new(); _dispvars->vsync_condition = scond_new(); if (input && input_data) *input = NULL; /* Launching vsync thread */ _dispvars->vsync_thread = sthread_create(sunxi_vsync_thread_func, _dispvars); return _dispvars; error: if (_dispvars) free(_dispvars); return NULL; }
static void ctr_update_viewport(ctr_video_t* ctr) { int x = 0; int y = 0; float device_aspect = ((float)ctr->vp.full_width) / ctr->vp.full_height; float width = ctr->vp.full_width; float height = ctr->vp.full_height; settings_t *settings = config_get_ptr(); if (settings->video.scale_integer) { video_viewport_get_scaled_integer(&ctr->vp, ctr->vp.full_width, ctr->vp.full_height, video_driver_get_aspect_ratio(), ctr->keep_aspect); width = ctr->vp.width; height = ctr->vp.height; } else if (ctr->keep_aspect) { #if defined(HAVE_MENU) if (settings->video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM) { struct video_viewport *custom = video_viewport_get_custom(); if (custom) { x = custom->x; y = custom->y; width = custom->width; height = custom->height; } } else #endif { float delta; float desired_aspect = video_driver_get_aspect_ratio(); if (fabsf(device_aspect - desired_aspect) < 0.0001f) { /* If the aspect ratios of screen and desired aspect * ratio are sufficiently equal (floating point stuff), * assume they are actually equal. */ } else if (device_aspect > desired_aspect) { delta = (desired_aspect / device_aspect - 1.0f) / 2.0f + 0.5f; x = (int)roundf(width * (0.5f - delta)); width = (unsigned)roundf(2.0f * width * delta); } else { delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f; y = (int)roundf(height * (0.5f - delta)); height = (unsigned)roundf(2.0f * height * delta); } } ctr->vp.x = x; ctr->vp.y = y; ctr->vp.width = width; ctr->vp.height = height; } else { ctr->vp.x = ctr->vp.y = 0; ctr->vp.width = width; ctr->vp.height = height; } ctr_set_screen_coords(ctr); ctr->should_resize = false; }