File: LayerSnapshotBuilder.h

package info (click to toggle)
android-platform-tools 35.0.2-1~exp6
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 211,716 kB
  • sloc: cpp: 995,749; java: 290,495; ansic: 145,647; xml: 58,531; python: 39,608; sh: 14,500; javascript: 5,198; asm: 4,866; makefile: 3,115; yacc: 769; awk: 368; ruby: 183; sql: 140; perl: 88; lex: 67
file content (140 lines) | stat: -rw-r--r-- 6,413 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
 * 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 "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 {
private:
    static LayerSnapshot getRootSnapshot();

public:
    enum class ForceUpdateFlags {
        NONE,
        ALL,
        HIERARCHY,
    };
    struct Args {
        LayerHierarchy root;
        const LayerLifecycleManager& layerLifecycleManager;
        ForceUpdateFlags forceUpdate = ForceUpdateFlags::NONE;
        bool includeMetadata = false;
        const DisplayInfos& displays;
        // Set to true if there were display changes since last update.
        bool displayChanges = false;
        const ShadowSettings& globalShadowSettings;
        bool supportsBlur = true;
        bool forceFullDamage = false;
        std::optional<FloatRect> parentCrop = std::nullopt;
        std::unordered_set<uint32_t> excludeLayerIds;
        const std::unordered_map<std::string, bool>& supportedLayerGenericMetadata;
        const std::unordered_map<std::string, uint32_t>& genericLayerMetadataKeyMap;
        bool skipRoundCornersWhenProtected = false;
        LayerSnapshot rootSnapshot = getRootSnapshot();
    };
    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;
    LayerSnapshot* getSnapshot(const LayerHierarchy::TraversalPath& id) const;

    typedef std::function<void(const LayerSnapshot& snapshot)> ConstVisitor;

    // Visit each visible snapshot in z-order
    void forEachVisibleSnapshot(const ConstVisitor& visitor) const;

    // Visit each visible snapshot in z-order
    void forEachVisibleSnapshot(const ConstVisitor& visitor, const LayerHierarchy& root) 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;

    // 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, int depth);
    void updateSnapshot(LayerSnapshot&, const Args&, const RequestedLayerState&,
                        const LayerSnapshot& parentSnapshot, const LayerHierarchy::TraversalPath&);
    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, const Args& args);
    void updateLayerBounds(LayerSnapshot& snapshot, const RequestedLayerState& layerState,
                           const LayerSnapshot& parentSnapshot, uint32_t displayRotationFlags);
    static void updateShadows(LayerSnapshot& snapshot, const RequestedLayerState& requested,
                              const ShadowSettings& globalShadowSettings);
    void updateInput(LayerSnapshot& snapshot, const RequestedLayerState& requested,
                     const LayerSnapshot& parentSnapshot, const LayerHierarchy::TraversalPath& path,
                     const Args& args);
    // Return true if there are unreachable snapshots
    bool sortSnapshotsByZ(const Args& args);
    LayerSnapshot* createSnapshot(const LayerHierarchy::TraversalPath& id,
                                  const RequestedLayerState& layer,
                                  const LayerSnapshot& parentSnapshot);
    void updateFrameRateFromChildSnapshot(LayerSnapshot& snapshot,
                                          const LayerSnapshot& childSnapshot, const Args& args);
    void updateTouchableRegionCrop(const Args& args);

    std::unordered_map<LayerHierarchy::TraversalPath, LayerSnapshot*,
                       LayerHierarchy::TraversalPathHash>
            mPathToSnapshot;
    std::multimap<uint32_t, LayerSnapshot*> mIdToSnapshots;

    // Track snapshots that needs touchable region crop from other snapshots
    std::unordered_set<LayerHierarchy::TraversalPath, LayerHierarchy::TraversalPathHash>
            mNeedsTouchableRegionCrop;
    std::vector<std::unique_ptr<LayerSnapshot>> mSnapshots;
    bool mResortSnapshots = false;
    int mNumInterestingSnapshots = 0;
};

} // namespace android::surfaceflinger::frontend