1 /*
2  * Copyright (c) 2014-2020, 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 <QService.h>
35 #include <utils/utils.h>
36 #include <algorithm>
37 #include <utility>
38 #include <bitset>
39 #include <iterator>
40 #include <memory>
41 #include <string>
42 #include <thread>
43 #include <vector>
44 
45 #include "hwc_buffer_allocator.h"
46 #include "hwc_session.h"
47 #include "hwc_debugger.h"
48 
49 #define __CLASS__ "HWCSession"
50 
51 #define HWC_UEVENT_SWITCH_HDMI "change@/devices/virtual/switch/hdmi"
52 #define HWC_UEVENT_DRM_EXT_HOTPLUG "mdss_mdp/drm/card"
53 
54 static sdm::HWCSession::HWCModuleMethods g_hwc_module_methods;
55 
56 hwc_module_t HAL_MODULE_INFO_SYM = {
57   .common = {
58     .tag = HARDWARE_MODULE_TAG,
59     .version_major = 3,
60     .version_minor = 0,
61     .id = HWC_HARDWARE_MODULE_ID,
62     .name = "QTI Hardware Composer Module",
63     .author = "CodeAurora Forum",
64     .methods = &g_hwc_module_methods,
65     .dso = 0,
66     .reserved = {0},
67   }
68 };
69 
70 namespace sdm {
71 
72 static HWCUEvent g_hwc_uevent_;
73 Locker HWCSession::locker_[HWCCallbacks::kNumDisplays];
74 bool HWCSession::power_on_pending_[HWCCallbacks::kNumDisplays];
75 Locker HWCSession::power_state_[HWCCallbacks::kNumDisplays];
76 Locker HWCSession::display_config_locker_;
77 static const int kSolidFillDelay = 100 * 1000;
78 int HWCSession::null_display_mode_ = 0;
79 
80 // Map the known color modes to dataspace.
GetDataspaceFromColorMode(ColorMode mode)81 int32_t GetDataspaceFromColorMode(ColorMode mode) {
82   switch (mode) {
83     case ColorMode::SRGB:
84     case ColorMode::NATIVE:
85       return HAL_DATASPACE_V0_SRGB;
86     case ColorMode::DCI_P3:
87       return HAL_DATASPACE_DCI_P3;
88     case ColorMode::DISPLAY_P3:
89       return HAL_DATASPACE_DISPLAY_P3;
90     case ColorMode::BT2100_PQ:
91       return HAL_DATASPACE_BT2020_PQ;
92     case ColorMode::BT2100_HLG:
93       return HAL_DATASPACE_BT2020_HLG;
94     default:
95       return HAL_DATASPACE_UNKNOWN;
96   }
97 }
98 
UEventThread(HWCUEvent * hwc_uevent)99 void HWCUEvent::UEventThread(HWCUEvent *hwc_uevent) {
100   const char *uevent_thread_name = "HWC_UeventThread";
101 
102   prctl(PR_SET_NAME, uevent_thread_name, 0, 0, 0);
103   setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
104 
105   int status = uevent_init();
106   if (!status) {
107     std::unique_lock<std::mutex> caller_lock(hwc_uevent->mutex_);
108     hwc_uevent->caller_cv_.notify_one();
109     DLOGE("Failed to init uevent with err %d", status);
110     return;
111   }
112 
113   {
114     // Signal caller thread that worker thread is ready to listen to events.
115     std::unique_lock<std::mutex> caller_lock(hwc_uevent->mutex_);
116     hwc_uevent->init_done_ = true;
117     hwc_uevent->caller_cv_.notify_one();
118   }
119 
120   while (1) {
121     char uevent_data[PAGE_SIZE] = {};
122 
123     // keep last 2 zeros to ensure double 0 termination
124     int length = uevent_next_event(uevent_data, INT32(sizeof(uevent_data)) - 2);
125 
126     // scope of lock to this block only, so that caller is free to set event handler to nullptr;
127     {
128       std::lock_guard<std::mutex> guard(hwc_uevent->mutex_);
129       if (hwc_uevent->uevent_listener_) {
130         hwc_uevent->uevent_listener_->UEventHandler(uevent_data, length);
131       } else {
132         DLOGW("UEvent dropped. No uevent listener.");
133       }
134     }
135   }
136 }
137 
HWCUEvent()138 HWCUEvent::HWCUEvent() {
139   std::unique_lock<std::mutex> caller_lock(mutex_);
140   std::thread thread(HWCUEvent::UEventThread, this);
141   thread.detach();
142   caller_cv_.wait(caller_lock);
143 }
144 
Register(HWCUEventListener * uevent_listener)145 void HWCUEvent::Register(HWCUEventListener *uevent_listener) {
146   DLOGI("Set uevent listener = %p", uevent_listener);
147 
148   std::lock_guard<std::mutex> obj(mutex_);
149   uevent_listener_ = uevent_listener;
150 }
151 
HWCSession(const hw_module_t * module)152 HWCSession::HWCSession(const hw_module_t *module) {
153   hwc2_device_t::common.tag = HARDWARE_DEVICE_TAG;
154   hwc2_device_t::common.version = HWC_DEVICE_API_VERSION_2_0;
155   hwc2_device_t::common.module = const_cast<hw_module_t *>(module);
156   hwc2_device_t::common.close = Close;
157   hwc2_device_t::getCapabilities = GetCapabilities;
158   hwc2_device_t::getFunction = GetFunction;
159 }
160 
Init()161 int HWCSession::Init() {
162   SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
163 
164   int status = -EINVAL;
165   const char *qservice_name = "display.qservice";
166 
167   if (!g_hwc_uevent_.InitDone()) {
168     return status;
169   }
170 
171 
172 #if defined(DISPLAY_CONFIG_1_2) && defined(CONFIG_BASEID_FROM_PROP)
173   char indices[kPropertyMax];
174   uint32_t index_start, index_size;
175   if (Debug::Get()->GetProperty(BUILTIN_BASEID_AND_SIZE_PROP, indices) == kErrorNone) {
176     if (std::sscanf(indices, "%d,%d", &index_start, &index_size) == 2) {
177       setDisplayIndex(IDisplayConfig::DisplayTypeExt::DISPLAY_BUILTIN,
178                index_start, index_size);
179     }
180   }
181   if (Debug::Get()->GetProperty(PLUGGABLE_BASEID_AND_SIZE_PROP, indices) == kErrorNone) {
182     if (std::sscanf(indices, "%d,%d", &index_start, &index_size) == 2) {
183       setDisplayIndex(IDisplayConfig::DisplayTypeExt::DISPLAY_PLUGGABLE,
184                index_start, index_size);
185     }
186   }
187   if (Debug::Get()->GetProperty(VIRTUAL_BASEID_AND_SIZE_PROP, indices) == kErrorNone) {
188     if (std::sscanf(indices, "%d,%d", &index_start, &index_size) == 2) {
189       setDisplayIndex(IDisplayConfig::DisplayTypeExt::DISPLAY_VIRTUAL,
190                index_start, index_size);
191     }
192   }
193 #endif
194 
195   // Start QService and connect to it.
196   qService::QService::init();
197   android::sp<qService::IQService> iqservice = android::interface_cast<qService::IQService>(
198       android::defaultServiceManager()->getService(android::String16(qservice_name)));
199 
200   if (iqservice.get()) {
201     iqservice->connect(android::sp<qClient::IQClient>(this));
202     qservice_ = reinterpret_cast<qService::QService *>(iqservice.get());
203   } else {
204     DLOGE("Failed to acquire %s", qservice_name);
205     return -EINVAL;
206   }
207 
208   HWCDebugHandler::Get()->GetProperty(ENABLE_NULL_DISPLAY_PROP, &null_display_mode_);
209   HWCDebugHandler::Get()->GetProperty(DISABLE_HOTPLUG_BWCHECK, &disable_hotplug_bwcheck_);
210   HWCDebugHandler::Get()->GetProperty(DISABLE_MASK_LAYER_HINT, &disable_mask_layer_hint_);
211 
212   if (!null_display_mode_) {
213     g_hwc_uevent_.Register(this);
214   }
215 
216   int value = 0;
217   Debug::Get()->GetProperty(ENABLE_ASYNC_POWERMODE, &value);
218   async_powermode_ = (value == 1);
219   DLOGI("builtin_powermode_override: %d", async_powermode_);
220 
221   InitSupportedDisplaySlots();
222   // Create primary display here. Remaining builtin displays will be created after client has set
223   // display indexes which may happen sometime before callback is registered.
224   status = CreatePrimaryDisplay();
225   if (status) {
226     Deinit();
227     return status;
228   }
229 
230   is_composer_up_ = true;
231   StartServices();
232 
233   return 0;
234 }
235 
Deinit()236 int HWCSession::Deinit() {
237   // Destroy all connected displays
238   DestroyDisplay(&map_info_primary_);
239 
240   for (auto &map_info : map_info_builtin_) {
241     DestroyDisplay(&map_info);
242   }
243 
244   for (auto &map_info : map_info_pluggable_) {
245     DestroyDisplay(&map_info);
246   }
247 
248   for (auto &map_info : map_info_virtual_) {
249     DestroyDisplay(&map_info);
250   }
251 
252   if (color_mgr_) {
253     color_mgr_->DestroyColorManager();
254   }
255 
256   if (!null_display_mode_) {
257     g_hwc_uevent_.Register(nullptr);
258 
259     DisplayError error = CoreInterface::DestroyCore();
260     if (error != kErrorNone) {
261       DLOGE("Display core de-initialization failed. Error = %d", error);
262     }
263   }
264 
265   return 0;
266 }
267 
InitSupportedDisplaySlots()268 void HWCSession::InitSupportedDisplaySlots() {
269   // Default slots:
270   //    Primary = 0, External = 1
271   //    Additional external displays 2,3,...max_pluggable_count.
272   //    Additional builtin displays max_pluggable_count + 1, max_pluggable_count + 2,...
273   //    Last slots for virtual displays.
274   // Virtual display id is only for SF <--> HWC communication.
275   // It need not align with hwccomposer_defs
276 
277   map_info_primary_.client_id = qdutils::DISPLAY_PRIMARY;
278 
279   if (null_display_mode_) {
280     // Skip display slot initialization.
281     return;
282   }
283 
284   DisplayError error = CoreInterface::CreateCore(&buffer_allocator_, &buffer_sync_handler_,
285                                                  &socket_handler_, &core_intf_);
286   if (error != kErrorNone) {
287     DLOGE("Failed to create CoreInterface");
288     return;
289   }
290 
291   HWDisplayInterfaceInfo hw_disp_info = {};
292   error = core_intf_->GetFirstDisplayInterfaceType(&hw_disp_info);
293   if (error != kErrorNone) {
294     CoreInterface::DestroyCore();
295     DLOGE("Primary display type not recognized. Error = %d", error);
296     return;
297   }
298 
299   int max_builtin = 0;
300   int max_pluggable = 0;
301   int max_virtual = 0;
302 
303   error = core_intf_->GetMaxDisplaysSupported(kBuiltIn, &max_builtin);
304   if (error != kErrorNone) {
305     CoreInterface::DestroyCore();
306     DLOGE("Could not find maximum built-in displays supported. Error = %d", error);
307     return;
308   }
309 
310   error = core_intf_->GetMaxDisplaysSupported(kPluggable, &max_pluggable);
311   if (error != kErrorNone) {
312     CoreInterface::DestroyCore();
313     DLOGE("Could not find maximum pluggable displays supported. Error = %d", error);
314     return;
315   }
316 
317   error = core_intf_->GetMaxDisplaysSupported(kVirtual, &max_virtual);
318   if (error != kErrorNone) {
319     CoreInterface::DestroyCore();
320     DLOGE("Could not find maximum virtual displays supported. Error = %d", error);
321     return;
322   }
323 
324   if (kPluggable == hw_disp_info.type && max_pluggable != 0) {
325     // If primary is a pluggable display, we have already used one pluggable display interface.
326     max_pluggable--;
327   } else if (max_builtin != 0) {
328     max_builtin--;
329   }
330 
331   // Init slots in accordance to h/w capability.
332   uint32_t disp_count = UINT32(std::min(max_pluggable, HWCCallbacks::kNumPluggable));
333   hwc2_display_t base_id = qdutils::DISPLAY_EXTERNAL;
334   map_info_pluggable_.resize(disp_count);
335   for (auto &map_info : map_info_pluggable_) {
336     map_info.client_id = base_id++;
337   }
338 
339   disp_count = UINT32(std::min(max_builtin, HWCCallbacks::kNumBuiltIn));
340   map_info_builtin_.resize(disp_count);
341   for (auto &map_info : map_info_builtin_) {
342     map_info.client_id = base_id++;
343   }
344 
345   disp_count = UINT32(std::min(max_virtual, HWCCallbacks::kNumVirtual));
346   map_info_virtual_.resize(disp_count);
347   for (auto &map_info : map_info_virtual_) {
348     map_info.client_id = base_id++;
349   }
350 
351   // resize HDR supported map to total number of displays.
352   is_hdr_display_.resize(UINT32(base_id));
353 
354   if (!async_powermode_) {
355     return;
356   }
357 
358   int start_index = HWCCallbacks::kNumRealDisplays;
359   std::vector<DisplayMapInfo> map_info = {map_info_primary_};
360   std::copy(map_info_builtin_.begin(), map_info_builtin_.end(), std::back_inserter(map_info));
361   std::copy(map_info_pluggable_.begin(), map_info_pluggable_.end(), std::back_inserter(map_info));
362   for (auto &map : map_info) {
363     DLOGI("Display Pairs: map.client_id: %d, start_index: %d", map.client_id, start_index);
364     map_hwc_display_.insert(std::make_pair(map.client_id, start_index++));
365   }
366 }
367 
GetDisplayIndex(int dpy)368 int HWCSession::GetDisplayIndex(int dpy) {
369   DisplayMapInfo *map_info = nullptr;
370   switch (dpy) {
371     case qdutils::DISPLAY_PRIMARY:
372       map_info = &map_info_primary_;
373       break;
374     case qdutils::DISPLAY_EXTERNAL:
375       map_info = map_info_pluggable_.size() ? &map_info_pluggable_[0] : nullptr;
376       break;
377     case qdutils::DISPLAY_EXTERNAL_2:
378       map_info = (map_info_pluggable_.size() > 1) ? &map_info_pluggable_[1] : nullptr;
379       break;
380     case qdutils::DISPLAY_VIRTUAL:
381       map_info = map_info_virtual_.size() ? &map_info_virtual_[0] : nullptr;
382       break;
383     case qdutils::DISPLAY_BUILTIN_2:
384       map_info = map_info_builtin_.size() ? &map_info_builtin_[0] : nullptr;
385       break;
386     default:
387       DLOGW("Unknown display %d.", dpy);
388       break;
389   }
390 
391   if (!map_info) {
392     DLOGE("Display index not found for display %d.", dpy);
393     return -1;
394   }
395 
396   return INT(map_info->client_id);
397 }
398 
Open(const hw_module_t * module,const char * name,hw_device_t ** device)399 int HWCSession::Open(const hw_module_t *module, const char *name, hw_device_t **device) {
400   if (!module || !name || !device) {
401     DLOGE("Invalid parameters.");
402     return -EINVAL;
403   }
404 
405   if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
406     HWCSession *hwc_session = new HWCSession(module);
407     if (!hwc_session) {
408       return -ENOMEM;
409     }
410 
411     int status = hwc_session->Init();
412     if (status != 0) {
413       delete hwc_session;
414       hwc_session = NULL;
415       return status;
416     }
417 
418     hwc2_device_t *composer_device = hwc_session;
419     *device = reinterpret_cast<hw_device_t *>(composer_device);
420   }
421 
422   return 0;
423 }
424 
Close(hw_device_t * device)425 int HWCSession::Close(hw_device_t *device) {
426   if (!device) {
427     return -EINVAL;
428   }
429 
430   hwc2_device_t *composer_device = reinterpret_cast<hwc2_device_t *>(device);
431   HWCSession *hwc_session = static_cast<HWCSession *>(composer_device);
432 
433   hwc_session->Deinit();
434 
435   return 0;
436 }
437 
GetCapabilities(struct hwc2_device * device,uint32_t * outCount,int32_t * outCapabilities)438 void HWCSession::GetCapabilities(struct hwc2_device *device, uint32_t *outCount,
439                                  int32_t *outCapabilities) {
440   if (!outCount) {
441     return;
442   }
443 
444   int value = 0;
445   bool disable_skip_validate = false;
446   if (Debug::Get()->GetProperty(DISABLE_SKIP_VALIDATE_PROP, &value) == kErrorNone) {
447     disable_skip_validate = (value == 1);
448   }
449   uint32_t count = 1 + (disable_skip_validate ? 0 : 1);
450 
451   if (outCapabilities != nullptr && (*outCount >= count)) {
452     outCapabilities[0] = HWC2_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM;
453     if (!disable_skip_validate) {
454       outCapabilities[1] = HWC2_CAPABILITY_SKIP_VALIDATE;
455     }
456   }
457   *outCount = count;
458 }
459 
GetDisplayBrightnessSupport(hwc2_device_t * device,hwc2_display_t display,bool * out_support)460 int32_t HWCSession::GetDisplayBrightnessSupport(hwc2_device_t *device, hwc2_display_t display,
461                                                 bool *out_support) {
462   if (!device || (display >= HWCCallbacks::kNumDisplays)) {
463     return HWC2_ERROR_BAD_DISPLAY;
464   }
465 
466   if (!out_support) {
467     return HWC2_ERROR_BAD_PARAMETER;
468   }
469 
470   return CallDisplayFunction(device, display, &HWCDisplay::GetDisplayBrightnessSupport,
471                              out_support);
472 }
473 
474 template <typename PFN, typename T>
AsFP(T function)475 static hwc2_function_pointer_t AsFP(T function) {
476   static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer");
477   return reinterpret_cast<hwc2_function_pointer_t>(function);
478 }
479 
480 // HWC2 functions returned in GetFunction
481 // Defined in the same order as in the HWC2 header
482 
AcceptDisplayChanges(hwc2_device_t * device,hwc2_display_t display)483 int32_t HWCSession::AcceptDisplayChanges(hwc2_device_t *device, hwc2_display_t display) {
484   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::AcceptDisplayChanges);
485 }
486 
CreateLayer(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t * out_layer_id)487 int32_t HWCSession::CreateLayer(hwc2_device_t *device, hwc2_display_t display,
488                                 hwc2_layer_t *out_layer_id) {
489   if (!out_layer_id) {
490     return  HWC2_ERROR_BAD_PARAMETER;
491   }
492 
493   return CallDisplayFunction(device, display, &HWCDisplay::CreateLayer, out_layer_id);
494 }
495 
CreateVirtualDisplay(hwc2_device_t * device,uint32_t width,uint32_t height,int32_t * format,hwc2_display_t * out_display_id)496 int32_t HWCSession::CreateVirtualDisplay(hwc2_device_t *device, uint32_t width, uint32_t height,
497                                          int32_t *format, hwc2_display_t *out_display_id) {
498   // TODO(user): Handle concurrency with HDMI
499   if (!device) {
500     return HWC2_ERROR_BAD_DISPLAY;
501   }
502 
503   if (!out_display_id || !width || !height || !format) {
504     return  HWC2_ERROR_BAD_PARAMETER;
505   }
506 
507   HWCSession *hwc_session = static_cast<HWCSession *>(device);
508   auto status = hwc_session->CreateVirtualDisplayObj(width, height, format, out_display_id);
509   if (status == HWC2::Error::None) {
510     DLOGI("Created virtual display id:% " PRIu64 ", res: %dx%d", *out_display_id, width, height);
511   } else {
512     DLOGE("Failed to create virtual display: %s", to_string(status).c_str());
513   }
514   return INT32(status);
515 }
516 
DestroyLayer(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer)517 int32_t HWCSession::DestroyLayer(hwc2_device_t *device, hwc2_display_t display,
518                                  hwc2_layer_t layer) {
519   return CallDisplayFunction(device, display, &HWCDisplay::DestroyLayer, layer);
520 }
521 
DestroyVirtualDisplay(hwc2_device_t * device,hwc2_display_t display)522 int32_t HWCSession::DestroyVirtualDisplay(hwc2_device_t *device, hwc2_display_t display) {
523   if (!device || display >= HWCCallbacks::kNumDisplays) {
524     return HWC2_ERROR_BAD_DISPLAY;
525   }
526 
527   auto *hwc_session = static_cast<HWCSession *>(device);
528   hwc2_display_t active_builtin_disp_id = hwc_session->GetActiveBuiltinDisplay();
529 
530   if (active_builtin_disp_id < HWCCallbacks::kNumDisplays) {
531     Locker::ScopeLock lock_a(locker_[active_builtin_disp_id]);
532     std::bitset<kSecureMax> secure_sessions = 0;
533     hwc_session->hwc_display_[active_builtin_disp_id]->GetActiveSecureSession(&secure_sessions);
534     if (secure_sessions.any()) {
535       DLOGW("Secure session is active, defer destruction of virtual display id:%" PRIu64, display);
536       hwc_session->destroy_virtual_disp_pending_ = true;
537       return HWC2_ERROR_NONE;
538     }
539   }
540 
541   for (auto &map_info : hwc_session->map_info_virtual_) {
542     if (map_info.client_id == display) {
543       DLOGI("Destroying virtual display id:%" PRIu64, display);
544       hwc_session->DestroyDisplay(&map_info);
545       break;
546     }
547   }
548 
549   return HWC2_ERROR_NONE;
550 }
551 
Dump(hwc2_device_t * device,uint32_t * out_size,char * out_buffer)552 void HWCSession::Dump(hwc2_device_t *device, uint32_t *out_size, char *out_buffer) {
553   if (!device || !out_size) {
554     return;
555   }
556 
557   auto *hwc_session = static_cast<HWCSession *>(device);
558   const size_t max_dump_size = 8192;
559 
560   if (out_buffer == nullptr) {
561     *out_size = max_dump_size;
562   } else {
563     std::string s {};
564     for (int id = 0; id < HWCCallbacks::kNumRealDisplays; id++) {
565       SCOPE_LOCK(locker_[id]);
566       if (hwc_session->hwc_display_[id]) {
567         s += hwc_session->hwc_display_[id]->Dump();
568       }
569     }
570     auto copied = s.copy(out_buffer, std::min(s.size(), max_dump_size), 0);
571     *out_size = UINT32(copied);
572   }
573 }
574 
GetMaxVirtualDisplayCount(hwc2_device_t * device)575 uint32_t HWCSession::GetMaxVirtualDisplayCount(hwc2_device_t *device) {
576   if (device == nullptr) {
577     return HWC2_ERROR_BAD_PARAMETER;
578   }
579 
580   return 1;
581 }
582 
GetActiveConfig(hwc2_device_t * device,hwc2_display_t display,hwc2_config_t * out_config)583 static int32_t GetActiveConfig(hwc2_device_t *device, hwc2_display_t display,
584                                hwc2_config_t *out_config) {
585   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetActiveConfig, out_config);
586 }
587 
GetChangedCompositionTypes(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_elements,hwc2_layer_t * out_layers,int32_t * out_types)588 static int32_t GetChangedCompositionTypes(hwc2_device_t *device, hwc2_display_t display,
589                                           uint32_t *out_num_elements, hwc2_layer_t *out_layers,
590                                           int32_t *out_types) {
591   // null_ptr check only for out_num_elements, as out_layers and out_types can be null.
592   if (!out_num_elements) {
593     return  HWC2_ERROR_BAD_PARAMETER;
594   }
595   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetChangedCompositionTypes,
596                                          out_num_elements, out_layers, out_types);
597 }
598 
GetClientTargetSupport(hwc2_device_t * device,hwc2_display_t display,uint32_t width,uint32_t height,int32_t format,int32_t dataspace)599 static int32_t GetClientTargetSupport(hwc2_device_t *device, hwc2_display_t display, uint32_t width,
600                                       uint32_t height, int32_t format, int32_t dataspace) {
601   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetClientTargetSupport,
602                                          width, height, format, dataspace);
603 }
604 
GetColorModes(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_modes,int32_t * int_out_modes)605 static int32_t GetColorModes(hwc2_device_t *device, hwc2_display_t display, uint32_t *out_num_modes,
606                              int32_t /*ColorMode*/ *int_out_modes) {
607   auto out_modes = reinterpret_cast<ColorMode *>(int_out_modes);
608   if (out_num_modes == nullptr) {
609     return HWC2_ERROR_BAD_PARAMETER;
610   }
611   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetColorModes, out_num_modes,
612                                          out_modes);
613 }
614 
GetRenderIntents(hwc2_device_t * device,hwc2_display_t display,int32_t int_mode,uint32_t * out_num_intents,int32_t * int_out_intents)615 static int32_t GetRenderIntents(hwc2_device_t *device, hwc2_display_t display,
616                                 int32_t /*ColorMode*/ int_mode, uint32_t *out_num_intents,
617                                 int32_t /*RenderIntent*/ *int_out_intents) {
618   auto mode = static_cast<ColorMode>(int_mode);
619   auto out_intents = reinterpret_cast<RenderIntent *>(int_out_intents);
620   if (out_num_intents == nullptr) {
621     return HWC2_ERROR_BAD_PARAMETER;
622   }
623 
624   if (mode < ColorMode::NATIVE || mode > ColorMode::BT2100_HLG) {
625     DLOGE("Invalid ColorMode: %d", mode);
626     return HWC2_ERROR_BAD_PARAMETER;
627   }
628   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetRenderIntents, mode,
629                                          out_num_intents, out_intents);
630 }
631 
GetDataspaceSaturationMatrix(hwc2_device_t * device,int32_t int_dataspace,float * out_matrix)632 static int32_t GetDataspaceSaturationMatrix(hwc2_device_t *device,
633                                             int32_t /*Dataspace*/ int_dataspace,
634                                             float *out_matrix) {
635   auto dataspace = static_cast<Dataspace>(int_dataspace);
636   if (device == nullptr || out_matrix == nullptr || dataspace != Dataspace::SRGB_LINEAR) {
637     return HWC2_ERROR_BAD_PARAMETER;
638   }
639   // We only have the matrix for sRGB
640   float saturation_matrix[kDataspaceSaturationMatrixCount] = { 1.0, 0.0, 0.0, 0.0, \
641                                                                0.0, 1.0, 0.0, 0.0, \
642                                                                0.0, 0.0, 1.0, 0.0, \
643                                                                0.0, 0.0, 0.0, 1.0 };
644 
645   // TODO(user): This value should ideally be retrieved from a QDCM configuration file
646   char value[kPropertyMax] = {};
647   if (Debug::Get()->GetProperty(DATASPACE_SATURATION_MATRIX_PROP, value) != kErrorNone) {
648     DLOGW("Undefined saturation matrix");
649     return HWC2_ERROR_BAD_CONFIG;
650   }
651   std::string value_string(value);
652   std::size_t start = 0, end = 0;
653   int index = 0;
654   while ((end = value_string.find(",", start)) != std::string::npos) {
655     saturation_matrix[index] = std::stof(value_string.substr(start, end - start));
656     start = end + 1;
657     index++;
658     // We expect a 3x3, SF needs 4x4, keep the last row/column identity
659     if ((index + 1) % 4 == 0) {
660       index++;
661     }
662   }
663   saturation_matrix[index] = std::stof(value_string.substr(start, end - start));
664   if (index < kDataspaceSaturationPropertyElements - 1) {
665     // The property must have kDataspaceSaturationPropertyElements delimited by commas
666     DLOGW("Invalid saturation matrix defined");
667     return HWC2_ERROR_BAD_CONFIG;
668   }
669   for (int32_t i = 0; i < kDataspaceSaturationMatrixCount; i += 4) {
670     DLOGD("%f %f %f %f", saturation_matrix[i], saturation_matrix[i + 1], saturation_matrix[i + 2],
671           saturation_matrix[i + 3]);
672   }
673   for (uint32_t i = 0; i < kDataspaceSaturationMatrixCount; i++) {
674     out_matrix[i] = saturation_matrix[i];
675   }
676   return HWC2_ERROR_NONE;
677 }
678 
GetPerFrameMetadataKeys(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_keys,int32_t * int_out_keys)679 static int32_t GetPerFrameMetadataKeys(hwc2_device_t *device, hwc2_display_t display,
680                                        uint32_t *out_num_keys, int32_t *int_out_keys) {
681   auto out_keys = reinterpret_cast<PerFrameMetadataKey *>(int_out_keys);
682   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetPerFrameMetadataKeys,
683                                          out_num_keys, out_keys);
684 }
685 
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)686 static int32_t SetLayerPerFrameMetadata(hwc2_device_t *device, hwc2_display_t display,
687                                         hwc2_layer_t layer, uint32_t num_elements,
688                                         const int32_t *int_keys, const float *metadata) {
689   auto keys = reinterpret_cast<const PerFrameMetadataKey *>(int_keys);
690   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerPerFrameMetadata,
691                                        num_elements, keys, metadata);
692 }
693 
SetDisplayedContentSamplingEnabled(hwc2_device_t * device,hwc2_display_t display,int32_t enabled,uint8_t component_mask,uint64_t max_frames)694 static int32_t SetDisplayedContentSamplingEnabled(hwc2_device_t* device,
695                                                   hwc2_display_t display,
696                                                   int32_t enabled, uint8_t component_mask,
697                                                   uint64_t max_frames) {
698     static constexpr int32_t validComponentMask =
699         HWC2_FORMAT_COMPONENT_0 | HWC2_FORMAT_COMPONENT_1 |
700         HWC2_FORMAT_COMPONENT_2 | HWC2_FORMAT_COMPONENT_3;
701     if (component_mask & ~validComponentMask) return HWC2_ERROR_BAD_PARAMETER;
702     return HWCSession::CallDisplayFunction(device, display,
703                                            &HWCDisplay::SetDisplayedContentSamplingEnabled,
704                                            enabled, component_mask, max_frames);
705 }
706 
GetDisplayedContentSamplingAttributes(hwc2_device_t * device,hwc2_display_t display,int32_t * format,int32_t * dataspace,uint8_t * supported_components)707 static int32_t GetDisplayedContentSamplingAttributes(hwc2_device_t* device,
708                                                      hwc2_display_t display,
709                                                      int32_t* format,
710                                                      int32_t* dataspace,
711                                                      uint8_t* supported_components) {
712     return HWCSession::CallDisplayFunction(device, display,
713                                            &HWCDisplay::GetDisplayedContentSamplingAttributes,
714                                            format, dataspace, supported_components);
715 }
716 
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])717 static int32_t GetDisplayedContentSample(
718     hwc2_device_t* device, hwc2_display_t display, uint64_t max_frames, uint64_t timestamp,
719     uint64_t* numFrames,
720     int32_t samples_size[NUM_HISTOGRAM_COLOR_COMPONENTS],
721     uint64_t* samples[NUM_HISTOGRAM_COLOR_COMPONENTS]) {
722 
723     return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayedContentSample,
724                                     max_frames, timestamp, numFrames, samples_size, samples);
725 }
726 
SetLayerPerFrameMetadataBlobs(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,uint32_t num_elements,const int32_t * int_keys,const uint32_t * sizes,const uint8_t * metadata)727 static int32_t SetLayerPerFrameMetadataBlobs(hwc2_device_t *device, hwc2_display_t display,
728                                              hwc2_layer_t layer, uint32_t num_elements,
729                                              const int32_t *int_keys, const uint32_t *sizes,
730                                              const uint8_t *metadata) {
731   auto keys = reinterpret_cast<const PerFrameMetadataKey *>(int_keys);
732   return HWCSession::CallLayerFunction(device, display, layer,
733                                        &HWCLayer::SetLayerPerFrameMetadataBlobs,
734                                        num_elements, keys, sizes, metadata);
735 }
736 
GetDisplayAttribute(hwc2_device_t * device,hwc2_display_t display,hwc2_config_t config,int32_t int_attribute,int32_t * out_value)737 static int32_t GetDisplayAttribute(hwc2_device_t *device, hwc2_display_t display,
738                                    hwc2_config_t config, int32_t int_attribute,
739                                    int32_t *out_value) {
740   if (out_value == nullptr || int_attribute < HWC2_ATTRIBUTE_INVALID ||
741       int_attribute > HWC2_ATTRIBUTE_CONFIG_GROUP) {
742     return HWC2_ERROR_BAD_PARAMETER;
743   }
744   auto attribute = static_cast<HWC2::Attribute>(int_attribute);
745   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayAttribute, config,
746                                          attribute, out_value);
747 }
748 
GetDisplayConfigs(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_configs,hwc2_config_t * out_configs)749 static int32_t GetDisplayConfigs(hwc2_device_t *device, hwc2_display_t display,
750                                  uint32_t *out_num_configs, hwc2_config_t *out_configs) {
751   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayConfigs,
752                                          out_num_configs, out_configs);
753 }
754 
GetDisplayVsyncPeriod(hwc2_device_t * device,hwc2_display_t display,hwc2_vsync_period_t * out_vsync_period)755 static int32_t GetDisplayVsyncPeriod(hwc2_device_t *device, hwc2_display_t display,
756                                      hwc2_vsync_period_t *out_vsync_period) {
757   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayVsyncPeriod,
758                                          out_vsync_period);
759 }
760 
SetActiveConfigWithConstraints(hwc2_device_t * device,hwc2_display_t display,hwc2_config_t config,hwc_vsync_period_change_constraints_t * vsync_period_change_constraints,hwc_vsync_period_change_timeline_t * out_timeline)761 static int32_t SetActiveConfigWithConstraints(
762     hwc2_device_t *device, hwc2_display_t display, hwc2_config_t config,
763     hwc_vsync_period_change_constraints_t *vsync_period_change_constraints,
764     hwc_vsync_period_change_timeline_t *out_timeline) {
765   return HWCSession::CallDisplayFunction(device, display,
766                                          &HWCDisplay::SetActiveConfigWithConstraints, config,
767                                          vsync_period_change_constraints, out_timeline);
768 }
769 
GetDisplayName(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_size,char * out_name)770 static int32_t GetDisplayName(hwc2_device_t *device, hwc2_display_t display, uint32_t *out_size,
771                               char *out_name) {
772   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayName, out_size,
773                                          out_name);
774 }
775 
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)776 static int32_t GetDisplayRequests(hwc2_device_t *device, hwc2_display_t display,
777                                   int32_t *out_display_requests, uint32_t *out_num_elements,
778                                   hwc2_layer_t *out_layers, int32_t *out_layer_requests) {
779   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayRequests,
780                                          out_display_requests, out_num_elements, out_layers,
781                                          out_layer_requests);
782 }
783 
GetDisplayType(hwc2_device_t * device,hwc2_display_t display,int32_t * out_type)784 static int32_t GetDisplayType(hwc2_device_t *device, hwc2_display_t display, int32_t *out_type) {
785   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayType, out_type);
786 }
787 
788 
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)789 static int32_t GetHdrCapabilities(hwc2_device_t* device, hwc2_display_t display,
790                                   uint32_t* out_num_types, int32_t* out_types,
791                                   float* out_max_luminance, float* out_max_average_luminance,
792                                   float* out_min_luminance) {
793   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetHdrCapabilities,
794                                          out_num_types, out_types, out_max_luminance,
795                                          out_max_average_luminance, out_min_luminance);
796 }
797 
798 
GetReleaseFences(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_elements,hwc2_layer_t * out_layers,int32_t * out_fences)799 static int32_t GetReleaseFences(hwc2_device_t *device, hwc2_display_t display,
800                                 uint32_t *out_num_elements, hwc2_layer_t *out_layers,
801                                 int32_t *out_fences) {
802   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetReleaseFences,
803                                          out_num_elements, out_layers, out_fences);
804 }
805 
GetDisplayConnectionType(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_type)806 static int32_t GetDisplayConnectionType(hwc2_device_t *device, hwc2_display_t display,
807                                         uint32_t /*hwc2_display_connection_type_t*/ *out_type) {
808   if (!out_type) {
809     return HWC2_ERROR_BAD_PARAMETER;
810   }
811   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayConnectionType,
812                                          out_type);
813 }
814 
GetProtectedContentsSupport(hwc2_device_t * device,hwc2_display_t display,bool * out_support)815 int32_t GetProtectedContentsSupport(hwc2_device_t *device, hwc2_display_t display,
816                                     bool *out_support) {
817   if (!out_support) {
818     return HWC2_ERROR_BAD_PARAMETER;
819   }
820   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetProtectedContentsSupport,
821                                          out_support);
822 }
823 
GetAutoLowLatencyModeSupport(hwc2_device_t * device,hwc2_display_t display,bool * out_support)824 int32_t GetAutoLowLatencyModeSupport(hwc2_device_t *device, hwc2_display_t display,
825                                      bool *out_support) {
826   if (!out_support) {
827     return HWC2_ERROR_BAD_PARAMETER;
828   }
829   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetAutoLowLatencyModeSupport,
830                                          out_support);
831 }
832 
SetAutoLowLatencyMode(hwc2_device_t * device,hwc2_display_t display,bool on)833 static int32_t SetAutoLowLatencyMode(hwc2_device_t *device, hwc2_display_t display, bool on) {
834   if (!device || display >= HWCCallbacks::kNumDisplays) {
835     return HWC2_ERROR_BAD_DISPLAY;
836   }
837 
838   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetAutoLowLatencyMode, on);
839 }
840 
GetSupportedContentTypes(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_types,uint32_t * out_types)841 static int32_t GetSupportedContentTypes(hwc2_device_t *device, hwc2_display_t display,
842                                         uint32_t *out_num_types, uint32_t *out_types) {
843   if (!device || display >= HWCCallbacks::kNumDisplays) {
844     return HWC2_ERROR_BAD_DISPLAY;
845   }
846 
847   if (!out_num_types) {
848     return INT32(HWC2::Error::None);
849   }
850 
851   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetSupportedContentTypes,
852                                          out_num_types, out_types);
853 }
854 
SetContentType(hwc2_device_t * device,hwc2_display_t display,int32_t content_type)855 static int32_t SetContentType(hwc2_device_t *device, hwc2_display_t display,
856                               int32_t /* hwc2_content_type_t */ content_type) {
857   if (!device || display >= HWCCallbacks::kNumDisplays) {
858     return HWC2_ERROR_BAD_DISPLAY;
859   }
860 
861   if (content_type < HWC2_CONTENT_TYPE_NONE || content_type > HWC2_CONTENT_TYPE_GAME) {
862     return HWC2_ERROR_BAD_PARAMETER;
863   }
864 
865   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetContentType,
866                                          content_type);
867 }
868 
PresentDisplay(hwc2_device_t * device,hwc2_display_t display,int32_t * out_retire_fence)869 int32_t HWCSession::PresentDisplay(hwc2_device_t *device, hwc2_display_t display,
870                                    int32_t *out_retire_fence) {
871   HWCSession *hwc_session = static_cast<HWCSession *>(device);
872   auto status = HWC2::Error::BadDisplay;
873   DTRACE_SCOPED();
874 
875   if (!hwc_session || (display >= HWCCallbacks::kNumDisplays)) {
876     DLOGW("Invalid Display : hwc session = %s display = %" PRIu64,
877           hwc_session ? "Valid" : "NULL", display);
878     return HWC2_ERROR_BAD_DISPLAY;
879   }
880 
881   hwc_session->HandleSecureSession();
882   {
883     SCOPE_LOCK(power_state_[display]);
884     if (hwc_session->power_state_transition_[display]) {
885       // Route all interactions with client to dummy display.
886       display = hwc_session->map_hwc_display_.find(display)->second;
887     }
888   }
889 
890   {
891     SEQUENCE_EXIT_SCOPE_LOCK(locker_[display]);
892     if (!hwc_session->hwc_display_[display]) {
893       DLOGW("Removed Display : display = %" PRIu64, display);
894       return HWC2_ERROR_BAD_DISPLAY;
895     }
896 
897     if (out_retire_fence == nullptr) {
898       return HWC2_ERROR_BAD_PARAMETER;
899     }
900 
901     if (power_on_pending_[display]) {
902       status = HWC2::Error::None;
903     } else {
904       hwc_session->hwc_display_[display]->ProcessActiveConfigChange();
905       status = hwc_session->PresentDisplayInternal(display, out_retire_fence);
906       if (status == HWC2::Error::None) {
907         // Check if hwc's refresh trigger is getting exercised.
908         if (hwc_session->callbacks_.NeedsRefresh(display)) {
909           hwc_session->hwc_display_[display]->SetPendingRefresh();
910           hwc_session->callbacks_.ResetRefresh(display);
911         }
912         status = hwc_session->hwc_display_[display]->Present(out_retire_fence);
913       }
914     }
915   }
916 
917   if (status != HWC2::Error::None && status != HWC2::Error::NotValidated) {
918     SEQUENCE_CANCEL_SCOPE_LOCK(locker_[display]);
919   }
920 
921   hwc_session->HandlePowerOnPending(display, *out_retire_fence);
922   hwc_session->HandleHotplugPending(display, *out_retire_fence);
923   hwc_session->display_ready_.set(UINT32(display));
924   hwc_session->HandlePendingRefresh();
925 
926   return INT32(status);
927 }
928 
HandlePendingRefresh()929 void HWCSession::HandlePendingRefresh() {
930   if (pending_refresh_.none()) {
931     return;
932   }
933 
934   for (size_t i = 0; i < pending_refresh_.size(); i++) {
935     if (pending_refresh_.test(i)) {
936       Refresh(i);
937     }
938     break;
939   }
940 
941   pending_refresh_.reset();
942 }
943 
RegisterCallback(hwc2_device_t * device,int32_t descriptor,hwc2_callback_data_t callback_data,hwc2_function_pointer_t pointer)944 int32_t HWCSession::RegisterCallback(hwc2_device_t *device, int32_t descriptor,
945                                      hwc2_callback_data_t callback_data,
946                                      hwc2_function_pointer_t pointer) {
947   if (!device) {
948     return HWC2_ERROR_BAD_PARAMETER;
949   }
950   HWCSession *hwc_session = static_cast<HWCSession *>(device);
951   SCOPE_LOCK(hwc_session->callbacks_lock_);
952   auto desc = static_cast<HWC2::Callback>(descriptor);
953   auto error = hwc_session->callbacks_.Register(desc, callback_data, pointer);
954   if (error != HWC2::Error::None) {
955     return INT32(error);
956   }
957 
958   DLOGD("%s callback: %s", pointer ? "Registering" : "Deregistering", to_string(desc).c_str());
959   if (descriptor == HWC2_CALLBACK_HOTPLUG) {
960     if (hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY]) {
961       DLOGI("Hotplugging primary...");
962       hwc_session->callbacks_.Hotplug(HWC_DISPLAY_PRIMARY, HWC2::Connection::Connected);
963     }
964 
965     std::vector<hwc2_display_t> pending_hotplugs;
966     if (pointer) {
967       for (auto &map_info : hwc_session->map_info_builtin_) {
968         SCOPE_LOCK(locker_[map_info.client_id]);
969         if (hwc_session->hwc_display_[map_info.client_id]) {
970           pending_hotplugs.push_back(static_cast<hwc2_display_t>(map_info.client_id));
971         }
972       }
973       for (auto &map_info : hwc_session->map_info_pluggable_) {
974         SCOPE_LOCK(locker_[map_info.client_id]);
975         if (hwc_session->hwc_display_[map_info.client_id]) {
976           pending_hotplugs.push_back(static_cast<hwc2_display_t>(map_info.client_id));
977         }
978       }
979     }
980 
981     // Create displays since they should now have their final display indices set.
982     DLOGI("Handling built-in displays...");
983     if (hwc_session->HandleBuiltInDisplays()) {
984       DLOGW("Failed handling built-in displays.");
985     }
986     DLOGI("Handling pluggable displays...");
987     int32_t err = hwc_session->HandlePluggableDisplays(false);
988     if (err) {
989       DLOGW("All displays could not be created. Error %d '%s'. Hotplug handling %s.", err,
990             strerror(abs(err)), hwc_session->hotplug_pending_event_ == kHotPlugEvent ? "deferred" :
991             "dropped");
992     }
993 
994     // If previously registered, call hotplug for all connected displays to refresh
995     if (pointer) {
996       std::vector<hwc2_display_t> updated_pending_hotplugs;
997       for (auto client_id : pending_hotplugs) {
998         SCOPE_LOCK(locker_[client_id]);
999         // check if the display is unregistered
1000         if (hwc_session->hwc_display_[client_id]) {
1001           updated_pending_hotplugs.push_back(client_id);
1002         }
1003       }
1004       for (auto client_id : updated_pending_hotplugs) {
1005         DLOGI("Re-hotplug display connected: client id = %d", client_id);
1006         hwc_session->callbacks_.Hotplug(client_id, HWC2::Connection::Connected);
1007       }
1008     }
1009 
1010     hwc_session->client_connected_ = !!pointer;
1011     // Notfify all displays.
1012     hwc_session->NotifyClientStatus(hwc_session->client_connected_);
1013   }
1014   hwc_session->need_invalidate_ = false;
1015   hwc_session->callbacks_lock_.Broadcast();
1016   return HWC2_ERROR_NONE;
1017 }
1018 
SetActiveConfig(hwc2_device_t * device,hwc2_display_t display,hwc2_config_t config)1019 static int32_t SetActiveConfig(hwc2_device_t *device, hwc2_display_t display,
1020                                hwc2_config_t config) {
1021   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetActiveConfig, config);
1022 }
1023 
SetClientTarget(hwc2_device_t * device,hwc2_display_t display,buffer_handle_t target,int32_t acquire_fence,int32_t dataspace,hwc_region_t damage)1024 static int32_t SetClientTarget(hwc2_device_t *device, hwc2_display_t display,
1025                                buffer_handle_t target, int32_t acquire_fence,
1026                                int32_t dataspace, hwc_region_t damage) {
1027   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetClientTarget, target,
1028                                          acquire_fence, dataspace, damage);
1029 }
1030 
SetColorMode(hwc2_device_t * device,hwc2_display_t display,int32_t int_mode)1031 int32_t HWCSession::SetColorMode(hwc2_device_t *device, hwc2_display_t display,
1032                                  int32_t /*ColorMode*/ int_mode) {
1033   auto mode = static_cast<ColorMode>(int_mode);
1034   if (mode < ColorMode::NATIVE || mode > ColorMode::BT2100_HLG) {
1035     return HWC2_ERROR_BAD_PARAMETER;
1036   }
1037   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
1038 }
1039 
SetColorModeWithRenderIntent(hwc2_device_t * device,hwc2_display_t display,int32_t int_mode,int32_t int_render_intent)1040 int32_t HWCSession::SetColorModeWithRenderIntent(hwc2_device_t *device, hwc2_display_t display,
1041                                                  int32_t /*ColorMode*/ int_mode,
1042                                                  int32_t /*RenderIntent*/ int_render_intent) {
1043   auto mode = static_cast<ColorMode>(int_mode);
1044   if (mode < ColorMode::NATIVE || mode > ColorMode::BT2100_HLG) {
1045     return HWC2_ERROR_BAD_PARAMETER;
1046   }
1047   auto render_intent = static_cast<RenderIntent>(int_render_intent);
1048   if ((render_intent < RenderIntent::COLORIMETRIC) ||
1049       (render_intent > RenderIntent::TONE_MAP_ENHANCE)) {
1050     DLOGE("Invalid RenderIntent: %d", render_intent);
1051     return HWC2_ERROR_BAD_PARAMETER;
1052   }
1053   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorModeWithRenderIntent,
1054                                          mode, render_intent);
1055 }
1056 
SetColorTransform(hwc2_device_t * device,hwc2_display_t display,const float * matrix,int32_t hint)1057 int32_t HWCSession::SetColorTransform(hwc2_device_t *device, hwc2_display_t display,
1058                                       const float *matrix,
1059                                       int32_t /*android_color_transform_t*/ hint) {
1060   if (!matrix || hint < HAL_COLOR_TRANSFORM_IDENTITY ||
1061        hint > HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA) {
1062     return HWC2_ERROR_BAD_PARAMETER;
1063   }
1064   android_color_transform_t transform_hint = static_cast<android_color_transform_t>(hint);
1065   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorTransform, matrix,
1066                                          transform_hint);
1067 }
1068 
SetCursorPosition(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t x,int32_t y)1069 static int32_t SetCursorPosition(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
1070                                  int32_t x, int32_t y) {
1071   auto status = INT32(HWC2::Error::None);
1072   status = HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetCursorPosition,
1073                                            layer, x, y);
1074   if (status == INT32(HWC2::Error::None)) {
1075     // Update cursor position
1076     HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetCursorPosition, x, y);
1077   }
1078   return status;
1079 }
1080 
SetLayerBlendMode(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t int_mode)1081 static int32_t SetLayerBlendMode(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
1082                                  int32_t int_mode) {
1083   if (int_mode < HWC2_BLEND_MODE_INVALID || int_mode > HWC2_BLEND_MODE_COVERAGE) {
1084     return HWC2_ERROR_BAD_PARAMETER;
1085   }
1086   auto mode = static_cast<HWC2::BlendMode>(int_mode);
1087   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerBlendMode, mode);
1088 }
1089 
SetLayerBuffer(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,buffer_handle_t buffer,int32_t acquire_fence)1090 static int32_t SetLayerBuffer(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
1091                               buffer_handle_t buffer, int32_t acquire_fence) {
1092   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerBuffer, buffer,
1093                                        acquire_fence);
1094 }
1095 
SetLayerColor(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_color_t color)1096 static int32_t SetLayerColor(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
1097                              hwc_color_t color) {
1098   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerColor, color);
1099 }
1100 
SetLayerCompositionType(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t int_type)1101 static int32_t SetLayerCompositionType(hwc2_device_t *device, hwc2_display_t display,
1102                                        hwc2_layer_t layer, int32_t int_type) {
1103   auto type = static_cast<HWC2::Composition>(int_type);
1104   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerCompositionType,
1105                                        type);
1106 }
1107 
SetLayerDataspace(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t dataspace)1108 static int32_t SetLayerDataspace(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
1109                                  int32_t dataspace) {
1110   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerDataspace,
1111                                        dataspace);
1112 }
1113 
SetLayerDisplayFrame(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_rect_t frame)1114 static int32_t SetLayerDisplayFrame(hwc2_device_t *device, hwc2_display_t display,
1115                                     hwc2_layer_t layer, hwc_rect_t frame) {
1116   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerDisplayFrame,
1117                                        frame);
1118 }
1119 
SetLayerPlaneAlpha(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,float alpha)1120 static int32_t SetLayerPlaneAlpha(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
1121                                   float alpha) {
1122   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerPlaneAlpha,
1123                                        alpha);
1124 }
1125 
SetLayerSourceCrop(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_frect_t crop)1126 static int32_t SetLayerSourceCrop(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
1127                                   hwc_frect_t crop) {
1128   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerSourceCrop, crop);
1129 }
1130 
SetLayerSurfaceDamage(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_region_t damage)1131 static int32_t SetLayerSurfaceDamage(hwc2_device_t *device, hwc2_display_t display,
1132                                      hwc2_layer_t layer, hwc_region_t damage) {
1133   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerSurfaceDamage,
1134                                        damage);
1135 }
1136 
SetLayerTransform(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t int_transform)1137 static int32_t SetLayerTransform(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
1138                                  int32_t int_transform) {
1139   auto transform = static_cast<HWC2::Transform>(int_transform);
1140   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerTransform,
1141                                        transform);
1142 }
1143 
SetLayerVisibleRegion(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_region_t visible)1144 static int32_t SetLayerVisibleRegion(hwc2_device_t *device, hwc2_display_t display,
1145                                      hwc2_layer_t layer, hwc_region_t visible) {
1146   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerVisibleRegion,
1147                                        visible);
1148 }
1149 
SetLayerZOrder(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,uint32_t z)1150 static int32_t SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
1151                               uint32_t z) {
1152   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetLayerZOrder, layer, z);
1153 }
1154 
SetLayerColorTransform(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,const float * matrix)1155 static int32_t SetLayerColorTransform(hwc2_device_t *device, hwc2_display_t display,
1156                                       hwc2_layer_t layer, const float *matrix) {
1157   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerColorTransform,
1158                                        matrix);
1159 }
1160 
SetOutputBuffer(hwc2_device_t * device,hwc2_display_t display,buffer_handle_t buffer,int32_t releaseFence)1161 int32_t HWCSession::SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
1162                                     buffer_handle_t buffer, int32_t releaseFence) {
1163   if (!device) {
1164     return HWC2_ERROR_BAD_PARAMETER;
1165   }
1166 
1167   auto *hwc_session = static_cast<HWCSession *>(device);
1168   if (INT32(display) != hwc_session->GetDisplayIndex(qdutils::DISPLAY_VIRTUAL)) {
1169     return HWC2_ERROR_UNSUPPORTED;
1170   }
1171 
1172   SCOPE_LOCK(locker_[display]);
1173   if (hwc_session->hwc_display_[display]) {
1174     auto vds = reinterpret_cast<HWCDisplayVirtual *>(hwc_session->hwc_display_[display]);
1175     auto status = vds->SetOutputBuffer(buffer, releaseFence);
1176     return INT32(status);
1177   } else {
1178     return HWC2_ERROR_BAD_DISPLAY;
1179   }
1180 }
1181 
SetPowerMode(hwc2_device_t * device,hwc2_display_t display,int32_t int_mode)1182 int32_t HWCSession::SetPowerMode(hwc2_device_t *device, hwc2_display_t display, int32_t int_mode) {
1183   if (display >= HWCCallbacks::kNumDisplays) {
1184     return HWC2_ERROR_BAD_DISPLAY;
1185   }
1186 
1187   //  validate device and also avoid undefined behavior in cast to HWC2::PowerMode
1188   if (!device || int_mode < HWC2_POWER_MODE_OFF || int_mode > HWC2_POWER_MODE_DOZE_SUSPEND) {
1189     return HWC2_ERROR_BAD_PARAMETER;
1190   }
1191 
1192   HWCSession *hwc_session = static_cast<HWCSession *>(device);
1193   if (hwc_session->power_on_pending_[display]) {
1194     DLOGW("Set power mode is not allowed during secure display session");
1195     return HWC2_ERROR_UNSUPPORTED;
1196   }
1197 
1198   auto mode = static_cast<HWC2::PowerMode>(int_mode);
1199 
1200   //  all displays support on/off. Check for doze modes
1201   int support = 0;
1202   auto status = hwc_session->GetDozeSupport(device, display, &support);
1203   if (status != HWC2_ERROR_NONE) {
1204     DLOGE("Failed to get doze support Error = %d", status);
1205     return INT32(status);
1206   }
1207 
1208   if (!support && (mode == HWC2::PowerMode::Doze || mode == HWC2::PowerMode::DozeSuspend)) {
1209     return HWC2_ERROR_UNSUPPORTED;
1210   }
1211 
1212   bool override_mode = hwc_session->async_powermode_ &&
1213                        hwc_session->display_ready_.test(UINT32(display));
1214   if (!override_mode) {
1215     auto error = CallDisplayFunction(device, display, &HWCDisplay::SetPowerMode, mode,
1216                                    false /* teardown */);
1217     if (error != HWC2_ERROR_NONE) {
1218       return error;
1219     }
1220   } else {
1221     SCOPE_LOCK(locker_[display]);
1222     // Update hwc state for now. Actual poweron will handled through DisplayConfig.
1223     hwc_session->hwc_display_[display]->UpdatePowerMode(mode);
1224   }
1225   // Reset idle pc ref count on suspend, as we enable idle pc during suspend.
1226   if (mode == HWC2::PowerMode::Off) {
1227     hwc_session->idle_pc_ref_cnt_ = 0;
1228   }
1229 
1230   hwc_session->UpdateThrottlingRate();
1231 
1232   // Trigger refresh for doze mode to take effect.
1233   if (mode == HWC2::PowerMode::Doze) {
1234     hwc_session->Refresh(display);
1235     // Trigger one more refresh for PP features to take effect.
1236     hwc_session->pending_refresh_.set(UINT32(display));
1237   } else {
1238     // Reset the pending refresh bit
1239     hwc_session->pending_refresh_.reset(UINT32(display));
1240   }
1241 
1242   return HWC2_ERROR_NONE;
1243 }
1244 
SetVsyncEnabled(hwc2_device_t * device,hwc2_display_t display,int32_t int_enabled)1245 int32_t HWCSession::SetVsyncEnabled(hwc2_device_t *device, hwc2_display_t display,
1246                                     int32_t int_enabled) {
1247   //  avoid undefined behavior in cast to HWC2::Vsync
1248   if (int_enabled < HWC2_VSYNC_INVALID || int_enabled > HWC2_VSYNC_DISABLE) {
1249     return HWC2_ERROR_BAD_PARAMETER;
1250   }
1251 
1252   auto enabled = static_cast<HWC2::Vsync>(int_enabled);
1253 
1254   HWCSession *hwc_session = static_cast<HWCSession *>(device);
1255 
1256   if (int_enabled == HWC2_VSYNC_ENABLE) {
1257     hwc_session->callbacks_.UpdateVsyncSource(display);
1258   }
1259 
1260   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetVsyncEnabled, enabled);
1261 }
1262 
GetDozeSupport(hwc2_device_t * device,hwc2_display_t display,int32_t * out_support)1263 int32_t HWCSession::GetDozeSupport(hwc2_device_t *device, hwc2_display_t display,
1264                                    int32_t *out_support) {
1265   if (!device || !out_support) {
1266     return HWC2_ERROR_BAD_PARAMETER;
1267   }
1268 
1269   HWCSession *hwc_session = static_cast<HWCSession *>(device);
1270   HWCDisplay *hwc_display = hwc_session->hwc_display_[display];;
1271   if (display >= HWCCallbacks::kNumDisplays || (hwc_display == nullptr)) {
1272     DLOGE("Invalid Display %d Handle %s ", display, hwc_display ?
1273           "Valid" : "NULL");
1274     return HWC2_ERROR_BAD_DISPLAY;
1275   }
1276 
1277   *out_support = 0;
1278   if (hwc_display->GetDisplayClass() == DISPLAY_CLASS_BUILTIN) {
1279     *out_support = 1;
1280   }
1281 
1282   return HWC2_ERROR_NONE;
1283 }
1284 
ValidateDisplay(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_types,uint32_t * out_num_requests)1285 int32_t HWCSession::ValidateDisplay(hwc2_device_t *device, hwc2_display_t display,
1286                                     uint32_t *out_num_types, uint32_t *out_num_requests) {
1287   //  out_num_types and out_num_requests will be non-NULL
1288   if (!device) {
1289     return HWC2_ERROR_BAD_PARAMETER;
1290   }
1291 
1292   if (display >= HWCCallbacks::kNumDisplays) {
1293     return HWC2_ERROR_BAD_DISPLAY;
1294   }
1295 
1296   HWCSession *hwc_session = static_cast<HWCSession *>(device);
1297 
1298   {
1299     SCOPE_LOCK(power_state_[display]);
1300     if (hwc_session->power_state_transition_[display]) {
1301       // Route all interactions with client to dummy display.
1302       display = hwc_session->map_hwc_display_.find(display)->second;
1303     }
1304   }
1305   DTRACE_SCOPED();
1306   // TODO(user): Handle secure session, handle QDCM solid fill
1307   auto status = HWC2::Error::BadDisplay;
1308   hwc_session->HandleSecureSession();
1309   {
1310     SEQUENCE_ENTRY_SCOPE_LOCK(locker_[display]);
1311     if (power_on_pending_[display]) {
1312       status = HWC2::Error::None;
1313     } else if (hwc_session->hwc_display_[display]) {
1314       hwc_session->hwc_display_[display]->ProcessActiveConfigChange();
1315       hwc_session->hwc_display_[display]->SetFastPathComposition(false);
1316       status = hwc_session->ValidateDisplayInternal(display, out_num_types, out_num_requests);
1317     }
1318   }
1319 
1320   // Sequence locking currently begins on Validate, so cancel the sequence lock on failures
1321   if (status != HWC2::Error::None && status != HWC2::Error::HasChanges) {
1322     SEQUENCE_CANCEL_SCOPE_LOCK(locker_[display]);
1323   }
1324 
1325   return INT32(status);
1326 }
1327 
GetDisplayCapabilities(hwc2_device_t * device,hwc2_display_t display,uint32_t * outNumCapabilities,uint32_t * outCapabilities)1328 int32_t HWCSession::GetDisplayCapabilities(hwc2_device_t* device, hwc2_display_t display,
1329         uint32_t* outNumCapabilities, uint32_t* outCapabilities) {
1330   if (outNumCapabilities == nullptr) {
1331     return INT32(HWC2::Error::None);
1332   }
1333 
1334   bool brightness_support = false;
1335   auto status = GetDisplayBrightnessSupport(device, display, &brightness_support);
1336   if (status != HWC2_ERROR_NONE) {
1337     DLOGE("Failed to get display brightness support Error = %" PRId32 , status);
1338     return INT32(status);
1339   }
1340   int doze_support = 0;
1341   status = GetDozeSupport(device, display, &doze_support);
1342   if (status != HWC2_ERROR_NONE) {
1343     DLOGE("Failed to get doze support Error = %d", status);
1344     return INT32(status);
1345   }
1346 
1347   bool protected_contents_support = false;
1348   if (auto status = GetProtectedContentsSupport(device, display, &protected_contents_support);
1349       status != HWC2_ERROR_NONE) {
1350     DLOGE("Failed to get protected contents support Error = %d", status);
1351     return INT32(status);
1352   }
1353 
1354   bool auto_low_latency_mode_support = false;
1355   if (auto status = GetAutoLowLatencyModeSupport(device, display, &auto_low_latency_mode_support);
1356       status != HWC2_ERROR_NONE) {
1357     DLOGE("Failed to get auto low latency mode support Error = %d", status);
1358     return INT32(status);
1359   }
1360 
1361   uint32_t count = 1 + static_cast<uint32_t>(doze_support) + (brightness_support ? 1 : 0) +
1362                    (protected_contents_support ? 1 : 0) + (auto_low_latency_mode_support ? 1 : 0);
1363   int index = 0;
1364   if (outCapabilities != nullptr && (*outNumCapabilities >= count)) {
1365     outCapabilities[index++] =
1366         uint32_t(IComposerClient::DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM);
1367     if (doze_support == 1) {
1368       outCapabilities[index++] = uint32_t(IComposerClient::DisplayCapability::DOZE);
1369     }
1370     if (brightness_support) {
1371       outCapabilities[index++] = uint32_t(IComposerClient::DisplayCapability::BRIGHTNESS);
1372     }
1373     if (protected_contents_support) {
1374       outCapabilities[index++] = uint32_t(IComposerClient::DisplayCapability::PROTECTED_CONTENTS);
1375     }
1376     if (auto_low_latency_mode_support) {
1377       outCapabilities[index++] =
1378           uint32_t(IComposerClient::DisplayCapability::AUTO_LOW_LATENCY_MODE);
1379     }
1380   }
1381 
1382   *outNumCapabilities = count;
1383   return INT32(HWC2::Error::None);
1384 }
1385 
SetDisplayBrightness(hwc2_device_t * device,hwc2_display_t display,float brightness)1386 int32_t HWCSession::SetDisplayBrightness(hwc2_device_t *device, hwc2_display_t display,
1387                                          float brightness) {
1388   if (!device || (display >= HWCCallbacks::kNumDisplays)) {
1389     return HWC2_ERROR_BAD_DISPLAY;
1390   }
1391 
1392   if (brightness != -1.0f && (brightness < 0.0f || brightness > 1.0f)) {
1393     return HWC2_ERROR_BAD_PARAMETER;
1394   }
1395 
1396   auto *hwc_session = static_cast<HWCSession *>(device);
1397   if (!hwc_session->hwc_display_[display]) {
1398     return HWC2_ERROR_BAD_DISPLAY;
1399   }
1400 
1401   int32_t max_brightness_level = 0;
1402   auto err = INT32(hwc_session->hwc_display_[display]->GetPanelMaxBrightness(max_brightness_level));
1403   if (err) {
1404     return err;
1405   }
1406 
1407   int32_t level;
1408   if (brightness == -1.0f) {
1409     level = 0;
1410   } else {
1411     level = INT32(brightness * (max_brightness_level - 1) + 1);
1412   }
1413 
1414   DLOGI_IF(kTagDisplay, "Setting brightness to level %d (%f percent)", level, brightness);
1415 
1416   return INT32(hwc_session->hwc_display_[display]->SetPanelBrightness(level));
1417 }
1418 
GetFunction(struct hwc2_device * device,int32_t int_descriptor)1419 hwc2_function_pointer_t HWCSession::GetFunction(struct hwc2_device *device,
1420                                                 int32_t int_descriptor) {
1421   auto descriptor = static_cast<HWC2::FunctionDescriptor>(int_descriptor);
1422 
1423   switch (descriptor) {
1424     case HWC2::FunctionDescriptor::AcceptDisplayChanges:
1425       return AsFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(HWCSession::AcceptDisplayChanges);
1426     case HWC2::FunctionDescriptor::CreateLayer:
1427       return AsFP<HWC2_PFN_CREATE_LAYER>(CreateLayer);
1428     case HWC2::FunctionDescriptor::CreateVirtualDisplay:
1429       return AsFP<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(HWCSession::CreateVirtualDisplay);
1430     case HWC2::FunctionDescriptor::DestroyLayer:
1431       return AsFP<HWC2_PFN_DESTROY_LAYER>(DestroyLayer);
1432     case HWC2::FunctionDescriptor::DestroyVirtualDisplay:
1433       return AsFP<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(HWCSession::DestroyVirtualDisplay);
1434     case HWC2::FunctionDescriptor::Dump:
1435       return AsFP<HWC2_PFN_DUMP>(HWCSession::Dump);
1436     case HWC2::FunctionDescriptor::GetActiveConfig:
1437       return AsFP<HWC2_PFN_GET_ACTIVE_CONFIG>(GetActiveConfig);
1438     case HWC2::FunctionDescriptor::GetChangedCompositionTypes:
1439       return AsFP<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(GetChangedCompositionTypes);
1440     case HWC2::FunctionDescriptor::GetClientTargetSupport:
1441       return AsFP<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(GetClientTargetSupport);
1442     case HWC2::FunctionDescriptor::GetColorModes:
1443       return AsFP<HWC2_PFN_GET_COLOR_MODES>(GetColorModes);
1444     case HWC2::FunctionDescriptor::GetDisplayAttribute:
1445       return AsFP<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(GetDisplayAttribute);
1446     case HWC2::FunctionDescriptor::GetDisplayConfigs:
1447       return AsFP<HWC2_PFN_GET_DISPLAY_CONFIGS>(GetDisplayConfigs);
1448     case HWC2::FunctionDescriptor::GetDisplayName:
1449       return AsFP<HWC2_PFN_GET_DISPLAY_NAME>(GetDisplayName);
1450     case HWC2::FunctionDescriptor::GetDisplayRequests:
1451       return AsFP<HWC2_PFN_GET_DISPLAY_REQUESTS>(GetDisplayRequests);
1452     case HWC2::FunctionDescriptor::GetDisplayType:
1453       return AsFP<HWC2_PFN_GET_DISPLAY_TYPE>(GetDisplayType);
1454     case HWC2::FunctionDescriptor::GetHdrCapabilities:
1455       return AsFP<HWC2_PFN_GET_HDR_CAPABILITIES>(GetHdrCapabilities);
1456     case HWC2::FunctionDescriptor::GetDozeSupport:
1457       return AsFP<HWC2_PFN_GET_DOZE_SUPPORT>(GetDozeSupport);
1458     case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount:
1459       return AsFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(HWCSession::GetMaxVirtualDisplayCount);
1460     case HWC2::FunctionDescriptor::GetReleaseFences:
1461       return AsFP<HWC2_PFN_GET_RELEASE_FENCES>(GetReleaseFences);
1462     case HWC2::FunctionDescriptor::PresentDisplay:
1463       return AsFP<HWC2_PFN_PRESENT_DISPLAY>(PresentDisplay);
1464     case HWC2::FunctionDescriptor::RegisterCallback:
1465       return AsFP<HWC2_PFN_REGISTER_CALLBACK>(RegisterCallback);
1466     case HWC2::FunctionDescriptor::SetActiveConfig:
1467       return AsFP<HWC2_PFN_SET_ACTIVE_CONFIG>(SetActiveConfig);
1468     case HWC2::FunctionDescriptor::SetClientTarget:
1469       return AsFP<HWC2_PFN_SET_CLIENT_TARGET>(SetClientTarget);
1470     case HWC2::FunctionDescriptor::SetColorMode:
1471       return AsFP<HWC2_PFN_SET_COLOR_MODE>(SetColorMode);
1472     case HWC2::FunctionDescriptor::SetColorTransform:
1473       return AsFP<HWC2_PFN_SET_COLOR_TRANSFORM>(SetColorTransform);
1474     case HWC2::FunctionDescriptor::SetCursorPosition:
1475       return AsFP<HWC2_PFN_SET_CURSOR_POSITION>(SetCursorPosition);
1476     case HWC2::FunctionDescriptor::SetLayerBlendMode:
1477       return AsFP<HWC2_PFN_SET_LAYER_BLEND_MODE>(SetLayerBlendMode);
1478     case HWC2::FunctionDescriptor::SetLayerBuffer:
1479       return AsFP<HWC2_PFN_SET_LAYER_BUFFER>(SetLayerBuffer);
1480     case HWC2::FunctionDescriptor::SetLayerColor:
1481       return AsFP<HWC2_PFN_SET_LAYER_COLOR>(SetLayerColor);
1482     case HWC2::FunctionDescriptor::SetLayerCompositionType:
1483       return AsFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(SetLayerCompositionType);
1484     case HWC2::FunctionDescriptor::SetLayerDataspace:
1485       return AsFP<HWC2_PFN_SET_LAYER_DATASPACE>(SetLayerDataspace);
1486     case HWC2::FunctionDescriptor::SetLayerDisplayFrame:
1487       return AsFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(SetLayerDisplayFrame);
1488     case HWC2::FunctionDescriptor::SetLayerPlaneAlpha:
1489       return AsFP<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(SetLayerPlaneAlpha);
1490     // Sideband stream is not supported
1491     // case HWC2::FunctionDescriptor::SetLayerSidebandStream:
1492     case HWC2::FunctionDescriptor::SetLayerSourceCrop:
1493       return AsFP<HWC2_PFN_SET_LAYER_SOURCE_CROP>(SetLayerSourceCrop);
1494     case HWC2::FunctionDescriptor::SetLayerSurfaceDamage:
1495       return AsFP<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(SetLayerSurfaceDamage);
1496     case HWC2::FunctionDescriptor::SetLayerTransform:
1497       return AsFP<HWC2_PFN_SET_LAYER_TRANSFORM>(SetLayerTransform);
1498     case HWC2::FunctionDescriptor::SetLayerVisibleRegion:
1499       return AsFP<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(SetLayerVisibleRegion);
1500     case HWC2::FunctionDescriptor::SetLayerZOrder:
1501       return AsFP<HWC2_PFN_SET_LAYER_Z_ORDER>(SetLayerZOrder);
1502     case HWC2::FunctionDescriptor::SetLayerColorTransform:
1503       return AsFP<HWC2_PFN_SET_LAYER_COLOR_TRANSFORM>(SetLayerColorTransform);
1504     case HWC2::FunctionDescriptor::SetOutputBuffer:
1505       return AsFP<HWC2_PFN_SET_OUTPUT_BUFFER>(SetOutputBuffer);
1506     case HWC2::FunctionDescriptor::SetPowerMode:
1507       return AsFP<HWC2_PFN_SET_POWER_MODE>(SetPowerMode);
1508     case HWC2::FunctionDescriptor::SetVsyncEnabled:
1509       return AsFP<HWC2_PFN_SET_VSYNC_ENABLED>(SetVsyncEnabled);
1510     case HWC2::FunctionDescriptor::ValidateDisplay:
1511       return AsFP<HWC2_PFN_VALIDATE_DISPLAY>(HWCSession::ValidateDisplay);
1512     case HWC2::FunctionDescriptor::SetReadbackBuffer:
1513       return AsFP<HWC2_PFN_SET_READBACK_BUFFER>(HWCSession::SetReadbackBuffer);
1514     case HWC2::FunctionDescriptor::GetReadbackBufferAttributes:
1515       return AsFP<HWC2_PFN_GET_READBACK_BUFFER_ATTRIBUTES>(HWCSession::GetReadbackBufferAttributes);
1516     case HWC2::FunctionDescriptor::GetReadbackBufferFence:
1517       return AsFP<HWC2_PFN_GET_READBACK_BUFFER_FENCE>(HWCSession::GetReadbackBufferFence);
1518     case HWC2::FunctionDescriptor::GetRenderIntents:
1519       return AsFP<HWC2_PFN_GET_RENDER_INTENTS>(GetRenderIntents);
1520     case HWC2::FunctionDescriptor::SetColorModeWithRenderIntent:
1521       return AsFP<HWC2_PFN_SET_COLOR_MODE_WITH_RENDER_INTENT>
1522              (HWCSession::SetColorModeWithRenderIntent);
1523     case HWC2::FunctionDescriptor::GetDataspaceSaturationMatrix:
1524       return AsFP<HWC2_PFN_GET_DATASPACE_SATURATION_MATRIX>(GetDataspaceSaturationMatrix);
1525     case HWC2::FunctionDescriptor::GetPerFrameMetadataKeys:
1526       return AsFP<HWC2_PFN_GET_PER_FRAME_METADATA_KEYS>(GetPerFrameMetadataKeys);
1527     case HWC2::FunctionDescriptor::SetLayerPerFrameMetadata:
1528       return AsFP<HWC2_PFN_SET_LAYER_PER_FRAME_METADATA>(SetLayerPerFrameMetadata);
1529     case HWC2::FunctionDescriptor::GetDisplayCapabilities:
1530       return AsFP<HWC2_PFN_GET_DISPLAY_CAPABILITIES>(GetDisplayCapabilities);
1531     case HWC2::FunctionDescriptor::SetDisplayBrightness:
1532       return AsFP<HWC2_PFN_SET_DISPLAY_BRIGHTNESS>(SetDisplayBrightness);
1533     case HWC2::FunctionDescriptor::SetDisplayedContentSamplingEnabled:
1534       return AsFP<HWC2_PFN_SET_DISPLAYED_CONTENT_SAMPLING_ENABLED>(SetDisplayedContentSamplingEnabled);
1535     case HWC2::FunctionDescriptor::GetDisplayedContentSamplingAttributes:
1536       return AsFP<HWC2_PFN_GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES>(GetDisplayedContentSamplingAttributes);
1537     case HWC2::FunctionDescriptor::GetDisplayedContentSample:
1538       return AsFP<HWC2_PFN_GET_DISPLAYED_CONTENT_SAMPLE>(GetDisplayedContentSample);
1539     case HWC2::FunctionDescriptor::SetLayerPerFrameMetadataBlobs:
1540       return AsFP<HWC2_PFN_SET_LAYER_PER_FRAME_METADATA_BLOBS>(SetLayerPerFrameMetadataBlobs);
1541     case HWC2::FunctionDescriptor::GetDisplayIdentificationData:
1542       return AsFP<HWC2_PFN_GET_DISPLAY_IDENTIFICATION_DATA>
1543              (HWCSession::GetDisplayIdentificationData);
1544     case HWC2::FunctionDescriptor::GetDisplayBrightnessSupport:
1545       return AsFP<HWC2_PFN_GET_DISPLAY_BRIGHTNESS_SUPPORT>(HWCSession::GetDisplayBrightnessSupport);
1546     case HWC2::FunctionDescriptor::GetDisplayConnectionType:
1547       return AsFP<HWC2_PFN_GET_DISPLAY_CONNECTION_TYPE>(GetDisplayConnectionType);
1548     case HWC2::FunctionDescriptor::GetDisplayVsyncPeriod:
1549       return AsFP<HWC2_PFN_GET_DISPLAY_VSYNC_PERIOD>(GetDisplayVsyncPeriod);
1550     case HWC2::FunctionDescriptor::SetActiveConfigWithConstraints:
1551       return AsFP<HWC2_PFN_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS>(SetActiveConfigWithConstraints);
1552     case HWC2::FunctionDescriptor::SetAutoLowLatencyMode:
1553       return AsFP<HWC2_PFN_SET_AUTO_LOW_LATENCY_MODE>(SetAutoLowLatencyMode);
1554     case HWC2::FunctionDescriptor::GetSupportedContentTypes:
1555       return AsFP<HWC2_PFN_GET_SUPPORTED_CONTENT_TYPES>(GetSupportedContentTypes);
1556     case HWC2::FunctionDescriptor::SetContentType:
1557       return AsFP<HWC2_PFN_SET_CONTENT_TYPE>(SetContentType);
1558     default:
1559       DLOGD("Unknown/Unimplemented function descriptor: %d (%s)", int_descriptor,
1560             to_string(descriptor).c_str());
1561       return nullptr;
1562   }
1563   return nullptr;
1564 }
1565 
CreateVirtualDisplayObj(uint32_t width,uint32_t height,int32_t * format,hwc2_display_t * out_display_id)1566 HWC2::Error HWCSession::CreateVirtualDisplayObj(uint32_t width, uint32_t height, int32_t *format,
1567                                                 hwc2_display_t *out_display_id) {
1568   if (!client_connected_) {
1569     DLOGE("Client is not ready yet.");
1570     return HWC2::Error::BadDisplay;
1571   }
1572 
1573   hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
1574   if (active_builtin_disp_id < HWCCallbacks::kNumDisplays) {
1575     SEQUENCE_WAIT_SCOPE_LOCK(locker_[active_builtin_disp_id]);
1576     std::bitset<kSecureMax> secure_sessions = 0;
1577     if (hwc_display_[active_builtin_disp_id]) {
1578       hwc_display_[active_builtin_disp_id]->GetActiveSecureSession(&secure_sessions);
1579     }
1580     if (secure_sessions.any()) {
1581       DLOGE("Secure session is active, cannot create virtual display.");
1582       return HWC2::Error::Unsupported;
1583     } else if (IsPluggableDisplayConnected()) {
1584       DLOGE("External session is active, cannot create virtual display.");
1585       return HWC2::Error::Unsupported;
1586     }
1587   }
1588 
1589   if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
1590     DisplayError error = hwc_display_[HWC_DISPLAY_PRIMARY]->TeardownConcurrentWriteback();
1591     if (error) {
1592       return HWC2::Error::NoResources;
1593     }
1594   }
1595 
1596   HWDisplaysInfo hw_displays_info = {};
1597   DisplayError error = core_intf_->GetDisplaysStatus(&hw_displays_info);
1598   if (error != kErrorNone) {
1599     DLOGE("Failed to get connected display list. Error = %d", error);
1600     return HWC2::Error::BadDisplay;
1601   }
1602 
1603   // Lock confined to this scope
1604   int status = -EINVAL;
1605   for (auto &iter : hw_displays_info) {
1606     auto &info = iter.second;
1607     if (info.display_type != kVirtual) {
1608       continue;
1609     }
1610 
1611     for (auto &map_info : map_info_virtual_) {
1612       hwc2_display_t client_id = map_info.client_id;
1613       {
1614         SCOPE_LOCK(locker_[client_id]);
1615         auto &hwc_display = hwc_display_[client_id];
1616         if (hwc_display) {
1617           continue;
1618         }
1619 
1620         status = HWCDisplayVirtual::Create(core_intf_, &buffer_allocator_, &callbacks_, client_id,
1621                                            info.display_id, width, height, format, &hwc_display,
1622                                            set_min_lum_, set_max_lum_);
1623         // TODO(user): validate width and height support
1624         if (status) {
1625           return HWC2::Error::NoResources;
1626         }
1627 
1628         is_hdr_display_[UINT32(client_id)] = HasHDRSupport(hwc_display);
1629         DLOGI("Created virtual display id:% " PRIu64 " with res: %dx%d", client_id, width, height);
1630 
1631         *out_display_id = client_id;
1632         map_info.disp_type = info.display_type;
1633         map_info.sdm_id = info.display_id;
1634         break;
1635       }
1636     }
1637   }
1638 
1639   if (active_builtin_disp_id < HWCCallbacks::kNumDisplays) {
1640     SEQUENCE_WAIT_SCOPE_LOCK(locker_[active_builtin_disp_id]);
1641     hwc_display_[active_builtin_disp_id]->ResetValidation();
1642   }
1643 
1644   return HWC2::Error::None;
1645 }
1646 
IsPluggableDisplayConnected()1647 bool HWCSession::IsPluggableDisplayConnected() {
1648   for (auto &map_info : map_info_pluggable_) {
1649     if (hwc_display_[map_info.client_id]) {
1650       return true;
1651     }
1652   }
1653   return false;
1654 }
1655 
1656 // Qclient methods
notifyCallback(uint32_t command,const android::Parcel * input_parcel,android::Parcel * output_parcel)1657 android::status_t HWCSession::notifyCallback(uint32_t command, const android::Parcel *input_parcel,
1658                                              android::Parcel *output_parcel) {
1659   android::status_t status = -EINVAL;
1660 
1661   switch (command) {
1662     case qService::IQService::DYNAMIC_DEBUG:
1663       if (!input_parcel) {
1664         DLOGE("QService command = %d: input_parcel needed.", command);
1665         break;
1666       }
1667       status = 0;
1668       DynamicDebug(input_parcel);
1669       break;
1670 
1671     case qService::IQService::SCREEN_REFRESH:
1672       if (!input_parcel) {
1673         DLOGE("QService command = %d: input_parcel needed.", command);
1674         break;
1675       }
1676       status = RefreshScreen(input_parcel);
1677       break;
1678 
1679     case qService::IQService::SET_IDLE_TIMEOUT:
1680       if (!input_parcel) {
1681         DLOGE("QService command = %d: input_parcel needed.", command);
1682         break;
1683       }
1684       status = setIdleTimeout(UINT32(input_parcel->readInt32()));
1685       break;
1686 
1687     case qService::IQService::SET_FRAME_DUMP_CONFIG:
1688       if (!input_parcel) {
1689         DLOGE("QService command = %d: input_parcel needed.", command);
1690         break;
1691       }
1692       status = SetFrameDumpConfig(input_parcel);
1693       break;
1694 
1695     case qService::IQService::SET_MAX_PIPES_PER_MIXER:
1696       if (!input_parcel) {
1697         DLOGE("QService command = %d: input_parcel needed.", command);
1698         break;
1699       }
1700       status = SetMaxMixerStages(input_parcel);
1701       break;
1702 
1703     case qService::IQService::SET_DISPLAY_MODE:
1704       if (!input_parcel) {
1705         DLOGE("QService command = %d: input_parcel needed.", command);
1706         break;
1707       }
1708       status = SetDisplayMode(input_parcel);
1709       break;
1710 
1711     case qService::IQService::SET_SECONDARY_DISPLAY_STATUS: {
1712         if (!input_parcel || !output_parcel) {
1713           DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1714           break;
1715         }
1716         int disp_id = INT(input_parcel->readInt32());
1717         HWCDisplay::DisplayStatus disp_status =
1718               static_cast<HWCDisplay::DisplayStatus>(input_parcel->readInt32());
1719         status = SetSecondaryDisplayStatus(disp_id, disp_status);
1720         output_parcel->writeInt32(status);
1721       }
1722       break;
1723 
1724     case qService::IQService::CONFIGURE_DYN_REFRESH_RATE:
1725       if (!input_parcel) {
1726         DLOGE("QService command = %d: input_parcel needed.", command);
1727         break;
1728       }
1729       status = ConfigureRefreshRate(input_parcel);
1730       break;
1731 
1732     case qService::IQService::SET_VIEW_FRAME:
1733       status = 0;
1734       break;
1735 
1736     case qService::IQService::TOGGLE_SCREEN_UPDATES: {
1737         if (!input_parcel || !output_parcel) {
1738           DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1739           break;
1740         }
1741         int32_t input = input_parcel->readInt32();
1742         status = toggleScreenUpdate(input == 1);
1743         output_parcel->writeInt32(status);
1744       }
1745       break;
1746 
1747     case qService::IQService::QDCM_SVC_CMDS:
1748       if (!input_parcel || !output_parcel) {
1749         DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1750         break;
1751       }
1752       status = QdcmCMDHandler(input_parcel, output_parcel);
1753       break;
1754 
1755     case qService::IQService::MIN_HDCP_ENCRYPTION_LEVEL_CHANGED: {
1756         if (!input_parcel || !output_parcel) {
1757           DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1758           break;
1759         }
1760         int disp_id = input_parcel->readInt32();
1761         uint32_t min_enc_level = UINT32(input_parcel->readInt32());
1762         status = MinHdcpEncryptionLevelChanged(disp_id, min_enc_level);
1763         output_parcel->writeInt32(status);
1764       }
1765       break;
1766 
1767     case qService::IQService::CONTROL_PARTIAL_UPDATE: {
1768         if (!input_parcel || !output_parcel) {
1769           DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1770           break;
1771         }
1772         int disp_id = input_parcel->readInt32();
1773         uint32_t enable = UINT32(input_parcel->readInt32());
1774         status = ControlPartialUpdate(disp_id, enable == 1);
1775         output_parcel->writeInt32(status);
1776       }
1777       break;
1778 
1779     case qService::IQService::SET_ACTIVE_CONFIG: {
1780         if (!input_parcel) {
1781           DLOGE("QService command = %d: input_parcel needed.", command);
1782           break;
1783         }
1784         uint32_t config = UINT32(input_parcel->readInt32());
1785         int disp_id = input_parcel->readInt32();
1786         status = SetActiveConfigIndex(disp_id, config);
1787       }
1788       break;
1789 
1790     case qService::IQService::GET_ACTIVE_CONFIG: {
1791         if (!input_parcel || !output_parcel) {
1792           DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1793           break;
1794         }
1795         int disp_id = input_parcel->readInt32();
1796         uint32_t config = 0;
1797         status = GetActiveConfigIndex(disp_id, &config);
1798         output_parcel->writeInt32(INT(config));
1799       }
1800       break;
1801 
1802     case qService::IQService::GET_CONFIG_COUNT: {
1803         if (!input_parcel || !output_parcel) {
1804           DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1805           break;
1806         }
1807         int disp_id = input_parcel->readInt32();
1808         uint32_t count = 0;
1809         status = GetConfigCount(disp_id, &count);
1810         output_parcel->writeInt32(INT(count));
1811       }
1812       break;
1813 
1814     case qService::IQService::GET_DISPLAY_ATTRIBUTES_FOR_CONFIG:
1815       if (!input_parcel || !output_parcel) {
1816         DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1817         break;
1818       }
1819       status = GetDisplayAttributesForConfig(input_parcel, output_parcel);
1820       break;
1821 
1822     case qService::IQService::GET_PANEL_BRIGHTNESS: {
1823         if (!output_parcel) {
1824           DLOGE("QService command = %d: output_parcel needed.", command);
1825           break;
1826         }
1827         int32_t level = 0;
1828         status = GetPanelBrightness(level);
1829         output_parcel->writeInt32(level);
1830       }
1831       break;
1832 
1833     case qService::IQService::SET_PANEL_BRIGHTNESS: {
1834         if (!input_parcel || !output_parcel) {
1835           DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1836           break;
1837         }
1838         uint32_t level = UINT32(input_parcel->readInt32());
1839         status = setPanelBrightness(level);
1840         output_parcel->writeInt32(status);
1841       }
1842       break;
1843 
1844     case qService::IQService::GET_DISPLAY_VISIBLE_REGION:
1845       if (!input_parcel || !output_parcel) {
1846         DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1847         break;
1848       }
1849       status = GetVisibleDisplayRect(input_parcel, output_parcel);
1850       break;
1851 
1852     case qService::IQService::SET_CAMERA_STATUS: {
1853         if (!input_parcel) {
1854           DLOGE("QService command = %d: input_parcel needed.", command);
1855           break;
1856         }
1857         uint32_t camera_status = UINT32(input_parcel->readInt32());
1858         status = setCameraLaunchStatus(camera_status);
1859       }
1860       break;
1861 
1862     case qService::IQService::GET_BW_TRANSACTION_STATUS: {
1863         if (!output_parcel) {
1864           DLOGE("QService command = %d: output_parcel needed.", command);
1865           break;
1866         }
1867         bool state = true;
1868         status = DisplayBWTransactionPending(&state);
1869         output_parcel->writeInt32(state);
1870       }
1871       break;
1872 
1873     case qService::IQService::SET_LAYER_MIXER_RESOLUTION:
1874       if (!input_parcel) {
1875         DLOGE("QService command = %d: input_parcel needed.", command);
1876         break;
1877       }
1878       status = SetMixerResolution(input_parcel);
1879       break;
1880 
1881     case qService::IQService::SET_COLOR_MODE:
1882       if (!input_parcel) {
1883         DLOGE("QService command = %d: input_parcel needed.", command);
1884         break;
1885       }
1886       status = SetColorModeOverride(input_parcel);
1887       break;
1888 
1889     case qService::IQService::SET_COLOR_MODE_WITH_RENDER_INTENT:
1890       if (!input_parcel) {
1891         DLOGE("QService command = %d: input_parcel needed.", command);
1892         break;
1893       }
1894       status = SetColorModeWithRenderIntentOverride(input_parcel);
1895       break;
1896 
1897     case qService::IQService::SET_COLOR_MODE_BY_ID:
1898       if (!input_parcel) {
1899         DLOGE("QService command = %d: input_parcel needed.", command);
1900         break;
1901       }
1902       status = SetColorModeById(input_parcel);
1903       break;
1904 
1905     case qService::IQService::GET_COMPOSER_STATUS:
1906       if (!output_parcel) {
1907         DLOGE("QService command = %d: output_parcel needed.", command);
1908         break;
1909       }
1910       status = 0;
1911       output_parcel->writeInt32(getComposerStatus());
1912       break;
1913 
1914     case qService::IQService::SET_QSYNC_MODE:
1915       if (!input_parcel) {
1916         DLOGE("QService command = %d: input_parcel needed.", command);
1917         break;
1918       }
1919       status = SetQSyncMode(input_parcel);
1920       break;
1921 
1922     case qService::IQService::SET_COLOR_SAMPLING_ENABLED:
1923       if (!input_parcel) {
1924         DLOGE("QService command = %d: input_parcel needed.", command);
1925         break;
1926       }
1927       status = setColorSamplingEnabled(input_parcel);
1928       break;
1929 
1930     case qService::IQService::SET_IDLE_PC:
1931       if (!input_parcel) {
1932         DLOGE("QService command = %d: input_parcel needed.", command);
1933         break;
1934       }
1935       status = SetIdlePC(input_parcel);
1936       break;
1937 
1938     case qService::IQService::SET_DISPLAY_DEVICE_STATUS:
1939       if (!input_parcel) {
1940         DLOGE("QService command = %d: input_parcel needed.", command);
1941         break;
1942       }
1943       status = SetDisplayDeviceStatus(input_parcel);
1944       break;
1945 
1946     case qService::IQService::SET_DPPS_AD4_ROI_CONFIG:
1947       if (!input_parcel) {
1948         DLOGE("QService command = %d: input_parcel needed.", command);
1949         break;
1950       }
1951       status = SetAd4RoiConfig(input_parcel);
1952       break;
1953 
1954     case qService::IQService::SET_DSI_CLK:
1955       if (!input_parcel) {
1956         DLOGE("QService command = %d: input_parcel needed.", command);
1957         break;
1958       }
1959       status = SetDsiClk(input_parcel);
1960       break;
1961 
1962     case qService::IQService::GET_DSI_CLK:
1963       if (!input_parcel || !output_parcel) {
1964         DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1965         break;
1966       }
1967       status = GetDsiClk(input_parcel, output_parcel);
1968       break;
1969 
1970     case qService::IQService::GET_SUPPORTED_DSI_CLK:
1971       if (!input_parcel || !output_parcel) {
1972         DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
1973         break;
1974       }
1975       status = GetSupportedDsiClk(input_parcel, output_parcel);
1976       break;
1977 
1978     case qService::IQService::SET_PANEL_LUMINANCE:
1979       if (!input_parcel) {
1980         DLOGE("QService command = %d: input_parcel needed.", command);
1981         break;
1982       }
1983       status = SetPanelLuminanceAttributes(input_parcel);
1984       break;
1985 
1986     case qService::IQService::SET_COLOR_MODE_FROM_CLIENT:
1987       if (!input_parcel) {
1988         DLOGE("QService command = %d: input_parcel needed.", command);
1989         break;
1990       }
1991       status = SetColorModeFromClient(input_parcel);
1992       break;
1993 
1994     default:
1995       DLOGW("QService command = %d is not supported.", command);
1996       break;
1997   }
1998 
1999   return status;
2000 }
2001 
SetDisplayDeviceStatus(const android::Parcel * input_parcel)2002 android::status_t HWCSession::SetDisplayDeviceStatus(const android::Parcel* input_parcel) {
2003   int dpy = input_parcel->readInt32();
2004   int error = android::BAD_VALUE;
2005   auto disp_status = static_cast<HWCDisplay::DisplayStatus>(input_parcel->readInt32());
2006 
2007   int disp_idx = GetDisplayIndex(dpy);
2008   if (disp_idx == -1) {
2009     DLOGE("Invalid display = %d");
2010     return android::BAD_VALUE;
2011   }
2012 
2013   SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_idx]);
2014   if (hwc_display_[disp_idx]) {
2015     error = hwc_display_[disp_idx]->SetDisplayStatus(disp_status);
2016     if (error != android::OK)
2017       DLOGW("Set disply %d status to %d failed with error %d", dpy, disp_status, error);
2018   } else {
2019     DLOGW("No display %d active", dpy);
2020   }
2021 
2022   return error;
2023 }
2024 
getComposerStatus()2025 android::status_t HWCSession::getComposerStatus() {
2026   return is_composer_up_;
2027 }
2028 
GetDisplayAttributesForConfig(const android::Parcel * input_parcel,android::Parcel * output_parcel)2029 android::status_t HWCSession::GetDisplayAttributesForConfig(const android::Parcel *input_parcel,
2030                                                             android::Parcel *output_parcel) {
2031   int config = input_parcel->readInt32();
2032   int dpy = input_parcel->readInt32();
2033   int error = android::BAD_VALUE;
2034   DisplayConfigVariableInfo display_attributes;
2035 
2036   int disp_idx = GetDisplayIndex(dpy);
2037   if (disp_idx == -1 || config < 0) {
2038     DLOGE("Invalid display = %d, or config = %d", dpy, config);
2039     return android::BAD_VALUE;
2040   }
2041 
2042   SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_idx]);
2043   if (hwc_display_[disp_idx]) {
2044     error = hwc_display_[disp_idx]->GetDisplayAttributesForConfig(config, &display_attributes);
2045     if (error == 0) {
2046       output_parcel->writeInt32(INT(display_attributes.vsync_period_ns));
2047       output_parcel->writeInt32(INT(display_attributes.x_pixels));
2048       output_parcel->writeInt32(INT(display_attributes.y_pixels));
2049       output_parcel->writeFloat(display_attributes.x_dpi);
2050       output_parcel->writeFloat(display_attributes.y_dpi);
2051       output_parcel->writeInt32(0);  // Panel type, unsupported.
2052     }
2053   }
2054 
2055   return error;
2056 }
2057 
setColorSamplingEnabled(const android::Parcel * input_parcel)2058 android::status_t HWCSession::setColorSamplingEnabled(const android::Parcel* input_parcel)
2059 {
2060     int dpy = input_parcel->readInt32();
2061     int enabled_cmd = input_parcel->readInt32();
2062     if (dpy < HWC_DISPLAY_PRIMARY || dpy >= HWC_NUM_DISPLAY_TYPES ||
2063         enabled_cmd < 0 || enabled_cmd > 1) {
2064         return android::BAD_VALUE;
2065     }
2066 
2067     SEQUENCE_WAIT_SCOPE_LOCK(locker_[dpy]);
2068     if (!hwc_display_[dpy]) {
2069         DLOGW("No display id %i active to enable histogram event", dpy);
2070         return android::BAD_VALUE;
2071     }
2072 
2073     auto error = hwc_display_[dpy]->SetDisplayedContentSamplingEnabledVndService(enabled_cmd);
2074     return (error == HWC2::Error::None) ? android::OK : android::BAD_VALUE;
2075 }
2076 
ConfigureRefreshRate(const android::Parcel * input_parcel)2077 android::status_t HWCSession::ConfigureRefreshRate(const android::Parcel *input_parcel) {
2078   SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
2079 
2080   uint32_t operation = UINT32(input_parcel->readInt32());
2081   HWCDisplay *hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
2082 
2083   if (!hwc_display) {
2084     DLOGW("Display = %d is not connected.", HWC_DISPLAY_PRIMARY);
2085     return -ENODEV;
2086   }
2087 
2088   switch (operation) {
2089     case qdutils::DISABLE_METADATA_DYN_REFRESH_RATE:
2090       return hwc_display->Perform(HWCDisplayBuiltIn::SET_METADATA_DYN_REFRESH_RATE, false);
2091 
2092     case qdutils::ENABLE_METADATA_DYN_REFRESH_RATE:
2093       return hwc_display->Perform(HWCDisplayBuiltIn::SET_METADATA_DYN_REFRESH_RATE, true);
2094 
2095     case qdutils::SET_BINDER_DYN_REFRESH_RATE: {
2096       uint32_t refresh_rate = UINT32(input_parcel->readInt32());
2097       return hwc_display->Perform(HWCDisplayBuiltIn::SET_BINDER_DYN_REFRESH_RATE, refresh_rate);
2098     }
2099 
2100     default:
2101       DLOGW("Invalid operation %d", operation);
2102       return -EINVAL;
2103   }
2104 
2105   return 0;
2106 }
2107 
SetDisplayMode(const android::Parcel * input_parcel)2108 android::status_t HWCSession::SetDisplayMode(const android::Parcel *input_parcel) {
2109   SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
2110 
2111   if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
2112     DLOGW("Display = %d is not connected.", HWC_DISPLAY_PRIMARY);
2113     return -ENODEV;
2114   }
2115 
2116   uint32_t mode = UINT32(input_parcel->readInt32());
2117   return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(HWCDisplayBuiltIn::SET_DISPLAY_MODE, mode);
2118 }
2119 
SetMaxMixerStages(const android::Parcel * input_parcel)2120 android::status_t HWCSession::SetMaxMixerStages(const android::Parcel *input_parcel) {
2121   DisplayError error = kErrorNone;
2122   std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32());
2123   uint32_t max_mixer_stages = UINT32(input_parcel->readInt32());
2124   android::status_t status = 0;
2125 
2126   for (uint32_t i = 0; i < 32 && bit_mask_display_type[i]; i++) {
2127     int disp_idx = GetDisplayIndex(INT(i));
2128     if (disp_idx == -1) {
2129       continue;
2130     }
2131     SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_idx]);
2132     auto &hwc_display = hwc_display_[disp_idx];
2133     if (!hwc_display) {
2134       DLOGW("Display = %d is not connected.", disp_idx);
2135       status = (status)? status : -ENODEV;  // Return higher priority error.
2136       continue;
2137     }
2138 
2139     error = hwc_display->SetMaxMixerStages(max_mixer_stages);
2140     if (error != kErrorNone) {
2141       status = -EINVAL;
2142     }
2143   }
2144 
2145   return status;
2146 }
2147 
SetFrameDumpConfig(const android::Parcel * input_parcel)2148 android::status_t HWCSession::SetFrameDumpConfig(const android::Parcel *input_parcel) {
2149   uint32_t frame_dump_count = UINT32(input_parcel->readInt32());
2150   std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32());
2151   uint32_t bit_mask_layer_type = UINT32(input_parcel->readInt32());
2152   int32_t output_format = HAL_PIXEL_FORMAT_RGB_888;
2153   bool post_processed = true;
2154 
2155   // Read optional user preferences: output_format and post_processed.
2156   if (input_parcel->dataPosition() != input_parcel->dataSize()) {
2157     // HAL Pixel Format for output buffer
2158     output_format = input_parcel->readInt32();
2159   }
2160   if (input_parcel->dataPosition() != input_parcel->dataSize()) {
2161     // Option to dump Layer Mixer output (0) or DSPP output (1)
2162     post_processed = (input_parcel->readInt32() != 0);
2163   }
2164 
2165   android::status_t status = 0;
2166 
2167   for (uint32_t i = 0; i < bit_mask_display_type.size(); i++) {
2168     if (!bit_mask_display_type[i]) {
2169       continue;
2170     }
2171     int disp_idx = GetDisplayIndex(INT(i));
2172     if (disp_idx == -1) {
2173       continue;
2174     }
2175     SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_idx]);
2176     auto &hwc_display = hwc_display_[disp_idx];
2177     if (!hwc_display) {
2178       DLOGW("Display = %d is not connected.", disp_idx);
2179       status = (status)? status : -ENODEV;  // Return higher priority error.
2180       continue;
2181     }
2182 
2183     HWC2::Error error = hwc_display->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type,
2184                                                         output_format, post_processed);
2185     if (error != HWC2::Error::None) {
2186       status = (HWC2::Error::NoResources == error) ? -ENOMEM : -EINVAL;
2187     }
2188   }
2189 
2190   return status;
2191 }
2192 
SetMixerResolution(const android::Parcel * input_parcel)2193 android::status_t HWCSession::SetMixerResolution(const android::Parcel *input_parcel) {
2194   DisplayError error = kErrorNone;
2195   uint32_t dpy = UINT32(input_parcel->readInt32());
2196 
2197   if (dpy != HWC_DISPLAY_PRIMARY) {
2198     DLOGW("Resolution change not supported for this display = %d", dpy);
2199     return -EINVAL;
2200   }
2201 
2202   SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
2203   if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
2204     DLOGW("Primary display is not initialized");
2205     return -ENODEV;
2206   }
2207 
2208   uint32_t width = UINT32(input_parcel->readInt32());
2209   uint32_t height = UINT32(input_parcel->readInt32());
2210 
2211   error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetMixerResolution(width, height);
2212   if (error != kErrorNone) {
2213     return -EINVAL;
2214   }
2215 
2216   return 0;
2217 }
2218 
SetColorModeOverride(const android::Parcel * input_parcel)2219 android::status_t HWCSession::SetColorModeOverride(const android::Parcel *input_parcel) {
2220   int display = static_cast<int>(input_parcel->readInt32());
2221   auto mode = static_cast<ColorMode>(input_parcel->readInt32());
2222   auto device = static_cast<hwc2_device_t *>(this);
2223 
2224   int disp_idx = GetDisplayIndex(display);
2225   if (disp_idx == -1) {
2226     DLOGE("Invalid display = %d", display);
2227     return -EINVAL;
2228   }
2229 
2230   if (mode < ColorMode::NATIVE || mode > ColorMode::BT2100_HLG) {
2231     DLOGE("Invalid ColorMode: %d", mode);
2232     return HWC2_ERROR_BAD_PARAMETER;
2233   }
2234   auto err = CallDisplayFunction(device, static_cast<hwc2_display_t>(disp_idx),
2235                                  &HWCDisplay::SetColorMode, mode);
2236   if (err != HWC2_ERROR_NONE)
2237     return -EINVAL;
2238 
2239   return 0;
2240 }
2241 
SetAd4RoiConfig(const android::Parcel * input_parcel)2242 android::status_t HWCSession::SetAd4RoiConfig(const android::Parcel *input_parcel) {
2243   auto display_id = static_cast<uint32_t>(input_parcel->readInt32());
2244   auto h_s = static_cast<uint32_t>(input_parcel->readInt32());
2245   auto h_e = static_cast<uint32_t>(input_parcel->readInt32());
2246   auto v_s = static_cast<uint32_t>(input_parcel->readInt32());
2247   auto v_e = static_cast<uint32_t>(input_parcel->readInt32());
2248   auto f_in = static_cast<uint32_t>(input_parcel->readInt32());
2249   auto f_out = static_cast<uint32_t>(input_parcel->readInt32());
2250 
2251   return static_cast<android::status_t>(SetDisplayDppsAdROI(display_id, h_s, h_e, v_s,
2252                                                             v_e, f_in, f_out));
2253 }
2254 
SetColorModeWithRenderIntentOverride(const android::Parcel * input_parcel)2255 android::status_t HWCSession::SetColorModeWithRenderIntentOverride(
2256     const android::Parcel *input_parcel) {
2257   auto display = static_cast<hwc2_display_t>(input_parcel->readInt32());
2258   auto mode = static_cast<ColorMode>(input_parcel->readInt32());
2259   auto intent = static_cast<RenderIntent>(input_parcel->readInt32());
2260   auto device = static_cast<hwc2_device_t *>(this);
2261 
2262   if (mode < ColorMode::NATIVE || mode > ColorMode::BT2100_HLG) {
2263     DLOGE("Invalid ColorMode: %d", mode);
2264     return HWC2_ERROR_BAD_PARAMETER;
2265   }
2266 
2267   if (intent < RenderIntent::COLORIMETRIC || intent > RenderIntent::TONE_MAP_ENHANCE) {
2268     DLOGE("Invalid RenderIntent: %d", intent);
2269     return HWC2_ERROR_BAD_PARAMETER;
2270   }
2271 
2272   auto err =
2273       CallDisplayFunction(device, display, &HWCDisplay::SetColorModeWithRenderIntent, mode, intent);
2274   if (err != HWC2_ERROR_NONE)
2275     return -EINVAL;
2276 
2277   return 0;
2278 }
SetColorModeById(const android::Parcel * input_parcel)2279 android::status_t HWCSession::SetColorModeById(const android::Parcel *input_parcel) {
2280   int display = input_parcel->readInt32();
2281   auto mode = input_parcel->readInt32();
2282   auto device = static_cast<hwc2_device_t *>(this);
2283 
2284   int disp_idx = GetDisplayIndex(display);
2285   if (disp_idx == -1) {
2286     DLOGE("Invalid display = %d", display);
2287     return -EINVAL;
2288   }
2289 
2290   auto err = CallDisplayFunction(device, static_cast<hwc2_display_t>(disp_idx),
2291                                  &HWCDisplay::SetColorModeById, mode);
2292   if (err != HWC2_ERROR_NONE)
2293     return -EINVAL;
2294 
2295   return 0;
2296 }
2297 
SetColorModeFromClient(const android::Parcel * input_parcel)2298 android::status_t HWCSession::SetColorModeFromClient(const android::Parcel *input_parcel) {
2299   int display = input_parcel->readInt32();
2300   auto mode = input_parcel->readInt32();
2301   auto device = static_cast<hwc2_device_t *>(this);
2302 
2303   int disp_idx = GetDisplayIndex(display);
2304   if (disp_idx == -1) {
2305     DLOGE("Invalid display = %d", display);
2306     return -EINVAL;
2307   }
2308 
2309   auto err = CallDisplayFunction(device, static_cast<hwc2_display_t>(disp_idx),
2310                                  &HWCDisplay::SetColorModeFromClientApi, mode);
2311   if (err != HWC2_ERROR_NONE)
2312     return -EINVAL;
2313 
2314   Refresh(static_cast<hwc2_display_t>(disp_idx));
2315 
2316   return 0;
2317 }
2318 
RefreshScreen(const android::Parcel * input_parcel)2319 android::status_t HWCSession::RefreshScreen(const android::Parcel *input_parcel) {
2320   int display = input_parcel->readInt32();
2321 
2322   int disp_idx = GetDisplayIndex(display);
2323   if (disp_idx == -1) {
2324     DLOGE("Invalid display = %d", display);
2325     return -EINVAL;
2326   }
2327 
2328   Refresh(static_cast<hwc2_display_t>(disp_idx));
2329 
2330   return 0;
2331 }
2332 
DynamicDebug(const android::Parcel * input_parcel)2333 void HWCSession::DynamicDebug(const android::Parcel *input_parcel) {
2334   int type = input_parcel->readInt32();
2335   bool enable = (input_parcel->readInt32() > 0);
2336   DLOGI("type = %d enable = %d", type, enable);
2337   int verbose_level = input_parcel->readInt32();
2338 
2339   switch (type) {
2340     case qService::IQService::DEBUG_ALL:
2341       HWCDebugHandler::DebugAll(enable, verbose_level);
2342       break;
2343 
2344     case qService::IQService::DEBUG_MDPCOMP:
2345       HWCDebugHandler::DebugStrategy(enable, verbose_level);
2346       HWCDebugHandler::DebugCompManager(enable, verbose_level);
2347       break;
2348 
2349     case qService::IQService::DEBUG_PIPE_LIFECYCLE:
2350       HWCDebugHandler::DebugResources(enable, verbose_level);
2351       HWCDebugHandler::DebugQos(enable, verbose_level);
2352       break;
2353 
2354     case qService::IQService::DEBUG_DRIVER_CONFIG:
2355       HWCDebugHandler::DebugDriverConfig(enable, verbose_level);
2356       break;
2357 
2358     case qService::IQService::DEBUG_ROTATOR:
2359       HWCDebugHandler::DebugResources(enable, verbose_level);
2360       HWCDebugHandler::DebugDriverConfig(enable, verbose_level);
2361       HWCDebugHandler::DebugRotator(enable, verbose_level);
2362       HWCDebugHandler::DebugQos(enable, verbose_level);
2363       break;
2364 
2365     case qService::IQService::DEBUG_QDCM:
2366       HWCDebugHandler::DebugQdcm(enable, verbose_level);
2367       break;
2368 
2369     case qService::IQService::DEBUG_SCALAR:
2370       HWCDebugHandler::DebugScalar(enable, verbose_level);
2371       break;
2372 
2373     case qService::IQService::DEBUG_CLIENT:
2374       HWCDebugHandler::DebugClient(enable, verbose_level);
2375       break;
2376 
2377     case qService::IQService::DEBUG_DISPLAY:
2378       HWCDebugHandler::DebugDisplay(enable, verbose_level);
2379       break;
2380 
2381     default:
2382       DLOGW("type = %d is not supported", type);
2383   }
2384 }
2385 
QdcmCMDDispatch(uint32_t display_id,const PPDisplayAPIPayload & req_payload,PPDisplayAPIPayload * resp_payload,PPPendingParams * pending_action)2386 android::status_t HWCSession::QdcmCMDDispatch(uint32_t display_id,
2387                                               const PPDisplayAPIPayload &req_payload,
2388                                               PPDisplayAPIPayload *resp_payload,
2389                                               PPPendingParams *pending_action) {
2390   int ret = 0;
2391   bool is_physical_display = false;
2392 
2393   if (display_id >= HWCCallbacks::kNumDisplays || !hwc_display_[display_id]) {
2394       DLOGW("Invalid display id or display = %d is not connected.", display_id);
2395       return -ENODEV;
2396   }
2397 
2398   if (display_id == map_info_primary_.client_id) {
2399     is_physical_display = true;
2400   } else {
2401     for (auto &map_info : map_info_builtin_) {
2402       if (map_info.client_id == display_id) {
2403         is_physical_display = true;
2404         break;
2405      }
2406     }
2407   }
2408 
2409   if (!is_physical_display) {
2410     DLOGW("Skipping QDCM command dispatch on display = %d", display_id);
2411     return ret;
2412   }
2413 
2414   ret = hwc_display_[display_id]->ColorSVCRequestRoute(req_payload,
2415                                                        resp_payload,
2416                                                        pending_action);
2417 
2418   return ret;
2419 }
2420 
QdcmCMDHandler(const android::Parcel * input_parcel,android::Parcel * output_parcel)2421 android::status_t HWCSession::QdcmCMDHandler(const android::Parcel *input_parcel,
2422                                              android::Parcel *output_parcel) {
2423   int ret = 0;
2424   int32_t *brightness_value = NULL;
2425   uint32_t display_id(0);
2426   PPPendingParams pending_action;
2427   PPDisplayAPIPayload resp_payload, req_payload;
2428   uint8_t *disp_id = NULL;
2429   bool invalidate_needed = true;
2430   int32_t *mode_id = NULL;
2431 
2432   if (!color_mgr_) {
2433     DLOGW("color_mgr_ not initialized.");
2434     return -ENOENT;
2435   }
2436 
2437   pending_action.action = kNoAction;
2438   pending_action.params = NULL;
2439 
2440   // Read display_id, payload_size and payload from in_parcel.
2441   ret = HWCColorManager::CreatePayloadFromParcel(*input_parcel, &display_id, &req_payload);
2442   if (!ret) {
2443     ret = QdcmCMDDispatch(display_id, req_payload, &resp_payload, &pending_action);
2444   }
2445 
2446   if (ret) {
2447     output_parcel->writeInt32(ret);  // first field in out parcel indicates return code.
2448     req_payload.DestroyPayload();
2449     resp_payload.DestroyPayload();
2450     return ret;
2451   }
2452 
2453   if (kNoAction != pending_action.action) {
2454     int32_t action = pending_action.action;
2455     int count = -1;
2456     while (action > 0) {
2457       count++;
2458       int32_t bit = (action & 1);
2459       action = action >> 1;
2460 
2461       if (!bit)
2462         continue;
2463 
2464       DLOGV_IF(kTagQDCM, "pending action = %d, display_id = %d", BITMAP(count), display_id);
2465       switch (BITMAP(count)) {
2466         case kInvalidating:
2467           {
2468             invalidate_needed = false;
2469             Refresh(display_id);
2470           }
2471           break;
2472         case kEnterQDCMMode:
2473           ret = color_mgr_->EnableQDCMMode(true, hwc_display_[display_id]);
2474           break;
2475         case kExitQDCMMode:
2476           ret = color_mgr_->EnableQDCMMode(false, hwc_display_[display_id]);
2477           break;
2478         case kApplySolidFill:
2479           {
2480             SCOPE_LOCK(locker_[display_id]);
2481             ret = color_mgr_->SetSolidFill(pending_action.params,
2482                                            true, hwc_display_[display_id]);
2483           }
2484           Refresh(display_id);
2485           usleep(kSolidFillDelay);
2486           break;
2487         case kDisableSolidFill:
2488           {
2489             SCOPE_LOCK(locker_[display_id]);
2490             ret = color_mgr_->SetSolidFill(pending_action.params,
2491                                            false, hwc_display_[display_id]);
2492           }
2493           Refresh(display_id);
2494           usleep(kSolidFillDelay);
2495           break;
2496         case kSetPanelBrightness:
2497           brightness_value = reinterpret_cast<int32_t *>(resp_payload.payload);
2498           if (brightness_value == NULL) {
2499             DLOGE("Brightness value is Null");
2500             ret = -EINVAL;
2501           } else {
2502             ret = INT(hwc_display_[display_id]->SetPanelBrightness(*brightness_value));
2503           }
2504           break;
2505         case kEnableFrameCapture:
2506           ret = color_mgr_->SetFrameCapture(pending_action.params, true,
2507                                             hwc_display_[display_id]);
2508           Refresh(display_id);
2509           break;
2510         case kDisableFrameCapture:
2511           ret = color_mgr_->SetFrameCapture(pending_action.params, false,
2512                                             hwc_display_[display_id]);
2513           break;
2514         case kConfigureDetailedEnhancer:
2515           ret = color_mgr_->SetDetailedEnhancer(pending_action.params,
2516                                                 hwc_display_[display_id]);
2517           Refresh(display_id);
2518           break;
2519         case kModeSet:
2520           ret = static_cast<int>
2521                   (hwc_display_[display_id]->RestoreColorTransform());
2522           Refresh(display_id);
2523           break;
2524         case kNoAction:
2525           break;
2526         case kMultiDispProc:
2527           for (auto &map_info : map_info_builtin_) {
2528             uint32_t id = UINT32(map_info.client_id);
2529             if (id < HWCCallbacks::kNumDisplays && hwc_display_[id]) {
2530               int result = 0;
2531               resp_payload.DestroyPayload();
2532               result = hwc_display_[id]->ColorSVCRequestRoute(req_payload,
2533                                                               &resp_payload,
2534                                                               &pending_action);
2535               if (result) {
2536                 DLOGW("Failed to dispatch action to disp %d ret %d", id, result);
2537                 ret = result;
2538               }
2539             }
2540           }
2541           break;
2542         case kMultiDispGetId:
2543           ret = resp_payload.CreatePayloadBytes(HWCCallbacks::kNumDisplays, &disp_id);
2544           if (ret) {
2545             DLOGW("Unable to create response payload!");
2546           } else {
2547             for (int i = 0; i < HWCCallbacks::kNumDisplays; i++) {
2548               disp_id[i] = HWCCallbacks::kNumDisplays;
2549             }
2550             if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
2551               disp_id[HWC_DISPLAY_PRIMARY] = HWC_DISPLAY_PRIMARY;
2552             }
2553             for (auto &map_info : map_info_builtin_) {
2554               uint64_t id = map_info.client_id;
2555               if (id < HWCCallbacks::kNumDisplays && hwc_display_[id]) {
2556                 disp_id[id] = (uint8_t)id;
2557               }
2558             }
2559           }
2560           break;
2561         case kSetModeFromClient:
2562           {
2563             SCOPE_LOCK(locker_[display_id]);
2564             mode_id = reinterpret_cast<int32_t *>(resp_payload.payload);
2565             if (mode_id) {
2566               ret = static_cast<int>(hwc_display_[display_id]->SetColorModeFromClientApi(*mode_id));
2567             } else {
2568               DLOGE("mode_id is Null");
2569               ret = -EINVAL;
2570             }
2571           }
2572           if (!ret) {
2573             Refresh(display_id);
2574           }
2575           break;
2576         default:
2577           DLOGW("Invalid pending action = %d!", pending_action.action);
2578           break;
2579       }
2580     }
2581   }
2582   // for display API getter case, marshall returned params into out_parcel.
2583   output_parcel->writeInt32(ret);
2584   HWCColorManager::MarshallStructIntoParcel(resp_payload, output_parcel);
2585   req_payload.DestroyPayload();
2586   resp_payload.DestroyPayload();
2587 
2588   SEQUENCE_WAIT_SCOPE_LOCK(locker_[display_id]);
2589   if (invalidate_needed) {
2590     hwc_display_[display_id]->ResetValidation();
2591   }
2592 
2593   return ret;
2594 }
2595 
GetEventValue(const char * uevent_data,int length,const char * event_info)2596 int GetEventValue(const char *uevent_data, int length, const char *event_info) {
2597   const char *iterator_str = uevent_data;
2598   while (((iterator_str - uevent_data) <= length) && (*iterator_str)) {
2599     const char *pstr = strstr(iterator_str, event_info);
2600     if (pstr != NULL) {
2601       return (atoi(iterator_str + strlen(event_info)));
2602     }
2603     iterator_str += strlen(iterator_str) + 1;
2604   }
2605 
2606   return -1;
2607 }
2608 
GetTokenValue(const char * uevent_data,int length,const char * token)2609 const char *GetTokenValue(const char *uevent_data, int length, const char *token) {
2610   const char *iterator_str = uevent_data;
2611   const char *pstr = NULL;
2612   while (((iterator_str - uevent_data) <= length) && (*iterator_str)) {
2613     pstr = strstr(iterator_str, token);
2614     if (pstr) {
2615       break;
2616     }
2617     iterator_str += strlen(iterator_str) + 1;
2618   }
2619 
2620   if (pstr)
2621     pstr = pstr+strlen(token);
2622 
2623   return pstr;
2624 }
2625 
SetDsiClk(const android::Parcel * input_parcel)2626 android::status_t HWCSession::SetDsiClk(const android::Parcel *input_parcel) {
2627   int disp_id = input_parcel->readInt32();
2628   uint64_t clk = UINT64(input_parcel->readInt64());
2629   if (disp_id < 0) {
2630     return -EINVAL;
2631   }
2632 
2633   SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
2634   if (!hwc_display_[disp_id]) {
2635     return -EINVAL;
2636   }
2637 
2638   return hwc_display_[disp_id]->SetDynamicDSIClock(clk);
2639 }
2640 
GetDsiClk(const android::Parcel * input_parcel,android::Parcel * output_parcel)2641 android::status_t HWCSession::GetDsiClk(const android::Parcel *input_parcel,
2642                                         android::Parcel *output_parcel) {
2643   int disp_id = input_parcel->readInt32();
2644   if (disp_id < 0) {
2645     return -EINVAL;
2646   }
2647 
2648   SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
2649   if (!hwc_display_[disp_id]) {
2650     return -EINVAL;
2651   }
2652 
2653   uint64_t bitrate = 0;
2654   hwc_display_[disp_id]->GetDynamicDSIClock(&bitrate);
2655   output_parcel->writeUint64(bitrate);
2656 
2657   return 0;
2658 }
2659 
GetSupportedDsiClk(const android::Parcel * input_parcel,android::Parcel * output_parcel)2660 android::status_t HWCSession::GetSupportedDsiClk(const android::Parcel *input_parcel,
2661                                                  android::Parcel *output_parcel) {
2662   int disp_id = input_parcel->readInt32();
2663   if (disp_id < 0) {
2664     return -EINVAL;
2665   }
2666 
2667   SCOPE_LOCK(locker_[disp_id]);
2668   if (!hwc_display_[disp_id]) {
2669     return -EINVAL;
2670   }
2671 
2672   std::vector<uint64_t> bit_rates;
2673   hwc_display_[disp_id]->GetSupportedDSIClock(&bit_rates);
2674   output_parcel->writeInt32(INT32(bit_rates.size()));
2675   for (auto &bit_rate : bit_rates) {
2676     output_parcel->writeUint64(bit_rate);
2677   }
2678 
2679   return 0;
2680 }
2681 
SetPanelLuminanceAttributes(const android::Parcel * input_parcel)2682 android::status_t HWCSession::SetPanelLuminanceAttributes(const android::Parcel *input_parcel) {
2683   int disp_id = input_parcel->readInt32();
2684 
2685   // currently doing only for virtual display
2686   if (disp_id != qdutils::DISPLAY_VIRTUAL) {
2687     return -EINVAL;
2688   }
2689 
2690   std::lock_guard<std::mutex> obj(mutex_lum_);
2691   set_min_lum_ = input_parcel->readFloat();
2692   set_max_lum_ = input_parcel->readFloat();
2693   DLOGI("set max_lum %f, min_lum %f", set_max_lum_, set_min_lum_);
2694 
2695   return 0;
2696 }
2697 
UEventHandler(const char * uevent_data,int length)2698 void HWCSession::UEventHandler(const char *uevent_data, int length) {
2699   // Drop hotplug uevents until SurfaceFlinger (the client) is connected. The equivalent of hotplug
2700   // uevent handling will be done once when SurfaceFlinger connects, at RegisterCallback(). Since
2701   // HandlePluggableDisplays() reads the latest connection states of all displays, no uevent is
2702   // lost.
2703   if (client_connected_ && strcasestr(uevent_data, HWC_UEVENT_DRM_EXT_HOTPLUG)) {
2704     // MST hotplug will not carry connection status/test pattern etc.
2705     // Pluggable display handler will check all connection status' and take action accordingly.
2706     const char *str_status = GetTokenValue(uevent_data, length, "status=");
2707     const char *str_mst = GetTokenValue(uevent_data, length, "MST_HOTPLUG=");
2708     if (!str_status && !str_mst) {
2709       return;
2710     }
2711 
2712     hpd_bpp_ = GetEventValue(uevent_data, length, "bpp=");
2713     hpd_pattern_ = GetEventValue(uevent_data, length, "pattern=");
2714     DLOGI("Uevent = %s, status = %s, MST_HOTPLUG = %s, bpp = %d, pattern = %d", uevent_data,
2715           str_status ? str_status : "NULL", str_mst ? str_mst : "NULL", hpd_bpp_, hpd_pattern_);
2716 
2717     int virtual_display_index =
2718         GetDisplayIndex(qdutils::DISPLAY_VIRTUAL);
2719 
2720     std::bitset<kSecureMax> secure_sessions = 0;
2721     hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
2722     if (active_builtin_disp_id < HWCCallbacks::kNumDisplays) {
2723       Locker::ScopeLock lock_a(locker_[active_builtin_disp_id]);
2724       hwc_display_[active_builtin_disp_id]->GetActiveSecureSession(&secure_sessions);
2725     }
2726     if (secure_sessions[kSecureDisplay] ||
2727         ((virtual_display_index != -1) && (hwc_display_[virtual_display_index]))) {
2728       // Defer hotplug handling.
2729       SCOPE_LOCK(pluggable_handler_lock_);
2730       DLOGI("Marking hotplug pending...");
2731       hotplug_pending_event_ = kHotPlugEvent;
2732     } else {
2733       // Handle hotplug.
2734       int32_t err = HandlePluggableDisplays(true);
2735       if (err) {
2736         DLOGW("Hotplug handling failed. Error %d '%s'. Hotplug handling %s.", err,
2737               strerror(abs(err)), (hotplug_pending_event_ == kHotPlugEvent) ?
2738               "deferred" : "dropped");
2739       }
2740     }
2741 
2742     if (str_status) {
2743       bool connected = (strncmp(str_status, "connected", strlen("connected")) == 0);
2744       DLOGI("Connected = %d", connected);
2745       // Pass on legacy HDMI hot-plug event.
2746       qservice_->onHdmiHotplug(INT(connected));
2747     }
2748   }
2749 }
2750 
GetVsyncPeriod(int disp)2751 int HWCSession::GetVsyncPeriod(int disp) {
2752   SCOPE_LOCK(locker_[disp]);
2753   // default value
2754   int32_t vsync_period = 1000000000l / 60;
2755   auto attribute = HWC2::Attribute::VsyncPeriod;
2756 
2757   if (hwc_display_[disp]) {
2758     hwc_display_[disp]->GetDisplayAttribute(0, attribute, &vsync_period);
2759   }
2760 
2761   return vsync_period;
2762 }
2763 
GetVisibleDisplayRect(const android::Parcel * input_parcel,android::Parcel * output_parcel)2764 android::status_t HWCSession::GetVisibleDisplayRect(const android::Parcel *input_parcel,
2765                                                     android::Parcel *output_parcel) {
2766   int disp_idx = GetDisplayIndex(input_parcel->readInt32());
2767   if (disp_idx == -1) {
2768     DLOGE("Invalid display = %d", disp_idx);
2769     return android::BAD_VALUE;
2770   }
2771 
2772   SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_idx]);
2773   if (!hwc_display_[disp_idx]) {
2774     return android::NO_INIT;
2775   }
2776 
2777   hwc_rect_t visible_rect = {0, 0, 0, 0};
2778   int error = hwc_display_[disp_idx]->GetVisibleDisplayRect(&visible_rect);
2779   if (error < 0) {
2780     return error;
2781   }
2782 
2783   output_parcel->writeInt32(visible_rect.left);
2784   output_parcel->writeInt32(visible_rect.top);
2785   output_parcel->writeInt32(visible_rect.right);
2786   output_parcel->writeInt32(visible_rect.bottom);
2787 
2788   return android::NO_ERROR;
2789 }
2790 
Refresh(hwc2_display_t display)2791 void HWCSession::Refresh(hwc2_display_t display) {
2792   SCOPE_LOCK(callbacks_lock_);
2793   HWC2::Error err = callbacks_.Refresh(display);
2794   while (err != HWC2::Error::None) {
2795     callbacks_lock_.Wait();
2796     err = callbacks_.Refresh(display);
2797   }
2798 }
2799 
HotPlug(hwc2_display_t display,HWC2::Connection state)2800 void HWCSession::HotPlug(hwc2_display_t display, HWC2::Connection state) {
2801   SCOPE_LOCK(callbacks_lock_);
2802   HWC2::Error err = callbacks_.Hotplug(display, state);
2803   while (err != HWC2::Error::None) {
2804     callbacks_lock_.Wait();
2805     err = callbacks_.Hotplug(display, state);
2806   }
2807 }
2808 
CreatePrimaryDisplay()2809 int HWCSession::CreatePrimaryDisplay() {
2810   int status = -EINVAL;
2811   HWDisplaysInfo hw_displays_info = {};
2812 
2813   if (null_display_mode_) {
2814     HWDisplayInfo hw_info = {};
2815     hw_info.display_type = kBuiltIn;
2816     hw_info.is_connected = 1;
2817     hw_info.is_primary = 1;
2818     hw_info.is_wb_ubwc_supported = 0;
2819     hw_info.display_id = 1;
2820     hw_displays_info[hw_info.display_id] = hw_info;
2821   } else {
2822     DisplayError error = core_intf_->GetDisplaysStatus(&hw_displays_info);
2823     if (error != kErrorNone) {
2824       DLOGE("Failed to get connected display list. Error = %d", error);
2825       return status;
2826     }
2827   }
2828 
2829   for (auto &iter : hw_displays_info) {
2830     auto &info = iter.second;
2831     if (!info.is_primary) {
2832       continue;
2833     }
2834 
2835     // todo (user): If primary display is not connected (e.g. hdmi as primary), a NULL display
2836     // need to be created. SF expects primary display hotplug during callback registration unlike
2837     // previous implementation where first hotplug could be notified anytime.
2838     if (!info.is_connected) {
2839       DLOGE("Primary display is not connected. Not supported at present.");
2840       break;
2841     }
2842 
2843     auto hwc_display = &hwc_display_[HWC_DISPLAY_PRIMARY];
2844     hwc2_display_t client_id = map_info_primary_.client_id;
2845 
2846     DLOGI("Create primary display type = %d, sdm id = %d, client id = %d", info.display_type,
2847                                                                     info.display_id, client_id);
2848     if (info.display_type == kBuiltIn) {
2849       status = HWCDisplayBuiltIn::Create(core_intf_, &buffer_allocator_, &callbacks_, this,
2850                                          qservice_, client_id, info.display_id, hwc_display);
2851     } else if (info.display_type == kPluggable) {
2852       status = HWCDisplayPluggable::Create(core_intf_, &buffer_allocator_, &callbacks_, this,
2853                                            qservice_, client_id, info.display_id, 0, 0, false,
2854                                            hwc_display);
2855     } else {
2856       DLOGE("Spurious primary display type = %d", info.display_type);
2857       break;
2858     }
2859 
2860     if (!status) {
2861       is_hdr_display_[UINT32(client_id)] = HasHDRSupport(*hwc_display);
2862       DLOGI("Primary display created.");
2863       map_info_primary_.disp_type = info.display_type;
2864       map_info_primary_.sdm_id = info.display_id;
2865 
2866       CreateDummyDisplay(HWC_DISPLAY_PRIMARY);
2867       color_mgr_ = HWCColorManager::CreateColorManager(&buffer_allocator_);
2868       if (!color_mgr_) {
2869         DLOGW("Failed to load HWCColorManager.");
2870       }
2871     } else {
2872       DLOGE("Primary display creation failed.");
2873     }
2874 
2875     // Primary display is found, no need to parse more.
2876     break;
2877   }
2878 
2879   return status;
2880 }
2881 
CreateDummyDisplay(hwc2_display_t client_id)2882 void HWCSession::CreateDummyDisplay(hwc2_display_t client_id) {
2883   if (!async_powermode_) {
2884     return;
2885   }
2886 
2887   hwc2_display_t dummy_disp_id = map_hwc_display_.find(client_id)->second;
2888   auto hwc_display_dummy = &hwc_display_[dummy_disp_id];
2889   HWCDisplayDummy::Create(core_intf_, &buffer_allocator_, &callbacks_, this, qservice_,
2890                     0, 0, hwc_display_dummy);
2891   if (!*hwc_display_dummy) {
2892     DLOGE("Dummy display creation failed for %d display\n", client_id);
2893   }
2894 }
2895 
HandleBuiltInDisplays()2896 int HWCSession::HandleBuiltInDisplays() {
2897   if (null_display_mode_) {
2898     DLOGW("Skipped BuiltIn display handling in null-display mode");
2899     return 0;
2900   }
2901 
2902   HWDisplaysInfo hw_displays_info = {};
2903   DisplayError error = core_intf_->GetDisplaysStatus(&hw_displays_info);
2904   if (error != kErrorNone) {
2905     DLOGE("Failed to get connected display list. Error = %d", error);
2906     return -EINVAL;
2907   }
2908 
2909   int status = 0;
2910   for (auto &iter : hw_displays_info) {
2911     auto &info = iter.second;
2912 
2913     // Do not recreate primary display.
2914     if (info.is_primary || info.display_type != kBuiltIn) {
2915       continue;
2916     }
2917 
2918     for (auto &map_info : map_info_builtin_) {
2919       hwc2_display_t client_id = map_info.client_id;
2920 
2921       {
2922         SCOPE_LOCK(locker_[client_id]);
2923         // Lock confined to this scope
2924         if (hwc_display_[client_id]) {
2925           continue;
2926         }
2927 
2928         DLOGI("Create builtin display, sdm id = %d, client id = %d", info.display_id, client_id);
2929         status = HWCDisplayBuiltIn::Create(core_intf_, &buffer_allocator_, &callbacks_, this,
2930                                            qservice_, client_id, info.display_id,
2931                                            &hwc_display_[client_id]);
2932         if (status) {
2933           DLOGE("Builtin display creation failed.");
2934           break;
2935         }
2936         is_hdr_display_[UINT32(client_id)] = HasHDRSupport(hwc_display_[client_id]);
2937         DLOGI("Builtin display created: sdm id = %d, client id = %d", info.display_id, client_id);
2938         map_info.disp_type = info.display_type;
2939         map_info.sdm_id = info.display_id;
2940         CreateDummyDisplay(client_id);
2941       }
2942 
2943       DLOGI("Hotplugging builtin display, sdm id = %d, client id = %d", info.display_id, client_id);
2944       callbacks_.Hotplug(client_id, HWC2::Connection::Connected);
2945       break;
2946     }
2947   }
2948 
2949   return status;
2950 }
2951 
HandlePluggableDisplays(bool delay_hotplug)2952 int HWCSession::HandlePluggableDisplays(bool delay_hotplug) {
2953   SCOPE_LOCK(pluggable_handler_lock_);
2954   if (null_display_mode_) {
2955     DLOGW("Skipped pluggable display handling in null-display mode");
2956     return 0;
2957   }
2958 
2959   DLOGI("Handling hotplug...");
2960   HWDisplaysInfo hw_displays_info = {};
2961   DisplayError error = core_intf_->GetDisplaysStatus(&hw_displays_info);
2962   if (error != kErrorNone) {
2963     DLOGE("Failed to get connected display list. Error = %d", error);
2964     return -EINVAL;
2965   }
2966 
2967   int status = HandleDisconnectedDisplays(&hw_displays_info);
2968   if (status) {
2969     DLOGE("All displays could not be disconnected.");
2970     return status;
2971   }
2972 
2973   status = HandleConnectedDisplays(&hw_displays_info, delay_hotplug);
2974   if (status) {
2975     switch (status) {
2976       case -EAGAIN:
2977       case -ENODEV:
2978         // Errors like device removal or deferral for which we want to try another hotplug handling.
2979         hotplug_pending_event_ = kHotPlugEvent;
2980         status = 0;
2981         break;
2982       default:
2983         // Real errors we want to flag and stop hotplug handling.
2984         hotplug_pending_event_ = kHotPlugNone;
2985         DLOGE("All displays could not be connected. Error %d '%s'.", status, strerror(abs(status)));
2986     }
2987     DLOGI("Handling hotplug... %s", (kHotPlugNone ==hotplug_pending_event_) ?
2988           "Stopped." : "Done. Hotplug events pending.");
2989     return status;
2990   }
2991 
2992   hotplug_pending_event_ = kHotPlugNone;
2993 
2994   DLOGI("Handling hotplug... Done.");
2995   return 0;
2996 }
2997 
HandleConnectedDisplays(HWDisplaysInfo * hw_displays_info,bool delay_hotplug)2998 int HWCSession::HandleConnectedDisplays(HWDisplaysInfo *hw_displays_info, bool delay_hotplug) {
2999   int status = 0;
3000   std::vector<hwc2_display_t> pending_hotplugs = {};
3001 
3002   for (auto &iter : *hw_displays_info) {
3003     auto &info = iter.second;
3004 
3005     // Do not recreate primary display or if display is not connected.
3006     if (info.is_primary || info.display_type != kPluggable || !info.is_connected) {
3007       continue;
3008     }
3009 
3010     // Check if we are already using the display.
3011     auto display_used = std::find_if(map_info_pluggable_.begin(), map_info_pluggable_.end(),
3012                                      [&](auto &p) {
3013                                        return (p.sdm_id == info.display_id);
3014                                      });
3015     if (display_used != map_info_pluggable_.end()) {
3016       // Display is already used in a slot.
3017       continue;
3018     }
3019 
3020     // Count active pluggable display slots and slots with no commits.
3021     bool first_commit_pending = false;
3022     std::for_each(map_info_pluggable_.begin(), map_info_pluggable_.end(),
3023                    [&](auto &p) {
3024                      SCOPE_LOCK(locker_[p.client_id]);
3025                      if (hwc_display_[p.client_id]) {
3026                        if (!hwc_display_[p.client_id]->IsFirstCommitDone()) {
3027                          DLOGI("Display commit pending on display %d-1", p.sdm_id);
3028                          first_commit_pending = true;
3029                        }
3030                      }
3031                    });
3032 
3033     if (!disable_hotplug_bwcheck_ && first_commit_pending) {
3034       // Hotplug bandwidth check is accomplished by creating and hotplugging a new display after
3035       // a display commit has happened on previous hotplugged displays. This allows the driver to
3036       // return updated modes for the new display based on available link bandwidth.
3037       DLOGI("Pending display commit on one of the displays. Deferring display creation.");
3038       status = -EAGAIN;
3039       if (client_connected_) {
3040         // Trigger a display refresh since we depend on PresentDisplay() to handle pending hotplugs.
3041         hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
3042         if (active_builtin_disp_id >= HWCCallbacks::kNumDisplays) {
3043           active_builtin_disp_id = HWC_DISPLAY_PRIMARY;
3044         }
3045         Refresh(active_builtin_disp_id);
3046       }
3047       break;
3048     }
3049 
3050     // find an empty slot to create display.
3051     for (auto &map_info : map_info_pluggable_) {
3052       hwc2_display_t client_id = map_info.client_id;
3053 
3054       // Lock confined to this scope
3055       {
3056         SCOPE_LOCK(locker_[client_id]);
3057         auto &hwc_display = hwc_display_[client_id];
3058         if (hwc_display) {
3059           // Display slot is already used.
3060           continue;
3061         }
3062 
3063         DLOGI("Create pluggable display, sdm id = %d, client id = %d", info.display_id, client_id);
3064 
3065         // Test pattern generation ?
3066         map_info.test_pattern = (hpd_bpp_ > 0) && (hpd_pattern_ > 0);
3067         int err = 0;
3068         if (!map_info.test_pattern) {
3069           err = HWCDisplayPluggable::Create(core_intf_, &buffer_allocator_,
3070                                             &callbacks_, this, qservice_, client_id,
3071                                             info.display_id, 0, 0, false, &hwc_display);
3072         } else {
3073           err = HWCDisplayPluggableTest::Create(core_intf_, &buffer_allocator_,
3074                                                 &callbacks_, this, qservice_, client_id,
3075                                                 info.display_id, UINT32(hpd_bpp_),
3076                                                 UINT32(hpd_pattern_), &hwc_display);
3077         }
3078 
3079         if (err) {
3080           DLOGW("Pluggable display creation failed/aborted. Error %d '%s'.", err,
3081                 strerror(abs(err)));
3082           status = err;
3083           // Attempt creating remaining pluggable displays.
3084           break;
3085         }
3086 
3087         is_hdr_display_[UINT32(client_id)] = HasHDRSupport(hwc_display);
3088         DLOGI("Created pluggable display successfully: sdm id = %d, client id = %d",
3089               info.display_id, client_id);
3090         CreateDummyDisplay(client_id);
3091       }
3092 
3093       map_info.disp_type = info.display_type;
3094       map_info.sdm_id = info.display_id;
3095 
3096       pending_hotplugs.push_back((hwc2_display_t)client_id);
3097 
3098       // Display is created for this sdm id, move to next connected display.
3099       break;
3100     }
3101   }
3102 
3103   // No display was created.
3104   if (!pending_hotplugs.size()) {
3105     return status;
3106   }
3107 
3108   // Active builtin display needs revalidation
3109   hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
3110   if (active_builtin_disp_id < HWCCallbacks::kNumDisplays) {
3111     {
3112       SEQUENCE_WAIT_SCOPE_LOCK(locker_[active_builtin_disp_id]);
3113       hwc_display_[active_builtin_disp_id]->ResetValidation();
3114     }
3115 
3116     if (client_connected_) {
3117       Refresh(active_builtin_disp_id);
3118     }
3119 
3120     // Do not sleep if this method is called from client thread.
3121     if (delay_hotplug) {
3122       // wait sufficient time to ensure resources are available for new display connection.
3123       usleep(UINT32(GetVsyncPeriod(INT32(active_builtin_disp_id))) * 2 / 1000);
3124     }
3125   }
3126 
3127   for (auto client_id : pending_hotplugs) {
3128     DLOGI("Notify hotplug display connected: client id = %d", client_id);
3129     callbacks_.Hotplug(client_id, HWC2::Connection::Connected);
3130   }
3131 
3132   return status;
3133 }
3134 
HasHDRSupport(HWCDisplay * hwc_display)3135 bool HWCSession::HasHDRSupport(HWCDisplay *hwc_display) {
3136   // query number of hdr types
3137   uint32_t out_num_types = 0;
3138   float out_max_luminance = 0.0f;
3139   float out_max_average_luminance = 0.0f;
3140   float out_min_luminance = 0.0f;
3141   if (hwc_display->GetHdrCapabilities(&out_num_types, nullptr, &out_max_luminance,
3142                                       &out_max_average_luminance, &out_min_luminance)
3143                                       != HWC2::Error::None) {
3144     return false;
3145   }
3146 
3147   return (out_num_types > 0);
3148 }
3149 
HandleDisconnectedDisplays(HWDisplaysInfo * hw_displays_info)3150 int HWCSession::HandleDisconnectedDisplays(HWDisplaysInfo *hw_displays_info) {
3151   // Destroy pluggable displays which were connected earlier but got disconnected now.
3152   for (auto &map_info : map_info_pluggable_) {
3153     bool disconnect = true;   // disconnect in case display id is not found in list.
3154 
3155     for (auto &iter : *hw_displays_info) {
3156       auto &info = iter.second;
3157       if (info.display_id != map_info.sdm_id) {
3158         continue;
3159       }
3160       if (info.is_connected) {
3161         disconnect = false;
3162       }
3163       break;
3164     }
3165 
3166     if (disconnect) {
3167       DestroyDisplay(&map_info);
3168     }
3169   }
3170 
3171   return 0;
3172 }
3173 
DestroyDisplay(DisplayMapInfo * map_info)3174 void HWCSession::DestroyDisplay(DisplayMapInfo *map_info) {
3175   switch (map_info->disp_type) {
3176     case kPluggable:
3177       DestroyPluggableDisplay(map_info);
3178       break;
3179     default:
3180       DestroyNonPluggableDisplay(map_info);
3181       break;
3182     }
3183 }
3184 
DestroyPluggableDisplay(DisplayMapInfo * map_info)3185 void HWCSession::DestroyPluggableDisplay(DisplayMapInfo *map_info) {
3186   hwc2_display_t client_id = map_info->client_id;
3187 
3188   DLOGI("Notify hotplug display disconnected: client id = %d", client_id);
3189   callbacks_.Hotplug(client_id, HWC2::Connection::Disconnected);
3190 
3191   // Trigger refresh to make sure disconnect event received/updated properly by SurfaceFlinger.
3192   Refresh(HWC_DISPLAY_PRIMARY);
3193 
3194   // wait for sufficient time to ensure sufficient resources are available to process
3195   // connection.
3196   usleep(UINT32(GetVsyncPeriod(HWC_DISPLAY_PRIMARY)) * 2 / 1000);
3197 
3198   {
3199     SCOPE_LOCK(locker_[client_id]);
3200     auto &hwc_display = hwc_display_[client_id];
3201     if (!hwc_display) {
3202       return;
3203     }
3204     DLOGI("Destroy display %d-%d, client id = %d", map_info->sdm_id, map_info->disp_type,
3205          client_id);
3206 
3207     is_hdr_display_[UINT32(client_id)] = false;
3208     if (!map_info->test_pattern) {
3209       HWCDisplayPluggable::Destroy(hwc_display);
3210     } else {
3211       HWCDisplayPluggableTest::Destroy(hwc_display);
3212     }
3213 
3214     if (async_powermode_) {
3215       hwc2_display_t dummy_disp_id = map_hwc_display_.find(client_id)->second;
3216       auto &hwc_display_dummy = hwc_display_[dummy_disp_id];
3217       display_ready_.reset(UINT32(dummy_disp_id));
3218       if (hwc_display_dummy) {
3219         HWCDisplayDummy::Destroy(hwc_display_dummy);
3220         hwc_display_dummy = nullptr;
3221       }
3222     }
3223     display_ready_.reset(UINT32(client_id));
3224     hwc_display = nullptr;
3225     map_info->Reset();
3226   }
3227 }
3228 
DestroyNonPluggableDisplay(DisplayMapInfo * map_info)3229 void HWCSession::DestroyNonPluggableDisplay(DisplayMapInfo *map_info) {
3230   hwc2_display_t client_id = map_info->client_id;
3231 
3232   SCOPE_LOCK(locker_[client_id]);
3233   auto &hwc_display = hwc_display_[client_id];
3234   if (!hwc_display) {
3235     return;
3236   }
3237   DLOGI("Destroy display %d-%d, client id = %d", map_info->sdm_id, map_info->disp_type,
3238         client_id);
3239   is_hdr_display_[UINT32(client_id)] = false;
3240   switch (map_info->disp_type) {
3241     case kBuiltIn:
3242       HWCDisplayBuiltIn::Destroy(hwc_display);
3243       break;
3244     default:
3245       HWCDisplayVirtual::Destroy(hwc_display);
3246       break;
3247     }
3248 
3249     if (async_powermode_ && map_info->disp_type == kBuiltIn) {
3250       hwc2_display_t dummy_disp_id = map_hwc_display_.find(client_id)->second;
3251       auto &hwc_display_dummy = hwc_display_[dummy_disp_id];
3252       display_ready_.reset(UINT32(dummy_disp_id));
3253       if (hwc_display_dummy) {
3254         HWCDisplayDummy::Destroy(hwc_display_dummy);
3255         hwc_display_dummy = nullptr;
3256       }
3257     }
3258     hwc_display = nullptr;
3259     display_ready_.reset(UINT32(client_id));
3260     map_info->Reset();
3261 }
3262 
ValidateDisplayInternal(hwc2_display_t display,uint32_t * out_num_types,uint32_t * out_num_requests)3263 HWC2::Error HWCSession::ValidateDisplayInternal(hwc2_display_t display, uint32_t *out_num_types,
3264                                                 uint32_t *out_num_requests) {
3265   HWCDisplay *hwc_display = hwc_display_[display];
3266 
3267   DTRACE_SCOPED();
3268   if (hwc_display->IsInternalValidateState()) {
3269     // Internal Validation has already been done on display, get the Output params.
3270     return hwc_display->GetValidateDisplayOutput(out_num_types, out_num_requests);
3271   }
3272 
3273   if (display == HWC_DISPLAY_PRIMARY) {
3274     // TODO(user): This can be moved to HWCDisplayPrimary
3275     if (need_invalidate_) {
3276       Refresh(display);
3277       need_invalidate_ = false;
3278     }
3279 
3280     if (color_mgr_) {
3281       color_mgr_->SetColorModeDetailEnhancer(hwc_display_[display]);
3282     }
3283   }
3284 
3285   return hwc_display->Validate(out_num_types, out_num_requests);
3286 }
3287 
PresentDisplayInternal(hwc2_display_t display,int32_t * out_retire_fence)3288 HWC2::Error HWCSession::PresentDisplayInternal(hwc2_display_t display, int32_t *out_retire_fence) {
3289   HWCDisplay *hwc_display = hwc_display_[display];
3290 
3291   DTRACE_SCOPED();
3292   // If display is in Skip-Validate state and Validate cannot be skipped, do Internal
3293   // Validation to optimize for the frames which don't require the Client composition.
3294   if (hwc_display->IsSkipValidateState() && !hwc_display->CanSkipValidate()) {
3295     uint32_t out_num_types = 0, out_num_requests = 0;
3296     hwc_display->SetFastPathComposition(true);
3297     HWC2::Error error = ValidateDisplayInternal(display, &out_num_types, &out_num_requests);
3298     if ((error != HWC2::Error::None) || hwc_display->HWCClientNeedsValidate()) {
3299       hwc_display->SetValidationState(HWCDisplay::kInternalValidate);
3300       hwc_display->SetFastPathComposition(false);
3301       return HWC2::Error::NotValidated;
3302     }
3303   }
3304   return HWC2::Error::None;
3305 }
3306 
DisplayPowerReset()3307 void HWCSession::DisplayPowerReset() {
3308   // Acquire lock on all displays.
3309   for (hwc2_display_t display = HWC_DISPLAY_PRIMARY;
3310     display < HWCCallbacks::kNumDisplays; display++) {
3311     locker_[display].Lock();
3312   }
3313 
3314   HWC2::Error status = HWC2::Error::None;
3315   HWC2::PowerMode last_power_mode[HWCCallbacks::kNumDisplays] = {};
3316 
3317   for (hwc2_display_t display = HWC_DISPLAY_PRIMARY;
3318     display < HWCCallbacks::kNumDisplays; display++) {
3319     if (hwc_display_[display] != NULL) {
3320       last_power_mode[display] = hwc_display_[display]->GetCurrentPowerMode();
3321       DLOGI("Powering off display = %d", display);
3322       status = hwc_display_[display]->SetPowerMode(HWC2::PowerMode::Off,
3323                                                    true /* teardown */);
3324       if (status != HWC2::Error::None) {
3325         DLOGE("Power off for display = %d failed with error = %d", display, status);
3326       }
3327     }
3328   }
3329   for (hwc2_display_t display = HWC_DISPLAY_PRIMARY;
3330     display < HWCCallbacks::kNumDisplays; display++) {
3331     if (hwc_display_[display] != NULL) {
3332       HWC2::PowerMode mode = last_power_mode[display];
3333       DLOGI("Setting display %d to mode = %d", display, mode);
3334       status = hwc_display_[display]->SetPowerMode(mode, false /* teardown */);
3335       if (status != HWC2::Error::None) {
3336         DLOGE("%d mode for display = %d failed with error = %d", mode, display, status);
3337       }
3338       ColorMode color_mode = hwc_display_[display]->GetCurrentColorMode();
3339       RenderIntent intent = hwc_display_[display]->GetCurrentRenderIntent();
3340       status = hwc_display_[display]->SetColorModeWithRenderIntent(color_mode, intent);
3341       if (status != HWC2::Error::None) {
3342         DLOGE("SetColorMode failed for display = %d error = %d", display, status);
3343       }
3344     }
3345   }
3346 
3347   hwc2_display_t vsync_source = callbacks_.GetVsyncSource();
3348   status = hwc_display_[vsync_source]->SetVsyncEnabled(HWC2::Vsync::Enable);
3349   if (status != HWC2::Error::None) {
3350     DLOGE("Enabling vsync failed for disp: %" PRIu64 " with error = %d", vsync_source, status);
3351   }
3352 
3353   // Release lock on all displays.
3354   for (hwc2_display_t display = HWC_DISPLAY_PRIMARY;
3355     display < HWCCallbacks::kNumDisplays; display++) {
3356     locker_[display].Unlock();
3357   }
3358 
3359   Refresh(vsync_source);
3360 }
3361 
HandleSecureSession()3362 void HWCSession::HandleSecureSession() {
3363   std::bitset<kSecureMax> secure_sessions = 0;
3364   {
3365     hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
3366     if (active_builtin_disp_id >= HWCCallbacks::kNumDisplays) {
3367       return;
3368     }
3369     Locker::ScopeLock lock_a(locker_[active_builtin_disp_id]);
3370     hwc_display_[active_builtin_disp_id]->GetActiveSecureSession(&secure_sessions);
3371   }
3372 
3373   // If it is called during primary prepare/commit, we need to pause any ongoing commit on
3374   // external/virtual display.
3375   for (hwc2_display_t display = HWC_DISPLAY_PRIMARY;
3376     display < HWCCallbacks::kNumDisplays; display++) {
3377     Locker::ScopeLock lock_d(locker_[display]);
3378     if (hwc_display_[display]) {
3379       hwc_display_[display]->HandleSecureSession(secure_sessions, &power_on_pending_[display]);
3380     }
3381   }
3382 }
3383 
HandlePowerOnPending(hwc2_display_t disp_id,int retire_fence)3384 void HWCSession::HandlePowerOnPending(hwc2_display_t disp_id, int retire_fence) {
3385   hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
3386   if (disp_id != active_builtin_disp_id) {
3387     return;
3388   }
3389 
3390   Locker::ScopeLock lock_a(locker_[active_builtin_disp_id]);
3391   bool power_on_pending = false;
3392   for (hwc2_display_t display = HWC_DISPLAY_PRIMARY;
3393     display < HWCCallbacks::kNumDisplays; display++) {
3394     if (display != active_builtin_disp_id) {
3395       Locker::ScopeLock lock_d(locker_[display]);
3396       if (power_on_pending_[display]) {
3397         power_on_pending = true;
3398         break;
3399       }
3400     }
3401   }
3402   if (power_on_pending) {
3403     // retire fence is set only after successful primary commit, So check for retire fence to know
3404     // non secure commit went through to notify driver to change the CRTC mode to non secure.
3405     // Otherwise any commit to non-primary display would fail.
3406     if (retire_fence < 0) {
3407       return;
3408     }
3409     int error = sync_wait(retire_fence, 1000);
3410     if (error < 0) {
3411       DLOGE("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
3412     }
3413   } else {
3414     return;
3415   }
3416 
3417   for (hwc2_display_t display = HWC_DISPLAY_PRIMARY;
3418     display < HWCCallbacks::kNumDisplays; display++) {
3419     if (display != active_builtin_disp_id) {
3420       Locker::ScopeLock lock_d(locker_[display]);
3421       if (power_on_pending_[display] && hwc_display_[display]) {
3422         HWC2::Error status =
3423           hwc_display_[display]->SetPowerMode(HWC2::PowerMode::On, false /* teardown */);
3424         if (status == HWC2::Error::None) {
3425           power_on_pending_[display] = false;
3426         }
3427       }
3428     }
3429   }
3430 }
3431 
HandleHotplugPending(hwc2_display_t disp_id,int retire_fence)3432 void HWCSession::HandleHotplugPending(hwc2_display_t disp_id, int retire_fence) {
3433   hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
3434   if (disp_id != active_builtin_disp_id ||
3435       (kHotPlugNone == hotplug_pending_event_ && !destroy_virtual_disp_pending_)) {
3436     return;
3437   }
3438 
3439   std :: bitset < kSecureMax > secure_sessions = 0;
3440   if (active_builtin_disp_id < HWCCallbacks::kNumDisplays) {
3441     Locker::ScopeLock lock_a(locker_[active_builtin_disp_id]);
3442     hwc_display_[active_builtin_disp_id]->GetActiveSecureSession(&secure_sessions);
3443   }
3444 
3445   if (secure_sessions.any() || active_builtin_disp_id >= HWCCallbacks::kNumDisplays) {
3446     return;
3447   }
3448 
3449   if (destroy_virtual_disp_pending_ || kHotPlugEvent == hotplug_pending_event_) {
3450     if (retire_fence >= 0) {
3451       int error = sync_wait(retire_fence, 1000);
3452       if (error < 0) {
3453         DLOGE("sync_wait error errno = %d, desc = %s", errno,  strerror(errno));
3454       }
3455     }
3456     // Destroy the pending virtual display if secure session not present.
3457     if (destroy_virtual_disp_pending_) {
3458       for (auto &map_info : map_info_virtual_) {
3459         DestroyDisplay(&map_info);
3460         destroy_virtual_disp_pending_ = false;
3461       }
3462     }
3463     // Handle connect/disconnect hotplugs if secure session is not present.
3464     int virtual_display_idx = GetDisplayIndex(qdutils::DISPLAY_VIRTUAL);
3465     if (!(virtual_display_idx != -1 && hwc_display_[virtual_display_idx]) &&
3466         kHotPlugEvent == hotplug_pending_event_) {
3467       // Handle deferred hotplug event.
3468       int32_t err = pluggable_handler_lock_.TryLock();
3469       if (!err) {
3470         // Do hotplug handling in a different thread to avoid blocking PresentDisplay.
3471         std::thread(&HWCSession::HandlePluggableDisplays, this, true).detach();
3472         pluggable_handler_lock_.Unlock();
3473       } else {
3474         // EBUSY means another thread is already handling hotplug. Skip deferred hotplug handling.
3475         if (EBUSY != err) {
3476           DLOGW("Failed to acquire pluggable display handler lock. Error %d '%s'.", err,
3477                 strerror(abs(err)));
3478         }
3479       }
3480     }
3481   }
3482 }
3483 
GetReadbackBufferAttributes(hwc2_device_t * device,hwc2_display_t display,int32_t * format,int32_t * dataspace)3484 int32_t HWCSession::GetReadbackBufferAttributes(hwc2_device_t *device, hwc2_display_t display,
3485                                                 int32_t *format, int32_t *dataspace) {
3486   if (!device || !format || !dataspace) {
3487     return HWC2_ERROR_BAD_PARAMETER;
3488   }
3489 
3490   if (display != HWC_DISPLAY_PRIMARY) {
3491     return HWC2_ERROR_BAD_DISPLAY;
3492   }
3493 
3494   HWCSession *hwc_session = static_cast<HWCSession *>(device);
3495   HWCDisplay *hwc_display = hwc_session->hwc_display_[display];
3496 
3497   if (hwc_display) {
3498     if (!hwc_display->IsDisplayCommandMode()) {
3499       return HWC2_ERROR_UNSUPPORTED;
3500     }
3501     *format = HAL_PIXEL_FORMAT_RGB_888;
3502     *dataspace = GetDataspaceFromColorMode(hwc_display->GetCurrentColorMode());
3503     return HWC2_ERROR_NONE;
3504   }
3505 
3506   return HWC2_ERROR_BAD_DISPLAY;
3507 }
3508 
SetReadbackBuffer(hwc2_device_t * device,hwc2_display_t display,const native_handle_t * buffer,int32_t acquire_fence)3509 int32_t HWCSession::SetReadbackBuffer(hwc2_device_t *device, hwc2_display_t display,
3510                                       const native_handle_t *buffer, int32_t acquire_fence) {
3511   if (!buffer) {
3512     return HWC2_ERROR_BAD_PARAMETER;
3513   }
3514 
3515   if (display != HWC_DISPLAY_PRIMARY) {
3516     return HWC2_ERROR_BAD_DISPLAY;
3517   }
3518 
3519   HWCSession *hwc_session = static_cast<HWCSession *>(device);
3520 
3521   const int external_display_index = hwc_session->GetDisplayIndex(qdutils::DISPLAY_EXTERNAL);
3522   if ((external_display_index >=0) && (hwc_session->hwc_display_[external_display_index])) {
3523     return HWC2_ERROR_UNSUPPORTED;
3524   }
3525 
3526   const int virtual_display_index = hwc_session->GetDisplayIndex(qdutils::DISPLAY_VIRTUAL);
3527   if ((virtual_display_index >=0) && (hwc_session->hwc_display_[virtual_display_index])) {
3528     return HWC2_ERROR_UNSUPPORTED;
3529   }
3530 
3531   return CallDisplayFunction(device, display, &HWCDisplay::SetReadbackBuffer,
3532                              buffer, acquire_fence, false);
3533 }
3534 
GetReadbackBufferFence(hwc2_device_t * device,hwc2_display_t display,int32_t * release_fence)3535 int32_t HWCSession::GetReadbackBufferFence(hwc2_device_t *device, hwc2_display_t display,
3536                                            int32_t *release_fence) {
3537   if (!release_fence) {
3538     return HWC2_ERROR_BAD_PARAMETER;
3539   }
3540 
3541   if (display != HWC_DISPLAY_PRIMARY) {
3542     return HWC2_ERROR_BAD_DISPLAY;
3543   }
3544 
3545   return CallDisplayFunction(device, display, &HWCDisplay::GetReadbackBufferFence, release_fence);
3546 }
3547 
GetDisplayIdentificationData(hwc2_device_t * device,hwc2_display_t display,uint8_t * outPort,uint32_t * outDataSize,uint8_t * outData)3548 int32_t HWCSession::GetDisplayIdentificationData(hwc2_device_t *device, hwc2_display_t display,
3549                                                  uint8_t *outPort, uint32_t *outDataSize,
3550                                                  uint8_t *outData) {
3551   if (!outPort || !outDataSize) {
3552     return HWC2_ERROR_BAD_PARAMETER;
3553   }
3554 
3555   if (display >= HWCCallbacks::kNumDisplays) {
3556     return HWC2_ERROR_BAD_DISPLAY;
3557   }
3558 
3559   return CallDisplayFunction(device, display, &HWCDisplay::GetDisplayIdentificationData, outPort,
3560                              outDataSize, outData);
3561 }
3562 
SetQSyncMode(const android::Parcel * input_parcel)3563 android::status_t HWCSession::SetQSyncMode(const android::Parcel *input_parcel) {
3564   auto mode = input_parcel->readInt32();
3565   auto device = static_cast<hwc2_device_t *>(this);
3566 
3567   QSyncMode qsync_mode = kQSyncModeNone;
3568   switch (mode) {
3569     case qService::IQService::QSYNC_MODE_NONE:
3570       qsync_mode = kQSyncModeNone;
3571       break;
3572     case qService::IQService::QSYNC_MODE_CONTINUOUS:
3573       qsync_mode = kQSyncModeContinuous;
3574       break;
3575     case qService::IQService::QSYNC_MODE_ONESHOT:
3576       qsync_mode = kQsyncModeOneShot;
3577       break;
3578     default:
3579       DLOGE("Qsync mode not supported %d", mode);
3580       return -EINVAL;
3581   }
3582   return CallDisplayFunction(device, HWC_DISPLAY_PRIMARY, &HWCDisplay::SetQSyncMode, qsync_mode);
3583 }
3584 
UpdateThrottlingRate()3585 void HWCSession::UpdateThrottlingRate() {
3586   uint32_t new_min = 0;
3587 
3588   for (int i=0; i < HWCCallbacks::kNumDisplays; i++) {
3589     auto &display = hwc_display_[i];
3590     if (!display)
3591       continue;
3592     if (display->GetCurrentPowerMode() != HWC2::PowerMode::Off)
3593       new_min = (new_min == 0) ? display->GetMaxRefreshRate() :
3594         std::min(new_min, display->GetMaxRefreshRate());
3595   }
3596 
3597   SetNewThrottlingRate(new_min);
3598 }
3599 
SetNewThrottlingRate(const uint32_t new_rate)3600 void HWCSession::SetNewThrottlingRate(const uint32_t new_rate) {
3601   if (new_rate !=0 && throttling_refresh_rate_ != new_rate) {
3602     HWCDisplay::SetThrottlingRefreshRate(new_rate);
3603     throttling_refresh_rate_ = new_rate;
3604   }
3605 }
3606 
SetIdlePC(const android::Parcel * input_parcel)3607 android::status_t HWCSession::SetIdlePC(const android::Parcel *input_parcel) {
3608   auto enable = input_parcel->readInt32();
3609   auto synchronous = input_parcel->readInt32();
3610 
3611   return static_cast<android::status_t>(controlIdlePowerCollapse(enable, synchronous));
3612 }
3613 
GetActiveBuiltinDisplay()3614 hwc2_display_t HWCSession::GetActiveBuiltinDisplay() {
3615   hwc2_display_t disp_id = HWCCallbacks::kNumDisplays;
3616   // Get first active display among primary and built-in displays.
3617   std::vector<DisplayMapInfo> map_info = {map_info_primary_};
3618   std::copy(map_info_builtin_.begin(), map_info_builtin_.end(), std::back_inserter(map_info));
3619 
3620   for (auto &info : map_info) {
3621     SCOPE_LOCK(locker_[info.client_id]);
3622     auto &hwc_display = hwc_display_[info.client_id];
3623     if (hwc_display && hwc_display->GetCurrentPowerMode() != HWC2::PowerMode::Off) {
3624       disp_id = info.client_id;
3625       break;
3626     }
3627   }
3628 
3629   return disp_id;
3630 }
3631 
NotifyClientStatus(bool connected)3632 void HWCSession::NotifyClientStatus(bool connected) {
3633   for (uint32_t i = 0; i < HWCCallbacks::kNumDisplays; i++) {
3634     if (!hwc_display_[i]) {
3635       continue;
3636     }
3637     SCOPE_LOCK(locker_[i]);
3638     hwc_display_[i]->NotifyClientStatus(connected);
3639   }
3640 }
3641 
3642 }  // namespace sdm
3643