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

Commit 33d56fbd authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes Icef8ee6c,I2abd5d58,I96266db8,Id84f5b99

* changes:
  Eliminate duplicate device creation code
  Fix VrFlinger handoff
  Move hotplug processing to the main thread
  Create processDisplayChangesLocked
parents 88d73c02 03dfbd52
Loading
Loading
Loading
Loading
+0 −14
Original line number Diff line number Diff line
@@ -169,20 +169,6 @@ DisplayDevice::DisplayDevice(
    mPowerMode = (mType >= DisplayDevice::DISPLAY_VIRTUAL) ?
                  HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF;

    // Name the display.  The name will be replaced shortly if the display
    // was created with createDisplay().
    switch (mType) {
        case DISPLAY_PRIMARY:
            mDisplayName = "Built-in Screen";
            break;
        case DISPLAY_EXTERNAL:
            mDisplayName = "HDMI Screen";
            break;
        default:
            mDisplayName = "Virtual Screen";    // e.g. Overlay #n
            break;
    }

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

+240 −240
Original line number Diff line number Diff line
@@ -369,17 +369,6 @@ void SurfaceFlinger::destroyDisplay(const sp<IBinder>& display) {
    setTransactionFlags(eDisplayTransactionNeeded);
}

void SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) {
    ALOGV("createBuiltinDisplayLocked(%d)", type);
    ALOGW_IF(mBuiltinDisplays[type],
            "Overwriting display token for display type %d", type);
    mBuiltinDisplays[type] = new BBinder();
    // All non-virtual displays are currently considered secure.
    DisplayDeviceState info(type, true);
    mCurrentState.displays.add(mBuiltinDisplays[type], info);
    mInterceptor.saveDisplayCreation(info);
}

sp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
    if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
        ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
@@ -627,6 +616,15 @@ void SurfaceFlinger::init() {
            "Starting with vr flinger active is not currently supported.");
    mHwc.reset(new HWComposer(mHwcServiceName));
    mHwc->registerCallback(this, mComposerSequenceId);
    // Process any initial hotplug and resulting display changes.
    processDisplayHotplugEventsLocked();
    LOG_ALWAYS_FATAL_IF(!mHwc->isConnected(HWC_DISPLAY_PRIMARY),
                        "Registered composer callback but didn't create the default primary "
                        "display");

    // make the default display GLContext current so that we can create textures
    // when creating Layers (which may happens before we render something)
    getDefaultDisplayDeviceLocked()->makeCurrent(mEGLDisplay, mEGLContext);

    if (useVrFlinger) {
        auto vrFlingerRequestDisplayCallback = [this] (bool requestDisplay) {
@@ -1262,52 +1260,6 @@ void SurfaceFlinger::getCompositorTiming(CompositorTiming* compositorTiming) {
    *compositorTiming = mCompositorTiming;
}

void SurfaceFlinger::createDefaultDisplayDevice() {
    const DisplayDevice::DisplayType type = DisplayDevice::DISPLAY_PRIMARY;
    wp<IBinder> token = mBuiltinDisplays[type];

    // All non-virtual displays are currently considered secure.
    const bool isSecure = true;

    sp<IGraphicBufferProducer> producer;
    sp<IGraphicBufferConsumer> consumer;
    BufferQueue::createBufferQueue(&producer, &consumer);

    sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, type, consumer);

    bool hasWideColorModes = false;
    std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(type);
    for (android_color_mode_t colorMode : modes) {
        switch (colorMode) {
            case HAL_COLOR_MODE_DISPLAY_P3:
            case HAL_COLOR_MODE_ADOBE_RGB:
            case HAL_COLOR_MODE_DCI_P3:
                hasWideColorModes = true;
                break;
            default:
                break;
        }
    }
    sp<DisplayDevice> hw = new DisplayDevice(this, DisplayDevice::DISPLAY_PRIMARY, type, isSecure,
                                             token, fbs, producer, mRenderEngine->getEGLConfig(),
                                             hasWideColorModes && hasWideColorDisplay);
    mDisplays.add(token, hw);
    android_color_mode defaultColorMode = HAL_COLOR_MODE_NATIVE;
    if (hasWideColorModes && hasWideColorDisplay) {
        defaultColorMode = HAL_COLOR_MODE_SRGB;
    }
    setActiveColorModeInternal(hw, defaultColorMode);
    hw->setCompositionDataSpace(HAL_DATASPACE_UNKNOWN);

    // Add the primary display token to mDrawingState so we don't try to
    // recreate the DisplayDevice for the primary display.
    mDrawingState.displays.add(token, DisplayDeviceState(type, true));

    // make the GLContext current so that we can create textures when creating
    // Layers (which may happens before we render something)
    hw->makeCurrent(mEGLDisplay, mEGLContext);
}

void SurfaceFlinger::onHotplugReceived(int32_t sequenceId,
        hwc2_display_t display, HWC2::Connection connection,
        bool primaryDisplay) {
@@ -1317,39 +1269,25 @@ void SurfaceFlinger::onHotplugReceived(int32_t sequenceId,
                  "connected" : "disconnected",
          primaryDisplay ? "primary" : "external");

    // Ignore events that do not have the right sequenceId.
    if (sequenceId != mComposerSequenceId) {
        return;
    }

    // Only lock if we're not on the main thread. This function is normally
    // called on a hwbinder thread, but for the primary display it's called on
    // the main thread with the state lock already held, so don't attempt to
    // acquire it here.
    ConditionalLock lock(mStateLock,
            std::this_thread::get_id() != mMainThreadId);
    ConditionalLock lock(mStateLock, std::this_thread::get_id() != mMainThreadId);

    if (primaryDisplay) {
        mHwc->onHotplug(display, connection);
        if (!mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY].get()) {
            createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY);
        }
        createDefaultDisplayDevice();
    } else {
        if (sequenceId != mComposerSequenceId) {
            return;
        }
        if (mHwc->isUsingVrComposer()) {
            ALOGE("External displays are not supported by the vr hardware composer.");
            return;
        }
        mHwc->onHotplug(display, connection);
        auto type = DisplayDevice::DISPLAY_EXTERNAL;
        if (connection == HWC2::Connection::Connected) {
            createBuiltinDisplayLocked(type);
        } else {
            mCurrentState.displays.removeItem(mBuiltinDisplays[type]);
            mBuiltinDisplays[type].clear();
        }
        setTransactionFlags(eDisplayTransactionNeeded);
    mPendingHotplugEvents.emplace_back(HotplugEvent{display, connection, primaryDisplay});

        // Defer EventThread notification until SF has updated mDisplays.
    if (std::this_thread::get_id() == mMainThreadId) {
        // Process all pending hot plug events immediately if we are on the main thread.
        processDisplayHotplugEventsLocked();
    }

    setTransactionFlags(eDisplayTransactionNeeded);
}

void SurfaceFlinger::onRefreshReceived(int sequenceId,
@@ -2089,34 +2027,49 @@ void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
    // here the transaction has been committed
}

void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
{
    // Notify all layers of available frames
    mCurrentState.traverseInZOrder([](Layer* layer) {
        layer->notifyAvailableFrames();
    });
void SurfaceFlinger::processDisplayHotplugEventsLocked() {
    for (const auto& event : mPendingHotplugEvents) {
        DisplayDevice::DisplayType displayType = event.isPrimaryDisplay
                ? DisplayDevice::DISPLAY_PRIMARY
                : DisplayDevice::DISPLAY_EXTERNAL;

    /*
     * Traversal of the children
     * (perform the transaction for each of them if needed)
     */
        if (mHwc->isUsingVrComposer() && displayType == DisplayDevice::DISPLAY_EXTERNAL) {
            ALOGE("External displays are not supported by the vr hardware composer.");
            continue;
        }

    if (transactionFlags & eTraversalNeeded) {
        mCurrentState.traverseInZOrder([&](Layer* layer) {
            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
            if (!trFlags) return;
        mHwc->onHotplug(event.display, event.connection);

            const uint32_t flags = layer->doTransaction(0);
            if (flags & Layer::eVisibleRegion)
                mVisibleRegionsDirty = true;
        });
        if (event.connection == HWC2::Connection::Connected) {
            ALOGV("Creating built in display %d", displayType);
            ALOGW_IF(mBuiltinDisplays[displayType], "Overwriting display token for display type %d",
                     displayType);
            mBuiltinDisplays[displayType] = new BBinder();
            // All non-virtual displays are currently considered secure.
            DisplayDeviceState info(displayType, true);
            info.displayName = displayType == DisplayDevice::DISPLAY_PRIMARY ? "Built-in Screen"
                                                                             : "External Screen";
            mCurrentState.displays.add(mBuiltinDisplays[displayType], info);
            mInterceptor.saveDisplayCreation(info);
        } else {
            ALOGV("Removing built in display %d", displayType);

            ssize_t idx = mCurrentState.displays.indexOfKey(mBuiltinDisplays[displayType]);
            if (idx >= 0) {
                const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx));
                mInterceptor.saveDisplayDeletion(info.displayId);
                mCurrentState.displays.removeItemsAt(idx);
            }
            mBuiltinDisplays[displayType].clear();
        }

    /*
     * Perform display own transactions if needed
     */
        processDisplayChangesLocked();
    }

    if (transactionFlags & eDisplayTransactionNeeded) {
    mPendingHotplugEvents.clear();
}

void SurfaceFlinger::processDisplayChangesLocked() {
    // here we take advantage of Vector's copy-on-write semantics to
    // improve performance by skipping the transaction entirely when
    // know that the lists are identical
@@ -2142,8 +2095,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
                    const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDeviceLocked());
                    defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext);
                    sp<DisplayDevice> hw(getDisplayDeviceLocked(draw.keyAt(i)));
                        if (hw != NULL)
                            hw->disconnect(getHwComposer());
                    if (hw != NULL) hw->disconnect(getHwComposer());
                    if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES)
                        mEventThread->onHotplugReceived(draw[i].type, false);
                    mDisplays.removeItem(draw.keyAt(i));
@@ -2162,8 +2114,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
                    // from the drawing state, so that it get re-added
                    // below.
                    sp<DisplayDevice> hw(getDisplayDeviceLocked(display));
                        if (hw != NULL)
                            hw->disconnect(getHwComposer());
                    if (hw != NULL) hw->disconnect(getHwComposer());
                    mDisplays.removeItem(display);
                    mDrawingState.displays.removeItemsAt(i);
                    dc--;
@@ -2176,12 +2127,9 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
                    if (state.layerStack != draw[i].layerStack) {
                        disp->setLayerStack(state.layerStack);
                    }
                        if ((state.orientation != draw[i].orientation)
                                || (state.viewport != draw[i].viewport)
                                || (state.frame != draw[i].frame))
                        {
                            disp->setProjection(state.orientation,
                                    state.viewport, state.frame);
                    if ((state.orientation != draw[i].orientation) ||
                        (state.viewport != draw[i].viewport) || (state.frame != draw[i].frame)) {
                        disp->setProjection(state.orientation, state.viewport, state.frame);
                    }
                    if (state.width != draw[i].width || state.height != draw[i].height) {
                        disp->setDisplaySize(state.width, state.height);
@@ -2209,36 +2157,26 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
                    // they have external state (layer stack, projection,
                    // etc.) but no internal state (i.e. a DisplayDevice).
                    if (state.surface != NULL) {

                        // Allow VR composer to use virtual displays.
                        if (mUseHwcVirtualDisplays || mHwc->isUsingVrComposer()) {
                            int width = 0;
                                int status = state.surface->query(
                                        NATIVE_WINDOW_WIDTH, &width);
                                ALOGE_IF(status != NO_ERROR,
                                        "Unable to query width (%d)", status);
                            int status = state.surface->query(NATIVE_WINDOW_WIDTH, &width);
                            ALOGE_IF(status != NO_ERROR, "Unable to query width (%d)", status);
                            int height = 0;
                                status = state.surface->query(
                                        NATIVE_WINDOW_HEIGHT, &height);
                                ALOGE_IF(status != NO_ERROR,
                                        "Unable to query height (%d)", status);
                            status = state.surface->query(NATIVE_WINDOW_HEIGHT, &height);
                            ALOGE_IF(status != NO_ERROR, "Unable to query height (%d)", status);
                            int intFormat = 0;
                                status = state.surface->query(
                                        NATIVE_WINDOW_FORMAT, &intFormat);
                                ALOGE_IF(status != NO_ERROR,
                                        "Unable to query format (%d)", status);
                                auto format = static_cast<android_pixel_format_t>(
                                        intFormat);
                            status = state.surface->query(NATIVE_WINDOW_FORMAT, &intFormat);
                            ALOGE_IF(status != NO_ERROR, "Unable to query format (%d)", status);
                            auto format = static_cast<android_pixel_format_t>(intFormat);

                                mHwc->allocateVirtualDisplay(width, height, &format,
                                        &hwcId);
                            mHwc->allocateVirtualDisplay(width, height, &format, &hwcId);
                        }

                        // TODO: Plumb requested format back up to consumer

                        sp<VirtualDisplaySurface> vds =
                                    new VirtualDisplaySurface(*mHwc,
                                            hwcId, state.surface, bqProducer,
                                new VirtualDisplaySurface(*mHwc, hwcId, state.surface, bqProducer,
                                                          bqConsumer, state.displayName);

                        dispSurface = vds;
@@ -2256,15 +2194,43 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
                }

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

                if (dispSurface != NULL) {
                    bool useWideColorMode = hasWideColorDisplay;
                    if (state.isMainDisplay()) {
                        bool hasWideColorModes = false;
                        std::vector<android_color_mode_t> modes =
                                getHwComposer().getColorModes(state.type);
                        for (android_color_mode_t colorMode : modes) {
                            switch (colorMode) {
                                case HAL_COLOR_MODE_DISPLAY_P3:
                                case HAL_COLOR_MODE_ADOBE_RGB:
                                case HAL_COLOR_MODE_DCI_P3:
                                    hasWideColorModes = true;
                                    break;
                                default:
                                    break;
                            }
                        }
                        useWideColorMode = hasWideColorModes && hasWideColorDisplay;
                    }

                    sp<DisplayDevice> hw =
                            new DisplayDevice(this, state.type, hwcId, state.isSecure, display,
                                                  dispSurface, producer,
                                                  mRenderEngine->getEGLConfig(),
                                                  hasWideColorDisplay);
                                              dispSurface, producer, mRenderEngine->getEGLConfig(),
                                              useWideColorMode);

                    if (state.isMainDisplay()) {
                        android_color_mode defaultColorMode = HAL_COLOR_MODE_NATIVE;
                        if (useWideColorMode) {
                            defaultColorMode = HAL_COLOR_MODE_SRGB;
                        }
                        setActiveColorModeInternal(hw, defaultColorMode);
                        hw->setCompositionDataSpace(HAL_DATASPACE_UNKNOWN);
                    }

                    hw->setLayerStack(state.layerStack);
                        hw->setProjection(state.orientation,
                                state.viewport, state.frame);
                    hw->setProjection(state.orientation, state.viewport, state.frame);
                    hw->setDisplayName(state.displayName);
                    mDisplays.add(display, hw);
                    if (!state.isVirtualDisplay()) {
@@ -2274,6 +2240,40 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
            }
        }
    }

    mDrawingState.displays = mCurrentState.displays;
}

void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
{
    // Notify all layers of available frames
    mCurrentState.traverseInZOrder([](Layer* layer) {
        layer->notifyAvailableFrames();
    });

    /*
     * Traversal of the children
     * (perform the transaction for each of them if needed)
     */

    if (transactionFlags & eTraversalNeeded) {
        mCurrentState.traverseInZOrder([&](Layer* layer) {
            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
            if (!trFlags) return;

            const uint32_t flags = layer->doTransaction(0);
            if (flags & Layer::eVisibleRegion)
                mVisibleRegionsDirty = true;
        });
    }

    /*
     * Perform display own transactions if needed
     */

    if (transactionFlags & eDisplayTransactionNeeded) {
        processDisplayChangesLocked();
        processDisplayHotplugEventsLocked();
    }

    if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) {
+15 −4
Original line number Diff line number Diff line
@@ -483,9 +483,9 @@ private:
    // called when starting, or restarting after system_server death
    void initializeDisplays();

    // Create an IBinder for a builtin display and add it to current state
#ifndef USE_HWC2
    void createBuiltinDisplayLocked(DisplayDevice::DisplayType type);

#endif

    sp<const DisplayDevice> getDisplayDevice(const wp<IBinder>& dpy) const {
      Mutex::Autolock _l(mStateLock);
@@ -511,8 +511,6 @@ private:
        return getDisplayDeviceLocked(mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY]);
    }

    void createDefaultDisplayDevice();

    int32_t getDisplayType(const sp<IBinder>& display) {
        if (!display.get()) return NAME_NOT_FOUND;
        for (int i = 0; i < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES; ++i) {
@@ -576,6 +574,8 @@ private:
    /* ------------------------------------------------------------------------
     * Display management
     */
    void processDisplayChangesLocked();
    void processDisplayHotplugEventsLocked();

    /* ------------------------------------------------------------------------
     * VSync
@@ -705,6 +705,17 @@ private:
    FenceTimeline mGlCompositionDoneTimeline;
    FenceTimeline mDisplayTimeline;

#ifdef USE_HWC2
    struct HotplugEvent {
        hwc2_display_t display;
        HWC2::Connection connection = HWC2::Connection::Invalid;
        bool isPrimaryDisplay;
    };
    // protected by mStateLock
    std::vector<HotplugEvent> mPendingHotplugEvents;
#endif


    // this may only be written from the main thread with mStateLock held
    // it may be read from other threads with mStateLock held
    DefaultKeyedVector< wp<IBinder>, sp<DisplayDevice> > mDisplays;
+3 −0
Original line number Diff line number Diff line
@@ -309,6 +309,9 @@ void SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type)
    mBuiltinDisplays[type] = new BBinder();
    // All non-virtual displays are currently considered secure.
    DisplayDeviceState info(type, true);
    info.displayName =
            type== DisplayDevice::DISPLAY_PRIMARY ? "Built-in Screen" : "External Screen";

    mCurrentState.displays.add(mBuiltinDisplays[type], info);
    mInterceptor.saveDisplayCreation(info);
}