blob: 33b250c79372085e24318ef73de876a3d2f2c359 [file] [log] [blame]
/*
* 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;
};
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();
private:
friend class LayerSnapshotTest;
LayerSnapshot* getSnapshot(uint32_t layerId) const;
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);
void updateSnapshotsInHierarchy(const Args&, const LayerHierarchy& hierarchy,
LayerHierarchy::TraversalPath& traversalPath,
const LayerSnapshot& parentSnapshot);
void updateSnapshot(LayerSnapshot& snapshot, const Args& args, const RequestedLayerState&,
const LayerSnapshot& parentSnapshot,
const LayerHierarchy::TraversalPath& path);
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);
static 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 frontend::DisplayInfo& displayInfo,
bool noValidDisplay, const LayerHierarchy::TraversalPath& path);
void sortSnapshotsByZ(const Args& args);
LayerSnapshot* getOrCreateSnapshot(const LayerHierarchy::TraversalPath& id,
const RequestedLayerState& layer);
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;
};
} // namespace android::surfaceflinger::frontend