1*0a9764feSAndroid Build Coastguard Worker /*
2*0a9764feSAndroid Build Coastguard Worker * Copyright (C) 2024 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 "DrmHwcThree.h"
20*0a9764feSAndroid Build Coastguard Worker
21*0a9764feSAndroid Build Coastguard Worker #include <cinttypes>
22*0a9764feSAndroid Build Coastguard Worker
23*0a9764feSAndroid Build Coastguard Worker #include "Utils.h"
24*0a9764feSAndroid Build Coastguard Worker #include "aidl/android/hardware/graphics/common/Dataspace.h"
25*0a9764feSAndroid Build Coastguard Worker #if __ANDROID_API__ >= 35
26*0a9764feSAndroid Build Coastguard Worker #include "aidl/android/hardware/graphics/common/DisplayHotplugEvent.h"
27*0a9764feSAndroid Build Coastguard Worker #endif
28*0a9764feSAndroid Build Coastguard Worker
29*0a9764feSAndroid Build Coastguard Worker namespace aidl::android::hardware::graphics::composer3::impl {
30*0a9764feSAndroid Build Coastguard Worker
31*0a9764feSAndroid Build Coastguard Worker using ::android::HwcDisplay;
32*0a9764feSAndroid Build Coastguard Worker
~DrmHwcThree()33*0a9764feSAndroid Build Coastguard Worker DrmHwcThree::~DrmHwcThree() {
34*0a9764feSAndroid Build Coastguard Worker /* Display deinit routine is handled by resource manager */
35*0a9764feSAndroid Build Coastguard Worker GetResMan().DeInit();
36*0a9764feSAndroid Build Coastguard Worker }
37*0a9764feSAndroid Build Coastguard Worker
Init(std::shared_ptr<IComposerCallback> callback)38*0a9764feSAndroid Build Coastguard Worker void DrmHwcThree::Init(std::shared_ptr<IComposerCallback> callback) {
39*0a9764feSAndroid Build Coastguard Worker composer_callback_ = std::move(callback);
40*0a9764feSAndroid Build Coastguard Worker GetResMan().Init();
41*0a9764feSAndroid Build Coastguard Worker }
42*0a9764feSAndroid Build Coastguard Worker
SendVsyncPeriodTimingChangedEventToClient(uint64_t display_id,int64_t timestamp) const43*0a9764feSAndroid Build Coastguard Worker void DrmHwcThree::SendVsyncPeriodTimingChangedEventToClient(
44*0a9764feSAndroid Build Coastguard Worker uint64_t display_id, int64_t timestamp) const {
45*0a9764feSAndroid Build Coastguard Worker VsyncPeriodChangeTimeline timeline;
46*0a9764feSAndroid Build Coastguard Worker timeline.newVsyncAppliedTimeNanos = timestamp;
47*0a9764feSAndroid Build Coastguard Worker timeline.refreshRequired = false;
48*0a9764feSAndroid Build Coastguard Worker timeline.refreshTimeNanos = 0;
49*0a9764feSAndroid Build Coastguard Worker
50*0a9764feSAndroid Build Coastguard Worker composer_callback_->onVsyncPeriodTimingChanged(static_cast<int64_t>(
51*0a9764feSAndroid Build Coastguard Worker display_id),
52*0a9764feSAndroid Build Coastguard Worker timeline);
53*0a9764feSAndroid Build Coastguard Worker }
54*0a9764feSAndroid Build Coastguard Worker
SendRefreshEventToClient(uint64_t display_id)55*0a9764feSAndroid Build Coastguard Worker void DrmHwcThree::SendRefreshEventToClient(uint64_t display_id) {
56*0a9764feSAndroid Build Coastguard Worker composer_resources_->SetDisplayMustValidateState(display_id, true);
57*0a9764feSAndroid Build Coastguard Worker composer_callback_->onRefresh(static_cast<int64_t>(display_id));
58*0a9764feSAndroid Build Coastguard Worker }
59*0a9764feSAndroid Build Coastguard Worker
SendVsyncEventToClient(uint64_t display_id,int64_t timestamp,uint32_t vsync_period) const60*0a9764feSAndroid Build Coastguard Worker void DrmHwcThree::SendVsyncEventToClient(uint64_t display_id, int64_t timestamp,
61*0a9764feSAndroid Build Coastguard Worker uint32_t vsync_period) const {
62*0a9764feSAndroid Build Coastguard Worker composer_callback_->onVsync(static_cast<int64_t>(display_id), timestamp,
63*0a9764feSAndroid Build Coastguard Worker static_cast<int32_t>(vsync_period));
64*0a9764feSAndroid Build Coastguard Worker }
65*0a9764feSAndroid Build Coastguard Worker
66*0a9764feSAndroid Build Coastguard Worker #if __ANDROID_API__ >= 35
67*0a9764feSAndroid Build Coastguard Worker
SendHotplugEventToClient(hwc2_display_t display_id,DrmHwc::DisplayStatus display_status)68*0a9764feSAndroid Build Coastguard Worker void DrmHwcThree::SendHotplugEventToClient(
69*0a9764feSAndroid Build Coastguard Worker hwc2_display_t display_id, DrmHwc::DisplayStatus display_status) {
70*0a9764feSAndroid Build Coastguard Worker common::DisplayHotplugEvent event = common::DisplayHotplugEvent::DISCONNECTED;
71*0a9764feSAndroid Build Coastguard Worker switch (display_status) {
72*0a9764feSAndroid Build Coastguard Worker case DrmHwc::kDisconnected:
73*0a9764feSAndroid Build Coastguard Worker event = common::DisplayHotplugEvent::DISCONNECTED;
74*0a9764feSAndroid Build Coastguard Worker HandleDisplayHotplugEvent(static_cast<uint64_t>(display_id), false);
75*0a9764feSAndroid Build Coastguard Worker break;
76*0a9764feSAndroid Build Coastguard Worker case DrmHwc::kConnected:
77*0a9764feSAndroid Build Coastguard Worker event = common::DisplayHotplugEvent::CONNECTED;
78*0a9764feSAndroid Build Coastguard Worker HandleDisplayHotplugEvent(static_cast<uint64_t>(display_id), true);
79*0a9764feSAndroid Build Coastguard Worker break;
80*0a9764feSAndroid Build Coastguard Worker case DrmHwc::kLinkTrainingFailed:
81*0a9764feSAndroid Build Coastguard Worker event = common::DisplayHotplugEvent::ERROR_INCOMPATIBLE_CABLE;
82*0a9764feSAndroid Build Coastguard Worker break;
83*0a9764feSAndroid Build Coastguard Worker }
84*0a9764feSAndroid Build Coastguard Worker composer_callback_->onHotplugEvent(static_cast<int64_t>(display_id), event);
85*0a9764feSAndroid Build Coastguard Worker }
86*0a9764feSAndroid Build Coastguard Worker
87*0a9764feSAndroid Build Coastguard Worker #else
88*0a9764feSAndroid Build Coastguard Worker
SendHotplugEventToClient(hwc2_display_t display_id,DrmHwc::DisplayStatus display_status)89*0a9764feSAndroid Build Coastguard Worker void DrmHwcThree::SendHotplugEventToClient(
90*0a9764feSAndroid Build Coastguard Worker hwc2_display_t display_id, DrmHwc::DisplayStatus display_status) {
91*0a9764feSAndroid Build Coastguard Worker bool connected = display_status != DrmHwc::kDisconnected;
92*0a9764feSAndroid Build Coastguard Worker HandleDisplayHotplugEvent(static_cast<uint64_t>(display_id), connected);
93*0a9764feSAndroid Build Coastguard Worker composer_callback_->onHotplug(static_cast<int64_t>(display_id), connected);
94*0a9764feSAndroid Build Coastguard Worker }
95*0a9764feSAndroid Build Coastguard Worker
96*0a9764feSAndroid Build Coastguard Worker #endif
97*0a9764feSAndroid Build Coastguard Worker
CleanDisplayResources(uint64_t display_id)98*0a9764feSAndroid Build Coastguard Worker void DrmHwcThree::CleanDisplayResources(uint64_t display_id) {
99*0a9764feSAndroid Build Coastguard Worker DEBUG_FUNC();
100*0a9764feSAndroid Build Coastguard Worker HwcDisplay* display = GetDisplay(display_id);
101*0a9764feSAndroid Build Coastguard Worker if (display == nullptr) {
102*0a9764feSAndroid Build Coastguard Worker return;
103*0a9764feSAndroid Build Coastguard Worker }
104*0a9764feSAndroid Build Coastguard Worker
105*0a9764feSAndroid Build Coastguard Worker display->SetPowerMode(static_cast<int32_t>(PowerMode::OFF));
106*0a9764feSAndroid Build Coastguard Worker
107*0a9764feSAndroid Build Coastguard Worker size_t cache_size = 0;
108*0a9764feSAndroid Build Coastguard Worker auto err = composer_resources_->GetDisplayClientTargetCacheSize(display_id,
109*0a9764feSAndroid Build Coastguard Worker &cache_size);
110*0a9764feSAndroid Build Coastguard Worker if (err != hwc3::Error::kNone) {
111*0a9764feSAndroid Build Coastguard Worker ALOGE("%s: Could not clear target buffer cache for display: %" PRIu64,
112*0a9764feSAndroid Build Coastguard Worker __func__, display_id);
113*0a9764feSAndroid Build Coastguard Worker return;
114*0a9764feSAndroid Build Coastguard Worker }
115*0a9764feSAndroid Build Coastguard Worker
116*0a9764feSAndroid Build Coastguard Worker for (size_t slot = 0; slot < cache_size; slot++) {
117*0a9764feSAndroid Build Coastguard Worker buffer_handle_t buffer_handle = nullptr;
118*0a9764feSAndroid Build Coastguard Worker auto buf_releaser = ComposerResources::CreateResourceReleaser(true);
119*0a9764feSAndroid Build Coastguard Worker
120*0a9764feSAndroid Build Coastguard Worker Buffer buf{};
121*0a9764feSAndroid Build Coastguard Worker buf.slot = static_cast<int32_t>(slot);
122*0a9764feSAndroid Build Coastguard Worker err = composer_resources_->GetDisplayClientTarget(display_id, buf,
123*0a9764feSAndroid Build Coastguard Worker &buffer_handle,
124*0a9764feSAndroid Build Coastguard Worker buf_releaser.get());
125*0a9764feSAndroid Build Coastguard Worker if (err != hwc3::Error::kNone) {
126*0a9764feSAndroid Build Coastguard Worker continue;
127*0a9764feSAndroid Build Coastguard Worker }
128*0a9764feSAndroid Build Coastguard Worker
129*0a9764feSAndroid Build Coastguard Worker err = Hwc2toHwc3Error(
130*0a9764feSAndroid Build Coastguard Worker display->SetClientTarget(buffer_handle, -1,
131*0a9764feSAndroid Build Coastguard Worker static_cast<int32_t>(
132*0a9764feSAndroid Build Coastguard Worker common::Dataspace::UNKNOWN),
133*0a9764feSAndroid Build Coastguard Worker {}));
134*0a9764feSAndroid Build Coastguard Worker if (err != hwc3::Error::kNone) {
135*0a9764feSAndroid Build Coastguard Worker ALOGE(
136*0a9764feSAndroid Build Coastguard Worker "%s: Could not clear slot %zu of the target buffer cache for "
137*0a9764feSAndroid Build Coastguard Worker "display %" PRIu64,
138*0a9764feSAndroid Build Coastguard Worker __func__, slot, display_id);
139*0a9764feSAndroid Build Coastguard Worker }
140*0a9764feSAndroid Build Coastguard Worker }
141*0a9764feSAndroid Build Coastguard Worker }
142*0a9764feSAndroid Build Coastguard Worker
HandleDisplayHotplugEvent(uint64_t display_id,bool connected)143*0a9764feSAndroid Build Coastguard Worker void DrmHwcThree::HandleDisplayHotplugEvent(uint64_t display_id,
144*0a9764feSAndroid Build Coastguard Worker bool connected) {
145*0a9764feSAndroid Build Coastguard Worker DEBUG_FUNC();
146*0a9764feSAndroid Build Coastguard Worker if (!connected) {
147*0a9764feSAndroid Build Coastguard Worker composer_resources_->RemoveDisplay(display_id);
148*0a9764feSAndroid Build Coastguard Worker Displays().erase(display_id);
149*0a9764feSAndroid Build Coastguard Worker return;
150*0a9764feSAndroid Build Coastguard Worker }
151*0a9764feSAndroid Build Coastguard Worker
152*0a9764feSAndroid Build Coastguard Worker if (composer_resources_->HasDisplay(display_id)) {
153*0a9764feSAndroid Build Coastguard Worker /* Cleanup existing display resources */
154*0a9764feSAndroid Build Coastguard Worker CleanDisplayResources(display_id);
155*0a9764feSAndroid Build Coastguard Worker composer_resources_->RemoveDisplay(display_id);
156*0a9764feSAndroid Build Coastguard Worker Displays().erase(display_id);
157*0a9764feSAndroid Build Coastguard Worker }
158*0a9764feSAndroid Build Coastguard Worker composer_resources_->AddPhysicalDisplay(display_id);
159*0a9764feSAndroid Build Coastguard Worker }
160*0a9764feSAndroid Build Coastguard Worker
161*0a9764feSAndroid Build Coastguard Worker } // namespace aidl::android::hardware::graphics::composer3::impl
162