blob: f353abb91478e10669f5ccbf06926c4932fab96c [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
205 std::vector<hwc2_layer_t> hwc_changed_layers(num_types);
206 std::vector<int32_t> hwc_composition_types(num_types);
207 hwc3::Error error = Hwc2toHwc3Error(
208 display.GetChangedCompositionTypes(&num_types, hwc_changed_layers.data(),
209 hwc_composition_types.data()));
210 if (error != hwc3::Error::kNone) {
211 return error;
212 }
213
214 int32_t display_reqs = 0;
215 out_request_masks->resize(num_requests);
216 std::vector<hwc2_layer_t> hwc_requested_layers(num_requests);
217 error = Hwc2toHwc3Error(
218 display.GetDisplayRequests(&display_reqs, &num_requests,
219 hwc_requested_layers.data(),
220 out_request_masks->data()));
221 if (error != hwc3::Error::kNone) {
222 return error;
223 }
224
225 for (const auto& layer : hwc_changed_layers) {
226 out_changed_layers->emplace_back(Hwc2LayerToHwc3(layer));
227 }
228 for (const auto& type : hwc_composition_types) {
229 out_composition_types->emplace_back(Hwc2CompositionTypeToHwc3(type));
230 }
231 for (const auto& layer : hwc_requested_layers) {
232 out_requested_layers->emplace_back(Hwc2LayerToHwc3(layer));
233 }
234 *out_display_request_mask = display_reqs;
235
236 /* Client target property/dimming stage unsupported */
237 return hwc3::Error::kNone;
238}
239
240hwc3::Error ComposerClient::PresentDisplayInternal(
241 uint64_t display_id, ::android::base::unique_fd& out_display_fence,
242 std::unordered_map<int64_t, ::android::base::unique_fd>&
243 out_release_fences) {
244 DEBUG_FUNC();
245 auto* display = GetDisplay(display_id);
246 if (display == nullptr) {
247 return hwc3::Error::kBadDisplay;
248 }
249
250 if (composer_resources_->MustValidateDisplay(display_id)) {
251 return hwc3::Error::kNotValidated;
252 }
253
254 int32_t present_fence = -1;
255 auto error = Hwc2toHwc3Error(display->PresentDisplay(&present_fence));
256 if (error != hwc3::Error::kNone) {
257 return error;
258 }
259 out_display_fence.reset(present_fence);
260
261 uint32_t release_fence_count = 0;
262 error = Hwc2toHwc3Error(
263 display->GetReleaseFences(&release_fence_count, nullptr, nullptr));
264 if (error != hwc3::Error::kNone) {
265 return error;
266 }
267
268 std::vector<hwc2_layer_t> hwc_layers(release_fence_count);
269 std::vector<int32_t> hwc_fences(release_fence_count);
270 error = Hwc2toHwc3Error(display->GetReleaseFences(&release_fence_count,
271 hwc_layers.data(),
272 hwc_fences.data()));
273 if (error != hwc3::Error::kNone) {
274 return error;
275 }
276
277 for (size_t i = 0; i < hwc_layers.size(); i++) {
278 auto layer = Hwc2LayerToHwc3(hwc_layers[i]);
279 out_release_fences[layer] = ::android::base::unique_fd{hwc_fences[i]};
280 }
281
282 return hwc3::Error::kNone;
283}
284
285::android::HwcDisplay* ComposerClient::GetDisplay(uint64_t display_id) {
286 return hwc_->GetDisplay(display_id);
287}
288
289void ComposerClient::DispatchLayerCommand(int64_t display_id,
290 const LayerCommand& command) {
291 auto* display = GetDisplay(display_id);
292 if (display == nullptr) {
293 cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
294 return;
295 }
296
297 auto* layer = display->get_layer(command.layer);
298 if (layer == nullptr) {
299 cmd_result_writer_->AddError(hwc3::Error::kBadLayer);
300 return;
301 }
302
303 HwcLayerWrapper layer_wrapper{command.layer, layer};
304 if (command.buffer) {
305 ExecuteSetLayerBuffer(display_id, layer_wrapper, *command.buffer);
306 }
307 if (command.blendMode) {
308 ExecuteSetLayerBlendMode(display_id, layer_wrapper, *command.blendMode);
309 }
310 if (command.composition) {
311 ExecuteSetLayerComposition(display_id, layer_wrapper, *command.composition);
312 }
313 if (command.dataspace) {
314 ExecuteSetLayerDataspace(display_id, layer_wrapper, *command.dataspace);
315 }
316 if (command.displayFrame) {
317 ExecuteSetLayerDisplayFrame(display_id, layer_wrapper,
318 *command.displayFrame);
319 }
320 if (command.planeAlpha) {
321 ExecuteSetLayerPlaneAlpha(display_id, layer_wrapper, *command.planeAlpha);
322 }
323 if (command.sourceCrop) {
324 ExecuteSetLayerSourceCrop(display_id, layer_wrapper, *command.sourceCrop);
325 }
326 if (command.transform) {
327 ExecuteSetLayerTransform(display_id, layer_wrapper, *command.transform);
328 }
329 if (command.z) {
330 ExecuteSetLayerZOrder(display_id, layer_wrapper, *command.z);
331 }
332 if (command.brightness) {
333 ExecuteSetLayerBrightness(display_id, layer_wrapper, *command.brightness);
334 }
335
336 // Some unsupported functionality returns kUnsupported, and others
337 // are just a no-op.
338 // TODO: Audit whether some of these should actually return kUnsupported
339 // instead.
340 if (command.sidebandStream) {
341 cmd_result_writer_->AddError(hwc3::Error::kUnsupported);
342 }
343 // TODO: Blocking region handling missing.
344 // TODO: Layer surface damage.
345 // TODO: Layer visible region.
346 // TODO: Per-frame metadata.
347 // TODO: Layer color transform.
348 // TODO: Layer cursor position.
349 // TODO: Layer color.
350}
351
352void ComposerClient::ExecuteDisplayCommand(const DisplayCommand& command) {
353 const int64_t display_id = command.display;
354 if (hwc_->GetDisplay(display_id) == nullptr) {
355 cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
356 return;
357 }
358
359 for (const auto& layer_cmd : command.layers) {
360 DispatchLayerCommand(command.display, layer_cmd);
361 }
362
363 if (command.brightness) {
364 ExecuteSetDisplayBrightness(command.display, *command.brightness);
365 }
366 if (command.colorTransformMatrix) {
367 ExecuteSetDisplayColorTransform(command.display,
368 *command.colorTransformMatrix);
369 }
370 if (command.clientTarget) {
371 ExecuteSetDisplayClientTarget(command.display, *command.clientTarget);
372 }
373 if (command.virtualDisplayOutputBuffer) {
374 ExecuteSetDisplayOutputBuffer(command.display,
375 *command.virtualDisplayOutputBuffer);
376 }
377 if (command.validateDisplay) {
378 ExecuteValidateDisplay(command.display, command.expectedPresentTime);
379 }
380 if (command.acceptDisplayChanges) {
381 ExecuteAcceptDisplayChanges(command.display);
382 }
383 if (command.presentDisplay) {
384 ExecutePresentDisplay(command.display);
385 }
386 if (command.presentOrValidateDisplay) {
387 ExecutePresentOrValidateDisplay(command.display,
388 command.expectedPresentTime);
389 }
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000390}
391
392ndk::ScopedAStatus ComposerClient::executeCommands(
Drew Davenport5951b112024-08-05 09:44:27 -0600393 const std::vector<DisplayCommand>& commands,
394 std::vector<CommandResultPayload>* results) {
Drew Davenport49965852024-09-05 10:59:40 -0600395 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
396 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600397 cmd_result_writer_ = std::make_unique<CommandResultWriter>(results);
398 for (const auto& cmd : commands) {
399 ExecuteDisplayCommand(cmd);
400 cmd_result_writer_->IncrementCommand();
401 }
402 cmd_result_writer_.reset();
403
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000404 return ndk::ScopedAStatus::ok();
405}
406
Drew Davenport5951b112024-08-05 09:44:27 -0600407ndk::ScopedAStatus ComposerClient::getActiveConfig(int64_t display_id,
408 int32_t* config) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000409 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600410 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
411 HwcDisplay* display = GetDisplay(display_id);
412 if (display == nullptr) {
413 return ToBinderStatus(hwc3::Error::kBadDisplay);
414 }
415
416 uint32_t hwc2_config = 0;
417 const hwc3::Error error = Hwc2toHwc3Error(
418 display->GetActiveConfig(&hwc2_config));
419 if (error != hwc3::Error::kNone) {
420 return ToBinderStatus(error);
421 }
422 *config = Hwc2ConfigIdToHwc3(hwc2_config);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000423 return ndk::ScopedAStatus::ok();
424}
425
426ndk::ScopedAStatus ComposerClient::getColorModes(
Drew Davenport5951b112024-08-05 09:44:27 -0600427 int64_t display_id, std::vector<ColorMode>* color_modes) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000428 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600429 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
430 HwcDisplay* display = GetDisplay(display_id);
431 if (display == nullptr) {
432 return ToBinderStatus(hwc3::Error::kBadDisplay);
433 }
434
435 uint32_t num_modes = 0;
436 auto error = Hwc2toHwc3Error(display->GetColorModes(&num_modes, nullptr));
437 if (error != hwc3::Error::kNone) {
438 return ToBinderStatus(error);
439 }
440
441 std::vector<int32_t> hwc2_color_modes(num_modes);
442 error = Hwc2toHwc3Error(
443 display->GetColorModes(&num_modes, hwc2_color_modes.data()));
444 if (error != hwc3::Error::kNone) {
445 return ToBinderStatus(error);
446 }
447
448 for (const auto& mode : hwc2_color_modes) {
449 color_modes->push_back(Hwc2ColorModeToHwc3(mode));
450 }
451
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000452 return ndk::ScopedAStatus::ok();
453}
454
455ndk::ScopedAStatus ComposerClient::getDataspaceSaturationMatrix(
Drew Davenport5951b112024-08-05 09:44:27 -0600456 common::Dataspace dataspace, std::vector<float>* matrix) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000457 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600458 if (dataspace != common::Dataspace::SRGB_LINEAR) {
459 return ToBinderStatus(hwc3::Error::kBadParameter);
460 }
461
462 matrix->clear();
463 matrix->insert(matrix->begin(), kIdentityMatrix.begin(),
464 kIdentityMatrix.end());
465
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000466 return ndk::ScopedAStatus::ok();
467}
468
469ndk::ScopedAStatus ComposerClient::getDisplayAttribute(
Drew Davenport5951b112024-08-05 09:44:27 -0600470 int64_t display_id, int32_t config, DisplayAttribute attribute,
471 int32_t* value) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000472 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600473 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
474 HwcDisplay* display = GetDisplay(display_id);
475 if (display == nullptr) {
476 return ToBinderStatus(hwc3::Error::kBadDisplay);
477 }
478
479 const hwc3::Error error = Hwc2toHwc3Error(
480 display->GetDisplayAttribute(Hwc3ConfigIdToHwc2(config),
481 Hwc3DisplayAttributeToHwc2(attribute),
482 value));
483 return ToBinderStatus(error);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000484}
485
486ndk::ScopedAStatus ComposerClient::getDisplayCapabilities(
Drew Davenport5951b112024-08-05 09:44:27 -0600487 int64_t display_id, std::vector<DisplayCapability>* caps) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000488 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600489 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
490 HwcDisplay* display = GetDisplay(display_id);
491 if (display == nullptr) {
492 return ToBinderStatus(hwc3::Error::kBadDisplay);
493 }
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000494
Drew Davenport5951b112024-08-05 09:44:27 -0600495 uint32_t num_capabilities = 0;
496 hwc3::Error error = Hwc2toHwc3Error(
497 display->GetDisplayCapabilities(&num_capabilities, nullptr));
498 if (error != hwc3::Error::kNone) {
499 return ToBinderStatus(error);
500 }
501
502 std::vector<uint32_t> out_caps(num_capabilities);
503 error = Hwc2toHwc3Error(
504 display->GetDisplayCapabilities(&num_capabilities, out_caps.data()));
505 if (error != hwc3::Error::kNone) {
506 return ToBinderStatus(error);
507 }
508
509 caps->reserve(num_capabilities);
510 for (const auto cap : out_caps) {
511 caps->emplace_back(Hwc2DisplayCapabilityToHwc3(cap));
512 }
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000513 return ndk::ScopedAStatus::ok();
514}
515
516ndk::ScopedAStatus ComposerClient::getDisplayConfigs(
Drew Davenport5951b112024-08-05 09:44:27 -0600517 int64_t display_id, std::vector<int32_t>* configs) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000518 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600519 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
520 HwcDisplay* display = GetDisplay(display_id);
521 if (display == nullptr) {
522 return ToBinderStatus(hwc3::Error::kBadDisplay);
523 }
524
525 uint32_t num_configs = 0;
526 hwc3::Error error = Hwc2toHwc3Error(
Drew Davenportf7e88332024-09-06 12:54:38 -0600527 display->LegacyGetDisplayConfigs(&num_configs, nullptr));
Drew Davenport5951b112024-08-05 09:44:27 -0600528 if (error != hwc3::Error::kNone) {
529 return ToBinderStatus(error);
530 }
531
532 std::vector<hwc2_config_t> out_configs(num_configs);
533 error = Hwc2toHwc3Error(
Drew Davenportf7e88332024-09-06 12:54:38 -0600534 display->LegacyGetDisplayConfigs(&num_configs, out_configs.data()));
Drew Davenport5951b112024-08-05 09:44:27 -0600535 if (error != hwc3::Error::kNone) {
536 return ToBinderStatus(error);
537 }
538
539 configs->reserve(num_configs);
540 for (const auto config : out_configs) {
541 configs->emplace_back(Hwc2ConfigIdToHwc3(config));
542 }
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000543 return ndk::ScopedAStatus::ok();
544}
545
546ndk::ScopedAStatus ComposerClient::getDisplayConnectionType(
Drew Davenport5951b112024-08-05 09:44:27 -0600547 int64_t display_id, DisplayConnectionType* type) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000548 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600549 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
550 HwcDisplay* display = GetDisplay(display_id);
551 if (display == nullptr) {
552 return ToBinderStatus(hwc3::Error::kBadDisplay);
553 }
554
555 uint32_t out_type = 0;
556 const hwc3::Error error = Hwc2toHwc3Error(
557 display->GetDisplayConnectionType(&out_type));
558 if (error != hwc3::Error::kNone) {
559 return ToBinderStatus(error);
560 }
561
562 *type = Hwc2DisplayConnectionTypeToHwc3(out_type);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000563 return ndk::ScopedAStatus::ok();
564}
565
566ndk::ScopedAStatus ComposerClient::getDisplayIdentificationData(
Drew Davenport5951b112024-08-05 09:44:27 -0600567 int64_t display_id, DisplayIdentification* id) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000568 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600569 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
570 HwcDisplay* display = GetDisplay(display_id);
571 if (display == nullptr) {
572 return ToBinderStatus(hwc3::Error::kBadDisplay);
573 }
574
575 uint8_t port = 0;
576 uint32_t data_size = 0;
577 hwc3::Error error = Hwc2toHwc3Error(
578 display->GetDisplayIdentificationData(&port, &data_size, nullptr));
579 if (error != hwc3::Error::kNone) {
580 return ToBinderStatus(error);
581 }
582
583 id->data.resize(data_size);
584 error = Hwc2toHwc3Error(
585 display->GetDisplayIdentificationData(&port, &data_size,
586 id->data.data()));
587 if (error != hwc3::Error::kNone) {
588 return ToBinderStatus(error);
589 }
590
591 id->port = static_cast<int8_t>(port);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000592 return ndk::ScopedAStatus::ok();
593}
594
Drew Davenport5951b112024-08-05 09:44:27 -0600595ndk::ScopedAStatus ComposerClient::getDisplayName(int64_t display_id,
596 std::string* name) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000597 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600598 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
599 HwcDisplay* display = GetDisplay(display_id);
600 if (display == nullptr) {
601 return ToBinderStatus(hwc3::Error::kBadDisplay);
602 }
603
604 uint32_t size = 0;
605 auto error = Hwc2toHwc3Error(display->GetDisplayName(&size, nullptr));
606 if (error != hwc3::Error::kNone) {
607 return ToBinderStatus(error);
608 }
609
610 name->resize(size);
611 error = Hwc2toHwc3Error(display->GetDisplayName(&size, name->data()));
612 return ToBinderStatus(error);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000613}
614
615ndk::ScopedAStatus ComposerClient::getDisplayVsyncPeriod(
Drew Davenport5951b112024-08-05 09:44:27 -0600616 int64_t display_id, int32_t* vsync_period) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000617 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600618 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
619 HwcDisplay* display = GetDisplay(display_id);
620 if (display == nullptr) {
621 return ToBinderStatus(hwc3::Error::kBadDisplay);
622 }
623
624 uint32_t hwc2_vsync_period = 0;
625 auto error = Hwc2toHwc3Error(
626 display->GetDisplayVsyncPeriod(&hwc2_vsync_period));
627 if (error != hwc3::Error::kNone) {
628 return ToBinderStatus(error);
629 }
630
631 *vsync_period = static_cast<int32_t>(hwc2_vsync_period);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000632 return ndk::ScopedAStatus::ok();
633}
634
635ndk::ScopedAStatus ComposerClient::getDisplayedContentSample(
Drew Davenport5951b112024-08-05 09:44:27 -0600636 int64_t /*display_id*/, int64_t /*max_frames*/, int64_t /*timestamp*/,
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000637 DisplayContentSample* /*samples*/) {
638 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600639 return ToBinderStatus(hwc3::Error::kUnsupported);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000640}
641
642ndk::ScopedAStatus ComposerClient::getDisplayedContentSamplingAttributes(
Drew Davenport5951b112024-08-05 09:44:27 -0600643 int64_t /*display_id*/, DisplayContentSamplingAttributes* /*attrs*/) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000644 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600645 return ToBinderStatus(hwc3::Error::kUnsupported);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000646}
647
648ndk::ScopedAStatus ComposerClient::getDisplayPhysicalOrientation(
Drew Davenport5951b112024-08-05 09:44:27 -0600649 int64_t display_id, common::Transform* orientation) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000650 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600651 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
652 HwcDisplay* display = GetDisplay(display_id);
653 if (display == nullptr) {
654 return ToBinderStatus(hwc3::Error::kBadDisplay);
655 }
656
657 *orientation = common::Transform::NONE;
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000658 return ndk::ScopedAStatus::ok();
659}
660
Drew Davenport5951b112024-08-05 09:44:27 -0600661ndk::ScopedAStatus ComposerClient::getHdrCapabilities(int64_t display_id,
662 HdrCapabilities* caps) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000663 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600664 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
665 HwcDisplay* display = GetDisplay(display_id);
666 if (display == nullptr) {
667 return ToBinderStatus(hwc3::Error::kBadDisplay);
668 }
669
670 /* No HDR capabilities */
671 caps->types.clear();
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000672 return ndk::ScopedAStatus::ok();
673}
674
Drew Davenport5951b112024-08-05 09:44:27 -0600675ndk::ScopedAStatus ComposerClient::getMaxVirtualDisplayCount(int32_t* count) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000676 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600677 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
678 *count = static_cast<int32_t>(hwc_->GetMaxVirtualDisplayCount());
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000679 return ndk::ScopedAStatus::ok();
680}
681
682ndk::ScopedAStatus ComposerClient::getPerFrameMetadataKeys(
Drew Davenport5951b112024-08-05 09:44:27 -0600683 int64_t /*display_id*/, std::vector<PerFrameMetadataKey>* /*keys*/) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000684 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600685 return ToBinderStatus(hwc3::Error::kUnsupported);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000686}
687
688ndk::ScopedAStatus ComposerClient::getReadbackBufferAttributes(
Drew Davenport5951b112024-08-05 09:44:27 -0600689 int64_t /*display_id*/, ReadbackBufferAttributes* /*attrs*/) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000690 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600691 return ToBinderStatus(hwc3::Error::kUnsupported);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000692}
693
694ndk::ScopedAStatus ComposerClient::getReadbackBufferFence(
Drew Davenport5951b112024-08-05 09:44:27 -0600695 int64_t /*display_id*/, ndk::ScopedFileDescriptor* /*acquireFence*/) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000696 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600697 return ToBinderStatus(hwc3::Error::kUnsupported);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000698}
699
700ndk::ScopedAStatus ComposerClient::getRenderIntents(
Drew Davenport5951b112024-08-05 09:44:27 -0600701 int64_t display_id, ColorMode mode, std::vector<RenderIntent>* intents) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000702 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600703 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
704 HwcDisplay* display = GetDisplay(display_id);
705 if (display == nullptr) {
706 return ToBinderStatus(hwc3::Error::kBadDisplay);
707 }
708
709 const int32_t hwc2_color_mode = Hwc3ColorModeToHwc2(mode);
710 uint32_t out_num_intents = 0;
711 auto error = Hwc2toHwc3Error(
712 display->GetRenderIntents(hwc2_color_mode, &out_num_intents, nullptr));
713 if (error != hwc3::Error::kNone) {
714 return ToBinderStatus(error);
715 }
716
717 std::vector<int32_t> out_intents(out_num_intents);
718 error = Hwc2toHwc3Error(display->GetRenderIntents(hwc2_color_mode,
719 &out_num_intents,
720 out_intents.data()));
721 if (error != hwc3::Error::kNone) {
722 return ToBinderStatus(error);
723 }
724
725 intents->reserve(out_num_intents);
726 for (const auto intent : out_intents) {
727 intents->emplace_back(Hwc2RenderIntentToHwc3(intent));
728 }
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000729 return ndk::ScopedAStatus::ok();
730}
731
732ndk::ScopedAStatus ComposerClient::getSupportedContentTypes(
Drew Davenport5951b112024-08-05 09:44:27 -0600733 int64_t display_id, std::vector<ContentType>* types) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000734 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600735 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
736 HwcDisplay* display = GetDisplay(display_id);
737 if (display == nullptr) {
738 return ToBinderStatus(hwc3::Error::kBadDisplay);
739 }
740
741 uint32_t out_num_supported_types = 0;
742 auto error = Hwc2toHwc3Error(
743 display->GetSupportedContentTypes(&out_num_supported_types, nullptr));
744 if (error != hwc3::Error::kNone) {
745 return ToBinderStatus(error);
746 }
747
748 std::vector<uint32_t> out_supported_types(out_num_supported_types);
749 error = Hwc2toHwc3Error(
750 display->GetSupportedContentTypes(&out_num_supported_types,
751 out_supported_types.data()));
752 if (error != hwc3::Error::kNone) {
753 return ToBinderStatus(error);
754 }
755
756 for (const auto type : out_supported_types) {
757 types->push_back(Hwc2ContentTypeToHwc3(type));
758 }
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000759 return ndk::ScopedAStatus::ok();
760}
761
762ndk::ScopedAStatus ComposerClient::getDisplayDecorationSupport(
Drew Davenport5951b112024-08-05 09:44:27 -0600763 int64_t /*display_id*/,
764 std::optional<common::DisplayDecorationSupport>* /*support_struct*/) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000765 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600766 return ToBinderStatus(hwc3::Error::kUnsupported);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000767}
768
769ndk::ScopedAStatus ComposerClient::registerCallback(
Drew Davenport5951b112024-08-05 09:44:27 -0600770 const std::shared_ptr<IComposerCallback>& callback) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000771 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600772 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
773 // This function is specified to be called exactly once.
774 hwc_->Init(callback);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000775 return ndk::ScopedAStatus::ok();
776}
777
Drew Davenport5951b112024-08-05 09:44:27 -0600778ndk::ScopedAStatus ComposerClient::setActiveConfig(int64_t display_id,
779 int32_t config) {
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 HwcDisplay* display = GetDisplay(display_id);
783 if (display == nullptr) {
784 return ToBinderStatus(hwc3::Error::kBadDisplay);
785 }
786
787 return ToBinderStatus(Hwc2toHwc3Error(display->SetActiveConfig(config)));
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000788}
789
790ndk::ScopedAStatus ComposerClient::setActiveConfigWithConstraints(
Drew Davenport5951b112024-08-05 09:44:27 -0600791 int64_t display_id, int32_t config,
792 const VsyncPeriodChangeConstraints& constraints,
793 VsyncPeriodChangeTimeline* timeline) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000794 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600795 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
796 HwcDisplay* display = GetDisplay(display_id);
797 if (display == nullptr) {
798 return ToBinderStatus(hwc3::Error::kBadDisplay);
799 }
800
801 hwc_vsync_period_change_constraints_t hwc2_constraints;
802 hwc2_constraints.desiredTimeNanos = constraints.desiredTimeNanos;
803 hwc2_constraints.seamlessRequired = static_cast<uint8_t>(
804 constraints.seamlessRequired);
805
806 hwc_vsync_period_change_timeline_t hwc2_timeline{};
807 auto error = Hwc2toHwc3Error(
808 display->SetActiveConfigWithConstraints(config, &hwc2_constraints,
809 &hwc2_timeline));
810 if (error != hwc3::Error::kNone) {
811 return ToBinderStatus(error);
812 }
813
814 timeline->refreshTimeNanos = hwc2_timeline.refreshTimeNanos;
815 timeline->newVsyncAppliedTimeNanos = hwc2_timeline.newVsyncAppliedTimeNanos;
816 timeline->refreshRequired = static_cast<bool>(hwc2_timeline.refreshRequired);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000817 return ndk::ScopedAStatus::ok();
818}
819
Drew Davenport5951b112024-08-05 09:44:27 -0600820ndk::ScopedAStatus ComposerClient::setBootDisplayConfig(int64_t /*display_id*/,
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000821 int32_t /*config*/) {
822 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600823 return ToBinderStatus(hwc3::Error::kUnsupported);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000824}
825
Drew Davenport5951b112024-08-05 09:44:27 -0600826ndk::ScopedAStatus ComposerClient::clearBootDisplayConfig(
827 int64_t /*display_id*/) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000828 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600829 return ToBinderStatus(hwc3::Error::kUnsupported);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000830}
831
832ndk::ScopedAStatus ComposerClient::getPreferredBootDisplayConfig(
Drew Davenport5951b112024-08-05 09:44:27 -0600833 int64_t /*display_id*/, int32_t* /*config*/) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000834 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600835 return ToBinderStatus(hwc3::Error::kUnsupported);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000836}
837
Drew Davenport5951b112024-08-05 09:44:27 -0600838ndk::ScopedAStatus ComposerClient::setAutoLowLatencyMode(int64_t display_id,
839 bool on) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000840 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600841 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
842 HwcDisplay* display = GetDisplay(display_id);
843 if (display == nullptr) {
844 return ToBinderStatus(hwc3::Error::kBadDisplay);
845 }
846
847 auto error = Hwc2toHwc3Error(display->SetAutoLowLatencyMode(on));
848 return ToBinderStatus(error);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000849}
850
Drew Davenport5951b112024-08-05 09:44:27 -0600851ndk::ScopedAStatus ComposerClient::setClientTargetSlotCount(int64_t display_id,
852 int32_t count) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000853 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600854 return ToBinderStatus(
855 composer_resources_->SetDisplayClientTargetCacheSize(display_id, count));
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000856}
857
Drew Davenport5951b112024-08-05 09:44:27 -0600858ndk::ScopedAStatus ComposerClient::setColorMode(int64_t display_id,
859 ColorMode mode,
860 RenderIntent intent) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000861 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600862 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
863 HwcDisplay* display = GetDisplay(display_id);
864 if (display == nullptr) {
865 return ToBinderStatus(hwc3::Error::kBadDisplay);
866 }
867
868 auto error = display->SetColorModeWithIntent(Hwc3ColorModeToHwc2(mode),
869 Hwc3RenderIntentToHwc2(intent));
870 return ToBinderStatus(Hwc2toHwc3Error(error));
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000871}
872
Drew Davenport5951b112024-08-05 09:44:27 -0600873ndk::ScopedAStatus ComposerClient::setContentType(int64_t display_id,
874 ContentType type) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000875 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600876 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
877 HwcDisplay* display = GetDisplay(display_id);
878 if (display == nullptr) {
879 return ToBinderStatus(hwc3::Error::kBadDisplay);
880 }
881
882 auto error = display->SetContentType(Hwc3ContentTypeToHwc2(type));
883 return ToBinderStatus(Hwc2toHwc3Error(error));
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000884}
885
886ndk::ScopedAStatus ComposerClient::setDisplayedContentSamplingEnabled(
Drew Davenport5951b112024-08-05 09:44:27 -0600887 int64_t /*display_id*/, bool /*enable*/,
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000888 FormatColorComponent /*componentMask*/, int64_t /*maxFrames*/) {
889 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600890 return ToBinderStatus(hwc3::Error::kUnsupported);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000891}
892
Drew Davenport5951b112024-08-05 09:44:27 -0600893ndk::ScopedAStatus ComposerClient::setPowerMode(int64_t display_id,
894 PowerMode mode) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000895 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600896 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
897 HwcDisplay* display = GetDisplay(display_id);
898 if (display == nullptr) {
899 return ToBinderStatus(hwc3::Error::kBadDisplay);
900 }
901
Dennis Tsiang1a966202024-01-24 12:46:33 +0000902 if (mode == PowerMode::ON_SUSPEND) {
903 return ToBinderStatus(hwc3::Error::kUnsupported);
904 }
905
Drew Davenport5951b112024-08-05 09:44:27 -0600906 auto error = display->SetPowerMode(Hwc3PowerModeToHwc2(mode));
907 return ToBinderStatus(Hwc2toHwc3Error(error));
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000908}
909
910ndk::ScopedAStatus ComposerClient::setReadbackBuffer(
Drew Davenport5951b112024-08-05 09:44:27 -0600911 int64_t /*display_id*/, const AidlNativeHandle& /*aidlBuffer*/,
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000912 const ndk::ScopedFileDescriptor& /*releaseFence*/) {
913 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600914 return ToBinderStatus(hwc3::Error::kUnsupported);
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000915}
916
Drew Davenport5951b112024-08-05 09:44:27 -0600917ndk::ScopedAStatus ComposerClient::setVsyncEnabled(int64_t display_id,
918 bool enabled) {
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000919 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600920 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
921 HwcDisplay* display = GetDisplay(display_id);
922 if (display == nullptr) {
923 return ToBinderStatus(hwc3::Error::kBadDisplay);
924 }
925
926 auto error = display->SetVsyncEnabled(static_cast<int32_t>(enabled));
927 return ToBinderStatus(Hwc2toHwc3Error(error));
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000928}
929
Drew Davenport5951b112024-08-05 09:44:27 -0600930ndk::ScopedAStatus ComposerClient::setIdleTimerEnabled(int64_t /*display_id*/,
Dennis Tsiang33f0ece2023-11-29 12:45:04 +0000931 int32_t /*timeout*/) {
932 DEBUG_FUNC();
Drew Davenport5951b112024-08-05 09:44:27 -0600933 return ToBinderStatus(hwc3::Error::kUnsupported);
934}
935
Drew Davenport7f1761b2024-08-20 10:09:43 -0600936ndk::ScopedAStatus ComposerClient::getOverlaySupport(
937 OverlayProperties* /*out_overlay_properties*/) {
938 return ToBinderStatus(hwc3::Error::kUnsupported);
939}
940
941ndk::ScopedAStatus ComposerClient::getHdrConversionCapabilities(
942 std::vector<common::HdrConversionCapability>* /*out_capabilities*/) {
943 return ToBinderStatus(hwc3::Error::kUnsupported);
944}
945
946ndk::ScopedAStatus ComposerClient::setHdrConversionStrategy(
947 const common::HdrConversionStrategy& /*conversion_strategy*/,
948 common::Hdr* /*out_hdr*/) {
949 return ToBinderStatus(hwc3::Error::kUnsupported);
950}
951
952ndk::ScopedAStatus ComposerClient::setRefreshRateChangedCallbackDebugEnabled(
953 int64_t /*display*/, bool /*enabled*/) {
954 return ToBinderStatus(hwc3::Error::kUnsupported);
955}
956
957ndk::ScopedAStatus ComposerClient::getDisplayConfigurations(
Drew Davenportf7e88332024-09-06 12:54:38 -0600958 int64_t display_id, int32_t /*max_frame_interval_ns*/,
Drew Davenport7f1761b2024-08-20 10:09:43 -0600959 std::vector<DisplayConfiguration>* configurations) {
Drew Davenportf7e88332024-09-06 12:54:38 -0600960 DEBUG_FUNC();
961 const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
962 HwcDisplay* display = GetDisplay(display_id);
963 if (display == nullptr) {
964 return ToBinderStatus(hwc3::Error::kBadDisplay);
965 }
966
967 const HwcDisplayConfigs& configs = display->GetDisplayConfigs();
968 for (const auto& [id, config] : configs.hwc_configs) {
969 static const int kNanosecondsPerSecond = 1E9;
970 configurations->emplace_back(
971 DisplayConfiguration{.configId = static_cast<int32_t>(config.id),
972 .width = config.mode.GetRawMode().hdisplay,
973 .height = config.mode.GetRawMode().vdisplay,
974 .configGroup = static_cast<int32_t>(
975 config.group_id),
976 .vsyncPeriod = static_cast<int>(kNanosecondsPerSecond * double(
977 1 / config.mode.GetVRefresh()))});
978
979 if (configs.mm_width != 0) {
980 // ideally this should be vdisplay/mm_heigth, however mm_height
981 // comes from edid parsing and is highly unreliable. Viewing the
982 // rarity of anisotropic displays, falling back to a single value
983 // for dpi yield more correct output.
984 static const float kMmPerInch = 25.4;
985 float dpi = float(config.mode.GetRawMode().hdisplay) * kMmPerInch /
986 float(configs.mm_width);
987 configurations->back().dpi = {.x = dpi, .y = dpi};
988 }
989
990 // TODO: Populate vrrConfig.
991 }
992 return ndk::ScopedAStatus::ok();
Drew Davenport7f1761b2024-08-20 10:09:43 -0600993}
994
995ndk::ScopedAStatus ComposerClient::notifyExpectedPresent(
996 int64_t /*display*/, const ClockMonotonicTimestamp& /*expected_present_time*/,
997 int32_t /*frame_interval_ns*/) {
998 return ToBinderStatus(hwc3::Error::kUnsupported);
999}
1000
Drew Davenport5951b112024-08-05 09:44:27 -06001001std::string ComposerClient::Dump() {
1002 uint32_t size = 0;
1003 hwc_->Dump(&size, nullptr);
1004
1005 std::string buffer(size, '\0');
1006 hwc_->Dump(&size, &buffer.front());
1007 return buffer;
Dennis Tsiang33f0ece2023-11-29 12:45:04 +00001008}
1009
1010::ndk::SpAIBinder ComposerClient::createBinder() {
1011 auto binder = BnComposerClient::createBinder();
1012 AIBinder_setInheritRt(binder.get(), true);
1013 return binder;
1014}
1015
Drew Davenport5951b112024-08-05 09:44:27 -06001016void ComposerClient::ExecuteSetLayerBuffer(int64_t display_id,
1017 HwcLayerWrapper& layer,
1018 const Buffer& buffer) {
1019 buffer_handle_t imported_buffer = nullptr;
1020
1021 auto releaser = composer_resources_->CreateResourceReleaser(true);
1022 auto err = composer_resources_->GetLayerBuffer(display_id, layer.layer_id,
1023 buffer, &imported_buffer,
1024 releaser.get());
1025 if (err != hwc3::Error::kNone) {
1026 cmd_result_writer_->AddError(err);
1027 return;
1028 }
1029
1030 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
1031 auto fence_fd = const_cast<ndk::ScopedFileDescriptor&>(buffer.fence)
1032 .release();
1033 err = Hwc2toHwc3Error(layer.layer->SetLayerBuffer(imported_buffer, fence_fd));
1034 if (err != hwc3::Error::kNone) {
1035 cmd_result_writer_->AddError(err);
1036 }
1037}
1038
1039void ComposerClient::ExecuteSetLayerBlendMode(
1040 int64_t /*display_id*/, HwcLayerWrapper& layer,
1041 const ParcelableBlendMode& blend_mode) {
1042 auto err = Hwc2toHwc3Error(layer.layer->SetLayerBlendMode(
1043 Hwc3BlendModeToHwc2(blend_mode.blendMode)));
1044 if (err != hwc3::Error::kNone) {
1045 cmd_result_writer_->AddError(err);
1046 }
1047}
1048
1049void ComposerClient::ExecuteSetLayerComposition(
1050 int64_t /*display_id*/, HwcLayerWrapper& layer,
1051 const ParcelableComposition& composition) {
1052 hwc3::Error error = hwc3::Error::kNone;
1053 switch (composition.composition) {
1054 // Unsupported composition types should set an error for the current
1055 // DisplayCommand.
1056 case Composition::DISPLAY_DECORATION:
1057 case Composition::SIDEBAND:
1058 error = hwc3::Error::kUnsupported;
1059 break;
1060 default:
1061 error = Hwc2toHwc3Error(layer.layer->SetLayerCompositionType(
1062 Hwc3CompositionToHwc2(composition.composition)));
1063 }
1064 if (error != hwc3::Error::kNone) {
1065 cmd_result_writer_->AddError(error);
1066 }
1067}
1068
1069void ComposerClient::ExecuteSetLayerDataspace(
1070 int64_t /*display_id*/, HwcLayerWrapper& layer,
1071 const ParcelableDataspace& dataspace) {
1072 auto err = Hwc2toHwc3Error(
1073 layer.layer->SetLayerDataspace(Hwc3DataspaceToHwc2(dataspace.dataspace)));
1074 if (err != hwc3::Error::kNone) {
1075 cmd_result_writer_->AddError(err);
1076 }
1077}
1078
1079void ComposerClient::ExecuteSetLayerDisplayFrame(int64_t /*display_id*/,
1080 HwcLayerWrapper& layer,
1081 const common::Rect& rect) {
1082 const hwc_rect_t hwc2_rect{rect.left, rect.top, rect.right, rect.bottom};
1083 auto err = Hwc2toHwc3Error(layer.layer->SetLayerDisplayFrame(hwc2_rect));
1084 if (err != hwc3::Error::kNone) {
1085 cmd_result_writer_->AddError(err);
1086 }
1087}
1088void ComposerClient::ExecuteSetLayerPlaneAlpha(int64_t /*display_id*/,
1089 HwcLayerWrapper& layer,
1090 const PlaneAlpha& plane_alpha) {
1091 auto err = Hwc2toHwc3Error(
1092 layer.layer->SetLayerPlaneAlpha(plane_alpha.alpha));
1093 if (err != hwc3::Error::kNone) {
1094 cmd_result_writer_->AddError(err);
1095 }
1096}
1097
1098void ComposerClient::ExecuteSetLayerSourceCrop(
1099 int64_t /*display_id*/, HwcLayerWrapper& layer,
1100 const common::FRect& source_crop) {
1101 const hwc_frect_t rect{source_crop.left, source_crop.top, source_crop.right,
1102 source_crop.bottom};
1103 auto err = Hwc2toHwc3Error(layer.layer->SetLayerSourceCrop(rect));
1104 if (err != hwc3::Error::kNone) {
1105 cmd_result_writer_->AddError(err);
1106 }
1107}
1108void ComposerClient::ExecuteSetLayerTransform(
1109 int64_t /*display_id*/, HwcLayerWrapper& layer,
1110 const ParcelableTransform& transform) {
1111 auto err = Hwc2toHwc3Error(
1112 layer.layer->SetLayerTransform(Hwc3TransformToHwc2(transform.transform)));
1113 if (err != hwc3::Error::kNone) {
1114 cmd_result_writer_->AddError(err);
1115 }
1116}
1117void ComposerClient::ExecuteSetLayerZOrder(int64_t /*display_id*/,
1118 HwcLayerWrapper& layer,
1119 const ZOrder& z_order) {
1120 auto err = Hwc2toHwc3Error(layer.layer->SetLayerZOrder(z_order.z));
1121 if (err != hwc3::Error::kNone) {
1122 cmd_result_writer_->AddError(err);
1123 }
1124}
1125
1126void ComposerClient::ExecuteSetLayerBrightness(
1127 int64_t /*display_id*/, HwcLayerWrapper& /*layer*/,
1128 const LayerBrightness& brightness) {
1129 if (std::signbit(brightness.brightness) ||
1130 std::isnan(brightness.brightness)) {
1131 cmd_result_writer_->AddError(hwc3::Error::kBadParameter);
1132 }
1133}
1134
1135void ComposerClient::ExecuteSetDisplayBrightness(
1136 uint64_t display_id, const DisplayBrightness& command) {
1137 auto* display = GetDisplay(display_id);
1138 if (display == nullptr) {
1139 cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
1140 return;
1141 }
1142
1143 auto error = Hwc2toHwc3Error(
1144 display->SetDisplayBrightness(command.brightness));
1145 if (error != hwc3::Error::kNone) {
1146 cmd_result_writer_->AddError(error);
1147 }
1148}
1149void ComposerClient::ExecuteSetDisplayColorTransform(
1150 uint64_t display_id, const std::vector<float>& matrix) {
1151 auto* display = GetDisplay(display_id);
1152 if (display == nullptr) {
1153 cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
1154 return;
1155 }
1156
1157 auto almost_equal = [](auto a, auto b) {
1158 const float epsilon = 0.001F;
1159 return std::abs(a - b) < epsilon;
1160 };
1161 const bool is_identity = std::equal(matrix.begin(), matrix.end(),
1162 kIdentityMatrix.begin(), almost_equal);
1163
1164 const int32_t hint = is_identity ? HAL_COLOR_TRANSFORM_IDENTITY
1165 : HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX;
1166
1167 auto error = Hwc2toHwc3Error(display->SetColorTransform(matrix.data(), hint));
1168 if (error != hwc3::Error::kNone) {
1169 cmd_result_writer_->AddError(error);
1170 }
1171}
1172void ComposerClient::ExecuteSetDisplayClientTarget(
1173 uint64_t display_id, const ClientTarget& command) {
1174 auto* display = GetDisplay(display_id);
1175 if (display == nullptr) {
1176 cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
1177 return;
1178 }
1179
1180 hwc_region_t damage_regions;
1181 damage_regions.numRects = command.damage.size();
1182
1183 std::vector<hwc_rect_t> regions(command.damage.size());
1184 for (const auto& region : command.damage) {
1185 regions.push_back({region.left, region.top, region.right, region.bottom});
1186 }
1187 damage_regions.rects = regions.data();
1188
1189 buffer_handle_t imported_buffer = nullptr;
1190 auto buf_releaser = composer_resources_->CreateResourceReleaser(true);
1191
1192 auto error = composer_resources_->GetDisplayClientTarget(display_id,
1193 command.buffer,
1194 &imported_buffer,
1195 buf_releaser.get());
1196 if (error != hwc3::Error::kNone) {
1197 cmd_result_writer_->AddError(error);
1198 return;
1199 }
1200
1201 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
1202 auto fence = const_cast<::ndk::ScopedFileDescriptor&>(command.buffer.fence)
1203 .release();
1204 error = Hwc2toHwc3Error(
1205 display->SetClientTarget(imported_buffer, fence,
1206 Hwc3DataspaceToHwc2(command.dataspace),
1207 damage_regions));
1208 if (error != hwc3::Error::kNone) {
1209 cmd_result_writer_->AddError(error);
1210 }
1211}
1212
1213void ComposerClient::ExecuteSetDisplayOutputBuffer(uint64_t display_id,
1214 const Buffer& buffer) {
1215 auto* display = GetDisplay(display_id);
1216 if (display == nullptr) {
1217 cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
1218 return;
1219 }
1220
1221 buffer_handle_t imported_buffer = nullptr;
1222 auto buf_releaser = composer_resources_->CreateResourceReleaser(true);
1223
1224 auto error = composer_resources_->GetDisplayOutputBuffer(display_id, buffer,
1225 &imported_buffer,
1226 buf_releaser.get());
1227 if (error != hwc3::Error::kNone) {
1228 cmd_result_writer_->AddError(error);
1229 return;
1230 }
1231
1232 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
1233 auto fence = const_cast<::ndk::ScopedFileDescriptor&>(buffer.fence).release();
1234 error = Hwc2toHwc3Error(display->SetOutputBuffer(imported_buffer, fence));
1235 if (error != hwc3::Error::kNone) {
1236 cmd_result_writer_->AddError(error);
1237 return;
1238 }
1239}
1240void ComposerClient::ExecuteValidateDisplay(
1241 int64_t display_id,
1242 std::optional<ClockMonotonicTimestamp> /*expected_present_time*/
1243) {
1244 auto* display = GetDisplay(display_id);
1245 if (display == nullptr) {
1246 cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
1247 return;
1248 }
1249
1250 /* TODO: Handle expectedPresentTime */
Normunds Rieksts42820952024-03-12 15:42:06 +00001251 /* This can be implemented in multiple ways. For example, the expected present
1252 * time property can be implemented by the DRM driver directly as a CRTC
1253 * property. See:
1254 * https://cs.android.com/android/platform/superproject/main/+/b8b3b1646e64d0235f77b9e717a3e4082e26f2a8:hardware/google/graphics/common/libhwc2.1/libdrmresource/drm/drmcrtc.cpp;drc=468f6172546ab98983de18210222f231f16b21e1;l=88
1255 * Unfortunately there doesn't seem to be a standardised way of delaying
1256 * presentation with a timestamp in the DRM API. What we can do alternatively
1257 * is to spawn a separate presentation thread that could handle the VBlank
1258 * events by using DRM_MODE_PAGE_FLIP_EVENT and schedule them appropriately.
1259 */
Drew Davenport5951b112024-08-05 09:44:27 -06001260
1261 std::vector<int64_t> changed_layers;
1262 std::vector<Composition> composition_types;
1263 int32_t display_request_mask = 0;
1264 std::vector<int64_t> requested_layers;
1265 std::vector<int32_t> request_masks;
1266
1267 const hwc3::Error error = ValidateDisplayInternal(*display, &changed_layers,
1268 &composition_types,
1269 &display_request_mask,
1270 &requested_layers,
1271 &request_masks, nullptr,
1272 nullptr);
1273
1274 if (error != hwc3::Error::kNone) {
1275 cmd_result_writer_->AddError(error);
1276 }
1277
1278 // If a CommandError has been been set for the current DisplayCommand, then
1279 // no other results should be returned besides the error.
1280 if (cmd_result_writer_->HasError()) {
1281 return;
1282 }
1283
1284 DisplayChanges changes{};
1285 for (size_t i = 0; i < composition_types.size(); i++) {
1286 changes.AddLayerCompositionChange(display_id, changed_layers[i],
1287 composition_types[i]);
1288 }
1289
1290 std::vector<DisplayRequest::LayerRequest> layer_requests;
1291 for (size_t i = 0; i < requested_layers.size(); i++) {
1292 layer_requests.push_back({requested_layers[i], request_masks[i]});
1293 }
1294
1295 const DisplayRequest request_changes{display_id, display_request_mask,
1296 layer_requests};
1297 changes.display_request_changes = request_changes;
1298
1299 cmd_result_writer_->AddChanges(changes);
1300 composer_resources_->SetDisplayMustValidateState(display_id, false);
1301}
1302
1303void ComposerClient::ExecuteAcceptDisplayChanges(int64_t display_id) {
1304 auto* display = GetDisplay(display_id);
1305 if (display == nullptr) {
1306 cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
1307 return;
1308 }
1309
1310 auto error = Hwc2toHwc3Error(display->AcceptDisplayChanges());
1311 if (error != hwc3::Error::kNone) {
1312 cmd_result_writer_->AddError(error);
1313 return;
1314 }
1315}
1316
1317void ComposerClient::ExecutePresentDisplay(int64_t display_id) {
1318 auto* display = GetDisplay(display_id);
1319 if (display == nullptr) {
1320 cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
1321 return;
1322 }
1323
1324 ::android::base::unique_fd display_fence;
1325 std::unordered_map<int64_t, ::android::base::unique_fd> release_fences;
1326 auto error = PresentDisplayInternal(display_id, display_fence,
1327 release_fences);
1328 if (error != hwc3::Error::kNone) {
1329 cmd_result_writer_->AddError(error);
1330 }
1331 if (cmd_result_writer_->HasError()) {
1332 return;
1333 }
1334
1335 cmd_result_writer_->AddPresentFence(display_id, std::move(display_fence));
1336 cmd_result_writer_->AddReleaseFence(display_id, release_fences);
1337}
1338
1339void ComposerClient::ExecutePresentOrValidateDisplay(
1340 int64_t display_id,
1341 std::optional<ClockMonotonicTimestamp> expected_present_time) {
1342 auto* display = GetDisplay(display_id);
1343 if (display == nullptr) {
1344 cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
1345 return;
1346 }
1347
1348 /* TODO: Handle expectedPresentTime */
Normunds Rieksts42820952024-03-12 15:42:06 +00001349 /* This can be implemented in multiple ways. For example, the expected present
1350 * time property can be implemented by the DRM driver directly as a CRTC
1351 * property. See:
1352 * https://cs.android.com/android/platform/superproject/main/+/b8b3b1646e64d0235f77b9e717a3e4082e26f2a8:hardware/google/graphics/common/libhwc2.1/libdrmresource/drm/drmcrtc.cpp;drc=468f6172546ab98983de18210222f231f16b21e1;l=88
1353 * Unfortunately there doesn't seem to be a standardised way of delaying
1354 * presentation with a timestamp in the DRM API. What we can do alternatively
1355 * is to spawn a separate presentation thread that could handle the VBlank
1356 * events by using DRM_MODE_PAGE_FLIP_EVENT and schedule them appropriately.
1357 */
1358
Drew Davenport5951b112024-08-05 09:44:27 -06001359 /* TODO: Add check if it's possible to skip display validation */
1360 ExecuteValidateDisplay(display_id, expected_present_time);
1361 cmd_result_writer_
1362 ->AddPresentOrValidateResult(display_id,
1363 PresentOrValidate::Result::Validated);
1364}
1365
Dennis Tsiang33f0ece2023-11-29 12:45:04 +00001366} // namespace aidl::android::hardware::graphics::composer3::impl