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
SetLayerColorTransform(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,const float * matrix)853 static int32_t SetLayerColorTransform(hwc2_device_t *device, hwc2_display_t display,
854 hwc2_layer_t layer, const float *matrix) {
855 return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerColorTransform,
856 matrix);
857 }
858
SetOutputBuffer(hwc2_device_t * device,hwc2_display_t display,buffer_handle_t buffer,int32_t releaseFence)859 int32_t HWCSession::SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
860 buffer_handle_t buffer, int32_t releaseFence) {
861 if (!device) {
862 return HWC2_ERROR_BAD_PARAMETER;
863 }
864
865 if (display != HWC_DISPLAY_VIRTUAL) {
866 return HWC2_ERROR_UNSUPPORTED;
867 }
868
869 SCOPE_LOCK(locker_[display]);
870 auto *hwc_session = static_cast<HWCSession *>(device);
871 if (hwc_session->hwc_display_[display]) {
872 auto vds = reinterpret_cast<HWCDisplayVirtual *>(hwc_session->hwc_display_[display]);
873 auto status = vds->SetOutputBuffer(buffer, releaseFence);
874 return INT32(status);
875 } else {
876 return HWC2_ERROR_BAD_DISPLAY;
877 }
878 }
879
SetPowerMode(hwc2_device_t * device,hwc2_display_t display,int32_t int_mode)880 int32_t HWCSession::SetPowerMode(hwc2_device_t *device, hwc2_display_t display, int32_t int_mode) {
881 if (display >= HWC_NUM_DISPLAY_TYPES) {
882 return HWC2_ERROR_BAD_DISPLAY;
883 }
884
885 // validate device and also avoid undefined behavior in cast to HWC2::PowerMode
886 if (!device || int_mode < HWC2_POWER_MODE_OFF || int_mode > HWC2_POWER_MODE_DOZE_SUSPEND) {
887 return HWC2_ERROR_BAD_PARAMETER;
888 }
889
890 auto mode = static_cast<HWC2::PowerMode>(int_mode);
891
892 // all displays support on/off. Check for doze modes
893 int support = 0;
894
895 auto status = GetDozeSupport(device, display, &support);
896 if (status != HWC2_ERROR_NONE) {
897 return INT32(status);
898 }
899
900 if (!support && (mode == HWC2::PowerMode::Doze || mode == HWC2::PowerMode::DozeSuspend)) {
901 return HWC2_ERROR_UNSUPPORTED;
902 }
903
904 auto error = CallDisplayFunction(device, display, &HWCDisplay::SetPowerMode, mode);
905 if (error != HWC2_ERROR_NONE) {
906 return error;
907 }
908 // Reset idle pc ref count on suspend, as we enable idle pc during suspend.
909 if (mode == HWC2::PowerMode::Off) {
910 HWCSession *hwc_session = static_cast<HWCSession *>(device);
911 hwc_session->idle_pc_ref_cnt_ = 0;
912 }
913
914 return HWC2_ERROR_NONE;
915 }
916
SetVsyncEnabled(hwc2_device_t * device,hwc2_display_t display,int32_t int_enabled)917 static int32_t SetVsyncEnabled(hwc2_device_t *device, hwc2_display_t display, int32_t int_enabled) {
918 // avoid undefined behavior in cast to HWC2::Vsync
919 if (int_enabled < HWC2_VSYNC_INVALID || int_enabled > HWC2_VSYNC_DISABLE) {
920 return HWC2_ERROR_BAD_PARAMETER;
921 }
922
923 auto enabled = static_cast<HWC2::Vsync>(int_enabled);
924 return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetVsyncEnabled, enabled);
925 }
926
ValidateDisplay(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_types,uint32_t * out_num_requests)927 int32_t HWCSession::ValidateDisplay(hwc2_device_t *device, hwc2_display_t display,
928 uint32_t *out_num_types, uint32_t *out_num_requests) {
929 // out_num_types and out_num_requests will be non-NULL
930 if (!device) {
931 return HWC2_ERROR_BAD_PARAMETER;
932 }
933
934 if (display >= HWC_NUM_DISPLAY_TYPES) {
935 return HWC2_ERROR_BAD_DISPLAY;
936 }
937
938 DTRACE_SCOPED();
939 HWCSession *hwc_session = static_cast<HWCSession *>(device);
940 // TODO(user): Handle secure session, handle QDCM solid fill
941 // Handle external_pending_connect_ in CreateVirtualDisplay
942 auto status = HWC2::Error::BadDisplay;
943 {
944 SEQUENCE_ENTRY_SCOPE_LOCK(locker_[display]);
945 if (hwc_session->hwc_display_[display]) {
946 status = hwc_session->ValidateDisplayInternal(display, out_num_types, out_num_requests);
947 }
948 }
949
950 // Sequence locking currently begins on Validate, so cancel the sequence lock on failures
951 if (status != HWC2::Error::None && status != HWC2::Error::HasChanges) {
952 SEQUENCE_CANCEL_SCOPE_LOCK(locker_[display]);
953 }
954
955 return INT32(status);
956 }
957
GetDisplayCapabilities(hwc2_device_t * device,hwc2_display_t display,uint32_t * outNumCapabilities,uint32_t * outCapabilities)958 int32_t HWCSession::GetDisplayCapabilities(hwc2_device_t* device, hwc2_display_t display,
959 uint32_t* outNumCapabilities, uint32_t* outCapabilities) {
960 if (outNumCapabilities == nullptr) {
961 return INT32(HWC2::Error::None);
962 }
963
964 bool brightness_support = false;
965 auto status = GetDisplayBrightnessSupport(device, display, &brightness_support);
966 if (status != HWC2_ERROR_NONE) {
967 DLOGE("Failed to get display brightness support Error = %d", status);
968 return INT32(status);
969 }
970 int doze_support = 0;
971 status = GetDozeSupport(device, display, &doze_support);
972 if (status != HWC2_ERROR_NONE) {
973 DLOGE("Failed to get doze support Error = %d", status);
974 return INT32(status);
975 }
976
977 uint32_t count = 1 + static_cast<uint32_t>(doze_support) + (brightness_support ? 1 : 0);
978 int index = 0;
979 if (outCapabilities != nullptr && (*outNumCapabilities >= count)) {
980 outCapabilities[index++] = HWC2_DISPLAY_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM;
981 if (doze_support == 1) {
982 outCapabilities[index++] = HWC2_DISPLAY_CAPABILITY_DOZE;
983 }
984 if (brightness_support) {
985 outCapabilities[index++] = HWC2_DISPLAY_CAPABILITY_BRIGHTNESS;
986 }
987 }
988
989 *outNumCapabilities = count;
990 return INT32(HWC2::Error::None);
991 }
992
SetDisplayBrightness(hwc2_device_t * device,hwc2_display_t display,float brightness)993 int32_t HWCSession::SetDisplayBrightness(hwc2_device_t *device, hwc2_display_t display,
994 float brightness) {
995 bool brightness_support = false;
996 auto status = GetDisplayBrightnessSupport(device, display, &brightness_support);
997 if (status != HWC2_ERROR_NONE) {
998 return INT32(status);
999 }
1000 if (!brightness_support) {
1001 return HWC2_ERROR_UNSUPPORTED;
1002 }
1003 int backlight = -1;
1004 if (brightness == -1.0f) {
1005 backlight = 0;
1006 } else if (brightness < 0.0f || brightness > 1.0f) {
1007 return INT32(HWC2::Error::BadParameter);
1008 } else {
1009 // 0 is reserved for "backlight off", so we scale the brightness from 1 to MAX_BRIGHTNESS.
1010 backlight = (int) ((MAX_BRIGHTNESS - 1.0f) * brightness + 1.0f);
1011 }
1012 char buff[20];
1013 int n = snprintf(buff, sizeof(buff), "%d\n", backlight);
1014 if (n < 0 || n >= sizeof(buff)) {
1015 return INT32(HWC2::Error::BadParameter);
1016 }
1017
1018 HWCSession *hwc_session = static_cast<HWCSession *>(device);
1019 long error = lseek(hwc_session->brightness_fd_, 0, SEEK_SET);
1020 if (error == -1) {
1021 DLOGW("Failed to rewind brightness file: [%d] %s", errno, strerror(errno));
1022 return INT32(HWC2::Error::NoResources);
1023 }
1024 error = write(hwc_session->brightness_fd_, buff, (size_t) n);
1025 if (error == -1) {
1026 DLOGW("Failed to write to brightness file: [%d] %s", errno, strerror(errno));
1027 return INT32(HWC2::Error::NoResources);
1028 }
1029 error = fsync(hwc_session->brightness_fd_);
1030 if (error == -1) {
1031 DLOGW("Failed to flush brightness file: [%d] %s", errno, strerror(errno));
1032 return INT32(HWC2::Error::NoResources);
1033 }
1034
1035 return INT32(HWC2::Error::None);
1036 }
1037
GetFunction(struct hwc2_device * device,int32_t int_descriptor)1038 hwc2_function_pointer_t HWCSession::GetFunction(struct hwc2_device *device,
1039 int32_t int_descriptor) {
1040 auto descriptor = static_cast<HWC2::FunctionDescriptor>(int_descriptor);
1041
1042 switch (descriptor) {
1043 case HWC2::FunctionDescriptor::AcceptDisplayChanges:
1044 return AsFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(HWCSession::AcceptDisplayChanges);
1045 case HWC2::FunctionDescriptor::CreateLayer:
1046 return AsFP<HWC2_PFN_CREATE_LAYER>(CreateLayer);
1047 case HWC2::FunctionDescriptor::CreateVirtualDisplay:
1048 return AsFP<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(HWCSession::CreateVirtualDisplay);
1049 case HWC2::FunctionDescriptor::DestroyLayer:
1050 return AsFP<HWC2_PFN_DESTROY_LAYER>(DestroyLayer);
1051 case HWC2::FunctionDescriptor::DestroyVirtualDisplay:
1052 return AsFP<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(HWCSession::DestroyVirtualDisplay);
1053 case HWC2::FunctionDescriptor::Dump:
1054 return AsFP<HWC2_PFN_DUMP>(HWCSession::Dump);
1055 case HWC2::FunctionDescriptor::GetActiveConfig:
1056 return AsFP<HWC2_PFN_GET_ACTIVE_CONFIG>(GetActiveConfig);
1057 case HWC2::FunctionDescriptor::GetChangedCompositionTypes:
1058 return AsFP<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(GetChangedCompositionTypes);
1059 case HWC2::FunctionDescriptor::GetClientTargetSupport:
1060 return AsFP<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(GetClientTargetSupport);
1061 case HWC2::FunctionDescriptor::GetColorModes:
1062 return AsFP<HWC2_PFN_GET_COLOR_MODES>(GetColorModes);
1063 case HWC2::FunctionDescriptor::GetDisplayAttribute:
1064 return AsFP<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(GetDisplayAttribute);
1065 case HWC2::FunctionDescriptor::GetDisplayConfigs:
1066 return AsFP<HWC2_PFN_GET_DISPLAY_CONFIGS>(GetDisplayConfigs);
1067 case HWC2::FunctionDescriptor::GetDisplayName:
1068 return AsFP<HWC2_PFN_GET_DISPLAY_NAME>(GetDisplayName);
1069 case HWC2::FunctionDescriptor::GetDisplayRequests:
1070 return AsFP<HWC2_PFN_GET_DISPLAY_REQUESTS>(GetDisplayRequests);
1071 case HWC2::FunctionDescriptor::GetDisplayType:
1072 return AsFP<HWC2_PFN_GET_DISPLAY_TYPE>(GetDisplayType);
1073 case HWC2::FunctionDescriptor::GetHdrCapabilities:
1074 return AsFP<HWC2_PFN_GET_HDR_CAPABILITIES>(GetHdrCapabilities);
1075 case HWC2::FunctionDescriptor::GetDozeSupport:
1076 return AsFP<HWC2_PFN_GET_DOZE_SUPPORT>(GetDozeSupport);
1077 case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount:
1078 return AsFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(GetMaxVirtualDisplayCount);
1079 case HWC2::FunctionDescriptor::GetReleaseFences:
1080 return AsFP<HWC2_PFN_GET_RELEASE_FENCES>(GetReleaseFences);
1081 case HWC2::FunctionDescriptor::PresentDisplay:
1082 return AsFP<HWC2_PFN_PRESENT_DISPLAY>(PresentDisplay);
1083 case HWC2::FunctionDescriptor::RegisterCallback:
1084 return AsFP<HWC2_PFN_REGISTER_CALLBACK>(RegisterCallback);
1085 case HWC2::FunctionDescriptor::SetActiveConfig:
1086 return AsFP<HWC2_PFN_SET_ACTIVE_CONFIG>(SetActiveConfig);
1087 case HWC2::FunctionDescriptor::SetClientTarget:
1088 return AsFP<HWC2_PFN_SET_CLIENT_TARGET>(SetClientTarget);
1089 case HWC2::FunctionDescriptor::SetColorMode:
1090 return AsFP<HWC2_PFN_SET_COLOR_MODE>(SetColorMode);
1091 case HWC2::FunctionDescriptor::SetColorTransform:
1092 return AsFP<HWC2_PFN_SET_COLOR_TRANSFORM>(SetColorTransform);
1093 case HWC2::FunctionDescriptor::SetCursorPosition:
1094 return AsFP<HWC2_PFN_SET_CURSOR_POSITION>(SetCursorPosition);
1095 case HWC2::FunctionDescriptor::SetLayerBlendMode:
1096 return AsFP<HWC2_PFN_SET_LAYER_BLEND_MODE>(SetLayerBlendMode);
1097 case HWC2::FunctionDescriptor::SetLayerBuffer:
1098 return AsFP<HWC2_PFN_SET_LAYER_BUFFER>(SetLayerBuffer);
1099 case HWC2::FunctionDescriptor::SetLayerColor:
1100 return AsFP<HWC2_PFN_SET_LAYER_COLOR>(SetLayerColor);
1101 case HWC2::FunctionDescriptor::SetLayerCompositionType:
1102 return AsFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(SetLayerCompositionType);
1103 case HWC2::FunctionDescriptor::SetLayerDataspace:
1104 return AsFP<HWC2_PFN_SET_LAYER_DATASPACE>(SetLayerDataspace);
1105 case HWC2::FunctionDescriptor::SetLayerDisplayFrame:
1106 return AsFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(SetLayerDisplayFrame);
1107 case HWC2::FunctionDescriptor::SetLayerPlaneAlpha:
1108 return AsFP<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(SetLayerPlaneAlpha);
1109 // Sideband stream is not supported
1110 // case HWC2::FunctionDescriptor::SetLayerSidebandStream:
1111 case HWC2::FunctionDescriptor::SetLayerSourceCrop:
1112 return AsFP<HWC2_PFN_SET_LAYER_SOURCE_CROP>(SetLayerSourceCrop);
1113 case HWC2::FunctionDescriptor::SetLayerSurfaceDamage:
1114 return AsFP<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(SetLayerSurfaceDamage);
1115 case HWC2::FunctionDescriptor::SetLayerTransform:
1116 return AsFP<HWC2_PFN_SET_LAYER_TRANSFORM>(SetLayerTransform);
1117 case HWC2::FunctionDescriptor::SetLayerVisibleRegion:
1118 return AsFP<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(SetLayerVisibleRegion);
1119 case HWC2::FunctionDescriptor::SetLayerZOrder:
1120 return AsFP<HWC2_PFN_SET_LAYER_Z_ORDER>(SetLayerZOrder);
1121 case HWC2::FunctionDescriptor::SetLayerColorTransform:
1122 return AsFP<HWC2_PFN_SET_LAYER_COLOR_TRANSFORM>(SetLayerColorTransform);
1123 case HWC2::FunctionDescriptor::SetOutputBuffer:
1124 return AsFP<HWC2_PFN_SET_OUTPUT_BUFFER>(SetOutputBuffer);
1125 case HWC2::FunctionDescriptor::SetPowerMode:
1126 return AsFP<HWC2_PFN_SET_POWER_MODE>(SetPowerMode);
1127 case HWC2::FunctionDescriptor::SetVsyncEnabled:
1128 return AsFP<HWC2_PFN_SET_VSYNC_ENABLED>(SetVsyncEnabled);
1129 case HWC2::FunctionDescriptor::ValidateDisplay:
1130 return AsFP<HWC2_PFN_VALIDATE_DISPLAY>(HWCSession::ValidateDisplay);
1131 case HWC2::FunctionDescriptor::SetReadbackBuffer:
1132 return AsFP<HWC2_PFN_SET_READBACK_BUFFER>(HWCSession::SetReadbackBuffer);
1133 case HWC2::FunctionDescriptor::GetReadbackBufferAttributes:
1134 return AsFP<HWC2_PFN_GET_READBACK_BUFFER_ATTRIBUTES>(HWCSession::GetReadbackBufferAttributes);
1135 case HWC2::FunctionDescriptor::GetReadbackBufferFence:
1136 return AsFP<HWC2_PFN_GET_READBACK_BUFFER_FENCE>(HWCSession::GetReadbackBufferFence);
1137 case HWC2::FunctionDescriptor::GetRenderIntents:
1138 return AsFP<HWC2_PFN_GET_RENDER_INTENTS>(GetRenderIntents);
1139 case HWC2::FunctionDescriptor::SetColorModeWithRenderIntent:
1140 return AsFP<HWC2_PFN_SET_COLOR_MODE_WITH_RENDER_INTENT>(
1141 HWCSession::SetColorModeWithRenderIntent);
1142 case HWC2::FunctionDescriptor::GetDataspaceSaturationMatrix:
1143 return AsFP<HWC2_PFN_GET_DATASPACE_SATURATION_MATRIX>(GetDataspaceSaturationMatrix);
1144 case HWC2::FunctionDescriptor::GetPerFrameMetadataKeys:
1145 return AsFP<HWC2_PFN_GET_PER_FRAME_METADATA_KEYS>(GetPerFrameMetadataKeys);
1146 case HWC2::FunctionDescriptor::SetLayerPerFrameMetadata:
1147 return AsFP<HWC2_PFN_SET_LAYER_PER_FRAME_METADATA>(SetLayerPerFrameMetadata);
1148 case HWC2::FunctionDescriptor::SetDisplayedContentSamplingEnabled:
1149 return AsFP<HWC2_PFN_SET_DISPLAYED_CONTENT_SAMPLING_ENABLED>(SetDisplayedContentSamplingEnabled);
1150 case HWC2::FunctionDescriptor::GetDisplayedContentSamplingAttributes:
1151 return AsFP<HWC2_PFN_GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES>(GetDisplayedContentSamplingAttributes);
1152 case HWC2::FunctionDescriptor::GetDisplayedContentSample:
1153 return AsFP<HWC2_PFN_GET_DISPLAYED_CONTENT_SAMPLE>(GetDisplayedContentSample);
1154 case HWC2::FunctionDescriptor::GetDisplayCapabilities:
1155 return AsFP<HWC2_PFN_GET_DISPLAY_CAPABILITIES>(GetDisplayCapabilities);
1156 case HWC2::FunctionDescriptor::SetDisplayBrightness:
1157 return AsFP<HWC2_PFN_SET_DISPLAY_BRIGHTNESS>(SetDisplayBrightness);
1158 default:
1159 DLOGD("Unknown/Unimplemented function descriptor: %d (%s)", int_descriptor,
1160 to_string(descriptor).c_str());
1161 return nullptr;
1162 }
1163 return nullptr;
1164 }
1165
CreateVirtualDisplayObject(uint32_t width,uint32_t height,int32_t * format)1166 HWC2::Error HWCSession::CreateVirtualDisplayObject(uint32_t width, uint32_t height,
1167 int32_t *format) {
1168 {
1169 SCOPE_LOCK(locker_[HWC_DISPLAY_VIRTUAL]);
1170 if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
1171 return HWC2::Error::NoResources;
1172 }
1173
1174 if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
1175 auto error = hwc_display_[HWC_DISPLAY_PRIMARY]->TeardownConcurrentWriteback();
1176 if (error) {
1177 return HWC2::Error::NoResources;
1178 }
1179 }
1180
1181 auto status = HWCDisplayVirtual::Create(core_intf_, &buffer_allocator_, &callbacks_, width,
1182 height, format, &hwc_display_[HWC_DISPLAY_VIRTUAL]);
1183 // TODO(user): validate width and height support
1184 if (status) {
1185 return HWC2::Error::NoResources;
1186 }
1187 }
1188
1189 SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1190 hwc_display_[HWC_DISPLAY_PRIMARY]->ResetValidation();
1191
1192 return HWC2::Error::None;
1193 }
1194
ConnectDisplay(int disp)1195 int32_t HWCSession::ConnectDisplay(int disp) {
1196 DLOGI("Display = %d", disp);
1197
1198 int status = 0;
1199 uint32_t primary_width = 0;
1200 uint32_t primary_height = 0;
1201
1202 hwc_display_[HWC_DISPLAY_PRIMARY]->GetFrameBufferResolution(&primary_width, &primary_height);
1203
1204 if (disp == HWC_DISPLAY_EXTERNAL) {
1205 status = CreateExternalDisplay(disp, primary_width, primary_height, false);
1206 } else {
1207 DLOGE("Invalid display type");
1208 return -1;
1209 }
1210
1211 if (!status) {
1212 hwc_display_[disp]->SetSecureDisplay(secure_display_active_);
1213 }
1214
1215 return status;
1216 }
1217
DisconnectDisplay(int disp)1218 int HWCSession::DisconnectDisplay(int disp) {
1219 DLOGI("Display = %d", disp);
1220
1221 if (disp == HWC_DISPLAY_EXTERNAL) {
1222 DisplayError error = hwc_display_[disp]->Flush();
1223 if (error != kErrorNone) {
1224 DLOGW("Flush failed. Error = %d", error);
1225 }
1226 HWCDisplayExternal::Destroy(hwc_display_[disp]);
1227 } else if (disp == HWC_DISPLAY_VIRTUAL) {
1228 HWCDisplayVirtual::Destroy(hwc_display_[disp]);
1229 } else {
1230 DLOGE("Invalid display type");
1231 return -1;
1232 }
1233
1234 hwc_display_[disp] = NULL;
1235
1236 return 0;
1237 }
1238
1239 // Qclient methods
notifyCallback(uint32_t command,const android::Parcel * input_parcel,android::Parcel * output_parcel)1240 android::status_t HWCSession::notifyCallback(uint32_t command, const android::Parcel *input_parcel,
1241 android::Parcel *output_parcel) {
1242 android::status_t status = -EINVAL;
1243
1244 switch (command) {
1245 case qService::IQService::DYNAMIC_DEBUG:
1246 if (!input_parcel) {
1247 DLOGE("QService command = %d: input_parcel needed.", command);
1248 break;
1249 }
1250 status = 0;
1251 DynamicDebug(input_parcel);
1252 break;
1253
1254 case qService::IQService::SCREEN_REFRESH:
1255 status = refreshScreen();
1256 break;
1257
1258 case qService::IQService::SET_IDLE_TIMEOUT:
1259 if (!input_parcel) {
1260 DLOGE("QService command = %d: input_parcel needed.", command);
1261 break;
1262 }
1263 status = setIdleTimeout(UINT32(input_parcel->readInt32()));
1264 break;
1265
1266 case qService::IQService::SET_FRAME_DUMP_CONFIG:
1267 if (!input_parcel) {
1268 DLOGE("QService command = %d: input_parcel needed.", command);
1269 break;
1270 }
1271 status = SetFrameDumpConfig(input_parcel);
1272 break;
1273
1274 case qService::IQService::SET_MAX_PIPES_PER_MIXER:
1275 if (!input_parcel) {
1276 DLOGE("QService command = %d: input_parcel needed.", command);
1277 break;
1278 }
1279 status = SetMaxMixerStages(input_parcel);
1280 break;
1281
1282 case qService::IQService::SET_DISPLAY_MODE:
1283 if (!input_parcel) {
1284 DLOGE("QService command = %d: input_parcel needed.", command);
1285 break;
1286 }
1287 status = SetDisplayMode(input_parcel);
1288 break;
1289
1290 case qService::IQService::SET_SECONDARY_DISPLAY_STATUS: {
1291 if (!input_parcel || !output_parcel) {
1292 DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1293 break;
1294 }
1295 int disp_id = INT(input_parcel->readInt32());
1296 HWCDisplay::DisplayStatus disp_status =
1297 static_cast<HWCDisplay::DisplayStatus>(input_parcel->readInt32());
1298 status = SetSecondaryDisplayStatus(disp_id, disp_status);
1299 output_parcel->writeInt32(status);
1300 }
1301 break;
1302
1303 case qService::IQService::CONFIGURE_DYN_REFRESH_RATE:
1304 if (!input_parcel) {
1305 DLOGE("QService command = %d: input_parcel needed.", command);
1306 break;
1307 }
1308 status = ConfigureRefreshRate(input_parcel);
1309 break;
1310
1311 case qService::IQService::SET_VIEW_FRAME:
1312 status = 0;
1313 break;
1314
1315 case qService::IQService::TOGGLE_SCREEN_UPDATES: {
1316 if (!input_parcel || !output_parcel) {
1317 DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1318 break;
1319 }
1320 int32_t input = input_parcel->readInt32();
1321 status = toggleScreenUpdate(input == 1);
1322 output_parcel->writeInt32(status);
1323 }
1324 break;
1325
1326 case qService::IQService::QDCM_SVC_CMDS:
1327 if (!input_parcel || !output_parcel) {
1328 DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1329 break;
1330 }
1331 status = QdcmCMDHandler(input_parcel, output_parcel);
1332 break;
1333
1334 case qService::IQService::MIN_HDCP_ENCRYPTION_LEVEL_CHANGED: {
1335 if (!input_parcel || !output_parcel) {
1336 DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1337 break;
1338 }
1339 int disp_id = input_parcel->readInt32();
1340 uint32_t min_enc_level = UINT32(input_parcel->readInt32());
1341 status = MinHdcpEncryptionLevelChanged(disp_id, min_enc_level);
1342 output_parcel->writeInt32(status);
1343 }
1344 break;
1345
1346 case qService::IQService::CONTROL_PARTIAL_UPDATE: {
1347 if (!input_parcel || !output_parcel) {
1348 DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1349 break;
1350 }
1351 int disp_id = input_parcel->readInt32();
1352 uint32_t enable = UINT32(input_parcel->readInt32());
1353 status = ControlPartialUpdate(disp_id, enable == 1);
1354 output_parcel->writeInt32(status);
1355 }
1356 break;
1357
1358 case qService::IQService::SET_ACTIVE_CONFIG: {
1359 if (!input_parcel) {
1360 DLOGE("QService command = %d: input_parcel needed.", command);
1361 break;
1362 }
1363 uint32_t config = UINT32(input_parcel->readInt32());
1364 int disp_id = input_parcel->readInt32();
1365 status = SetActiveConfigIndex(disp_id, config);
1366 }
1367 break;
1368
1369 case qService::IQService::GET_ACTIVE_CONFIG: {
1370 if (!input_parcel || !output_parcel) {
1371 DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1372 break;
1373 }
1374 int disp_id = input_parcel->readInt32();
1375 uint32_t config = 0;
1376 status = GetActiveConfigIndex(disp_id, &config);
1377 output_parcel->writeInt32(INT(config));
1378 }
1379 break;
1380
1381 case qService::IQService::GET_CONFIG_COUNT: {
1382 if (!input_parcel || !output_parcel) {
1383 DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1384 break;
1385 }
1386 int disp_id = input_parcel->readInt32();
1387 uint32_t count = 0;
1388 status = GetConfigCount(disp_id, &count);
1389 output_parcel->writeInt32(INT(count));
1390 }
1391 break;
1392
1393 case qService::IQService::GET_DISPLAY_ATTRIBUTES_FOR_CONFIG:
1394 if (!input_parcel || !output_parcel) {
1395 DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1396 break;
1397 }
1398 status = HandleGetDisplayAttributesForConfig(input_parcel, output_parcel);
1399 break;
1400
1401 case qService::IQService::GET_PANEL_BRIGHTNESS: {
1402 if (!output_parcel) {
1403 DLOGE("QService command = %d: output_parcel needed.", command);
1404 break;
1405 }
1406 int level = 0;
1407 status = GetPanelBrightness(&level);
1408 output_parcel->writeInt32(level);
1409 }
1410 break;
1411
1412 case qService::IQService::SET_PANEL_BRIGHTNESS: {
1413 if (!input_parcel || !output_parcel) {
1414 DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1415 break;
1416 }
1417 uint32_t level = UINT32(input_parcel->readInt32());
1418 status = setPanelBrightness(level);
1419 output_parcel->writeInt32(status);
1420 }
1421 break;
1422
1423 case qService::IQService::GET_DISPLAY_VISIBLE_REGION:
1424 if (!input_parcel || !output_parcel) {
1425 DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1426 break;
1427 }
1428 status = GetVisibleDisplayRect(input_parcel, output_parcel);
1429 break;
1430
1431 case qService::IQService::SET_CAMERA_STATUS: {
1432 if (!input_parcel) {
1433 DLOGE("QService command = %d: input_parcel needed.", command);
1434 break;
1435 }
1436 uint32_t camera_status = UINT32(input_parcel->readInt32());
1437 status = setCameraLaunchStatus(camera_status);
1438 }
1439 break;
1440
1441 case qService::IQService::GET_BW_TRANSACTION_STATUS: {
1442 if (!output_parcel) {
1443 DLOGE("QService command = %d: output_parcel needed.", command);
1444 break;
1445 }
1446 bool state = true;
1447 status = DisplayBWTransactionPending(&state);
1448 output_parcel->writeInt32(state);
1449 }
1450 break;
1451
1452 case qService::IQService::SET_LAYER_MIXER_RESOLUTION:
1453 if (!input_parcel) {
1454 DLOGE("QService command = %d: input_parcel needed.", command);
1455 break;
1456 }
1457 status = SetMixerResolution(input_parcel);
1458 break;
1459
1460 case qService::IQService::SET_COLOR_MODE:
1461 if (!input_parcel) {
1462 DLOGE("QService command = %d: input_parcel needed.", command);
1463 break;
1464 }
1465 status = SetColorModeOverride(input_parcel);
1466 break;
1467
1468 case qService::IQService::SET_COLOR_MODE_WITH_RENDER_INTENT:
1469 if (!input_parcel) {
1470 DLOGE("QService command = %d: input_parcel needed.", command);
1471 break;
1472 }
1473 status = SetColorModeWithRenderIntentOverride(input_parcel);
1474 break;
1475
1476 case qService::IQService::SET_COLOR_MODE_BY_ID:
1477 if (!input_parcel) {
1478 DLOGE("QService command = %d: input_parcel needed.", command);
1479 break;
1480 }
1481 status = SetColorModeById(input_parcel);
1482 break;
1483
1484 case qService::IQService::GET_COMPOSER_STATUS:
1485 if (!output_parcel) {
1486 DLOGE("QService command = %d: output_parcel needed.", command);
1487 break;
1488 }
1489 status = 0;
1490 output_parcel->writeInt32(getComposerStatus());
1491 break;
1492
1493 case qService::IQService::SET_IDLE_PC:
1494 if (!input_parcel) {
1495 DLOGE("QService command = %d: input_parcel needed.", command);
1496 break;
1497 }
1498 status = SetIdlePC(input_parcel);
1499 break;
1500
1501 case qService::IQService::SET_COLOR_SAMPLING_ENABLED:
1502 if (!input_parcel) {
1503 DLOGE("QService command = %d: input_parcel needed.", command);
1504 break;
1505 }
1506 status = setColorSamplingEnabled(input_parcel);
1507 break;
1508
1509 case qService::IQService::SET_WHITE_COMPENSATION:
1510 if (!input_parcel) {
1511 DLOGE("QService command = %d: input_parcel needed.", command);
1512 break;
1513 }
1514 status = SetWhiteCompensation(input_parcel);
1515 break;
1516 default:
1517 DLOGW("QService command = %d is not supported.", command);
1518 break;
1519 }
1520
1521 return status;
1522 }
1523
getComposerStatus()1524 android::status_t HWCSession::getComposerStatus() {
1525 return is_composer_up_;
1526 }
1527
setColorSamplingEnabled(const android::Parcel * input_parcel)1528 android::status_t HWCSession::setColorSamplingEnabled(const android::Parcel* input_parcel)
1529 {
1530 int dpy = input_parcel->readInt32();
1531 int enabled_cmd = input_parcel->readInt32();
1532 if (dpy < HWC_DISPLAY_PRIMARY || dpy >= HWC_NUM_DISPLAY_TYPES ||
1533 enabled_cmd < 0 || enabled_cmd > 1) {
1534 return android::BAD_VALUE;
1535 }
1536
1537 SEQUENCE_WAIT_SCOPE_LOCK(locker_[dpy]);
1538 if (!hwc_display_[dpy]) {
1539 DLOGW("No display id %i active to enable histogram event", dpy);
1540 return android::BAD_VALUE;
1541 }
1542
1543 auto error = hwc_display_[dpy]->SetDisplayedContentSamplingEnabledVndService(enabled_cmd);
1544 return (error == HWC2::Error::None) ? android::OK : android::BAD_VALUE;
1545 }
1546
HandleGetDisplayAttributesForConfig(const android::Parcel * input_parcel,android::Parcel * output_parcel)1547 android::status_t HWCSession::HandleGetDisplayAttributesForConfig(const android::Parcel
1548 *input_parcel,
1549 android::Parcel *output_parcel) {
1550 int config = input_parcel->readInt32();
1551 int dpy = input_parcel->readInt32();
1552 int error = android::BAD_VALUE;
1553 DisplayConfigVariableInfo display_attributes;
1554
1555 if (dpy < HWC_DISPLAY_PRIMARY || dpy >= HWC_NUM_DISPLAY_TYPES || config < 0) {
1556 return android::BAD_VALUE;
1557 }
1558
1559 SEQUENCE_WAIT_SCOPE_LOCK(locker_[dpy]);
1560 if (hwc_display_[dpy]) {
1561 error = hwc_display_[dpy]->GetDisplayAttributesForConfig(config, &display_attributes);
1562 if (error == 0) {
1563 output_parcel->writeInt32(INT(display_attributes.vsync_period_ns));
1564 output_parcel->writeInt32(INT(display_attributes.x_pixels));
1565 output_parcel->writeInt32(INT(display_attributes.y_pixels));
1566 output_parcel->writeFloat(display_attributes.x_dpi);
1567 output_parcel->writeFloat(display_attributes.y_dpi);
1568 output_parcel->writeInt32(0); // Panel type, unsupported.
1569 }
1570 }
1571
1572 return error;
1573 }
1574
ConfigureRefreshRate(const android::Parcel * input_parcel)1575 android::status_t HWCSession::ConfigureRefreshRate(const android::Parcel *input_parcel) {
1576 SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1577
1578 uint32_t operation = UINT32(input_parcel->readInt32());
1579 HWCDisplay *hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
1580
1581 if (!hwc_display) {
1582 DLOGW("Display = %d is not connected.", HWC_DISPLAY_PRIMARY);
1583 return -ENODEV;
1584 }
1585
1586 switch (operation) {
1587 case qdutils::DISABLE_METADATA_DYN_REFRESH_RATE:
1588 return hwc_display->Perform(HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, false);
1589
1590 case qdutils::ENABLE_METADATA_DYN_REFRESH_RATE:
1591 return hwc_display->Perform(HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, true);
1592
1593 case qdutils::SET_BINDER_DYN_REFRESH_RATE: {
1594 uint32_t refresh_rate = UINT32(input_parcel->readInt32());
1595 return hwc_display->Perform(HWCDisplayPrimary::SET_BINDER_DYN_REFRESH_RATE, refresh_rate);
1596 }
1597
1598 default:
1599 DLOGW("Invalid operation %d", operation);
1600 return -EINVAL;
1601 }
1602
1603 return 0;
1604 }
1605
SetDisplayMode(const android::Parcel * input_parcel)1606 android::status_t HWCSession::SetDisplayMode(const android::Parcel *input_parcel) {
1607 SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1608
1609 if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
1610 DLOGW("Display = %d is not connected.", HWC_DISPLAY_PRIMARY);
1611 return -ENODEV;
1612 }
1613
1614 uint32_t mode = UINT32(input_parcel->readInt32());
1615 return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(HWCDisplayPrimary::SET_DISPLAY_MODE, mode);
1616 }
1617
SetMaxMixerStages(const android::Parcel * input_parcel)1618 android::status_t HWCSession::SetMaxMixerStages(const android::Parcel *input_parcel) {
1619 DisplayError error = kErrorNone;
1620 std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32());
1621 uint32_t max_mixer_stages = UINT32(input_parcel->readInt32());
1622 android::status_t status = 0;
1623
1624 for (uint32_t disp_id = HWC_DISPLAY_PRIMARY; disp_id < HWC_NUM_DISPLAY_TYPES; disp_id++) {
1625 if (bit_mask_display_type[disp_id]) {
1626 SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
1627 if (hwc_display_[disp_id]) {
1628 error = hwc_display_[disp_id]->SetMaxMixerStages(max_mixer_stages);
1629 if (error != kErrorNone) {
1630 status = -EINVAL;
1631 continue;
1632 }
1633 } else {
1634 DLOGW("Display = %d is not connected.", disp_id);
1635 status = (status)? status : -ENODEV; // Return higher priority error.
1636 continue;
1637 }
1638 }
1639 }
1640
1641 return status;
1642 }
1643
SetFrameDumpConfig(const android::Parcel * input_parcel)1644 android::status_t HWCSession::SetFrameDumpConfig(const android::Parcel *input_parcel) {
1645 uint32_t frame_dump_count = UINT32(input_parcel->readInt32());
1646 std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32());
1647 uint32_t bit_mask_layer_type = UINT32(input_parcel->readInt32());
1648 int32_t output_format = HAL_PIXEL_FORMAT_RGB_888;
1649 bool post_processed = true;
1650
1651 // Read optional user preferences: output_format and post_processed.
1652 if (input_parcel->dataPosition() != input_parcel->dataSize()) {
1653 // HAL Pixel Format for output buffer
1654 output_format = input_parcel->readInt32();
1655 }
1656 if (input_parcel->dataPosition() != input_parcel->dataSize()) {
1657 // Option to dump Layer Mixer output (0) or DSPP output (1)
1658 post_processed = (input_parcel->readInt32() != 0);
1659 }
1660
1661 android::status_t status = 0;
1662
1663 for (uint32_t disp_id = HWC_DISPLAY_PRIMARY; disp_id < HWC_NUM_DISPLAY_TYPES; disp_id++) {
1664 if (bit_mask_display_type[disp_id]) {
1665 SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
1666 if (hwc_display_[disp_id]) {
1667 HWC2::Error error;
1668 error = hwc_display_[disp_id]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type,
1669 output_format, post_processed);
1670 if (HWC2::Error::None != error) {
1671 if (HWC2::Error::NoResources == error)
1672 status = -ENOMEM;
1673 else
1674 status = -EINVAL;
1675 continue;
1676 }
1677 } else {
1678 DLOGW("Display = %d is not connected.", disp_id);
1679 status = (status)? status : -ENODEV; // Return higher priority error.
1680 continue;
1681 }
1682 }
1683 }
1684
1685 return status;
1686 }
1687
SetMixerResolution(const android::Parcel * input_parcel)1688 android::status_t HWCSession::SetMixerResolution(const android::Parcel *input_parcel) {
1689 DisplayError error = kErrorNone;
1690 uint32_t dpy = UINT32(input_parcel->readInt32());
1691
1692 if (dpy != HWC_DISPLAY_PRIMARY) {
1693 DLOGW("Resolution change not supported for this display = %d", dpy);
1694 return -EINVAL;
1695 }
1696
1697 SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1698 if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
1699 DLOGW("Primary display is not initialized");
1700 return -ENODEV;
1701 }
1702
1703 uint32_t width = UINT32(input_parcel->readInt32());
1704 uint32_t height = UINT32(input_parcel->readInt32());
1705
1706 error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetMixerResolution(width, height);
1707 if (error != kErrorNone) {
1708 return -EINVAL;
1709 }
1710
1711 return 0;
1712 }
1713
SetColorModeOverride(const android::Parcel * input_parcel)1714 android::status_t HWCSession::SetColorModeOverride(const android::Parcel *input_parcel) {
1715 auto display = static_cast<hwc2_display_t >(input_parcel->readInt32());
1716 auto mode = static_cast<ColorMode>(input_parcel->readInt32());
1717 auto device = static_cast<hwc2_device_t *>(this);
1718
1719 if (mode < ColorMode::NATIVE || mode > ColorMode::BT2100_HLG) {
1720 DLOGE("Invalid ColorMode: %d", mode);
1721 return HWC2_ERROR_BAD_PARAMETER;
1722 }
1723
1724 auto err = CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
1725 if (err != HWC2_ERROR_NONE)
1726 return -EINVAL;
1727
1728 return 0;
1729 }
1730
SetWhiteCompensation(const android::Parcel * input_parcel)1731 android::status_t HWCSession::SetWhiteCompensation(const android::Parcel *input_parcel) {
1732 auto display = static_cast<hwc2_display_t>(input_parcel->readInt32());
1733 auto enabled = static_cast<bool>(input_parcel->readInt32());
1734 auto device = static_cast<hwc2_device_t *>(this);
1735
1736 auto err = CallDisplayFunction(device, display, &HWCDisplay::SetWhiteCompensation, enabled);
1737 if (err != HWC2_ERROR_NONE)
1738 return -EINVAL;
1739
1740 return 0;
1741 }
1742
SetColorModeWithRenderIntentOverride(const android::Parcel * input_parcel)1743 android::status_t HWCSession::SetColorModeWithRenderIntentOverride(
1744 const android::Parcel *input_parcel) {
1745 auto display = static_cast<hwc2_display_t>(input_parcel->readInt32());
1746 auto mode = static_cast<ColorMode>(input_parcel->readInt32());
1747 auto intent = static_cast<RenderIntent>(input_parcel->readInt32());
1748 auto device = static_cast<hwc2_device_t *>(this);
1749
1750 if (mode < ColorMode::NATIVE || mode > ColorMode::BT2100_HLG) {
1751 DLOGE("Invalid ColorMode: %d", mode);
1752 return HWC2_ERROR_BAD_PARAMETER;
1753 }
1754
1755 if (intent < RenderIntent::COLORIMETRIC || intent > RenderIntent::TONE_MAP_ENHANCE) {
1756 DLOGE("Invalid RenderIntent: %d", intent);
1757 return HWC2_ERROR_BAD_PARAMETER;
1758 }
1759
1760 auto err =
1761 CallDisplayFunction(device, display, &HWCDisplay::SetColorModeWithRenderIntent, mode, intent);
1762 if (err != HWC2_ERROR_NONE)
1763 return -EINVAL;
1764
1765 return 0;
1766 }
SetColorModeById(const android::Parcel * input_parcel)1767 android::status_t HWCSession::SetColorModeById(const android::Parcel *input_parcel) {
1768 auto display = static_cast<hwc2_display_t >(input_parcel->readInt32());
1769 auto mode = input_parcel->readInt32();
1770 auto device = static_cast<hwc2_device_t *>(this);
1771
1772 auto err = CallDisplayFunction(device, display, &HWCDisplay::SetColorModeById, mode);
1773 if (err != HWC2_ERROR_NONE)
1774 return -EINVAL;
1775
1776 return 0;
1777 }
1778
DynamicDebug(const android::Parcel * input_parcel)1779 void HWCSession::DynamicDebug(const android::Parcel *input_parcel) {
1780 int type = input_parcel->readInt32();
1781 bool enable = (input_parcel->readInt32() > 0);
1782 DLOGI("type = %d enable = %d", type, enable);
1783 int verbose_level = input_parcel->readInt32();
1784
1785 switch (type) {
1786 case qService::IQService::DEBUG_ALL:
1787 HWCDebugHandler::DebugAll(enable, verbose_level);
1788 break;
1789
1790 case qService::IQService::DEBUG_MDPCOMP:
1791 HWCDebugHandler::DebugStrategy(enable, verbose_level);
1792 HWCDebugHandler::DebugCompManager(enable, verbose_level);
1793 break;
1794
1795 case qService::IQService::DEBUG_PIPE_LIFECYCLE:
1796 HWCDebugHandler::DebugResources(enable, verbose_level);
1797 break;
1798
1799 case qService::IQService::DEBUG_DRIVER_CONFIG:
1800 HWCDebugHandler::DebugDriverConfig(enable, verbose_level);
1801 break;
1802
1803 case qService::IQService::DEBUG_ROTATOR:
1804 HWCDebugHandler::DebugResources(enable, verbose_level);
1805 HWCDebugHandler::DebugDriverConfig(enable, verbose_level);
1806 HWCDebugHandler::DebugRotator(enable, verbose_level);
1807 break;
1808
1809 case qService::IQService::DEBUG_QDCM:
1810 HWCDebugHandler::DebugQdcm(enable, verbose_level);
1811 break;
1812
1813 case qService::IQService::DEBUG_SCALAR:
1814 HWCDebugHandler::DebugScalar(enable, verbose_level);
1815 break;
1816
1817 case qService::IQService::DEBUG_CLIENT:
1818 HWCDebugHandler::DebugClient(enable, verbose_level);
1819 break;
1820
1821 case qService::IQService::DEBUG_DISPLAY:
1822 HWCDebugHandler::DebugDisplay(enable, verbose_level);
1823 break;
1824
1825 default:
1826 DLOGW("type = %d is not supported", type);
1827 }
1828 }
1829
QdcmCMDHandler(const android::Parcel * input_parcel,android::Parcel * output_parcel)1830 android::status_t HWCSession::QdcmCMDHandler(const android::Parcel *input_parcel,
1831 android::Parcel *output_parcel) {
1832 int ret = 0;
1833 int32_t *brightness_value = NULL;
1834 uint32_t display_id(0);
1835 PPPendingParams pending_action;
1836 PPDisplayAPIPayload resp_payload, req_payload;
1837
1838 if (!color_mgr_) {
1839 DLOGW("color_mgr_ not initialized.");
1840 return -ENOENT;
1841 }
1842
1843 pending_action.action = kNoAction;
1844 pending_action.params = NULL;
1845
1846 // Read display_id, payload_size and payload from in_parcel.
1847 ret = HWCColorManager::CreatePayloadFromParcel(*input_parcel, &display_id, &req_payload);
1848 if (!ret) {
1849 if ((display_id >= HWC_NUM_DISPLAY_TYPES) || !hwc_display_[display_id]) {
1850 DLOGW("Invalid display id or display = %d is not connected.", display_id);
1851 ret = -ENODEV;
1852 }
1853 }
1854
1855 if (!ret) {
1856 if ((HWC_DISPLAY_PRIMARY == display_id) || (HWC_DISPLAY_EXTERNAL == display_id)) {
1857 ret = hwc_display_[display_id]->ColorSVCRequestRoute(req_payload, &resp_payload,
1858 &pending_action);
1859 } else {
1860 // Virtual, Tertiary etc. not supported.
1861 DLOGW("Operation not supported on display = %d.", display_id);
1862 ret = -EINVAL;
1863 }
1864 }
1865
1866 if (ret) {
1867 output_parcel->writeInt32(ret); // first field in out parcel indicates return code.
1868 req_payload.DestroyPayload();
1869 resp_payload.DestroyPayload();
1870 return ret;
1871 }
1872
1873 if (kNoAction != pending_action.action) {
1874 // Restrict pending actions to primary display.
1875 if (HWC_DISPLAY_PRIMARY != display_id) {
1876 DLOGW("Skipping pending action %d on display = %d.", pending_action.action, display_id);
1877 pending_action.action = kNoAction;
1878 }
1879
1880 int32_t action = pending_action.action;
1881 int count = -1;
1882 while (action > 0) {
1883 count++;
1884 int32_t bit = (action & 1);
1885 action = action >> 1;
1886
1887 if (!bit)
1888 continue;
1889
1890 DLOGV_IF(kTagQDCM, "pending action = %d", BITMAP(count));
1891 switch (BITMAP(count)) {
1892 case kInvalidating:
1893 Refresh(HWC_DISPLAY_PRIMARY);
1894 break;
1895 case kEnterQDCMMode:
1896 ret = color_mgr_->EnableQDCMMode(true, hwc_display_[HWC_DISPLAY_PRIMARY]);
1897 break;
1898 case kExitQDCMMode:
1899 ret = color_mgr_->EnableQDCMMode(false, hwc_display_[HWC_DISPLAY_PRIMARY]);
1900 break;
1901 case kApplySolidFill:
1902 {
1903 SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1904 ret = color_mgr_->SetSolidFill(pending_action.params,
1905 true, hwc_display_[HWC_DISPLAY_PRIMARY]);
1906 }
1907 Refresh(HWC_DISPLAY_PRIMARY);
1908 usleep(kSolidFillDelay);
1909 break;
1910 case kDisableSolidFill:
1911 {
1912 SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1913 ret = color_mgr_->SetSolidFill(pending_action.params,
1914 false, hwc_display_[HWC_DISPLAY_PRIMARY]);
1915 }
1916 Refresh(HWC_DISPLAY_PRIMARY);
1917 usleep(kSolidFillDelay);
1918 break;
1919 case kSetPanelBrightness:
1920 brightness_value = reinterpret_cast<int32_t *>(resp_payload.payload);
1921 if (brightness_value == NULL) {
1922 DLOGE("Brightness value is Null");
1923 ret = -EINVAL;
1924 } else {
1925 ret = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(*brightness_value);
1926 }
1927 break;
1928 case kEnableFrameCapture:
1929 ret = color_mgr_->SetFrameCapture(pending_action.params, true,
1930 hwc_display_[HWC_DISPLAY_PRIMARY]);
1931 Refresh(HWC_DISPLAY_PRIMARY);
1932 break;
1933 case kDisableFrameCapture:
1934 ret = color_mgr_->SetFrameCapture(pending_action.params, false,
1935 hwc_display_[HWC_DISPLAY_PRIMARY]);
1936 break;
1937 case kConfigureDetailedEnhancer:
1938 ret = color_mgr_->SetDetailedEnhancer(pending_action.params,
1939 hwc_display_[HWC_DISPLAY_PRIMARY]);
1940 Refresh(HWC_DISPLAY_PRIMARY);
1941 break;
1942 case kModeSet:
1943 ret = static_cast<int>
1944 (hwc_display_[HWC_DISPLAY_PRIMARY]->RestoreColorTransform());
1945 Refresh(HWC_DISPLAY_PRIMARY);
1946 break;
1947 case kNoAction:
1948 break;
1949 default:
1950 DLOGW("Invalid pending action = %d!", pending_action.action);
1951 break;
1952 }
1953 }
1954 }
1955 // for display API getter case, marshall returned params into out_parcel.
1956 output_parcel->writeInt32(ret);
1957 HWCColorManager::MarshallStructIntoParcel(resp_payload, output_parcel);
1958 req_payload.DestroyPayload();
1959 resp_payload.DestroyPayload();
1960 hwc_display_[display_id]->ResetValidation();
1961
1962 return ret;
1963 }
1964
UEventHandler(const char * uevent_data,int length)1965 void HWCSession::UEventHandler(const char *uevent_data, int length) {
1966 if (strcasestr(uevent_data, HWC_UEVENT_SWITCH_HDMI)) {
1967 DLOGI("Uevent HDMI = %s", uevent_data);
1968 int connected = GetEventValue(uevent_data, length, "SWITCH_STATE=");
1969 if (connected >= 0) {
1970 DLOGI("HDMI = %s", connected ? "connected" : "disconnected");
1971 if (HotPlugHandler(connected) == -1) {
1972 DLOGE("Failed handling Hotplug = %s", connected ? "connected" : "disconnected");
1973 }
1974 }
1975 } else if (strcasestr(uevent_data, HWC_UEVENT_GRAPHICS_FB0)) {
1976 DLOGI("Uevent FB0 = %s", uevent_data);
1977 int panel_reset = GetEventValue(uevent_data, length, "PANEL_ALIVE=");
1978 if (panel_reset == 0) {
1979 Refresh(0);
1980 reset_panel_ = true;
1981 }
1982 } else if (strcasestr(uevent_data, HWC_UEVENT_DRM_EXT_HOTPLUG)) {
1983 HandleExtHPD(uevent_data, length);
1984 }
1985 }
1986
GetTokenValue(const char * uevent_data,int length,const char * token)1987 const char *GetTokenValue(const char *uevent_data, int length, const char *token) {
1988 const char *iterator_str = uevent_data;
1989 const char *pstr = NULL;
1990 while (((iterator_str - uevent_data) <= length) && (*iterator_str)) {
1991 pstr = strstr(iterator_str, token);
1992 if (pstr) {
1993 break;
1994 }
1995 iterator_str += strlen(iterator_str) + 1;
1996 }
1997
1998 if (pstr)
1999 pstr = pstr+strlen(token);
2000
2001 return pstr;
2002 }
2003
HandleExtHPD(const char * uevent_data,int length)2004 void HWCSession::HandleExtHPD(const char *uevent_data, int length) {
2005 const char *pstr = GetTokenValue(uevent_data, length, "name=");
2006 if (!pstr || (strncmp(pstr, "DP-1", strlen("DP-1")) != 0)) {
2007 return;
2008 }
2009
2010 pstr = GetTokenValue(uevent_data, length, "status=");
2011 if (pstr) {
2012 bool connected = false;
2013 hpd_bpp_ = 0;
2014 hpd_pattern_ = 0;
2015 if (strncmp(pstr, "connected", strlen("connected")) == 0) {
2016 connected = true;
2017 }
2018 int bpp = GetEventValue(uevent_data, length, "bpp=");
2019 int pattern = GetEventValue(uevent_data, length, "pattern=");
2020 if (bpp >=0 && pattern >= 0) {
2021 hpd_bpp_ = bpp;
2022 hpd_pattern_ = pattern;
2023 }
2024
2025 DLOGI("Recived Ext HPD, connected:%d status=%s bpp = %d pattern =%d ",
2026 connected, pstr, hpd_bpp_, hpd_pattern_);
2027 HotPlugHandler(connected);
2028 }
2029 }
2030
GetEventValue(const char * uevent_data,int length,const char * event_info)2031 int HWCSession::GetEventValue(const char *uevent_data, int length, const char *event_info) {
2032 const char *iterator_str = uevent_data;
2033 while (((iterator_str - uevent_data) <= length) && (*iterator_str)) {
2034 const char *pstr = strstr(iterator_str, event_info);
2035 if (pstr != NULL) {
2036 return (atoi(iterator_str + strlen(event_info)));
2037 }
2038 iterator_str += strlen(iterator_str) + 1;
2039 }
2040
2041 return -1;
2042 }
2043
ResetPanel()2044 void HWCSession::ResetPanel() {
2045 HWC2::Error status;
2046
2047 DLOGI("Powering off primary");
2048 status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(HWC2::PowerMode::Off);
2049 if (status != HWC2::Error::None) {
2050 DLOGE("power-off on primary failed with error = %d", status);
2051 }
2052
2053 DLOGI("Restoring power mode on primary");
2054 HWC2::PowerMode mode = hwc_display_[HWC_DISPLAY_PRIMARY]->GetLastPowerMode();
2055 status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(mode);
2056 if (status != HWC2::Error::None) {
2057 DLOGE("Setting power mode = %d on primary failed with error = %d", mode, status);
2058 }
2059
2060 status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetVsyncEnabled(HWC2::Vsync::Enable);
2061 if (status != HWC2::Error::None) {
2062 DLOGE("enabling vsync failed for primary with error = %d", status);
2063 }
2064
2065 reset_panel_ = false;
2066 }
2067
HotPlugHandler(bool connected)2068 int HWCSession::HotPlugHandler(bool connected) {
2069 int status = 0;
2070 bool notify_hotplug = false;
2071
2072 // To prevent sending events to client while a lock is held, acquire scope locks only within
2073 // below scope so that those get automatically unlocked after the scope ends.
2074 do {
2075 // If HDMI is primary but not created yet (first time), create it and notify surfaceflinger.
2076 // if it is already created, but got disconnected/connected again,
2077 // just toggle display status and do not notify surfaceflinger.
2078 // If HDMI is not primary, create/destroy external display normally.
2079 if (hdmi_is_primary_) {
2080 SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
2081 if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
2082 status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetState(connected);
2083 } else {
2084 status = CreateExternalDisplay(HWC_DISPLAY_PRIMARY, 0, 0, false);
2085 notify_hotplug = true;
2086 }
2087
2088 break;
2089 }
2090
2091 {
2092 SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
2093 // Primary display must be connected for HDMI as secondary cases.
2094 if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
2095 DLOGE("Primary display is not connected.");
2096 return -1;
2097 }
2098
2099 hwc_display_[HWC_DISPLAY_PRIMARY]->ResetValidation();
2100 }
2101
2102 if (connected) {
2103 SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
2104 Locker::ScopeLock lock_v(locker_[HWC_DISPLAY_VIRTUAL]);
2105 // Connect external display if virtual display is not connected.
2106 // Else, defer external display connection and process it when virtual display
2107 // tears down; Do not notify SurfaceFlinger since connection is deferred now.
2108 if (!hwc_display_[HWC_DISPLAY_VIRTUAL]) {
2109 status = ConnectDisplay(HWC_DISPLAY_EXTERNAL);
2110 if (status) {
2111 return status;
2112 }
2113 notify_hotplug = true;
2114 } else {
2115 DLOGI("Virtual display is connected, pending connection");
2116 external_pending_connect_ = true;
2117 }
2118 } else {
2119 SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
2120 if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
2121 notify_hotplug = true;
2122 }
2123 external_pending_connect_ = false;
2124 }
2125 } while (0);
2126
2127 if (connected) {
2128 // In connect case, we send hotplug after we create display
2129 Refresh(0);
2130
2131 if (!hdmi_is_primary_) {
2132 // wait for sufficient time to ensure sufficient resources are available to process new
2133 // new display connection.
2134 uint32_t vsync_period = UINT32(GetVsyncPeriod(HWC_DISPLAY_PRIMARY));
2135 usleep(vsync_period * 2 / 1000);
2136 }
2137 if (notify_hotplug) {
2138 HotPlug(hdmi_is_primary_ ? HWC_DISPLAY_PRIMARY : HWC_DISPLAY_EXTERNAL,
2139 HWC2::Connection::Connected);
2140 }
2141 } else {
2142 // In disconnect case, we notify hotplug first to let the listener state update happen first
2143 // Then we can destroy the underlying display object
2144 if (notify_hotplug) {
2145 HotPlug(hdmi_is_primary_ ? HWC_DISPLAY_PRIMARY : HWC_DISPLAY_EXTERNAL,
2146 HWC2::Connection::Disconnected);
2147 }
2148 Refresh(0);
2149 if (!hdmi_is_primary_) {
2150 uint32_t vsync_period = UINT32(GetVsyncPeriod(HWC_DISPLAY_PRIMARY));
2151 usleep(vsync_period * 2 / 1000);
2152 }
2153 // Now disconnect the display
2154 {
2155 SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
2156 // Do not return error if external display is not in connected status.
2157 // Due to virtual display concurrency, external display connection might be still pending
2158 // but hdmi got disconnected before pending connection could be processed.
2159 if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
2160 status = DisconnectDisplay(HWC_DISPLAY_EXTERNAL);
2161 }
2162 }
2163 }
2164
2165 // notify client
2166
2167 qservice_->onHdmiHotplug(INT(connected));
2168
2169 return 0;
2170 }
2171
GetVsyncPeriod(int disp)2172 int HWCSession::GetVsyncPeriod(int disp) {
2173 SCOPE_LOCK(locker_[disp]);
2174 // default value
2175 int32_t vsync_period = 1000000000l / 60;
2176 auto attribute = HWC2::Attribute::VsyncPeriod;
2177
2178 if (hwc_display_[disp]) {
2179 hwc_display_[disp]->GetDisplayAttribute(0, attribute, &vsync_period);
2180 }
2181
2182 return vsync_period;
2183 }
2184
GetVisibleDisplayRect(const android::Parcel * input_parcel,android::Parcel * output_parcel)2185 android::status_t HWCSession::GetVisibleDisplayRect(const android::Parcel *input_parcel,
2186 android::Parcel *output_parcel) {
2187 int dpy = input_parcel->readInt32();
2188 if (dpy < HWC_DISPLAY_PRIMARY || dpy >= HWC_NUM_DISPLAY_TYPES) {
2189 return android::BAD_VALUE;
2190 }
2191
2192 SEQUENCE_WAIT_SCOPE_LOCK(locker_[dpy]);
2193 if (!hwc_display_[dpy]) {
2194 return android::NO_INIT;
2195 }
2196
2197 hwc_rect_t visible_rect = {0, 0, 0, 0};
2198 int error = hwc_display_[dpy]->GetVisibleDisplayRect(&visible_rect);
2199 if (error < 0) {
2200 return error;
2201 }
2202
2203 output_parcel->writeInt32(visible_rect.left);
2204 output_parcel->writeInt32(visible_rect.top);
2205 output_parcel->writeInt32(visible_rect.right);
2206 output_parcel->writeInt32(visible_rect.bottom);
2207
2208 return android::NO_ERROR;
2209 }
2210
Refresh(hwc2_display_t display)2211 void HWCSession::Refresh(hwc2_display_t display) {
2212 SCOPE_LOCK(callbacks_lock_);
2213 HWC2::Error err = callbacks_.Refresh(display);
2214 while (err != HWC2::Error::None) {
2215 callbacks_lock_.Wait();
2216 err = callbacks_.Refresh(display);
2217 }
2218 }
2219
HotPlug(hwc2_display_t display,HWC2::Connection state)2220 void HWCSession::HotPlug(hwc2_display_t display, HWC2::Connection state) {
2221 SCOPE_LOCK(callbacks_lock_);
2222 HWC2::Error err = callbacks_.Hotplug(display, state);
2223 while (err != HWC2::Error::None) {
2224 callbacks_lock_.Wait();
2225 err = callbacks_.Hotplug(display, state);
2226 }
2227 }
2228
CreateExternalDisplay(int disp_id,uint32_t primary_width,uint32_t primary_height,bool use_primary_res)2229 int HWCSession::CreateExternalDisplay(int disp_id, uint32_t primary_width,
2230 uint32_t primary_height, bool use_primary_res) {
2231 uint32_t panel_bpp = 0;
2232 uint32_t pattern_type = 0;
2233
2234 if (GetDriverType() == DriverType::FB) {
2235 qdutils::getDPTestConfig(&panel_bpp, &pattern_type);
2236 } else {
2237 panel_bpp = static_cast<uint32_t>(hpd_bpp_);
2238 pattern_type = static_cast<uint32_t>(hpd_pattern_);
2239 }
2240
2241 if (panel_bpp && pattern_type) {
2242 return HWCDisplayExternalTest::Create(core_intf_, &buffer_allocator_, &callbacks_,
2243 qservice_, panel_bpp, pattern_type,
2244 &hwc_display_[disp_id]);
2245 }
2246
2247 return HWCDisplayExternal::Create(core_intf_, &buffer_allocator_, &callbacks_,
2248 primary_width, primary_height, qservice_,
2249 use_primary_res, &hwc_display_[disp_id]);
2250 }
2251
ValidateDisplayInternal(hwc2_display_t display,uint32_t * out_num_types,uint32_t * out_num_requests)2252 HWC2::Error HWCSession::ValidateDisplayInternal(hwc2_display_t display, uint32_t *out_num_types,
2253 uint32_t *out_num_requests) {
2254 HWCDisplay *hwc_display = hwc_display_[display];
2255 if (hwc_display->IsInternalValidateState()) {
2256 // Internal Validation has already been done on display, get the Output params.
2257 return hwc_display->GetValidateDisplayOutput(out_num_types, out_num_requests);
2258 }
2259
2260 if (display == HWC_DISPLAY_PRIMARY) {
2261 // TODO(user): This can be moved to HWCDisplayPrimary
2262 if (reset_panel_) {
2263 DLOGW("panel is in bad state, resetting the panel");
2264 ResetPanel();
2265 }
2266
2267 if (need_invalidate_) {
2268 Refresh(display);
2269 need_invalidate_ = false;
2270 }
2271
2272 if (color_mgr_) {
2273 color_mgr_->SetColorModeDetailEnhancer(hwc_display_[display]);
2274 }
2275 }
2276
2277 return hwc_display->Validate(out_num_types, out_num_requests);
2278 }
2279
PresentDisplayInternal(hwc2_display_t display,int32_t * out_retire_fence)2280 HWC2::Error HWCSession::PresentDisplayInternal(hwc2_display_t display, int32_t *out_retire_fence) {
2281 HWCDisplay *hwc_display = hwc_display_[display];
2282 // If display is in Skip-Validate state and Validate cannot be skipped, do Internal
2283 // Validation to optimize for the frames which don't require the Client composition.
2284 if (hwc_display->IsSkipValidateState() && !hwc_display->CanSkipValidate()) {
2285 uint32_t out_num_types = 0, out_num_requests = 0;
2286 HWC2::Error error = ValidateDisplayInternal(display, &out_num_types, &out_num_requests);
2287 if ((error != HWC2::Error::None) || hwc_display->HasClientComposition()) {
2288 hwc_display->SetValidationState(HWCDisplay::kInternalValidate);
2289 return HWC2::Error::NotValidated;
2290 }
2291 }
2292
2293 return hwc_display->Present(out_retire_fence);
2294 }
2295
GetReadbackBufferAttributes(hwc2_device_t * device,hwc2_display_t display,int32_t * format,int32_t * dataspace)2296 int32_t HWCSession::GetReadbackBufferAttributes(hwc2_device_t *device, hwc2_display_t display,
2297 int32_t *format, int32_t *dataspace) {
2298 if (!device || !format || !dataspace) {
2299 return HWC2_ERROR_BAD_PARAMETER;
2300 }
2301
2302 if (display != HWC_DISPLAY_PRIMARY) {
2303 return HWC2_ERROR_BAD_DISPLAY;
2304 }
2305
2306 HWCSession *hwc_session = static_cast<HWCSession *>(device);
2307 HWCDisplay *hwc_display = hwc_session->hwc_display_[display];
2308
2309 if (hwc_display) {
2310 *format = HAL_PIXEL_FORMAT_RGB_888;
2311 *dataspace = GetDataspace(hwc_display->GetCurrentColorMode());
2312 return HWC2_ERROR_NONE;
2313 }
2314
2315 return HWC2_ERROR_BAD_DISPLAY;
2316 }
2317
SetReadbackBuffer(hwc2_device_t * device,hwc2_display_t display,const native_handle_t * buffer,int32_t acquire_fence)2318 int32_t HWCSession::SetReadbackBuffer(hwc2_device_t *device, hwc2_display_t display,
2319 const native_handle_t *buffer, int32_t acquire_fence) {
2320 if (!buffer) {
2321 return HWC2_ERROR_BAD_PARAMETER;
2322 }
2323
2324 if (display != HWC_DISPLAY_PRIMARY) {
2325 return HWC2_ERROR_BAD_DISPLAY;
2326 }
2327
2328 HWCSession *hwc_session = static_cast<HWCSession *>(device);
2329 if (hwc_session->hwc_display_[HWC_DISPLAY_EXTERNAL] ||
2330 hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL]) {
2331 return HWC2_ERROR_UNSUPPORTED;
2332 }
2333
2334 return CallDisplayFunction(device, display, &HWCDisplay::SetReadbackBuffer,
2335 buffer, acquire_fence, false);
2336 }
2337
GetReadbackBufferFence(hwc2_device_t * device,hwc2_display_t display,int32_t * release_fence)2338 int32_t HWCSession::GetReadbackBufferFence(hwc2_device_t *device, hwc2_display_t display,
2339 int32_t *release_fence) {
2340 if (!release_fence) {
2341 return HWC2_ERROR_BAD_PARAMETER;
2342 }
2343
2344 if (display != HWC_DISPLAY_PRIMARY) {
2345 return HWC2_ERROR_BAD_DISPLAY;
2346 }
2347
2348 return CallDisplayFunction(device, display, &HWCDisplay::GetReadbackBufferFence, release_fence);
2349 }
2350
SetIdlePC(const android::Parcel * input_parcel)2351 android::status_t HWCSession::SetIdlePC(const android::Parcel *input_parcel) {
2352 auto enable = input_parcel->readInt32();
2353 auto synchronous = input_parcel->readInt32();
2354
2355 #ifdef DISPLAY_CONFIG_1_3
2356 return static_cast<android::status_t>(controlIdlePowerCollapse(enable, synchronous));
2357 #else
2358 {
2359 SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
2360 if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
2361 DLOGE("Primary display is not ready");
2362 return -EINVAL;
2363 }
2364 auto error = hwc_display_[HWC_DISPLAY_PRIMARY]->ControlIdlePowerCollapse(enable, synchronous);
2365 if (error != HWC2::Error::None) {
2366 return -EINVAL;
2367 }
2368 if (!enable) {
2369 Refresh(HWC_DISPLAY_PRIMARY);
2370 int32_t error = locker_[HWC_DISPLAY_PRIMARY].WaitFinite(kCommitDoneTimeoutMs);
2371 if (error == ETIMEDOUT) {
2372 DLOGE("Timed out!! Next frame commit done event not received!!");
2373 return error;
2374 }
2375 }
2376 DLOGI("Idle PC %s!!", enable ? "enabled" : "disabled");
2377 }
2378 return 0;
2379 #endif
2380 }
2381
2382 } // namespace sdm
2383