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