1 /*
2 * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
3 * Not a Contribution.
4 *
5 * Copyright 2015 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20 #include <QService.h>
21 #include <binder/Parcel.h>
22 #include <core/buffer_allocator.h>
23 #include <cutils/properties.h>
24 #include <display_config.h>
25 #include <hardware_legacy/uevent.h>
26 #include <private/color_params.h>
27 #include <qd_utils.h>
28 #include <sync/sync.h>
29 #include <sys/prctl.h>
30 #include <sys/resource.h>
31 #include <utils/String16.h>
32 #include <utils/constants.h>
33 #include <utils/debug.h>
34 #include <utils/utils.h>
35 #include <algorithm>
36 #include <bitset>
37 #include <memory>
38 #include <string>
39 #include <thread>
40 #include <vector>
41
42 #include "hwc_buffer_allocator.h"
43 #include "hwc_buffer_sync_handler.h"
44 #include "hwc_session.h"
45 #include "hwc_debugger.h"
46 #include "hwc_display_primary.h"
47 #include "hwc_display_virtual.h"
48 #include "hwc_display_external_test.h"
49
50 #define __CLASS__ "HWCSession"
51
52 #define HWC_UEVENT_SWITCH_HDMI "change@/devices/virtual/switch/hdmi"
53 #define HWC_UEVENT_GRAPHICS_FB0 "change@/devices/virtual/graphics/fb0"
54 #define HWC_UEVENT_DRM_EXT_HOTPLUG "mdss_mdp/drm/card"
55
56 #define MAX_BRIGHTNESS 255
57 #define BRIGHTNESS_FILE1 "/sys/class/leds/lcd-backlight/brightness"
58 #define BRIGHTNESS_FILE2 "/sys/class/backlight/panel0-backlight/brightness"
59
60 static sdm::HWCSession::HWCModuleMethods g_hwc_module_methods;
61
62 hwc_module_t HAL_MODULE_INFO_SYM = {
63 .common = {
64 .tag = HARDWARE_MODULE_TAG,
65 .version_major = 3,
66 .version_minor = 0,
67 .id = HWC_HARDWARE_MODULE_ID,
68 .name = "QTI Hardware Composer Module",
69 .author = "CodeAurora Forum",
70 .methods = &g_hwc_module_methods,
71 .dso = 0,
72 .reserved = {0},
73 }
74 };
75
76 namespace sdm {
77
78 static HWCUEvent g_hwc_uevent_;
79 Locker HWCSession::locker_[HWC_NUM_DISPLAY_TYPES];
80 static const int kSolidFillDelay = 100 * 1000;
81
UEventThread(HWCUEvent * hwc_uevent)82 void HWCUEvent::UEventThread(HWCUEvent *hwc_uevent) {
83 const char *uevent_thread_name = "HWC_UeventThread";
84
85 prctl(PR_SET_NAME, uevent_thread_name, 0, 0, 0);
86 setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
87
88 int status = uevent_init();
89 if (!status) {
90 std::unique_lock<std::mutex> caller_lock(hwc_uevent->mutex_);
91 hwc_uevent->caller_cv_.notify_one();
92 DLOGE("Failed to init uevent with err %d", status);
93 return;
94 }
95
96 {
97 // Signal caller thread that worker thread is ready to listen to events.
98 std::unique_lock<std::mutex> caller_lock(hwc_uevent->mutex_);
99 hwc_uevent->init_done_ = true;
100 hwc_uevent->caller_cv_.notify_one();
101 }
102
103 while (1) {
104 char uevent_data[PAGE_SIZE] = {};
105
106 // keep last 2 zeroes to ensure double 0 termination
107 int length = uevent_next_event(uevent_data, INT32(sizeof(uevent_data)) - 2);
108
109 // scope of lock to this block only, so that caller is free to set event handler to nullptr;
110 {
111 std::lock_guard<std::mutex> guard(hwc_uevent->mutex_);
112 if (hwc_uevent->uevent_listener_) {
113 hwc_uevent->uevent_listener_->UEventHandler(uevent_data, length);
114 } else {
115 DLOGW("UEvent dropped. No uevent listener.");
116 }
117 }
118 }
119 }
120
HWCUEvent()121 HWCUEvent::HWCUEvent() {
122 std::unique_lock<std::mutex> caller_lock(mutex_);
123 std::thread thread(HWCUEvent::UEventThread, this);
124 thread.detach();
125 caller_cv_.wait(caller_lock);
126 }
127
Register(HWCUEventListener * uevent_listener)128 void HWCUEvent::Register(HWCUEventListener *uevent_listener) {
129 DLOGI("Set uevent listener = %p", uevent_listener);
130
131 std::lock_guard<std::mutex> obj(mutex_);
132 uevent_listener_ = uevent_listener;
133 }
134
HWCSession(const hw_module_t * module)135 HWCSession::HWCSession(const hw_module_t *module) {
136 hwc2_device_t::common.tag = HARDWARE_DEVICE_TAG;
137 hwc2_device_t::common.version = HWC_DEVICE_API_VERSION_2_0;
138 hwc2_device_t::common.module = const_cast<hw_module_t *>(module);
139 hwc2_device_t::common.close = Close;
140 hwc2_device_t::getCapabilities = GetCapabilities;
141 hwc2_device_t::getFunction = GetFunction;
142 }
143
Init()144 int HWCSession::Init() {
145 SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
146
147 int status = -EINVAL;
148 const char *qservice_name = "display.qservice";
149
150 if (!g_hwc_uevent_.InitDone()) {
151 return status;
152 }
153
154 // Start QService and connect to it.
155 qService::QService::init();
156 android::sp<qService::IQService> iqservice = android::interface_cast<qService::IQService>(
157 android::defaultServiceManager()->getService(android::String16(qservice_name)));
158
159 if (iqservice.get()) {
160 iqservice->connect(android::sp<qClient::IQClient>(this));
161 qservice_ = reinterpret_cast<qService::QService *>(iqservice.get());
162 } else {
163 DLOGE("Failed to acquire %s", qservice_name);
164 return -EINVAL;
165 }
166
167 StartServices();
168
169 g_hwc_uevent_.Register(this);
170
171 auto error = CoreInterface::CreateCore(&buffer_allocator_, &buffer_sync_handler_,
172 &socket_handler_, &core_intf_);
173
174 // If HDMI display is primary display, defer display creation until hotplug event is received.
175 HWDisplayInterfaceInfo hw_disp_info = {};
176 error = core_intf_->GetFirstDisplayInterfaceType(&hw_disp_info);
177 if (error != kErrorNone) {
178 g_hwc_uevent_.Register(nullptr);
179 CoreInterface::DestroyCore();
180 DLOGE("Primary display type not recognized. Error = %d", error);
181 return -EINVAL;
182 }
183
184 if (hw_disp_info.type == kHDMI) {
185 status = 0;
186 hdmi_is_primary_ = true;
187 // Create display if it is connected, else wait for hotplug connect event.
188 if (hw_disp_info.is_connected) {
189 status = CreateExternalDisplay(HWC_DISPLAY_PRIMARY, 0, 0, false);
190 }
191 } else {
192 // Create and power on primary display
193 status = HWCDisplayPrimary::Create(core_intf_, &buffer_allocator_, &callbacks_, qservice_,
194 &hwc_display_[HWC_DISPLAY_PRIMARY]);
195 color_mgr_ = HWCColorManager::CreateColorManager(&buffer_allocator_);
196 if (!color_mgr_) {
197 DLOGW("Failed to load HWCColorManager.");
198 }
199 }
200
201 if (status) {
202 g_hwc_uevent_.Register(nullptr);
203 CoreInterface::DestroyCore();
204 return status;
205 }
206
207 is_composer_up_ = true;
208 struct rlimit fd_limit = {};
209 getrlimit(RLIMIT_NOFILE, &fd_limit);
210 fd_limit.rlim_cur = fd_limit.rlim_cur * 2;
211 if (fd_limit.rlim_cur < fd_limit.rlim_max) {
212 auto err = setrlimit(RLIMIT_NOFILE, &fd_limit);
213 if (err) {
214 DLOGW("Unable to increase fd limit - err:%d, %s", errno, strerror(errno));
215 }
216 }
217
218 char const *brightness_file;
219 if (access(BRIGHTNESS_FILE1, F_OK) == 0) {
220 brightness_file = BRIGHTNESS_FILE1;
221 } else {
222 brightness_file = BRIGHTNESS_FILE2;
223 }
224 brightness_fd_ = open(brightness_file, O_WRONLY);
225 if (brightness_fd_ == -1) {
226 DLOGW("Unable to open brightness file: [%d] %s", errno, strerror(errno));
227 }
228
229 return 0;
230 }
231
Deinit()232 int HWCSession::Deinit() {
233 Locker::SequenceCancelScopeLock lock_v(locker_[HWC_DISPLAY_VIRTUAL]);
234 Locker::SequenceCancelScopeLock lock_e(locker_[HWC_DISPLAY_EXTERNAL]);
235 Locker::SequenceCancelScopeLock lock_p(locker_[HWC_DISPLAY_PRIMARY]);
236
237 HWCDisplay *primary_display = hwc_display_[HWC_DISPLAY_PRIMARY];
238 if (primary_display) {
239 if (hdmi_is_primary_) {
240 HWCDisplayExternal::Destroy(primary_display);
241 } else {
242 HWCDisplayPrimary::Destroy(primary_display);
243 }
244 }
245 hwc_display_[HWC_DISPLAY_PRIMARY] = nullptr;
246
247 if (color_mgr_) {
248 color_mgr_->DestroyColorManager();
249 }
250
251 g_hwc_uevent_.Register(nullptr);
252
253 DisplayError error = CoreInterface::DestroyCore();
254 if (error != kErrorNone) {
255 DLOGE("Display core de-initialization failed. Error = %d", error);
256 }
257
258 close(brightness_fd_);
259
260 return 0;
261 }
262
Open(const hw_module_t * module,const char * name,hw_device_t ** device)263 int HWCSession::Open(const hw_module_t *module, const char *name, hw_device_t **device) {
264 if (!module || !name || !device) {
265 DLOGE("Invalid parameters.");
266 return -EINVAL;
267 }
268
269 if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
270 HWCSession *hwc_session = new HWCSession(module);
271 if (!hwc_session) {
272 return -ENOMEM;
273 }
274
275 int status = hwc_session->Init();
276 if (status != 0) {
277 delete hwc_session;
278 hwc_session = NULL;
279 return status;
280 }
281
282 hwc2_device_t *composer_device = hwc_session;
283 *device = reinterpret_cast<hw_device_t *>(composer_device);
284 }
285
286 return 0;
287 }
288
Close(hw_device_t * device)289 int HWCSession::Close(hw_device_t *device) {
290 if (!device) {
291 return -EINVAL;
292 }
293
294 hwc2_device_t *composer_device = reinterpret_cast<hwc2_device_t *>(device);
295 HWCSession *hwc_session = static_cast<HWCSession *>(composer_device);
296
297 hwc_session->Deinit();
298
299 return 0;
300 }
301
GetCapabilities(struct hwc2_device * device,uint32_t * outCount,int32_t * outCapabilities)302 void HWCSession::GetCapabilities(struct hwc2_device *device, uint32_t *outCount,
303 int32_t *outCapabilities) {
304 if (!outCount) {
305 return;
306 }
307
308 int value = 0;
309 bool disable_skip_validate = false;
310 if (Debug::Get()->GetProperty(DISABLE_SKIP_VALIDATE_PROP, &value) == kErrorNone) {
311 disable_skip_validate = (value == 1);
312 }
313 uint32_t count = 1 + (disable_skip_validate ? 0 : 1);
314
315 if (outCapabilities != nullptr && (*outCount >= count)) {
316 outCapabilities[0] = HWC2_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM;
317 if (!disable_skip_validate) {
318 outCapabilities[1] = HWC2_CAPABILITY_SKIP_VALIDATE;
319 }
320 }
321 *outCount = count;
322 }
323
GetDisplayBrightnessSupport(hwc2_device_t * device,hwc2_display_t display,bool * out_support)324 int32_t HWCSession::GetDisplayBrightnessSupport(hwc2_device_t *device, hwc2_display_t display,
325 bool *out_support) {
326 HWCSession *hwc_session = static_cast<HWCSession *>(device);
327 *out_support = display == HWC_DISPLAY_PRIMARY && hwc_session->brightness_fd_ != -1;
328 return INT32(HWC2::Error::None);
329 }
330
331 template <typename PFN, typename T>
AsFP(T function)332 static hwc2_function_pointer_t AsFP(T function) {
333 static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer");
334 return reinterpret_cast<hwc2_function_pointer_t>(function);
335 }
336
337 // HWC2 functions returned in GetFunction
338 // Defined in the same order as in the HWC2 header
339
AcceptDisplayChanges(hwc2_device_t * device,hwc2_display_t display)340 int32_t HWCSession::AcceptDisplayChanges(hwc2_device_t *device, hwc2_display_t display) {
341 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::AcceptDisplayChanges);
342 }
343
CreateLayer(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t * out_layer_id)344 int32_t HWCSession::CreateLayer(hwc2_device_t *device, hwc2_display_t display,
345 hwc2_layer_t *out_layer_id) {
346 if (!out_layer_id) {
347 return HWC2_ERROR_BAD_PARAMETER;
348 }
349
350 return CallDisplayFunction(device, display, &HWCDisplay::CreateLayer, out_layer_id);
351 }
352
CreateVirtualDisplay(hwc2_device_t * device,uint32_t width,uint32_t height,int32_t * format,hwc2_display_t * out_display_id)353 int32_t HWCSession::CreateVirtualDisplay(hwc2_device_t *device, uint32_t width, uint32_t height,
354 int32_t *format, hwc2_display_t *out_display_id) {
355 // TODO(user): Handle concurrency with HDMI
356 if (!device) {
357 return HWC2_ERROR_BAD_DISPLAY;
358 }
359
360 if (!out_display_id || !width || !height || !format) {
361 return HWC2_ERROR_BAD_PARAMETER;
362 }
363
364 HWCSession *hwc_session = static_cast<HWCSession *>(device);
365 auto status = hwc_session->CreateVirtualDisplayObject(width, height, format);
366
367 if (status == HWC2::Error::None) {
368 *out_display_id = HWC_DISPLAY_VIRTUAL;
369 DLOGI("Created virtual display id:% " PRIu64 " with res: %dx%d",
370 *out_display_id, width, height);
371 } else {
372 DLOGE("Failed to create virtual display: %s", to_string(status).c_str());
373 }
374 return INT32(status);
375 }
376
DestroyLayer(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer)377 int32_t HWCSession::DestroyLayer(hwc2_device_t *device, hwc2_display_t display,
378 hwc2_layer_t layer) {
379 return CallDisplayFunction(device, display, &HWCDisplay::DestroyLayer, layer);
380 }
381
DestroyVirtualDisplay(hwc2_device_t * device,hwc2_display_t display)382 int32_t HWCSession::DestroyVirtualDisplay(hwc2_device_t *device, hwc2_display_t display) {
383 if (!device || display != HWC_DISPLAY_VIRTUAL) {
384 return HWC2_ERROR_BAD_DISPLAY;
385 }
386
387 SCOPE_LOCK(locker_[display]);
388 DLOGI("Destroying virtual display id:%" PRIu64, display);
389 auto *hwc_session = static_cast<HWCSession *>(device);
390
391 if (hwc_session->hwc_display_[display]) {
392 HWCDisplayVirtual::Destroy(hwc_session->hwc_display_[display]);
393 hwc_session->hwc_display_[display] = nullptr;
394 return HWC2_ERROR_NONE;
395 } else {
396 return HWC2_ERROR_BAD_DISPLAY;
397 }
398 }
399
Dump(hwc2_device_t * device,uint32_t * out_size,char * out_buffer)400 void HWCSession::Dump(hwc2_device_t *device, uint32_t *out_size, char *out_buffer) {
401 if (!device || !out_size) {
402 return;
403 }
404
405 auto *hwc_session = static_cast<HWCSession *>(device);
406 const size_t max_dump_size = 8192;
407
408 if (out_buffer == nullptr) {
409 *out_size = max_dump_size;
410 } else {
411 std::string s {};
412 for (int id = HWC_DISPLAY_PRIMARY; id <= HWC_DISPLAY_VIRTUAL; id++) {
413 SCOPE_LOCK(locker_[id]);
414 if (hwc_session->hwc_display_[id]) {
415 s += hwc_session->hwc_display_[id]->Dump();
416 }
417 }
418 auto copied = s.copy(out_buffer, std::min(s.size(), max_dump_size), 0);
419 *out_size = UINT32(copied);
420 }
421 }
422
GetActiveConfig(hwc2_device_t * device,hwc2_display_t display,hwc2_config_t * out_config)423 static int32_t GetActiveConfig(hwc2_device_t *device, hwc2_display_t display,
424 hwc2_config_t *out_config) {
425 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetActiveConfig, out_config);
426 }
427
GetChangedCompositionTypes(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_elements,hwc2_layer_t * out_layers,int32_t * out_types)428 static int32_t GetChangedCompositionTypes(hwc2_device_t *device, hwc2_display_t display,
429 uint32_t *out_num_elements, hwc2_layer_t *out_layers,
430 int32_t *out_types) {
431 // null_ptr check only for out_num_elements, as out_layers and out_types can be null.
432 if (!out_num_elements) {
433 return HWC2_ERROR_BAD_PARAMETER;
434 }
435 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetChangedCompositionTypes,
436 out_num_elements, out_layers, out_types);
437 }
438
GetClientTargetSupport(hwc2_device_t * device,hwc2_display_t display,uint32_t width,uint32_t height,int32_t format,int32_t dataspace)439 static int32_t GetClientTargetSupport(hwc2_device_t *device, hwc2_display_t display, uint32_t width,
440 uint32_t height, int32_t format, int32_t dataspace) {
441 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetClientTargetSupport,
442 width, height, format, dataspace);
443 }
444
GetColorModes(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_modes,int32_t * int_out_modes)445 static int32_t GetColorModes(hwc2_device_t *device, hwc2_display_t display, uint32_t *out_num_modes,
446 int32_t /*ColorMode*/ *int_out_modes) {
447 auto out_modes = reinterpret_cast<ColorMode *>(int_out_modes);
448 if (out_num_modes == nullptr) {
449 return HWC2_ERROR_BAD_PARAMETER;
450 }
451 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetColorModes, out_num_modes,
452 out_modes);
453 }
454
GetRenderIntents(hwc2_device_t * device,hwc2_display_t display,int32_t int_mode,uint32_t * out_num_intents,int32_t * int_out_intents)455 static int32_t GetRenderIntents(hwc2_device_t *device, hwc2_display_t display,
456 int32_t /*ColorMode*/ int_mode, uint32_t *out_num_intents,
457 int32_t /*RenderIntent*/ *int_out_intents) {
458 auto mode = static_cast<ColorMode>(int_mode);
459 auto out_intents = reinterpret_cast<RenderIntent *>(int_out_intents);
460 if (out_num_intents == nullptr) {
461 return HWC2_ERROR_BAD_PARAMETER;
462 }
463
464 if (mode < ColorMode::NATIVE || mode > ColorMode::BT2100_HLG) {
465 DLOGE("Invalid ColorMode: %d", mode);
466 return HWC2_ERROR_BAD_PARAMETER;
467 }
468 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetRenderIntents, mode,
469 out_num_intents, out_intents);
470 }
471
GetDataspaceSaturationMatrix(hwc2_device_t * device,int32_t int_dataspace,float * out_matrix)472 static int32_t GetDataspaceSaturationMatrix(hwc2_device_t *device,
473 int32_t /*Dataspace*/ int_dataspace,
474 float *out_matrix) {
475 auto dataspace = static_cast<Dataspace>(int_dataspace);
476 if (device == nullptr || out_matrix == nullptr || dataspace != Dataspace::SRGB_LINEAR) {
477 return HWC2_ERROR_BAD_PARAMETER;
478 }
479 // We only have the matrix for sRGB
480 float saturation_matrix[kDataspaceSaturationMatrixCount] = { 1.0, 0.0, 0.0, 0.0, \
481 0.0, 1.0, 0.0, 0.0, \
482 0.0, 0.0, 1.0, 0.0, \
483 0.0, 0.0, 0.0, 1.0 };
484
485 // TODO(user): This value should ideally be retrieved from a QDCM configuration file
486 char value[kPropertyMax] = {};
487 if (Debug::Get()->GetProperty(DATASPACE_SATURATION_MATRIX_PROP, value) != kErrorNone) {
488 DLOGW("Undefined saturation matrix");
489 return HWC2_ERROR_BAD_CONFIG;
490 }
491 std::string value_string(value);
492 std::size_t start = 0, end = 0;
493 int index = 0;
494 while ((end = value_string.find(",", start)) != std::string::npos) {
495 saturation_matrix[index] = std::stof(value_string.substr(start, end - start));
496 start = end + 1;
497 index++;
498 // We expect a 3x3, SF needs 4x4, keep the last row/column identity
499 if ((index + 1) % 4 == 0) {
500 index++;
501 }
502 }
503 saturation_matrix[index] = std::stof(value_string.substr(start, end - start));
504 if (index < kDataspaceSaturationPropertyElements - 1) {
505 // The property must have kDataspaceSaturationPropertyElements delimited by commas
506 DLOGW("Invalid saturation matrix defined");
507 return HWC2_ERROR_BAD_CONFIG;
508 }
509 for (int32_t i = 0; i < kDataspaceSaturationMatrixCount; i += 4) {
510 DLOGD("%f %f %f %f", saturation_matrix[i], saturation_matrix[i + 1], saturation_matrix[i + 2],
511 saturation_matrix[i + 3]);
512 }
513 for (uint32_t i = 0; i < kDataspaceSaturationMatrixCount; i++) {
514 out_matrix[i] = saturation_matrix[i];
515 }
516 return HWC2_ERROR_NONE;
517 }
518
GetPerFrameMetadataKeys(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_keys,int32_t * int_out_keys)519 static int32_t GetPerFrameMetadataKeys(hwc2_device_t *device, hwc2_display_t display,
520 uint32_t *out_num_keys, int32_t *int_out_keys) {
521 auto out_keys = reinterpret_cast<PerFrameMetadataKey *>(int_out_keys);
522 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetPerFrameMetadataKeys,
523 out_num_keys, out_keys);
524 }
525
SetLayerPerFrameMetadata(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,uint32_t num_elements,const int32_t * int_keys,const float * metadata)526 static int32_t SetLayerPerFrameMetadata(hwc2_device_t *device, hwc2_display_t display,
527 hwc2_layer_t layer, uint32_t num_elements,
528 const int32_t *int_keys, const float *metadata) {
529 auto keys = reinterpret_cast<const PerFrameMetadataKey *>(int_keys);
530 return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerPerFrameMetadata,
531 num_elements, keys, metadata);
532 }
533
SetDisplayedContentSamplingEnabled(hwc2_device_t * device,hwc2_display_t display,int32_t enabled,uint8_t component_mask,uint64_t max_frames)534 static int32_t SetDisplayedContentSamplingEnabled(hwc2_device_t* device,
535 hwc2_display_t display,
536 int32_t enabled, uint8_t component_mask,
537 uint64_t max_frames) {
538 static constexpr int32_t validComponentMask =
539 HWC2_FORMAT_COMPONENT_0 | HWC2_FORMAT_COMPONENT_1 |
540 HWC2_FORMAT_COMPONENT_2 | HWC2_FORMAT_COMPONENT_3;
541 if (component_mask & ~validComponentMask) return HWC2_ERROR_BAD_PARAMETER;
542 return HWCSession::CallDisplayFunction(device, display,
543 &HWCDisplay::SetDisplayedContentSamplingEnabled,
544 enabled, component_mask, max_frames);
545 }
546
GetDisplayedContentSamplingAttributes(hwc2_device_t * device,hwc2_display_t display,int32_t * format,int32_t * dataspace,uint8_t * supported_components)547 static int32_t GetDisplayedContentSamplingAttributes(hwc2_device_t* device,
548 hwc2_display_t display,
549 int32_t* format,
550 int32_t* dataspace,
551 uint8_t* supported_components) {
552 return HWCSession::CallDisplayFunction(device, display,
553 &HWCDisplay::GetDisplayedContentSamplingAttributes,
554 format, dataspace, supported_components);
555 }
556
GetDisplayedContentSample(hwc2_device_t * device,hwc2_display_t display,uint64_t max_frames,uint64_t timestamp,uint64_t * numFrames,int32_t samples_size[NUM_HISTOGRAM_COLOR_COMPONENTS],uint64_t * samples[NUM_HISTOGRAM_COLOR_COMPONENTS])557 static int32_t GetDisplayedContentSample(
558 hwc2_device_t* device, hwc2_display_t display, uint64_t max_frames, uint64_t timestamp,
559 uint64_t* numFrames,
560 int32_t samples_size[NUM_HISTOGRAM_COLOR_COMPONENTS],
561 uint64_t* samples[NUM_HISTOGRAM_COLOR_COMPONENTS]) {
562
563 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayedContentSample,
564 max_frames, timestamp, numFrames, samples_size, samples);
565 }
566
GetDisplayAttribute(hwc2_device_t * device,hwc2_display_t display,hwc2_config_t config,int32_t int_attribute,int32_t * out_value)567 static int32_t GetDisplayAttribute(hwc2_device_t *device, hwc2_display_t display,
568 hwc2_config_t config, int32_t int_attribute,
569 int32_t *out_value) {
570 if (out_value == nullptr || int_attribute < HWC2_ATTRIBUTE_INVALID ||
571 int_attribute > HWC2_ATTRIBUTE_DPI_Y) {
572 return HWC2_ERROR_BAD_PARAMETER;
573 }
574 auto attribute = static_cast<HWC2::Attribute>(int_attribute);
575 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayAttribute, config,
576 attribute, out_value);
577 }
578
GetDisplayConfigs(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_configs,hwc2_config_t * out_configs)579 static int32_t GetDisplayConfigs(hwc2_device_t *device, hwc2_display_t display,
580 uint32_t *out_num_configs, hwc2_config_t *out_configs) {
581 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayConfigs,
582 out_num_configs, out_configs);
583 }
584
GetDisplayName(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_size,char * out_name)585 static int32_t GetDisplayName(hwc2_device_t *device, hwc2_display_t display, uint32_t *out_size,
586 char *out_name) {
587 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayName, out_size,
588 out_name);
589 }
590
GetDisplayRequests(hwc2_device_t * device,hwc2_display_t display,int32_t * out_display_requests,uint32_t * out_num_elements,hwc2_layer_t * out_layers,int32_t * out_layer_requests)591 static int32_t GetDisplayRequests(hwc2_device_t *device, hwc2_display_t display,
592 int32_t *out_display_requests, uint32_t *out_num_elements,
593 hwc2_layer_t *out_layers, int32_t *out_layer_requests) {
594 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayRequests,
595 out_display_requests, out_num_elements, out_layers,
596 out_layer_requests);
597 }
598
GetDisplayType(hwc2_device_t * device,hwc2_display_t display,int32_t * out_type)599 static int32_t GetDisplayType(hwc2_device_t *device, hwc2_display_t display, int32_t *out_type) {
600 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayType, out_type);
601 }
602
GetDozeSupport(hwc2_device_t * device,hwc2_display_t display,int32_t * out_support)603 int32_t HWCSession::GetDozeSupport(hwc2_device_t *device, hwc2_display_t display,
604 int32_t *out_support) {
605 if (!device || !out_support) {
606 return HWC2_ERROR_BAD_PARAMETER;
607 }
608
609 HWCSession *hwc_session = static_cast<HWCSession *>(device);
610 if (display >= HWC_NUM_DISPLAY_TYPES || (hwc_session->hwc_display_[display] == nullptr) ) {
611 return HWC2_ERROR_BAD_DISPLAY;
612 }
613
614 if (display == HWC_DISPLAY_PRIMARY) {
615 *out_support = 1;
616 } else {
617 *out_support = 0;
618 }
619
620 return HWC2_ERROR_NONE;
621 }
622
GetHdrCapabilities(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_types,int32_t * out_types,float * out_max_luminance,float * out_max_average_luminance,float * out_min_luminance)623 static int32_t GetHdrCapabilities(hwc2_device_t* device, hwc2_display_t display,
624 uint32_t* out_num_types, int32_t* out_types,
625 float* out_max_luminance, float* out_max_average_luminance,
626 float* out_min_luminance) {
627 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetHdrCapabilities,
628 out_num_types, out_types, out_max_luminance,
629 out_max_average_luminance, out_min_luminance);
630 }
631
GetMaxVirtualDisplayCount(hwc2_device_t * device)632 static uint32_t GetMaxVirtualDisplayCount(hwc2_device_t *device) {
633 if (device == nullptr) {
634 return HWC2_ERROR_BAD_PARAMETER;
635 }
636
637 return 1;
638 }
639
GetReleaseFences(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_elements,hwc2_layer_t * out_layers,int32_t * out_fences)640 static int32_t GetReleaseFences(hwc2_device_t *device, hwc2_display_t display,
641 uint32_t *out_num_elements, hwc2_layer_t *out_layers,
642 int32_t *out_fences) {
643 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetReleaseFences,
644 out_num_elements, out_layers, out_fences);
645 }
646
PresentDisplay(hwc2_device_t * device,hwc2_display_t display,int32_t * out_retire_fence)647 int32_t HWCSession::PresentDisplay(hwc2_device_t *device, hwc2_display_t display,
648 int32_t *out_retire_fence) {
649 HWCSession *hwc_session = static_cast<HWCSession *>(device);
650 bool notify_hotplug = false;
651 auto status = HWC2::Error::BadDisplay;
652 DTRACE_SCOPED();
653
654 if (display >= HWC_NUM_DISPLAY_TYPES || (hwc_session->hwc_display_[display] == nullptr)) {
655 return HWC2_ERROR_BAD_DISPLAY;
656 }
657
658 {
659 SEQUENCE_EXIT_SCOPE_LOCK(locker_[display]);
660 if (!device) {
661 return HWC2_ERROR_BAD_DISPLAY;
662 }
663
664 if (out_retire_fence == nullptr) {
665 return HWC2_ERROR_BAD_PARAMETER;
666 }
667
668 // TODO(user): Handle virtual display/HDMI concurrency
669 status = hwc_session->PresentDisplayInternal(display, out_retire_fence);
670 }
671
672 if (status != HWC2::Error::None && status != HWC2::Error::NotValidated) {
673 SEQUENCE_CANCEL_SCOPE_LOCK(locker_[display]);
674 }
675
676 // Handle Pending external display connection
677 if (hwc_session->external_pending_connect_ && (display == HWC_DISPLAY_PRIMARY)) {
678 Locker::ScopeLock lock_e(locker_[HWC_DISPLAY_EXTERNAL]);
679 Locker::ScopeLock lock_v(locker_[HWC_DISPLAY_VIRTUAL]);
680
681 if (!hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL]) {
682 DLOGD("Process pending external display connection");
683 hwc_session->ConnectDisplay(HWC_DISPLAY_EXTERNAL);
684 hwc_session->external_pending_connect_ = false;
685 notify_hotplug = true;
686 }
687 }
688
689 if (notify_hotplug) {
690 hwc_session->HotPlug(HWC_DISPLAY_EXTERNAL, HWC2::Connection::Connected);
691 }
692
693 return INT32(status);
694 }
695
RegisterCallback(hwc2_device_t * device,int32_t descriptor,hwc2_callback_data_t callback_data,hwc2_function_pointer_t pointer)696 int32_t HWCSession::RegisterCallback(hwc2_device_t *device, int32_t descriptor,
697 hwc2_callback_data_t callback_data,
698 hwc2_function_pointer_t pointer) {
699 if (!device) {
700 return HWC2_ERROR_BAD_PARAMETER;
701 }
702 HWCSession *hwc_session = static_cast<HWCSession *>(device);
703 SCOPE_LOCK(hwc_session->callbacks_lock_);
704 auto desc = static_cast<HWC2::Callback>(descriptor);
705 auto error = hwc_session->callbacks_.Register(desc, callback_data, pointer);
706 DLOGD("%s callback: %s", pointer ? "Registering" : "Deregistering", to_string(desc).c_str());
707 if (descriptor == HWC2_CALLBACK_HOTPLUG) {
708 if (hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY]) {
709 hwc_session->callbacks_.Hotplug(HWC_DISPLAY_PRIMARY, HWC2::Connection::Connected);
710 }
711 }
712 hwc_session->need_invalidate_ = false;
713 hwc_session->callbacks_lock_.Broadcast();
714 return INT32(error);
715 }
716
SetActiveConfig(hwc2_device_t * device,hwc2_display_t display,hwc2_config_t config)717 static int32_t SetActiveConfig(hwc2_device_t *device, hwc2_display_t display,
718 hwc2_config_t config) {
719 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetActiveConfig, config);
720 }
721
SetClientTarget(hwc2_device_t * device,hwc2_display_t display,buffer_handle_t target,int32_t acquire_fence,int32_t dataspace,hwc_region_t damage)722 static int32_t SetClientTarget(hwc2_device_t *device, hwc2_display_t display,
723 buffer_handle_t target, int32_t acquire_fence,
724 int32_t dataspace, hwc_region_t damage) {
725 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetClientTarget, target,
726 acquire_fence, dataspace, damage);
727 }
728
SetColorMode(hwc2_device_t * device,hwc2_display_t display,int32_t int_mode)729 int32_t HWCSession::SetColorMode(hwc2_device_t *device, hwc2_display_t display,
730 int32_t /*ColorMode*/ int_mode) {
731 auto mode = static_cast<ColorMode>(int_mode);
732 if (mode < ColorMode::NATIVE || mode > ColorMode::BT2100_HLG) {
733 return HWC2_ERROR_BAD_PARAMETER;
734 }
735 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
736 }
737
SetColorModeWithRenderIntent(hwc2_device_t * device,hwc2_display_t display,int32_t int_mode,int32_t int_render_intent)738 int32_t HWCSession::SetColorModeWithRenderIntent(hwc2_device_t *device, hwc2_display_t display,
739 int32_t /*ColorMode*/ int_mode,
740 int32_t /*RenderIntent*/ int_render_intent) {
741 auto mode = static_cast<ColorMode>(int_mode);
742 if (mode < ColorMode::NATIVE || mode > ColorMode::BT2100_HLG) {
743 return HWC2_ERROR_BAD_PARAMETER;
744 }
745 auto render_intent = static_cast<RenderIntent>(int_render_intent);
746 if ((render_intent < RenderIntent::COLORIMETRIC) ||
747 (render_intent > RenderIntent::TONE_MAP_ENHANCE)) {
748 DLOGE("Invalid RenderIntent: %d", render_intent);
749 return HWC2_ERROR_BAD_PARAMETER;
750 }
751 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorModeWithRenderIntent,
752 mode, render_intent);
753 }
754
SetColorTransform(hwc2_device_t * device,hwc2_display_t display,const float * matrix,int32_t hint)755 int32_t HWCSession::SetColorTransform(hwc2_device_t *device, hwc2_display_t display,
756 const float *matrix,
757 int32_t /*android_color_transform_t*/ hint) {
758 if (!matrix || hint < HAL_COLOR_TRANSFORM_IDENTITY ||
759 hint > HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA) {
760 return HWC2_ERROR_BAD_PARAMETER;
761 }
762 android_color_transform_t transform_hint = static_cast<android_color_transform_t>(hint);
763 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorTransform, matrix,
764 transform_hint);
765 }
766
SetCursorPosition(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t x,int32_t y)767 static int32_t SetCursorPosition(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
768 int32_t x, int32_t y) {
769 auto status = INT32(HWC2::Error::None);
770 status = HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetCursorPosition,
771 layer, x, y);
772 if (status == INT32(HWC2::Error::None)) {
773 // Update cursor position
774 HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetCursorPosition, x, y);
775 }
776 return status;
777 }
778
SetLayerBlendMode(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t int_mode)779 static int32_t SetLayerBlendMode(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
780 int32_t int_mode) {
781 if (int_mode < HWC2_BLEND_MODE_INVALID || int_mode > HWC2_BLEND_MODE_COVERAGE) {
782 return HWC2_ERROR_BAD_PARAMETER;
783 }
784 auto mode = static_cast<HWC2::BlendMode>(int_mode);
785 return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerBlendMode, mode);
786 }
787
SetLayerBuffer(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,buffer_handle_t buffer,int32_t acquire_fence)788 static int32_t SetLayerBuffer(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
789 buffer_handle_t buffer, int32_t acquire_fence) {
790 return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerBuffer, buffer,
791 acquire_fence);
792 }
793
SetLayerColor(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_color_t color)794 static int32_t SetLayerColor(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
795 hwc_color_t color) {
796 return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerColor, color);
797 }
798
SetLayerCompositionType(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t int_type)799 static int32_t SetLayerCompositionType(hwc2_device_t *device, hwc2_display_t display,
800 hwc2_layer_t layer, int32_t int_type) {
801 auto type = static_cast<HWC2::Composition>(int_type);
802 return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerCompositionType,
803 type);
804 }
805
SetLayerDataspace(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t dataspace)806 static int32_t SetLayerDataspace(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
807 int32_t dataspace) {
808 return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerDataspace,
809 dataspace);
810 }
811
SetLayerDisplayFrame(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_rect_t frame)812 static int32_t SetLayerDisplayFrame(hwc2_device_t *device, hwc2_display_t display,
813 hwc2_layer_t layer, hwc_rect_t frame) {
814 return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerDisplayFrame,
815 frame);
816 }
817
SetLayerPlaneAlpha(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,float alpha)818 static int32_t SetLayerPlaneAlpha(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
819 float alpha) {
820 return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerPlaneAlpha,
821 alpha);
822 }
823
SetLayerSourceCrop(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_frect_t crop)824 static int32_t SetLayerSourceCrop(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
825 hwc_frect_t crop) {
826 return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerSourceCrop, crop);
827 }
828
SetLayerSurfaceDamage(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_region_t damage)829 static int32_t SetLayerSurfaceDamage(hwc2_device_t *device, hwc2_display_t display,
830 hwc2_layer_t layer, hwc_region_t damage) {
831 return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerSurfaceDamage,
832 damage);
833 }
834
SetLayerTransform(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t int_transform)835 static int32_t SetLayerTransform(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
836 int32_t int_transform) {
837 auto transform = static_cast<HWC2::Transform>(int_transform);
838 return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerTransform,
839 transform);
840 }
841
SetLayerVisibleRegion(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_region_t visible)842 static int32_t SetLayerVisibleRegion(hwc2_device_t *device, hwc2_display_t display,
843 hwc2_layer_t layer, hwc_region_t visible) {
844 return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerVisibleRegion,
845 visible);
846 }
847
SetLayerZOrder(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,uint32_t z)848 static int32_t SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
849 uint32_t z) {
850 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetLayerZOrder, layer, z);
851 }
852
SetOutputBuffer(hwc2_device_t * device,hwc2_display_t display,buffer_handle_t buffer,int32_t releaseFence)853 int32_t HWCSession::SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
854 buffer_handle_t buffer, int32_t releaseFence) {
855 if (!device) {
856 return HWC2_ERROR_BAD_PARAMETER;
857 }
858
859 if (display != HWC_DISPLAY_VIRTUAL) {
860 return HWC2_ERROR_UNSUPPORTED;
861 }
862
863 SCOPE_LOCK(locker_[display]);
864 auto *hwc_session = static_cast<HWCSession *>(device);
865 if (hwc_session->hwc_display_[display]) {
866 auto vds = reinterpret_cast<HWCDisplayVirtual *>(hwc_session->hwc_display_[display]);
867 auto status = vds->SetOutputBuffer(buffer, releaseFence);
868 return INT32(status);
869 } else {
870 return HWC2_ERROR_BAD_DISPLAY;
871 }
872 }
873
SetPowerMode(hwc2_device_t * device,hwc2_display_t display,int32_t int_mode)874 int32_t HWCSession::SetPowerMode(hwc2_device_t *device, hwc2_display_t display, int32_t int_mode) {
875 if (display >= HWC_NUM_DISPLAY_TYPES) {
876 return HWC2_ERROR_BAD_DISPLAY;
877 }
878
879 // validate device and also avoid undefined behavior in cast to HWC2::PowerMode
880 if (!device || int_mode < HWC2_POWER_MODE_OFF || int_mode > HWC2_POWER_MODE_DOZE_SUSPEND) {
881 return HWC2_ERROR_BAD_PARAMETER;
882 }
883
884 auto mode = static_cast<HWC2::PowerMode>(int_mode);
885
886 // all displays support on/off. Check for doze modes
887 int support = 0;
888
889 auto status = GetDozeSupport(device, display, &support);
890 if (status != HWC2_ERROR_NONE) {
891 return INT32(status);
892 }
893
894 if (!support && (mode == HWC2::PowerMode::Doze || mode == HWC2::PowerMode::DozeSuspend)) {
895 return HWC2_ERROR_UNSUPPORTED;
896 }
897
898 auto error = CallDisplayFunction(device, display, &HWCDisplay::SetPowerMode, mode);
899 if (error != HWC2_ERROR_NONE) {
900 return error;
901 }
902 // Reset idle pc ref count on suspend, as we enable idle pc during suspend.
903 if (mode == HWC2::PowerMode::Off) {
904 HWCSession *hwc_session = static_cast<HWCSession *>(device);
905 hwc_session->idle_pc_ref_cnt_ = 0;
906 }
907
908 return HWC2_ERROR_NONE;
909 }
910
SetVsyncEnabled(hwc2_device_t * device,hwc2_display_t display,int32_t int_enabled)911 static int32_t SetVsyncEnabled(hwc2_device_t *device, hwc2_display_t display, int32_t int_enabled) {
912 // avoid undefined behavior in cast to HWC2::Vsync
913 if (int_enabled < HWC2_VSYNC_INVALID || int_enabled > HWC2_VSYNC_DISABLE) {
914 return HWC2_ERROR_BAD_PARAMETER;
915 }
916
917 auto enabled = static_cast<HWC2::Vsync>(int_enabled);
918 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetVsyncEnabled, enabled);
919 }
920
ValidateDisplay(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_types,uint32_t * out_num_requests)921 int32_t HWCSession::ValidateDisplay(hwc2_device_t *device, hwc2_display_t display,
922 uint32_t *out_num_types, uint32_t *out_num_requests) {
923 // out_num_types and out_num_requests will be non-NULL
924 if (!device) {
925 return HWC2_ERROR_BAD_PARAMETER;
926 }
927
928 if (display >= HWC_NUM_DISPLAY_TYPES) {
929 return HWC2_ERROR_BAD_DISPLAY;
930 }
931
932 DTRACE_SCOPED();
933 HWCSession *hwc_session = static_cast<HWCSession *>(device);
934 // TODO(user): Handle secure session, handle QDCM solid fill
935 // Handle external_pending_connect_ in CreateVirtualDisplay
936 auto status = HWC2::Error::BadDisplay;
937 {
938 SEQUENCE_ENTRY_SCOPE_LOCK(locker_[display]);
939 if (hwc_session->hwc_display_[display]) {
940 status = hwc_session->ValidateDisplayInternal(display, out_num_types, out_num_requests);
941 }
942 }
943
944 // Sequence locking currently begins on Validate, so cancel the sequence lock on failures
945 if (status != HWC2::Error::None && status != HWC2::Error::HasChanges) {
946 SEQUENCE_CANCEL_SCOPE_LOCK(locker_[display]);
947 }
948
949 return INT32(status);
950 }
951
GetDisplayCapabilities(hwc2_device_t * device,hwc2_display_t display,uint32_t * outNumCapabilities,uint32_t * outCapabilities)952 int32_t HWCSession::GetDisplayCapabilities(hwc2_device_t* device, hwc2_display_t display,
953 uint32_t* outNumCapabilities, uint32_t* outCapabilities) {
954 if (outNumCapabilities == nullptr) {
955 return INT32(HWC2::Error::None);
956 }
957
958 bool brightness_support = false;
959 auto status = GetDisplayBrightnessSupport(device, display, &brightness_support);
960 if (status != HWC2_ERROR_NONE) {
961 DLOGE("Failed to get display brightness support Error = %d", status);
962 return INT32(status);
963 }
964 int doze_support = 0;
965 status = GetDozeSupport(device, display, &doze_support);
966 if (status != HWC2_ERROR_NONE) {
967 DLOGE("Failed to get doze support Error = %d", status);
968 return INT32(status);
969 }
970
971 uint32_t count = 1 + static_cast<uint32_t>(doze_support) + (brightness_support ? 1 : 0);
972 int index = 0;
973 if (outCapabilities != nullptr && (*outNumCapabilities >= count)) {
974 outCapabilities[index++] = HWC2_DISPLAY_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM;
975 if (doze_support == 1) {
976 outCapabilities[index++] = HWC2_DISPLAY_CAPABILITY_DOZE;
977 }
978 if (brightness_support) {
979 outCapabilities[index++] = HWC2_DISPLAY_CAPABILITY_BRIGHTNESS;
980 }
981 }
982
983 *outNumCapabilities = count;
984 return INT32(HWC2::Error::None);
985 }
986
SetDisplayBrightness(hwc2_device_t * device,hwc2_display_t display,float brightness)987 int32_t HWCSession::SetDisplayBrightness(hwc2_device_t *device, hwc2_display_t display,
988 float brightness) {
989 bool brightness_support = false;
990 auto status = GetDisplayBrightnessSupport(device, display, &brightness_support);
991 if (status != HWC2_ERROR_NONE) {
992 return INT32(status);
993 }
994 if (!brightness_support) {
995 return HWC2_ERROR_UNSUPPORTED;
996 }
997 int backlight = -1;
998 if (brightness == -1.0f) {
999 backlight = 0;
1000 } else if (brightness < 0.0f || brightness > 1.0f) {
1001 return INT32(HWC2::Error::BadParameter);
1002 } else {
1003 // 0 is reserved for "backlight off", so we scale the brightness from 1 to MAX_BRIGHTNESS.
1004 backlight = (int) ((MAX_BRIGHTNESS - 1.0f) * brightness + 1.0f);
1005 }
1006 char buff[20];
1007 int n = snprintf(buff, sizeof(buff), "%d\n", backlight);
1008 if (n < 0 || n >= sizeof(buff)) {
1009 return INT32(HWC2::Error::BadParameter);
1010 }
1011
1012 HWCSession *hwc_session = static_cast<HWCSession *>(device);
1013 long error = lseek(hwc_session->brightness_fd_, 0, SEEK_SET);
1014 if (error == -1) {
1015 DLOGW("Failed to rewind brightness file: [%d] %s", errno, strerror(errno));
1016 return INT32(HWC2::Error::NoResources);
1017 }
1018 error = write(hwc_session->brightness_fd_, buff, (size_t) n);
1019 if (error == -1) {
1020 DLOGW("Failed to write to brightness file: [%d] %s", errno, strerror(errno));
1021 return INT32(HWC2::Error::NoResources);
1022 }
1023 error = fsync(hwc_session->brightness_fd_);
1024 if (error == -1) {
1025 DLOGW("Failed to flush brightness file: [%d] %s", errno, strerror(errno));
1026 return INT32(HWC2::Error::NoResources);
1027 }
1028
1029 return INT32(HWC2::Error::None);
1030 }
1031
GetFunction(struct hwc2_device * device,int32_t int_descriptor)1032 hwc2_function_pointer_t HWCSession::GetFunction(struct hwc2_device *device,
1033 int32_t int_descriptor) {
1034 auto descriptor = static_cast<HWC2::FunctionDescriptor>(int_descriptor);
1035
1036 switch (descriptor) {
1037 case HWC2::FunctionDescriptor::AcceptDisplayChanges:
1038 return AsFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(HWCSession::AcceptDisplayChanges);
1039 case HWC2::FunctionDescriptor::CreateLayer:
1040 return AsFP<HWC2_PFN_CREATE_LAYER>(CreateLayer);
1041 case HWC2::FunctionDescriptor::CreateVirtualDisplay:
1042 return AsFP<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(HWCSession::CreateVirtualDisplay);
1043 case HWC2::FunctionDescriptor::DestroyLayer:
1044 return AsFP<HWC2_PFN_DESTROY_LAYER>(DestroyLayer);
1045 case HWC2::FunctionDescriptor::DestroyVirtualDisplay:
1046 return AsFP<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(HWCSession::DestroyVirtualDisplay);
1047 case HWC2::FunctionDescriptor::Dump:
1048 return AsFP<HWC2_PFN_DUMP>(HWCSession::Dump);
1049 case HWC2::FunctionDescriptor::GetActiveConfig:
1050 return AsFP<HWC2_PFN_GET_ACTIVE_CONFIG>(GetActiveConfig);
1051 case HWC2::FunctionDescriptor::GetChangedCompositionTypes:
1052 return AsFP<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(GetChangedCompositionTypes);
1053 case HWC2::FunctionDescriptor::GetClientTargetSupport:
1054 return AsFP<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(GetClientTargetSupport);
1055 case HWC2::FunctionDescriptor::GetColorModes:
1056 return AsFP<HWC2_PFN_GET_COLOR_MODES>(GetColorModes);
1057 case HWC2::FunctionDescriptor::GetDisplayAttribute:
1058 return AsFP<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(GetDisplayAttribute);
1059 case HWC2::FunctionDescriptor::GetDisplayConfigs:
1060 return AsFP<HWC2_PFN_GET_DISPLAY_CONFIGS>(GetDisplayConfigs);
1061 case HWC2::FunctionDescriptor::GetDisplayName:
1062 return AsFP<HWC2_PFN_GET_DISPLAY_NAME>(GetDisplayName);
1063 case HWC2::FunctionDescriptor::GetDisplayRequests:
1064 return AsFP<HWC2_PFN_GET_DISPLAY_REQUESTS>(GetDisplayRequests);
1065 case HWC2::FunctionDescriptor::GetDisplayType:
1066 return AsFP<HWC2_PFN_GET_DISPLAY_TYPE>(GetDisplayType);
1067 case HWC2::FunctionDescriptor::GetHdrCapabilities:
1068 return AsFP<HWC2_PFN_GET_HDR_CAPABILITIES>(GetHdrCapabilities);
1069 case HWC2::FunctionDescriptor::GetDozeSupport:
1070 return AsFP<HWC2_PFN_GET_DOZE_SUPPORT>(GetDozeSupport);
1071 case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount:
1072 return AsFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(GetMaxVirtualDisplayCount);
1073 case HWC2::FunctionDescriptor::GetReleaseFences:
1074 return AsFP<HWC2_PFN_GET_RELEASE_FENCES>(GetReleaseFences);
1075 case HWC2::FunctionDescriptor::PresentDisplay:
1076 return AsFP<HWC2_PFN_PRESENT_DISPLAY>(PresentDisplay);
1077 case HWC2::FunctionDescriptor::RegisterCallback:
1078 return AsFP<HWC2_PFN_REGISTER_CALLBACK>(RegisterCallback);
1079 case HWC2::FunctionDescriptor::SetActiveConfig:
1080 return AsFP<HWC2_PFN_SET_ACTIVE_CONFIG>(SetActiveConfig);
1081 case HWC2::FunctionDescriptor::SetClientTarget:
1082 return AsFP<HWC2_PFN_SET_CLIENT_TARGET>(SetClientTarget);
1083 case HWC2::FunctionDescriptor::SetColorMode:
1084 return AsFP<HWC2_PFN_SET_COLOR_MODE>(SetColorMode);
1085 case HWC2::FunctionDescriptor::SetColorTransform:
1086 return AsFP<HWC2_PFN_SET_COLOR_TRANSFORM>(SetColorTransform);
1087 case HWC2::FunctionDescriptor::SetCursorPosition:
1088 return AsFP<HWC2_PFN_SET_CURSOR_POSITION>(SetCursorPosition);
1089 case HWC2::FunctionDescriptor::SetLayerBlendMode:
1090 return AsFP<HWC2_PFN_SET_LAYER_BLEND_MODE>(SetLayerBlendMode);
1091 case HWC2::FunctionDescriptor::SetLayerBuffer:
1092 return AsFP<HWC2_PFN_SET_LAYER_BUFFER>(SetLayerBuffer);
1093 case HWC2::FunctionDescriptor::SetLayerColor:
1094 return AsFP<HWC2_PFN_SET_LAYER_COLOR>(SetLayerColor);
1095 case HWC2::FunctionDescriptor::SetLayerCompositionType:
1096 return AsFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(SetLayerCompositionType);
1097 case HWC2::FunctionDescriptor::SetLayerDataspace:
1098 return AsFP<HWC2_PFN_SET_LAYER_DATASPACE>(SetLayerDataspace);
1099 case HWC2::FunctionDescriptor::SetLayerDisplayFrame:
1100 return AsFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(SetLayerDisplayFrame);
1101 case HWC2::FunctionDescriptor::SetLayerPlaneAlpha:
1102 return AsFP<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(SetLayerPlaneAlpha);
1103 // Sideband stream is not supported
1104 // case HWC2::FunctionDescriptor::SetLayerSidebandStream:
1105 case HWC2::FunctionDescriptor::SetLayerSourceCrop:
1106 return AsFP<HWC2_PFN_SET_LAYER_SOURCE_CROP>(SetLayerSourceCrop);
1107 case HWC2::FunctionDescriptor::SetLayerSurfaceDamage:
1108 return AsFP<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(SetLayerSurfaceDamage);
1109 case HWC2::FunctionDescriptor::SetLayerTransform:
1110 return AsFP<HWC2_PFN_SET_LAYER_TRANSFORM>(SetLayerTransform);
1111 case HWC2::FunctionDescriptor::SetLayerVisibleRegion:
1112 return AsFP<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(SetLayerVisibleRegion);
1113 case HWC2::FunctionDescriptor::SetLayerZOrder:
1114 return AsFP<HWC2_PFN_SET_LAYER_Z_ORDER>(SetLayerZOrder);
1115 case HWC2::FunctionDescriptor::SetOutputBuffer:
1116 return AsFP<HWC2_PFN_SET_OUTPUT_BUFFER>(SetOutputBuffer);
1117 case HWC2::FunctionDescriptor::SetPowerMode:
1118 return AsFP<HWC2_PFN_SET_POWER_MODE>(SetPowerMode);
1119 case HWC2::FunctionDescriptor::SetVsyncEnabled:
1120 return AsFP<HWC2_PFN_SET_VSYNC_ENABLED>(SetVsyncEnabled);
1121 case HWC2::FunctionDescriptor::ValidateDisplay:
1122 return AsFP<HWC2_PFN_VALIDATE_DISPLAY>(HWCSession::ValidateDisplay);
1123 case HWC2::FunctionDescriptor::SetReadbackBuffer:
1124 return AsFP<HWC2_PFN_SET_READBACK_BUFFER>(HWCSession::SetReadbackBuffer);
1125 case HWC2::FunctionDescriptor::GetReadbackBufferAttributes:
1126 return AsFP<HWC2_PFN_GET_READBACK_BUFFER_ATTRIBUTES>(HWCSession::GetReadbackBufferAttributes);
1127 case HWC2::FunctionDescriptor::GetReadbackBufferFence:
1128 return AsFP<HWC2_PFN_GET_READBACK_BUFFER_FENCE>(HWCSession::GetReadbackBufferFence);
1129 case HWC2::FunctionDescriptor::GetRenderIntents:
1130 return AsFP<HWC2_PFN_GET_RENDER_INTENTS>(GetRenderIntents);
1131 case HWC2::FunctionDescriptor::SetColorModeWithRenderIntent:
1132 return AsFP<HWC2_PFN_SET_COLOR_MODE_WITH_RENDER_INTENT>(
1133 HWCSession::SetColorModeWithRenderIntent);
1134 case HWC2::FunctionDescriptor::GetDataspaceSaturationMatrix:
1135 return AsFP<HWC2_PFN_GET_DATASPACE_SATURATION_MATRIX>(GetDataspaceSaturationMatrix);
1136 case HWC2::FunctionDescriptor::GetPerFrameMetadataKeys:
1137 return AsFP<HWC2_PFN_GET_PER_FRAME_METADATA_KEYS>(GetPerFrameMetadataKeys);
1138 case HWC2::FunctionDescriptor::SetLayerPerFrameMetadata:
1139 return AsFP<HWC2_PFN_SET_LAYER_PER_FRAME_METADATA>(SetLayerPerFrameMetadata);
1140 case HWC2::FunctionDescriptor::SetDisplayedContentSamplingEnabled:
1141 return AsFP<HWC2_PFN_SET_DISPLAYED_CONTENT_SAMPLING_ENABLED>(SetDisplayedContentSamplingEnabled);
1142 case HWC2::FunctionDescriptor::GetDisplayedContentSamplingAttributes:
1143 return AsFP<HWC2_PFN_GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES>(GetDisplayedContentSamplingAttributes);
1144 case HWC2::FunctionDescriptor::GetDisplayedContentSample:
1145 return AsFP<HWC2_PFN_GET_DISPLAYED_CONTENT_SAMPLE>(GetDisplayedContentSample);
1146 case HWC2::FunctionDescriptor::GetDisplayCapabilities:
1147 return AsFP<HWC2_PFN_GET_DISPLAY_CAPABILITIES>(GetDisplayCapabilities);
1148 case HWC2::FunctionDescriptor::SetDisplayBrightness:
1149 return AsFP<HWC2_PFN_SET_DISPLAY_BRIGHTNESS>(SetDisplayBrightness);
1150 default:
1151 DLOGD("Unknown/Unimplemented function descriptor: %d (%s)", int_descriptor,
1152 to_string(descriptor).c_str());
1153 return nullptr;
1154 }
1155 return nullptr;
1156 }
1157
CreateVirtualDisplayObject(uint32_t width,uint32_t height,int32_t * format)1158 HWC2::Error HWCSession::CreateVirtualDisplayObject(uint32_t width, uint32_t height,
1159 int32_t *format) {
1160 {
1161 SCOPE_LOCK(locker_[HWC_DISPLAY_VIRTUAL]);
1162 if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
1163 return HWC2::Error::NoResources;
1164 }
1165
1166 if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
1167 auto error = hwc_display_[HWC_DISPLAY_PRIMARY]->TeardownConcurrentWriteback();
1168 if (error) {
1169 return HWC2::Error::NoResources;
1170 }
1171 }
1172
1173 auto status = HWCDisplayVirtual::Create(core_intf_, &buffer_allocator_, &callbacks_, width,
1174 height, format, &hwc_display_[HWC_DISPLAY_VIRTUAL]);
1175 // TODO(user): validate width and height support
1176 if (status) {
1177 return HWC2::Error::NoResources;
1178 }
1179 }
1180
1181 SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1182 hwc_display_[HWC_DISPLAY_PRIMARY]->ResetValidation();
1183
1184 return HWC2::Error::None;
1185 }
1186
ConnectDisplay(int disp)1187 int32_t HWCSession::ConnectDisplay(int disp) {
1188 DLOGI("Display = %d", disp);
1189
1190 int status = 0;
1191 uint32_t primary_width = 0;
1192 uint32_t primary_height = 0;
1193
1194 hwc_display_[HWC_DISPLAY_PRIMARY]->GetFrameBufferResolution(&primary_width, &primary_height);
1195
1196 if (disp == HWC_DISPLAY_EXTERNAL) {
1197 status = CreateExternalDisplay(disp, primary_width, primary_height, false);
1198 } else {
1199 DLOGE("Invalid display type");
1200 return -1;
1201 }
1202
1203 if (!status) {
1204 hwc_display_[disp]->SetSecureDisplay(secure_display_active_);
1205 }
1206
1207 return status;
1208 }
1209
DisconnectDisplay(int disp)1210 int HWCSession::DisconnectDisplay(int disp) {
1211 DLOGI("Display = %d", disp);
1212
1213 if (disp == HWC_DISPLAY_EXTERNAL) {
1214 DisplayError error = hwc_display_[disp]->Flush();
1215 if (error != kErrorNone) {
1216 DLOGW("Flush failed. Error = %d", error);
1217 }
1218 HWCDisplayExternal::Destroy(hwc_display_[disp]);
1219 } else if (disp == HWC_DISPLAY_VIRTUAL) {
1220 HWCDisplayVirtual::Destroy(hwc_display_[disp]);
1221 } else {
1222 DLOGE("Invalid display type");
1223 return -1;
1224 }
1225
1226 hwc_display_[disp] = NULL;
1227
1228 return 0;
1229 }
1230
1231 // Qclient methods
notifyCallback(uint32_t command,const android::Parcel * input_parcel,android::Parcel * output_parcel)1232 android::status_t HWCSession::notifyCallback(uint32_t command, const android::Parcel *input_parcel,
1233 android::Parcel *output_parcel) {
1234 android::status_t status = -EINVAL;
1235
1236 switch (command) {
1237 case qService::IQService::DYNAMIC_DEBUG:
1238 if (!input_parcel) {
1239 DLOGE("QService command = %d: input_parcel needed.", command);
1240 break;
1241 }
1242 status = 0;
1243 DynamicDebug(input_parcel);
1244 break;
1245
1246 case qService::IQService::SCREEN_REFRESH:
1247 status = refreshScreen();
1248 break;
1249
1250 case qService::IQService::SET_IDLE_TIMEOUT:
1251 if (!input_parcel) {
1252 DLOGE("QService command = %d: input_parcel needed.", command);
1253 break;
1254 }
1255 status = setIdleTimeout(UINT32(input_parcel->readInt32()));
1256 break;
1257
1258 case qService::IQService::SET_FRAME_DUMP_CONFIG:
1259 if (!input_parcel) {
1260 DLOGE("QService command = %d: input_parcel needed.", command);
1261 break;
1262 }
1263 status = SetFrameDumpConfig(input_parcel);
1264 break;
1265
1266 case qService::IQService::SET_MAX_PIPES_PER_MIXER:
1267 if (!input_parcel) {
1268 DLOGE("QService command = %d: input_parcel needed.", command);
1269 break;
1270 }
1271 status = SetMaxMixerStages(input_parcel);
1272 break;
1273
1274 case qService::IQService::SET_DISPLAY_MODE:
1275 if (!input_parcel) {
1276 DLOGE("QService command = %d: input_parcel needed.", command);
1277 break;
1278 }
1279 status = SetDisplayMode(input_parcel);
1280 break;
1281
1282 case qService::IQService::SET_SECONDARY_DISPLAY_STATUS: {
1283 if (!input_parcel || !output_parcel) {
1284 DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1285 break;
1286 }
1287 int disp_id = INT(input_parcel->readInt32());
1288 HWCDisplay::DisplayStatus disp_status =
1289 static_cast<HWCDisplay::DisplayStatus>(input_parcel->readInt32());
1290 status = SetSecondaryDisplayStatus(disp_id, disp_status);
1291 output_parcel->writeInt32(status);
1292 }
1293 break;
1294
1295 case qService::IQService::CONFIGURE_DYN_REFRESH_RATE:
1296 if (!input_parcel) {
1297 DLOGE("QService command = %d: input_parcel needed.", command);
1298 break;
1299 }
1300 status = ConfigureRefreshRate(input_parcel);
1301 break;
1302
1303 case qService::IQService::SET_VIEW_FRAME:
1304 status = 0;
1305 break;
1306
1307 case qService::IQService::TOGGLE_SCREEN_UPDATES: {
1308 if (!input_parcel || !output_parcel) {
1309 DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1310 break;
1311 }
1312 int32_t input = input_parcel->readInt32();
1313 status = toggleScreenUpdate(input == 1);
1314 output_parcel->writeInt32(status);
1315 }
1316 break;
1317
1318 case qService::IQService::QDCM_SVC_CMDS:
1319 if (!input_parcel || !output_parcel) {
1320 DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1321 break;
1322 }
1323 status = QdcmCMDHandler(input_parcel, output_parcel);
1324 break;
1325
1326 case qService::IQService::MIN_HDCP_ENCRYPTION_LEVEL_CHANGED: {
1327 if (!input_parcel || !output_parcel) {
1328 DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1329 break;
1330 }
1331 int disp_id = input_parcel->readInt32();
1332 uint32_t min_enc_level = UINT32(input_parcel->readInt32());
1333 status = MinHdcpEncryptionLevelChanged(disp_id, min_enc_level);
1334 output_parcel->writeInt32(status);
1335 }
1336 break;
1337
1338 case qService::IQService::CONTROL_PARTIAL_UPDATE: {
1339 if (!input_parcel || !output_parcel) {
1340 DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1341 break;
1342 }
1343 int disp_id = input_parcel->readInt32();
1344 uint32_t enable = UINT32(input_parcel->readInt32());
1345 status = ControlPartialUpdate(disp_id, enable == 1);
1346 output_parcel->writeInt32(status);
1347 }
1348 break;
1349
1350 case qService::IQService::SET_ACTIVE_CONFIG: {
1351 if (!input_parcel) {
1352 DLOGE("QService command = %d: input_parcel needed.", command);
1353 break;
1354 }
1355 uint32_t config = UINT32(input_parcel->readInt32());
1356 int disp_id = input_parcel->readInt32();
1357 status = SetActiveConfigIndex(disp_id, config);
1358 }
1359 break;
1360
1361 case qService::IQService::GET_ACTIVE_CONFIG: {
1362 if (!input_parcel || !output_parcel) {
1363 DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1364 break;
1365 }
1366 int disp_id = input_parcel->readInt32();
1367 uint32_t config = 0;
1368 status = GetActiveConfigIndex(disp_id, &config);
1369 output_parcel->writeInt32(INT(config));
1370 }
1371 break;
1372
1373 case qService::IQService::GET_CONFIG_COUNT: {
1374 if (!input_parcel || !output_parcel) {
1375 DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1376 break;
1377 }
1378 int disp_id = input_parcel->readInt32();
1379 uint32_t count = 0;
1380 status = GetConfigCount(disp_id, &count);
1381 output_parcel->writeInt32(INT(count));
1382 }
1383 break;
1384
1385 case qService::IQService::GET_DISPLAY_ATTRIBUTES_FOR_CONFIG:
1386 if (!input_parcel || !output_parcel) {
1387 DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1388 break;
1389 }
1390 status = HandleGetDisplayAttributesForConfig(input_parcel, output_parcel);
1391 break;
1392
1393 case qService::IQService::GET_PANEL_BRIGHTNESS: {
1394 if (!output_parcel) {
1395 DLOGE("QService command = %d: output_parcel needed.", command);
1396 break;
1397 }
1398 int level = 0;
1399 status = GetPanelBrightness(&level);
1400 output_parcel->writeInt32(level);
1401 }
1402 break;
1403
1404 case qService::IQService::SET_PANEL_BRIGHTNESS: {
1405 if (!input_parcel || !output_parcel) {
1406 DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1407 break;
1408 }
1409 uint32_t level = UINT32(input_parcel->readInt32());
1410 status = setPanelBrightness(level);
1411 output_parcel->writeInt32(status);
1412 }
1413 break;
1414
1415 case qService::IQService::GET_DISPLAY_VISIBLE_REGION:
1416 if (!input_parcel || !output_parcel) {
1417 DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1418 break;
1419 }
1420 status = GetVisibleDisplayRect(input_parcel, output_parcel);
1421 break;
1422
1423 case qService::IQService::SET_CAMERA_STATUS: {
1424 if (!input_parcel) {
1425 DLOGE("QService command = %d: input_parcel needed.", command);
1426 break;
1427 }
1428 uint32_t camera_status = UINT32(input_parcel->readInt32());
1429 status = setCameraLaunchStatus(camera_status);
1430 }
1431 break;
1432
1433 case qService::IQService::GET_BW_TRANSACTION_STATUS: {
1434 if (!output_parcel) {
1435 DLOGE("QService command = %d: output_parcel needed.", command);
1436 break;
1437 }
1438 bool state = true;
1439 status = DisplayBWTransactionPending(&state);
1440 output_parcel->writeInt32(state);
1441 }
1442 break;
1443
1444 case qService::IQService::SET_LAYER_MIXER_RESOLUTION:
1445 if (!input_parcel) {
1446 DLOGE("QService command = %d: input_parcel needed.", command);
1447 break;
1448 }
1449 status = SetMixerResolution(input_parcel);
1450 break;
1451
1452 case qService::IQService::SET_COLOR_MODE:
1453 if (!input_parcel) {
1454 DLOGE("QService command = %d: input_parcel needed.", command);
1455 break;
1456 }
1457 status = SetColorModeOverride(input_parcel);
1458 break;
1459
1460 case qService::IQService::SET_COLOR_MODE_WITH_RENDER_INTENT:
1461 if (!input_parcel) {
1462 DLOGE("QService command = %d: input_parcel needed.", command);
1463 break;
1464 }
1465 status = SetColorModeWithRenderIntentOverride(input_parcel);
1466 break;
1467
1468 case qService::IQService::SET_COLOR_MODE_BY_ID:
1469 if (!input_parcel) {
1470 DLOGE("QService command = %d: input_parcel needed.", command);
1471 break;
1472 }
1473 status = SetColorModeById(input_parcel);
1474 break;
1475
1476 case qService::IQService::GET_COMPOSER_STATUS:
1477 if (!output_parcel) {
1478 DLOGE("QService command = %d: output_parcel needed.", command);
1479 break;
1480 }
1481 status = 0;
1482 output_parcel->writeInt32(getComposerStatus());
1483 break;
1484
1485 case qService::IQService::SET_IDLE_PC:
1486 if (!input_parcel) {
1487 DLOGE("QService command = %d: input_parcel needed.", command);
1488 break;
1489 }
1490 status = SetIdlePC(input_parcel);
1491 break;
1492
1493 case qService::IQService::SET_COLOR_SAMPLING_ENABLED:
1494 if (!input_parcel) {
1495 DLOGE("QService command = %d: input_parcel needed.", command);
1496 break;
1497 }
1498 status = setColorSamplingEnabled(input_parcel);
1499 break;
1500
1501 case qService::IQService::SET_WHITE_COMPENSATION:
1502 if (!input_parcel) {
1503 DLOGE("QService command = %d: input_parcel needed.", command);
1504 break;
1505 }
1506 status = SetWhiteCompensation(input_parcel);
1507 break;
1508 default:
1509 DLOGW("QService command = %d is not supported.", command);
1510 break;
1511 }
1512
1513 return status;
1514 }
1515
getComposerStatus()1516 android::status_t HWCSession::getComposerStatus() {
1517 return is_composer_up_;
1518 }
1519
setColorSamplingEnabled(const android::Parcel * input_parcel)1520 android::status_t HWCSession::setColorSamplingEnabled(const android::Parcel* input_parcel)
1521 {
1522 int dpy = input_parcel->readInt32();
1523 int enabled_cmd = input_parcel->readInt32();
1524 if (dpy < HWC_DISPLAY_PRIMARY || dpy >= HWC_NUM_DISPLAY_TYPES ||
1525 enabled_cmd < 0 || enabled_cmd > 1) {
1526 return android::BAD_VALUE;
1527 }
1528
1529 SEQUENCE_WAIT_SCOPE_LOCK(locker_[dpy]);
1530 if (!hwc_display_[dpy]) {
1531 DLOGW("No display id %i active to enable histogram event", dpy);
1532 return android::BAD_VALUE;
1533 }
1534
1535 auto error = hwc_display_[dpy]->SetDisplayedContentSamplingEnabledVndService(enabled_cmd);
1536 return (error == HWC2::Error::None) ? android::OK : android::BAD_VALUE;
1537 }
1538
HandleGetDisplayAttributesForConfig(const android::Parcel * input_parcel,android::Parcel * output_parcel)1539 android::status_t HWCSession::HandleGetDisplayAttributesForConfig(const android::Parcel
1540 *input_parcel,
1541 android::Parcel *output_parcel) {
1542 int config = input_parcel->readInt32();
1543 int dpy = input_parcel->readInt32();
1544 int error = android::BAD_VALUE;
1545 DisplayConfigVariableInfo display_attributes;
1546
1547 if (dpy < HWC_DISPLAY_PRIMARY || dpy >= HWC_NUM_DISPLAY_TYPES || config < 0) {
1548 return android::BAD_VALUE;
1549 }
1550
1551 SEQUENCE_WAIT_SCOPE_LOCK(locker_[dpy]);
1552 if (hwc_display_[dpy]) {
1553 error = hwc_display_[dpy]->GetDisplayAttributesForConfig(config, &display_attributes);
1554 if (error == 0) {
1555 output_parcel->writeInt32(INT(display_attributes.vsync_period_ns));
1556 output_parcel->writeInt32(INT(display_attributes.x_pixels));
1557 output_parcel->writeInt32(INT(display_attributes.y_pixels));
1558 output_parcel->writeFloat(display_attributes.x_dpi);
1559 output_parcel->writeFloat(display_attributes.y_dpi);
1560 output_parcel->writeInt32(0); // Panel type, unsupported.
1561 }
1562 }
1563
1564 return error;
1565 }
1566
ConfigureRefreshRate(const android::Parcel * input_parcel)1567 android::status_t HWCSession::ConfigureRefreshRate(const android::Parcel *input_parcel) {
1568 SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1569
1570 uint32_t operation = UINT32(input_parcel->readInt32());
1571 HWCDisplay *hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
1572
1573 if (!hwc_display) {
1574 DLOGW("Display = %d is not connected.", HWC_DISPLAY_PRIMARY);
1575 return -ENODEV;
1576 }
1577
1578 switch (operation) {
1579 case qdutils::DISABLE_METADATA_DYN_REFRESH_RATE:
1580 return hwc_display->Perform(HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, false);
1581
1582 case qdutils::ENABLE_METADATA_DYN_REFRESH_RATE:
1583 return hwc_display->Perform(HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, true);
1584
1585 case qdutils::SET_BINDER_DYN_REFRESH_RATE: {
1586 uint32_t refresh_rate = UINT32(input_parcel->readInt32());
1587 return hwc_display->Perform(HWCDisplayPrimary::SET_BINDER_DYN_REFRESH_RATE, refresh_rate);
1588 }
1589
1590 default:
1591 DLOGW("Invalid operation %d", operation);
1592 return -EINVAL;
1593 }
1594
1595 return 0;
1596 }
1597
SetDisplayMode(const android::Parcel * input_parcel)1598 android::status_t HWCSession::SetDisplayMode(const android::Parcel *input_parcel) {
1599 SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1600
1601 if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
1602 DLOGW("Display = %d is not connected.", HWC_DISPLAY_PRIMARY);
1603 return -ENODEV;
1604 }
1605
1606 uint32_t mode = UINT32(input_parcel->readInt32());
1607 return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(HWCDisplayPrimary::SET_DISPLAY_MODE, mode);
1608 }
1609
SetMaxMixerStages(const android::Parcel * input_parcel)1610 android::status_t HWCSession::SetMaxMixerStages(const android::Parcel *input_parcel) {
1611 DisplayError error = kErrorNone;
1612 std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32());
1613 uint32_t max_mixer_stages = UINT32(input_parcel->readInt32());
1614 android::status_t status = 0;
1615
1616 for (uint32_t disp_id = HWC_DISPLAY_PRIMARY; disp_id < HWC_NUM_DISPLAY_TYPES; disp_id++) {
1617 if (bit_mask_display_type[disp_id]) {
1618 SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
1619 if (hwc_display_[disp_id]) {
1620 error = hwc_display_[disp_id]->SetMaxMixerStages(max_mixer_stages);
1621 if (error != kErrorNone) {
1622 status = -EINVAL;
1623 continue;
1624 }
1625 } else {
1626 DLOGW("Display = %d is not connected.", disp_id);
1627 status = (status)? status : -ENODEV; // Return higher priority error.
1628 continue;
1629 }
1630 }
1631 }
1632
1633 return status;
1634 }
1635
SetFrameDumpConfig(const android::Parcel * input_parcel)1636 android::status_t HWCSession::SetFrameDumpConfig(const android::Parcel *input_parcel) {
1637 uint32_t frame_dump_count = UINT32(input_parcel->readInt32());
1638 std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32());
1639 uint32_t bit_mask_layer_type = UINT32(input_parcel->readInt32());
1640 int32_t output_format = HAL_PIXEL_FORMAT_RGB_888;
1641 bool post_processed = true;
1642
1643 // Read optional user preferences: output_format and post_processed.
1644 if (input_parcel->dataPosition() != input_parcel->dataSize()) {
1645 // HAL Pixel Format for output buffer
1646 output_format = input_parcel->readInt32();
1647 }
1648 if (input_parcel->dataPosition() != input_parcel->dataSize()) {
1649 // Option to dump Layer Mixer output (0) or DSPP output (1)
1650 post_processed = (input_parcel->readInt32() != 0);
1651 }
1652
1653 android::status_t status = 0;
1654
1655 for (uint32_t disp_id = HWC_DISPLAY_PRIMARY; disp_id < HWC_NUM_DISPLAY_TYPES; disp_id++) {
1656 if (bit_mask_display_type[disp_id]) {
1657 SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
1658 if (hwc_display_[disp_id]) {
1659 HWC2::Error error;
1660 error = hwc_display_[disp_id]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type,
1661 output_format, post_processed);
1662 if (HWC2::Error::None != error) {
1663 if (HWC2::Error::NoResources == error)
1664 status = -ENOMEM;
1665 else
1666 status = -EINVAL;
1667 continue;
1668 }
1669 } else {
1670 DLOGW("Display = %d is not connected.", disp_id);
1671 status = (status)? status : -ENODEV; // Return higher priority error.
1672 continue;
1673 }
1674 }
1675 }
1676
1677 return status;
1678 }
1679
SetMixerResolution(const android::Parcel * input_parcel)1680 android::status_t HWCSession::SetMixerResolution(const android::Parcel *input_parcel) {
1681 DisplayError error = kErrorNone;
1682 uint32_t dpy = UINT32(input_parcel->readInt32());
1683
1684 if (dpy != HWC_DISPLAY_PRIMARY) {
1685 DLOGW("Resolution change not supported for this display = %d", dpy);
1686 return -EINVAL;
1687 }
1688
1689 SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1690 if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
1691 DLOGW("Primary display is not initialized");
1692 return -ENODEV;
1693 }
1694
1695 uint32_t width = UINT32(input_parcel->readInt32());
1696 uint32_t height = UINT32(input_parcel->readInt32());
1697
1698 error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetMixerResolution(width, height);
1699 if (error != kErrorNone) {
1700 return -EINVAL;
1701 }
1702
1703 return 0;
1704 }
1705
SetColorModeOverride(const android::Parcel * input_parcel)1706 android::status_t HWCSession::SetColorModeOverride(const android::Parcel *input_parcel) {
1707 auto display = static_cast<hwc2_display_t >(input_parcel->readInt32());
1708 auto mode = static_cast<ColorMode>(input_parcel->readInt32());
1709 auto device = static_cast<hwc2_device_t *>(this);
1710
1711 if (mode < ColorMode::NATIVE || mode > ColorMode::BT2100_HLG) {
1712 DLOGE("Invalid ColorMode: %d", mode);
1713 return HWC2_ERROR_BAD_PARAMETER;
1714 }
1715
1716 auto err = CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
1717 if (err != HWC2_ERROR_NONE)
1718 return -EINVAL;
1719
1720 return 0;
1721 }
1722
SetWhiteCompensation(const android::Parcel * input_parcel)1723 android::status_t HWCSession::SetWhiteCompensation(const android::Parcel *input_parcel) {
1724 auto display = static_cast<hwc2_display_t>(input_parcel->readInt32());
1725 auto enabled = static_cast<bool>(input_parcel->readInt32());
1726 auto device = static_cast<hwc2_device_t *>(this);
1727
1728 auto err = CallDisplayFunction(device, display, &HWCDisplay::SetWhiteCompensation, enabled);
1729 if (err != HWC2_ERROR_NONE)
1730 return -EINVAL;
1731
1732 return 0;
1733 }
1734
SetColorModeWithRenderIntentOverride(const android::Parcel * input_parcel)1735 android::status_t HWCSession::SetColorModeWithRenderIntentOverride(
1736 const android::Parcel *input_parcel) {
1737 auto display = static_cast<hwc2_display_t>(input_parcel->readInt32());
1738 auto mode = static_cast<ColorMode>(input_parcel->readInt32());
1739 auto intent = static_cast<RenderIntent>(input_parcel->readInt32());
1740 auto device = static_cast<hwc2_device_t *>(this);
1741
1742 if (mode < ColorMode::NATIVE || mode > ColorMode::BT2100_HLG) {
1743 DLOGE("Invalid ColorMode: %d", mode);
1744 return HWC2_ERROR_BAD_PARAMETER;
1745 }
1746
1747 if (intent < RenderIntent::COLORIMETRIC || intent > RenderIntent::TONE_MAP_ENHANCE) {
1748 DLOGE("Invalid RenderIntent: %d", intent);
1749 return HWC2_ERROR_BAD_PARAMETER;
1750 }
1751
1752 auto err =
1753 CallDisplayFunction(device, display, &HWCDisplay::SetColorModeWithRenderIntent, mode, intent);
1754 if (err != HWC2_ERROR_NONE)
1755 return -EINVAL;
1756
1757 return 0;
1758 }
SetColorModeById(const android::Parcel * input_parcel)1759 android::status_t HWCSession::SetColorModeById(const android::Parcel *input_parcel) {
1760 auto display = static_cast<hwc2_display_t >(input_parcel->readInt32());
1761 auto mode = input_parcel->readInt32();
1762 auto device = static_cast<hwc2_device_t *>(this);
1763
1764 auto err = CallDisplayFunction(device, display, &HWCDisplay::SetColorModeById, mode);
1765 if (err != HWC2_ERROR_NONE)
1766 return -EINVAL;
1767
1768 return 0;
1769 }
1770
DynamicDebug(const android::Parcel * input_parcel)1771 void HWCSession::DynamicDebug(const android::Parcel *input_parcel) {
1772 int type = input_parcel->readInt32();
1773 bool enable = (input_parcel->readInt32() > 0);
1774 DLOGI("type = %d enable = %d", type, enable);
1775 int verbose_level = input_parcel->readInt32();
1776
1777 switch (type) {
1778 case qService::IQService::DEBUG_ALL:
1779 HWCDebugHandler::DebugAll(enable, verbose_level);
1780 break;
1781
1782 case qService::IQService::DEBUG_MDPCOMP:
1783 HWCDebugHandler::DebugStrategy(enable, verbose_level);
1784 HWCDebugHandler::DebugCompManager(enable, verbose_level);
1785 break;
1786
1787 case qService::IQService::DEBUG_PIPE_LIFECYCLE:
1788 HWCDebugHandler::DebugResources(enable, verbose_level);
1789 break;
1790
1791 case qService::IQService::DEBUG_DRIVER_CONFIG:
1792 HWCDebugHandler::DebugDriverConfig(enable, verbose_level);
1793 break;
1794
1795 case qService::IQService::DEBUG_ROTATOR:
1796 HWCDebugHandler::DebugResources(enable, verbose_level);
1797 HWCDebugHandler::DebugDriverConfig(enable, verbose_level);
1798 HWCDebugHandler::DebugRotator(enable, verbose_level);
1799 break;
1800
1801 case qService::IQService::DEBUG_QDCM:
1802 HWCDebugHandler::DebugQdcm(enable, verbose_level);
1803 break;
1804
1805 case qService::IQService::DEBUG_SCALAR:
1806 HWCDebugHandler::DebugScalar(enable, verbose_level);
1807 break;
1808
1809 case qService::IQService::DEBUG_CLIENT:
1810 HWCDebugHandler::DebugClient(enable, verbose_level);
1811 break;
1812
1813 case qService::IQService::DEBUG_DISPLAY:
1814 HWCDebugHandler::DebugDisplay(enable, verbose_level);
1815 break;
1816
1817 default:
1818 DLOGW("type = %d is not supported", type);
1819 }
1820 }
1821
QdcmCMDHandler(const android::Parcel * input_parcel,android::Parcel * output_parcel)1822 android::status_t HWCSession::QdcmCMDHandler(const android::Parcel *input_parcel,
1823 android::Parcel *output_parcel) {
1824 int ret = 0;
1825 int32_t *brightness_value = NULL;
1826 uint32_t display_id(0);
1827 PPPendingParams pending_action;
1828 PPDisplayAPIPayload resp_payload, req_payload;
1829
1830 if (!color_mgr_) {
1831 DLOGW("color_mgr_ not initialized.");
1832 return -ENOENT;
1833 }
1834
1835 pending_action.action = kNoAction;
1836 pending_action.params = NULL;
1837
1838 // Read display_id, payload_size and payload from in_parcel.
1839 ret = HWCColorManager::CreatePayloadFromParcel(*input_parcel, &display_id, &req_payload);
1840 if (!ret) {
1841 if ((display_id >= HWC_NUM_DISPLAY_TYPES) || !hwc_display_[display_id]) {
1842 DLOGW("Invalid display id or display = %d is not connected.", display_id);
1843 ret = -ENODEV;
1844 }
1845 }
1846
1847 if (!ret) {
1848 if ((HWC_DISPLAY_PRIMARY == display_id) || (HWC_DISPLAY_EXTERNAL == display_id)) {
1849 ret = hwc_display_[display_id]->ColorSVCRequestRoute(req_payload, &resp_payload,
1850 &pending_action);
1851 } else {
1852 // Virtual, Tertiary etc. not supported.
1853 DLOGW("Operation not supported on display = %d.", display_id);
1854 ret = -EINVAL;
1855 }
1856 }
1857
1858 if (ret) {
1859 output_parcel->writeInt32(ret); // first field in out parcel indicates return code.
1860 req_payload.DestroyPayload();
1861 resp_payload.DestroyPayload();
1862 return ret;
1863 }
1864
1865 if (kNoAction != pending_action.action) {
1866 // Restrict pending actions to primary display.
1867 if (HWC_DISPLAY_PRIMARY != display_id) {
1868 DLOGW("Skipping pending action %d on display = %d.", pending_action.action, display_id);
1869 pending_action.action = kNoAction;
1870 }
1871
1872 int32_t action = pending_action.action;
1873 int count = -1;
1874 while (action > 0) {
1875 count++;
1876 int32_t bit = (action & 1);
1877 action = action >> 1;
1878
1879 if (!bit)
1880 continue;
1881
1882 DLOGV_IF(kTagQDCM, "pending action = %d", BITMAP(count));
1883 switch (BITMAP(count)) {
1884 case kInvalidating:
1885 Refresh(HWC_DISPLAY_PRIMARY);
1886 break;
1887 case kEnterQDCMMode:
1888 ret = color_mgr_->EnableQDCMMode(true, hwc_display_[HWC_DISPLAY_PRIMARY]);
1889 break;
1890 case kExitQDCMMode:
1891 ret = color_mgr_->EnableQDCMMode(false, hwc_display_[HWC_DISPLAY_PRIMARY]);
1892 break;
1893 case kApplySolidFill:
1894 {
1895 SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1896 ret = color_mgr_->SetSolidFill(pending_action.params,
1897 true, hwc_display_[HWC_DISPLAY_PRIMARY]);
1898 }
1899 Refresh(HWC_DISPLAY_PRIMARY);
1900 usleep(kSolidFillDelay);
1901 break;
1902 case kDisableSolidFill:
1903 {
1904 SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1905 ret = color_mgr_->SetSolidFill(pending_action.params,
1906 false, hwc_display_[HWC_DISPLAY_PRIMARY]);
1907 }
1908 Refresh(HWC_DISPLAY_PRIMARY);
1909 usleep(kSolidFillDelay);
1910 break;
1911 case kSetPanelBrightness:
1912 brightness_value = reinterpret_cast<int32_t *>(resp_payload.payload);
1913 if (brightness_value == NULL) {
1914 DLOGE("Brightness value is Null");
1915 ret = -EINVAL;
1916 } else {
1917 ret = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(*brightness_value);
1918 }
1919 break;
1920 case kEnableFrameCapture:
1921 ret = color_mgr_->SetFrameCapture(pending_action.params, true,
1922 hwc_display_[HWC_DISPLAY_PRIMARY]);
1923 Refresh(HWC_DISPLAY_PRIMARY);
1924 break;
1925 case kDisableFrameCapture:
1926 ret = color_mgr_->SetFrameCapture(pending_action.params, false,
1927 hwc_display_[HWC_DISPLAY_PRIMARY]);
1928 break;
1929 case kConfigureDetailedEnhancer:
1930 ret = color_mgr_->SetDetailedEnhancer(pending_action.params,
1931 hwc_display_[HWC_DISPLAY_PRIMARY]);
1932 Refresh(HWC_DISPLAY_PRIMARY);
1933 break;
1934 case kModeSet:
1935 ret = static_cast<int>
1936 (hwc_display_[HWC_DISPLAY_PRIMARY]->RestoreColorTransform());
1937 Refresh(HWC_DISPLAY_PRIMARY);
1938 break;
1939 case kNoAction:
1940 break;
1941 default:
1942 DLOGW("Invalid pending action = %d!", pending_action.action);
1943 break;
1944 }
1945 }
1946 }
1947 // for display API getter case, marshall returned params into out_parcel.
1948 output_parcel->writeInt32(ret);
1949 HWCColorManager::MarshallStructIntoParcel(resp_payload, output_parcel);
1950 req_payload.DestroyPayload();
1951 resp_payload.DestroyPayload();
1952 hwc_display_[display_id]->ResetValidation();
1953
1954 return ret;
1955 }
1956
UEventHandler(const char * uevent_data,int length)1957 void HWCSession::UEventHandler(const char *uevent_data, int length) {
1958 if (strcasestr(uevent_data, HWC_UEVENT_SWITCH_HDMI)) {
1959 DLOGI("Uevent HDMI = %s", uevent_data);
1960 int connected = GetEventValue(uevent_data, length, "SWITCH_STATE=");
1961 if (connected >= 0) {
1962 DLOGI("HDMI = %s", connected ? "connected" : "disconnected");
1963 if (HotPlugHandler(connected) == -1) {
1964 DLOGE("Failed handling Hotplug = %s", connected ? "connected" : "disconnected");
1965 }
1966 }
1967 } else if (strcasestr(uevent_data, HWC_UEVENT_GRAPHICS_FB0)) {
1968 DLOGI("Uevent FB0 = %s", uevent_data);
1969 int panel_reset = GetEventValue(uevent_data, length, "PANEL_ALIVE=");
1970 if (panel_reset == 0) {
1971 Refresh(0);
1972 reset_panel_ = true;
1973 }
1974 } else if (strcasestr(uevent_data, HWC_UEVENT_DRM_EXT_HOTPLUG)) {
1975 HandleExtHPD(uevent_data, length);
1976 }
1977 }
1978
GetTokenValue(const char * uevent_data,int length,const char * token)1979 const char *GetTokenValue(const char *uevent_data, int length, const char *token) {
1980 const char *iterator_str = uevent_data;
1981 const char *pstr = NULL;
1982 while (((iterator_str - uevent_data) <= length) && (*iterator_str)) {
1983 pstr = strstr(iterator_str, token);
1984 if (pstr) {
1985 break;
1986 }
1987 iterator_str += strlen(iterator_str) + 1;
1988 }
1989
1990 if (pstr)
1991 pstr = pstr+strlen(token);
1992
1993 return pstr;
1994 }
1995
HandleExtHPD(const char * uevent_data,int length)1996 void HWCSession::HandleExtHPD(const char *uevent_data, int length) {
1997 const char *pstr = GetTokenValue(uevent_data, length, "name=");
1998 if (!pstr || (strncmp(pstr, "DP-1", strlen("DP-1")) != 0)) {
1999 return;
2000 }
2001
2002 pstr = GetTokenValue(uevent_data, length, "status=");
2003 if (pstr) {
2004 bool connected = false;
2005 hpd_bpp_ = 0;
2006 hpd_pattern_ = 0;
2007 if (strncmp(pstr, "connected", strlen("connected")) == 0) {
2008 connected = true;
2009 }
2010 int bpp = GetEventValue(uevent_data, length, "bpp=");
2011 int pattern = GetEventValue(uevent_data, length, "pattern=");
2012 if (bpp >=0 && pattern >= 0) {
2013 hpd_bpp_ = bpp;
2014 hpd_pattern_ = pattern;
2015 }
2016
2017 DLOGI("Recived Ext HPD, connected:%d status=%s bpp = %d pattern =%d ",
2018 connected, pstr, hpd_bpp_, hpd_pattern_);
2019 HotPlugHandler(connected);
2020 }
2021 }
2022
GetEventValue(const char * uevent_data,int length,const char * event_info)2023 int HWCSession::GetEventValue(const char *uevent_data, int length, const char *event_info) {
2024 const char *iterator_str = uevent_data;
2025 while (((iterator_str - uevent_data) <= length) && (*iterator_str)) {
2026 const char *pstr = strstr(iterator_str, event_info);
2027 if (pstr != NULL) {
2028 return (atoi(iterator_str + strlen(event_info)));
2029 }
2030 iterator_str += strlen(iterator_str) + 1;
2031 }
2032
2033 return -1;
2034 }
2035
ResetPanel()2036 void HWCSession::ResetPanel() {
2037 HWC2::Error status;
2038
2039 DLOGI("Powering off primary");
2040 status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(HWC2::PowerMode::Off);
2041 if (status != HWC2::Error::None) {
2042 DLOGE("power-off on primary failed with error = %d", status);
2043 }
2044
2045 DLOGI("Restoring power mode on primary");
2046 HWC2::PowerMode mode = hwc_display_[HWC_DISPLAY_PRIMARY]->GetLastPowerMode();
2047 status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(mode);
2048 if (status != HWC2::Error::None) {
2049 DLOGE("Setting power mode = %d on primary failed with error = %d", mode, status);
2050 }
2051
2052 status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetVsyncEnabled(HWC2::Vsync::Enable);
2053 if (status != HWC2::Error::None) {
2054 DLOGE("enabling vsync failed for primary with error = %d", status);
2055 }
2056
2057 reset_panel_ = false;
2058 }
2059
HotPlugHandler(bool connected)2060 int HWCSession::HotPlugHandler(bool connected) {
2061 int status = 0;
2062 bool notify_hotplug = false;
2063
2064 // To prevent sending events to client while a lock is held, acquire scope locks only within
2065 // below scope so that those get automatically unlocked after the scope ends.
2066 do {
2067 // If HDMI is primary but not created yet (first time), create it and notify surfaceflinger.
2068 // if it is already created, but got disconnected/connected again,
2069 // just toggle display status and do not notify surfaceflinger.
2070 // If HDMI is not primary, create/destroy external display normally.
2071 if (hdmi_is_primary_) {
2072 SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
2073 if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
2074 status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetState(connected);
2075 } else {
2076 status = CreateExternalDisplay(HWC_DISPLAY_PRIMARY, 0, 0, false);
2077 notify_hotplug = true;
2078 }
2079
2080 break;
2081 }
2082
2083 {
2084 SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
2085 // Primary display must be connected for HDMI as secondary cases.
2086 if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
2087 DLOGE("Primary display is not connected.");
2088 return -1;
2089 }
2090
2091 hwc_display_[HWC_DISPLAY_PRIMARY]->ResetValidation();
2092 }
2093
2094 if (connected) {
2095 SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
2096 Locker::ScopeLock lock_v(locker_[HWC_DISPLAY_VIRTUAL]);
2097 // Connect external display if virtual display is not connected.
2098 // Else, defer external display connection and process it when virtual display
2099 // tears down; Do not notify SurfaceFlinger since connection is deferred now.
2100 if (!hwc_display_[HWC_DISPLAY_VIRTUAL]) {
2101 status = ConnectDisplay(HWC_DISPLAY_EXTERNAL);
2102 if (status) {
2103 return status;
2104 }
2105 notify_hotplug = true;
2106 } else {
2107 DLOGI("Virtual display is connected, pending connection");
2108 external_pending_connect_ = true;
2109 }
2110 } else {
2111 SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
2112 if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
2113 notify_hotplug = true;
2114 }
2115 external_pending_connect_ = false;
2116 }
2117 } while (0);
2118
2119 if (connected) {
2120 // In connect case, we send hotplug after we create display
2121 Refresh(0);
2122
2123 if (!hdmi_is_primary_) {
2124 // wait for sufficient time to ensure sufficient resources are available to process new
2125 // new display connection.
2126 uint32_t vsync_period = UINT32(GetVsyncPeriod(HWC_DISPLAY_PRIMARY));
2127 usleep(vsync_period * 2 / 1000);
2128 }
2129 if (notify_hotplug) {
2130 HotPlug(hdmi_is_primary_ ? HWC_DISPLAY_PRIMARY : HWC_DISPLAY_EXTERNAL,
2131 HWC2::Connection::Connected);
2132 }
2133 } else {
2134 // In disconnect case, we notify hotplug first to let the listener state update happen first
2135 // Then we can destroy the underlying display object
2136 if (notify_hotplug) {
2137 HotPlug(hdmi_is_primary_ ? HWC_DISPLAY_PRIMARY : HWC_DISPLAY_EXTERNAL,
2138 HWC2::Connection::Disconnected);
2139 }
2140 Refresh(0);
2141 if (!hdmi_is_primary_) {
2142 uint32_t vsync_period = UINT32(GetVsyncPeriod(HWC_DISPLAY_PRIMARY));
2143 usleep(vsync_period * 2 / 1000);
2144 }
2145 // Now disconnect the display
2146 {
2147 SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
2148 // Do not return error if external display is not in connected status.
2149 // Due to virtual display concurrency, external display connection might be still pending
2150 // but hdmi got disconnected before pending connection could be processed.
2151 if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
2152 status = DisconnectDisplay(HWC_DISPLAY_EXTERNAL);
2153 }
2154 }
2155 }
2156
2157 // notify client
2158
2159 qservice_->onHdmiHotplug(INT(connected));
2160
2161 return 0;
2162 }
2163
GetVsyncPeriod(int disp)2164 int HWCSession::GetVsyncPeriod(int disp) {
2165 SCOPE_LOCK(locker_[disp]);
2166 // default value
2167 int32_t vsync_period = 1000000000l / 60;
2168 auto attribute = HWC2::Attribute::VsyncPeriod;
2169
2170 if (hwc_display_[disp]) {
2171 hwc_display_[disp]->GetDisplayAttribute(0, attribute, &vsync_period);
2172 }
2173
2174 return vsync_period;
2175 }
2176
GetVisibleDisplayRect(const android::Parcel * input_parcel,android::Parcel * output_parcel)2177 android::status_t HWCSession::GetVisibleDisplayRect(const android::Parcel *input_parcel,
2178 android::Parcel *output_parcel) {
2179 int dpy = input_parcel->readInt32();
2180 if (dpy < HWC_DISPLAY_PRIMARY || dpy >= HWC_NUM_DISPLAY_TYPES) {
2181 return android::BAD_VALUE;
2182 }
2183
2184 SEQUENCE_WAIT_SCOPE_LOCK(locker_[dpy]);
2185 if (!hwc_display_[dpy]) {
2186 return android::NO_INIT;
2187 }
2188
2189 hwc_rect_t visible_rect = {0, 0, 0, 0};
2190 int error = hwc_display_[dpy]->GetVisibleDisplayRect(&visible_rect);
2191 if (error < 0) {
2192 return error;
2193 }
2194
2195 output_parcel->writeInt32(visible_rect.left);
2196 output_parcel->writeInt32(visible_rect.top);
2197 output_parcel->writeInt32(visible_rect.right);
2198 output_parcel->writeInt32(visible_rect.bottom);
2199
2200 return android::NO_ERROR;
2201 }
2202
Refresh(hwc2_display_t display)2203 void HWCSession::Refresh(hwc2_display_t display) {
2204 SCOPE_LOCK(callbacks_lock_);
2205 HWC2::Error err = callbacks_.Refresh(display);
2206 while (err != HWC2::Error::None) {
2207 callbacks_lock_.Wait();
2208 err = callbacks_.Refresh(display);
2209 }
2210 }
2211
HotPlug(hwc2_display_t display,HWC2::Connection state)2212 void HWCSession::HotPlug(hwc2_display_t display, HWC2::Connection state) {
2213 SCOPE_LOCK(callbacks_lock_);
2214 HWC2::Error err = callbacks_.Hotplug(display, state);
2215 while (err != HWC2::Error::None) {
2216 callbacks_lock_.Wait();
2217 err = callbacks_.Hotplug(display, state);
2218 }
2219 }
2220
CreateExternalDisplay(int disp_id,uint32_t primary_width,uint32_t primary_height,bool use_primary_res)2221 int HWCSession::CreateExternalDisplay(int disp_id, uint32_t primary_width,
2222 uint32_t primary_height, bool use_primary_res) {
2223 uint32_t panel_bpp = 0;
2224 uint32_t pattern_type = 0;
2225
2226 if (GetDriverType() == DriverType::FB) {
2227 qdutils::getDPTestConfig(&panel_bpp, &pattern_type);
2228 } else {
2229 panel_bpp = static_cast<uint32_t>(hpd_bpp_);
2230 pattern_type = static_cast<uint32_t>(hpd_pattern_);
2231 }
2232
2233 if (panel_bpp && pattern_type) {
2234 return HWCDisplayExternalTest::Create(core_intf_, &buffer_allocator_, &callbacks_,
2235 qservice_, panel_bpp, pattern_type,
2236 &hwc_display_[disp_id]);
2237 }
2238
2239 return HWCDisplayExternal::Create(core_intf_, &buffer_allocator_, &callbacks_,
2240 primary_width, primary_height, qservice_,
2241 use_primary_res, &hwc_display_[disp_id]);
2242 }
2243
ValidateDisplayInternal(hwc2_display_t display,uint32_t * out_num_types,uint32_t * out_num_requests)2244 HWC2::Error HWCSession::ValidateDisplayInternal(hwc2_display_t display, uint32_t *out_num_types,
2245 uint32_t *out_num_requests) {
2246 HWCDisplay *hwc_display = hwc_display_[display];
2247 if (hwc_display->IsInternalValidateState()) {
2248 // Internal Validation has already been done on display, get the Output params.
2249 return hwc_display->GetValidateDisplayOutput(out_num_types, out_num_requests);
2250 }
2251
2252 if (display == HWC_DISPLAY_PRIMARY) {
2253 // TODO(user): This can be moved to HWCDisplayPrimary
2254 if (reset_panel_) {
2255 DLOGW("panel is in bad state, resetting the panel");
2256 ResetPanel();
2257 }
2258
2259 if (need_invalidate_) {
2260 Refresh(display);
2261 need_invalidate_ = false;
2262 }
2263
2264 if (color_mgr_) {
2265 color_mgr_->SetColorModeDetailEnhancer(hwc_display_[display]);
2266 }
2267 }
2268
2269 return hwc_display->Validate(out_num_types, out_num_requests);
2270 }
2271
PresentDisplayInternal(hwc2_display_t display,int32_t * out_retire_fence)2272 HWC2::Error HWCSession::PresentDisplayInternal(hwc2_display_t display, int32_t *out_retire_fence) {
2273 HWCDisplay *hwc_display = hwc_display_[display];
2274 // If display is in Skip-Validate state and Validate cannot be skipped, do Internal
2275 // Validation to optimize for the frames which don't require the Client composition.
2276 if (hwc_display->IsSkipValidateState() && !hwc_display->CanSkipValidate()) {
2277 uint32_t out_num_types = 0, out_num_requests = 0;
2278 HWC2::Error error = ValidateDisplayInternal(display, &out_num_types, &out_num_requests);
2279 if ((error != HWC2::Error::None) || hwc_display->HasClientComposition()) {
2280 hwc_display->SetValidationState(HWCDisplay::kInternalValidate);
2281 return HWC2::Error::NotValidated;
2282 }
2283 }
2284
2285 return hwc_display->Present(out_retire_fence);
2286 }
2287
GetReadbackBufferAttributes(hwc2_device_t * device,hwc2_display_t display,int32_t * format,int32_t * dataspace)2288 int32_t HWCSession::GetReadbackBufferAttributes(hwc2_device_t *device, hwc2_display_t display,
2289 int32_t *format, int32_t *dataspace) {
2290 if (!device || !format || !dataspace) {
2291 return HWC2_ERROR_BAD_PARAMETER;
2292 }
2293
2294 if (display != HWC_DISPLAY_PRIMARY) {
2295 return HWC2_ERROR_BAD_DISPLAY;
2296 }
2297
2298 HWCSession *hwc_session = static_cast<HWCSession *>(device);
2299 HWCDisplay *hwc_display = hwc_session->hwc_display_[display];
2300
2301 if (hwc_display) {
2302 *format = HAL_PIXEL_FORMAT_RGB_888;
2303 *dataspace = GetDataspace(hwc_display->GetCurrentColorMode());
2304 return HWC2_ERROR_NONE;
2305 }
2306
2307 return HWC2_ERROR_BAD_DISPLAY;
2308 }
2309
SetReadbackBuffer(hwc2_device_t * device,hwc2_display_t display,const native_handle_t * buffer,int32_t acquire_fence)2310 int32_t HWCSession::SetReadbackBuffer(hwc2_device_t *device, hwc2_display_t display,
2311 const native_handle_t *buffer, int32_t acquire_fence) {
2312 if (!buffer) {
2313 return HWC2_ERROR_BAD_PARAMETER;
2314 }
2315
2316 if (display != HWC_DISPLAY_PRIMARY) {
2317 return HWC2_ERROR_BAD_DISPLAY;
2318 }
2319
2320 HWCSession *hwc_session = static_cast<HWCSession *>(device);
2321 if (hwc_session->hwc_display_[HWC_DISPLAY_EXTERNAL] ||
2322 hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL]) {
2323 return HWC2_ERROR_UNSUPPORTED;
2324 }
2325
2326 return CallDisplayFunction(device, display, &HWCDisplay::SetReadbackBuffer,
2327 buffer, acquire_fence, false);
2328 }
2329
GetReadbackBufferFence(hwc2_device_t * device,hwc2_display_t display,int32_t * release_fence)2330 int32_t HWCSession::GetReadbackBufferFence(hwc2_device_t *device, hwc2_display_t display,
2331 int32_t *release_fence) {
2332 if (!release_fence) {
2333 return HWC2_ERROR_BAD_PARAMETER;
2334 }
2335
2336 if (display != HWC_DISPLAY_PRIMARY) {
2337 return HWC2_ERROR_BAD_DISPLAY;
2338 }
2339
2340 return CallDisplayFunction(device, display, &HWCDisplay::GetReadbackBufferFence, release_fence);
2341 }
2342
SetIdlePC(const android::Parcel * input_parcel)2343 android::status_t HWCSession::SetIdlePC(const android::Parcel *input_parcel) {
2344 auto enable = input_parcel->readInt32();
2345 auto synchronous = input_parcel->readInt32();
2346
2347 #ifdef DISPLAY_CONFIG_1_3
2348 return static_cast<android::status_t>(controlIdlePowerCollapse(enable, synchronous));
2349 #else
2350 {
2351 SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
2352 if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
2353 DLOGE("Primary display is not ready");
2354 return -EINVAL;
2355 }
2356 auto error = hwc_display_[HWC_DISPLAY_PRIMARY]->ControlIdlePowerCollapse(enable, synchronous);
2357 if (error != HWC2::Error::None) {
2358 return -EINVAL;
2359 }
2360 if (!enable) {
2361 Refresh(HWC_DISPLAY_PRIMARY);
2362 int32_t error = locker_[HWC_DISPLAY_PRIMARY].WaitFinite(kCommitDoneTimeoutMs);
2363 if (error == ETIMEDOUT) {
2364 DLOGE("Timed out!! Next frame commit done event not received!!");
2365 return error;
2366 }
2367 }
2368 DLOGI("Idle PC %s!!", enable ? "enabled" : "disabled");
2369 }
2370 return 0;
2371 #endif
2372 }
2373
2374 } // namespace sdm
2375