void SDLRenderer::apply_viewport() { Size target_size = (g_config->use_fullscreen && g_config->fullscreen_size != Size(0, 0)) ? g_config->fullscreen_size : g_config->window_size; float pixel_aspect_ratio = 1.0f; if (g_config->aspect_size != Size(0, 0)) { pixel_aspect_ratio = calculate_pixel_aspect_ratio(m_desktop_size, g_config->aspect_size); } else if (g_config->use_fullscreen) { pixel_aspect_ratio = calculate_pixel_aspect_ratio(m_desktop_size, target_size); } // calculate the viewport Size max_size(1280, 800); Size min_size(640, 480); Size logical_size; calculate_viewport(min_size, max_size, target_size, pixel_aspect_ratio, g_config->magnification, m_scale, logical_size, m_viewport); SCREEN_WIDTH = logical_size.width; SCREEN_HEIGHT = logical_size.height; if (m_viewport.x != 0 || m_viewport.y != 0) { // Clear the screen to avoid garbage in unreachable areas after we // reset the coordinate system SDL_SetRenderDrawColor(m_renderer, 0, 0, 0, 255); SDL_SetRenderDrawBlendMode(m_renderer, SDL_BLENDMODE_NONE); SDL_RenderClear(m_renderer); SDL_RenderPresent(m_renderer); SDL_RenderClear(m_renderer); } // SetViewport() works in scaled screen coordinates, so we have to // reset it to 1.0, 1.0 to get meaningful results SDL_RenderSetScale(m_renderer, 1.0f, 1.0f); SDL_RenderSetViewport(m_renderer, &m_viewport); SDL_RenderSetScale(m_renderer, m_scale.x, m_scale.y); }
void Video::set_2d_view(const std::pair<Point2f, Point2f> &camera2d, const std::pair<Point2i, Point2i> &viewport, const bool &fix_aspect_ratio) { m_3d = false; set_viewport(calculate_viewport(camera2d, viewport, fix_aspect_ratio)); const Matrix4f view = Matrix4f::Identity(); set_view_matrix(view); const std::pair<Point2i, Point2i> &vp = get_viewport(); Point2f offset = get_pixel_offset(); offset.x *= (camera2d.second.x - camera2d.first.x) / (vp.second.x - vp.first.x); offset.y *= (camera2d.second.y - camera2d.first.y) / (vp.second.y - vp.first.y); const Matrix4f projection = Matrix4f::Orthographic(camera2d.first.x + offset.x, camera2d.second.x + offset.x, camera2d.second.y + offset.y, camera2d.first.y + offset.y, ZENI_2D_NEAR, ZENI_2D_FAR); set_projection_matrix(projection); }
void calculate_viewport(const Size& min_size, const Size& max_size, const Size& real_window_size, float pixel_aspect_ratio, float magnification, Vector& out_scale, Size& out_logical_size, SDL_Rect& out_viewport) { // Transform the real window_size by the aspect ratio, then do // calculations on that virtual window_size Size window_size = apply_pixel_aspect_ratio_pre(real_window_size, pixel_aspect_ratio); float scale = calculate_scale(min_size, max_size, window_size, magnification); // Calculate the new viewport size out_viewport = calculate_viewport(max_size, window_size, scale); out_logical_size.width = static_cast<int>(out_viewport.w / scale); out_logical_size.height = static_cast<int>(out_viewport.h / scale); // Transform the virtual window_size back into real window coordinates apply_pixel_aspect_ratio_post(real_window_size, window_size, scale, out_viewport, out_scale); }
std::pair<Point2i, Point2i> Video::calculate_viewport(const std::pair<Point2f, Point2f> &camera2d, const std::pair<Point2i, Point2i> &viewport, const bool &fix_aspect_ratio) { if(fix_aspect_ratio) return calculate_viewport((camera2d.second.x - camera2d.first.x) / (camera2d.second.y - camera2d.first.y), viewport); else return viewport; }
void Video::set_viewport(const float &aspect_ratio, const std::pair<Point2i, Point2i> &viewport_) { set_viewport(calculate_viewport(aspect_ratio, viewport_)); }
static bool dce110_transform_v_set_scaler( struct transform *xfm, const struct scaler_data *data) { struct dce110_transform *xfm110 = TO_DCE110_TRANSFORM(xfm); bool is_scaling_required = false; bool filter_updated = false; struct rect luma_viewport = {0}; struct rect chroma_viewport = {0}; struct dc_context *ctx = xfm->ctx; /* 1. Calculate viewport, viewport programming should happen after init * calculations as they may require an adjustment in the viewport. */ calculate_viewport(data, &luma_viewport, &chroma_viewport); /* 2. Program overscan */ program_overscan(xfm110, &data->overscan); /* 3. Program taps and configuration */ is_scaling_required = setup_scaling_configuration(xfm110, data); if (is_scaling_required) { /* 4. Calculate and program ratio, filter initialization */ struct sclv_ratios_inits inits = { 0 }; calculate_inits( xfm110, data, &inits, &luma_viewport, &chroma_viewport); program_scl_ratios_inits(xfm110, &inits); /*scaler coeff of 2-TAPS use hardware auto calculated value*/ /* 5. Program vertical filters */ if (data->taps.v_taps > 2) { program_two_taps_filter_vert(xfm110, false); if (!program_multi_taps_filter(xfm110, data, false)) { dal_logger_write(ctx->logger, LOG_MAJOR_DCP, LOG_MINOR_DCP_SCALER, "Failed vertical taps programming\n"); return false; } filter_updated = true; } else program_two_taps_filter_vert(xfm110, true); /* 6. Program horizontal filters */ if (data->taps.h_taps > 2) { program_two_taps_filter_horz(xfm110, false); if (!program_multi_taps_filter(xfm110, data, true)) { dal_logger_write(ctx->logger, LOG_MAJOR_DCP, LOG_MINOR_DCP_SCALER, "Failed horizontal taps programming\n"); return false; } filter_updated = true; } else program_two_taps_filter_horz(xfm110, true); } /* 7. Program the viewport */ program_viewport(xfm110, &luma_viewport, &chroma_viewport); /* 8. Set bit to flip to new coefficient memory */ if (filter_updated) set_coeff_update_complete(xfm110); return true; }