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

Commit 1c569c4d authored by Jesse Hall's avatar Jesse Hall
Browse files

Tell HWComposer the dimensions of virtual displays

HWComposer queries the HWC for dimensions of physical displays, but
can't do that for virtual displays. The dimensions are used to set the
display frame of the framebuffer target layer passed to HWC, and
implicitly the dimensions of the virtual display.

Bug: 8316155
Change-Id: I9cbd2530d2fa878f86128a1472def520b5d694a5
parent 39c24a20
Loading
Loading
Loading
Loading
+23 −13
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@
#include <hardware/hardware.h>
#include <hardware/hwcomposer.h>

#include <android/configuration.h>

#include <cutils/log.h>
#include <cutils/properties.h>

@@ -297,6 +299,11 @@ void HWComposer::hotplug(int disp, int connected) {
    mEventHandler.onHotplugReceived(disp, bool(connected));
}

static float getDefaultDensity(uint32_t height) {
    if (height >= 1080) return ACONFIGURATION_DENSITY_XHIGH;
    else                return ACONFIGURATION_DENSITY_TV;
}

static const uint32_t DISPLAY_ATTRIBUTES[] = {
    HWC_DISPLAY_VSYNC_PERIOD,
    HWC_DISPLAY_WIDTH,
@@ -307,10 +314,6 @@ static const uint32_t DISPLAY_ATTRIBUTES[] = {
};
#define NUM_DISPLAY_ATTRIBUTES (sizeof(DISPLAY_ATTRIBUTES) / sizeof(DISPLAY_ATTRIBUTES)[0])

// http://developer.android.com/reference/android/util/DisplayMetrics.html
#define ANDROID_DENSITY_TV    213
#define ANDROID_DENSITY_XHIGH 320

status_t HWComposer::queryDisplayProperties(int disp) {

    LOG_ALWAYS_FATAL_IF(!mHwc || !hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1));
@@ -364,15 +367,23 @@ status_t HWComposer::queryDisplayProperties(int disp) {
    mDisplayData[disp].format = HAL_PIXEL_FORMAT_RGBA_8888;
    mDisplayData[disp].connected = true;
    if (mDisplayData[disp].xdpi == 0.0f || mDisplayData[disp].ydpi == 0.0f) {
        // is there anything smarter we can do?
        if (h >= 1080) {
            mDisplayData[disp].xdpi = ANDROID_DENSITY_XHIGH;
            mDisplayData[disp].ydpi = ANDROID_DENSITY_XHIGH;
        } else {
            mDisplayData[disp].xdpi = ANDROID_DENSITY_TV;
            mDisplayData[disp].ydpi = ANDROID_DENSITY_TV;
        float dpi = getDefaultDensity(h);
        mDisplayData[disp].xdpi = dpi;
        mDisplayData[disp].ydpi = dpi;
    }
    return NO_ERROR;
}

status_t HWComposer::setVirtualDisplayProperties(int32_t id,
        uint32_t w, uint32_t h, uint32_t format) {
    if (id < VIRTUAL_DISPLAY_ID_BASE || id >= int32_t(mNumDisplays) ||
            !mAllocatedDisplayIDs.hasBit(id)) {
        return BAD_INDEX;
    }
    mDisplayData[id].width = w;
    mDisplayData[id].height = h;
    mDisplayData[id].format = format;
    mDisplayData[id].xdpi = mDisplayData[id].ydpi = getDefaultDensity(h);
    return NO_ERROR;
}

@@ -416,7 +427,6 @@ sp<Fence> HWComposer::getDisplayFence(int disp) const {
    return mDisplayData[disp].lastDisplayFence;
}


uint32_t HWComposer::getWidth(int disp) const {
    return mDisplayData[disp].width;
}
+3 −0
Original line number Diff line number Diff line
@@ -253,6 +253,9 @@ public:
    float getDpiY(int disp) const;
    bool isConnected(int disp) const;

    status_t setVirtualDisplayProperties(int32_t id, uint32_t w, uint32_t h,
            uint32_t format);

    // this class is only used to fake the VSync event on systems that don't
    // have it.
    class VSyncThread : public Thread {
+8 −1
Original line number Diff line number Diff line
@@ -1187,13 +1187,20 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
                                state.viewport, state.frame);
                        hw->setDisplayName(state.displayName);
                        mDisplays.add(display, hw);
                        if (state.type < DisplayDevice::NUM_DISPLAY_TYPES)
                        if (state.isVirtualDisplay()) {
                            if (hwcDisplayId >= 0) {
                                mHwc->setVirtualDisplayProperties(hwcDisplayId,
                                        hw->getWidth(), hw->getHeight(),
                                        hw->getFormat());
                            }
                        } else {
                            mEventThread->onHotplugReceived(state.type, true);
                        }
                    }
                }
            }
        }
    }

    if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) {
        // The transform hint might have changed for some layers