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