1 /**
2 * Copyright (c) 2021, 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 #include "GraphicsComposerCallback.h"
18 #include <log/log_main.h>
19 #include <utils/Timers.h>
20 #include <cinttypes>
21
22 #pragma push_macro("LOG_TAG")
23 #undef LOG_TAG
24 #define LOG_TAG "GraphicsComposerCallback"
25
26 namespace aidl::android::hardware::graphics::composer3::vts {
27
setVsyncAllowed(bool allowed)28 void GraphicsComposerCallback::setVsyncAllowed(bool allowed) {
29 std::scoped_lock lock(mMutex);
30 mVsyncAllowed = allowed;
31 }
32
setRefreshRateChangedDebugDataEnabledCallbackAllowed(bool allowed)33 void GraphicsComposerCallback::setRefreshRateChangedDebugDataEnabledCallbackAllowed(bool allowed) {
34 std::scoped_lock lock(mMutex);
35 mRefreshRateChangedDebugDataEnabledCallbackAllowed = allowed;
36 }
37
getDisplays() const38 std::vector<int64_t> GraphicsComposerCallback::getDisplays() const {
39 std::scoped_lock lock(mMutex);
40 return mDisplays;
41 }
42
getInvalidHotplugCount() const43 int32_t GraphicsComposerCallback::getInvalidHotplugCount() const {
44 std::scoped_lock lock(mMutex);
45 return mInvalidHotplugCount;
46 }
47
getInvalidRefreshCount() const48 int32_t GraphicsComposerCallback::getInvalidRefreshCount() const {
49 std::scoped_lock lock(mMutex);
50 return mInvalidRefreshCount;
51 }
52
getInvalidVsyncCount() const53 int32_t GraphicsComposerCallback::getInvalidVsyncCount() const {
54 std::scoped_lock lock(mMutex);
55 return mInvalidVsyncCount;
56 }
57
getInvalidVsyncPeriodChangeCount() const58 int32_t GraphicsComposerCallback::getInvalidVsyncPeriodChangeCount() const {
59 std::scoped_lock lock(mMutex);
60 return mInvalidVsyncPeriodChangeCount;
61 }
62
getInvalidSeamlessPossibleCount() const63 int32_t GraphicsComposerCallback::getInvalidSeamlessPossibleCount() const {
64 std::scoped_lock lock(mMutex);
65 return mInvalidSeamlessPossibleCount;
66 }
67
getVsyncIdleCount() const68 int32_t GraphicsComposerCallback::getVsyncIdleCount() const {
69 std::scoped_lock lock(mMutex);
70 return mVsyncIdleCount;
71 }
72
getVsyncIdleTime() const73 int64_t GraphicsComposerCallback::getVsyncIdleTime() const {
74 std::scoped_lock lock(mMutex);
75 return mVsyncIdleTime;
76 }
77
78 std::optional<VsyncPeriodChangeTimeline>
takeLastVsyncPeriodChangeTimeline()79 GraphicsComposerCallback::takeLastVsyncPeriodChangeTimeline() {
80 std::scoped_lock lock(mMutex);
81
82 std::optional<VsyncPeriodChangeTimeline> ret;
83 ret.swap(mTimeline);
84
85 return ret;
86 }
87
88 std::vector<RefreshRateChangedDebugData>
takeListOfRefreshRateChangedDebugData()89 GraphicsComposerCallback::takeListOfRefreshRateChangedDebugData() {
90 std::scoped_lock lock(mMutex);
91
92 std::vector<RefreshRateChangedDebugData> ret;
93 ret.swap(mRefreshRateChangedDebugData);
94
95 return ret;
96 }
97
getInvalidRefreshRateDebugEnabledCallbackCount() const98 int32_t GraphicsComposerCallback::getInvalidRefreshRateDebugEnabledCallbackCount() const {
99 std::scoped_lock lock(mMutex);
100 return mInvalidRefreshRateDebugEnabledCallbackCount;
101 }
102
onHotplug(int64_t in_display,bool in_connected)103 ::ndk::ScopedAStatus GraphicsComposerCallback::onHotplug(int64_t in_display, bool in_connected) {
104 std::scoped_lock lock(mMutex);
105
106 const auto it = std::find(mDisplays.begin(), mDisplays.end(), in_display);
107 if (in_connected) {
108 if (it == mDisplays.end()) {
109 mDisplays.push_back(in_display);
110 } else {
111 mInvalidHotplugCount++;
112 }
113 } else {
114 if (it != mDisplays.end()) {
115 mDisplays.erase(it);
116 } else {
117 mInvalidHotplugCount++;
118 }
119 }
120 return ::ndk::ScopedAStatus::ok();
121 }
122
onRefresh(int64_t in_display)123 ::ndk::ScopedAStatus GraphicsComposerCallback::onRefresh(int64_t in_display) {
124 std::scoped_lock lock(mMutex);
125
126 const auto it = std::find(mDisplays.begin(), mDisplays.end(), in_display);
127 if (it == mDisplays.end()) {
128 mInvalidRefreshCount++;
129 }
130
131 return ::ndk::ScopedAStatus::ok();
132 }
133
onVsync(int64_t in_display,int64_t in_timestamp,int32_t in_vsyncPeriodNanos)134 ::ndk::ScopedAStatus GraphicsComposerCallback::onVsync(int64_t in_display, int64_t in_timestamp,
135 int32_t in_vsyncPeriodNanos) {
136 std::scoped_lock lock(mMutex);
137
138 const auto it = std::find(mDisplays.begin(), mDisplays.end(), in_display);
139 if (!mVsyncAllowed || it == mDisplays.end()) {
140 mInvalidVsyncCount++;
141 }
142
143 ALOGV("%ld, %d", static_cast<long>(in_timestamp), in_vsyncPeriodNanos);
144
145 return ::ndk::ScopedAStatus::ok();
146 }
147
onRefreshRateChangedDebug(const RefreshRateChangedDebugData & data)148 ::ndk::ScopedAStatus GraphicsComposerCallback::onRefreshRateChangedDebug(
149 const RefreshRateChangedDebugData& data) {
150 std::scoped_lock lock(mMutex);
151
152 const auto it = std::find(mDisplays.begin(), mDisplays.end(), data.display);
153 if (mRefreshRateChangedDebugDataEnabledCallbackAllowed && it != mDisplays.end()) {
154 mRefreshRateChangedDebugData.push_back(data);
155 } else {
156 mInvalidRefreshRateDebugEnabledCallbackCount++;
157 }
158 return ::ndk::ScopedAStatus::ok();
159 }
160
onVsyncPeriodTimingChanged(int64_t in_display,const::aidl::android::hardware::graphics::composer3::VsyncPeriodChangeTimeline & in_updatedTimeline)161 ::ndk::ScopedAStatus GraphicsComposerCallback::onVsyncPeriodTimingChanged(
162 int64_t in_display,
163 const ::aidl::android::hardware::graphics::composer3::VsyncPeriodChangeTimeline&
164 in_updatedTimeline) {
165 std::scoped_lock lock(mMutex);
166
167 const auto it = std::find(mDisplays.begin(), mDisplays.end(), in_display);
168 if (it == mDisplays.end()) {
169 mInvalidVsyncPeriodChangeCount++;
170 }
171 mTimeline = in_updatedTimeline;
172
173 return ::ndk::ScopedAStatus::ok();
174 }
175
onSeamlessPossible(int64_t in_display)176 ::ndk::ScopedAStatus GraphicsComposerCallback::onSeamlessPossible(int64_t in_display) {
177 std::scoped_lock lock(mMutex);
178
179 const auto it = std::find(mDisplays.begin(), mDisplays.end(), in_display);
180 if (it != mDisplays.end()) {
181 mInvalidSeamlessPossibleCount++;
182 }
183 return ::ndk::ScopedAStatus::ok();
184 }
185
onVsyncIdle(int64_t in_display)186 ::ndk::ScopedAStatus GraphicsComposerCallback::onVsyncIdle(int64_t in_display) {
187 std::scoped_lock lock(mMutex);
188
189 const auto it = std::find(mDisplays.begin(), mDisplays.end(), in_display);
190 if (it != mDisplays.end()) {
191 mVsyncIdleCount++;
192 mVsyncIdleTime = systemTime();
193 }
194 return ::ndk::ScopedAStatus::ok();
195 }
196
onHotplugEvent(int64_t in_display,common::DisplayHotplugEvent event)197 ::ndk::ScopedAStatus GraphicsComposerCallback::onHotplugEvent(int64_t in_display,
198 common::DisplayHotplugEvent event) {
199 switch (event) {
200 case common::DisplayHotplugEvent::CONNECTED:
201 return onHotplug(in_display, true);
202 case common::DisplayHotplugEvent::DISCONNECTED:
203 return onHotplug(in_display, false);
204 default:
205 ALOGE("%s(): display:%" PRIu64 ", event:%d", __func__, in_display,
206 static_cast<int32_t>(event));
207 return ::ndk::ScopedAStatus::ok();
208 }
209 }
210
211 } // namespace aidl::android::hardware::graphics::composer3::vts
212