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