Add DisplayHandle which is a typedef for int64_t. Use this type instead of the HWC2 hwc2_display_t type. Additionally, rename variable names to prefer `display_handle` over `display_id`, since "DisplayId" is overloaded and carries a different meaning in the Android framework. Change-Id: I2a8ecce3b2c19fcd5e945d6c645f83d6a7d27a42
132 lines
4.2 KiB
C++
132 lines
4.2 KiB
C++
/*
|
|
* Copyright (C) 2016 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#define LOG_TAG "drmhwc"
|
|
|
|
#include "DrmHwcTwo.h"
|
|
|
|
#include <cinttypes>
|
|
|
|
#include "backend/Backend.h"
|
|
#include "utils/log.h"
|
|
|
|
namespace android {
|
|
|
|
HWC2::Error DrmHwcTwo::RegisterCallback(int32_t descriptor,
|
|
hwc2_callback_data_t data,
|
|
hwc2_function_pointer_t function) {
|
|
switch (static_cast<HWC2::Callback>(descriptor)) {
|
|
case HWC2::Callback::Hotplug: {
|
|
hotplug_callback_ = std::make_pair(HWC2_PFN_HOTPLUG(function), data);
|
|
if (function != nullptr) {
|
|
GetResMan().Init();
|
|
} else {
|
|
GetResMan().DeInit();
|
|
/* Headless display may still be here. Remove it! */
|
|
if (Displays().count(kPrimaryDisplay) != 0) {
|
|
Displays()[kPrimaryDisplay]->Deinit();
|
|
Displays().erase(kPrimaryDisplay);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case HWC2::Callback::Refresh: {
|
|
refresh_callback_ = std::make_pair(HWC2_PFN_REFRESH(function), data);
|
|
break;
|
|
}
|
|
case HWC2::Callback::Vsync: {
|
|
vsync_callback_ = std::make_pair(HWC2_PFN_VSYNC(function), data);
|
|
break;
|
|
}
|
|
#if __ANDROID_API__ > 29
|
|
case HWC2::Callback::Vsync_2_4: {
|
|
vsync_2_4_callback_ = std::make_pair(HWC2_PFN_VSYNC_2_4(function), data);
|
|
break;
|
|
}
|
|
case HWC2::Callback::VsyncPeriodTimingChanged: {
|
|
period_timing_changed_callback_ = std::
|
|
make_pair(HWC2_PFN_VSYNC_PERIOD_TIMING_CHANGED(function), data);
|
|
break;
|
|
}
|
|
#endif
|
|
default:
|
|
break;
|
|
}
|
|
return HWC2::Error::None;
|
|
}
|
|
|
|
void DrmHwcTwo::SendHotplugEventToClient(DisplayHandle display_handle,
|
|
DisplayStatus display_status) {
|
|
auto hc = hotplug_callback_;
|
|
|
|
if (hc.first != nullptr && hc.second != nullptr) {
|
|
/* For some reason HWC Service will call HWC2 API in hotplug callback
|
|
* handler. This is the reason we're using recursive mutex.
|
|
*/
|
|
hc.first(hc.second, display_handle,
|
|
display_status ? HWC2_CONNECTION_CONNECTED
|
|
: HWC2_CONNECTION_DISCONNECTED);
|
|
}
|
|
}
|
|
|
|
void DrmHwcTwo::SendVsyncEventToClient(
|
|
DisplayHandle display_handle, int64_t timestamp,
|
|
[[maybe_unused]] uint32_t vsync_period) const {
|
|
/* vsync callback */
|
|
#if __ANDROID_API__ > 29
|
|
if (vsync_2_4_callback_.first != nullptr &&
|
|
vsync_2_4_callback_.second != nullptr) {
|
|
vsync_2_4_callback_.first(vsync_2_4_callback_.second, display_handle,
|
|
timestamp, vsync_period);
|
|
} else
|
|
#endif
|
|
if (vsync_callback_.first != nullptr &&
|
|
vsync_callback_.second != nullptr) {
|
|
vsync_callback_.first(vsync_callback_.second, display_handle, timestamp);
|
|
}
|
|
}
|
|
|
|
void DrmHwcTwo::SendVsyncPeriodTimingChangedEventToClient(
|
|
[[maybe_unused]] DisplayHandle display_handle,
|
|
[[maybe_unused]] int64_t timestamp) const {
|
|
#if __ANDROID_API__ > 29
|
|
hwc_vsync_period_change_timeline_t timeline = {
|
|
.newVsyncAppliedTimeNanos = timestamp,
|
|
.refreshRequired = false,
|
|
.refreshTimeNanos = 0,
|
|
};
|
|
if (period_timing_changed_callback_.first != nullptr &&
|
|
period_timing_changed_callback_.second != nullptr) {
|
|
period_timing_changed_callback_
|
|
.first(period_timing_changed_callback_.second, display_handle,
|
|
&timeline);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void DrmHwcTwo::SendRefreshEventToClient(DisplayHandle display_handle) {
|
|
if (refresh_callback_.first != nullptr &&
|
|
refresh_callback_.second != nullptr) {
|
|
refresh_callback_.first(refresh_callback_.second, display_handle);
|
|
}
|
|
}
|
|
|
|
const std::string& DrmHwcTwo::RefreshStateDump() {
|
|
last_state_dump_ = DumpState();
|
|
return last_state_dump_;
|
|
}
|
|
|
|
} // namespace android
|