Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 65912a48 authored by Oleg Blinnikov's avatar Oleg Blinnikov
Browse files

Anisotropy correction external displays only

Display's EDID have rounding up to 1cm, which
results into a large uncertainty in the
screen aspect ratio. Previously 2.5% permissible
uncertainty was used but it is not enough for the
smaller displays (typically internal displays).

This CL applies anisotropy scaling only to external
displays, to make sure internal display always
use unscaled logical display.

Change-Id: Ic58f790ff3d9917b781665e3a20bac65955aeed3
Test: atest LogicalDisplayTest DisplayDeviceTest
Bug: 331562320
Bug: 317363416
Bug: 304248677
parent cf5fa2a3
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -160,8 +160,8 @@ abstract class DisplayDevice {
        DisplayDeviceInfo displayDeviceInfo = getDisplayDeviceInfoLocked();
        var width = displayDeviceInfo.width;
        var height = displayDeviceInfo.height;
        if (mIsAnisotropyCorrectionEnabled && displayDeviceInfo.yDpi > 0
                    && displayDeviceInfo.xDpi > 0) {
        if (mIsAnisotropyCorrectionEnabled && displayDeviceInfo.type == Display.TYPE_EXTERNAL
                    && displayDeviceInfo.yDpi > 0 && displayDeviceInfo.xDpi > 0) {
            if (displayDeviceInfo.xDpi > displayDeviceInfo.yDpi * MAX_ANISOTROPY) {
                height = (int) (height * displayDeviceInfo.xDpi / displayDeviceInfo.yDpi + 0.5);
            } else if (displayDeviceInfo.xDpi * MAX_ANISOTROPY < displayDeviceInfo.yDpi) {
+4 −3
Original line number Diff line number Diff line
@@ -482,7 +482,8 @@ final class LogicalDisplay {
            int maskedWidth = deviceInfo.width - maskingInsets.left - maskingInsets.right;
            int maskedHeight = deviceInfo.height - maskingInsets.top - maskingInsets.bottom;

            if (mIsAnisotropyCorrectionEnabled && deviceInfo.xDpi > 0 && deviceInfo.yDpi > 0) {
            if (mIsAnisotropyCorrectionEnabled && deviceInfo.type == Display.TYPE_EXTERNAL
                        && deviceInfo.xDpi > 0 && deviceInfo.yDpi > 0) {
                if (deviceInfo.xDpi > deviceInfo.yDpi * DisplayDevice.MAX_ANISOTROPY) {
                    maskedHeight = (int) (maskedHeight * deviceInfo.xDpi / deviceInfo.yDpi + 0.5);
                } else if (deviceInfo.xDpi * DisplayDevice.MAX_ANISOTROPY < deviceInfo.yDpi) {
@@ -711,8 +712,8 @@ final class LogicalDisplay {
        var displayLogicalWidth = displayInfo.logicalWidth;
        var displayLogicalHeight = displayInfo.logicalHeight;

        if (mIsAnisotropyCorrectionEnabled && displayDeviceInfo.xDpi > 0
                    && displayDeviceInfo.yDpi > 0) {
        if (mIsAnisotropyCorrectionEnabled && displayDeviceInfo.type == Display.TYPE_EXTERNAL
                    && displayDeviceInfo.xDpi > 0 && displayDeviceInfo.yDpi > 0) {
            if (displayDeviceInfo.xDpi > displayDeviceInfo.yDpi * DisplayDevice.MAX_ANISOTROPY) {
                var scalingFactor = displayDeviceInfo.yDpi / displayDeviceInfo.xDpi;
                if (rotated) {
+24 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import static com.google.common.truth.Truth.assertThat;
import android.graphics.Point;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import android.view.Display;
import android.view.SurfaceControl;

import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -72,6 +73,7 @@ public class DisplayDeviceTest {

    @Test
    public void testGetDisplaySurfaceDefaultSizeLocked_notRotated_anisotropyCorrection() {
        mDisplayDeviceInfo.type = Display.TYPE_EXTERNAL;
        mDisplayDeviceInfo.xDpi = 0.5f;
        mDisplayDeviceInfo.yDpi = 1.0f;
        DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo,
@@ -80,6 +82,16 @@ public class DisplayDeviceTest {
                PORTRAIT_DOUBLE_WIDTH);
    }

    @Test
    public void testGetDisplaySurfaceDefaultSizeLocked_notRotated_noAnisotropyCorrection() {
        mDisplayDeviceInfo.type = Display.TYPE_INTERNAL;
        mDisplayDeviceInfo.xDpi = 0.5f;
        mDisplayDeviceInfo.yDpi = 1.0f;
        DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo,
                mMockDisplayAdapter, /*isAnisotropyCorrectionEnabled=*/ true);
        assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(PORTRAIT_SIZE);
    }

    @Test
    public void testGetDisplaySurfaceDefaultSizeLocked_notRotated() {
        DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo,
@@ -97,6 +109,7 @@ public class DisplayDeviceTest {

    @Test
    public void testGetDisplaySurfaceDefaultSizeLocked_rotation90_anisotropyCorrection() {
        mDisplayDeviceInfo.type = Display.TYPE_EXTERNAL;
        mDisplayDeviceInfo.xDpi = 0.5f;
        mDisplayDeviceInfo.yDpi = 1.0f;
        DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo,
@@ -106,6 +119,17 @@ public class DisplayDeviceTest {
                LANDSCAPE_DOUBLE_HEIGHT);
    }

    @Test
    public void testGetDisplaySurfaceDefaultSizeLocked_rotation90_noAnisotropyCorrection() {
        mDisplayDeviceInfo.type = Display.TYPE_INTERNAL;
        mDisplayDeviceInfo.xDpi = 0.5f;
        mDisplayDeviceInfo.yDpi = 1.0f;
        DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo,
                mMockDisplayAdapter, /*isAnisotropyCorrectionEnabled=*/ true);
        displayDevice.setProjectionLocked(mMockTransaction, ROTATION_90, new Rect(), new Rect());
        assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(LANDSCAPE_SIZE);
    }

    @Test
    public void testGetDisplaySurfaceDefaultSizeLocked_rotation90() {
        DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo,
+35 −0
Original line number Diff line number Diff line
@@ -142,8 +142,39 @@ public class LogicalDisplayTest {
        assertEquals(new Point(0, DISPLAY_HEIGHT / 4), mLogicalDisplay.getDisplayPosition());
    }


    @Test
    public void testNoLetterbox_noAnisotropyCorrectionForInternalDisplay() {
        mDisplayDeviceInfo.type = Display.TYPE_INTERNAL;
        mLogicalDisplay = new LogicalDisplay(DISPLAY_ID, LAYER_STACK, mDisplayDevice,
                /*isAnisotropyCorrectionEnabled=*/ true,
                /*isAlwaysRotateDisplayDeviceEnabled=*/ true);

        // In case of Anisotropy of pixels, then the content should be rescaled so it would adjust
        // to using the whole screen. This is because display will rescale it back to fill the
        // screen (in case the display menu setting is set to stretch the pixels across the display)
        mDisplayDeviceInfo.xDpi = 0.5f;
        mDisplayDeviceInfo.yDpi = 1.0f;

        mLogicalDisplay.updateLocked(mDeviceRepo);
        var originalDisplayInfo = mLogicalDisplay.getDisplayInfoLocked();
        // Content width not scaled
        assertEquals(DISPLAY_WIDTH, originalDisplayInfo.logicalWidth);
        assertEquals(DISPLAY_HEIGHT, originalDisplayInfo.logicalHeight);

        SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class);
        mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);

        // Applications need to think that they are shown on a display with square pixels.
        // as applications can be displayed on multiple displays simultaneously (mirrored).
        // Content is too wide, should have become letterboxed - but it won't because of anisotropy
        // correction
        assertEquals(new Point(0, 0), mLogicalDisplay.getDisplayPosition());
    }

    @Test
    public void testNoLetterbox_anisotropyCorrection() {
        mDisplayDeviceInfo.type = Display.TYPE_EXTERNAL;
        mLogicalDisplay = new LogicalDisplay(DISPLAY_ID, LAYER_STACK, mDisplayDevice,
                /*isAnisotropyCorrectionEnabled=*/ true,
                /*isAlwaysRotateDisplayDeviceEnabled=*/ true);
@@ -172,6 +203,7 @@ public class LogicalDisplayTest {

    @Test
    public void testLetterbox_anisotropyCorrectionYDpi() {
        mDisplayDeviceInfo.type = Display.TYPE_EXTERNAL;
        mLogicalDisplay = new LogicalDisplay(DISPLAY_ID, LAYER_STACK, mDisplayDevice,
                /*isAnisotropyCorrectionEnabled=*/ true,
                /*isAlwaysRotateDisplayDeviceEnabled=*/ true);
@@ -229,6 +261,7 @@ public class LogicalDisplayTest {

    @Test
    public void testPillarbox_anisotropyCorrection() {
        mDisplayDeviceInfo.type = Display.TYPE_EXTERNAL;
        mLogicalDisplay = new LogicalDisplay(DISPLAY_ID, LAYER_STACK, mDisplayDevice,
                /*isAnisotropyCorrectionEnabled=*/ true,
                /*isAlwaysRotateDisplayDeviceEnabled=*/ true);
@@ -257,6 +290,7 @@ public class LogicalDisplayTest {

    @Test
    public void testNoPillarbox_anisotropyCorrectionYDpi() {
        mDisplayDeviceInfo.type = Display.TYPE_EXTERNAL;
        mLogicalDisplay = new LogicalDisplay(DISPLAY_ID, LAYER_STACK, mDisplayDevice,
                /*isAnisotropyCorrectionEnabled=*/ true,
                /*isAlwaysRotateDisplayDeviceEnabled=*/ true);
@@ -318,6 +352,7 @@ public class LogicalDisplayTest {

    @Test
    public void testGetDisplayPositionAlwaysRotateDisplayEnabled() {
        mDisplayDeviceInfo.type = Display.TYPE_EXTERNAL;
        mLogicalDisplay = new LogicalDisplay(DISPLAY_ID, LAYER_STACK, mDisplayDevice,
                /*isAnisotropyCorrectionEnabled=*/ true,
                /*isAlwaysRotateDisplayDeviceEnabled=*/ true);