blob: e3babbabef92cad1a0cda789218899019e4b6339 [file] [log] [blame]
Ana Krulec61f86db2018-11-19 14:16:35 +01001/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -070019#include <android-base/thread_annotations.h>
20#include <utils/RefBase.h>
Ana Krulec61f86db2018-11-19 14:16:35 +010021#include <utils/Timers.h>
22
Nathaniel Nifong1303d912021-10-06 09:41:24 -040023#include <map>
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -070024#include <memory>
25#include <mutex>
Dominik Laskowski983f2b52020-06-25 16:54:06 -070026#include <string>
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -070027#include <utility>
28#include <vector>
Ana Krulec434c22d2018-11-28 13:48:36 +010029
Rachel Lee2248f522023-01-27 16:45:23 -080030#include "EventThread.h"
31
Vishnu Nair80e8cfe2023-09-29 17:03:45 -070032#include "FrameRateCompatibility.h"
Dominik Laskowskid82e0f02022-10-26 15:23:04 -040033#include "RefreshRateSelector.h"
Ady Abraham8a82ba62020-01-17 12:43:17 -080034
Ana Krulec61f86db2018-11-19 14:16:35 +010035namespace android {
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -070036
37class Layer;
38
Ady Abraham09bd3922019-04-08 10:44:56 -070039namespace scheduler {
Ana Krulec61f86db2018-11-19 14:16:35 +010040
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -070041class LayerInfo;
Vishnu Nairef68d6d2023-02-28 06:18:27 +000042struct LayerProps;
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -070043
Ana Krulec61f86db2018-11-19 14:16:35 +010044class LayerHistory {
45public:
Andy Yu8c2703d2023-11-03 11:22:46 -070046 using FrameRateOverride = DisplayEventReceiver::Event::FrameRateOverride;
Dominik Laskowskid82e0f02022-10-26 15:23:04 -040047 using LayerVoteType = RefreshRateSelector::LayerVoteType;
Arthur Hungc70bee22023-06-02 01:35:52 +000048 static constexpr std::chrono::nanoseconds kMaxPeriodForHistory = 1s;
Ady Abraham8a82ba62020-01-17 12:43:17 -080049
Ady Abraham3efa3942021-06-24 19:01:25 -070050 LayerHistory();
Marin Shalamanov1bc43ee2020-11-20 16:56:52 +010051 ~LayerHistory();
Ana Krulec61f86db2018-11-19 14:16:35 +010052
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -070053 // Layers are unregistered when the weak reference expires.
Vishnu Nair5c61a012024-08-05 21:14:39 -070054 void registerLayer(Layer*, bool contentDetectionEnabled,
55 FrameRateCompatibility frameRateCompatibility);
Ady Abraham8a82ba62020-01-17 12:43:17 -080056
57 // Sets the display size. Client is responsible for synchronization.
Marin Shalamanov1bc43ee2020-11-20 16:56:52 +010058 void setDisplayArea(uint32_t displayArea) { mDisplayArea = displayArea; }
Ady Abraham09bd3922019-04-08 10:44:56 -070059
Marin Shalamanova7fe3042021-01-29 21:02:08 +010060 // Sets whether a mode change is pending to be applied
61 void setModeChangePending(bool pending) { mModeChangePending = pending; }
Ady Abraham32efd542020-05-19 17:49:26 -070062
Ady Abraham5def7332020-05-29 16:13:47 -070063 // Represents which layer activity is recorded
64 enum class LayerUpdateType {
65 Buffer, // a new buffer queued
66 AnimationTX, // a new transaction with eAnimation flag set
67 SetFrameRate, // setFrameRate API was called
68 };
69
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -070070 // Marks the layer as active, and records the given state to its history.
Vishnu Nairef68d6d2023-02-28 06:18:27 +000071 void record(int32_t id, const LayerProps& props, nsecs_t presentTime, nsecs_t now,
72 LayerUpdateType updateType);
Ady Abrahama315ce72019-04-24 14:35:20 -070073
Andy Labrada096227e2022-06-15 16:58:11 +000074 // Updates the default frame rate compatibility which takes effect when the app
75 // does not set a preference for refresh rate.
Vishnu Nair80e8cfe2023-09-29 17:03:45 -070076 void setDefaultFrameRateCompatibility(int32_t id, FrameRateCompatibility frameRateCompatibility,
77 bool contentDetectionEnabled);
Vishnu Nair41376b62023-11-08 05:08:58 -080078 void setLayerProperties(int32_t id, const LayerProps&);
Dominik Laskowskid82e0f02022-10-26 15:23:04 -040079 using Summary = std::vector<RefreshRateSelector::LayerRequirement>;
Ady Abraham09bd3922019-04-08 10:44:56 -070080
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -070081 // Rebuilds sets of active/inactive layers, and accumulates stats for active layers.
Dominik Laskowskid82e0f02022-10-26 15:23:04 -040082 Summary summarize(const RefreshRateSelector&, nsecs_t now);
Ady Abrahama9bf4ca2019-06-11 19:08:58 -070083
Marin Shalamanov1bc43ee2020-11-20 16:56:52 +010084 void clear();
Ady Abrahambdda8f02021-04-01 16:06:11 -070085
86 void deregisterLayer(Layer*);
Marin Shalamanov1bc43ee2020-11-20 16:56:52 +010087 std::string dump() const;
Ady Abraham8a82ba62020-01-17 12:43:17 -080088
Nathaniel Nifong1303d912021-10-06 09:41:24 -040089 // return the frames per second of the layer with the given sequence id.
90 float getLayerFramerate(nsecs_t now, int32_t id) const;
91
Tony Huang9ac5e6e2023-08-24 09:01:44 +000092 bool isSmallDirtyArea(uint32_t dirtyArea, float threshold) const;
Arthur Hungc70bee22023-06-02 01:35:52 +000093
Andy Yu8c2703d2023-11-03 11:22:46 -070094 // Updates the frame rate override set by game mode intervention
95 void updateGameModeFrameRateOverride(FrameRateOverride frameRateOverride) EXCLUDES(mLock);
96
97 // Updates the frame rate override set by game default frame rate
98 void updateGameDefaultFrameRateOverride(FrameRateOverride frameRateOverride) EXCLUDES(mLock);
99
100 std::pair<Fps, Fps> getGameFrameRateOverride(uid_t uid) const EXCLUDES(mLock);
101 std::pair<Fps, Fps> getGameFrameRateOverrideLocked(uid_t uid) const REQUIRES(mLock);
102
Ady Abraham8a82ba62020-01-17 12:43:17 -0800103private:
Dominik Laskowski068173d2021-08-11 17:22:59 -0700104 friend class LayerHistoryTest;
Vishnu Nair47b7bb42023-09-29 16:27:33 -0700105 friend class LayerHistoryIntegrationTest;
Dominik Laskowski068173d2021-08-11 17:22:59 -0700106 friend class TestableScheduler;
Ady Abraham8a82ba62020-01-17 12:43:17 -0800107
Ady Abrahambdda8f02021-04-01 16:06:11 -0700108 using LayerPair = std::pair<Layer*, std::unique_ptr<LayerInfo>>;
Nathaniel Nifong1303d912021-10-06 09:41:24 -0400109 // keyed by id as returned from Layer::getSequence()
110 using LayerInfos = std::unordered_map<int32_t, LayerPair>;
Ady Abraham8a82ba62020-01-17 12:43:17 -0800111
Andy Yu0dca4862024-02-26 15:01:05 -0800112 std::string dumpGameFrameRateOverridesLocked() const REQUIRES(mLock);
113
Nathaniel Nifong1303d912021-10-06 09:41:24 -0400114 // Iterates over layers maps moving all active layers to mActiveLayerInfos and all inactive
Rachel Lee45681982024-03-14 18:40:15 -0700115 // layers to mInactiveLayerInfos. Layer's active state is determined by multiple factors
116 // such as update activity, visibility, and frame rate vote.
Nathaniel Nifong1303d912021-10-06 09:41:24 -0400117 // worst case time complexity is O(2 * inactive + active)
Rachel Lee45681982024-03-14 18:40:15 -0700118 // now: the current time (system time) when calling the method
119 // isVrrDevice: true if the device has DisplayMode with VrrConfig specified.
120 void partitionLayers(nsecs_t now, bool isVrrDevice) REQUIRES(mLock);
Ady Abraham8a82ba62020-01-17 12:43:17 -0800121
Dominik Laskowski0c41ffa2021-12-24 16:45:12 -0800122 enum class LayerStatus {
Nathaniel Nifong1303d912021-10-06 09:41:24 -0400123 NotFound,
124 LayerInActiveMap,
125 LayerInInactiveMap,
Ady Abraham8a82ba62020-01-17 12:43:17 -0800126 };
127
Nathaniel Nifong1303d912021-10-06 09:41:24 -0400128 // looks up a layer by sequence id in both layerInfo maps.
129 // The first element indicates if and where the item was found
Dominik Laskowski0c41ffa2021-12-24 16:45:12 -0800130 std::pair<LayerStatus, LayerPair*> findLayer(int32_t id) REQUIRES(mLock);
131
132 std::pair<LayerStatus, const LayerPair*> findLayer(int32_t id) const REQUIRES(mLock) {
133 return const_cast<LayerHistory*>(this)->findLayer(id);
134 }
Ady Abraham8a82ba62020-01-17 12:43:17 -0800135
136 mutable std::mutex mLock;
137
Nathaniel Nifong1303d912021-10-06 09:41:24 -0400138 // Partitioned into two maps to facility two kinds of retrieval:
139 // 1. retrieval of a layer by id (attempt lookup in both maps)
140 // 2. retrieval of all active layers (iterate that map)
141 // The partitioning is allowed to become out of date but calling partitionLayers refreshes the
142 // validity of each map.
143 LayerInfos mActiveLayerInfos GUARDED_BY(mLock);
144 LayerInfos mInactiveLayerInfos GUARDED_BY(mLock);
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -0700145
Ady Abraham8a82ba62020-01-17 12:43:17 -0800146 uint32_t mDisplayArea = 0;
147
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -0700148 // Whether to emit systrace output and debug logs.
149 const bool mTraceEnabled;
Ana Krulecc84d09b2019-11-02 23:10:29 +0100150
151 // Whether to use priority sent from WindowManager to determine the relevancy of the layer.
152 const bool mUseFrameRatePriority;
Ady Abraham32efd542020-05-19 17:49:26 -0700153
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100154 // Whether a mode change is in progress or not
155 std::atomic<bool> mModeChangePending = false;
Andy Yu8c2703d2023-11-03 11:22:46 -0700156
157 // A list to look up the game frame rate overrides
158 // Each entry includes:
159 // 1. the uid of the app
160 // 2. a pair of game mode intervention frame frame and game default frame rate override
161 // set to 0.0 if there is no such override
162 std::map<uid_t, std::pair<Fps, Fps>> mGameFrameRateOverride GUARDED_BY(mLock);
Ana Krulec61f86db2018-11-19 14:16:35 +0100163};
164
Ady Abraham09bd3922019-04-08 10:44:56 -0700165} // namespace scheduler
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -0700166} // namespace android