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

Commit f2f18f7b authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "SF: Clean up HWComposer"

parents 87a65959 1af4793a
Loading
Loading
Loading
Loading
+22 −64
Original line number Diff line number Diff line
@@ -20,31 +20,12 @@
#define LOG_TAG "HWComposer"
#define ATRACE_TAG ATRACE_TAG_GRAPHICS

#include <inttypes.h>
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

#include <utils/Errors.h>
#include <utils/misc.h>
#include <utils/NativeHandle.h>
#include <utils/String8.h>
#include <utils/Thread.h>
#include <utils/Trace.h>
#include <utils/Vector.h>

#include <ui/DebugUtils.h>
#include <ui/GraphicBuffer.h>

#include <hardware/hardware.h>
#include <hardware/hwcomposer.h>

#include <android/configuration.h>

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

#include "HWComposer.h"
@@ -85,11 +66,7 @@

namespace android {

#define MIN_HWC_HEADER_VERSION HWC_HEADER_VERSION

// ---------------------------------------------------------------------------

HWComposer::HWComposer(std::unique_ptr<android::Hwc2::Composer> composer)
HWComposer::HWComposer(std::unique_ptr<Hwc2::Composer> composer)
      : mHwcDevice(std::make_unique<HWC2::Device>(std::move(composer))) {}

HWComposer::~HWComposer() {
@@ -184,30 +161,31 @@ bool HWComposer::onVsync(hwc2_display_t hwcDisplayId, int64_t timestamp) {

    RETURN_IF_INVALID_DISPLAY(*displayId, false);

    const auto& displayData = mDisplayData[*displayId];
    auto& displayData = mDisplayData[*displayId];
    if (displayData.isVirtual) {
        LOG_DISPLAY_ERROR(*displayId, "Invalid operation on virtual display");
        return false;
    }

    {
        Mutex::Autolock _l(mLock);
        std::lock_guard lock(displayData.lastHwVsyncLock);

        // There have been reports of HWCs that signal several vsync events
        // with the same timestamp when turning the display off and on. This
        // is a bug in the HWC implementation, but filter the extra events
        // out here so they don't cause havoc downstream.
        if (timestamp == mLastHwVSync[*displayId]) {
        if (timestamp == displayData.lastHwVsync) {
            ALOGW("Ignoring duplicate VSYNC event from HWC for display %s (t=%" PRId64 ")",
                  to_string(*displayId).c_str(), timestamp);
            return false;
        }

        mLastHwVSync[*displayId] = timestamp;
        displayData.lastHwVsync = timestamp;
    }

    const auto tag = "HW_VSYNC_" + to_string(*displayId);
    ATRACE_INT(tag.c_str(), ++mVSyncCounts[*displayId] & 1);
    ATRACE_INT(tag.c_str(), displayData.vsyncTraceToggle);
    displayData.vsyncTraceToggle = !displayData.vsyncTraceToggle;

    return true;
}
@@ -270,13 +248,14 @@ void HWComposer::destroyLayer(DisplayId displayId, HWC2::Layer* layer) {

nsecs_t HWComposer::getRefreshTimestamp(DisplayId displayId) const {
    RETURN_IF_INVALID_DISPLAY(displayId, 0);
    const auto& displayData = mDisplayData.at(displayId);
    // this returns the last refresh timestamp.
    // if the last one is not available, we estimate it based on
    // the refresh period and whatever closest timestamp we have.
    Mutex::Autolock _l(mLock);
    std::lock_guard lock(displayData.lastHwVsyncLock);
    nsecs_t now = systemTime(CLOCK_MONOTONIC);
    auto vsyncPeriod = getActiveConfig(displayId)->getVsyncPeriod();
    return now - ((now - mLastHwVSync[displayId]) % vsyncPeriod);
    return now - ((now - displayData.lastHwVsync) % vsyncPeriod);
}

bool HWComposer::isConnected(DisplayId displayId) const {
@@ -375,8 +354,11 @@ void HWComposer::setVsyncEnabled(DisplayId displayId, HWC2::Vsync enabled) {
    // into the HWC with the lock held, and we want to make sure
    // that even if HWC blocks (which it shouldn't), it won't
    // affect other threads.
    Mutex::Autolock _l(mVsyncLock);
    if (enabled != displayData.vsyncEnabled) {
    std::lock_guard lock(displayData.vsyncEnabledLock);
    if (enabled == displayData.vsyncEnabled) {
        return;
    }

    ATRACE_CALL();
    auto error = displayData.hwcDisplay->setVsyncEnabled(enabled);
    RETURN_IF_HWC_ERROR(error, displayId);
@@ -386,7 +368,6 @@ void HWComposer::setVsyncEnabled(DisplayId displayId, HWC2::Vsync enabled) {
    const auto tag = "HW_VSYNC_ON_" + to_string(displayId);
    ATRACE_INT(tag.c_str(), enabled == HWC2::Vsync::Enable ? 1 : 0);
}
}

status_t HWComposer::setClientTarget(DisplayId displayId, uint32_t slot,
                                     const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target,
@@ -405,8 +386,6 @@ status_t HWComposer::prepare(DisplayId displayId, std::vector<CompositionInfo>&

    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);

    Mutex::Autolock _l(mDisplayLock);

    auto& displayData = mDisplayData[displayId];
    auto& hwcDisplay = displayData.hwcDisplay;
    if (!hwcDisplay->isConnected()) {
@@ -428,7 +407,7 @@ status_t HWComposer::prepare(DisplayId displayId, std::vector<CompositionInfo>&
    // back to validate when there is any client layer.
    displayData.validateWasSkipped = false;
    if (!displayData.hasClientComposition) {
        sp<android::Fence> outPresentFence;
        sp<Fence> outPresentFence;
        uint32_t state = UINT32_MAX;
        error = hwcDisplay->presentOrValidate(&numTypes, &numRequests, &outPresentFence , &state);
        if (error != HWC2::Error::HasChanges) {
@@ -689,7 +668,6 @@ void HWComposer::disconnectDisplay(DisplayId displayId) {
    const auto hwcDisplayId = displayData.hwcDisplay->getId();
    mPhysicalDisplayIdMap.erase(hwcDisplayId);
    mDisplayData.erase(displayId);
    mVSyncCounts.erase(displayId);

    // TODO(b/74619554): Select internal/external display from remaining displays.
    if (hwcDisplayId == mInternalHwcDisplayId) {
@@ -755,26 +733,6 @@ mat4 HWComposer::getDataspaceSaturationMatrix(DisplayId displayId, ui::Dataspace
    return matrix;
}

// Converts a PixelFormat to a human-readable string.  Max 11 chars.
// (Could use a table of prefab String8 objects.)
/*
static String8 getFormatStr(PixelFormat format) {
    switch (format) {
    case PIXEL_FORMAT_RGBA_8888:    return String8("RGBA_8888");
    case PIXEL_FORMAT_RGBX_8888:    return String8("RGBx_8888");
    case PIXEL_FORMAT_RGB_888:      return String8("RGB_888");
    case PIXEL_FORMAT_RGB_565:      return String8("RGB_565");
    case PIXEL_FORMAT_BGRA_8888:    return String8("BGRA_8888");
    case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
                                    return String8("ImplDef");
    default:
        String8 result;
        result.appendFormat("? %08x", format);
        return result;
    }
}
*/

bool HWComposer::isUsingVrComposer() const {
    return getComposer()->isUsingVrComposer();
}
+20 −54
Original line number Diff line number Diff line
@@ -17,49 +17,26 @@
#ifndef ANDROID_SF_HWCOMPOSER_H
#define ANDROID_SF_HWCOMPOSER_H

#include "HWC2.h"

#include <stdint.h>
#include <sys/types.h>

#include <ui/Fence.h>
#include <ui/GraphicTypes.h>
#include <utils/BitSet.h>
#include <utils/Condition.h>
#include <utils/Mutex.h>
#include <utils/StrongPointer.h>
#include <utils/Thread.h>
#include <utils/Timers.h>
#include <utils/Vector.h>

#include <cstdint>
#include <memory>
#include <mutex>
#include <optional>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include "DisplayIdentification.h"

extern "C" int clock_nanosleep(clockid_t clock_id, int flags,
                           const struct timespec *request,
                           struct timespec *remain);

struct framebuffer_device_t;
#include <android-base/thread_annotations.h>
#include <ui/Fence.h>
#include <ui/GraphicTypes.h>
#include <utils/StrongPointer.h>
#include <utils/Timers.h>

namespace HWC2 {
    class Device;
    class Display;
}
#include "DisplayIdentification.h"
#include "HWC2.h"

namespace android {
// ---------------------------------------------------------------------------

class DisplayDevice;
class Fence;
class FloatRect;
class GraphicBuffer;
class NativeHandle;
class Region;
class String8;
class TestableSurfaceFlinger;
struct CompositionInfo;
@@ -71,7 +48,7 @@ class Composer;
class HWComposer
{
public:
    explicit HWComposer(std::unique_ptr<android::Hwc2::Composer> composer);
    explicit HWComposer(std::unique_ptr<Hwc2::Composer> composer);

    ~HWComposer();

@@ -177,7 +154,7 @@ public:
    // for debugging ----------------------------------------------------------
    void dump(String8& out) const;

    android::Hwc2::Composer* getComposer() const { return mHwcDevice->getComposer(); }
    Hwc2::Composer* getComposer() const { return mHwcDevice->getComposer(); }

    // TODO(b/74619554): Remove special cases for internal/external display.
    std::optional<hwc2_display_t> getInternalHwcDisplayId() const { return mInternalHwcDisplayId; }
@@ -194,8 +171,6 @@ private:

    static void validateChange(HWC2::Composition from, HWC2::Composition to);

    struct cb_context;

    struct DisplayData {
        bool isVirtual = false;
        bool hasClientComposition = false;
@@ -209,11 +184,16 @@ private:
        mutable std::unordered_map<int32_t,
                std::shared_ptr<const HWC2::Display::Config>> configMap;

        // protected by mVsyncLock
        HWC2::Vsync vsyncEnabled = HWC2::Vsync::Disable;

        bool validateWasSkipped;
        HWC2::Error presentError;

        bool vsyncTraceToggle = false;

        std::mutex vsyncEnabledLock;
        HWC2::Vsync vsyncEnabled GUARDED_BY(vsyncEnabledLock) = HWC2::Vsync::Disable;

        mutable std::mutex lastHwVsyncLock;
        nsecs_t lastHwVsync GUARDED_BY(lastHwVsyncLock) = 0;
    };

    std::unordered_map<DisplayId, DisplayData> mDisplayData;
@@ -227,25 +207,11 @@ private:
    std::optional<hwc2_display_t> mExternalHwcDisplayId;
    bool mHasMultiDisplaySupport = false;

    // protect mDisplayData from races between prepare and dump
    mutable Mutex mDisplayLock;

    cb_context* mCBContext = nullptr;
    std::unordered_map<DisplayId, size_t> mVSyncCounts;

    std::unordered_set<DisplayId> mFreeVirtualDisplayIds;
    uint32_t mNextVirtualDisplayId = 0;
    uint32_t mRemainingHwcVirtualDisplays{mHwcDevice->getMaxVirtualDisplayCount()};

    // protected by mLock
    mutable Mutex mLock;
    mutable std::unordered_map<DisplayId, nsecs_t> mLastHwVSync;

    // thread-safe
    mutable Mutex mVsyncLock;
};

// ---------------------------------------------------------------------------
}; // namespace android
} // namespace android

#endif // ANDROID_SF_HWCOMPOSER_H
+3 −3
Original line number Diff line number Diff line
@@ -1272,7 +1272,7 @@ TEST_F(SetupNewDisplayDeviceInternalTest, createHwcVirtualDisplay) {
    // Insert display data so that the HWC thinks it created the virtual display.
    const auto displayId = Case::Display::DISPLAY_ID::get();
    ASSERT_TRUE(displayId);
    mFlinger.mutableHwcDisplayData()[*displayId] = {};
    mFlinger.mutableHwcDisplayData().try_emplace(*displayId);

    setupNewDisplayDeviceInternalTest<Case>();
}
@@ -1785,7 +1785,7 @@ TEST_F(HandleTransactionLockedTest, processesVirtualDisplayRemoval) {
    // A virtual display is set up but is removed from the current state.
    const auto displayId = Case::Display::DISPLAY_ID::get();
    ASSERT_TRUE(displayId);
    mFlinger.mutableHwcDisplayData()[*displayId] = {};
    mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
    Case::Display::injectHwcDisplay(this);
    auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
    existing.inject();
@@ -2914,7 +2914,7 @@ TEST_F(SetPowerModeInternalTest, setPowerModeInternalDoesNothingIfVirtualDisplay
    // Insert display data so that the HWC thinks it created the virtual display.
    const auto displayId = Case::Display::DISPLAY_ID::get();
    ASSERT_TRUE(displayId);
    mFlinger.mutableHwcDisplayData()[*displayId] = {};
    mFlinger.mutableHwcDisplayData().try_emplace(*displayId);

    // A virtual display device is set up
    Case::Display::injectHwcDisplay(this);