blob: 06c190901bdf59409e54d454b1aff4067992ec26 [file] [log] [blame]
Sean Pauled2ec4b2016-03-10 15:35:40 -05001/*
2 * Copyright (C) 2016 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#define ATRACE_TAG ATRACE_TAG_GRAPHICS
18#define LOG_TAG "hwc-drm-two"
19
Roman Stratiienko13cc3662020-08-29 21:35:39 +030020#include "DrmHwcTwo.h"
Sean Pauled2ec4b2016-03-10 15:35:40 -050021
Roman Stratiienko0fade372021-02-20 13:59:55 +020022#include <fcntl.h>
Sean Paulac874152016-03-10 16:00:26 -050023#include <hardware/hardware.h>
Sean Pauled2ec4b2016-03-10 15:35:40 -050024#include <hardware/hwcomposer2.h>
Roman Stratiienko74774712021-02-05 16:32:47 +020025#include <sync/sync.h>
Roman Stratiienko0fade372021-02-20 13:59:55 +020026#include <unistd.h>
Sean Pauled2ec4b2016-03-10 15:35:40 -050027
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +020028#include <cinttypes>
Roman Stratiienkod21071f2021-03-09 21:56:50 +020029#include <iostream>
30#include <sstream>
Roman Stratiienkoaa3cd542020-08-29 11:26:16 +030031#include <string>
32
Roman Stratiienko13cc3662020-08-29 21:35:39 +030033#include "backend/BackendManager.h"
Roman Stratiienko33365c22020-10-10 23:06:36 +030034#include "bufferinfo/BufferInfoGetter.h"
Roman Stratiienko13cc3662020-08-29 21:35:39 +030035#include "compositor/DrmDisplayComposition.h"
Roman Stratiienkod21071f2021-03-09 21:56:50 +020036#include "utils/log.h"
37#include "utils/properties.h"
Roman Stratiienkoaa3cd542020-08-29 11:26:16 +030038
Sean Pauled2ec4b2016-03-10 15:35:40 -050039namespace android {
40
Roman Stratiienko26fd2b22022-01-04 12:59:29 +020041DrmHwcTwo::DrmHwcTwo() = default;
Sean Pauled2ec4b2016-03-10 15:35:40 -050042
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +030043HWC2::Error DrmHwcTwo::CreateDisplay(hwc2_display_t displ,
44 HWC2::DisplayType type) {
Roman Stratiienkod26619b2021-08-04 19:55:37 +030045 DrmDevice *drm = resource_manager_.GetDrmDevice(static_cast<int>(displ));
Roman Stratiienko8666dc92021-02-09 17:49:55 +020046 if (!drm) {
47 ALOGE("Failed to get a valid drmresource");
Sean Paulac874152016-03-10 16:00:26 -050048 return HWC2::Error::NoResources;
49 }
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +030050 displays_.emplace(std::piecewise_construct, std::forward_as_tuple(displ),
Roman Stratiienko863a3c22021-09-29 13:00:29 +030051 std::forward_as_tuple(&resource_manager_, drm, displ, type,
52 this));
Sean Paulac874152016-03-10 16:00:26 -050053
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +030054 DrmCrtc *crtc = drm->GetCrtcForDisplay(static_cast<int>(displ));
Sean Paulac874152016-03-10 16:00:26 -050055 if (!crtc) {
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +030056 ALOGE("Failed to get crtc for display %d", static_cast<int>(displ));
Sean Paulac874152016-03-10 16:00:26 -050057 return HWC2::Error::BadDisplay;
58 }
Roman Stratiienkod21071f2021-03-09 21:56:50 +020059 auto display_planes = std::vector<DrmPlane *>();
60 for (const auto &plane : drm->planes()) {
Sean Paulac874152016-03-10 16:00:26 -050061 if (plane->GetCrtcSupported(*crtc))
62 display_planes.push_back(plane.get());
63 }
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +030064 displays_.at(displ).Init(&display_planes);
Sean Paulac874152016-03-10 16:00:26 -050065 return HWC2::Error::None;
66}
67
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +030068HWC2::Error DrmHwcTwo::Init() {
69 int rv = resource_manager_.Init();
70 if (rv) {
71 ALOGE("Can't initialize the resource manager %d", rv);
72 return HWC2::Error::NoResources;
73 }
74
75 HWC2::Error ret = HWC2::Error::None;
Roman Stratiienkofc014f52021-12-23 19:04:29 +020076 for (int i = 0; i < resource_manager_.GetDisplayCount(); i++) {
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +030077 ret = CreateDisplay(i, HWC2::DisplayType::Physical);
78 if (ret != HWC2::Error::None) {
79 ALOGE("Failed to create display %d with error %d", i, ret);
80 return ret;
81 }
82 }
83
Roman Stratiienko1e053b42021-10-25 22:54:20 +030084 resource_manager_.GetUEventListener()->RegisterHotplugHandler(
85 [this] { HandleHotplugUEvent(); });
86
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +030087 return ret;
88}
89
Roman Stratiienko7f576ec2021-12-22 17:34:18 +020090HWC2::Error DrmHwcTwo::CreateVirtualDisplay(uint32_t /*width*/,
91 uint32_t /*height*/,
92 int32_t * /*format*/,
93 hwc2_display_t * /*display*/) {
94 // TODO(nobody): Implement virtual display
Sean Pauled2ec4b2016-03-10 15:35:40 -050095 return HWC2::Error::Unsupported;
96}
97
Roman Stratiienko7f576ec2021-12-22 17:34:18 +020098HWC2::Error DrmHwcTwo::DestroyVirtualDisplay(hwc2_display_t /*display*/) {
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +020099 // TODO(nobody): Implement virtual display
Roman Stratiienko7f576ec2021-12-22 17:34:18 +0200100 return HWC2::Error::Unsupported;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500101}
102
Roman Stratiienko0d1a2cd2019-11-28 17:51:16 +0200103std::string DrmHwcTwo::HwcDisplay::DumpDelta(
104 DrmHwcTwo::HwcDisplay::Stats delta) {
105 if (delta.total_pixops_ == 0)
106 return "No stats yet";
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +0200107 double ratio = 1.0 - double(delta.gpu_pixops_) / double(delta.total_pixops_);
Roman Stratiienko0d1a2cd2019-11-28 17:51:16 +0200108
Roman Stratiienkod21071f2021-03-09 21:56:50 +0200109 std::stringstream ss;
110 ss << " Total frames count: " << delta.total_frames_ << "\n"
111 << " Failed to test commit frames: " << delta.failed_kms_validate_ << "\n"
112 << " Failed to commit frames: " << delta.failed_kms_present_ << "\n"
113 << ((delta.failed_kms_present_ > 0)
114 ? " !!! Internal failure, FIX it please\n"
115 : "")
116 << " Flattened frames: " << delta.frames_flattened_ << "\n"
117 << " Pixel operations (free units)"
118 << " : [TOTAL: " << delta.total_pixops_ << " / GPU: " << delta.gpu_pixops_
119 << "]\n"
120 << " Composition efficiency: " << ratio;
121
122 return ss.str();
Roman Stratiienko0d1a2cd2019-11-28 17:51:16 +0200123}
124
125std::string DrmHwcTwo::HwcDisplay::Dump() {
Roman Stratiienkoe8c06792021-09-30 10:09:31 +0300126 std::string flattening_state_str;
127 switch (flattenning_state_) {
128 case ClientFlattenningState::Disabled:
129 flattening_state_str = "Disabled";
130 break;
131 case ClientFlattenningState::NotRequired:
132 flattening_state_str = "Not needed";
133 break;
134 case ClientFlattenningState::Flattened:
135 flattening_state_str = "Active";
136 break;
137 case ClientFlattenningState::ClientRefreshRequested:
138 flattening_state_str = "Refresh requested";
139 break;
140 default:
141 flattening_state_str = std::to_string(flattenning_state_) +
142 " VSync remains";
143 }
144
Roman Stratiienkod21071f2021-03-09 21:56:50 +0200145 std::stringstream ss;
146 ss << "- Display on: " << connector_->name() << "\n"
Roman Stratiienkoe8c06792021-09-30 10:09:31 +0300147 << " Flattening state: " << flattening_state_str << "\n"
Roman Stratiienkod21071f2021-03-09 21:56:50 +0200148 << "Statistics since system boot:\n"
149 << DumpDelta(total_stats_) << "\n\n"
150 << "Statistics since last dumpsys request:\n"
151 << DumpDelta(total_stats_.minus(prev_stats_)) << "\n\n";
Roman Stratiienko0d1a2cd2019-11-28 17:51:16 +0200152
153 memcpy(&prev_stats_, &total_stats_, sizeof(Stats));
Roman Stratiienkod21071f2021-03-09 21:56:50 +0200154 return ss.str();
Roman Stratiienko0d1a2cd2019-11-28 17:51:16 +0200155}
156
157void DrmHwcTwo::Dump(uint32_t *outSize, char *outBuffer) {
Roman Stratiienko0d1a2cd2019-11-28 17:51:16 +0200158 if (outBuffer != nullptr) {
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +0200159 auto copied_bytes = mDumpString.copy(outBuffer, *outSize);
160 *outSize = static_cast<uint32_t>(copied_bytes);
Roman Stratiienko0d1a2cd2019-11-28 17:51:16 +0200161 return;
162 }
163
164 std::stringstream output;
165
166 output << "-- drm_hwcomposer --\n\n";
167
168 for (std::pair<const hwc2_display_t, DrmHwcTwo::HwcDisplay> &dp : displays_)
169 output << dp.second.Dump();
170
171 mDumpString = output.str();
172 *outSize = static_cast<uint32_t>(mDumpString.size());
Sean Pauled2ec4b2016-03-10 15:35:40 -0500173}
174
175uint32_t DrmHwcTwo::GetMaxVirtualDisplayCount() {
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +0200176 // TODO(nobody): Implement virtual display
Sean Pauled2ec4b2016-03-10 15:35:40 -0500177 return 0;
178}
179
180HWC2::Error DrmHwcTwo::RegisterCallback(int32_t descriptor,
Sean Paulac874152016-03-10 16:00:26 -0500181 hwc2_callback_data_t data,
182 hwc2_function_pointer_t function) {
Roman Stratiienko863a3c22021-09-29 13:00:29 +0300183 std::unique_lock<std::mutex> lock(callback_lock_);
184
Roman Stratiienko23701092020-09-26 02:08:41 +0300185 switch (static_cast<HWC2::Callback>(descriptor)) {
Sean Paulac874152016-03-10 16:00:26 -0500186 case HWC2::Callback::Hotplug: {
Roman Stratiienko863a3c22021-09-29 13:00:29 +0300187 hotplug_callback_ = std::make_pair(HWC2_PFN_HOTPLUG(function), data);
188 lock.unlock();
Roman Stratiienkofc014f52021-12-23 19:04:29 +0200189 const auto &drm_devices = resource_manager_.GetDrmDevices();
Roman Stratiienkod21071f2021-03-09 21:56:50 +0200190 for (const auto &device : drm_devices)
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +0300191 HandleInitialHotplugState(device.get());
Sean Paulac874152016-03-10 16:00:26 -0500192 break;
193 }
Roman Kovalivskyi8fae1562020-01-30 20:20:47 +0200194 case HWC2::Callback::Refresh: {
Roman Stratiienko863a3c22021-09-29 13:00:29 +0300195 refresh_callback_ = std::make_pair(HWC2_PFN_REFRESH(function), data);
Roman Kovalivskyi8fae1562020-01-30 20:20:47 +0200196 break;
197 }
Sean Paulac874152016-03-10 16:00:26 -0500198 case HWC2::Callback::Vsync: {
Roman Stratiienko863a3c22021-09-29 13:00:29 +0300199 vsync_callback_ = std::make_pair(HWC2_PFN_VSYNC(function), data);
Sean Paulac874152016-03-10 16:00:26 -0500200 break;
201 }
Roman Stratiienko11ef8c52021-09-29 13:01:39 +0300202#if PLATFORM_SDK_VERSION > 29
203 case HWC2::Callback::Vsync_2_4: {
204 vsync_2_4_callback_ = std::make_pair(HWC2_PFN_VSYNC_2_4(function), data);
205 break;
206 }
207#endif
Sean Paulac874152016-03-10 16:00:26 -0500208 default:
209 break;
210 }
211 return HWC2::Error::None;
212}
213
Alexandru Gheorghe6f0030f2018-05-01 17:25:48 +0100214DrmHwcTwo::HwcDisplay::HwcDisplay(ResourceManager *resource_manager,
Roman Stratiienko8666dc92021-02-09 17:49:55 +0200215 DrmDevice *drm, hwc2_display_t handle,
Roman Stratiienko863a3c22021-09-29 13:00:29 +0300216 HWC2::DisplayType type, DrmHwcTwo *hwc2)
217 : hwc2_(hwc2),
218 resource_manager_(resource_manager),
Alexandru Gheorghe6f0030f2018-05-01 17:25:48 +0100219 drm_(drm),
Alexandru Gheorghe6f0030f2018-05-01 17:25:48 +0100220 handle_(handle),
Roman Kovalivskyi12b91a32019-12-11 19:09:51 +0200221 type_(type),
222 color_transform_hint_(HAL_COLOR_TRANSFORM_IDENTITY) {
Roman Kovalivskyi12b91a32019-12-11 19:09:51 +0200223 // clang-format off
224 color_transform_matrix_ = {1.0, 0.0, 0.0, 0.0,
225 0.0, 1.0, 0.0, 0.0,
226 0.0, 0.0, 1.0, 0.0,
227 0.0, 0.0, 0.0, 1.0};
228 // clang-format on
Sean Paulac874152016-03-10 16:00:26 -0500229}
230
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +0300231void DrmHwcTwo::HwcDisplay::ClearDisplay() {
Roman Stratiienkodccc6fb2021-10-23 17:35:44 +0300232 AtomicCommitArgs a_args = {.clear_active_composition = true};
233 compositor_.ExecuteAtomicCommit(a_args);
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +0300234}
235
Sean Paulac874152016-03-10 16:00:26 -0500236HWC2::Error DrmHwcTwo::HwcDisplay::Init(std::vector<DrmPlane *> *planes) {
Sean Paulac874152016-03-10 16:00:26 -0500237 int display = static_cast<int>(handle_);
Roman Stratiienkoe8c06792021-09-30 10:09:31 +0300238 int ret = compositor_.Init(resource_manager_, display);
Sean Paulac874152016-03-10 16:00:26 -0500239 if (ret) {
240 ALOGE("Failed display compositor init for display %d (%d)", display, ret);
241 return HWC2::Error::NoResources;
242 }
243
244 // Split up the given display planes into primary and overlay to properly
245 // interface with the composition
246 char use_overlay_planes_prop[PROPERTY_VALUE_MAX];
Jason Macnakf1af9572020-08-20 11:49:51 -0700247 property_get("vendor.hwc.drm.use_overlay_planes", use_overlay_planes_prop,
248 "1");
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +0200249 bool use_overlay_planes = strtol(use_overlay_planes_prop, nullptr, 10);
Sean Paulac874152016-03-10 16:00:26 -0500250 for (auto &plane : *planes) {
Roman Stratiienkofc014f52021-12-23 19:04:29 +0200251 if (plane->GetType() == DRM_PLANE_TYPE_PRIMARY)
Sean Paulac874152016-03-10 16:00:26 -0500252 primary_planes_.push_back(plane);
Roman Stratiienkofc014f52021-12-23 19:04:29 +0200253 else if (use_overlay_planes && (plane)->GetType() == DRM_PLANE_TYPE_OVERLAY)
Sean Paulac874152016-03-10 16:00:26 -0500254 overlay_planes_.push_back(plane);
255 }
256
257 crtc_ = drm_->GetCrtcForDisplay(display);
258 if (!crtc_) {
259 ALOGE("Failed to get crtc for display %d", display);
260 return HWC2::Error::BadDisplay;
261 }
262
263 connector_ = drm_->GetConnectorForDisplay(display);
264 if (!connector_) {
265 ALOGE("Failed to get connector for display %d", display);
266 return HWC2::Error::BadDisplay;
267 }
268
Roman Stratiienko863a3c22021-09-29 13:00:29 +0300269 ret = vsync_worker_.Init(drm_, display, [this](int64_t timestamp) {
Roman Stratiienko863a3c22021-09-29 13:00:29 +0300270 const std::lock_guard<std::mutex> lock(hwc2_->callback_lock_);
Roman Stratiienko11ef8c52021-09-29 13:01:39 +0300271 /* vsync callback */
272#if PLATFORM_SDK_VERSION > 29
273 if (hwc2_->vsync_2_4_callback_.first != nullptr &&
274 hwc2_->vsync_2_4_callback_.second != nullptr) {
275 hwc2_vsync_period_t period_ns{};
276 GetDisplayVsyncPeriod(&period_ns);
277 hwc2_->vsync_2_4_callback_.first(hwc2_->vsync_2_4_callback_.second,
278 handle_, timestamp, period_ns);
279 } else
280#endif
281 if (hwc2_->vsync_callback_.first != nullptr &&
282 hwc2_->vsync_callback_.second != nullptr) {
Roman Stratiienko863a3c22021-09-29 13:00:29 +0300283 hwc2_->vsync_callback_.first(hwc2_->vsync_callback_.second, handle_,
284 timestamp);
285 }
286 });
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +0300287 if (ret) {
288 ALOGE("Failed to create event worker for d=%d %d\n", display, ret);
289 return HWC2::Error::BadDisplay;
290 }
291
Roman Stratiienkoe8c06792021-09-30 10:09:31 +0300292 ret = flattening_vsync_worker_.Init(drm_, display, [this](int64_t /*timestamp*/) {
293 const std::lock_guard<std::mutex> lock(hwc2_->callback_lock_);
294 /* Frontend flattening */
295 if (flattenning_state_ > ClientFlattenningState::ClientRefreshRequested &&
296 --flattenning_state_ ==
297 ClientFlattenningState::ClientRefreshRequested &&
298 hwc2_->refresh_callback_.first != nullptr &&
299 hwc2_->refresh_callback_.second != nullptr) {
300 hwc2_->refresh_callback_.first(hwc2_->refresh_callback_.second, handle_);
301 flattening_vsync_worker_.VSyncControl(false);
302 }
303 });
304 if (ret) {
305 ALOGE("Failed to create event worker for d=%d %d\n", display, ret);
306 return HWC2::Error::BadDisplay;
307 }
308
Matvii Zorinef3c7972020-08-11 15:15:44 +0300309 ret = BackendManager::GetInstance().SetBackendForDisplay(this);
310 if (ret) {
311 ALOGE("Failed to set backend for d=%d %d\n", display, ret);
312 return HWC2::Error::BadDisplay;
313 }
314
Roman Stratiienko720f6522021-12-06 14:56:14 +0200315 client_layer_.SetLayerBlendMode(HWC2_BLEND_MODE_PREMULTIPLIED);
316
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +0300317 return ChosePreferredConfig();
318}
319
320HWC2::Error DrmHwcTwo::HwcDisplay::ChosePreferredConfig() {
Sean Paulac874152016-03-10 16:00:26 -0500321 // Fetch the number of modes from the display
Roman Stratiienkob3b5c1e2021-02-15 13:44:19 +0200322 uint32_t num_configs = 0;
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +0200323 HWC2::Error err = GetDisplayConfigs(&num_configs, nullptr);
Sean Paulac874152016-03-10 16:00:26 -0500324 if (err != HWC2::Error::None || !num_configs)
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200325 return HWC2::Error::BadDisplay;
Sean Paulac874152016-03-10 16:00:26 -0500326
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200327 return SetActiveConfig(preferred_config_id_);
Sean Paulac874152016-03-10 16:00:26 -0500328}
329
Sean Pauled2ec4b2016-03-10 15:35:40 -0500330HWC2::Error DrmHwcTwo::HwcDisplay::AcceptDisplayChanges() {
Sean Paulac874152016-03-10 16:00:26 -0500331 for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_)
332 l.second.accept_type_change();
333 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500334}
335
336HWC2::Error DrmHwcTwo::HwcDisplay::CreateLayer(hwc2_layer_t *layer) {
Sean Paulac874152016-03-10 16:00:26 -0500337 layers_.emplace(static_cast<hwc2_layer_t>(layer_idx_), HwcLayer());
338 *layer = static_cast<hwc2_layer_t>(layer_idx_);
339 ++layer_idx_;
340 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500341}
342
343HWC2::Error DrmHwcTwo::HwcDisplay::DestroyLayer(hwc2_layer_t layer) {
Vincent Donnefort9abec032019-10-09 15:43:43 +0100344 if (!get_layer(layer))
345 return HWC2::Error::BadLayer;
346
Sean Paulac874152016-03-10 16:00:26 -0500347 layers_.erase(layer);
348 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500349}
350
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200351HWC2::Error DrmHwcTwo::HwcDisplay::GetActiveConfig(
352 hwc2_config_t *config) const {
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200353 if (hwc_configs_.count(active_config_id_) == 0)
Sean Paulac874152016-03-10 16:00:26 -0500354 return HWC2::Error::BadConfig;
355
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200356 *config = active_config_id_;
Sean Paulac874152016-03-10 16:00:26 -0500357 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500358}
359
360HWC2::Error DrmHwcTwo::HwcDisplay::GetChangedCompositionTypes(
361 uint32_t *num_elements, hwc2_layer_t *layers, int32_t *types) {
Sean Paulac874152016-03-10 16:00:26 -0500362 uint32_t num_changes = 0;
363 for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
364 if (l.second.type_changed()) {
365 if (layers && num_changes < *num_elements)
366 layers[num_changes] = l.first;
367 if (types && num_changes < *num_elements)
368 types[num_changes] = static_cast<int32_t>(l.second.validated_type());
369 ++num_changes;
370 }
371 }
372 if (!layers && !types)
373 *num_elements = num_changes;
374 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500375}
376
377HWC2::Error DrmHwcTwo::HwcDisplay::GetClientTargetSupport(uint32_t width,
Sean Paulac874152016-03-10 16:00:26 -0500378 uint32_t height,
379 int32_t /*format*/,
380 int32_t dataspace) {
Sean Paulac874152016-03-10 16:00:26 -0500381 std::pair<uint32_t, uint32_t> min = drm_->min_resolution();
382 std::pair<uint32_t, uint32_t> max = drm_->max_resolution();
383
384 if (width < min.first || height < min.second)
385 return HWC2::Error::Unsupported;
386
387 if (width > max.first || height > max.second)
388 return HWC2::Error::Unsupported;
389
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +0200390 if (dataspace != HAL_DATASPACE_UNKNOWN)
Sean Paulac874152016-03-10 16:00:26 -0500391 return HWC2::Error::Unsupported;
392
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +0200393 // TODO(nobody): Validate format can be handled by either GL or planes
Sean Paulac874152016-03-10 16:00:26 -0500394 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500395}
396
397HWC2::Error DrmHwcTwo::HwcDisplay::GetColorModes(uint32_t *num_modes,
Sean Paulac874152016-03-10 16:00:26 -0500398 int32_t *modes) {
Kalyan Kondapallyda5839c2016-11-10 10:59:50 -0800399 if (!modes)
400 *num_modes = 1;
401
402 if (modes)
403 *modes = HAL_COLOR_MODE_NATIVE;
404
405 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500406}
407
408HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayAttribute(hwc2_config_t config,
Sean Paulac874152016-03-10 16:00:26 -0500409 int32_t attribute_in,
410 int32_t *value) {
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200411 int conf = static_cast<int>(config);
412
413 if (hwc_configs_.count(conf) == 0) {
414 ALOGE("Could not find active mode for %d", conf);
Sean Paulac874152016-03-10 16:00:26 -0500415 return HWC2::Error::BadConfig;
416 }
417
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200418 auto &hwc_config = hwc_configs_[conf];
419
Sean Paulac874152016-03-10 16:00:26 -0500420 static const int32_t kUmPerInch = 25400;
421 uint32_t mm_width = connector_->mm_width();
422 uint32_t mm_height = connector_->mm_height();
423 auto attribute = static_cast<HWC2::Attribute>(attribute_in);
424 switch (attribute) {
425 case HWC2::Attribute::Width:
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200426 *value = static_cast<int>(hwc_config.mode.h_display());
Sean Paulac874152016-03-10 16:00:26 -0500427 break;
428 case HWC2::Attribute::Height:
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200429 *value = static_cast<int>(hwc_config.mode.v_display());
Sean Paulac874152016-03-10 16:00:26 -0500430 break;
431 case HWC2::Attribute::VsyncPeriod:
432 // in nanoseconds
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200433 *value = static_cast<int>(1E9 / hwc_config.mode.v_refresh());
Sean Paulac874152016-03-10 16:00:26 -0500434 break;
435 case HWC2::Attribute::DpiX:
436 // Dots per 1000 inches
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200437 *value = mm_width ? static_cast<int>(hwc_config.mode.h_display() *
438 kUmPerInch / mm_width)
439 : -1;
Sean Paulac874152016-03-10 16:00:26 -0500440 break;
441 case HWC2::Attribute::DpiY:
442 // Dots per 1000 inches
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200443 *value = mm_height ? static_cast<int>(hwc_config.mode.v_display() *
444 kUmPerInch / mm_height)
Roman Stratiienkod26619b2021-08-04 19:55:37 +0300445 : -1;
Sean Paulac874152016-03-10 16:00:26 -0500446 break;
Roman Stratiienko6f5df172020-09-27 22:48:08 +0300447#if PLATFORM_SDK_VERSION > 29
448 case HWC2::Attribute::ConfigGroup:
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200449 /* Dispite ConfigGroup is a part of HWC2.4 API, framework
450 * able to request it even if service @2.1 is used */
451 *value = hwc_config.group_id;
Roman Stratiienko6f5df172020-09-27 22:48:08 +0300452 break;
453#endif
Sean Paulac874152016-03-10 16:00:26 -0500454 default:
455 *value = -1;
456 return HWC2::Error::BadConfig;
457 }
458 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500459}
460
Roman Stratiienko5f2f3ce2021-12-22 11:46:03 +0200461// NOLINTNEXTLINE (readability-function-cognitive-complexity): Fixme
Sean Pauled2ec4b2016-03-10 15:35:40 -0500462HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayConfigs(uint32_t *num_configs,
463 hwc2_config_t *configs) {
Sean Paulac874152016-03-10 16:00:26 -0500464 // Since this callback is normally invoked twice (once to get the count, and
465 // once to populate configs), we don't really want to read the edid
466 // redundantly. Instead, only update the modes on the first invocation. While
467 // it's possible this will result in stale modes, it'll all come out in the
468 // wash when we try to set the active config later.
469 if (!configs) {
470 int ret = connector_->UpdateModes();
471 if (ret) {
472 ALOGE("Failed to update display modes %d", ret);
473 return HWC2::Error::BadDisplay;
474 }
Sean Paulac874152016-03-10 16:00:26 -0500475
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200476 hwc_configs_.clear();
477 preferred_config_id_ = 0;
478 int preferred_config_group_id_ = 0;
Neil Armstrongb67d0492019-06-20 09:00:21 +0000479
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200480 if (connector_->modes().empty()) {
481 ALOGE("No modes reported by KMS");
482 return HWC2::Error::BadDisplay;
Neil Armstrong4c027a72019-06-04 14:48:02 +0000483 }
Neil Armstrongb67d0492019-06-20 09:00:21 +0000484
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200485 int last_config_id = 1;
486 int last_group_id = 1;
Neil Armstrongb67d0492019-06-20 09:00:21 +0000487
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200488 /* Group modes */
489 for (const auto &mode : connector_->modes()) {
490 /* Find group for the new mode or create new group */
491 int group_found = 0;
492 for (auto &hwc_config : hwc_configs_) {
493 if (mode.h_display() == hwc_config.second.mode.h_display() &&
494 mode.v_display() == hwc_config.second.mode.v_display()) {
495 group_found = hwc_config.second.group_id;
496 }
497 }
498 if (group_found == 0) {
499 group_found = last_group_id++;
500 }
501
502 bool disabled = false;
503 if (mode.flags() & DRM_MODE_FLAG_3D_MASK) {
504 ALOGI("Disabling display mode %s (Modes with 3D flag aren't supported)",
505 mode.name().c_str());
506 disabled = true;
507 }
508
509 /* Add config */
510 hwc_configs_[last_config_id] = {
511 .id = last_config_id,
512 .group_id = group_found,
513 .mode = mode,
514 .disabled = disabled,
515 };
516
517 /* Chwck if the mode is preferred */
518 if ((mode.type() & DRM_MODE_TYPE_PREFERRED) != 0 &&
519 preferred_config_id_ == 0) {
520 preferred_config_id_ = last_config_id;
521 preferred_config_group_id_ = group_found;
522 }
523
524 last_config_id++;
525 }
526
527 /* We must have preferred mode. Set first mode as preferred
528 * in case KMS haven't reported anything. */
529 if (preferred_config_id_ == 0) {
530 preferred_config_id_ = 1;
531 preferred_config_group_id_ = 1;
532 }
533
534 for (int group = 1; group < last_group_id; group++) {
535 bool has_interlaced = false;
536 bool has_progressive = false;
537 for (auto &hwc_config : hwc_configs_) {
538 if (hwc_config.second.group_id != group || hwc_config.second.disabled) {
539 continue;
540 }
541
542 if (hwc_config.second.IsInterlaced()) {
543 has_interlaced = true;
544 } else {
545 has_progressive = true;
546 }
547 }
548
549 bool has_both = has_interlaced && has_progressive;
550 if (!has_both) {
551 continue;
552 }
553
554 bool group_contains_preferred_interlaced = false;
555 if (group == preferred_config_group_id_ &&
556 hwc_configs_[preferred_config_id_].IsInterlaced()) {
557 group_contains_preferred_interlaced = true;
558 }
559
560 for (auto &hwc_config : hwc_configs_) {
561 if (hwc_config.second.group_id != group || hwc_config.second.disabled) {
562 continue;
563 }
564
565 bool disable = group_contains_preferred_interlaced
566 ? !hwc_config.second.IsInterlaced()
567 : hwc_config.second.IsInterlaced();
568
569 if (disable) {
570 ALOGI(
571 "Group %i: Disabling display mode %s (This group should consist "
572 "of %s modes)",
573 group, hwc_config.second.mode.name().c_str(),
574 group_contains_preferred_interlaced ? "interlaced"
575 : "progressive");
576
577 hwc_config.second.disabled = true;
578 }
579 }
580 }
581
582 /* Group should not contain 2 modes with FPS delta less than ~1HZ
583 * otherwise android.graphics.cts.SetFrameRateTest CTS will fail
584 */
585 for (int m1 = 1; m1 < last_config_id; m1++) {
586 for (int m2 = 1; m2 < last_config_id; m2++) {
587 if (m1 != m2 &&
588 hwc_configs_[m1].group_id == hwc_configs_[m2].group_id &&
589 !hwc_configs_[m1].disabled && !hwc_configs_[m2].disabled &&
590 fabsf(hwc_configs_[m1].mode.v_refresh() -
591 hwc_configs_[m2].mode.v_refresh()) < 1.0) {
592 ALOGI(
593 "Group %i: Disabling display mode %s (Refresh rate value is "
594 "too close to existing mode %s)",
595 hwc_configs_[m2].group_id, hwc_configs_[m2].mode.name().c_str(),
596 hwc_configs_[m1].mode.name().c_str());
597
598 hwc_configs_[m2].disabled = true;
599 }
600 }
601 }
Neil Armstrongb67d0492019-06-20 09:00:21 +0000602 }
603
604 uint32_t idx = 0;
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200605 for (auto &hwc_config : hwc_configs_) {
606 if (hwc_config.second.disabled) {
607 continue;
608 }
609
610 if (configs != nullptr) {
611 if (idx >= *num_configs) {
612 break;
613 }
614 configs[idx] = hwc_config.second.id;
615 }
616
617 idx++;
Sean Paulac874152016-03-10 16:00:26 -0500618 }
619 *num_configs = idx;
620 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500621}
622
623HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayName(uint32_t *size, char *name) {
Sean Paulac874152016-03-10 16:00:26 -0500624 std::ostringstream stream;
625 stream << "display-" << connector_->id();
626 std::string string = stream.str();
627 size_t length = string.length();
628 if (!name) {
629 *size = length;
630 return HWC2::Error::None;
631 }
632
633 *size = std::min<uint32_t>(static_cast<uint32_t>(length - 1), *size);
634 strncpy(name, string.c_str(), *size);
635 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500636}
637
Roman Stratiienko7f576ec2021-12-22 17:34:18 +0200638HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayRequests(
639 int32_t * /*display_requests*/, uint32_t *num_elements,
640 hwc2_layer_t * /*layers*/, int32_t * /*layer_requests*/) {
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +0200641 // TODO(nobody): I think virtual display should request
Sean Paulac874152016-03-10 16:00:26 -0500642 // HWC2_DISPLAY_REQUEST_WRITE_CLIENT_TARGET_TO_OUTPUT here
Sean Paulac874152016-03-10 16:00:26 -0500643 *num_elements = 0;
644 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500645}
646
647HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayType(int32_t *type) {
Sean Paulac874152016-03-10 16:00:26 -0500648 *type = static_cast<int32_t>(type_);
649 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500650}
651
652HWC2::Error DrmHwcTwo::HwcDisplay::GetDozeSupport(int32_t *support) {
Sean Paulac874152016-03-10 16:00:26 -0500653 *support = 0;
654 return HWC2::Error::None;
655}
656
657HWC2::Error DrmHwcTwo::HwcDisplay::GetHdrCapabilities(
Sean Paulf72cccd2018-08-27 13:59:08 -0400658 uint32_t *num_types, int32_t * /*types*/, float * /*max_luminance*/,
659 float * /*max_average_luminance*/, float * /*min_luminance*/) {
Sean Paulac874152016-03-10 16:00:26 -0500660 *num_types = 0;
661 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500662}
663
Roman Stratiienko3e2f9e72021-05-21 14:33:28 +0300664/* Find API details at:
665 * https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:hardware/libhardware/include/hardware/hwcomposer2.h;l=1767
666 */
Sean Pauled2ec4b2016-03-10 15:35:40 -0500667HWC2::Error DrmHwcTwo::HwcDisplay::GetReleaseFences(uint32_t *num_elements,
Sean Paulac874152016-03-10 16:00:26 -0500668 hwc2_layer_t *layers,
669 int32_t *fences) {
Sean Paulac874152016-03-10 16:00:26 -0500670 uint32_t num_layers = 0;
671
672 for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
673 ++num_layers;
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +0200674 if (layers == nullptr || fences == nullptr)
Sean Paulac874152016-03-10 16:00:26 -0500675 continue;
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +0200676
677 if (num_layers > *num_elements) {
Sean Paulac874152016-03-10 16:00:26 -0500678 ALOGW("Overflow num_elements %d/%d", num_layers, *num_elements);
679 return HWC2::Error::None;
680 }
681
682 layers[num_layers - 1] = l.first;
Roman Stratiienko0fade372021-02-20 13:59:55 +0200683 fences[num_layers - 1] = l.second.release_fence_.Release();
Sean Paulac874152016-03-10 16:00:26 -0500684 }
685 *num_elements = num_layers;
686 return HWC2::Error::None;
687}
688
Roman Stratiienko2a1f1ae2021-10-23 17:47:35 +0300689HWC2::Error DrmHwcTwo::HwcDisplay::CreateComposition(AtomicCommitArgs &a_args) {
Sean Paulac874152016-03-10 16:00:26 -0500690 // order the layers by z-order
691 bool use_client_layer = false;
Alexandru Gheorghe1542d292018-06-13 16:46:36 +0100692 uint32_t client_z_order = UINT32_MAX;
Sean Paulac874152016-03-10 16:00:26 -0500693 std::map<uint32_t, DrmHwcTwo::HwcLayer *> z_map;
694 for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
Roman Stratiienkof2647232019-11-21 01:58:35 +0200695 switch (l.second.validated_type()) {
Sean Paulac874152016-03-10 16:00:26 -0500696 case HWC2::Composition::Device:
697 z_map.emplace(std::make_pair(l.second.z_order(), &l.second));
698 break;
699 case HWC2::Composition::Client:
Alexandru Gheorghe1542d292018-06-13 16:46:36 +0100700 // Place it at the z_order of the lowest client layer
Sean Paulac874152016-03-10 16:00:26 -0500701 use_client_layer = true;
Alexandru Gheorghe1542d292018-06-13 16:46:36 +0100702 client_z_order = std::min(client_z_order, l.second.z_order());
Sean Paulac874152016-03-10 16:00:26 -0500703 break;
704 default:
705 continue;
706 }
707 }
708 if (use_client_layer)
709 z_map.emplace(std::make_pair(client_z_order, &client_layer_));
710
Rob Herring4f6c62e2018-05-17 14:33:02 -0500711 if (z_map.empty())
712 return HWC2::Error::BadLayer;
713
Matvii Zorin5368b732021-01-12 10:53:08 +0200714 std::vector<DrmHwcLayer> composition_layers;
715
Sean Paulac874152016-03-10 16:00:26 -0500716 // now that they're ordered by z, add them to the composition
717 for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map) {
718 DrmHwcLayer layer;
719 l.second->PopulateDrmLayer(&layer);
Roman Stratiienko8666dc92021-02-09 17:49:55 +0200720 int ret = layer.ImportBuffer(drm_);
Sean Paulac874152016-03-10 16:00:26 -0500721 if (ret) {
722 ALOGE("Failed to import layer, ret=%d", ret);
723 return HWC2::Error::NoResources;
724 }
Matvii Zorin5368b732021-01-12 10:53:08 +0200725 composition_layers.emplace_back(std::move(layer));
Sean Paulac874152016-03-10 16:00:26 -0500726 }
Sean Paulac874152016-03-10 16:00:26 -0500727
Roman Stratiienko753d1072021-12-30 18:05:27 +0200728 auto composition = std::make_shared<DrmDisplayComposition>(crtc_);
Sean Paulac874152016-03-10 16:00:26 -0500729
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +0200730 // TODO(nobody): Don't always assume geometry changed
Matvii Zorin5368b732021-01-12 10:53:08 +0200731 int ret = composition->SetLayers(composition_layers.data(),
Roman Stratiienko36a7f282021-10-05 18:17:53 +0300732 composition_layers.size());
Sean Paulac874152016-03-10 16:00:26 -0500733 if (ret) {
734 ALOGE("Failed to set layers in the composition ret=%d", ret);
735 return HWC2::Error::BadLayer;
736 }
737
738 std::vector<DrmPlane *> primary_planes(primary_planes_);
739 std::vector<DrmPlane *> overlay_planes(overlay_planes_);
Rob Herringaf0d9752018-05-04 16:34:19 -0500740 ret = composition->Plan(&primary_planes, &overlay_planes);
Sean Paulac874152016-03-10 16:00:26 -0500741 if (ret) {
John Stultz66763d52021-08-24 04:59:25 +0000742 ALOGV("Failed to plan the composition ret=%d", ret);
Sean Paulac874152016-03-10 16:00:26 -0500743 return HWC2::Error::BadConfig;
744 }
745
Roman Stratiienko2a1f1ae2021-10-23 17:47:35 +0300746 a_args.composition = composition;
Roman Stratiienkof81d2c82022-01-11 19:47:24 +0200747 if (staged_mode) {
748 a_args.display_mode = *staged_mode;
749 }
Roman Stratiienkodccc6fb2021-10-23 17:35:44 +0300750 ret = compositor_.ExecuteAtomicCommit(a_args);
751
Sean Paulac874152016-03-10 16:00:26 -0500752 if (ret) {
Roman Stratiienko2a1f1ae2021-10-23 17:47:35 +0300753 if (!a_args.test_only)
John Stultz78c9f6c2018-05-24 16:43:35 -0700754 ALOGE("Failed to apply the frame composition ret=%d", ret);
Sean Paulac874152016-03-10 16:00:26 -0500755 return HWC2::Error::BadParameter;
756 }
Roman Stratiienkof81d2c82022-01-11 19:47:24 +0200757
758 if (!a_args.test_only) {
759 staged_mode.reset();
760 }
761
Rob Herring4f6c62e2018-05-17 14:33:02 -0500762 return HWC2::Error::None;
763}
764
Roman Stratiienko3e2f9e72021-05-21 14:33:28 +0300765/* Find API details at:
766 * https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:hardware/libhardware/include/hardware/hwcomposer2.h;l=1805
767 */
Matteo Franchinc56eede2019-12-03 17:10:38 +0000768HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *present_fence) {
Rob Herring4f6c62e2018-05-17 14:33:02 -0500769 HWC2::Error ret;
770
Roman Stratiienko0d1a2cd2019-11-28 17:51:16 +0200771 ++total_stats_.total_frames_;
772
Roman Stratiienko2a1f1ae2021-10-23 17:47:35 +0300773 AtomicCommitArgs a_args{};
774 ret = CreateComposition(a_args);
775
Roman Stratiienko0d1a2cd2019-11-28 17:51:16 +0200776 if (ret != HWC2::Error::None)
777 ++total_stats_.failed_kms_present_;
778
Rob Herring4f6c62e2018-05-17 14:33:02 -0500779 if (ret == HWC2::Error::BadLayer) {
780 // Can we really have no client or device layers?
Matteo Franchinc56eede2019-12-03 17:10:38 +0000781 *present_fence = -1;
Rob Herring4f6c62e2018-05-17 14:33:02 -0500782 return HWC2::Error::None;
783 }
784 if (ret != HWC2::Error::None)
785 return ret;
Sean Paulac874152016-03-10 16:00:26 -0500786
Roman Stratiienko2a1f1ae2021-10-23 17:47:35 +0300787 *present_fence = a_args.out_fence.Release();
Sean Paulac874152016-03-10 16:00:26 -0500788
789 ++frame_no_;
790 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500791}
792
793HWC2::Error DrmHwcTwo::HwcDisplay::SetActiveConfig(hwc2_config_t config) {
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200794 int conf = static_cast<int>(config);
795
796 if (hwc_configs_.count(conf) == 0) {
797 ALOGE("Could not find active mode for %d", conf);
Sean Paulac874152016-03-10 16:00:26 -0500798 return HWC2::Error::BadConfig;
799 }
800
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200801 auto &mode = hwc_configs_[conf].mode;
802
Roman Stratiienkof81d2c82022-01-11 19:47:24 +0200803 staged_mode = mode;
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +0300804
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200805 active_config_id_ = conf;
Sean Paulac874152016-03-10 16:00:26 -0500806
807 // Setup the client layer's dimensions
808 hwc_rect_t display_frame = {.left = 0,
809 .top = 0,
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200810 .right = static_cast<int>(mode.h_display()),
811 .bottom = static_cast<int>(mode.v_display())};
Sean Paulac874152016-03-10 16:00:26 -0500812 client_layer_.SetLayerDisplayFrame(display_frame);
Sean Paulac874152016-03-10 16:00:26 -0500813
814 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500815}
816
Roman Stratiienko3e2f9e72021-05-21 14:33:28 +0300817/* Find API details at:
818 * https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:hardware/libhardware/include/hardware/hwcomposer2.h;l=1861
819 */
Sean Pauled2ec4b2016-03-10 15:35:40 -0500820HWC2::Error DrmHwcTwo::HwcDisplay::SetClientTarget(buffer_handle_t target,
821 int32_t acquire_fence,
822 int32_t dataspace,
Rob Herring1b2685c2017-11-29 10:19:57 -0600823 hwc_region_t /*damage*/) {
Sean Paulac874152016-03-10 16:00:26 -0500824 client_layer_.set_buffer(target);
John Stultz8adf5442021-07-31 00:19:50 +0000825 client_layer_.acquire_fence_ = UniqueFd(acquire_fence);
Sean Paulac874152016-03-10 16:00:26 -0500826 client_layer_.SetLayerDataspace(dataspace);
Roman Stratiienko33365c22020-10-10 23:06:36 +0300827
828 /* TODO: Do not update source_crop every call.
829 * It makes sense to do it once after every hotplug event. */
Roman Stratiienkofc014f52021-12-23 19:04:29 +0200830 HwcDrmBo bo{};
Roman Stratiienko33365c22020-10-10 23:06:36 +0300831 BufferInfoGetter::GetInstance()->ConvertBoInfo(target, &bo);
832
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +0200833 hwc_frect_t source_crop = {.left = 0.0F,
834 .top = 0.0F,
Roman Stratiienkod26619b2021-08-04 19:55:37 +0300835 .right = static_cast<float>(bo.width),
836 .bottom = static_cast<float>(bo.height)};
Roman Stratiienko33365c22020-10-10 23:06:36 +0300837 client_layer_.SetLayerSourceCrop(source_crop);
838
Sean Paulac874152016-03-10 16:00:26 -0500839 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500840}
841
842HWC2::Error DrmHwcTwo::HwcDisplay::SetColorMode(int32_t mode) {
Roman Stratiienkod146d6d2020-10-04 23:56:46 +0300843 if (mode < HAL_COLOR_MODE_NATIVE || mode > HAL_COLOR_MODE_BT2100_HLG)
844 return HWC2::Error::BadParameter;
845
Kalyan Kondapallyda5839c2016-11-10 10:59:50 -0800846 if (mode != HAL_COLOR_MODE_NATIVE)
Roman Stratiienko27d2ed62020-09-26 23:59:19 +0300847 return HWC2::Error::Unsupported;
Kalyan Kondapallyda5839c2016-11-10 10:59:50 -0800848
849 color_mode_ = mode;
850 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500851}
852
853HWC2::Error DrmHwcTwo::HwcDisplay::SetColorTransform(const float *matrix,
Sean Paulac874152016-03-10 16:00:26 -0500854 int32_t hint) {
Roman Kovalivskyi12b91a32019-12-11 19:09:51 +0200855 if (hint < HAL_COLOR_TRANSFORM_IDENTITY ||
856 hint > HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA)
857 return HWC2::Error::BadParameter;
858
859 if (!matrix && hint == HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX)
860 return HWC2::Error::BadParameter;
861
862 color_transform_hint_ = static_cast<android_color_transform_t>(hint);
863 if (color_transform_hint_ == HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX)
864 std::copy(matrix, matrix + MATRIX_SIZE, color_transform_matrix_.begin());
865
866 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500867}
868
Roman Stratiienko7f576ec2021-12-22 17:34:18 +0200869HWC2::Error DrmHwcTwo::HwcDisplay::SetOutputBuffer(buffer_handle_t /*buffer*/,
870 int32_t /*release_fence*/) {
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +0200871 // TODO(nobody): Need virtual display support
Roman Stratiienko7f576ec2021-12-22 17:34:18 +0200872 return HWC2::Error::Unsupported;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500873}
874
Sean Paulac874152016-03-10 16:00:26 -0500875HWC2::Error DrmHwcTwo::HwcDisplay::SetPowerMode(int32_t mode_in) {
Sean Paulac874152016-03-10 16:00:26 -0500876 auto mode = static_cast<HWC2::PowerMode>(mode_in);
Roman Stratiienkodccc6fb2021-10-23 17:35:44 +0300877 AtomicCommitArgs a_args{};
878
Sean Paulac874152016-03-10 16:00:26 -0500879 switch (mode) {
880 case HWC2::PowerMode::Off:
Roman Stratiienkodccc6fb2021-10-23 17:35:44 +0300881 a_args.active = false;
Sean Paulac874152016-03-10 16:00:26 -0500882 break;
883 case HWC2::PowerMode::On:
Roman Stratiienkof81d2c82022-01-11 19:47:24 +0200884 /*
885 * Setting the display to active before we have a composition
886 * can break some drivers, so skip setting a_args.active to
887 * true, as the next composition frame will implicitly activate
888 * the display
889 */
890 return HWC2::Error::None;
Sean Paulac874152016-03-10 16:00:26 -0500891 break;
Vincent Donnefort60ef7eb2019-10-09 11:39:28 +0100892 case HWC2::PowerMode::Doze:
893 case HWC2::PowerMode::DozeSuspend:
894 return HWC2::Error::Unsupported;
Sean Paulac874152016-03-10 16:00:26 -0500895 default:
896 ALOGI("Power mode %d is unsupported\n", mode);
Vincent Donnefort60ef7eb2019-10-09 11:39:28 +0100897 return HWC2::Error::BadParameter;
Sean Paulac874152016-03-10 16:00:26 -0500898 };
899
Roman Stratiienkodccc6fb2021-10-23 17:35:44 +0300900 int err = compositor_.ExecuteAtomicCommit(a_args);
901 if (err) {
902 ALOGE("Failed to apply the dpms composition err=%d", err);
Sean Paulac874152016-03-10 16:00:26 -0500903 return HWC2::Error::BadParameter;
904 }
905 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500906}
907
908HWC2::Error DrmHwcTwo::HwcDisplay::SetVsyncEnabled(int32_t enabled) {
Andrii Chepurnyi4bdd0fe2018-07-27 15:14:37 +0300909 vsync_worker_.VSyncControl(HWC2_VSYNC_ENABLE == enabled);
Sean Paulac874152016-03-10 16:00:26 -0500910 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500911}
912
913HWC2::Error DrmHwcTwo::HwcDisplay::ValidateDisplay(uint32_t *num_types,
Sean Paulac874152016-03-10 16:00:26 -0500914 uint32_t *num_requests) {
Matvii Zorinef3c7972020-08-11 15:15:44 +0300915 return backend_->ValidateDisplay(this, num_types, num_requests);
Sean Pauled2ec4b2016-03-10 15:35:40 -0500916}
917
Matvii Zorined90ef92021-01-29 18:32:06 +0200918std::vector<DrmHwcTwo::HwcLayer *>
919DrmHwcTwo::HwcDisplay::GetOrderLayersByZPos() {
920 std::vector<DrmHwcTwo::HwcLayer *> ordered_layers;
921 ordered_layers.reserve(layers_.size());
922
923 for (auto &[handle, layer] : layers_) {
924 ordered_layers.emplace_back(&layer);
925 }
926
927 std::sort(std::begin(ordered_layers), std::end(ordered_layers),
928 [](const DrmHwcTwo::HwcLayer *lhs, const DrmHwcTwo::HwcLayer *rhs) {
929 return lhs->z_order() < rhs->z_order();
930 });
931
932 return ordered_layers;
933}
934
Roman Stratiienko6f5df172020-09-27 22:48:08 +0300935#if PLATFORM_SDK_VERSION > 29
936HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayConnectionType(uint32_t *outType) {
937 if (connector_->internal())
938 *outType = static_cast<uint32_t>(HWC2::DisplayConnectionType::Internal);
939 else if (connector_->external())
940 *outType = static_cast<uint32_t>(HWC2::DisplayConnectionType::External);
941 else
942 return HWC2::Error::BadConfig;
943
944 return HWC2::Error::None;
945}
946
947HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayVsyncPeriod(
948 hwc2_vsync_period_t *outVsyncPeriod /* ns */) {
Roman Stratiienkoa148f212021-11-16 18:23:18 +0200949 return GetDisplayAttribute(active_config_id_, HWC2_ATTRIBUTE_VSYNC_PERIOD,
950 (int32_t *)(outVsyncPeriod));
Roman Stratiienko6f5df172020-09-27 22:48:08 +0300951}
952
953HWC2::Error DrmHwcTwo::HwcDisplay::SetActiveConfigWithConstraints(
954 hwc2_config_t /*config*/,
955 hwc_vsync_period_change_constraints_t *vsyncPeriodChangeConstraints,
956 hwc_vsync_period_change_timeline_t *outTimeline) {
Roman Stratiienko6f5df172020-09-27 22:48:08 +0300957 if (vsyncPeriodChangeConstraints == nullptr || outTimeline == nullptr) {
958 return HWC2::Error::BadParameter;
959 }
960
961 return HWC2::Error::BadConfig;
962}
963
964HWC2::Error DrmHwcTwo::HwcDisplay::SetAutoLowLatencyMode(bool /*on*/) {
965 return HWC2::Error::Unsupported;
966}
967
968HWC2::Error DrmHwcTwo::HwcDisplay::GetSupportedContentTypes(
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +0200969 uint32_t *outNumSupportedContentTypes,
970 const uint32_t *outSupportedContentTypes) {
Roman Stratiienko6f5df172020-09-27 22:48:08 +0300971 if (outSupportedContentTypes == nullptr)
972 *outNumSupportedContentTypes = 0;
973
974 return HWC2::Error::None;
975}
976
977HWC2::Error DrmHwcTwo::HwcDisplay::SetContentType(int32_t contentType) {
Roman Stratiienko6f5df172020-09-27 22:48:08 +0300978 if (contentType != HWC2_CONTENT_TYPE_NONE)
979 return HWC2::Error::Unsupported;
980
981 /* TODO: Map to the DRM Connector property:
982 * https://elixir.bootlin.com/linux/v5.4-rc5/source/drivers/gpu/drm/drm_connector.c#L809
983 */
984
985 return HWC2::Error::None;
986}
987#endif
988
John Stultz8c7229d2020-02-07 21:31:08 +0000989#if PLATFORM_SDK_VERSION > 28
Lowry Li (Arm Technology China)b3d81782019-12-18 14:28:22 +0800990HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayIdentificationData(
991 uint8_t *outPort, uint32_t *outDataSize, uint8_t *outData) {
Roman Stratiienko3e8ce572021-09-29 12:46:28 +0300992 auto blob = connector_->GetEdidBlob();
Lowry Li (Arm Technology China)b3d81782019-12-18 14:28:22 +0800993
Roman Stratiienko3e8ce572021-09-29 12:46:28 +0300994 if (!blob) {
Lowry Li (Arm Technology China)b3d81782019-12-18 14:28:22 +0800995 ALOGE("Failed to get edid property value.");
996 return HWC2::Error::Unsupported;
997 }
998
Andrii Chepurnyi8115dbe2020-04-14 13:03:57 +0300999 if (outData) {
1000 *outDataSize = std::min(*outDataSize, blob->length);
1001 memcpy(outData, blob->data, *outDataSize);
1002 } else {
1003 *outDataSize = blob->length;
1004 }
Lowry Li (Arm Technology China)b3d81782019-12-18 14:28:22 +08001005 *outPort = connector_->id();
Lowry Li (Arm Technology China)b3d81782019-12-18 14:28:22 +08001006
1007 return HWC2::Error::None;
1008}
1009
1010HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayCapabilities(
Roman Stratiienko7f576ec2021-12-22 17:34:18 +02001011 uint32_t *outNumCapabilities, uint32_t * /*outCapabilities*/) {
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +02001012 if (outNumCapabilities == nullptr) {
Lowry Li (Arm Technology China)b3d81782019-12-18 14:28:22 +08001013 return HWC2::Error::BadParameter;
1014 }
1015
1016 *outNumCapabilities = 0;
1017
1018 return HWC2::Error::None;
1019}
Andrii Chepurnyi2619aab2020-07-03 11:21:33 +03001020
1021HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayBrightnessSupport(
1022 bool *supported) {
1023 *supported = false;
1024 return HWC2::Error::None;
1025}
1026
1027HWC2::Error DrmHwcTwo::HwcDisplay::SetDisplayBrightness(
1028 float /* brightness */) {
1029 return HWC2::Error::Unsupported;
1030}
1031
John Stultz8c7229d2020-02-07 21:31:08 +00001032#endif /* PLATFORM_SDK_VERSION > 28 */
Lowry Li (Arm Technology China)b3d81782019-12-18 14:28:22 +08001033
Andrii Chepurnyi50d37452020-04-24 14:20:24 +03001034#if PLATFORM_SDK_VERSION > 27
1035
1036HWC2::Error DrmHwcTwo::HwcDisplay::GetRenderIntents(
1037 int32_t mode, uint32_t *outNumIntents,
1038 int32_t * /*android_render_intent_v1_1_t*/ outIntents) {
1039 if (mode != HAL_COLOR_MODE_NATIVE) {
1040 return HWC2::Error::BadParameter;
1041 }
1042
1043 if (outIntents == nullptr) {
1044 *outNumIntents = 1;
1045 return HWC2::Error::None;
1046 }
1047 *outNumIntents = 1;
1048 outIntents[0] = HAL_RENDER_INTENT_COLORIMETRIC;
1049 return HWC2::Error::None;
1050}
1051
Andrii Chepurnyi857a53f2020-04-29 23:15:28 +03001052HWC2::Error DrmHwcTwo::HwcDisplay::SetColorModeWithIntent(int32_t mode,
1053 int32_t intent) {
Roman Stratiienko27d2ed62020-09-26 23:59:19 +03001054 if (intent < HAL_RENDER_INTENT_COLORIMETRIC ||
1055 intent > HAL_RENDER_INTENT_TONE_MAP_ENHANCE)
1056 return HWC2::Error::BadParameter;
1057
1058 if (mode < HAL_COLOR_MODE_NATIVE || mode > HAL_COLOR_MODE_BT2100_HLG)
1059 return HWC2::Error::BadParameter;
1060
Andrii Chepurnyi857a53f2020-04-29 23:15:28 +03001061 if (mode != HAL_COLOR_MODE_NATIVE)
Roman Stratiienko27d2ed62020-09-26 23:59:19 +03001062 return HWC2::Error::Unsupported;
1063
Andrii Chepurnyi857a53f2020-04-29 23:15:28 +03001064 if (intent != HAL_RENDER_INTENT_COLORIMETRIC)
Roman Stratiienko27d2ed62020-09-26 23:59:19 +03001065 return HWC2::Error::Unsupported;
1066
Andrii Chepurnyi857a53f2020-04-29 23:15:28 +03001067 color_mode_ = mode;
1068 return HWC2::Error::None;
1069}
1070
Andrii Chepurnyi50d37452020-04-24 14:20:24 +03001071#endif /* PLATFORM_SDK_VERSION > 27 */
1072
Roman Stratiienko24a7fc42021-12-23 16:25:20 +02001073const Backend *DrmHwcTwo::HwcDisplay::backend() const {
1074 return backend_.get();
1075}
1076
1077void DrmHwcTwo::HwcDisplay::set_backend(std::unique_ptr<Backend> backend) {
1078 backend_ = std::move(backend);
1079}
1080
Roman Stratiienkoaaaa4692021-09-29 12:50:10 +03001081HWC2::Error DrmHwcTwo::HwcLayer::SetCursorPosition(int32_t /*x*/,
1082 int32_t /*y*/) {
Kalyan Kondapallyda5839c2016-11-10 10:59:50 -08001083 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -05001084}
1085
1086HWC2::Error DrmHwcTwo::HwcLayer::SetLayerBlendMode(int32_t mode) {
Roman Stratiienko5063d532021-09-29 12:47:31 +03001087 switch (static_cast<HWC2::BlendMode>(mode)) {
1088 case HWC2::BlendMode::None:
1089 blending_ = DrmHwcBlending::kNone;
1090 break;
1091 case HWC2::BlendMode::Premultiplied:
1092 blending_ = DrmHwcBlending::kPreMult;
1093 break;
1094 case HWC2::BlendMode::Coverage:
1095 blending_ = DrmHwcBlending::kCoverage;
1096 break;
1097 default:
1098 ALOGE("Unknown blending mode b=%d", blending_);
1099 blending_ = DrmHwcBlending::kNone;
1100 break;
1101 }
Sean Paulac874152016-03-10 16:00:26 -05001102 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -05001103}
1104
Roman Stratiienko3e2f9e72021-05-21 14:33:28 +03001105/* Find API details at:
1106 * https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:hardware/libhardware/include/hardware/hwcomposer2.h;l=2314
1107 */
Sean Pauled2ec4b2016-03-10 15:35:40 -05001108HWC2::Error DrmHwcTwo::HwcLayer::SetLayerBuffer(buffer_handle_t buffer,
Sean Paulac874152016-03-10 16:00:26 -05001109 int32_t acquire_fence) {
Sean Paulac874152016-03-10 16:00:26 -05001110 set_buffer(buffer);
John Stultz8adf5442021-07-31 00:19:50 +00001111 acquire_fence_ = UniqueFd(acquire_fence);
Sean Paulac874152016-03-10 16:00:26 -05001112 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -05001113}
1114
Roman Stratiienkoaaaa4692021-09-29 12:50:10 +03001115HWC2::Error DrmHwcTwo::HwcLayer::SetLayerColor(hwc_color_t /*color*/) {
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +02001116 // TODO(nobody): Put to client composition here?
Roman Kovalivskyibb375692019-12-11 17:48:44 +02001117 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -05001118}
1119
1120HWC2::Error DrmHwcTwo::HwcLayer::SetLayerCompositionType(int32_t type) {
Sean Paulac874152016-03-10 16:00:26 -05001121 sf_type_ = static_cast<HWC2::Composition>(type);
1122 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -05001123}
1124
1125HWC2::Error DrmHwcTwo::HwcLayer::SetLayerDataspace(int32_t dataspace) {
Roman Stratiienko515da8f2021-09-29 12:47:21 +03001126 switch (dataspace & HAL_DATASPACE_STANDARD_MASK) {
1127 case HAL_DATASPACE_STANDARD_BT709:
1128 color_space_ = DrmHwcColorSpace::kItuRec709;
1129 break;
1130 case HAL_DATASPACE_STANDARD_BT601_625:
1131 case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED:
1132 case HAL_DATASPACE_STANDARD_BT601_525:
1133 case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED:
1134 color_space_ = DrmHwcColorSpace::kItuRec601;
1135 break;
1136 case HAL_DATASPACE_STANDARD_BT2020:
1137 case HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE:
1138 color_space_ = DrmHwcColorSpace::kItuRec2020;
1139 break;
1140 default:
1141 color_space_ = DrmHwcColorSpace::kUndefined;
1142 }
1143
1144 switch (dataspace & HAL_DATASPACE_RANGE_MASK) {
1145 case HAL_DATASPACE_RANGE_FULL:
1146 sample_range_ = DrmHwcSampleRange::kFullRange;
1147 break;
1148 case HAL_DATASPACE_RANGE_LIMITED:
1149 sample_range_ = DrmHwcSampleRange::kLimitedRange;
1150 break;
1151 default:
1152 sample_range_ = DrmHwcSampleRange::kUndefined;
1153 }
Sean Paulac874152016-03-10 16:00:26 -05001154 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -05001155}
1156
1157HWC2::Error DrmHwcTwo::HwcLayer::SetLayerDisplayFrame(hwc_rect_t frame) {
Sean Paulac874152016-03-10 16:00:26 -05001158 display_frame_ = frame;
1159 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -05001160}
1161
1162HWC2::Error DrmHwcTwo::HwcLayer::SetLayerPlaneAlpha(float alpha) {
Sean Paulac874152016-03-10 16:00:26 -05001163 alpha_ = alpha;
1164 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -05001165}
1166
1167HWC2::Error DrmHwcTwo::HwcLayer::SetLayerSidebandStream(
Roman Stratiienko7f576ec2021-12-22 17:34:18 +02001168 const native_handle_t * /*stream*/) {
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +02001169 // TODO(nobody): We don't support sideband
Roman Stratiienko7f576ec2021-12-22 17:34:18 +02001170 return HWC2::Error::Unsupported;
1171 ;
Sean Pauled2ec4b2016-03-10 15:35:40 -05001172}
1173
1174HWC2::Error DrmHwcTwo::HwcLayer::SetLayerSourceCrop(hwc_frect_t crop) {
Sean Paulac874152016-03-10 16:00:26 -05001175 source_crop_ = crop;
1176 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -05001177}
1178
Roman Stratiienko7f576ec2021-12-22 17:34:18 +02001179HWC2::Error DrmHwcTwo::HwcLayer::SetLayerSurfaceDamage(
1180 hwc_region_t /*damage*/) {
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +02001181 // TODO(nobody): We don't use surface damage, marking as unsupported
Sean Paulac874152016-03-10 16:00:26 -05001182 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -05001183}
1184
1185HWC2::Error DrmHwcTwo::HwcLayer::SetLayerTransform(int32_t transform) {
Roman Stratiienko2ed4cbe2021-09-29 12:47:35 +03001186 uint32_t l_transform = 0;
1187
1188 // 270* and 180* cannot be combined with flips. More specifically, they
1189 // already contain both horizontal and vertical flips, so those fields are
1190 // redundant in this case. 90* rotation can be combined with either horizontal
1191 // flip or vertical flip, so treat it differently
1192 if (transform == HWC_TRANSFORM_ROT_270) {
1193 l_transform = DrmHwcTransform::kRotate270;
1194 } else if (transform == HWC_TRANSFORM_ROT_180) {
1195 l_transform = DrmHwcTransform::kRotate180;
1196 } else {
1197 if (transform & HWC_TRANSFORM_FLIP_H)
1198 l_transform |= DrmHwcTransform::kFlipH;
1199 if (transform & HWC_TRANSFORM_FLIP_V)
1200 l_transform |= DrmHwcTransform::kFlipV;
1201 if (transform & HWC_TRANSFORM_ROT_90)
1202 l_transform |= DrmHwcTransform::kRotate90;
1203 }
1204
1205 transform_ = static_cast<DrmHwcTransform>(l_transform);
Sean Paulac874152016-03-10 16:00:26 -05001206 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -05001207}
1208
Roman Stratiienko7f576ec2021-12-22 17:34:18 +02001209HWC2::Error DrmHwcTwo::HwcLayer::SetLayerVisibleRegion(
1210 hwc_region_t /*visible*/) {
Roman Stratiienkoe2f2c922021-02-13 10:57:47 +02001211 // TODO(nobody): We don't use this information, marking as unsupported
Sean Paulac874152016-03-10 16:00:26 -05001212 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -05001213}
1214
Sean Paulac874152016-03-10 16:00:26 -05001215HWC2::Error DrmHwcTwo::HwcLayer::SetLayerZOrder(uint32_t order) {
Sean Paulac874152016-03-10 16:00:26 -05001216 z_order_ = order;
1217 return HWC2::Error::None;
1218}
1219
1220void DrmHwcTwo::HwcLayer::PopulateDrmLayer(DrmHwcLayer *layer) {
Sean Paulac874152016-03-10 16:00:26 -05001221 layer->sf_handle = buffer_;
Roman Stratiienko0fade372021-02-20 13:59:55 +02001222 // TODO(rsglobal): Avoid extra fd duplication
1223 layer->acquire_fence = UniqueFd(fcntl(acquire_fence_.Get(), F_DUPFD_CLOEXEC));
Roman Kovalivskyib8652272021-01-24 20:32:37 +02001224 layer->display_frame = display_frame_;
Roman Stratiienkoe78235c2021-12-23 17:36:12 +02001225 layer->alpha = std::lround(65535.0F * alpha_);
Roman Stratiienko5063d532021-09-29 12:47:31 +03001226 layer->blending = blending_;
Roman Kovalivskyib8652272021-01-24 20:32:37 +02001227 layer->source_crop = source_crop_;
Roman Stratiienko2ed4cbe2021-09-29 12:47:35 +03001228 layer->transform = transform_;
Roman Stratiienko515da8f2021-09-29 12:47:21 +03001229 layer->color_space = color_space_;
1230 layer->sample_range = sample_range_;
Sean Pauled2ec4b2016-03-10 15:35:40 -05001231}
1232
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +03001233void DrmHwcTwo::HandleDisplayHotplug(hwc2_display_t displayid, int state) {
Roman Stratiienko863a3c22021-09-29 13:00:29 +03001234 const std::lock_guard<std::mutex> lock(callback_lock_);
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +03001235
Roman Stratiienko863a3c22021-09-29 13:00:29 +03001236 if (hotplug_callback_.first != nullptr &&
1237 hotplug_callback_.second != nullptr) {
1238 hotplug_callback_.first(hotplug_callback_.second, displayid,
1239 state == DRM_MODE_CONNECTED
1240 ? HWC2_CONNECTION_CONNECTED
1241 : HWC2_CONNECTION_DISCONNECTED);
1242 }
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +03001243}
1244
1245void DrmHwcTwo::HandleInitialHotplugState(DrmDevice *drmDevice) {
Roman Stratiienkod21071f2021-03-09 21:56:50 +02001246 for (const auto &conn : drmDevice->connectors()) {
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +03001247 if (conn->state() != DRM_MODE_CONNECTED)
1248 continue;
1249 HandleDisplayHotplug(conn->display(), conn->state());
1250 }
1251}
1252
Roman Stratiienko1e053b42021-10-25 22:54:20 +03001253void DrmHwcTwo::HandleHotplugUEvent() {
Roman Stratiienkofc014f52021-12-23 19:04:29 +02001254 for (const auto &drm : resource_manager_.GetDrmDevices()) {
Roman Stratiienko1e053b42021-10-25 22:54:20 +03001255 for (const auto &conn : drm->connectors()) {
1256 drmModeConnection old_state = conn->state();
1257 drmModeConnection cur_state = conn->UpdateModes()
1258 ? DRM_MODE_UNKNOWNCONNECTION
1259 : conn->state();
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +03001260
Roman Stratiienko1e053b42021-10-25 22:54:20 +03001261 if (cur_state == old_state)
1262 continue;
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +03001263
Roman Stratiienko1e053b42021-10-25 22:54:20 +03001264 ALOGI("%s event for connector %u on display %d",
1265 cur_state == DRM_MODE_CONNECTED ? "Plug" : "Unplug", conn->id(),
1266 conn->display());
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +03001267
Roman Stratiienko1e053b42021-10-25 22:54:20 +03001268 int display_id = conn->display();
1269 if (cur_state == DRM_MODE_CONNECTED) {
1270 auto &display = displays_.at(display_id);
1271 display.ChosePreferredConfig();
1272 } else {
1273 auto &display = displays_.at(display_id);
1274 display.ClearDisplay();
1275 }
1276
1277 HandleDisplayHotplug(display_id, cur_state);
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +03001278 }
Andrii Chepurnyi495e4cc2018-08-01 17:42:56 +03001279 }
1280}
1281
Sean Paulf72cccd2018-08-27 13:59:08 -04001282} // namespace android