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

Commit 4952a2ce authored by Vishnu Nair's avatar Vishnu Nair Committed by Android (Google) Code Review
Browse files

Merge "SF: Support display mirroring with new frontend"

parents d4c2c504 a9c43763
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -18,10 +18,12 @@

#include <binder/Binder.h>
#include <gui/LayerMetadata.h>
#include <ui/LayerStack.h>
#include <utils/StrongPointer.h>
#include <cstdint>
#include <limits>
#include <optional>

constexpr uint32_t UNASSIGNED_LAYER_ID = std::numeric_limits<uint32_t>::max();

namespace android {
@@ -51,6 +53,7 @@ struct LayerCreationArgs {
    bool addToRoot = true;
    wp<IBinder> parentHandle = nullptr;
    wp<IBinder> mirrorLayerHandle = nullptr;
    ui::LayerStack layerStackToMirror = ui::INVALID_LAYER_STACK;
};

} // namespace android::surfaceflinger
+7 −7
Original line number Diff line number Diff line
@@ -252,8 +252,8 @@ void LayerHierarchyBuilder::onLayerAdded(RequestedLayerState* layer) {
    attachToParent(hierarchy);
    attachToRelativeParent(hierarchy);

    if (layer->mirrorId != UNASSIGNED_LAYER_ID) {
        LayerHierarchy* mirror = getHierarchyFromId(layer->mirrorId);
    for (uint32_t mirrorId : layer->mirrorIds) {
        LayerHierarchy* mirror = getHierarchyFromId(mirrorId);
        hierarchy->addChild(mirror, LayerHierarchy::Variant::Mirror);
    }
}
@@ -292,14 +292,14 @@ void LayerHierarchyBuilder::updateMirrorLayer(RequestedLayerState* layer) {
    auto it = hierarchy->mChildren.begin();
    while (it != hierarchy->mChildren.end()) {
        if (it->second == LayerHierarchy::Variant::Mirror) {
            hierarchy->mChildren.erase(it);
            break;
        }
            it = hierarchy->mChildren.erase(it);
        } else {
            it++;
        }
    }

    if (layer->mirrorId != UNASSIGNED_LAYER_ID) {
        hierarchy->addChild(getHierarchyFromId(layer->mirrorId), LayerHierarchy::Variant::Mirror);
    for (uint32_t mirrorId : layer->mirrorIds) {
        hierarchy->addChild(getHierarchyFromId(mirrorId), LayerHierarchy::Variant::Mirror);
    }
}

+71 −5
Original line number Diff line number Diff line
@@ -44,9 +44,28 @@ void LayerLifecycleManager::addLayers(std::vector<std::unique_ptr<RequestedLayer

        layer.parentId = linkLayer(layer.parentId, layer.id);
        layer.relativeParentId = linkLayer(layer.relativeParentId, layer.id);
        layer.mirrorId = linkLayer(layer.mirrorId, layer.id);
        if (layer.layerStackToMirror != ui::INVALID_LAYER_STACK) {
            // if this layer is mirroring a display, then walk though all the existing root layers
            // for the layer stack and add them as children to be mirrored.
            mDisplayMirroringLayers.emplace_back(layer.id);
            for (auto& rootLayer : mLayers) {
                if (rootLayer->isRoot() && rootLayer->layerStack == layer.layerStackToMirror) {
                    layer.mirrorIds.emplace_back(rootLayer->id);
                    linkLayer(rootLayer->id, layer.id);
                }
            }
        } else {
            // Check if we are mirroring a single layer, and if so add it to the list of children
            // to be mirrored.
            layer.layerIdToMirror = linkLayer(layer.layerIdToMirror, layer.id);
            if (layer.layerIdToMirror != UNASSIGNED_LAYER_ID) {
                layer.mirrorIds.emplace_back(layer.layerIdToMirror);
            }
        }
        layer.touchCropId = linkLayer(layer.touchCropId, layer.id);

        if (layer.isRoot()) {
            updateDisplayMirrorLayers(layer);
        }
        mLayers.emplace_back(std::move(newLayer));
    }
}
@@ -85,7 +104,14 @@ void LayerLifecycleManager::onHandlesDestroyed(const std::vector<uint32_t>& dest

        layer.parentId = unlinkLayer(layer.parentId, layer.id);
        layer.relativeParentId = unlinkLayer(layer.relativeParentId, layer.id);
        layer.mirrorId = unlinkLayer(layer.mirrorId, layer.id);
        if (layer.layerStackToMirror != ui::INVALID_LAYER_STACK) {
            layer.mirrorIds = unlinkLayers(layer.mirrorIds, layer.id);
            swapErase(mDisplayMirroringLayers, layer.id);
        } else {
            layer.layerIdToMirror = unlinkLayer(layer.layerIdToMirror, layer.id);
            layer.mirrorIds.clear();
        }

        layer.touchCropId = unlinkLayer(layer.touchCropId, layer.id);

        auto& references = it->second.references;
@@ -106,8 +132,8 @@ void LayerLifecycleManager::onHandlesDestroyed(const std::vector<uint32_t>& dest
            if (linkedLayer->relativeParentId == layer.id) {
                linkedLayer->relativeParentId = UNASSIGNED_LAYER_ID;
            }
            if (linkedLayer->mirrorId == layer.id) {
                linkedLayer->mirrorId = UNASSIGNED_LAYER_ID;
            if (swapErase(linkedLayer->mirrorIds, layer.id)) {
                linkedLayer->changes |= RequestedLayerState::Changes::Mirror;
            }
            if (linkedLayer->touchCropId == layer.id) {
                linkedLayer->touchCropId = UNASSIGNED_LAYER_ID;
@@ -200,6 +226,12 @@ void LayerLifecycleManager::applyTransactions(const std::vector<TransactionState
            if (oldParentId != layer->parentId) {
                unlinkLayer(oldParentId, layer->id);
                layer->parentId = linkLayer(layer->parentId, layer->id);
                if (oldParentId == UNASSIGNED_LAYER_ID) {
                    updateDisplayMirrorLayers(*layer);
                }
            }
            if (layer->what & layer_state_t::eLayerStackChanged && layer->isRoot()) {
                updateDisplayMirrorLayers(*layer);
            }
            if (oldRelativeParentId != layer->relativeParentId) {
                unlinkLayer(oldRelativeParentId, layer->id);
@@ -308,6 +340,14 @@ uint32_t LayerLifecycleManager::unlinkLayer(uint32_t layerId, uint32_t linkedLay
    return UNASSIGNED_LAYER_ID;
}

std::vector<uint32_t> LayerLifecycleManager::unlinkLayers(const std::vector<uint32_t>& layerIds,
                                                          uint32_t linkedLayer) {
    for (uint32_t layerId : layerIds) {
        unlinkLayer(layerId, linkedLayer);
    }
    return {};
}

std::string LayerLifecycleManager::References::getDebugString() const {
    std::string debugInfo = owner.name + "[" + std::to_string(owner.id) + "] refs:";
    std::for_each(references.begin(), references.end(),
@@ -329,4 +369,30 @@ void LayerLifecycleManager::fixRelativeZLoop(uint32_t relativeRootId) {
    mGlobalChanges |= RequestedLayerState::Changes::Hierarchy;
}

// Some layers mirror the entire display stack. Since we don't have a single root layer per display
// we have to track all these layers and update what they mirror when the list of root layers
// on a display changes. This function walks through the list of display mirroring layers
// and updates its list of layers that its mirroring. This function should be called when a new
// root layer is added, removed or moved to another display.
void LayerLifecycleManager::updateDisplayMirrorLayers(RequestedLayerState& rootLayer) {
    for (uint32_t mirrorLayerId : mDisplayMirroringLayers) {
        RequestedLayerState* mirrorLayer = getLayerFromId(mirrorLayerId);
        bool canBeMirrored =
                rootLayer.isRoot() && rootLayer.layerStack == mirrorLayer->layerStackToMirror;
        bool currentlyMirrored =
                std::find(mirrorLayer->mirrorIds.begin(), mirrorLayer->mirrorIds.end(),
                          rootLayer.id) != mirrorLayer->mirrorIds.end();

        if (canBeMirrored && !currentlyMirrored) {
            mirrorLayer->mirrorIds.emplace_back(rootLayer.id);
            linkLayer(rootLayer.id, mirrorLayer->id);
            mirrorLayer->changes |= RequestedLayerState::Changes::Mirror;
        } else if (!canBeMirrored && currentlyMirrored) {
            swapErase(mirrorLayer->mirrorIds, rootLayer.id);
            unlinkLayer(rootLayer.id, mirrorLayer->id);
            mirrorLayer->changes |= RequestedLayerState::Changes::Mirror;
        }
    }
}

} // namespace android::surfaceflinger::frontend
+5 −0
Original line number Diff line number Diff line
@@ -80,6 +80,9 @@ private:
    std::vector<uint32_t>* getLinkedLayersFromId(uint32_t);
    uint32_t linkLayer(uint32_t layerId, uint32_t layerToLink);
    uint32_t unlinkLayer(uint32_t layerId, uint32_t linkedLayer);
    std::vector<uint32_t> unlinkLayers(const std::vector<uint32_t>& layerIds, uint32_t linkedLayer);

    void updateDisplayMirrorLayers(RequestedLayerState& rootLayer);

    struct References {
        // Lifetime tied to mLayers
@@ -90,6 +93,8 @@ private:
    std::unordered_map<uint32_t, References> mIdToLayer;
    // Listeners are invoked once changes are committed.
    std::vector<std::shared_ptr<ILifecycleListener>> mListeners;
    // Layers that mirror a display stack (see updateDisplayMirrorLayers)
    std::vector<uint32_t> mDisplayMirroringLayers;

    // Aggregation of changes since last commit.
    ftl::Flags<RequestedLayerState::Changes> mGlobalChanges;
+5 −0
Original line number Diff line number Diff line
@@ -112,6 +112,10 @@ bool LayerSnapshot::isHiddenByPolicy() const {
}

bool LayerSnapshot::getIsVisible() const {
    if (handleSkipScreenshotFlag & outputFilter.toInternalDisplay) {
        return false;
    }

    if (!hasSomethingToDraw()) {
        return false;
    }
@@ -125,6 +129,7 @@ bool LayerSnapshot::getIsVisible() const {

std::string LayerSnapshot::getIsVisibleReason() const {
    // not visible
    if (handleSkipScreenshotFlag & outputFilter.toInternalDisplay) return "eLayerSkipScreenshot";
    if (!hasSomethingToDraw()) return "!hasSomethingToDraw";
    if (invalidTransform) return "invalidTransform";
    if (isHiddenByPolicyFromParent) return "hidden by parent or layer flag";
Loading