blob: d7588658c23315013686ad0359e905117c5be015 [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
17#include "DrmHwcThree.h"
18
19#include <cinttypes>
20
Drew Davenport5951b112024-08-05 09:44:27 -060021#include "Utils.h"
22#include "aidl/android/hardware/graphics/common/Dataspace.h"
Drew Davenport7231bbd2024-09-13 10:39:03 -060023#include "aidl/android/hardware/graphics/common/DisplayHotplugEvent.h"
Drew Davenport5951b112024-08-05 09:44:27 -060024
Drew Davenportade69652024-07-16 15:54:33 -060025namespace aidl::android::hardware::graphics::composer3::impl {
26
Drew Davenport5951b112024-08-05 09:44:27 -060027using ::android::HwcDisplay;
28
Drew Davenport5951b112024-08-05 09:44:27 -060029DrmHwcThree::~DrmHwcThree() {
Normunds Rieksts425a6962024-03-11 14:46:07 +000030 /* Display deinit routine is handled by resource manager */
31 GetResMan().DeInit();
Drew Davenport5951b112024-08-05 09:44:27 -060032}
33
Drew Davenportade69652024-07-16 15:54:33 -060034void DrmHwcThree::Init(std::shared_ptr<IComposerCallback> callback) {
35 composer_callback_ = std::move(callback);
36 GetResMan().Init();
37}
38
39void DrmHwcThree::SendVsyncPeriodTimingChangedEventToClient(
40 uint64_t display_id, int64_t timestamp) const {
41 VsyncPeriodChangeTimeline timeline;
42 timeline.newVsyncAppliedTimeNanos = timestamp;
43 timeline.refreshRequired = false;
44 timeline.refreshTimeNanos = 0;
45
46 composer_callback_->onVsyncPeriodTimingChanged(static_cast<int64_t>(
47 display_id),
48 timeline);
49}
50
51void DrmHwcThree::SendRefreshEventToClient(uint64_t display_id) {
Drew Davenport5951b112024-08-05 09:44:27 -060052 composer_resources_->SetDisplayMustValidateState(display_id, true);
Drew Davenportade69652024-07-16 15:54:33 -060053 composer_callback_->onRefresh(static_cast<int64_t>(display_id));
54}
55
56void DrmHwcThree::SendVsyncEventToClient(uint64_t display_id, int64_t timestamp,
57 uint32_t vsync_period) const {
58 composer_callback_->onVsync(static_cast<int64_t>(display_id), timestamp,
59 static_cast<int32_t>(vsync_period));
60}
61
62void DrmHwcThree::SendHotplugEventToClient(hwc2_display_t display_id,
63 bool connected) {
Drew Davenport5951b112024-08-05 09:44:27 -060064 HandleDisplayHotplugEvent(static_cast<uint64_t>(display_id), connected);
Drew Davenport7231bbd2024-09-13 10:39:03 -060065 common::DisplayHotplugEvent event = connected ? common::DisplayHotplugEvent::CONNECTED : common::DisplayHotplugEvent::DISCONNECTED;
66 composer_callback_->onHotplugEvent(static_cast<int64_t>(display_id), event);
Drew Davenportade69652024-07-16 15:54:33 -060067}
68
Drew Davenport5951b112024-08-05 09:44:27 -060069void DrmHwcThree::CleanDisplayResources(uint64_t display_id) {
70 DEBUG_FUNC();
71 HwcDisplay* display = GetDisplay(display_id);
72 if (display == nullptr) {
73 return;
74 }
75
76 display->SetPowerMode(static_cast<int32_t>(PowerMode::OFF));
77
78 size_t cache_size = 0;
79 auto err = composer_resources_->GetDisplayClientTargetCacheSize(display_id,
80 &cache_size);
81 if (err != hwc3::Error::kNone) {
82 ALOGE("%s: Could not clear target buffer cache for display: %" PRIu64,
83 __func__, display_id);
84 return;
85 }
86
87 for (size_t slot = 0; slot < cache_size; slot++) {
88 buffer_handle_t buffer_handle = nullptr;
89 auto buf_releaser = ComposerResources::CreateResourceReleaser(true);
90
91 Buffer buf{};
92 buf.slot = static_cast<int32_t>(slot);
93 err = composer_resources_->GetDisplayClientTarget(display_id, buf,
94 &buffer_handle,
95 buf_releaser.get());
96 if (err != hwc3::Error::kNone) {
97 continue;
98 }
99
100 err = Hwc2toHwc3Error(
101 display->SetClientTarget(buffer_handle, -1,
102 static_cast<int32_t>(
103 common::Dataspace::UNKNOWN),
104 {}));
105 if (err != hwc3::Error::kNone) {
106 ALOGE(
107 "%s: Could not clear slot %zu of the target buffer cache for "
108 "display %" PRIu64,
109 __func__, slot, display_id);
110 }
111 }
112}
113
114void DrmHwcThree::HandleDisplayHotplugEvent(uint64_t display_id,
115 bool connected) {
116 DEBUG_FUNC();
117 if (!connected) {
118 composer_resources_->RemoveDisplay(display_id);
Drew Davenport0bf6c2b2024-08-05 11:54:52 -0600119 Displays().erase(display_id);
Drew Davenport5951b112024-08-05 09:44:27 -0600120 return;
121 }
122
123 if (composer_resources_->HasDisplay(display_id)) {
124 /* Cleanup existing display resources */
125 CleanDisplayResources(display_id);
126 composer_resources_->RemoveDisplay(display_id);
Drew Davenport0bf6c2b2024-08-05 11:54:52 -0600127 Displays().erase(display_id);
Drew Davenport5951b112024-08-05 09:44:27 -0600128 }
129 composer_resources_->AddPhysicalDisplay(display_id);
130}
131
Drew Davenportade69652024-07-16 15:54:33 -0600132} // namespace aidl::android::hardware::graphics::composer3::impl