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

Commit 99d3da56 authored by Lloyd Pique's avatar Lloyd Pique
Browse files

SF: Refactor display device creation

Move display device creation to its own function which handles all
initialization before creating a DisplayDevice instance, which now just
simply constructs an instance from the passed values.

Also introduces a factory to abstract creating libgui Surface instances,
so that can be replaced by the test.

Test: Builds
Bug: 74827900
Change-Id: Ia80c865dc96b300033c506cc3093e563bcab787b
parent 1cd9d30e
Loading
Loading
Loading
Loading
+19 −51
Original line number Original line Diff line number Diff line
@@ -57,9 +57,6 @@ using namespace android;
using namespace android::hardware::configstore;
using namespace android::hardware::configstore;
using namespace android::hardware::configstore::V1_0;
using namespace android::hardware::configstore::V1_0;


static bool useTripleFramebuffer = getInt64< ISurfaceFlingerConfigs,
        &ISurfaceFlingerConfigs::maxFrameBufferAcquiredBuffers>(2) >= 3;

/*
/*
 * Initialize the display to the specified values.
 * Initialize the display to the specified values.
 *
 *
@@ -74,72 +71,43 @@ DisplayDevice::DisplayDevice(
        int32_t hwcId,
        int32_t hwcId,
        bool isSecure,
        bool isSecure,
        const wp<IBinder>& displayToken,
        const wp<IBinder>& displayToken,
        const sp<ANativeWindow>& nativeWindow,
        const sp<DisplaySurface>& displaySurface,
        const sp<DisplaySurface>& displaySurface,
        const sp<IGraphicBufferProducer>& producer,
        std::unique_ptr<RE::Surface> renderSurface,
        int displayWidth,
        int displayHeight,
        bool supportWideColor,
        bool supportWideColor,
        bool supportHdr)
        bool supportHdr,
        int initialPowerMode)
    : lastCompositionHadVisibleLayers(false),
    : lastCompositionHadVisibleLayers(false),
      mFlinger(flinger),
      mFlinger(flinger),
      mType(type),
      mType(type),
      mHwcDisplayId(hwcId),
      mHwcDisplayId(hwcId),
      mDisplayToken(displayToken),
      mDisplayToken(displayToken),
      mNativeWindow(nativeWindow),
      mDisplaySurface(displaySurface),
      mDisplaySurface(displaySurface),
      mSurface{flinger->getRenderEngine().createSurface()},
      mSurface{std::move(renderSurface)},
      mDisplayWidth(),
      mDisplayWidth(displayWidth),
      mDisplayHeight(),
      mDisplayHeight(displayHeight),
      mPageFlipCount(),
      mPageFlipCount(0),
      mIsSecure(isSecure),
      mIsSecure(isSecure),
      mLayerStack(NO_LAYER_STACK),
      mLayerStack(NO_LAYER_STACK),
      mOrientation(),
      mOrientation(),
      mPowerMode(HWC_POWER_MODE_OFF),
      mViewport(Rect::INVALID_RECT),
      mActiveConfig(0)
      mFrame(Rect::INVALID_RECT),
      mPowerMode(initialPowerMode),
      mActiveConfig(0),
      mActiveColorMode(ColorMode::NATIVE),
      mDisplayHasWideColor(supportWideColor),
      mDisplayHasHdr(supportHdr)
{
{
    // clang-format on
    // clang-format on
    Surface* surface;
    mNativeWindow = surface = new Surface(producer, false);
    ANativeWindow* const window = mNativeWindow.get();

    mActiveColorMode = ColorMode::NATIVE;
    mDisplayHasWideColor = supportWideColor;
    mDisplayHasHdr = supportHdr;

    /*
     * Create our display's surface
     */
    mSurface->setCritical(mType == DisplayDevice::DISPLAY_PRIMARY);
    mSurface->setAsync(mType >= DisplayDevice::DISPLAY_VIRTUAL);
    mSurface->setNativeWindow(window);
    mDisplayWidth = mSurface->queryWidth();
    mDisplayHeight = mSurface->queryHeight();

    // Make sure that composition can never be stalled by a virtual display
    // consumer that isn't processing buffers fast enough. We have to do this
    // in two places:
    // * Here, in case the display is composed entirely by HWC.
    // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the
    //   window's swap interval in eglMakeCurrent, so they'll override the
    //   interval we set here.
    if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
        window->setSwapInterval(window, 0);

    mPageFlipCount = 0;
    mViewport.makeInvalid();
    mFrame.makeInvalid();

    // virtual displays are always considered enabled
    mPowerMode = (mType >= DisplayDevice::DISPLAY_VIRTUAL) ?
                  HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF;


    // initialize the display orientation transform.
    // initialize the display orientation transform.
    setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
    setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);

    if (useTripleFramebuffer) {
        surface->allocateBuffers();
    }
}
}


DisplayDevice::~DisplayDevice() {
DisplayDevice::~DisplayDevice() = default;
}


void DisplayDevice::disconnect(HWComposer& hwc) {
void DisplayDevice::disconnect(HWComposer& hwc) {
    if (mHwcDisplayId >= 0) {
    if (mHwcDisplayId >= 0) {
+7 −2
Original line number Original line Diff line number Diff line
@@ -77,9 +77,14 @@ public:
            int32_t hwcId,
            int32_t hwcId,
            bool isSecure,
            bool isSecure,
            const wp<IBinder>& displayToken,
            const wp<IBinder>& displayToken,
            const sp<ANativeWindow>& nativeWindow,
            const sp<DisplaySurface>& displaySurface,
            const sp<DisplaySurface>& displaySurface,
            const sp<IGraphicBufferProducer>& producer,
            std::unique_ptr<RE::Surface> renderSurface,
            bool supportWideColor, bool supportHdr);
            int displayWidth,
            int displayHeight,
            bool supportWideColor,
            bool supportHdr,
            int initialPowerMode);
    // clang-format on
    // clang-format on


    ~DisplayDevice();
    ~DisplayDevice();
+110 −45
Original line number Original line Diff line number Diff line
@@ -154,6 +154,32 @@ bool useTrebleTestingOverride() {
    return std::string(value) == "true";
    return std::string(value) == "true";
}
}


NativeWindowSurface::~NativeWindowSurface() = default;

namespace impl {

class NativeWindowSurface final : public android::NativeWindowSurface {
public:
    static std::unique_ptr<android::NativeWindowSurface> create(
            const sp<IGraphicBufferProducer>& producer) {
        return std::make_unique<NativeWindowSurface>(producer);
    }

    explicit NativeWindowSurface(const sp<IGraphicBufferProducer>& producer)
          : surface(new Surface(producer, false)) {}

    ~NativeWindowSurface() override = default;

private:
    sp<ANativeWindow> getNativeWindow() const override { return surface; }

    void preallocateBuffers() override { surface->allocateBuffers(); }

    sp<Surface> surface;
};

} // namespace impl

SurfaceFlingerBE::SurfaceFlingerBE()
SurfaceFlingerBE::SurfaceFlingerBE()
      : mHwcServiceName(getHwcServiceName()),
      : mHwcServiceName(getHwcServiceName()),
        mRenderEngine(nullptr),
        mRenderEngine(nullptr),
@@ -194,7 +220,8 @@ SurfaceFlinger::SurfaceFlinger(SurfaceFlinger::SkipInitializationTag)
        mNumLayers(0),
        mNumLayers(0),
        mVrFlingerRequestsDisplay(false),
        mVrFlingerRequestsDisplay(false),
        mMainThreadId(std::this_thread::get_id()),
        mMainThreadId(std::this_thread::get_id()),
        mCreateBufferQueue(&BufferQueue::createBufferQueue) {}
        mCreateBufferQueue(&BufferQueue::createBufferQueue),
        mCreateNativeWindowSurface(&impl::NativeWindowSurface::create) {}


SurfaceFlinger::SurfaceFlinger() : SurfaceFlinger(SkipInitialization) {
SurfaceFlinger::SurfaceFlinger() : SurfaceFlinger(SkipInitialization) {
    ALOGI("SurfaceFlinger is starting");
    ALOGI("SurfaceFlinger is starting");
@@ -2182,6 +2209,84 @@ void SurfaceFlinger::processDisplayHotplugEventsLocked() {
    mPendingHotplugEvents.clear();
    mPendingHotplugEvents.clear();
}
}


sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
        const wp<IBinder>& display, int hwcId, const DisplayDeviceState& state,
        const sp<DisplaySurface>& dispSurface, const sp<IGraphicBufferProducer>& producer) {
    bool hasWideColorSupport = false;
    if (hasWideColorDisplay) {
        std::vector<ColorMode> modes = getHwComposer().getColorModes(state.type);
        for (ColorMode colorMode : modes) {
            switch (colorMode) {
                case ColorMode::DISPLAY_P3:
                case ColorMode::ADOBE_RGB:
                case ColorMode::DCI_P3:
                    hasWideColorSupport = true;
                    break;
                default:
                    break;
            }
        }
    }

    bool hasHdrSupport = false;
    std::unique_ptr<HdrCapabilities> hdrCapabilities =
            getHwComposer().getHdrCapabilities(state.type);
    if (hdrCapabilities) {
        const std::vector<int32_t> types = hdrCapabilities->getSupportedHdrTypes();
        auto iter = std::find(types.cbegin(), types.cend(), HAL_HDR_HDR10);
        hasHdrSupport = iter != types.cend();
    }

    auto nativeWindowSurface = mCreateNativeWindowSurface(producer);
    auto nativeWindow = nativeWindowSurface->getNativeWindow();

    /*
     * Create our display's surface
     */
    std::unique_ptr<RE::Surface> renderSurface = getRenderEngine().createSurface();
    renderSurface->setCritical(state.type == DisplayDevice::DISPLAY_PRIMARY);
    renderSurface->setAsync(state.type >= DisplayDevice::DISPLAY_VIRTUAL);
    renderSurface->setNativeWindow(nativeWindow.get());
    const int displayWidth = renderSurface->queryWidth();
    const int displayHeight = renderSurface->queryHeight();

    // Make sure that composition can never be stalled by a virtual display
    // consumer that isn't processing buffers fast enough. We have to do this
    // in two places:
    // * Here, in case the display is composed entirely by HWC.
    // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the
    //   window's swap interval in eglMakeCurrent, so they'll override the
    //   interval we set here.
    if (state.type >= DisplayDevice::DISPLAY_VIRTUAL) {
        nativeWindow->setSwapInterval(nativeWindow.get(), 0);
    }

    // virtual displays are always considered enabled
    auto initialPowerMode = (state.type >= DisplayDevice::DISPLAY_VIRTUAL) ? HWC_POWER_MODE_NORMAL
                                                                           : HWC_POWER_MODE_OFF;

    sp<DisplayDevice> hw =
            new DisplayDevice(this, state.type, hwcId, state.isSecure, display, nativeWindow,
                              dispSurface, std::move(renderSurface), displayWidth, displayHeight,
                              hasWideColorSupport, hasHdrSupport, initialPowerMode);

    if (maxFrameBufferAcquiredBuffers >= 3) {
        nativeWindowSurface->preallocateBuffers();
    }

    ColorMode defaultColorMode = ColorMode::NATIVE;
    if (hasWideColorSupport) {
        defaultColorMode = ColorMode::SRGB;
    }
    setActiveColorModeInternal(hw, defaultColorMode);
    hw->setCompositionDataSpace(HAL_DATASPACE_UNKNOWN);
    hw->setLayerStack(state.layerStack);
    hw->setProjection(state.orientation, state.viewport, state.frame);
    hw->setDisplayName(state.displayName);

    return hw;
}

void SurfaceFlinger::processDisplayChangesLocked() {
void SurfaceFlinger::processDisplayChangesLocked() {
    // here we take advantage of Vector's copy-on-write semantics to
    // here we take advantage of Vector's copy-on-write semantics to
    // improve performance by skipping the transaction entirely when
    // improve performance by skipping the transaction entirely when
@@ -2304,50 +2409,10 @@ void SurfaceFlinger::processDisplayChangesLocked() {
                }
                }


                const wp<IBinder>& display(curr.keyAt(i));
                const wp<IBinder>& display(curr.keyAt(i));

                if (dispSurface != nullptr) {
                if (dispSurface != nullptr) {
                    bool hasWideColorSupport = false;
                    mDisplays.add(display,
                    if (hasWideColorDisplay) {
                                  setupNewDisplayDeviceInternal(display, hwcId, state, dispSurface,
                        std::vector<ColorMode> modes =
                                                                producer));
                                getHwComposer().getColorModes(state.type);
                        for (ColorMode colorMode : modes) {
                            switch (colorMode) {
                                case ColorMode::DISPLAY_P3:
                                case ColorMode::ADOBE_RGB:
                                case ColorMode::DCI_P3:
                                    hasWideColorSupport = true;
                                    break;
                                default:
                                    break;
                            }
                        }
                    }

                    bool hasHdrSupport = false;
                    std::unique_ptr<HdrCapabilities> hdrCapabilities =
                        getHwComposer().getHdrCapabilities(state.type);
                    if (hdrCapabilities) {
                        const std::vector<int32_t> types = hdrCapabilities->getSupportedHdrTypes();
                        auto iter = std::find(types.cbegin(), types.cend(), HAL_HDR_HDR10);
                        hasHdrSupport = iter != types.cend();
                    }

                    sp<DisplayDevice> hw =
                            new DisplayDevice(this, state.type, hwcId, state.isSecure, display,
                                              dispSurface, producer, hasWideColorSupport,
                                              hasHdrSupport);

                    ColorMode defaultColorMode = ColorMode::NATIVE;
                    if (hasWideColorSupport) {
                        defaultColorMode = ColorMode::SRGB;
                    }
                    setActiveColorModeInternal(hw, defaultColorMode);
                    hw->setCompositionDataSpace(HAL_DATASPACE_UNKNOWN);
                    hw->setLayerStack(state.layerStack);
                    hw->setProjection(state.orientation, state.viewport, state.frame);
                    hw->setDisplayName(state.displayName);

                    mDisplays.add(display, hw);
                    if (!state.isVirtualDisplay()) {
                    if (!state.isVirtualDisplay()) {
                        mEventThread->onHotplugReceived(state.type, true);
                        mEventThread->onHotplugReceived(state.type, true);
                    }
                    }
+21 −0
Original line number Original line Diff line number Diff line
@@ -121,6 +121,19 @@ enum {
    eTransactionMask          = 0x07
    eTransactionMask          = 0x07
};
};


// A thin interface to abstract creating instances of Surface (gui/Surface.h) to
// use as a NativeWindow.
class NativeWindowSurface {
public:
    virtual ~NativeWindowSurface();

    // Gets the NativeWindow to use for the surface.
    virtual sp<ANativeWindow> getNativeWindow() const = 0;

    // Indicates that the surface should allocate its buffers now.
    virtual void preallocateBuffers() = 0;
};

class SurfaceFlingerBE
class SurfaceFlingerBE
{
{
public:
public:
@@ -650,6 +663,10 @@ private:
     */
     */
    DisplayDevice::DisplayType determineDisplayType(hwc2_display_t display,
    DisplayDevice::DisplayType determineDisplayType(hwc2_display_t display,
            HWC2::Connection connection) const;
            HWC2::Connection connection) const;
    sp<DisplayDevice> setupNewDisplayDeviceInternal(const wp<IBinder>& display, int hwcId,
                                                    const DisplayDeviceState& state,
                                                    const sp<DisplaySurface>& dispSurface,
                                                    const sp<IGraphicBufferProducer>& producer);
    void processDisplayChangesLocked();
    void processDisplayChangesLocked();
    void processDisplayHotplugEventsLocked();
    void processDisplayHotplugEventsLocked();


@@ -843,6 +860,10 @@ private:
                               bool /* consumerIsSurfaceFlinger */)>;
                               bool /* consumerIsSurfaceFlinger */)>;
    CreateBufferQueueFunction mCreateBufferQueue;
    CreateBufferQueueFunction mCreateBufferQueue;


    using CreateNativeWindowSurfaceFunction =
            std::function<std::unique_ptr<NativeWindowSurface>(const sp<IGraphicBufferProducer>&)>;
    CreateNativeWindowSurfaceFunction mCreateNativeWindowSurface;

    SurfaceFlingerBE mBE;
    SurfaceFlingerBE mBE;
};
};
}; // namespace android
}; // namespace android