| /* |
| * 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. |
| */ |
| |
| #pragma once |
| |
| #include "Display/DisplayMap.h" |
| #include "FrontEnd/DisplayInfo.h" |
| #include "FrontEnd/LayerLifecycleManager.h" |
| #include "LayerHierarchy.h" |
| #include "LayerSnapshot.h" |
| #include "RequestedLayerState.h" |
| |
| namespace android::surfaceflinger::frontend { |
| |
| // Walks through the layer hierarchy to build an ordered list |
| // of LayerSnapshots that can be passed on to CompositionEngine. |
| // This builder does a minimum amount of work to update |
| // an existing set of snapshots based on hierarchy changes |
| // and RequestedLayerState changes. |
| |
| // The builder also uses a fast path to update |
| // snapshots when there are only buffer updates. |
| class LayerSnapshotBuilder { |
| public: |
| struct Args { |
| const LayerHierarchy& root; |
| const LayerLifecycleManager& layerLifecycleManager; |
| bool forceUpdate = false; |
| bool includeMetadata = false; |
| const display::DisplayMap<ui::LayerStack, frontend::DisplayInfo>& displays; |
| // Set to true if there were display changes since last update. |
| bool displayChanges = false; |
| const renderengine::ShadowSettings& globalShadowSettings; |
| bool supportsBlur = true; |
| bool forceFullDamage = false; |
| }; |
| LayerSnapshotBuilder(); |
| |
| // Rebuild the snapshots from scratch. |
| LayerSnapshotBuilder(Args); |
| |
| // Update an existing set of snapshot using change flags in RequestedLayerState |
| // and LayerLifecycleManager. This needs to be called before |
| // LayerLifecycleManager.commitChanges is called as that function will clear all |
| // change flags. |
| void update(const Args&); |
| std::vector<std::unique_ptr<LayerSnapshot>>& getSnapshots(); |
| LayerSnapshot* getSnapshot(uint32_t layerId) const; |
| |
| typedef std::function<void(const LayerSnapshot& snapshot)> ConstVisitor; |
| |
| // Visit each visible snapshot in z-order |
| void forEachVisibleSnapshot(const ConstVisitor& visitor) const; |
| |
| typedef std::function<void(std::unique_ptr<LayerSnapshot>& snapshot)> Visitor; |
| // Visit each visible snapshot in z-order and move the snapshot if needed |
| void forEachVisibleSnapshot(const Visitor& visitor); |
| |
| // Visit each snapshot interesting to input reverse z-order |
| void forEachInputSnapshot(const ConstVisitor& visitor) const; |
| |
| private: |
| friend class LayerSnapshotTest; |
| LayerSnapshot* getSnapshot(const LayerHierarchy::TraversalPath& id) const; |
| static LayerSnapshot getRootSnapshot(); |
| |
| // return true if we were able to successfully update the snapshots via |
| // the fast path. |
| bool tryFastUpdate(const Args& args); |
| |
| void updateSnapshots(const Args& args); |
| |
| const LayerSnapshot& updateSnapshotsInHierarchy(const Args&, const LayerHierarchy& hierarchy, |
| LayerHierarchy::TraversalPath& traversalPath, |
| const LayerSnapshot& parentSnapshot); |
| void updateSnapshot(LayerSnapshot&, const Args&, const RequestedLayerState&, |
| const LayerSnapshot& parentSnapshot, const LayerHierarchy::TraversalPath&, |
| bool newSnapshot); |
| static void updateRelativeState(LayerSnapshot& snapshot, const LayerSnapshot& parentSnapshot, |
| bool parentIsRelative, const Args& args); |
| static void resetRelativeState(LayerSnapshot& snapshot); |
| static void updateRoundedCorner(LayerSnapshot& snapshot, const RequestedLayerState& layerState, |
| const LayerSnapshot& parentSnapshot); |
| void updateLayerBounds(LayerSnapshot& snapshot, const RequestedLayerState& layerState, |
| const LayerSnapshot& parentSnapshot, uint32_t displayRotationFlags); |
| static void updateShadows(LayerSnapshot& snapshot, const RequestedLayerState& requested, |
| const renderengine::ShadowSettings& globalShadowSettings); |
| void updateInput(LayerSnapshot& snapshot, const RequestedLayerState& requested, |
| const LayerSnapshot& parentSnapshot, const LayerHierarchy::TraversalPath& path, |
| const Args& args); |
| void sortSnapshotsByZ(const Args& args); |
| LayerSnapshot* createSnapshot(const LayerHierarchy::TraversalPath& id, |
| const RequestedLayerState& layer); |
| void updateChildState(LayerSnapshot& snapshot, const LayerSnapshot& childSnapshot, |
| const Args& args); |
| |
| struct TraversalPathHash { |
| std::size_t operator()(const LayerHierarchy::TraversalPath& key) const { |
| uint32_t hashCode = key.id * 31; |
| for (auto mirrorRoot : key.mirrorRootIds) { |
| hashCode += mirrorRoot * 31; |
| } |
| return std::hash<size_t>{}(hashCode); |
| } |
| }; |
| std::unordered_map<LayerHierarchy::TraversalPath, LayerSnapshot*, TraversalPathHash> |
| mIdToSnapshot; |
| std::vector<std::unique_ptr<LayerSnapshot>> mSnapshots; |
| LayerSnapshot mRootSnapshot; |
| bool mResortSnapshots = false; |
| int mNumInterestingSnapshots = 0; |
| }; |
| |
| } // namespace android::surfaceflinger::frontend |