blob: 04cbbf1ca9bb65f9f08f536f065440916145405c [file] [log] [blame]
Dennis Tsiang33f0ece2023-11-29 12:45:04 +00001/*
Drew Davenport5951b112024-08-05 09:44:27 -06002 * Copyright (C) 2024 The Android Open Source Project
Dennis Tsiang33f0ece2023-11-29 12:45:04 +00003 *
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
Drew Davenport5951b112024-08-05 09:44:27 -060017#define LOG_TAG "drmhwc"
Dennis Tsiang33f0ece2023-11-29 12:45:04 +000018#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
19
20#include "ComposerClient.h"
21
Drew Davenport5951b112024-08-05 09:44:27 -060022#include <aidlcommonsupport/NativeHandle.h>
Dennis Tsiang33f0ece2023-11-29 12:45:04 +000023#include <android-base/logging.h>
24#include <android/binder_ibinder_platform.h>
Drew Davenport5951b112024-08-05 09:44:27 -060025#include <hardware/hwcomposer2.h>
26
27#include <cinttypes>
Dennis Tsiang1a966202024-01-24 12:46:33 +000028#include <cmath>
Drew Davenport5951b112024-08-05 09:44:27 -060029#include <memory>
30#include <unordered_map>
31#include <vector>
32
33#include "aidl/android/hardware/graphics/common/Transform.h"
34#include "aidl/android/hardware/graphics/composer3/ClientTarget.h"
35#include "aidl/android/hardware/graphics/composer3/Composition.h"
36#include "aidl/android/hardware/graphics/composer3/DisplayRequest.h"
37#include "aidl/android/hardware/graphics/composer3/IComposerClient.h"
38#include "aidl/android/hardware/graphics/composer3/PowerMode.h"
39#include "aidl/android/hardware/graphics/composer3/PresentOrValidate.h"
40#include "aidl/android/hardware/graphics/composer3/RenderIntent.h"
41#include "android/binder_auto_utils.h"
42#include "cutils/native_handle.h"
43#include "hardware/hwcomposer_defs.h"
44#include "hwc2_device/HwcDisplay.h"
Drew Davenportf7e88332024-09-06 12:54:38 -060045#include "hwc2_device/HwcDisplayConfigs.h"
Drew Davenport5951b112024-08-05 09:44:27 -060046#include "hwc2_device/HwcLayer.h"
47#include "hwc3/DrmHwcThree.h"
48#include "hwc3/Utils.h"
49
50using ::android::HwcDisplay;
Drew Davenportf7e88332024-09-06 12:54:38 -060051using ::android::HwcDisplayConfigs;
Dennis Tsiang33f0ece2023-11-29 12:45:04 +000052
53#include "utils/log.h"
54
55namespace aidl::android::hardware::graphics::composer3::impl {
Drew Davenport5951b112024-08-05 09:44:27 -060056namespace {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +000057
Drew Davenport5951b112024-08-05 09:44:27 -060058// clang-format off
59constexpr std::array<float, 16> kIdentityMatrix = {
60 1.0F, 0.0F, 0.0F, 0.0F,
61 0.0F, 1.0F, 0.0F, 0.0F,
62 0.0F, 0.0F, 1.0F, 0.0F,
63 0.0F, 0.0F, 0.0F, 1.0F,
64};
65// clang-format on
Dennis Tsiang33f0ece2023-11-29 12:45:04 +000066
Drew Davenport5951b112024-08-05 09:44:27 -060067} // namespace
68
69ComposerClient::ComposerClient() {
70 DEBUG_FUNC();
71}
72
73bool ComposerClient::Init() {
74 DEBUG_FUNC();
75 composer_resources_ = ComposerResources::Create();
76 if (composer_resources_) {
77 hwc_ = std::make_unique<DrmHwcThree>(composer_resources_.get());
78 }
79 return composer_resources_ != nullptr;
80}
81
Dennis Tsiang33f0ece2023-11-29 12:45:04 +000082ComposerClient::~ComposerClient() {
83 DEBUG_FUNC();
Drew Davenport1ac3b622024-09-05 10:59:16 -060084 {
85 // First Deinit the displays to start shutting down the Display's dependent
86 // threads such as VSyncWorker.
87 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
88 hwc_->DeinitDisplays();
89 }
90 // Sleep to wait for threads to complete and exit.
91 const int time_for_threads_to_exit_us = 200000;
92 usleep(time_for_threads_to_exit_us);
93 {
94 // Hold the lock while destructing the hwc_ and the objects that it owns.
95 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
96 hwc_.reset();
97 }
Dennis Tsiang33f0ece2023-11-29 12:45:04 +000098 LOG(DEBUG) << "removed composer client";
99}
100
Drew Davenport5951b112024-08-05 09:44:27 -0600101ndk::ScopedAStatus ComposerClient::createLayer(int64_t display_id,
102 int32_t buffer_slot_count,
103 int64_t* layer_id) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000104 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600105 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
106
107 HwcDisplay* display = GetDisplay(display_id);
108 if (display == nullptr) {
109 return ToBinderStatus(hwc3::Error::kBadDisplay);
110 }
111
112 hwc2_layer_t hwc2_layer_id = 0;
113 auto err = Hwc2toHwc3Error(display->CreateLayer(&hwc2_layer_id));
114 if (err != hwc3::Error::kNone) {
115 return ToBinderStatus(err);
116 }
117
118 const int64_t created_layer_id = Hwc2LayerToHwc3(hwc2_layer_id);
119 err = composer_resources_->AddLayer(display_id, created_layer_id,
120 buffer_slot_count);
121 if (err != hwc3::Error::kNone) {
122 destroyLayer(display_id, created_layer_id);
123 return ToBinderStatus(err);
124 }
125
126 *layer_id = created_layer_id;
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000127 return ndk::ScopedAStatus::ok();
128}
129
130ndk::ScopedAStatus ComposerClient::createVirtualDisplay(
Drew Davenport5951b112024-08-05 09:44:27 -0600131 int32_t width, int32_t height, AidlPixelFormat format_hint,
132 int32_t output_buffer_slot_count, VirtualDisplay* out_display) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000133 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600134 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
135
136 hwc2_display_t hwc2_display_id = 0;
137 // TODO: Format is currently not used in drm_hwcomposer.
138 int32_t hwc2_format = 0;
139 auto err = Hwc2toHwc3Error(hwc_->CreateVirtualDisplay(width, height,
140 &hwc2_format,
141 &hwc2_display_id));
142 if (err != hwc3::Error::kNone) {
143 return ToBinderStatus(err);
144 }
145
146 const int64_t created_display_id = Hwc2DisplayToHwc3(hwc2_display_id);
147 err = composer_resources_->AddVirtualDisplay(hwc2_display_id,
148 output_buffer_slot_count);
149 if (err != hwc3::Error::kNone) {
150 hwc_->DestroyVirtualDisplay(hwc2_display_id);
151 return ToBinderStatus(err);
152 }
153
154 out_display->display = created_display_id;
155 out_display->format = format_hint;
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000156 return ndk::ScopedAStatus::ok();
157}
158
Drew Davenport5951b112024-08-05 09:44:27 -0600159ndk::ScopedAStatus ComposerClient::destroyLayer(int64_t display_id,
160 int64_t layer_id) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000161 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600162 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
163 HwcDisplay* display = GetDisplay(display_id);
164 if (display == nullptr) {
165 return ToBinderStatus(hwc3::Error::kBadDisplay);
166 }
167
168 auto err = Hwc2toHwc3Error(display->DestroyLayer(Hwc3LayerToHwc2(layer_id)));
169 if (err != hwc3::Error::kNone) {
170 return ToBinderStatus(err);
171 }
172
173 err = composer_resources_->RemoveLayer(display_id, layer_id);
174 return ToBinderStatus(err);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000175}
176
Drew Davenport5951b112024-08-05 09:44:27 -0600177ndk::ScopedAStatus ComposerClient::destroyVirtualDisplay(int64_t display_id) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000178 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600179 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
180 auto err = Hwc2toHwc3Error(hwc_->DestroyVirtualDisplay(display_id));
181 return ToBinderStatus(err);
182}
183
184hwc3::Error ComposerClient::ValidateDisplayInternal(
185 HwcDisplay& display, std::vector<int64_t>* out_changed_layers,
186 std::vector<Composition>* out_composition_types,
187 int32_t* out_display_request_mask,
188 std::vector<int64_t>* out_requested_layers,
189 std::vector<int32_t>* out_request_masks,
190 ClientTargetProperty* /*out_client_target_property*/,
191 DimmingStage* /*out_dimming_stage*/) {
192 DEBUG_FUNC();
193
194 uint32_t num_types = 0;
195 uint32_t num_requests = 0;
196 const HWC2::Error hwc2_error = display.ValidateDisplay(&num_types,
197 &num_requests);
198
199 /* Check if display has pending changes and no errors */
200 if (hwc2_error != HWC2::Error::None &&
201 hwc2_error != HWC2::Error::HasChanges) {
202 return Hwc2toHwc3Error(hwc2_error);
203 }
204
Drew Davenport3f4469f2024-10-03 10:01:51 -0600205 hwc3::Error error = Hwc2toHwc3Error(
206 display.GetChangedCompositionTypes(&num_types, nullptr, nullptr));
207 if (error != hwc3::Error::kNone) {
208 return error;
209 }
210
Drew Davenport5951b112024-08-05 09:44:27 -0600211 std::vector<hwc2_layer_t> hwc_changed_layers(num_types);
212 std::vector<int32_t> hwc_composition_types(num_types);
Drew Davenport3f4469f2024-10-03 10:01:51 -0600213 error = Hwc2toHwc3Error(
Drew Davenport5951b112024-08-05 09:44:27 -0600214 display.GetChangedCompositionTypes(&num_types, hwc_changed_layers.data(),
215 hwc_composition_types.data()));
216 if (error != hwc3::Error::kNone) {
217 return error;
218 }
219
220 int32_t display_reqs = 0;
221 out_request_masks->resize(num_requests);
222 std::vector<hwc2_layer_t> hwc_requested_layers(num_requests);
223 error = Hwc2toHwc3Error(
224 display.GetDisplayRequests(&display_reqs, &num_requests,
225 hwc_requested_layers.data(),
226 out_request_masks->data()));
227 if (error != hwc3::Error::kNone) {
228 return error;
229 }
230
231 for (const auto& layer : hwc_changed_layers) {
232 out_changed_layers->emplace_back(Hwc2LayerToHwc3(layer));
233 }
234 for (const auto& type : hwc_composition_types) {
235 out_composition_types->emplace_back(Hwc2CompositionTypeToHwc3(type));
236 }
237 for (const auto& layer : hwc_requested_layers) {
238 out_requested_layers->emplace_back(Hwc2LayerToHwc3(layer));
239 }
240 *out_display_request_mask = display_reqs;
241
242 /* Client target property/dimming stage unsupported */
243 return hwc3::Error::kNone;
244}
245
246hwc3::Error ComposerClient::PresentDisplayInternal(
247 uint64_t display_id, ::android::base::unique_fd& out_display_fence,
248 std::unordered_map<int64_t, ::android::base::unique_fd>&
249 out_release_fences) {
250 DEBUG_FUNC();
251 auto* display = GetDisplay(display_id);
252 if (display == nullptr) {
253 return hwc3::Error::kBadDisplay;
254 }
255
256 if (composer_resources_->MustValidateDisplay(display_id)) {
257 return hwc3::Error::kNotValidated;
258 }
259
260 int32_t present_fence = -1;
261 auto error = Hwc2toHwc3Error(display->PresentDisplay(&present_fence));
262 if (error != hwc3::Error::kNone) {
263 return error;
264 }
265 out_display_fence.reset(present_fence);
266
267 uint32_t release_fence_count = 0;
268 error = Hwc2toHwc3Error(
269 display->GetReleaseFences(&release_fence_count, nullptr, nullptr));
270 if (error != hwc3::Error::kNone) {
271 return error;
272 }
273
274 std::vector<hwc2_layer_t> hwc_layers(release_fence_count);
275 std::vector<int32_t> hwc_fences(release_fence_count);
276 error = Hwc2toHwc3Error(display->GetReleaseFences(&release_fence_count,
277 hwc_layers.data(),
278 hwc_fences.data()));
279 if (error != hwc3::Error::kNone) {
280 return error;
281 }
282
283 for (size_t i = 0; i < hwc_layers.size(); i++) {
284 auto layer = Hwc2LayerToHwc3(hwc_layers[i]);
285 out_release_fences[layer] = ::android::base::unique_fd{hwc_fences[i]};
286 }
287
288 return hwc3::Error::kNone;
289}
290
291::android::HwcDisplay* ComposerClient::GetDisplay(uint64_t display_id) {
292 return hwc_->GetDisplay(display_id);
293}
294
295void ComposerClient::DispatchLayerCommand(int64_t display_id,
296 const LayerCommand& command) {
297 auto* display = GetDisplay(display_id);
298 if (display == nullptr) {
299 cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
300 return;
301 }
302
303 auto* layer = display->get_layer(command.layer);
304 if (layer == nullptr) {
305 cmd_result_writer_->AddError(hwc3::Error::kBadLayer);
306 return;
307 }
308
309 HwcLayerWrapper layer_wrapper{command.layer, layer};
310 if (command.buffer) {
311 ExecuteSetLayerBuffer(display_id, layer_wrapper, *command.buffer);
312 }
313 if (command.blendMode) {
314 ExecuteSetLayerBlendMode(display_id, layer_wrapper, *command.blendMode);
315 }
316 if (command.composition) {
317 ExecuteSetLayerComposition(display_id, layer_wrapper, *command.composition);
318 }
319 if (command.dataspace) {
320 ExecuteSetLayerDataspace(display_id, layer_wrapper, *command.dataspace);
321 }
322 if (command.displayFrame) {
323 ExecuteSetLayerDisplayFrame(display_id, layer_wrapper,
324 *command.displayFrame);
325 }
326 if (command.planeAlpha) {
327 ExecuteSetLayerPlaneAlpha(display_id, layer_wrapper, *command.planeAlpha);
328 }
329 if (command.sourceCrop) {
330 ExecuteSetLayerSourceCrop(display_id, layer_wrapper, *command.sourceCrop);
331 }
332 if (command.transform) {
333 ExecuteSetLayerTransform(display_id, layer_wrapper, *command.transform);
334 }
335 if (command.z) {
336 ExecuteSetLayerZOrder(display_id, layer_wrapper, *command.z);
337 }
338 if (command.brightness) {
339 ExecuteSetLayerBrightness(display_id, layer_wrapper, *command.brightness);
340 }
Jason Macnak3dc274e2024-09-19 09:29:55 -0700341 if (command.luts) {
342 ExecuteLayerCommandSetLayerLuts(display_id, layer_wrapper, *command.luts);
343 }
Drew Davenport5951b112024-08-05 09:44:27 -0600344
345 // Some unsupported functionality returns kUnsupported, and others
346 // are just a no-op.
347 // TODO: Audit whether some of these should actually return kUnsupported
348 // instead.
349 if (command.sidebandStream) {
350 cmd_result_writer_->AddError(hwc3::Error::kUnsupported);
351 }
352 // TODO: Blocking region handling missing.
353 // TODO: Layer surface damage.
354 // TODO: Layer visible region.
355 // TODO: Per-frame metadata.
356 // TODO: Layer color transform.
357 // TODO: Layer cursor position.
358 // TODO: Layer color.
359}
360
361void ComposerClient::ExecuteDisplayCommand(const DisplayCommand& command) {
362 const int64_t display_id = command.display;
363 if (hwc_->GetDisplay(display_id) == nullptr) {
364 cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
365 return;
366 }
367
368 for (const auto& layer_cmd : command.layers) {
369 DispatchLayerCommand(command.display, layer_cmd);
370 }
371
372 if (command.brightness) {
373 ExecuteSetDisplayBrightness(command.display, *command.brightness);
374 }
375 if (command.colorTransformMatrix) {
376 ExecuteSetDisplayColorTransform(command.display,
377 *command.colorTransformMatrix);
378 }
379 if (command.clientTarget) {
380 ExecuteSetDisplayClientTarget(command.display, *command.clientTarget);
381 }
382 if (command.virtualDisplayOutputBuffer) {
383 ExecuteSetDisplayOutputBuffer(command.display,
384 *command.virtualDisplayOutputBuffer);
385 }
386 if (command.validateDisplay) {
387 ExecuteValidateDisplay(command.display, command.expectedPresentTime);
388 }
389 if (command.acceptDisplayChanges) {
390 ExecuteAcceptDisplayChanges(command.display);
391 }
392 if (command.presentDisplay) {
393 ExecutePresentDisplay(command.display);
394 }
395 if (command.presentOrValidateDisplay) {
396 ExecutePresentOrValidateDisplay(command.display,
397 command.expectedPresentTime);
398 }
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000399}
400
401ndk::ScopedAStatus ComposerClient::executeCommands(
Drew Davenport5951b112024-08-05 09:44:27 -0600402 const std::vector<DisplayCommand>& commands,
403 std::vector<CommandResultPayload>* results) {
Drew Davenport49965852024-09-05 10:59:40 -0600404 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
405 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600406 cmd_result_writer_ = std::make_unique<CommandResultWriter>(results);
407 for (const auto& cmd : commands) {
408 ExecuteDisplayCommand(cmd);
409 cmd_result_writer_->IncrementCommand();
410 }
411 cmd_result_writer_.reset();
412
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000413 return ndk::ScopedAStatus::ok();
414}
415
Drew Davenport5951b112024-08-05 09:44:27 -0600416ndk::ScopedAStatus ComposerClient::getActiveConfig(int64_t display_id,
417 int32_t* config) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000418 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600419 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
420 HwcDisplay* display = GetDisplay(display_id);
421 if (display == nullptr) {
422 return ToBinderStatus(hwc3::Error::kBadDisplay);
423 }
424
425 uint32_t hwc2_config = 0;
426 const hwc3::Error error = Hwc2toHwc3Error(
427 display->GetActiveConfig(&hwc2_config));
428 if (error != hwc3::Error::kNone) {
429 return ToBinderStatus(error);
430 }
431 *config = Hwc2ConfigIdToHwc3(hwc2_config);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000432 return ndk::ScopedAStatus::ok();
433}
434
435ndk::ScopedAStatus ComposerClient::getColorModes(
Drew Davenport5951b112024-08-05 09:44:27 -0600436 int64_t display_id, std::vector<ColorMode>* color_modes) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000437 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600438 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
439 HwcDisplay* display = GetDisplay(display_id);
440 if (display == nullptr) {
441 return ToBinderStatus(hwc3::Error::kBadDisplay);
442 }
443
444 uint32_t num_modes = 0;
445 auto error = Hwc2toHwc3Error(display->GetColorModes(&num_modes, nullptr));
446 if (error != hwc3::Error::kNone) {
447 return ToBinderStatus(error);
448 }
449
450 std::vector<int32_t> hwc2_color_modes(num_modes);
451 error = Hwc2toHwc3Error(
452 display->GetColorModes(&num_modes, hwc2_color_modes.data()));
453 if (error != hwc3::Error::kNone) {
454 return ToBinderStatus(error);
455 }
456
457 for (const auto& mode : hwc2_color_modes) {
458 color_modes->push_back(Hwc2ColorModeToHwc3(mode));
459 }
460
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000461 return ndk::ScopedAStatus::ok();
462}
463
464ndk::ScopedAStatus ComposerClient::getDataspaceSaturationMatrix(
Drew Davenport5951b112024-08-05 09:44:27 -0600465 common::Dataspace dataspace, std::vector<float>* matrix) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000466 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600467 if (dataspace != common::Dataspace::SRGB_LINEAR) {
468 return ToBinderStatus(hwc3::Error::kBadParameter);
469 }
470
471 matrix->clear();
472 matrix->insert(matrix->begin(), kIdentityMatrix.begin(),
473 kIdentityMatrix.end());
474
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000475 return ndk::ScopedAStatus::ok();
476}
477
478ndk::ScopedAStatus ComposerClient::getDisplayAttribute(
Drew Davenport5951b112024-08-05 09:44:27 -0600479 int64_t display_id, int32_t config, DisplayAttribute attribute,
480 int32_t* value) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000481 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600482 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
483 HwcDisplay* display = GetDisplay(display_id);
484 if (display == nullptr) {
485 return ToBinderStatus(hwc3::Error::kBadDisplay);
486 }
487
488 const hwc3::Error error = Hwc2toHwc3Error(
489 display->GetDisplayAttribute(Hwc3ConfigIdToHwc2(config),
490 Hwc3DisplayAttributeToHwc2(attribute),
491 value));
492 return ToBinderStatus(error);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000493}
494
495ndk::ScopedAStatus ComposerClient::getDisplayCapabilities(
Drew Davenport5951b112024-08-05 09:44:27 -0600496 int64_t display_id, std::vector<DisplayCapability>* caps) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000497 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600498 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
499 HwcDisplay* display = GetDisplay(display_id);
500 if (display == nullptr) {
501 return ToBinderStatus(hwc3::Error::kBadDisplay);
502 }
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000503
Drew Davenport5951b112024-08-05 09:44:27 -0600504 uint32_t num_capabilities = 0;
505 hwc3::Error error = Hwc2toHwc3Error(
506 display->GetDisplayCapabilities(&num_capabilities, nullptr));
507 if (error != hwc3::Error::kNone) {
508 return ToBinderStatus(error);
509 }
510
511 std::vector<uint32_t> out_caps(num_capabilities);
512 error = Hwc2toHwc3Error(
513 display->GetDisplayCapabilities(&num_capabilities, out_caps.data()));
514 if (error != hwc3::Error::kNone) {
515 return ToBinderStatus(error);
516 }
517
518 caps->reserve(num_capabilities);
519 for (const auto cap : out_caps) {
520 caps->emplace_back(Hwc2DisplayCapabilityToHwc3(cap));
521 }
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000522 return ndk::ScopedAStatus::ok();
523}
524
525ndk::ScopedAStatus ComposerClient::getDisplayConfigs(
Drew Davenport5951b112024-08-05 09:44:27 -0600526 int64_t display_id, std::vector<int32_t>* configs) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000527 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600528 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
529 HwcDisplay* display = GetDisplay(display_id);
530 if (display == nullptr) {
531 return ToBinderStatus(hwc3::Error::kBadDisplay);
532 }
533
534 uint32_t num_configs = 0;
535 hwc3::Error error = Hwc2toHwc3Error(
Drew Davenportf7e88332024-09-06 12:54:38 -0600536 display->LegacyGetDisplayConfigs(&num_configs, nullptr));
Drew Davenport5951b112024-08-05 09:44:27 -0600537 if (error != hwc3::Error::kNone) {
538 return ToBinderStatus(error);
539 }
540
541 std::vector<hwc2_config_t> out_configs(num_configs);
542 error = Hwc2toHwc3Error(
Drew Davenportf7e88332024-09-06 12:54:38 -0600543 display->LegacyGetDisplayConfigs(&num_configs, out_configs.data()));
Drew Davenport5951b112024-08-05 09:44:27 -0600544 if (error != hwc3::Error::kNone) {
545 return ToBinderStatus(error);
546 }
547
548 configs->reserve(num_configs);
549 for (const auto config : out_configs) {
550 configs->emplace_back(Hwc2ConfigIdToHwc3(config));
551 }
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000552 return ndk::ScopedAStatus::ok();
553}
554
555ndk::ScopedAStatus ComposerClient::getDisplayConnectionType(
Drew Davenport5951b112024-08-05 09:44:27 -0600556 int64_t display_id, DisplayConnectionType* type) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000557 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600558 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
559 HwcDisplay* display = GetDisplay(display_id);
560 if (display == nullptr) {
561 return ToBinderStatus(hwc3::Error::kBadDisplay);
562 }
563
564 uint32_t out_type = 0;
565 const hwc3::Error error = Hwc2toHwc3Error(
566 display->GetDisplayConnectionType(&out_type));
567 if (error != hwc3::Error::kNone) {
568 return ToBinderStatus(error);
569 }
570
571 *type = Hwc2DisplayConnectionTypeToHwc3(out_type);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000572 return ndk::ScopedAStatus::ok();
573}
574
575ndk::ScopedAStatus ComposerClient::getDisplayIdentificationData(
Drew Davenport5951b112024-08-05 09:44:27 -0600576 int64_t display_id, DisplayIdentification* id) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000577 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600578 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
579 HwcDisplay* display = GetDisplay(display_id);
580 if (display == nullptr) {
581 return ToBinderStatus(hwc3::Error::kBadDisplay);
582 }
583
584 uint8_t port = 0;
585 uint32_t data_size = 0;
586 hwc3::Error error = Hwc2toHwc3Error(
587 display->GetDisplayIdentificationData(&port, &data_size, nullptr));
588 if (error != hwc3::Error::kNone) {
589 return ToBinderStatus(error);
590 }
591
592 id->data.resize(data_size);
593 error = Hwc2toHwc3Error(
594 display->GetDisplayIdentificationData(&port, &data_size,
595 id->data.data()));
596 if (error != hwc3::Error::kNone) {
597 return ToBinderStatus(error);
598 }
599
600 id->port = static_cast<int8_t>(port);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000601 return ndk::ScopedAStatus::ok();
602}
603
Drew Davenport5951b112024-08-05 09:44:27 -0600604ndk::ScopedAStatus ComposerClient::getDisplayName(int64_t display_id,
605 std::string* name) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000606 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600607 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
608 HwcDisplay* display = GetDisplay(display_id);
609 if (display == nullptr) {
610 return ToBinderStatus(hwc3::Error::kBadDisplay);
611 }
612
613 uint32_t size = 0;
614 auto error = Hwc2toHwc3Error(display->GetDisplayName(&size, nullptr));
615 if (error != hwc3::Error::kNone) {
616 return ToBinderStatus(error);
617 }
618
619 name->resize(size);
620 error = Hwc2toHwc3Error(display->GetDisplayName(&size, name->data()));
621 return ToBinderStatus(error);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000622}
623
624ndk::ScopedAStatus ComposerClient::getDisplayVsyncPeriod(
Drew Davenport5951b112024-08-05 09:44:27 -0600625 int64_t display_id, int32_t* vsync_period) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000626 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600627 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
628 HwcDisplay* display = GetDisplay(display_id);
629 if (display == nullptr) {
630 return ToBinderStatus(hwc3::Error::kBadDisplay);
631 }
632
633 uint32_t hwc2_vsync_period = 0;
634 auto error = Hwc2toHwc3Error(
635 display->GetDisplayVsyncPeriod(&hwc2_vsync_period));
636 if (error != hwc3::Error::kNone) {
637 return ToBinderStatus(error);
638 }
639
640 *vsync_period = static_cast<int32_t>(hwc2_vsync_period);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000641 return ndk::ScopedAStatus::ok();
642}
643
644ndk::ScopedAStatus ComposerClient::getDisplayedContentSample(
Drew Davenport5951b112024-08-05 09:44:27 -0600645 int64_t /*display_id*/, int64_t /*max_frames*/, int64_t /*timestamp*/,
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000646 DisplayContentSample* /*samples*/) {
647 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600648 return ToBinderStatus(hwc3::Error::kUnsupported);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000649}
650
651ndk::ScopedAStatus ComposerClient::getDisplayedContentSamplingAttributes(
Drew Davenport5951b112024-08-05 09:44:27 -0600652 int64_t /*display_id*/, DisplayContentSamplingAttributes* /*attrs*/) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000653 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600654 return ToBinderStatus(hwc3::Error::kUnsupported);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000655}
656
657ndk::ScopedAStatus ComposerClient::getDisplayPhysicalOrientation(
Drew Davenport5951b112024-08-05 09:44:27 -0600658 int64_t display_id, common::Transform* orientation) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000659 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600660 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
661 HwcDisplay* display = GetDisplay(display_id);
662 if (display == nullptr) {
663 return ToBinderStatus(hwc3::Error::kBadDisplay);
664 }
665
666 *orientation = common::Transform::NONE;
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000667 return ndk::ScopedAStatus::ok();
668}
669
Drew Davenport5951b112024-08-05 09:44:27 -0600670ndk::ScopedAStatus ComposerClient::getHdrCapabilities(int64_t display_id,
671 HdrCapabilities* caps) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000672 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600673 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
674 HwcDisplay* display = GetDisplay(display_id);
675 if (display == nullptr) {
676 return ToBinderStatus(hwc3::Error::kBadDisplay);
677 }
678
679 /* No HDR capabilities */
680 caps->types.clear();
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000681 return ndk::ScopedAStatus::ok();
682}
683
Drew Davenport5951b112024-08-05 09:44:27 -0600684ndk::ScopedAStatus ComposerClient::getMaxVirtualDisplayCount(int32_t* count) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000685 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600686 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
687 *count = static_cast<int32_t>(hwc_->GetMaxVirtualDisplayCount());
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000688 return ndk::ScopedAStatus::ok();
689}
690
691ndk::ScopedAStatus ComposerClient::getPerFrameMetadataKeys(
Drew Davenport5951b112024-08-05 09:44:27 -0600692 int64_t /*display_id*/, std::vector<PerFrameMetadataKey>* /*keys*/) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000693 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600694 return ToBinderStatus(hwc3::Error::kUnsupported);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000695}
696
697ndk::ScopedAStatus ComposerClient::getReadbackBufferAttributes(
Drew Davenport5951b112024-08-05 09:44:27 -0600698 int64_t /*display_id*/, ReadbackBufferAttributes* /*attrs*/) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000699 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600700 return ToBinderStatus(hwc3::Error::kUnsupported);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000701}
702
703ndk::ScopedAStatus ComposerClient::getReadbackBufferFence(
Drew Davenport5951b112024-08-05 09:44:27 -0600704 int64_t /*display_id*/, ndk::ScopedFileDescriptor* /*acquireFence*/) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000705 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600706 return ToBinderStatus(hwc3::Error::kUnsupported);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000707}
708
709ndk::ScopedAStatus ComposerClient::getRenderIntents(
Drew Davenport5951b112024-08-05 09:44:27 -0600710 int64_t display_id, ColorMode mode, std::vector<RenderIntent>* intents) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000711 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600712 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
713 HwcDisplay* display = GetDisplay(display_id);
714 if (display == nullptr) {
715 return ToBinderStatus(hwc3::Error::kBadDisplay);
716 }
717
718 const int32_t hwc2_color_mode = Hwc3ColorModeToHwc2(mode);
719 uint32_t out_num_intents = 0;
720 auto error = Hwc2toHwc3Error(
721 display->GetRenderIntents(hwc2_color_mode, &out_num_intents, nullptr));
722 if (error != hwc3::Error::kNone) {
723 return ToBinderStatus(error);
724 }
725
726 std::vector<int32_t> out_intents(out_num_intents);
727 error = Hwc2toHwc3Error(display->GetRenderIntents(hwc2_color_mode,
728 &out_num_intents,
729 out_intents.data()));
730 if (error != hwc3::Error::kNone) {
731 return ToBinderStatus(error);
732 }
733
734 intents->reserve(out_num_intents);
735 for (const auto intent : out_intents) {
736 intents->emplace_back(Hwc2RenderIntentToHwc3(intent));
737 }
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000738 return ndk::ScopedAStatus::ok();
739}
740
741ndk::ScopedAStatus ComposerClient::getSupportedContentTypes(
Drew Davenport5951b112024-08-05 09:44:27 -0600742 int64_t display_id, std::vector<ContentType>* types) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000743 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600744 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
745 HwcDisplay* display = GetDisplay(display_id);
746 if (display == nullptr) {
747 return ToBinderStatus(hwc3::Error::kBadDisplay);
748 }
749
750 uint32_t out_num_supported_types = 0;
751 auto error = Hwc2toHwc3Error(
752 display->GetSupportedContentTypes(&out_num_supported_types, nullptr));
753 if (error != hwc3::Error::kNone) {
754 return ToBinderStatus(error);
755 }
756
757 std::vector<uint32_t> out_supported_types(out_num_supported_types);
758 error = Hwc2toHwc3Error(
759 display->GetSupportedContentTypes(&out_num_supported_types,
760 out_supported_types.data()));
761 if (error != hwc3::Error::kNone) {
762 return ToBinderStatus(error);
763 }
764
765 for (const auto type : out_supported_types) {
766 types->push_back(Hwc2ContentTypeToHwc3(type));
767 }
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000768 return ndk::ScopedAStatus::ok();
769}
770
771ndk::ScopedAStatus ComposerClient::getDisplayDecorationSupport(
Drew Davenport5951b112024-08-05 09:44:27 -0600772 int64_t /*display_id*/,
773 std::optional<common::DisplayDecorationSupport>* /*support_struct*/) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000774 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600775 return ToBinderStatus(hwc3::Error::kUnsupported);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000776}
777
778ndk::ScopedAStatus ComposerClient::registerCallback(
Drew Davenport5951b112024-08-05 09:44:27 -0600779 const std::shared_ptr<IComposerCallback>& callback) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000780 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600781 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
782 // This function is specified to be called exactly once.
783 hwc_->Init(callback);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000784 return ndk::ScopedAStatus::ok();
785}
786
Drew Davenport5951b112024-08-05 09:44:27 -0600787ndk::ScopedAStatus ComposerClient::setActiveConfig(int64_t display_id,
788 int32_t config) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000789 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600790 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
791 HwcDisplay* display = GetDisplay(display_id);
792 if (display == nullptr) {
793 return ToBinderStatus(hwc3::Error::kBadDisplay);
794 }
795
796 return ToBinderStatus(Hwc2toHwc3Error(display->SetActiveConfig(config)));
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000797}
798
799ndk::ScopedAStatus ComposerClient::setActiveConfigWithConstraints(
Drew Davenport5951b112024-08-05 09:44:27 -0600800 int64_t display_id, int32_t config,
801 const VsyncPeriodChangeConstraints& constraints,
802 VsyncPeriodChangeTimeline* timeline) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000803 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600804 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
805 HwcDisplay* display = GetDisplay(display_id);
806 if (display == nullptr) {
807 return ToBinderStatus(hwc3::Error::kBadDisplay);
808 }
809
810 hwc_vsync_period_change_constraints_t hwc2_constraints;
811 hwc2_constraints.desiredTimeNanos = constraints.desiredTimeNanos;
812 hwc2_constraints.seamlessRequired = static_cast<uint8_t>(
813 constraints.seamlessRequired);
814
815 hwc_vsync_period_change_timeline_t hwc2_timeline{};
816 auto error = Hwc2toHwc3Error(
817 display->SetActiveConfigWithConstraints(config, &hwc2_constraints,
818 &hwc2_timeline));
819 if (error != hwc3::Error::kNone) {
820 return ToBinderStatus(error);
821 }
822
823 timeline->refreshTimeNanos = hwc2_timeline.refreshTimeNanos;
824 timeline->newVsyncAppliedTimeNanos = hwc2_timeline.newVsyncAppliedTimeNanos;
825 timeline->refreshRequired = static_cast<bool>(hwc2_timeline.refreshRequired);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000826 return ndk::ScopedAStatus::ok();
827}
828
Drew Davenport5951b112024-08-05 09:44:27 -0600829ndk::ScopedAStatus ComposerClient::setBootDisplayConfig(int64_t /*display_id*/,
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000830 int32_t /*config*/) {
831 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600832 return ToBinderStatus(hwc3::Error::kUnsupported);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000833}
834
Drew Davenport5951b112024-08-05 09:44:27 -0600835ndk::ScopedAStatus ComposerClient::clearBootDisplayConfig(
836 int64_t /*display_id*/) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000837 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600838 return ToBinderStatus(hwc3::Error::kUnsupported);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000839}
840
841ndk::ScopedAStatus ComposerClient::getPreferredBootDisplayConfig(
Drew Davenport5951b112024-08-05 09:44:27 -0600842 int64_t /*display_id*/, int32_t* /*config*/) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000843 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600844 return ToBinderStatus(hwc3::Error::kUnsupported);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000845}
846
Drew Davenport5951b112024-08-05 09:44:27 -0600847ndk::ScopedAStatus ComposerClient::setAutoLowLatencyMode(int64_t display_id,
848 bool on) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000849 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600850 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
851 HwcDisplay* display = GetDisplay(display_id);
852 if (display == nullptr) {
853 return ToBinderStatus(hwc3::Error::kBadDisplay);
854 }
855
856 auto error = Hwc2toHwc3Error(display->SetAutoLowLatencyMode(on));
857 return ToBinderStatus(error);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000858}
859
Drew Davenport5951b112024-08-05 09:44:27 -0600860ndk::ScopedAStatus ComposerClient::setClientTargetSlotCount(int64_t display_id,
861 int32_t count) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000862 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600863 return ToBinderStatus(
864 composer_resources_->SetDisplayClientTargetCacheSize(display_id, count));
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000865}
866
Drew Davenport5951b112024-08-05 09:44:27 -0600867ndk::ScopedAStatus ComposerClient::setColorMode(int64_t display_id,
868 ColorMode mode,
869 RenderIntent intent) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000870 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600871 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
872 HwcDisplay* display = GetDisplay(display_id);
873 if (display == nullptr) {
874 return ToBinderStatus(hwc3::Error::kBadDisplay);
875 }
876
877 auto error = display->SetColorModeWithIntent(Hwc3ColorModeToHwc2(mode),
878 Hwc3RenderIntentToHwc2(intent));
879 return ToBinderStatus(Hwc2toHwc3Error(error));
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000880}
881
Drew Davenport5951b112024-08-05 09:44:27 -0600882ndk::ScopedAStatus ComposerClient::setContentType(int64_t display_id,
883 ContentType type) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000884 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600885 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
886 HwcDisplay* display = GetDisplay(display_id);
887 if (display == nullptr) {
888 return ToBinderStatus(hwc3::Error::kBadDisplay);
889 }
890
891 auto error = display->SetContentType(Hwc3ContentTypeToHwc2(type));
892 return ToBinderStatus(Hwc2toHwc3Error(error));
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000893}
894
895ndk::ScopedAStatus ComposerClient::setDisplayedContentSamplingEnabled(
Drew Davenport5951b112024-08-05 09:44:27 -0600896 int64_t /*display_id*/, bool /*enable*/,
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000897 FormatColorComponent /*componentMask*/, int64_t /*maxFrames*/) {
898 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600899 return ToBinderStatus(hwc3::Error::kUnsupported);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000900}
901
Drew Davenport5951b112024-08-05 09:44:27 -0600902ndk::ScopedAStatus ComposerClient::setPowerMode(int64_t display_id,
903 PowerMode mode) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000904 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600905 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
906 HwcDisplay* display = GetDisplay(display_id);
907 if (display == nullptr) {
908 return ToBinderStatus(hwc3::Error::kBadDisplay);
909 }
910
Dennis Tsiang1a966202024-01-24 12:46:33 +0000911 if (mode == PowerMode::ON_SUSPEND) {
912 return ToBinderStatus(hwc3::Error::kUnsupported);
913 }
914
Drew Davenport5951b112024-08-05 09:44:27 -0600915 auto error = display->SetPowerMode(Hwc3PowerModeToHwc2(mode));
916 return ToBinderStatus(Hwc2toHwc3Error(error));
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000917}
918
919ndk::ScopedAStatus ComposerClient::setReadbackBuffer(
Drew Davenport5951b112024-08-05 09:44:27 -0600920 int64_t /*display_id*/, const AidlNativeHandle& /*aidlBuffer*/,
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000921 const ndk::ScopedFileDescriptor& /*releaseFence*/) {
922 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600923 return ToBinderStatus(hwc3::Error::kUnsupported);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000924}
925
Drew Davenport5951b112024-08-05 09:44:27 -0600926ndk::ScopedAStatus ComposerClient::setVsyncEnabled(int64_t display_id,
927 bool enabled) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000928 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600929 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
930 HwcDisplay* display = GetDisplay(display_id);
931 if (display == nullptr) {
932 return ToBinderStatus(hwc3::Error::kBadDisplay);
933 }
934
935 auto error = display->SetVsyncEnabled(static_cast<int32_t>(enabled));
936 return ToBinderStatus(Hwc2toHwc3Error(error));
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000937}
938
Drew Davenport5951b112024-08-05 09:44:27 -0600939ndk::ScopedAStatus ComposerClient::setIdleTimerEnabled(int64_t /*display_id*/,
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000940 int32_t /*timeout*/) {
941 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600942 return ToBinderStatus(hwc3::Error::kUnsupported);
943}
944
Drew Davenport7f1761b2024-08-20 10:09:43 -0600945ndk::ScopedAStatus ComposerClient::getOverlaySupport(
946 OverlayProperties* /*out_overlay_properties*/) {
947 return ToBinderStatus(hwc3::Error::kUnsupported);
948}
949
950ndk::ScopedAStatus ComposerClient::getHdrConversionCapabilities(
951 std::vector<common::HdrConversionCapability>* /*out_capabilities*/) {
952 return ToBinderStatus(hwc3::Error::kUnsupported);
953}
954
955ndk::ScopedAStatus ComposerClient::setHdrConversionStrategy(
956 const common::HdrConversionStrategy& /*conversion_strategy*/,
957 common::Hdr* /*out_hdr*/) {
958 return ToBinderStatus(hwc3::Error::kUnsupported);
959}
960
961ndk::ScopedAStatus ComposerClient::setRefreshRateChangedCallbackDebugEnabled(
962 int64_t /*display*/, bool /*enabled*/) {
963 return ToBinderStatus(hwc3::Error::kUnsupported);
964}
965
966ndk::ScopedAStatus ComposerClient::getDisplayConfigurations(
Drew Davenportf7e88332024-09-06 12:54:38 -0600967 int64_t display_id, int32_t /*max_frame_interval_ns*/,
Drew Davenport7f1761b2024-08-20 10:09:43 -0600968 std::vector<DisplayConfiguration>* configurations) {
Drew Davenportf7e88332024-09-06 12:54:38 -0600969 DEBUG_FUNC();
970 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
971 HwcDisplay* display = GetDisplay(display_id);
972 if (display == nullptr) {
973 return ToBinderStatus(hwc3::Error::kBadDisplay);
974 }
975
976 const HwcDisplayConfigs& configs = display->GetDisplayConfigs();
977 for (const auto& [id, config] : configs.hwc_configs) {
Drew Davenportf7e88332024-09-06 12:54:38 -0600978 configurations->emplace_back(
979 DisplayConfiguration{.configId = static_cast<int32_t>(config.id),
980 .width = config.mode.GetRawMode().hdisplay,
981 .height = config.mode.GetRawMode().vdisplay,
982 .configGroup = static_cast<int32_t>(
983 config.group_id),
Drew Davenport8053f2e2024-10-02 13:44:41 -0600984 .vsyncPeriod = config.mode.GetVSyncPeriodNs()});
Drew Davenportf7e88332024-09-06 12:54:38 -0600985
986 if (configs.mm_width != 0) {
987 // ideally this should be vdisplay/mm_heigth, however mm_height
988 // comes from edid parsing and is highly unreliable. Viewing the
989 // rarity of anisotropic displays, falling back to a single value
990 // for dpi yield more correct output.
991 static const float kMmPerInch = 25.4;
992 float dpi = float(config.mode.GetRawMode().hdisplay) * kMmPerInch /
993 float(configs.mm_width);
994 configurations->back().dpi = {.x = dpi, .y = dpi};
995 }
996
997 // TODO: Populate vrrConfig.
998 }
999 return ndk::ScopedAStatus::ok();
Drew Davenport7f1761b2024-08-20 10:09:43 -06001000}
1001
1002ndk::ScopedAStatus ComposerClient::notifyExpectedPresent(
1003 int64_t /*display*/, const ClockMonotonicTimestamp& /*expected_present_time*/,
1004 int32_t /*frame_interval_ns*/) {
1005 return ToBinderStatus(hwc3::Error::kUnsupported);
1006}
1007
Drew Davenport5951b112024-08-05 09:44:27 -06001008std::string ComposerClient::Dump() {
1009 uint32_t size = 0;
1010 hwc_->Dump(&size, nullptr);
1011
1012 std::string buffer(size, '\0');
1013 hwc_->Dump(&size, &buffer.front());
1014 return buffer;
Dennis Tsiang33f0ece2023-11-29 12:45:04 +00001015}
1016
1017::ndk::SpAIBinder ComposerClient::createBinder() {
1018 auto binder = BnComposerClient::createBinder();
1019 AIBinder_setInheritRt(binder.get(), true);
1020 return binder;
1021}
1022
Drew Davenport5951b112024-08-05 09:44:27 -06001023void ComposerClient::ExecuteSetLayerBuffer(int64_t display_id,
1024 HwcLayerWrapper& layer,
1025 const Buffer& buffer) {
1026 buffer_handle_t imported_buffer = nullptr;
1027
1028 auto releaser = composer_resources_->CreateResourceReleaser(true);
1029 auto err = composer_resources_->GetLayerBuffer(display_id, layer.layer_id,
1030 buffer, &imported_buffer,
1031 releaser.get());
1032 if (err != hwc3::Error::kNone) {
1033 cmd_result_writer_->AddError(err);
1034 return;
1035 }
1036
1037 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
1038 auto fence_fd = const_cast<ndk::ScopedFileDescriptor&>(buffer.fence)
1039 .release();
1040 err = Hwc2toHwc3Error(layer.layer->SetLayerBuffer(imported_buffer, fence_fd));
1041 if (err != hwc3::Error::kNone) {
1042 cmd_result_writer_->AddError(err);
1043 }
1044}
1045
1046void ComposerClient::ExecuteSetLayerBlendMode(
1047 int64_t /*display_id*/, HwcLayerWrapper& layer,
1048 const ParcelableBlendMode& blend_mode) {
1049 auto err = Hwc2toHwc3Error(layer.layer->SetLayerBlendMode(
1050 Hwc3BlendModeToHwc2(blend_mode.blendMode)));
1051 if (err != hwc3::Error::kNone) {
1052 cmd_result_writer_->AddError(err);
1053 }
1054}
1055
1056void ComposerClient::ExecuteSetLayerComposition(
1057 int64_t /*display_id*/, HwcLayerWrapper& layer,
1058 const ParcelableComposition& composition) {
1059 hwc3::Error error = hwc3::Error::kNone;
1060 switch (composition.composition) {
1061 // Unsupported composition types should set an error for the current
1062 // DisplayCommand.
1063 case Composition::DISPLAY_DECORATION:
1064 case Composition::SIDEBAND:
1065 error = hwc3::Error::kUnsupported;
1066 break;
1067 default:
1068 error = Hwc2toHwc3Error(layer.layer->SetLayerCompositionType(
1069 Hwc3CompositionToHwc2(composition.composition)));
1070 }
1071 if (error != hwc3::Error::kNone) {
1072 cmd_result_writer_->AddError(error);
1073 }
1074}
1075
1076void ComposerClient::ExecuteSetLayerDataspace(
1077 int64_t /*display_id*/, HwcLayerWrapper& layer,
1078 const ParcelableDataspace& dataspace) {
1079 auto err = Hwc2toHwc3Error(
1080 layer.layer->SetLayerDataspace(Hwc3DataspaceToHwc2(dataspace.dataspace)));
1081 if (err != hwc3::Error::kNone) {
1082 cmd_result_writer_->AddError(err);
1083 }
1084}
1085
1086void ComposerClient::ExecuteSetLayerDisplayFrame(int64_t /*display_id*/,
1087 HwcLayerWrapper& layer,
1088 const common::Rect& rect) {
1089 const hwc_rect_t hwc2_rect{rect.left, rect.top, rect.right, rect.bottom};
1090 auto err = Hwc2toHwc3Error(layer.layer->SetLayerDisplayFrame(hwc2_rect));
1091 if (err != hwc3::Error::kNone) {
1092 cmd_result_writer_->AddError(err);
1093 }
1094}
1095void ComposerClient::ExecuteSetLayerPlaneAlpha(int64_t /*display_id*/,
1096 HwcLayerWrapper& layer,
1097 const PlaneAlpha& plane_alpha) {
1098 auto err = Hwc2toHwc3Error(
1099 layer.layer->SetLayerPlaneAlpha(plane_alpha.alpha));
1100 if (err != hwc3::Error::kNone) {
1101 cmd_result_writer_->AddError(err);
1102 }
1103}
1104
1105void ComposerClient::ExecuteSetLayerSourceCrop(
1106 int64_t /*display_id*/, HwcLayerWrapper& layer,
1107 const common::FRect& source_crop) {
1108 const hwc_frect_t rect{source_crop.left, source_crop.top, source_crop.right,
1109 source_crop.bottom};
1110 auto err = Hwc2toHwc3Error(layer.layer->SetLayerSourceCrop(rect));
1111 if (err != hwc3::Error::kNone) {
1112 cmd_result_writer_->AddError(err);
1113 }
1114}
1115void ComposerClient::ExecuteSetLayerTransform(
1116 int64_t /*display_id*/, HwcLayerWrapper& layer,
1117 const ParcelableTransform& transform) {
1118 auto err = Hwc2toHwc3Error(
1119 layer.layer->SetLayerTransform(Hwc3TransformToHwc2(transform.transform)));
1120 if (err != hwc3::Error::kNone) {
1121 cmd_result_writer_->AddError(err);
1122 }
1123}
1124void ComposerClient::ExecuteSetLayerZOrder(int64_t /*display_id*/,
1125 HwcLayerWrapper& layer,
1126 const ZOrder& z_order) {
1127 auto err = Hwc2toHwc3Error(layer.layer->SetLayerZOrder(z_order.z));
1128 if (err != hwc3::Error::kNone) {
1129 cmd_result_writer_->AddError(err);
1130 }
1131}
1132
1133void ComposerClient::ExecuteSetLayerBrightness(
1134 int64_t /*display_id*/, HwcLayerWrapper& /*layer*/,
1135 const LayerBrightness& brightness) {
1136 if (std::signbit(brightness.brightness) ||
1137 std::isnan(brightness.brightness)) {
1138 cmd_result_writer_->AddError(hwc3::Error::kBadParameter);
1139 }
1140}
1141
Jason Macnak3dc274e2024-09-19 09:29:55 -07001142void ComposerClient::ExecuteLayerCommandSetLayerLuts(
1143 int64_t /*display_id*/, HwcLayerWrapper& /*layer*/,
1144 const std::vector<std::optional<Lut>>& /*luts*/) {
1145 cmd_result_writer_->AddError(hwc3::Error::kUnsupported);
1146}
1147
Drew Davenport5951b112024-08-05 09:44:27 -06001148void ComposerClient::ExecuteSetDisplayBrightness(
1149 uint64_t display_id, const DisplayBrightness& command) {
1150 auto* display = GetDisplay(display_id);
1151 if (display == nullptr) {
1152 cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
1153 return;
1154 }
1155
1156 auto error = Hwc2toHwc3Error(
1157 display->SetDisplayBrightness(command.brightness));
1158 if (error != hwc3::Error::kNone) {
1159 cmd_result_writer_->AddError(error);
1160 }
1161}
1162void ComposerClient::ExecuteSetDisplayColorTransform(
1163 uint64_t display_id, const std::vector<float>& matrix) {
1164 auto* display = GetDisplay(display_id);
1165 if (display == nullptr) {
1166 cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
1167 return;
1168 }
1169
1170 auto almost_equal = [](auto a, auto b) {
1171 const float epsilon = 0.001F;
1172 return std::abs(a - b) < epsilon;
1173 };
1174 const bool is_identity = std::equal(matrix.begin(), matrix.end(),
1175 kIdentityMatrix.begin(), almost_equal);
1176
1177 const int32_t hint = is_identity ? HAL_COLOR_TRANSFORM_IDENTITY
1178 : HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX;
1179
1180 auto error = Hwc2toHwc3Error(display->SetColorTransform(matrix.data(), hint));
1181 if (error != hwc3::Error::kNone) {
1182 cmd_result_writer_->AddError(error);
1183 }
1184}
1185void ComposerClient::ExecuteSetDisplayClientTarget(
1186 uint64_t display_id, const ClientTarget& command) {
1187 auto* display = GetDisplay(display_id);
1188 if (display == nullptr) {
1189 cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
1190 return;
1191 }
1192
1193 hwc_region_t damage_regions;
1194 damage_regions.numRects = command.damage.size();
1195
1196 std::vector<hwc_rect_t> regions(command.damage.size());
1197 for (const auto& region : command.damage) {
1198 regions.push_back({region.left, region.top, region.right, region.bottom});
1199 }
1200 damage_regions.rects = regions.data();
1201
1202 buffer_handle_t imported_buffer = nullptr;
1203 auto buf_releaser = composer_resources_->CreateResourceReleaser(true);
1204
1205 auto error = composer_resources_->GetDisplayClientTarget(display_id,
1206 command.buffer,
1207 &imported_buffer,
1208 buf_releaser.get());
1209 if (error != hwc3::Error::kNone) {
1210 cmd_result_writer_->AddError(error);
1211 return;
1212 }
1213
1214 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
1215 auto fence = const_cast<::ndk::ScopedFileDescriptor&>(command.buffer.fence)
1216 .release();
1217 error = Hwc2toHwc3Error(
1218 display->SetClientTarget(imported_buffer, fence,
1219 Hwc3DataspaceToHwc2(command.dataspace),
1220 damage_regions));
1221 if (error != hwc3::Error::kNone) {
1222 cmd_result_writer_->AddError(error);
1223 }
1224}
1225
1226void ComposerClient::ExecuteSetDisplayOutputBuffer(uint64_t display_id,
1227 const Buffer& buffer) {
1228 auto* display = GetDisplay(display_id);
1229 if (display == nullptr) {
1230 cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
1231 return;
1232 }
1233
1234 buffer_handle_t imported_buffer = nullptr;
1235 auto buf_releaser = composer_resources_->CreateResourceReleaser(true);
1236
1237 auto error = composer_resources_->GetDisplayOutputBuffer(display_id, buffer,
1238 &imported_buffer,
1239 buf_releaser.get());
1240 if (error != hwc3::Error::kNone) {
1241 cmd_result_writer_->AddError(error);
1242 return;
1243 }
1244
1245 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
1246 auto fence = const_cast<::ndk::ScopedFileDescriptor&>(buffer.fence).release();
1247 error = Hwc2toHwc3Error(display->SetOutputBuffer(imported_buffer, fence));
1248 if (error != hwc3::Error::kNone) {
1249 cmd_result_writer_->AddError(error);
1250 return;
1251 }
1252}
1253void ComposerClient::ExecuteValidateDisplay(
1254 int64_t display_id,
1255 std::optional<ClockMonotonicTimestamp> /*expected_present_time*/
1256) {
1257 auto* display = GetDisplay(display_id);
1258 if (display == nullptr) {
1259 cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
1260 return;
1261 }
1262
1263 /* TODO: Handle expectedPresentTime */
Normunds Rieksts42820952024-03-12 15:42:06 +00001264 /* This can be implemented in multiple ways. For example, the expected present
1265 * time property can be implemented by the DRM driver directly as a CRTC
1266 * property. See:
1267 * https://cs.android.com/android/platform/superproject/main/+/b8b3b1646e64d0235f77b9e717a3e4082e26f2a8:hardware/google/graphics/common/libhwc2.1/libdrmresource/drm/drmcrtc.cpp;drc=468f6172546ab98983de18210222f231f16b21e1;l=88
1268 * Unfortunately there doesn't seem to be a standardised way of delaying
1269 * presentation with a timestamp in the DRM API. What we can do alternatively
1270 * is to spawn a separate presentation thread that could handle the VBlank
1271 * events by using DRM_MODE_PAGE_FLIP_EVENT and schedule them appropriately.
1272 */
Drew Davenport5951b112024-08-05 09:44:27 -06001273
1274 std::vector<int64_t> changed_layers;
1275 std::vector<Composition> composition_types;
1276 int32_t display_request_mask = 0;
1277 std::vector<int64_t> requested_layers;
1278 std::vector<int32_t> request_masks;
1279
1280 const hwc3::Error error = ValidateDisplayInternal(*display, &changed_layers,
1281 &composition_types,
1282 &display_request_mask,
1283 &requested_layers,
1284 &request_masks, nullptr,
1285 nullptr);
1286
1287 if (error != hwc3::Error::kNone) {
1288 cmd_result_writer_->AddError(error);
1289 }
1290
1291 // If a CommandError has been been set for the current DisplayCommand, then
1292 // no other results should be returned besides the error.
1293 if (cmd_result_writer_->HasError()) {
1294 return;
1295 }
1296
1297 DisplayChanges changes{};
1298 for (size_t i = 0; i < composition_types.size(); i++) {
1299 changes.AddLayerCompositionChange(display_id, changed_layers[i],
1300 composition_types[i]);
1301 }
1302
1303 std::vector<DisplayRequest::LayerRequest> layer_requests;
1304 for (size_t i = 0; i < requested_layers.size(); i++) {
1305 layer_requests.push_back({requested_layers[i], request_masks[i]});
1306 }
1307
1308 const DisplayRequest request_changes{display_id, display_request_mask,
1309 layer_requests};
1310 changes.display_request_changes = request_changes;
1311
1312 cmd_result_writer_->AddChanges(changes);
1313 composer_resources_->SetDisplayMustValidateState(display_id, false);
1314}
1315
1316void ComposerClient::ExecuteAcceptDisplayChanges(int64_t display_id) {
1317 auto* display = GetDisplay(display_id);
1318 if (display == nullptr) {
1319 cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
1320 return;
1321 }
1322
1323 auto error = Hwc2toHwc3Error(display->AcceptDisplayChanges());
1324 if (error != hwc3::Error::kNone) {
1325 cmd_result_writer_->AddError(error);
1326 return;
1327 }
1328}
1329
1330void ComposerClient::ExecutePresentDisplay(int64_t display_id) {
1331 auto* display = GetDisplay(display_id);
1332 if (display == nullptr) {
1333 cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
1334 return;
1335 }
1336
1337 ::android::base::unique_fd display_fence;
1338 std::unordered_map<int64_t, ::android::base::unique_fd> release_fences;
1339 auto error = PresentDisplayInternal(display_id, display_fence,
1340 release_fences);
1341 if (error != hwc3::Error::kNone) {
1342 cmd_result_writer_->AddError(error);
1343 }
1344 if (cmd_result_writer_->HasError()) {
1345 return;
1346 }
1347
1348 cmd_result_writer_->AddPresentFence(display_id, std::move(display_fence));
1349 cmd_result_writer_->AddReleaseFence(display_id, release_fences);
1350}
1351
1352void ComposerClient::ExecutePresentOrValidateDisplay(
1353 int64_t display_id,
1354 std::optional<ClockMonotonicTimestamp> expected_present_time) {
1355 auto* display = GetDisplay(display_id);
1356 if (display == nullptr) {
1357 cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
1358 return;
1359 }
1360
1361 /* TODO: Handle expectedPresentTime */
Normunds Rieksts42820952024-03-12 15:42:06 +00001362 /* This can be implemented in multiple ways. For example, the expected present
1363 * time property can be implemented by the DRM driver directly as a CRTC
1364 * property. See:
1365 * https://cs.android.com/android/platform/superproject/main/+/b8b3b1646e64d0235f77b9e717a3e4082e26f2a8:hardware/google/graphics/common/libhwc2.1/libdrmresource/drm/drmcrtc.cpp;drc=468f6172546ab98983de18210222f231f16b21e1;l=88
1366 * Unfortunately there doesn't seem to be a standardised way of delaying
1367 * presentation with a timestamp in the DRM API. What we can do alternatively
1368 * is to spawn a separate presentation thread that could handle the VBlank
1369 * events by using DRM_MODE_PAGE_FLIP_EVENT and schedule them appropriately.
1370 */
1371
Drew Davenport5951b112024-08-05 09:44:27 -06001372 /* TODO: Add check if it's possible to skip display validation */
1373 ExecuteValidateDisplay(display_id, expected_present_time);
1374 cmd_result_writer_
1375 ->AddPresentOrValidateResult(display_id,
1376 PresentOrValidate::Result::Validated);
1377}
1378
Dennis Tsiang33f0ece2023-11-29 12:45:04 +00001379} // namespace aidl::android::hardware::graphics::composer3::impl