• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 
19 #include <android/performance_hint.h>
20 #include <private/performance_hint_private.h>
21 
22 #include <future>
23 #include <memory>
24 #include <optional>
25 #include <vector>
26 
27 #include "utils/TimeUtils.h"
28 
29 namespace android {
30 namespace uirenderer {
31 
32 namespace renderthread {
33 
34 class RenderThread;
35 
36 class HintSessionWrapper {
37 public:
38     friend class HintSessionWrapperTests;
39 
40     HintSessionWrapper(pid_t uiThreadId, pid_t renderThreadId);
41     ~HintSessionWrapper();
42 
43     void updateTargetWorkDuration(long targetDurationNanos);
44     void reportActualWorkDuration(long actualDurationNanos);
45     void sendLoadResetHint();
46     void sendLoadIncreaseHint();
47     bool init();
48     void destroy();
49     bool alive();
50     nsecs_t getLastUpdate();
51     void delayedDestroy(renderthread::RenderThread& rt, nsecs_t delay,
52                         std::shared_ptr<HintSessionWrapper> wrapperPtr);
53     // Must be called on Render thread. Otherwise can cause a race condition.
54     void setActiveFunctorThreads(std::vector<pid_t> threadIds);
55 
56 private:
57     APerformanceHintSession* mHintSession = nullptr;
58     // This needs to work concurrently for testing
59     std::optional<std::shared_future<APerformanceHintSession*>> mHintSessionFuture;
60     // This needs to work concurrently for testing
61     std::optional<std::shared_future<int>> mSetThreadsFuture;
62 
63     int mResetsSinceLastReport = 0;
64     nsecs_t mLastFrameNotification = 0;
65     nsecs_t mLastTargetWorkDuration = 0;
66 
67     pid_t mUiThreadId;
68     pid_t mRenderThreadId;
69     std::vector<pid_t> mPermanentSessionTids;
70     std::vector<pid_t> mActiveFunctorTids;
71 
72     bool mSessionValid = true;
73 
74     static constexpr nsecs_t kResetHintTimeout = 100_ms;
75     static constexpr int64_t kSanityCheckLowerBound = 100_us;
76     static constexpr int64_t kSanityCheckUpperBound = 10_s;
77     static constexpr int64_t kDefaultTargetDuration = 16666667;
78 
79     // Allows easier stub when testing
80     class HintSessionBinding {
81     public:
82         virtual ~HintSessionBinding() = default;
83         virtual void init();
84         APerformanceHintManager* (*getManager)();
85         APerformanceHintSession* (*createSessionInternal)(APerformanceHintManager* manager,
86                                                           const int32_t* tids, size_t tidCount,
87                                                           int64_t defaultTarget,
88                                                           SessionTag tag) = nullptr;
89         void (*closeSession)(APerformanceHintSession* session) = nullptr;
90         void (*updateTargetWorkDuration)(APerformanceHintSession* session,
91                                          int64_t targetDuration) = nullptr;
92         void (*reportActualWorkDuration)(APerformanceHintSession* session,
93                                          int64_t actualDuration) = nullptr;
94         void (*sendHint)(APerformanceHintSession* session, int32_t hintId) = nullptr;
95         int (*setThreads)(APerformanceHintSession* session, const pid_t* tids,
96                           size_t size) = nullptr;
97 
98     private:
99         bool mInitialized = false;
100     };
101 
102     std::shared_ptr<HintSessionBinding> mBinding;
103 };
104 
105 } /* namespace renderthread */
106 } /* namespace uirenderer */
107 } /* namespace android */
108