/* * Copyright 2022 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. */ // #define LOG_NDEBUG 0 #define ATRACE_TAG ATRACE_TAG_GRAPHICS #undef LOG_TAG #define LOG_TAG "SurfaceFlinger" #include "LayerLifecycleManager.h" #include "Client.h" // temporarily needed for LayerCreationArgs #include "LayerLog.h" #include "SwapErase.h" namespace android::surfaceflinger::frontend { using namespace ftl::flag_operators; namespace { // Returns true if the layer is root of a display and can be mirrored by mirroringLayer bool canMirrorRootLayer(RequestedLayerState& mirroringLayer, RequestedLayerState& rootLayer) { return rootLayer.isRoot() && rootLayer.layerStack == mirroringLayer.layerStackToMirror && rootLayer.id != mirroringLayer.id; } } // namespace void LayerLifecycleManager::addLayers(std::vector> newLayers) { if (newLayers.empty()) { return; } mGlobalChanges |= RequestedLayerState::Changes::Hierarchy; for (auto& newLayer : newLayers) { RequestedLayerState& layer = *newLayer.get(); auto [it, inserted] = mIdToLayer.try_emplace(layer.id, References{.owner = layer}); LLOG_ALWAYS_FATAL_WITH_TRACE_IF(!inserted, "Duplicate layer id found. New layer: %s Existing layer: " "%s", layer.getDebugString().c_str(), it->second.owner.getDebugString().c_str()); mAddedLayers.push_back(newLayer.get()); mChangedLayers.push_back(newLayer.get()); layer.parentId = linkLayer(layer.parentId, layer.id); layer.relativeParentId = linkLayer(layer.relativeParentId, layer.id); if (layer.layerStackToMirror != ui::INVALID_LAYER_STACK) { // Set mirror layer's default layer stack to -1 so it doesn't end up rendered on a // display accidentally. layer.layerStack = 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 (canMirrorRootLayer(layer, *rootLayer)) { 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 (!FlagManager::getInstance().detached_mirror()) { if (layer.layerIdToMirror != UNASSIGNED_LAYER_ID) { layer.mirrorIds.emplace_back(layer.layerIdToMirror); } } } layer.touchCropId = linkLayer(layer.touchCropId, layer.id); if (layer.isRoot()) { updateDisplayMirrorLayers(layer); } LLOGV(layer.id, "%s", layer.getDebugString().c_str()); mLayers.emplace_back(std::move(newLayer)); } } void LayerLifecycleManager::onHandlesDestroyed( const std::vector>& destroyedHandles, bool ignoreUnknownHandles) { std::vector layersToBeDestroyed; for (const auto& [layerId, name] : destroyedHandles) { auto it = mIdToLayer.find(layerId); if (it == mIdToLayer.end()) { LLOG_ALWAYS_FATAL_WITH_TRACE_IF(!ignoreUnknownHandles, "%s Layerid not found %s[%d]", __func__, name.c_str(), layerId); continue; } RequestedLayerState& layer = it->second.owner; LLOGV(layer.id, "%s", layer.getDebugString().c_str()); layer.handleAlive = false; if (!layer.canBeDestroyed()) { continue; } layer.changes |= RequestedLayerState::Changes::Destroyed; layersToBeDestroyed.emplace_back(layerId); } if (layersToBeDestroyed.empty()) { return; } mGlobalChanges |= RequestedLayerState::Changes::Hierarchy; for (size_t i = 0; i < layersToBeDestroyed.size(); i++) { uint32_t layerId = layersToBeDestroyed[i]; auto it = mIdToLayer.find(layerId); LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mIdToLayer.end(), "%s Layer with id %d not found", __func__, layerId); RequestedLayerState& layer = it->second.owner; layer.parentId = unlinkLayer(layer.parentId, layer.id); layer.relativeParentId = unlinkLayer(layer.relativeParentId, 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; for (uint32_t linkedLayerId : references) { RequestedLayerState* linkedLayer = getLayerFromId(linkedLayerId); LLOG_ALWAYS_FATAL_WITH_TRACE_IF(!linkedLayer, "%s Layerid reference %d not found for %d", __func__, linkedLayerId, layer.id); if (linkedLayer->parentId == layer.id) { linkedLayer->parentId = UNASSIGNED_LAYER_ID; if (linkedLayer->canBeDestroyed()) { linkedLayer->changes |= RequestedLayerState::Changes::Destroyed; layersToBeDestroyed.emplace_back(linkedLayer->id); } } if (linkedLayer->relativeParentId == layer.id) { linkedLayer->relativeParentId = UNASSIGNED_LAYER_ID; } if (swapErase(linkedLayer->mirrorIds, layer.id)) { linkedLayer->changes |= RequestedLayerState::Changes::Mirror; } if (linkedLayer->layerIdToMirror == layer.id) { linkedLayer->layerIdToMirror = UNASSIGNED_LAYER_ID; linkedLayer->changes |= RequestedLayerState::Changes::Mirror; } if (linkedLayer->touchCropId == layer.id) { linkedLayer->touchCropId = UNASSIGNED_LAYER_ID; } } mIdToLayer.erase(it); } auto it = mLayers.begin(); while (it != mLayers.end()) { RequestedLayerState* layer = it->get(); if (layer->changes.test(RequestedLayerState::Changes::Destroyed)) { LLOGV(layer->id, "destroyed %s", layer->getDebugStringShort().c_str()); std::iter_swap(it, mLayers.end() - 1); mDestroyedLayers.emplace_back(std::move(mLayers.back())); if (it == mLayers.end() - 1) { it = mLayers.erase(mLayers.end() - 1); } else { mLayers.erase(mLayers.end() - 1); } } else { it++; } } } void LayerLifecycleManager::applyTransactions(const std::vector& transactions, bool ignoreUnknownLayers) { for (const auto& transaction : transactions) { for (const auto& resolvedComposerState : transaction.states) { const auto& clientState = resolvedComposerState.state; uint32_t layerId = resolvedComposerState.layerId; if (layerId == UNASSIGNED_LAYER_ID) { ALOGW("%s Handle %p is not valid", __func__, clientState.surface.get()); continue; } RequestedLayerState* layer = getLayerFromId(layerId); if (layer == nullptr) { LLOG_ALWAYS_FATAL_WITH_TRACE_IF(!ignoreUnknownLayers, "%s Layer with layerid=%d not found", __func__, layerId); continue; } LLOG_ALWAYS_FATAL_WITH_TRACE_IF(!layer->handleAlive, "%s Layer's with layerid=%d) is not alive. Possible " "out of " "order LayerLifecycleManager updates", __func__, layerId); if (layer->changes.get() == 0) { mChangedLayers.push_back(layer); } if (transaction.flags & ISurfaceComposer::eAnimation) { layer->changes |= RequestedLayerState::Changes::Animation; } uint32_t oldParentId = layer->parentId; uint32_t oldRelativeParentId = layer->relativeParentId; uint32_t oldTouchCropId = layer->touchCropId; layer->merge(resolvedComposerState); if (layer->what & layer_state_t::eBackgroundColorChanged) { if (layer->bgColorLayerId == UNASSIGNED_LAYER_ID && layer->bgColor.a != 0) { LayerCreationArgs backgroundLayerArgs(LayerCreationArgs::getInternalLayerId( LayerCreationArgs::sInternalSequence++), /*internalLayer=*/true); backgroundLayerArgs.parentId = layer->id; backgroundLayerArgs.name = layer->name + "BackgroundColorLayer"; backgroundLayerArgs.flags = ISurfaceComposerClient::eFXSurfaceEffect; std::vector> newLayers; newLayers.emplace_back( std::make_unique(backgroundLayerArgs)); RequestedLayerState* backgroundLayer = newLayers.back().get(); backgroundLayer->bgColorLayer = true; backgroundLayer->handleAlive = false; backgroundLayer->parentId = layer->id; backgroundLayer->z = std::numeric_limits::min(); backgroundLayer->color = layer->bgColor; backgroundLayer->dataspace = layer->bgColorDataspace; layer->bgColorLayerId = backgroundLayer->id; addLayers({std::move(newLayers)}); } else if (layer->bgColorLayerId != UNASSIGNED_LAYER_ID && layer->bgColor.a == 0) { RequestedLayerState* bgColorLayer = getLayerFromId(layer->bgColorLayerId); layer->bgColorLayerId = UNASSIGNED_LAYER_ID; bgColorLayer->parentId = unlinkLayer(bgColorLayer->parentId, bgColorLayer->id); onHandlesDestroyed({{bgColorLayer->id, bgColorLayer->debugName}}); } else if (layer->bgColorLayerId != UNASSIGNED_LAYER_ID) { RequestedLayerState* bgColorLayer = getLayerFromId(layer->bgColorLayerId); bgColorLayer->color = layer->bgColor; bgColorLayer->dataspace = layer->bgColorDataspace; bgColorLayer->what |= layer_state_t::eColorChanged | layer_state_t::eDataspaceChanged | layer_state_t::eAlphaChanged; bgColorLayer->changes |= RequestedLayerState::Changes::Content; mChangedLayers.push_back(bgColorLayer); mGlobalChanges |= RequestedLayerState::Changes::Content; } } 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); layer->relativeParentId = linkLayer(layer->relativeParentId, layer->id); } if (oldTouchCropId != layer->touchCropId) { unlinkLayer(oldTouchCropId, layer->id); layer->touchCropId = linkLayer(layer->touchCropId, layer->id); } mGlobalChanges |= layer->changes; } } } void LayerLifecycleManager::commitChanges() { for (auto layer : mAddedLayers) { for (auto& listener : mListeners) { listener->onLayerAdded(*layer); } } mAddedLayers.clear(); for (auto& layer : mLayers) { layer->clearChanges(); } for (auto& destroyedLayer : mDestroyedLayers) { for (auto& listener : mListeners) { listener->onLayerDestroyed(*destroyedLayer); } } mDestroyedLayers.clear(); mChangedLayers.clear(); mGlobalChanges.clear(); } void LayerLifecycleManager::addLifecycleListener(std::shared_ptr listener) { mListeners.emplace_back(std::move(listener)); } void LayerLifecycleManager::removeLifecycleListener(std::shared_ptr listener) { swapErase(mListeners, listener); } const std::vector>& LayerLifecycleManager::getLayers() const { return mLayers; } const std::vector>& LayerLifecycleManager::getDestroyedLayers() const { return mDestroyedLayers; } const std::vector& LayerLifecycleManager::getChangedLayers() const { return mChangedLayers; } const ftl::Flags LayerLifecycleManager::getGlobalChanges() const { return mGlobalChanges; } const RequestedLayerState* LayerLifecycleManager::getLayerFromId(uint32_t id) const { if (id == UNASSIGNED_LAYER_ID) { return nullptr; } auto it = mIdToLayer.find(id); if (it == mIdToLayer.end()) { return nullptr; } return &it->second.owner; } RequestedLayerState* LayerLifecycleManager::getLayerFromId(uint32_t id) { if (id == UNASSIGNED_LAYER_ID) { return nullptr; } auto it = mIdToLayer.find(id); if (it == mIdToLayer.end()) { return nullptr; } return &it->second.owner; } std::vector* LayerLifecycleManager::getLinkedLayersFromId(uint32_t id) { if (id == UNASSIGNED_LAYER_ID) { return nullptr; } auto it = mIdToLayer.find(id); if (it == mIdToLayer.end()) { return nullptr; } return &it->second.references; } uint32_t LayerLifecycleManager::linkLayer(uint32_t layerId, uint32_t layerToLink) { if (layerId == UNASSIGNED_LAYER_ID) { return UNASSIGNED_LAYER_ID; } std::vector* linkedLayers = getLinkedLayersFromId(layerId); if (!linkedLayers) { ALOGV("Could not find layer id %d to link %d. Parent is probably destroyed", layerId, layerToLink); return UNASSIGNED_LAYER_ID; } linkedLayers->emplace_back(layerToLink); return layerId; } uint32_t LayerLifecycleManager::unlinkLayer(uint32_t layerId, uint32_t linkedLayer) { std::vector* linkedLayers = getLinkedLayersFromId(layerId); if (!linkedLayers) { return UNASSIGNED_LAYER_ID; } swapErase(*linkedLayers, linkedLayer); return UNASSIGNED_LAYER_ID; } std::vector LayerLifecycleManager::unlinkLayers(const std::vector& 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(), [&debugInfo = debugInfo](const uint32_t& reference) mutable { debugInfo += std::to_string(reference) + ","; }); return debugInfo; } void LayerLifecycleManager::fixRelativeZLoop(uint32_t relativeRootId) { auto it = mIdToLayer.find(relativeRootId); if (it == mIdToLayer.end()) { return; } RequestedLayerState& layer = it->second.owner; layer.relativeParentId = unlinkLayer(layer.relativeParentId, layer.id); layer.changes |= RequestedLayerState::Changes::Hierarchy | RequestedLayerState::Changes::RelativeParent; 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 mirroringLayerId : mDisplayMirroringLayers) { RequestedLayerState* mirrorLayer = getLayerFromId(mirroringLayerId); bool canBeMirrored = canMirrorRootLayer(*mirrorLayer, rootLayer); 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; } } } bool LayerLifecycleManager::isLayerSecure(uint32_t layerId) const { if (layerId == UNASSIGNED_LAYER_ID) { return false; } if (getLayerFromId(layerId)->flags & layer_state_t::eLayerSecure) { return true; } return isLayerSecure(getLayerFromId(layerId)->parentId); } } // namespace android::surfaceflinger::frontend