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

Commit a524a098 authored by Marin Shalamanov's avatar Marin Shalamanov
Browse files

Use type safe display IDs.

Use a type safe wrapper around uint64_t for display ids.
We also modify the format of the EDID generated physical
display IDs by setting bit 62 to 1, which will indicate
that the display id is stable across reboot.

Bug: 160679868
Test: m && flash device
Test: take screnshot on device
Test: atest surfaceflinger_unittest
Change-Id: Ie2c7c2b737e0882fa4208c059caa85b7ded922b2
parent 6db8d6e9
Loading
Loading
Loading
Loading
+2 −3
Original line number Original line Diff line number Diff line
@@ -121,9 +121,8 @@ int DisplayEventDispatcher::handleEvent(int, int events, void*) {
    PhysicalDisplayId vsyncDisplayId;
    PhysicalDisplayId vsyncDisplayId;
    uint32_t vsyncCount;
    uint32_t vsyncCount;
    if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {
    if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {
        ALOGV("dispatcher %p ~ Vsync pulse: timestamp=%" PRId64
        ALOGV("dispatcher %p ~ Vsync pulse: timestamp=%" PRId64 ", displayId=%s, count=%d", this,
              ", displayId=%" ANDROID_PHYSICAL_DISPLAY_ID_FORMAT ", count=%d",
              ns2ms(vsyncTimestamp), to_string(vsyncDisplayId).c_str(), vsyncCount);
              this, ns2ms(vsyncTimestamp), vsyncDisplayId, vsyncCount);
        mWaitingForVsync = false;
        mWaitingForVsync = false;
        dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount);
        dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount);
    }
    }
+12 −5
Original line number Original line Diff line number Diff line
@@ -327,8 +327,11 @@ public:
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        if (remote()->transact(BnSurfaceComposer::GET_PHYSICAL_DISPLAY_IDS, data, &reply) ==
        if (remote()->transact(BnSurfaceComposer::GET_PHYSICAL_DISPLAY_IDS, data, &reply) ==
            NO_ERROR) {
            NO_ERROR) {
            std::vector<PhysicalDisplayId> displayIds;
            std::vector<uint64_t> rawIds;
            if (reply.readUint64Vector(&displayIds) == NO_ERROR) {
            if (reply.readUint64Vector(&rawIds) == NO_ERROR) {
                std::vector<PhysicalDisplayId> displayIds(rawIds.size());
                std::transform(rawIds.begin(), rawIds.end(), displayIds.begin(),
                               [](uint64_t rawId) { return PhysicalDisplayId(rawId); });
                return displayIds;
                return displayIds;
            }
            }
        }
        }
@@ -339,7 +342,7 @@ public:
    virtual sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId displayId) const {
    virtual sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId displayId) const {
        Parcel data, reply;
        Parcel data, reply;
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        data.writeUint64(displayId);
        data.writeUint64(displayId.value);
        remote()->transact(BnSurfaceComposer::GET_PHYSICAL_DISPLAY_TOKEN, data, &reply);
        remote()->transact(BnSurfaceComposer::GET_PHYSICAL_DISPLAY_TOKEN, data, &reply);
        return reply.readStrongBinder();
        return reply.readStrongBinder();
    }
    }
@@ -1417,7 +1420,7 @@ status_t BnSurfaceComposer::onTransact(
        }
        }
        case GET_PHYSICAL_DISPLAY_TOKEN: {
        case GET_PHYSICAL_DISPLAY_TOKEN: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            PhysicalDisplayId displayId = data.readUint64();
            PhysicalDisplayId displayId(data.readUint64());
            sp<IBinder> display = getPhysicalDisplayToken(displayId);
            sp<IBinder> display = getPhysicalDisplayToken(displayId);
            reply->writeStrongBinder(display);
            reply->writeStrongBinder(display);
            return NO_ERROR;
            return NO_ERROR;
@@ -1819,7 +1822,11 @@ status_t BnSurfaceComposer::onTransact(
        }
        }
        case GET_PHYSICAL_DISPLAY_IDS: {
        case GET_PHYSICAL_DISPLAY_IDS: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            return reply->writeUint64Vector(getPhysicalDisplayIds());
            std::vector<PhysicalDisplayId> ids = getPhysicalDisplayIds();
            std::vector<uint64_t> rawIds(ids.size());
            std::transform(ids.begin(), ids.end(), rawIds.begin(),
                           [](PhysicalDisplayId id) { return id.value; });
            return reply->writeUint64Vector(rawIds);
        }
        }
        case ADD_REGION_SAMPLING_LISTENER: {
        case ADD_REGION_SAMPLING_LISTENER: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+1 −1
Original line number Original line Diff line number Diff line
@@ -27,11 +27,11 @@
#include <math/vec4.h>
#include <math/vec4.h>


#include <ui/ConfigStoreTypes.h>
#include <ui/ConfigStoreTypes.h>
#include <ui/DisplayId.h>
#include <ui/DisplayedFrameStats.h>
#include <ui/DisplayedFrameStats.h>
#include <ui/FrameStats.h>
#include <ui/FrameStats.h>
#include <ui/GraphicBuffer.h>
#include <ui/GraphicBuffer.h>
#include <ui/GraphicTypes.h>
#include <ui/GraphicTypes.h>
#include <ui/PhysicalDisplayId.h>
#include <ui/PixelFormat.h>
#include <ui/PixelFormat.h>
#include <ui/Rotation.h>
#include <ui/Rotation.h>


+4 −6
Original line number Original line Diff line number Diff line
@@ -363,9 +363,8 @@ void Choreographer::dispatchVsync(nsecs_t timestamp, PhysicalDisplayId, uint32_t
}
}


void Choreographer::dispatchHotplug(nsecs_t, PhysicalDisplayId displayId, bool connected) {
void Choreographer::dispatchHotplug(nsecs_t, PhysicalDisplayId displayId, bool connected) {
    ALOGV("choreographer %p ~ received hotplug event (displayId=%"
    ALOGV("choreographer %p ~ received hotplug event (displayId=%s, connected=%s), ignoring.",
            ANDROID_PHYSICAL_DISPLAY_ID_FORMAT ", connected=%s), ignoring.",
            this, to_string(displayId).c_str(), toString(connected));
            this, displayId, toString(connected));
}
}


// TODO(b/74619554): The PhysicalDisplayId is ignored because currently
// TODO(b/74619554): The PhysicalDisplayId is ignored because currently
@@ -375,9 +374,8 @@ void Choreographer::dispatchHotplug(nsecs_t, PhysicalDisplayId displayId, bool c
// PhysicalDisplayId should no longer be ignored.
// PhysicalDisplayId should no longer be ignored.
void Choreographer::dispatchConfigChanged(nsecs_t, PhysicalDisplayId displayId, int32_t configId,
void Choreographer::dispatchConfigChanged(nsecs_t, PhysicalDisplayId displayId, int32_t configId,
                                          nsecs_t vsyncPeriod) {
                                          nsecs_t vsyncPeriod) {
    ALOGV("choreographer %p ~ received config change event "
    ALOGV("choreographer %p ~ received config change event (displayId=%s, configId=%d).",
          "(displayId=%" ANDROID_PHYSICAL_DISPLAY_ID_FORMAT ", configId=%d).",
          this, to_string(displayId).c_str(), configId);
          this, displayId, configId);


    const nsecs_t lastPeriod = mLatestVsyncPeriod;
    const nsecs_t lastPeriod = mLatestVsyncPeriod;
    std::vector<RefreshRateCallback> callbacks{};
    std::vector<RefreshRateCallback> callbacks{};
+102 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <cstdint>
#include <functional>
#include <string>

namespace android {

// ID of a physical or a virtual display. This class acts as a type safe wrapper around uint64_t.
struct DisplayId {
    // TODO(b/162612135) Remove default constructor
    DisplayId() = default;
    constexpr DisplayId(const DisplayId&) = default;
    DisplayId& operator=(const DisplayId&) = default;

    uint64_t value;

protected:
    explicit constexpr DisplayId(uint64_t id) : value(id) {}
};

static_assert(sizeof(DisplayId) == sizeof(uint64_t));

inline bool operator==(DisplayId lhs, DisplayId rhs) {
    return lhs.value == rhs.value;
}

inline bool operator!=(DisplayId lhs, DisplayId rhs) {
    return !(lhs == rhs);
}

inline std::string to_string(DisplayId displayId) {
    return std::to_string(displayId.value);
}

// DisplayId of a physical display, such as the internal display or externally connected display.
struct PhysicalDisplayId : DisplayId {
    // Flag indicating that the ID is stable across reboots.
    static constexpr uint64_t FLAG_STABLE = 1ULL << 62;

    // Returns a stable ID based on EDID information.
    static constexpr PhysicalDisplayId fromEdid(uint8_t port, uint16_t manufacturerId,
                                                uint32_t modelHash) {
        return PhysicalDisplayId(FLAG_STABLE, port, manufacturerId, modelHash);
    }

    // Returns an unstable ID. If EDID is available using "fromEdid" is preferred.
    static constexpr PhysicalDisplayId fromPort(uint8_t port) {
        constexpr uint16_t kManufacturerId = 0;
        constexpr uint32_t kModelHash = 0;
        return PhysicalDisplayId(0, port, kManufacturerId, kModelHash);
    }

    // TODO(b/162612135) Remove default constructor
    PhysicalDisplayId() = default;
    explicit constexpr PhysicalDisplayId(uint64_t id) : DisplayId(id) {}
    explicit constexpr PhysicalDisplayId(DisplayId other) : DisplayId(other.value) {}

    constexpr uint16_t getManufacturerId() const { return static_cast<uint16_t>(value >> 40); }

    constexpr uint8_t getPort() const { return static_cast<uint8_t>(value); }

private:
    constexpr PhysicalDisplayId(uint64_t flags, uint8_t port, uint16_t manufacturerId,
                                uint32_t modelHash)
          : DisplayId(flags | (static_cast<uint64_t>(manufacturerId) << 40) |
                      (static_cast<uint64_t>(modelHash) << 8) | port) {}
};

static_assert(sizeof(PhysicalDisplayId) == sizeof(uint64_t));

} // namespace android

namespace std {

template <>
struct hash<android::DisplayId> {
    size_t operator()(android::DisplayId displayId) const {
        return hash<uint64_t>()(displayId.value);
    }
};

template <>
struct hash<android::PhysicalDisplayId> : hash<android::DisplayId> {};

} // namespace std
Loading