#include #include "Common/System/Display.h" #include "Common/Math/math_util.h" #include "Common/GPU/MiscTypes.h" DisplayProperties g_display; DeviceOrientation DisplayProperties::GetDeviceOrientation() const { return (dp_yres > dp_xres * 1.1f) ? DeviceOrientation::Portrait : DeviceOrientation::Landscape; } std::string_view DeviceOrientationToString(DeviceOrientation orientation) { switch (orientation) { case DeviceOrientation::Landscape: return "Landscape"; case DeviceOrientation::Portrait: return "Portrait"; default: return "N/A"; } } template void RotateRectToDisplayImpl(DisplayRect &rect, T curRTWidth, T curRTHeight) { switch (g_display.rotation) { case DisplayRotation::ROTATE_180: rect.x = curRTWidth - rect.w - rect.x; rect.y = curRTHeight - rect.h - rect.y; break; case DisplayRotation::ROTATE_90: { // Note that curRTWidth_ and curRTHeight_ are "swapped"! T origX = rect.x; T origY = rect.y; T rth = curRTWidth; rect.x = clamp_value(rth - rect.h - origY, T{}, curRTHeight); rect.y = origX; T temp = rect.w; rect.w = rect.h; rect.h = temp; break; } case DisplayRotation::ROTATE_270: { T origX = rect.x; T origY = rect.y; T rtw = curRTHeight; rect.x = origY; rect.y = clamp_value(rtw - rect.w - origX, T{}, curRTWidth); T temp = rect.w; rect.w = rect.h; rect.h = temp; break; } case DisplayRotation::ROTATE_0: default: break; } } void RotateRectToDisplay(DisplayRect &rect, int curRTWidth, int curRTHeight) { RotateRectToDisplayImpl(rect, curRTWidth, curRTHeight); } void RotateRectToDisplay(DisplayRect &rect, float curRTWidth, float curRTHeight) { RotateRectToDisplayImpl(rect, curRTWidth, curRTHeight); } DisplayProperties::DisplayProperties() { rot_matrix.setIdentity(); } bool DisplayProperties::Recalculate(int new_pixel_xres, int new_pixel_yres, float new_scale_x, float new_scale_y, float customScale) { bool px_changed = false; if (new_pixel_xres > 0 && pixel_xres != new_pixel_xres) { pixel_xres = new_pixel_xres; px_changed = true; } if (new_pixel_yres > 0 && pixel_yres != new_pixel_yres) { pixel_yres = new_pixel_yres; px_changed = true; } if (new_scale_x > 0) { dpi_scale_real_x = new_scale_x; } if (new_scale_y > 0) { dpi_scale_real_y = new_scale_y; } dpi_scale_x = dpi_scale_real_x / customScale; dpi_scale_y = dpi_scale_real_y / customScale; pixel_in_dps_x = 1.0f / dpi_scale_x; pixel_in_dps_y = 1.0f / dpi_scale_y; int new_dp_xres = (int)(pixel_xres * dpi_scale_x); int new_dp_yres = (int)(pixel_yres * dpi_scale_y); if (new_dp_xres != dp_xres || new_dp_yres != dp_yres || px_changed) { dp_xres = new_dp_xres; dp_yres = new_dp_yres; return true; } else { return false; } } void DisplayProperties::Print() { printf("dp_xres/yres: %d, %d\n", dp_xres, dp_yres); printf("pixel_xres/yres: %d, %d\n", pixel_xres, pixel_yres); printf("dpi_scale: %f, %f\n", dpi_scale_x, dpi_scale_y); printf("pixel_in_dps: %f, %f\n", pixel_in_dps_x, pixel_in_dps_y); printf("dpi_real: %f, %f\n", dpi_scale_real_x, dpi_scale_real_y); printf("display_hz: %f\n", display_hz); printf("rotation: %d\n", (int)rotation); rot_matrix.print(); } // Y-flip compensation is done elsewhere now. Lin::Matrix4x4 ComputeOrthoMatrix(float xres, float yres, CoordConvention coordConvention) { using namespace Lin; Matrix4x4 ortho; switch (coordConvention) { case CoordConvention::Vulkan: case CoordConvention::Direct3D11: ortho.setOrthoD3D(0.0f, xres, 0, yres, -1.0f, 1.0f); break; case CoordConvention::OpenGL: default: ortho.setOrthoGL(0.0f, xres, yres, 0.0f, -1.0f, 1.0f); break; } // Compensate for rotated display if needed. if (g_display.rotation != DisplayRotation::ROTATE_0) { ortho = ortho * g_display.rot_matrix; } return ortho; }