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

Commit 7501ed66 authored by Iris Chang's avatar Iris Chang Committed by Steven Moreland
Browse files

Need GSI to support landscape LCM

When device uses landscape LCM, the nature of the screen shows that
the device is a portrait device. After we flash with GSI, there is
vendor solution for landscape LCM used at portrait device. As the
result, the screen displays landscape layout and orientation while
device is at portrait orientation. In addition, the sensor coordinate
system mismatches with android coordinate system.

We suggest Google can add config to handle the case "portrait device
uses landscape LCM or landscape device uses portrait LCM".

Bug: 69691076

Test: We verified following test cases for this patch on Android O-MR1.
    1. Make sure homescreen is normal
    2. Rotate device and make sure screen is normal
    3. Grab screen shot and check if screen shot is normal
    4. Connect to Wi-Fi display and make sure WFD screen is normal
Test: Tested 1, 2 and 3 on Pixel 2.

Test: artifially setup 90 degree rotation on Pixel and make sure that
    screenshots are aligned to the screen.

Change-Id: Ib42c9a216e8a6fe465139d6eece152fb1765b422
parent 6c14d463
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ cc_defaults {
        "android.frameworks.vr.composer@1.0",
        "android.hardware.configstore-utils",
        "android.hardware.configstore@1.0",
        "android.hardware.configstore@1.1",
        "android.hardware.graphics.allocator@2.0",
        "android.hardware.graphics.composer@2.1",
        "android.hardware.graphics.composer@2.2",
+9 −0
Original line number Diff line number Diff line
@@ -475,6 +475,15 @@ void DisplayDevice::setProjection(int orientation,
    TL.set(-src_x, -src_y);
    TP.set(dst_x, dst_y);

    // need to take care of primary display rotation for mGlobalTransform
    // for case if the panel is not installed aligned with device orientation
    if (mType == DisplayType::DISPLAY_PRIMARY) {
        int primaryDisplayOrientation = mFlinger->getPrimaryDisplayOrientation();
        DisplayDevice::orientationToTransfrom(
                (orientation + primaryDisplayOrientation) % (DisplayState::eOrientation270 + 1),
                w, h, &R);
    }

    // The viewport and frame are both in the logical orientation.
    // Apply the logical translation, scale to physical size, apply the
    // physical translation and finally rotate to the physical orientation.
+8 −2
Original line number Diff line number Diff line
#include "RenderArea.h"

#include <gui/LayerState.h>

namespace android {

float RenderArea::getCaptureFillValue(CaptureFill captureFill) {
@@ -15,7 +17,7 @@ float RenderArea::getCaptureFillValue(CaptureFill captureFill) {
 * Checks that the requested width and height are valid and updates them to the render area
 * dimensions if they are set to 0
 */
status_t RenderArea::updateDimensions() {
status_t RenderArea::updateDimensions(int displayRotation) {
    // get screen geometry

    uint32_t width = getWidth();
@@ -25,6 +27,10 @@ status_t RenderArea::updateDimensions() {
        std::swap(width, height);
    }

    if (displayRotation & DisplayState::eOrientationSwapMask) {
        std::swap(width, height);
    }

    if ((mReqWidth > width) || (mReqHeight > height)) {
        ALOGE("size mismatch (%d, %d) > (%d, %d)", mReqWidth, mReqHeight, width, height);
        return BAD_VALUE;
+1 −1
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@ public:
    int getReqHeight() const { return mReqHeight; };
    int getReqWidth() const { return mReqWidth; };
    Transform::orientation_flags getRotationFlags() const { return mRotationFlags; };
    status_t updateDimensions();
    status_t updateDimensions(int displayRotation);

    CaptureFill getCaptureFill() const { return mCaptureFill; };

+84 −4
Original line number Diff line number Diff line
@@ -88,6 +88,8 @@
#include <cutils/compiler.h>

#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
#include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h>
#include <android/hardware/configstore/1.1/types.h>
#include <configstore/Utils.h>

#include <layerproto/LayerProtoParser.h>
@@ -282,6 +284,26 @@ SurfaceFlinger::SurfaceFlinger() : SurfaceFlinger(SkipInitialization) {
    hasWideColorDisplay =
            getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(false);

    V1_1::DisplayOrientation primaryDisplayOrientation =
        getDisplayOrientation< V1_1::ISurfaceFlingerConfigs, &V1_1::ISurfaceFlingerConfigs::primaryDisplayOrientation>(
            V1_1::DisplayOrientation::ORIENTATION_0);

    switch (primaryDisplayOrientation) {
        case V1_1::DisplayOrientation::ORIENTATION_90:
            mPrimaryDisplayOrientation = DisplayState::eOrientation90;
            break;
        case V1_1::DisplayOrientation::ORIENTATION_180:
            mPrimaryDisplayOrientation = DisplayState::eOrientation180;
            break;
        case V1_1::DisplayOrientation::ORIENTATION_270:
            mPrimaryDisplayOrientation = DisplayState::eOrientation270;
            break;
        default:
            mPrimaryDisplayOrientation = DisplayState::eOrientationDefault;
            break;
    }
    ALOGV("Primary Display Orientation is set to %2d.", mPrimaryDisplayOrientation);

    mPrimaryDispSync.init(SurfaceFlinger::hasSyncFramework, SurfaceFlinger::dispSyncPresentTimeOffset);

    // debugging stuff...
@@ -895,6 +917,11 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
        // All non-virtual displays are currently considered secure.
        info.secure = true;

        if (type == DisplayDevice::DISPLAY_PRIMARY &&
            mPrimaryDisplayOrientation & DisplayState::eOrientationSwapMask) {
            std::swap(info.w, info.h);
        }

        configs->push_back(info);
    }

@@ -4913,7 +4940,7 @@ status_t SurfaceFlinger::captureScreenCommon(RenderArea& renderArea,
                                             bool useIdentityTransform) {
    ATRACE_CALL();

    renderArea.updateDimensions();
    renderArea.updateDimensions(mPrimaryDisplayOrientation);

    const uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
            GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
@@ -4997,13 +5024,35 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
    const auto reqHeight = renderArea.getReqHeight();
    Rect sourceCrop = renderArea.getSourceCrop();

    const bool filtering = static_cast<int32_t>(reqWidth) != raWidth ||
    bool filtering = false;
    if (mPrimaryDisplayOrientation & DisplayState::eOrientationSwapMask) {
        filtering = static_cast<int32_t>(reqWidth) != raHeight ||
                static_cast<int32_t>(reqHeight) != raWidth;
    } else {
        filtering = static_cast<int32_t>(reqWidth) != raWidth ||
                static_cast<int32_t>(reqHeight) != raHeight;
    }

    // if a default or invalid sourceCrop is passed in, set reasonable values
    if (sourceCrop.width() == 0 || sourceCrop.height() == 0 || !sourceCrop.isValid()) {
        sourceCrop.setLeftTop(Point(0, 0));
        sourceCrop.setRightBottom(Point(raWidth, raHeight));
    } else if (mPrimaryDisplayOrientation != DisplayState::eOrientationDefault) {
        Transform tr;
        uint32_t flags = 0x00;
        switch (mPrimaryDisplayOrientation) {
            case DisplayState::eOrientation90:
                flags = Transform::ROT_90;
                break;
            case DisplayState::eOrientation180:
                flags = Transform::ROT_180;
                break;
            case DisplayState::eOrientation270:
                flags = Transform::ROT_270;
                break;
        }
        tr.set(flags, raWidth, raHeight);
        sourceCrop = tr.transform(sourceCrop);
    }

    // ensure that sourceCrop is inside screen
@@ -5027,9 +5076,40 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
    // make sure to clear all GL error flags
    engine.checkErrors();

    Transform::orientation_flags rotation = renderArea.getRotationFlags();
    if (mPrimaryDisplayOrientation != DisplayState::eOrientationDefault) {
        // convert hw orientation into flag presentation
        // here inverse transform needed
        uint8_t hw_rot_90  = 0x00;
        uint8_t hw_flip_hv = 0x00;
        switch (mPrimaryDisplayOrientation) {
            case DisplayState::eOrientation90:
                hw_rot_90 = Transform::ROT_90;
                hw_flip_hv = Transform::ROT_180;
                break;
            case DisplayState::eOrientation180:
                hw_flip_hv = Transform::ROT_180;
                break;
            case DisplayState::eOrientation270:
                hw_rot_90  = Transform::ROT_90;
                break;
        }

        // transform flags operation
        // 1) flip H V if both have ROT_90 flag
        // 2) XOR these flags
        uint8_t rotation_rot_90  = rotation & Transform::ROT_90;
        uint8_t rotation_flip_hv = rotation & Transform::ROT_180;
        if (rotation_rot_90 & hw_rot_90) {
            rotation_flip_hv = (~rotation_flip_hv) & Transform::ROT_180;
        }
        rotation = static_cast<Transform::orientation_flags>
                   ((rotation_rot_90 ^ hw_rot_90) | (rotation_flip_hv ^ hw_flip_hv));
    }

    // set-up our viewport
    engine.setViewportAndProjection(reqWidth, reqHeight, sourceCrop, raHeight, yswap,
                                    renderArea.getRotationFlags());
                                    rotation);
    engine.disableTexturing();

    const float alpha = RenderArea::getCaptureFillValue(renderArea.getCaptureFill());
Loading