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 
21 #include <future>
22 
23 #include "utils/TimeUtils.h"
24 
25 namespace android {
26 namespace uirenderer {
27 
28 namespace renderthread {
29 
30 class HintSessionWrapper {
31 public:
32     friend class HintSessionWrapperTests;
33 
34     HintSessionWrapper(pid_t uiThreadId, pid_t renderThreadId);
35     ~HintSessionWrapper();
36 
37     void updateTargetWorkDuration(long targetDurationNanos);
38     void reportActualWorkDuration(long actualDurationNanos);
39     void sendLoadResetHint();
40     void sendLoadIncreaseHint();
41     bool init();
42     void destroy();
43 
44 private:
45     APerformanceHintSession* mHintSession = nullptr;
46     std::future<APerformanceHintSession*> mHintSessionFuture;
47 
48     int mResetsSinceLastReport = 0;
49     nsecs_t mLastFrameNotification = 0;
50     nsecs_t mLastTargetWorkDuration = 0;
51 
52     pid_t mUiThreadId;
53     pid_t mRenderThreadId;
54 
55     bool mSessionValid = true;
56 
57     static constexpr nsecs_t kResetHintTimeout = 100_ms;
58     static constexpr int64_t kSanityCheckLowerBound = 100_us;
59     static constexpr int64_t kSanityCheckUpperBound = 10_s;
60 
61     // Allows easier stub when testing
62     class HintSessionBinding {
63     public:
64         virtual ~HintSessionBinding() = default;
65         virtual void init();
66         APerformanceHintManager* (*getManager)();
67         APerformanceHintSession* (*createSession)(APerformanceHintManager* manager,
68                                                   const int32_t* tids, size_t tidCount,
69                                                   int64_t defaultTarget) = nullptr;
70         void (*closeSession)(APerformanceHintSession* session) = nullptr;
71         void (*updateTargetWorkDuration)(APerformanceHintSession* session,
72                                          int64_t targetDuration) = nullptr;
73         void (*reportActualWorkDuration)(APerformanceHintSession* session,
74                                          int64_t actualDuration) = nullptr;
75         void (*sendHint)(APerformanceHintSession* session, int32_t hintId) = nullptr;
76 
77     private:
78         bool mInitialized = false;
79     };
80 
81     std::shared_ptr<HintSessionBinding> mBinding;
82 };
83 
84 } /* namespace renderthread */
85 } /* namespace uirenderer */
86 } /* namespace android */
87