blob: 2ac307c00ba4d85399343374409d3396284aab5a [file] [log] [blame]
Drew Davenportade69652024-07-16 15:54:33 -06001/*
2 * Copyright (C) 2024 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
Manasi Navare3f0c01a2024-10-04 18:01:55 +000017#define LOG_TAG "drmhwc"
18
Drew Davenportade69652024-07-16 15:54:33 -060019#include "DrmHwcThree.h"
20
21#include <cinttypes>
22
Drew Davenport5951b112024-08-05 09:44:27 -060023#include "Utils.h"
24#include "aidl/android/hardware/graphics/common/Dataspace.h"
Drew Davenport7231bbd2024-09-13 10:39:03 -060025#include "aidl/android/hardware/graphics/common/DisplayHotplugEvent.h"
Drew Davenport5951b112024-08-05 09:44:27 -060026
Drew Davenportade69652024-07-16 15:54:33 -060027namespace aidl::android::hardware::graphics::composer3::impl {
28
Drew Davenport5951b112024-08-05 09:44:27 -060029using ::android::HwcDisplay;
30
Drew Davenport5951b112024-08-05 09:44:27 -060031DrmHwcThree::~DrmHwcThree() {
Normunds Rieksts425a6962024-03-11 14:46:07 +000032 /* Display deinit routine is handled by resource manager */
33 GetResMan().DeInit();
Drew Davenport5951b112024-08-05 09:44:27 -060034}
35
Drew Davenportade69652024-07-16 15:54:33 -060036void DrmHwcThree::Init(std::shared_ptr<IComposerCallback> callback) {
37 composer_callback_ = std::move(callback);
38 GetResMan().Init();
39}
40
41void DrmHwcThree::SendVsyncPeriodTimingChangedEventToClient(
42 uint64_t display_id, int64_t timestamp) const {
43 VsyncPeriodChangeTimeline timeline;
44 timeline.newVsyncAppliedTimeNanos = timestamp;
45 timeline.refreshRequired = false;
46 timeline.refreshTimeNanos = 0;
47
48 composer_callback_->onVsyncPeriodTimingChanged(static_cast<int64_t>(
49 display_id),
50 timeline);
51}
52
53void DrmHwcThree::SendRefreshEventToClient(uint64_t display_id) {
Drew Davenport5951b112024-08-05 09:44:27 -060054 composer_resources_->SetDisplayMustValidateState(display_id, true);
Drew Davenportade69652024-07-16 15:54:33 -060055 composer_callback_->onRefresh(static_cast<int64_t>(display_id));
56}
57
58void DrmHwcThree::SendVsyncEventToClient(uint64_t display_id, int64_t timestamp,
59 uint32_t vsync_period) const {
60 composer_callback_->onVsync(static_cast<int64_t>(display_id), timestamp,
61 static_cast<int32_t>(vsync_period));
62}
63
Manasi Navare3f0c01a2024-10-04 18:01:55 +000064void DrmHwcThree::SendHotplugEventToClient(
65 hwc2_display_t display_id, DrmHwc::DisplayStatus display_status) {
66 common::DisplayHotplugEvent event = common::DisplayHotplugEvent::DISCONNECTED;
67 switch (display_status) {
68 case DrmHwc::kDisconnected:
69 event = common::DisplayHotplugEvent::DISCONNECTED;
70 HandleDisplayHotplugEvent(static_cast<uint64_t>(display_id), false);
71 break;
72 case DrmHwc::kConnected:
73 event = common::DisplayHotplugEvent::CONNECTED;
74 HandleDisplayHotplugEvent(static_cast<uint64_t>(display_id), true);
75 break;
76 case DrmHwc::kLinkTrainingFailed:
77 event = common::DisplayHotplugEvent::ERROR_INCOMPATIBLE_CABLE;
78 break;
79 }
Drew Davenport7231bbd2024-09-13 10:39:03 -060080 composer_callback_->onHotplugEvent(static_cast<int64_t>(display_id), event);
Drew Davenportade69652024-07-16 15:54:33 -060081}
82
Drew Davenport5951b112024-08-05 09:44:27 -060083void DrmHwcThree::CleanDisplayResources(uint64_t display_id) {
84 DEBUG_FUNC();
85 HwcDisplay* display = GetDisplay(display_id);
86 if (display == nullptr) {
87 return;
88 }
89
90 display->SetPowerMode(static_cast<int32_t>(PowerMode::OFF));
91
92 size_t cache_size = 0;
93 auto err = composer_resources_->GetDisplayClientTargetCacheSize(display_id,
94 &cache_size);
95 if (err != hwc3::Error::kNone) {
96 ALOGE("%s: Could not clear target buffer cache for display: %" PRIu64,
97 __func__, display_id);
98 return;
99 }
100
101 for (size_t slot = 0; slot < cache_size; slot++) {
102 buffer_handle_t buffer_handle = nullptr;
103 auto buf_releaser = ComposerResources::CreateResourceReleaser(true);
104
105 Buffer buf{};
106 buf.slot = static_cast<int32_t>(slot);
107 err = composer_resources_->GetDisplayClientTarget(display_id, buf,
108 &buffer_handle,
109 buf_releaser.get());
110 if (err != hwc3::Error::kNone) {
111 continue;
112 }
113
114 err = Hwc2toHwc3Error(
115 display->SetClientTarget(buffer_handle, -1,
116 static_cast<int32_t>(
117 common::Dataspace::UNKNOWN),
118 {}));
119 if (err != hwc3::Error::kNone) {
120 ALOGE(
121 "%s: Could not clear slot %zu of the target buffer cache for "
122 "display %" PRIu64,
123 __func__, slot, display_id);
124 }
125 }
126}
127
128void DrmHwcThree::HandleDisplayHotplugEvent(uint64_t display_id,
129 bool connected) {
130 DEBUG_FUNC();
131 if (!connected) {
132 composer_resources_->RemoveDisplay(display_id);
Drew Davenport0bf6c2b2024-08-05 11:54:52 -0600133 Displays().erase(display_id);
Drew Davenport5951b112024-08-05 09:44:27 -0600134 return;
135 }
136
137 if (composer_resources_->HasDisplay(display_id)) {
138 /* Cleanup existing display resources */
139 CleanDisplayResources(display_id);
140 composer_resources_->RemoveDisplay(display_id);
Drew Davenport0bf6c2b2024-08-05 11:54:52 -0600141 Displays().erase(display_id);
Drew Davenport5951b112024-08-05 09:44:27 -0600142 }
143 composer_resources_->AddPhysicalDisplay(display_id);
144}
145
Drew Davenportade69652024-07-16 15:54:33 -0600146} // namespace aidl::android::hardware::graphics::composer3::impl