xref: /aosp_15_r20/external/drm_hwcomposer/hwc2_device/DrmHwcTwo.cpp (revision 0a9764fe0a15e71ebbeb85e87e10990c23aab47f)
1*0a9764feSAndroid Build Coastguard Worker /*
2*0a9764feSAndroid Build Coastguard Worker  * Copyright (C) 2016 The Android Open Source Project
3*0a9764feSAndroid Build Coastguard Worker  *
4*0a9764feSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*0a9764feSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*0a9764feSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*0a9764feSAndroid Build Coastguard Worker  *
8*0a9764feSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*0a9764feSAndroid Build Coastguard Worker  *
10*0a9764feSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*0a9764feSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*0a9764feSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*0a9764feSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*0a9764feSAndroid Build Coastguard Worker  * limitations under the License.
15*0a9764feSAndroid Build Coastguard Worker  */
16*0a9764feSAndroid Build Coastguard Worker 
17*0a9764feSAndroid Build Coastguard Worker #define LOG_TAG "drmhwc"
18*0a9764feSAndroid Build Coastguard Worker 
19*0a9764feSAndroid Build Coastguard Worker #include "DrmHwcTwo.h"
20*0a9764feSAndroid Build Coastguard Worker 
21*0a9764feSAndroid Build Coastguard Worker #include <cinttypes>
22*0a9764feSAndroid Build Coastguard Worker 
23*0a9764feSAndroid Build Coastguard Worker #include "backend/Backend.h"
24*0a9764feSAndroid Build Coastguard Worker #include "utils/log.h"
25*0a9764feSAndroid Build Coastguard Worker 
26*0a9764feSAndroid Build Coastguard Worker namespace android {
27*0a9764feSAndroid Build Coastguard Worker 
RegisterCallback(int32_t descriptor,hwc2_callback_data_t data,hwc2_function_pointer_t function)28*0a9764feSAndroid Build Coastguard Worker HWC2::Error DrmHwcTwo::RegisterCallback(int32_t descriptor,
29*0a9764feSAndroid Build Coastguard Worker                                         hwc2_callback_data_t data,
30*0a9764feSAndroid Build Coastguard Worker                                         hwc2_function_pointer_t function) {
31*0a9764feSAndroid Build Coastguard Worker   switch (static_cast<HWC2::Callback>(descriptor)) {
32*0a9764feSAndroid Build Coastguard Worker     case HWC2::Callback::Hotplug: {
33*0a9764feSAndroid Build Coastguard Worker       hotplug_callback_ = std::make_pair(HWC2_PFN_HOTPLUG(function), data);
34*0a9764feSAndroid Build Coastguard Worker       if (function != nullptr) {
35*0a9764feSAndroid Build Coastguard Worker         GetResMan().Init();
36*0a9764feSAndroid Build Coastguard Worker       } else {
37*0a9764feSAndroid Build Coastguard Worker         GetResMan().DeInit();
38*0a9764feSAndroid Build Coastguard Worker         /* Headless display may still be here. Remove it! */
39*0a9764feSAndroid Build Coastguard Worker         if (Displays().count(kPrimaryDisplay) != 0) {
40*0a9764feSAndroid Build Coastguard Worker           Displays()[kPrimaryDisplay]->Deinit();
41*0a9764feSAndroid Build Coastguard Worker           Displays().erase(kPrimaryDisplay);
42*0a9764feSAndroid Build Coastguard Worker         }
43*0a9764feSAndroid Build Coastguard Worker       }
44*0a9764feSAndroid Build Coastguard Worker       break;
45*0a9764feSAndroid Build Coastguard Worker     }
46*0a9764feSAndroid Build Coastguard Worker     case HWC2::Callback::Refresh: {
47*0a9764feSAndroid Build Coastguard Worker       refresh_callback_ = std::make_pair(HWC2_PFN_REFRESH(function), data);
48*0a9764feSAndroid Build Coastguard Worker       break;
49*0a9764feSAndroid Build Coastguard Worker     }
50*0a9764feSAndroid Build Coastguard Worker     case HWC2::Callback::Vsync: {
51*0a9764feSAndroid Build Coastguard Worker       vsync_callback_ = std::make_pair(HWC2_PFN_VSYNC(function), data);
52*0a9764feSAndroid Build Coastguard Worker       break;
53*0a9764feSAndroid Build Coastguard Worker     }
54*0a9764feSAndroid Build Coastguard Worker #if __ANDROID_API__ > 29
55*0a9764feSAndroid Build Coastguard Worker     case HWC2::Callback::Vsync_2_4: {
56*0a9764feSAndroid Build Coastguard Worker       vsync_2_4_callback_ = std::make_pair(HWC2_PFN_VSYNC_2_4(function), data);
57*0a9764feSAndroid Build Coastguard Worker       break;
58*0a9764feSAndroid Build Coastguard Worker     }
59*0a9764feSAndroid Build Coastguard Worker     case HWC2::Callback::VsyncPeriodTimingChanged: {
60*0a9764feSAndroid Build Coastguard Worker       period_timing_changed_callback_ = std::
61*0a9764feSAndroid Build Coastguard Worker           make_pair(HWC2_PFN_VSYNC_PERIOD_TIMING_CHANGED(function), data);
62*0a9764feSAndroid Build Coastguard Worker       break;
63*0a9764feSAndroid Build Coastguard Worker     }
64*0a9764feSAndroid Build Coastguard Worker #endif
65*0a9764feSAndroid Build Coastguard Worker     default:
66*0a9764feSAndroid Build Coastguard Worker       break;
67*0a9764feSAndroid Build Coastguard Worker   }
68*0a9764feSAndroid Build Coastguard Worker   return HWC2::Error::None;
69*0a9764feSAndroid Build Coastguard Worker }
70*0a9764feSAndroid Build Coastguard Worker 
SendHotplugEventToClient(hwc2_display_t displayid,DisplayStatus display_status)71*0a9764feSAndroid Build Coastguard Worker void DrmHwcTwo::SendHotplugEventToClient(hwc2_display_t displayid,
72*0a9764feSAndroid Build Coastguard Worker                                          DisplayStatus display_status) {
73*0a9764feSAndroid Build Coastguard Worker   auto hc = hotplug_callback_;
74*0a9764feSAndroid Build Coastguard Worker 
75*0a9764feSAndroid Build Coastguard Worker   if (hc.first != nullptr && hc.second != nullptr) {
76*0a9764feSAndroid Build Coastguard Worker     /* For some reason HWC Service will call HWC2 API in hotplug callback
77*0a9764feSAndroid Build Coastguard Worker      * handler. This is the reason we're using recursive mutex.
78*0a9764feSAndroid Build Coastguard Worker      */
79*0a9764feSAndroid Build Coastguard Worker     hc.first(hc.second, displayid,
80*0a9764feSAndroid Build Coastguard Worker              display_status ? HWC2_CONNECTION_CONNECTED
81*0a9764feSAndroid Build Coastguard Worker                             : HWC2_CONNECTION_DISCONNECTED);
82*0a9764feSAndroid Build Coastguard Worker   }
83*0a9764feSAndroid Build Coastguard Worker }
84*0a9764feSAndroid Build Coastguard Worker 
SendVsyncEventToClient(hwc2_display_t displayid,int64_t timestamp,uint32_t vsync_period) const85*0a9764feSAndroid Build Coastguard Worker void DrmHwcTwo::SendVsyncEventToClient(
86*0a9764feSAndroid Build Coastguard Worker     hwc2_display_t displayid, int64_t timestamp,
87*0a9764feSAndroid Build Coastguard Worker     [[maybe_unused]] uint32_t vsync_period) const {
88*0a9764feSAndroid Build Coastguard Worker   /* vsync callback */
89*0a9764feSAndroid Build Coastguard Worker #if __ANDROID_API__ > 29
90*0a9764feSAndroid Build Coastguard Worker   if (vsync_2_4_callback_.first != nullptr &&
91*0a9764feSAndroid Build Coastguard Worker       vsync_2_4_callback_.second != nullptr) {
92*0a9764feSAndroid Build Coastguard Worker     vsync_2_4_callback_.first(vsync_2_4_callback_.second, displayid, timestamp,
93*0a9764feSAndroid Build Coastguard Worker                               vsync_period);
94*0a9764feSAndroid Build Coastguard Worker   } else
95*0a9764feSAndroid Build Coastguard Worker #endif
96*0a9764feSAndroid Build Coastguard Worker       if (vsync_callback_.first != nullptr &&
97*0a9764feSAndroid Build Coastguard Worker           vsync_callback_.second != nullptr) {
98*0a9764feSAndroid Build Coastguard Worker     vsync_callback_.first(vsync_callback_.second, displayid, timestamp);
99*0a9764feSAndroid Build Coastguard Worker   }
100*0a9764feSAndroid Build Coastguard Worker }
101*0a9764feSAndroid Build Coastguard Worker 
SendVsyncPeriodTimingChangedEventToClient(hwc2_display_t displayid,int64_t timestamp) const102*0a9764feSAndroid Build Coastguard Worker void DrmHwcTwo::SendVsyncPeriodTimingChangedEventToClient(
103*0a9764feSAndroid Build Coastguard Worker     [[maybe_unused]] hwc2_display_t displayid,
104*0a9764feSAndroid Build Coastguard Worker     [[maybe_unused]] int64_t timestamp) const {
105*0a9764feSAndroid Build Coastguard Worker #if __ANDROID_API__ > 29
106*0a9764feSAndroid Build Coastguard Worker   hwc_vsync_period_change_timeline_t timeline = {
107*0a9764feSAndroid Build Coastguard Worker       .newVsyncAppliedTimeNanos = timestamp,
108*0a9764feSAndroid Build Coastguard Worker       .refreshRequired = false,
109*0a9764feSAndroid Build Coastguard Worker       .refreshTimeNanos = 0,
110*0a9764feSAndroid Build Coastguard Worker   };
111*0a9764feSAndroid Build Coastguard Worker   if (period_timing_changed_callback_.first != nullptr &&
112*0a9764feSAndroid Build Coastguard Worker       period_timing_changed_callback_.second != nullptr) {
113*0a9764feSAndroid Build Coastguard Worker     period_timing_changed_callback_
114*0a9764feSAndroid Build Coastguard Worker         .first(period_timing_changed_callback_.second, displayid, &timeline);
115*0a9764feSAndroid Build Coastguard Worker   }
116*0a9764feSAndroid Build Coastguard Worker #endif
117*0a9764feSAndroid Build Coastguard Worker }
118*0a9764feSAndroid Build Coastguard Worker 
SendRefreshEventToClient(hwc2_display_t displayid)119*0a9764feSAndroid Build Coastguard Worker void DrmHwcTwo::SendRefreshEventToClient(hwc2_display_t displayid) {
120*0a9764feSAndroid Build Coastguard Worker   if (refresh_callback_.first != nullptr &&
121*0a9764feSAndroid Build Coastguard Worker       refresh_callback_.second != nullptr) {
122*0a9764feSAndroid Build Coastguard Worker     refresh_callback_.first(refresh_callback_.second, displayid);
123*0a9764feSAndroid Build Coastguard Worker   }
124*0a9764feSAndroid Build Coastguard Worker }
125*0a9764feSAndroid Build Coastguard Worker 
126*0a9764feSAndroid Build Coastguard Worker }  // namespace android
127