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 <core/buffer_allocator.h>
21 #include <private/color_params.h>
22 #include <utils/constants.h>
23 #include <utils/String16.h>
24 #include <cutils/properties.h>
25 #include <hardware_legacy/uevent.h>
26 #include <sys/resource.h>
27 #include <sys/prctl.h>
28 #include <binder/Parcel.h>
29 #include <QService.h>
30 #include <display_config.h>
31 #include <utils/debug.h>
32 #include <sync/sync.h>
33 #include <profiler.h>
34 #include <algorithm>
35 #include <string>
36 #include <bitset>
37 #include <thread>
38 #include <memory>
39 
40 #include "hwc_buffer_allocator.h"
41 #include "hwc_buffer_sync_handler.h"
42 #include "hwc_session.h"
43 #include "hwc_debugger.h"
44 #include "hwc_display_primary.h"
45 #include "hwc_display_virtual.h"
46 #include "hwc_display_external_test.h"
47 #include "qd_utils.h"
48 
49 #define __CLASS__ "HWCSession"
50 
51 #define HWC_UEVENT_SWITCH_HDMI "change@/devices/virtual/switch/hdmi"
52 #define HWC_UEVENT_GRAPHICS_FB0 "change@/devices/virtual/graphics/fb0"
53 
54 static sdm::HWCSession::HWCModuleMethods g_hwc_module_methods;
55 
56 hwc_module_t HAL_MODULE_INFO_SYM = {
57   .common = {
58     .tag = HARDWARE_MODULE_TAG,
59     .version_major = 3,
60     .version_minor = 0,
61     .id = HWC_HARDWARE_MODULE_ID,
62     .name = "QTI Hardware Composer Module",
63     .author = "CodeAurora Forum",
64     .methods = &g_hwc_module_methods,
65     .dso = 0,
66     .reserved = {0},
67   }
68 };
69 
70 namespace sdm {
71 
72 static HWCUEvent g_hwc_uevent_;
73 Locker HWCSession::locker_[HWC_NUM_DISPLAY_TYPES];
74 bool HWCSession::disable_skip_validate_ = false;
75 
UEventThread(HWCUEvent * hwc_uevent)76 void HWCUEvent::UEventThread(HWCUEvent *hwc_uevent) {
77   const char *uevent_thread_name = "HWC_UeventThread";
78 
79   prctl(PR_SET_NAME, uevent_thread_name, 0, 0, 0);
80   setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
81 
82   int status = uevent_init();
83   if (!status) {
84     std::unique_lock<std::mutex> caller_lock(hwc_uevent->mutex_);
85     hwc_uevent->caller_cv_.notify_one();
86     DLOGE("Failed to init uevent with err %d", status);
87     return;
88   }
89 
90   {
91     // Signal caller thread that worker thread is ready to listen to events.
92     std::unique_lock<std::mutex> caller_lock(hwc_uevent->mutex_);
93     hwc_uevent->init_done_ = true;
94     hwc_uevent->caller_cv_.notify_one();
95   }
96 
97   while (1) {
98     char uevent_data[PAGE_SIZE] = {};
99 
100     // keep last 2 zeroes to ensure double 0 termination
101     int length = uevent_next_event(uevent_data, INT32(sizeof(uevent_data)) - 2);
102 
103     // scope of lock to this block only, so that caller is free to set event handler to nullptr;
104     {
105       std::lock_guard<std::mutex> guard(hwc_uevent->mutex_);
106       if (hwc_uevent->uevent_listener_) {
107         hwc_uevent->uevent_listener_->UEventHandler(uevent_data, length);
108       } else {
109         DLOGW("UEvent dropped. No uevent listener.");
110       }
111     }
112   }
113 }
114 
HWCUEvent()115 HWCUEvent::HWCUEvent() {
116   std::unique_lock<std::mutex> caller_lock(mutex_);
117   std::thread thread(HWCUEvent::UEventThread, this);
118   thread.detach();
119   caller_cv_.wait(caller_lock);
120 }
121 
Register(HWCUEventListener * uevent_listener)122 void HWCUEvent::Register(HWCUEventListener *uevent_listener) {
123   DLOGI("Set uevent listener = %p", uevent_listener);
124 
125   std::lock_guard<std::mutex> obj(mutex_);
126   uevent_listener_ = uevent_listener;
127 }
128 
HWCSession(const hw_module_t * module)129 HWCSession::HWCSession(const hw_module_t *module) {
130   hwc2_device_t::common.tag = HARDWARE_DEVICE_TAG;
131   hwc2_device_t::common.version = HWC_DEVICE_API_VERSION_2_0;
132   hwc2_device_t::common.module = const_cast<hw_module_t *>(module);
133   hwc2_device_t::common.close = Close;
134   hwc2_device_t::getCapabilities = GetCapabilities;
135   hwc2_device_t::getFunction = GetFunction;
136 }
137 
Init()138 int HWCSession::Init() {
139   SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
140 
141   int status = -EINVAL;
142   const char *qservice_name = "display.qservice";
143 
144   if (!g_hwc_uevent_.InitDone()) {
145     return status;
146   }
147 
148   // Start QService and connect to it.
149   qService::QService::init();
150   android::sp<qService::IQService> iqservice = android::interface_cast<qService::IQService>(
151       android::defaultServiceManager()->getService(android::String16(qservice_name)));
152 
153   if (iqservice.get()) {
154     iqservice->connect(android::sp<qClient::IQClient>(this));
155     qservice_ = reinterpret_cast<qService::QService *>(iqservice.get());
156   } else {
157     ALOGE("%s::%s: Failed to acquire %s", __CLASS__, __FUNCTION__, qservice_name);
158     return -EINVAL;
159   }
160 
161   StartServices();
162 
163   DisplayError error = buffer_allocator_.Init();
164   if (error != kErrorNone) {
165     ALOGE("%s::%s: Buffer allocaor initialization failed. Error = %d",
166           __CLASS__, __FUNCTION__, error);
167     return -EINVAL;
168   }
169 
170   error = CoreInterface::CreateCore(HWCDebugHandler::Get(), &buffer_allocator_,
171                                     &buffer_sync_handler_, &socket_handler_, &core_intf_);
172   if (error != kErrorNone) {
173     buffer_allocator_.Deinit();
174     ALOGE("%s::%s: Display core initialization failed. Error = %d", __CLASS__, __FUNCTION__, error);
175     return -EINVAL;
176   }
177 
178   g_hwc_uevent_.Register(this);
179 
180   // If HDMI display is primary display, defer display creation until hotplug event is received.
181   HWDisplayInterfaceInfo hw_disp_info = {};
182   error = core_intf_->GetFirstDisplayInterfaceType(&hw_disp_info);
183   if (error != kErrorNone) {
184     g_hwc_uevent_.Register(nullptr);
185     CoreInterface::DestroyCore();
186     buffer_allocator_.Deinit();
187     DLOGE("Primary display type not recognized. Error = %d", error);
188     return -EINVAL;
189   }
190 
191   if (hw_disp_info.type == kHDMI) {
192     status = 0;
193     hdmi_is_primary_ = true;
194     // Create display if it is connected, else wait for hotplug connect event.
195     if (hw_disp_info.is_connected) {
196       status = CreateExternalDisplay(HWC_DISPLAY_PRIMARY);
197     }
198   } else {
199     // Create and power on primary display
200     status = HWCDisplayPrimary::Create(core_intf_, &buffer_allocator_, &callbacks_, qservice_,
201                                        &hwc_display_[HWC_DISPLAY_PRIMARY]);
202     color_mgr_ = HWCColorManager::CreateColorManager(&buffer_allocator_);
203     if (!color_mgr_) {
204       DLOGW("Failed to load HWCColorManager.");
205     }
206   }
207 
208   if (status) {
209     g_hwc_uevent_.Register(nullptr);
210     CoreInterface::DestroyCore();
211     buffer_allocator_.Deinit();
212     return status;
213   }
214 
215   return 0;
216 }
217 
Deinit()218 int HWCSession::Deinit() {
219   Locker::SequenceCancelScopeLock lock_v(locker_[HWC_DISPLAY_VIRTUAL]);
220   Locker::SequenceCancelScopeLock lock_e(locker_[HWC_DISPLAY_EXTERNAL]);
221   Locker::SequenceCancelScopeLock lock_p(locker_[HWC_DISPLAY_PRIMARY]);
222 
223   HWCDisplay *primary_display = hwc_display_[HWC_DISPLAY_PRIMARY];
224   if (primary_display) {
225     if (hdmi_is_primary_) {
226       HWCDisplayExternal::Destroy(primary_display);
227     } else {
228       HWCDisplayPrimary::Destroy(primary_display);
229     }
230   }
231   hwc_display_[HWC_DISPLAY_PRIMARY] = nullptr;
232 
233   if (color_mgr_) {
234     color_mgr_->DestroyColorManager();
235   }
236 
237   g_hwc_uevent_.Register(nullptr);
238 
239   DisplayError error = CoreInterface::DestroyCore();
240   if (error != kErrorNone) {
241     ALOGE("Display core de-initialization failed. Error = %d", error);
242   }
243 
244   return 0;
245 }
246 
Open(const hw_module_t * module,const char * name,hw_device_t ** device)247 int HWCSession::Open(const hw_module_t *module, const char *name, hw_device_t **device) {
248   if (!module || !name || !device) {
249     ALOGE("%s::%s: Invalid parameters.", __CLASS__, __FUNCTION__);
250     return -EINVAL;
251   }
252 
253   if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
254     HWCSession *hwc_session = new HWCSession(module);
255     if (!hwc_session) {
256       return -ENOMEM;
257     }
258 
259     int status = hwc_session->Init();
260     if (status != 0) {
261       return status;
262     }
263 
264     hwc2_device_t *composer_device = hwc_session;
265     *device = reinterpret_cast<hw_device_t *>(composer_device);
266   }
267 
268   return 0;
269 }
270 
Close(hw_device_t * device)271 int HWCSession::Close(hw_device_t *device) {
272   if (!device) {
273     return -EINVAL;
274   }
275 
276   hwc2_device_t *composer_device = reinterpret_cast<hwc2_device_t *>(device);
277   HWCSession *hwc_session = static_cast<HWCSession *>(composer_device);
278 
279   hwc_session->Deinit();
280 
281   return 0;
282 }
283 
GetCapabilities(struct hwc2_device * device,uint32_t * outCount,int32_t * outCapabilities)284 void HWCSession::GetCapabilities(struct hwc2_device *device, uint32_t *outCount,
285                                  int32_t *outCapabilities) {
286   if (!outCount) {
287     return;
288   }
289 
290   int value = 0;
291   uint32_t count = 0;
292   HWCSession *hwc_session = static_cast<HWCSession *>(device);
293   bool color_transform_supported = hwc_session->core_intf_->IsColorTransformSupported();
294 
295   if (Debug::Get()->GetProperty(DISABLE_SKIP_VALIDATE_PROP, &value) == kErrorNone) {
296     disable_skip_validate_ = (value == 1);
297   }
298 
299   count += (color_transform_supported) ? 1 : 0;
300   count += (!disable_skip_validate_) ? 1 : 0;
301 
302   if (outCapabilities != nullptr && (*outCount >= count)) {
303     int i = 0;
304     if (color_transform_supported) {
305       outCapabilities[i++] = HWC2_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM;
306     }
307     if (!disable_skip_validate_) {
308       outCapabilities[i++] = HWC2_CAPABILITY_SKIP_VALIDATE;
309     }
310   }
311   *outCount = count;
312 }
313 
314 template <typename PFN, typename T>
AsFP(T function)315 static hwc2_function_pointer_t AsFP(T function) {
316   static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer");
317   return reinterpret_cast<hwc2_function_pointer_t>(function);
318 }
319 
320 // HWC2 functions returned in GetFunction
321 // Defined in the same order as in the HWC2 header
322 
AcceptDisplayChanges(hwc2_device_t * device,hwc2_display_t display)323 int32_t HWCSession::AcceptDisplayChanges(hwc2_device_t *device, hwc2_display_t display) {
324   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::AcceptDisplayChanges);
325 }
326 
CreateLayer(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t * out_layer_id)327 int32_t HWCSession::CreateLayer(hwc2_device_t *device, hwc2_display_t display,
328                                 hwc2_layer_t *out_layer_id) {
329   if (!out_layer_id) {
330     return  HWC2_ERROR_BAD_PARAMETER;
331   }
332 
333   return CallDisplayFunction(device, display, &HWCDisplay::CreateLayer, out_layer_id);
334 }
335 
CreateVirtualDisplay(hwc2_device_t * device,uint32_t width,uint32_t height,int32_t * format,hwc2_display_t * out_display_id)336 int32_t HWCSession::CreateVirtualDisplay(hwc2_device_t *device, uint32_t width, uint32_t height,
337                                          int32_t *format, hwc2_display_t *out_display_id) {
338   // TODO(user): Handle concurrency with HDMI
339   SCOPE_LOCK(locker_[HWC_DISPLAY_VIRTUAL]);
340   if (!device) {
341     return HWC2_ERROR_BAD_DISPLAY;
342   }
343 
344   if (!out_display_id || !width || !height || !format) {
345     return  HWC2_ERROR_BAD_PARAMETER;
346   }
347 
348   HWCSession *hwc_session = static_cast<HWCSession *>(device);
349   auto status = hwc_session->CreateVirtualDisplayObject(width, height, format);
350   if (status == HWC2::Error::None) {
351     *out_display_id = HWC_DISPLAY_VIRTUAL;
352     DLOGI("Created virtual display id:% " PRIu64 " with res: %dx%d",
353           *out_display_id, width, height);
354   } else {
355     DLOGE("Failed to create virtual display: %s", to_string(status).c_str());
356   }
357   return INT32(status);
358 }
359 
DestroyLayer(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer)360 int32_t HWCSession::DestroyLayer(hwc2_device_t *device, hwc2_display_t display,
361                                  hwc2_layer_t layer) {
362   return CallDisplayFunction(device, display, &HWCDisplay::DestroyLayer, layer);
363 }
364 
DestroyVirtualDisplay(hwc2_device_t * device,hwc2_display_t display)365 int32_t HWCSession::DestroyVirtualDisplay(hwc2_device_t *device, hwc2_display_t display) {
366   if (!device || display != HWC_DISPLAY_VIRTUAL) {
367     return HWC2_ERROR_BAD_DISPLAY;
368   }
369 
370   SCOPE_LOCK(locker_[display]);
371   DLOGI("Destroying virtual display id:%" PRIu64, display);
372   auto *hwc_session = static_cast<HWCSession *>(device);
373 
374   if (hwc_session->hwc_display_[display]) {
375     HWCDisplayVirtual::Destroy(hwc_session->hwc_display_[display]);
376     hwc_session->hwc_display_[display] = nullptr;
377     return HWC2_ERROR_NONE;
378   } else {
379     return HWC2_ERROR_BAD_DISPLAY;
380   }
381 }
382 
Dump(hwc2_device_t * device,uint32_t * out_size,char * out_buffer)383 void HWCSession::Dump(hwc2_device_t *device, uint32_t *out_size, char *out_buffer) {
384   if (!device || !out_size) {
385     return;
386   }
387 
388   auto *hwc_session = static_cast<HWCSession *>(device);
389   const size_t max_dump_size = 8192;
390 
391   if (out_buffer == nullptr) {
392     *out_size = max_dump_size;
393   } else {
394     std::string s {};
395     for (int id = HWC_DISPLAY_PRIMARY; id <= HWC_DISPLAY_VIRTUAL; id++) {
396       SCOPE_LOCK(locker_[id]);
397       if (hwc_session->hwc_display_[id]) {
398         s += hwc_session->hwc_display_[id]->Dump();
399       }
400     }
401     auto copied = s.copy(out_buffer, std::min(s.size(), max_dump_size), 0);
402     *out_size = UINT32(copied);
403   }
404 }
405 
GetActiveConfig(hwc2_device_t * device,hwc2_display_t display,hwc2_config_t * out_config)406 static int32_t GetActiveConfig(hwc2_device_t *device, hwc2_display_t display,
407                                hwc2_config_t *out_config) {
408   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetActiveConfig, out_config);
409 }
410 
GetChangedCompositionTypes(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_elements,hwc2_layer_t * out_layers,int32_t * out_types)411 static int32_t GetChangedCompositionTypes(hwc2_device_t *device, hwc2_display_t display,
412                                           uint32_t *out_num_elements, hwc2_layer_t *out_layers,
413                                           int32_t *out_types) {
414   // null_ptr check only for out_num_elements, as out_layers and out_types can be null.
415   if (!out_num_elements) {
416     return  HWC2_ERROR_BAD_PARAMETER;
417   }
418   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetChangedCompositionTypes,
419                                          out_num_elements, out_layers, out_types);
420 }
421 
GetClientTargetSupport(hwc2_device_t * device,hwc2_display_t display,uint32_t width,uint32_t height,int32_t format,int32_t dataspace)422 static int32_t GetClientTargetSupport(hwc2_device_t *device, hwc2_display_t display, uint32_t width,
423                                       uint32_t height, int32_t format, int32_t dataspace) {
424   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetClientTargetSupport,
425                                          width, height, format, dataspace);
426 }
427 
GetColorModes(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_modes,int32_t * int_out_modes)428 static int32_t GetColorModes(hwc2_device_t *device, hwc2_display_t display, uint32_t *out_num_modes,
429                              int32_t /*android_color_mode_t*/ *int_out_modes) {
430   auto out_modes = reinterpret_cast<android_color_mode_t *>(int_out_modes);
431   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetColorModes, out_num_modes,
432                                          out_modes);
433 }
434 
GetDisplayAttribute(hwc2_device_t * device,hwc2_display_t display,hwc2_config_t config,int32_t int_attribute,int32_t * out_value)435 static int32_t GetDisplayAttribute(hwc2_device_t *device, hwc2_display_t display,
436                                    hwc2_config_t config, int32_t int_attribute,
437                                    int32_t *out_value) {
438   auto attribute = static_cast<HWC2::Attribute>(int_attribute);
439   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayAttribute, config,
440                                          attribute, out_value);
441 }
442 
GetDisplayConfigs(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_configs,hwc2_config_t * out_configs)443 static int32_t GetDisplayConfigs(hwc2_device_t *device, hwc2_display_t display,
444                                  uint32_t *out_num_configs, hwc2_config_t *out_configs) {
445   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayConfigs,
446                                          out_num_configs, out_configs);
447 }
448 
GetDisplayName(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_size,char * out_name)449 static int32_t GetDisplayName(hwc2_device_t *device, hwc2_display_t display, uint32_t *out_size,
450                               char *out_name) {
451   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayName, out_size,
452                                          out_name);
453 }
454 
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)455 static int32_t GetDisplayRequests(hwc2_device_t *device, hwc2_display_t display,
456                                   int32_t *out_display_requests, uint32_t *out_num_elements,
457                                   hwc2_layer_t *out_layers, int32_t *out_layer_requests) {
458   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayRequests,
459                                          out_display_requests, out_num_elements, out_layers,
460                                          out_layer_requests);
461 }
462 
GetDisplayType(hwc2_device_t * device,hwc2_display_t display,int32_t * out_type)463 static int32_t GetDisplayType(hwc2_device_t *device, hwc2_display_t display, int32_t *out_type) {
464   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayType, out_type);
465 }
466 
GetDozeSupport(hwc2_device_t * device,hwc2_display_t display,int32_t * out_support)467 static int32_t GetDozeSupport(hwc2_device_t *device, hwc2_display_t display, int32_t *out_support) {
468   if (display == HWC_DISPLAY_PRIMARY) {
469     *out_support = 1;
470   } else {
471     // TODO(user): Port over connect_display_ from HWC1
472     // Return no error for connected displays
473     *out_support = 0;
474     return HWC2_ERROR_BAD_DISPLAY;
475   }
476   return HWC2_ERROR_NONE;
477 }
478 
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)479 static int32_t GetHdrCapabilities(hwc2_device_t* device, hwc2_display_t display,
480                                   uint32_t* out_num_types, int32_t* out_types,
481                                   float* out_max_luminance, float* out_max_average_luminance,
482                                   float* out_min_luminance) {
483   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetHdrCapabilities,
484                                          out_num_types, out_types, out_max_luminance,
485                                          out_max_average_luminance, out_min_luminance);
486 }
487 
GetMaxVirtualDisplayCount(hwc2_device_t * device)488 static uint32_t GetMaxVirtualDisplayCount(hwc2_device_t *device) {
489   char property[PROPERTY_VALUE_MAX];
490   property_get(WRITEBACK_SUPPORTED, property, "1");
491   return (uint32_t) atoi(property);
492 }
493 
GetReleaseFences(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_elements,hwc2_layer_t * out_layers,int32_t * out_fences)494 static int32_t GetReleaseFences(hwc2_device_t *device, hwc2_display_t display,
495                                 uint32_t *out_num_elements, hwc2_layer_t *out_layers,
496                                 int32_t *out_fences) {
497   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetReleaseFences,
498                                          out_num_elements, out_layers, out_fences);
499 }
500 
PresentDisplay(hwc2_device_t * device,hwc2_display_t display,int32_t * out_retire_fence)501 int32_t HWCSession::PresentDisplay(hwc2_device_t *device, hwc2_display_t display,
502                                    int32_t *out_retire_fence) {
503   HWCSession *hwc_session = static_cast<HWCSession *>(device);
504   bool notify_hotplug = false;
505   auto status = HWC2::Error::BadDisplay;
506   DTRACE_SCOPED();
507 
508   if (display >= HWC_NUM_DISPLAY_TYPES) {
509     return HWC2_ERROR_BAD_DISPLAY;
510   }
511 
512   {
513     SEQUENCE_EXIT_SCOPE_LOCK(locker_[display]);
514     if (!device) {
515       return HWC2_ERROR_BAD_DISPLAY;
516     }
517 
518     // TODO(user): Handle virtual display/HDMI concurrency
519     if (hwc_session->hwc_display_[display]) {
520       status = hwc_session->hwc_display_[display]->Present(out_retire_fence);
521       // This is only indicative of how many times SurfaceFlinger posts
522       // frames to the display.
523       CALC_FPS();
524     }
525   }
526 
527   if (status != HWC2::Error::None && status != HWC2::Error::NotValidated) {
528     SEQUENCE_CANCEL_SCOPE_LOCK(locker_[display]);
529   }
530 
531   // Handle Pending external display connection
532   if (hwc_session->external_pending_connect_ && (display == HWC_DISPLAY_PRIMARY)) {
533     Locker::ScopeLock lock_e(locker_[HWC_DISPLAY_EXTERNAL]);
534     Locker::ScopeLock lock_v(locker_[HWC_DISPLAY_VIRTUAL]);
535 
536     if (!hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL]) {
537       DLOGD("Process pending external display connection");
538       hwc_session->ConnectDisplay(HWC_DISPLAY_EXTERNAL);
539       hwc_session->external_pending_connect_ = false;
540       notify_hotplug = true;
541     }
542   }
543 
544   if (notify_hotplug) {
545     hwc_session->HotPlug(HWC_DISPLAY_EXTERNAL, HWC2::Connection::Connected);
546   }
547 
548   return INT32(status);
549 }
550 
RegisterCallback(hwc2_device_t * device,int32_t descriptor,hwc2_callback_data_t callback_data,hwc2_function_pointer_t pointer)551 int32_t HWCSession::RegisterCallback(hwc2_device_t *device, int32_t descriptor,
552                                      hwc2_callback_data_t callback_data,
553                                      hwc2_function_pointer_t pointer) {
554   if (!device) {
555     return HWC2_ERROR_BAD_PARAMETER;
556   }
557   HWCSession *hwc_session = static_cast<HWCSession *>(device);
558   auto error =  HWC2::Error::BadDisplay;
559   {
560     SCOPE_LOCK(hwc_session->callbacks_lock_);
561     auto desc = static_cast<HWC2::Callback>(descriptor);
562     error = hwc_session->callbacks_.Register(desc, callback_data, pointer);
563     hwc_session->callbacks_lock_.Broadcast();
564     DLOGD("%s callback: %s", pointer ? "Registering" : "Deregistering", to_string(desc).c_str());
565   }
566   if (descriptor == HWC2_CALLBACK_HOTPLUG) {
567     if (hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY]) {
568       hwc_session->callbacks_.Hotplug(HWC_DISPLAY_PRIMARY, HWC2::Connection::Connected);
569     }
570   }
571   hwc_session->need_invalidate_ = false;
572   return INT32(error);
573 }
574 
SetActiveConfig(hwc2_device_t * device,hwc2_display_t display,hwc2_config_t config)575 static int32_t SetActiveConfig(hwc2_device_t *device, hwc2_display_t display,
576                                hwc2_config_t config) {
577   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetActiveConfig, config);
578 }
579 
SetClientTarget(hwc2_device_t * device,hwc2_display_t display,buffer_handle_t target,int32_t acquire_fence,int32_t dataspace,hwc_region_t damage)580 static int32_t SetClientTarget(hwc2_device_t *device, hwc2_display_t display,
581                                buffer_handle_t target, int32_t acquire_fence,
582                                int32_t dataspace, hwc_region_t damage) {
583   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetClientTarget, target,
584                                          acquire_fence, dataspace, damage);
585 }
586 
SetColorMode(hwc2_device_t * device,hwc2_display_t display,int32_t int_mode)587 int32_t HWCSession::SetColorMode(hwc2_device_t *device, hwc2_display_t display,
588                                  int32_t /*android_color_mode_t*/ int_mode) {
589   if (int_mode < HAL_COLOR_MODE_NATIVE || int_mode > HAL_COLOR_MODE_DISPLAY_P3) {
590     return HWC2_ERROR_BAD_PARAMETER;
591   }
592   auto mode = static_cast<android_color_mode_t>(int_mode);
593   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
594 }
595 
SetColorTransform(hwc2_device_t * device,hwc2_display_t display,const float * matrix,int32_t hint)596 int32_t HWCSession::SetColorTransform(hwc2_device_t *device, hwc2_display_t display,
597                                       const float *matrix,
598                                       int32_t /*android_color_transform_t*/ hint) {
599   if (!matrix || hint < HAL_COLOR_TRANSFORM_IDENTITY ||
600        hint > HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA) {
601     return HWC2_ERROR_BAD_PARAMETER;
602   }
603   android_color_transform_t transform_hint = static_cast<android_color_transform_t>(hint);
604   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorTransform, matrix,
605                                          transform_hint);
606 }
607 
SetCursorPosition(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t x,int32_t y)608 static int32_t SetCursorPosition(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
609                                  int32_t x, int32_t y) {
610   auto status = INT32(HWC2::Error::None);
611   status = HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetCursorPosition,
612                                            layer, x, y);
613   if (status == INT32(HWC2::Error::None)) {
614     // Update cursor position
615     HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetCursorPosition, x, y);
616   }
617   return status;
618 }
619 
SetLayerBlendMode(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t int_mode)620 static int32_t SetLayerBlendMode(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
621                                  int32_t int_mode) {
622   if (int_mode < HWC2_BLEND_MODE_INVALID || int_mode > HWC2_BLEND_MODE_COVERAGE) {
623     return HWC2_ERROR_BAD_PARAMETER;
624   }
625   auto mode = static_cast<HWC2::BlendMode>(int_mode);
626   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerBlendMode, mode);
627 }
628 
SetLayerBuffer(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,buffer_handle_t buffer,int32_t acquire_fence)629 static int32_t SetLayerBuffer(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
630                               buffer_handle_t buffer, int32_t acquire_fence) {
631   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerBuffer, buffer,
632                                        acquire_fence);
633 }
634 
SetLayerColor(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_color_t color)635 static int32_t SetLayerColor(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
636                              hwc_color_t color) {
637   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerColor, color);
638 }
639 
SetLayerCompositionType(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t int_type)640 static int32_t SetLayerCompositionType(hwc2_device_t *device, hwc2_display_t display,
641                                        hwc2_layer_t layer, int32_t int_type) {
642   auto type = static_cast<HWC2::Composition>(int_type);
643   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerCompositionType,
644                                        type);
645 }
646 
SetLayerDataspace(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t dataspace)647 static int32_t SetLayerDataspace(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
648                                  int32_t dataspace) {
649   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerDataspace,
650                                        dataspace);
651 }
652 
SetLayerDisplayFrame(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_rect_t frame)653 static int32_t SetLayerDisplayFrame(hwc2_device_t *device, hwc2_display_t display,
654                                     hwc2_layer_t layer, hwc_rect_t frame) {
655   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerDisplayFrame,
656                                        frame);
657 }
658 
SetLayerPlaneAlpha(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,float alpha)659 static int32_t SetLayerPlaneAlpha(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
660                                   float alpha) {
661   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerPlaneAlpha,
662                                        alpha);
663 }
664 
SetLayerSourceCrop(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_frect_t crop)665 static int32_t SetLayerSourceCrop(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
666                                   hwc_frect_t crop) {
667   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerSourceCrop, crop);
668 }
669 
SetLayerSurfaceDamage(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_region_t damage)670 static int32_t SetLayerSurfaceDamage(hwc2_device_t *device, hwc2_display_t display,
671                                      hwc2_layer_t layer, hwc_region_t damage) {
672   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerSurfaceDamage,
673                                        damage);
674 }
675 
SetLayerTransform(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t int_transform)676 static int32_t SetLayerTransform(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
677                                  int32_t int_transform) {
678   auto transform = static_cast<HWC2::Transform>(int_transform);
679   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerTransform,
680                                        transform);
681 }
682 
SetLayerVisibleRegion(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_region_t visible)683 static int32_t SetLayerVisibleRegion(hwc2_device_t *device, hwc2_display_t display,
684                                      hwc2_layer_t layer, hwc_region_t visible) {
685   return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerVisibleRegion,
686                                        visible);
687 }
688 
SetLayerZOrder(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,uint32_t z)689 static int32_t SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
690                               uint32_t z) {
691   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetLayerZOrder, layer, z);
692 }
693 
SetOutputBuffer(hwc2_device_t * device,hwc2_display_t display,buffer_handle_t buffer,int32_t releaseFence)694 int32_t HWCSession::SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
695                                     buffer_handle_t buffer, int32_t releaseFence) {
696   if (!device) {
697     return HWC2_ERROR_BAD_DISPLAY;
698   }
699 
700   if (display != HWC_DISPLAY_VIRTUAL) {
701     return HWC2_ERROR_UNSUPPORTED;
702   }
703 
704   SCOPE_LOCK(locker_[display]);
705   auto *hwc_session = static_cast<HWCSession *>(device);
706   if (hwc_session->hwc_display_[display]) {
707     auto vds = reinterpret_cast<HWCDisplayVirtual *>(hwc_session->hwc_display_[display]);
708     auto status = vds->SetOutputBuffer(buffer, releaseFence);
709     return INT32(status);
710   } else {
711     return HWC2_ERROR_BAD_DISPLAY;
712   }
713 }
714 
SetPowerMode(hwc2_device_t * device,hwc2_display_t display,int32_t int_mode)715 int32_t HWCSession::SetPowerMode(hwc2_device_t *device, hwc2_display_t display, int32_t int_mode) {
716   auto mode = static_cast<HWC2::PowerMode>(int_mode);
717   return CallDisplayFunction(device, display, &HWCDisplay::SetPowerMode, mode);
718 }
719 
SetVsyncEnabled(hwc2_device_t * device,hwc2_display_t display,int32_t int_enabled)720 static int32_t SetVsyncEnabled(hwc2_device_t *device, hwc2_display_t display, int32_t int_enabled) {
721   auto enabled = static_cast<HWC2::Vsync>(int_enabled);
722   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetVsyncEnabled, enabled);
723 }
724 
ValidateDisplay(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_types,uint32_t * out_num_requests)725 int32_t HWCSession::ValidateDisplay(hwc2_device_t *device, hwc2_display_t display,
726                                     uint32_t *out_num_types, uint32_t *out_num_requests) {
727   DTRACE_SCOPED();
728   HWCSession *hwc_session = static_cast<HWCSession *>(device);
729   if (!device) {
730     return HWC2_ERROR_BAD_DISPLAY;
731   }
732 
733   // TODO(user): Handle secure session, handle QDCM solid fill
734   // Handle external_pending_connect_ in CreateVirtualDisplay
735   auto status = HWC2::Error::BadDisplay;
736   {
737     SEQUENCE_ENTRY_SCOPE_LOCK(locker_[display]);
738     if (hwc_session->hwc_display_[display]) {
739       if (display == HWC_DISPLAY_PRIMARY) {
740         // TODO(user): This can be moved to HWCDisplayPrimary
741         if (hwc_session->reset_panel_) {
742           DLOGW("panel is in bad state, resetting the panel");
743           hwc_session->ResetPanel();
744         }
745 
746         if (hwc_session->need_invalidate_) {
747           hwc_session->Refresh(display);
748           hwc_session->need_invalidate_ = false;
749         }
750 
751         if (hwc_session->color_mgr_) {
752           hwc_session->color_mgr_->SetColorModeDetailEnhancer(hwc_session->hwc_display_[display]);
753         }
754       }
755 
756       status = hwc_session->hwc_display_[display]->Validate(out_num_types, out_num_requests);
757     }
758   }
759 
760   // Sequence locking currently begins on Validate, so cancel the sequence lock on failures
761   if (status != HWC2::Error::None && status != HWC2::Error::HasChanges) {
762     SEQUENCE_CANCEL_SCOPE_LOCK(locker_[display]);
763   }
764 
765   return INT32(status);
766 }
767 
GetFunction(struct hwc2_device * device,int32_t int_descriptor)768 hwc2_function_pointer_t HWCSession::GetFunction(struct hwc2_device *device,
769                                                 int32_t int_descriptor) {
770   auto descriptor = static_cast<HWC2::FunctionDescriptor>(int_descriptor);
771 
772   switch (descriptor) {
773     case HWC2::FunctionDescriptor::AcceptDisplayChanges:
774       return AsFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(HWCSession::AcceptDisplayChanges);
775     case HWC2::FunctionDescriptor::CreateLayer:
776       return AsFP<HWC2_PFN_CREATE_LAYER>(CreateLayer);
777     case HWC2::FunctionDescriptor::CreateVirtualDisplay:
778       return AsFP<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(HWCSession::CreateVirtualDisplay);
779     case HWC2::FunctionDescriptor::DestroyLayer:
780       return AsFP<HWC2_PFN_DESTROY_LAYER>(DestroyLayer);
781     case HWC2::FunctionDescriptor::DestroyVirtualDisplay:
782       return AsFP<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(HWCSession::DestroyVirtualDisplay);
783     case HWC2::FunctionDescriptor::Dump:
784       return AsFP<HWC2_PFN_DUMP>(HWCSession::Dump);
785     case HWC2::FunctionDescriptor::GetActiveConfig:
786       return AsFP<HWC2_PFN_GET_ACTIVE_CONFIG>(GetActiveConfig);
787     case HWC2::FunctionDescriptor::GetChangedCompositionTypes:
788       return AsFP<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(GetChangedCompositionTypes);
789     case HWC2::FunctionDescriptor::GetClientTargetSupport:
790       return AsFP<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(GetClientTargetSupport);
791     case HWC2::FunctionDescriptor::GetColorModes:
792       return AsFP<HWC2_PFN_GET_COLOR_MODES>(GetColorModes);
793     case HWC2::FunctionDescriptor::GetDisplayAttribute:
794       return AsFP<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(GetDisplayAttribute);
795     case HWC2::FunctionDescriptor::GetDisplayConfigs:
796       return AsFP<HWC2_PFN_GET_DISPLAY_CONFIGS>(GetDisplayConfigs);
797     case HWC2::FunctionDescriptor::GetDisplayName:
798       return AsFP<HWC2_PFN_GET_DISPLAY_NAME>(GetDisplayName);
799     case HWC2::FunctionDescriptor::GetDisplayRequests:
800       return AsFP<HWC2_PFN_GET_DISPLAY_REQUESTS>(GetDisplayRequests);
801     case HWC2::FunctionDescriptor::GetDisplayType:
802       return AsFP<HWC2_PFN_GET_DISPLAY_TYPE>(GetDisplayType);
803     case HWC2::FunctionDescriptor::GetHdrCapabilities:
804       return AsFP<HWC2_PFN_GET_HDR_CAPABILITIES>(GetHdrCapabilities);
805     case HWC2::FunctionDescriptor::GetDozeSupport:
806       return AsFP<HWC2_PFN_GET_DOZE_SUPPORT>(GetDozeSupport);
807     case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount:
808       return AsFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(GetMaxVirtualDisplayCount);
809     case HWC2::FunctionDescriptor::GetReleaseFences:
810       return AsFP<HWC2_PFN_GET_RELEASE_FENCES>(GetReleaseFences);
811     case HWC2::FunctionDescriptor::PresentDisplay:
812       return AsFP<HWC2_PFN_PRESENT_DISPLAY>(PresentDisplay);
813     case HWC2::FunctionDescriptor::RegisterCallback:
814       return AsFP<HWC2_PFN_REGISTER_CALLBACK>(RegisterCallback);
815     case HWC2::FunctionDescriptor::SetActiveConfig:
816       return AsFP<HWC2_PFN_SET_ACTIVE_CONFIG>(SetActiveConfig);
817     case HWC2::FunctionDescriptor::SetClientTarget:
818       return AsFP<HWC2_PFN_SET_CLIENT_TARGET>(SetClientTarget);
819     case HWC2::FunctionDescriptor::SetColorMode:
820       return AsFP<HWC2_PFN_SET_COLOR_MODE>(SetColorMode);
821     case HWC2::FunctionDescriptor::SetColorTransform:
822       return AsFP<HWC2_PFN_SET_COLOR_TRANSFORM>(SetColorTransform);
823     case HWC2::FunctionDescriptor::SetCursorPosition:
824       return AsFP<HWC2_PFN_SET_CURSOR_POSITION>(SetCursorPosition);
825     case HWC2::FunctionDescriptor::SetLayerBlendMode:
826       return AsFP<HWC2_PFN_SET_LAYER_BLEND_MODE>(SetLayerBlendMode);
827     case HWC2::FunctionDescriptor::SetLayerBuffer:
828       return AsFP<HWC2_PFN_SET_LAYER_BUFFER>(SetLayerBuffer);
829     case HWC2::FunctionDescriptor::SetLayerColor:
830       return AsFP<HWC2_PFN_SET_LAYER_COLOR>(SetLayerColor);
831     case HWC2::FunctionDescriptor::SetLayerCompositionType:
832       return AsFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(SetLayerCompositionType);
833     case HWC2::FunctionDescriptor::SetLayerDataspace:
834       return AsFP<HWC2_PFN_SET_LAYER_DATASPACE>(SetLayerDataspace);
835     case HWC2::FunctionDescriptor::SetLayerDisplayFrame:
836       return AsFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(SetLayerDisplayFrame);
837     case HWC2::FunctionDescriptor::SetLayerPlaneAlpha:
838       return AsFP<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(SetLayerPlaneAlpha);
839     // Sideband stream is not supported
840     // case HWC2::FunctionDescriptor::SetLayerSidebandStream:
841     case HWC2::FunctionDescriptor::SetLayerSourceCrop:
842       return AsFP<HWC2_PFN_SET_LAYER_SOURCE_CROP>(SetLayerSourceCrop);
843     case HWC2::FunctionDescriptor::SetLayerSurfaceDamage:
844       return AsFP<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(SetLayerSurfaceDamage);
845     case HWC2::FunctionDescriptor::SetLayerTransform:
846       return AsFP<HWC2_PFN_SET_LAYER_TRANSFORM>(SetLayerTransform);
847     case HWC2::FunctionDescriptor::SetLayerVisibleRegion:
848       return AsFP<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(SetLayerVisibleRegion);
849     case HWC2::FunctionDescriptor::SetLayerZOrder:
850       return AsFP<HWC2_PFN_SET_LAYER_Z_ORDER>(SetLayerZOrder);
851     case HWC2::FunctionDescriptor::SetOutputBuffer:
852       return AsFP<HWC2_PFN_SET_OUTPUT_BUFFER>(SetOutputBuffer);
853     case HWC2::FunctionDescriptor::SetPowerMode:
854       return AsFP<HWC2_PFN_SET_POWER_MODE>(SetPowerMode);
855     case HWC2::FunctionDescriptor::SetVsyncEnabled:
856       return AsFP<HWC2_PFN_SET_VSYNC_ENABLED>(SetVsyncEnabled);
857     case HWC2::FunctionDescriptor::ValidateDisplay:
858       return AsFP<HWC2_PFN_VALIDATE_DISPLAY>(HWCSession::ValidateDisplay);
859     default:
860       DLOGD("Unknown/Unimplemented function descriptor: %d (%s)", int_descriptor,
861             to_string(descriptor).c_str());
862       return nullptr;
863   }
864   return nullptr;
865 }
866 
867 // TODO(user): handle locking
868 
CreateVirtualDisplayObject(uint32_t width,uint32_t height,int32_t * format)869 HWC2::Error HWCSession::CreateVirtualDisplayObject(uint32_t width, uint32_t height,
870                                                    int32_t *format) {
871   if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
872     return HWC2::Error::NoResources;
873   }
874   auto status = HWCDisplayVirtual::Create(core_intf_, &buffer_allocator_, &callbacks_, width,
875                                           height, format, &hwc_display_[HWC_DISPLAY_VIRTUAL]);
876   // TODO(user): validate width and height support
877   if (status)
878     return HWC2::Error::Unsupported;
879 
880   return HWC2::Error::None;
881 }
882 
ConnectDisplay(int disp)883 int32_t HWCSession::ConnectDisplay(int disp) {
884   DLOGI("Display = %d", disp);
885 
886   int status = 0;
887   uint32_t primary_width = 0;
888   uint32_t primary_height = 0;
889 
890   hwc_display_[HWC_DISPLAY_PRIMARY]->GetFrameBufferResolution(&primary_width, &primary_height);
891 
892   if (disp == HWC_DISPLAY_EXTERNAL) {
893     status = CreateExternalDisplay(disp, primary_width, primary_height);
894   } else {
895     DLOGE("Invalid display type");
896     return -1;
897   }
898 
899   if (!status) {
900     hwc_display_[disp]->SetSecureDisplay(secure_display_active_);
901   }
902 
903   return status;
904 }
905 
DisconnectDisplay(int disp)906 int HWCSession::DisconnectDisplay(int disp) {
907   DLOGI("Display = %d", disp);
908 
909   if (disp == HWC_DISPLAY_EXTERNAL) {
910     HWCDisplayExternal::Destroy(hwc_display_[disp]);
911   } else if (disp == HWC_DISPLAY_VIRTUAL) {
912     HWCDisplayVirtual::Destroy(hwc_display_[disp]);
913   } else {
914     DLOGE("Invalid display type");
915     return -1;
916   }
917 
918   hwc_display_[disp] = NULL;
919 
920   return 0;
921 }
922 
923 // Qclient methods
notifyCallback(uint32_t command,const android::Parcel * input_parcel,android::Parcel * output_parcel)924 android::status_t HWCSession::notifyCallback(uint32_t command, const android::Parcel *input_parcel,
925                                              android::Parcel *output_parcel) {
926   android::status_t status = 0;
927 
928   switch (command) {
929     case qService::IQService::DYNAMIC_DEBUG:
930       DynamicDebug(input_parcel);
931       break;
932 
933     case qService::IQService::SCREEN_REFRESH:
934       refreshScreen();
935       break;
936 
937     case qService::IQService::SET_IDLE_TIMEOUT:
938       setIdleTimeout(UINT32(input_parcel->readInt32()));
939       break;
940 
941     case qService::IQService::SET_FRAME_DUMP_CONFIG:
942       SetFrameDumpConfig(input_parcel);
943       break;
944 
945     case qService::IQService::SET_MAX_PIPES_PER_MIXER:
946       status = SetMaxMixerStages(input_parcel);
947       break;
948 
949     case qService::IQService::SET_DISPLAY_MODE:
950       status = SetDisplayMode(input_parcel);
951       break;
952 
953     case qService::IQService::SET_SECONDARY_DISPLAY_STATUS: {
954         int disp_id = INT(input_parcel->readInt32());
955         HWCDisplay::DisplayStatus disp_status =
956               static_cast<HWCDisplay::DisplayStatus>(input_parcel->readInt32());
957         status = SetSecondaryDisplayStatus(disp_id, disp_status);
958         output_parcel->writeInt32(status);
959       }
960       break;
961 
962     case qService::IQService::CONFIGURE_DYN_REFRESH_RATE:
963       status = ConfigureRefreshRate(input_parcel);
964       break;
965 
966     case qService::IQService::SET_VIEW_FRAME:
967       break;
968 
969     case qService::IQService::TOGGLE_SCREEN_UPDATES: {
970         int32_t input = input_parcel->readInt32();
971         status = toggleScreenUpdate(input == 1);
972         output_parcel->writeInt32(status);
973       }
974       break;
975 
976     case qService::IQService::QDCM_SVC_CMDS:
977       status = QdcmCMDHandler(input_parcel, output_parcel);
978       break;
979 
980     case qService::IQService::MIN_HDCP_ENCRYPTION_LEVEL_CHANGED: {
981         int disp_id = input_parcel->readInt32();
982         uint32_t min_enc_level = UINT32(input_parcel->readInt32());
983         status = MinHdcpEncryptionLevelChanged(disp_id, min_enc_level);
984         output_parcel->writeInt32(status);
985       }
986       break;
987 
988     case qService::IQService::CONTROL_PARTIAL_UPDATE: {
989         int disp_id = input_parcel->readInt32();
990         uint32_t enable = UINT32(input_parcel->readInt32());
991         status = ControlPartialUpdate(disp_id, enable == 1);
992         output_parcel->writeInt32(status);
993       }
994       break;
995 
996     case qService::IQService::SET_ACTIVE_CONFIG: {
997         uint32_t config = UINT32(input_parcel->readInt32());
998         int disp_id = input_parcel->readInt32();
999         status = SetActiveConfigIndex(disp_id, config);
1000       }
1001       break;
1002 
1003     case qService::IQService::GET_ACTIVE_CONFIG: {
1004         int disp_id = input_parcel->readInt32();
1005         uint32_t config = 0;
1006         status = GetActiveConfigIndex(disp_id, &config);
1007         output_parcel->writeInt32(INT(config));
1008       }
1009       break;
1010 
1011     case qService::IQService::GET_CONFIG_COUNT: {
1012         int disp_id = input_parcel->readInt32();
1013         uint32_t count = 0;
1014         status = GetConfigCount(disp_id, &count);
1015         output_parcel->writeInt32(INT(count));
1016       }
1017       break;
1018 
1019     case qService::IQService::GET_DISPLAY_ATTRIBUTES_FOR_CONFIG:
1020       status = HandleGetDisplayAttributesForConfig(input_parcel, output_parcel);
1021       break;
1022 
1023     case qService::IQService::GET_PANEL_BRIGHTNESS: {
1024         int level = 0;
1025         status = GetPanelBrightness(&level);
1026         output_parcel->writeInt32(level);
1027       }
1028       break;
1029 
1030     case qService::IQService::SET_PANEL_BRIGHTNESS: {
1031         uint32_t level = UINT32(input_parcel->readInt32());
1032         status = setPanelBrightness(level);
1033         output_parcel->writeInt32(status);
1034       }
1035       break;
1036 
1037     case qService::IQService::GET_DISPLAY_VISIBLE_REGION:
1038       status = GetVisibleDisplayRect(input_parcel, output_parcel);
1039       break;
1040 
1041     case qService::IQService::SET_CAMERA_STATUS: {
1042         uint32_t camera_status = UINT32(input_parcel->readInt32());
1043         status = setCameraLaunchStatus(camera_status);
1044       }
1045       break;
1046 
1047     case qService::IQService::GET_BW_TRANSACTION_STATUS: {
1048         bool state = true;
1049         status = DisplayBWTransactionPending(&state);
1050         output_parcel->writeInt32(state);
1051       }
1052       break;
1053 
1054     case qService::IQService::SET_LAYER_MIXER_RESOLUTION:
1055       status = SetMixerResolution(input_parcel);
1056       break;
1057 
1058     case qService::IQService::SET_COLOR_MODE:
1059       status = SetColorModeOverride(input_parcel);
1060       break;
1061 
1062     default:
1063       DLOGW("QService command = %d is not supported", command);
1064       return -EINVAL;
1065   }
1066 
1067   return status;
1068 }
1069 
HandleGetDisplayAttributesForConfig(const android::Parcel * input_parcel,android::Parcel * output_parcel)1070 android::status_t HWCSession::HandleGetDisplayAttributesForConfig(const android::Parcel
1071                                                                   *input_parcel,
1072                                                                   android::Parcel *output_parcel) {
1073   int config = input_parcel->readInt32();
1074   int dpy = input_parcel->readInt32();
1075   int error = android::BAD_VALUE;
1076   DisplayConfigVariableInfo display_attributes;
1077 
1078   if (dpy < HWC_DISPLAY_PRIMARY || dpy >= HWC_NUM_DISPLAY_TYPES || config < 0) {
1079     return android::BAD_VALUE;
1080   }
1081 
1082   SEQUENCE_WAIT_SCOPE_LOCK(locker_[dpy]);
1083   if (hwc_display_[dpy]) {
1084     error = hwc_display_[dpy]->GetDisplayAttributesForConfig(config, &display_attributes);
1085     if (error == 0) {
1086       output_parcel->writeInt32(INT(display_attributes.vsync_period_ns));
1087       output_parcel->writeInt32(INT(display_attributes.x_pixels));
1088       output_parcel->writeInt32(INT(display_attributes.y_pixels));
1089       output_parcel->writeFloat(display_attributes.x_dpi);
1090       output_parcel->writeFloat(display_attributes.y_dpi);
1091       output_parcel->writeInt32(0);  // Panel type, unsupported.
1092     }
1093   }
1094 
1095   return error;
1096 }
1097 
ConfigureRefreshRate(const android::Parcel * input_parcel)1098 android::status_t HWCSession::ConfigureRefreshRate(const android::Parcel *input_parcel) {
1099   SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1100 
1101   uint32_t operation = UINT32(input_parcel->readInt32());
1102   HWCDisplay *hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
1103 
1104   switch (operation) {
1105     case qdutils::DISABLE_METADATA_DYN_REFRESH_RATE:
1106       return hwc_display->Perform(HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, false);
1107 
1108     case qdutils::ENABLE_METADATA_DYN_REFRESH_RATE:
1109       return hwc_display->Perform(HWCDisplayPrimary::SET_METADATA_DYN_REFRESH_RATE, true);
1110 
1111     case qdutils::SET_BINDER_DYN_REFRESH_RATE: {
1112       uint32_t refresh_rate = UINT32(input_parcel->readInt32());
1113       return hwc_display->Perform(HWCDisplayPrimary::SET_BINDER_DYN_REFRESH_RATE, refresh_rate);
1114     }
1115 
1116     default:
1117       DLOGW("Invalid operation %d", operation);
1118       return -EINVAL;
1119   }
1120 
1121   return 0;
1122 }
1123 
SetDisplayMode(const android::Parcel * input_parcel)1124 android::status_t HWCSession::SetDisplayMode(const android::Parcel *input_parcel) {
1125   SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1126 
1127   uint32_t mode = UINT32(input_parcel->readInt32());
1128   return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(HWCDisplayPrimary::SET_DISPLAY_MODE, mode);
1129 }
1130 
SetMaxMixerStages(const android::Parcel * input_parcel)1131 android::status_t HWCSession::SetMaxMixerStages(const android::Parcel *input_parcel) {
1132   DisplayError error = kErrorNone;
1133   std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32());
1134   uint32_t max_mixer_stages = UINT32(input_parcel->readInt32());
1135 
1136   if (bit_mask_display_type[HWC_DISPLAY_PRIMARY]) {
1137     SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1138     if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
1139       error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetMaxMixerStages(max_mixer_stages);
1140       if (error != kErrorNone) {
1141         return -EINVAL;
1142       }
1143     }
1144   }
1145 
1146   if (bit_mask_display_type[HWC_DISPLAY_EXTERNAL]) {
1147     SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
1148     if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
1149       error = hwc_display_[HWC_DISPLAY_EXTERNAL]->SetMaxMixerStages(max_mixer_stages);
1150       if (error != kErrorNone) {
1151         return -EINVAL;
1152       }
1153     }
1154   }
1155 
1156   if (bit_mask_display_type[HWC_DISPLAY_VIRTUAL]) {
1157     SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_VIRTUAL]);
1158     if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
1159       error = hwc_display_[HWC_DISPLAY_VIRTUAL]->SetMaxMixerStages(max_mixer_stages);
1160       if (error != kErrorNone) {
1161         return -EINVAL;
1162       }
1163     }
1164   }
1165 
1166   return 0;
1167 }
1168 
SetFrameDumpConfig(const android::Parcel * input_parcel)1169 void HWCSession::SetFrameDumpConfig(const android::Parcel *input_parcel) {
1170   uint32_t frame_dump_count = UINT32(input_parcel->readInt32());
1171   std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32());
1172   uint32_t bit_mask_layer_type = UINT32(input_parcel->readInt32());
1173 
1174   if (bit_mask_display_type[HWC_DISPLAY_PRIMARY]) {
1175     SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1176     if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
1177       hwc_display_[HWC_DISPLAY_PRIMARY]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
1178     }
1179   }
1180 
1181   if (bit_mask_display_type[HWC_DISPLAY_EXTERNAL]) {
1182     SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
1183     if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
1184       hwc_display_[HWC_DISPLAY_EXTERNAL]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
1185     }
1186   }
1187 
1188   if (bit_mask_display_type[HWC_DISPLAY_VIRTUAL]) {
1189     SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_VIRTUAL]);
1190     if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
1191       hwc_display_[HWC_DISPLAY_VIRTUAL]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
1192     }
1193   }
1194 }
1195 
SetMixerResolution(const android::Parcel * input_parcel)1196 android::status_t HWCSession::SetMixerResolution(const android::Parcel *input_parcel) {
1197   DisplayError error = kErrorNone;
1198   uint32_t dpy = UINT32(input_parcel->readInt32());
1199 
1200   if (dpy != HWC_DISPLAY_PRIMARY) {
1201     DLOGI("Resoulution change not supported for this display %d", dpy);
1202     return -EINVAL;
1203   }
1204 
1205   SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1206   if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
1207     DLOGI("Primary display is not initialized");
1208     return -EINVAL;
1209   }
1210 
1211   uint32_t width = UINT32(input_parcel->readInt32());
1212   uint32_t height = UINT32(input_parcel->readInt32());
1213 
1214   error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetMixerResolution(width, height);
1215   if (error != kErrorNone) {
1216     return -EINVAL;
1217   }
1218 
1219   return 0;
1220 }
1221 
SetColorModeOverride(const android::Parcel * input_parcel)1222 android::status_t HWCSession::SetColorModeOverride(const android::Parcel *input_parcel) {
1223   auto display = static_cast<hwc2_display_t >(input_parcel->readInt32());
1224   auto mode = static_cast<android_color_mode_t>(input_parcel->readInt32());
1225   auto device = static_cast<hwc2_device_t *>(this);
1226 
1227   if (display >= HWC_NUM_DISPLAY_TYPES) {
1228     return -EINVAL;
1229   }
1230   auto err = CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
1231   if (err != HWC2_ERROR_NONE)
1232     return -EINVAL;
1233 
1234   return 0;
1235 }
1236 
DynamicDebug(const android::Parcel * input_parcel)1237 void HWCSession::DynamicDebug(const android::Parcel *input_parcel) {
1238   // TODO(user): Do we really need a lock here?
1239 
1240   int type = input_parcel->readInt32();
1241   bool enable = (input_parcel->readInt32() > 0);
1242   DLOGI("type = %d enable = %d", type, enable);
1243   int verbose_level = input_parcel->readInt32();
1244 
1245   switch (type) {
1246     case qService::IQService::DEBUG_ALL:
1247       HWCDebugHandler::DebugAll(enable, verbose_level);
1248       break;
1249 
1250     case qService::IQService::DEBUG_MDPCOMP:
1251       HWCDebugHandler::DebugStrategy(enable, verbose_level);
1252       HWCDebugHandler::DebugCompManager(enable, verbose_level);
1253       break;
1254 
1255     case qService::IQService::DEBUG_PIPE_LIFECYCLE:
1256       HWCDebugHandler::DebugResources(enable, verbose_level);
1257       break;
1258 
1259     case qService::IQService::DEBUG_DRIVER_CONFIG:
1260       HWCDebugHandler::DebugDriverConfig(enable, verbose_level);
1261       break;
1262 
1263     case qService::IQService::DEBUG_ROTATOR:
1264       HWCDebugHandler::DebugResources(enable, verbose_level);
1265       HWCDebugHandler::DebugDriverConfig(enable, verbose_level);
1266       HWCDebugHandler::DebugRotator(enable, verbose_level);
1267       break;
1268 
1269     case qService::IQService::DEBUG_QDCM:
1270       HWCDebugHandler::DebugQdcm(enable, verbose_level);
1271       break;
1272 
1273     case qService::IQService::DEBUG_SCALAR:
1274       HWCDebugHandler::DebugScalar(enable, verbose_level);
1275       break;
1276 
1277     case qService::IQService::DEBUG_CLIENT:
1278       HWCDebugHandler::DebugClient(enable, verbose_level);
1279       break;
1280 
1281     case qService::IQService::DEBUG_DISPLAY:
1282       HWCDebugHandler::DebugDisplay(enable, verbose_level);
1283       break;
1284 
1285     default:
1286       DLOGW("type = %d is not supported", type);
1287   }
1288 }
1289 
QdcmCMDHandler(const android::Parcel * input_parcel,android::Parcel * output_parcel)1290 android::status_t HWCSession::QdcmCMDHandler(const android::Parcel *input_parcel,
1291                                              android::Parcel *output_parcel) {
1292   int ret = 0;
1293   int32_t *brightness_value = NULL;
1294   uint32_t display_id(0);
1295   PPPendingParams pending_action;
1296   PPDisplayAPIPayload resp_payload, req_payload;
1297 
1298   if (!color_mgr_) {
1299     return -1;
1300   }
1301 
1302   pending_action.action = kNoAction;
1303   pending_action.params = NULL;
1304 
1305   // Read display_id, payload_size and payload from in_parcel.
1306   ret = HWCColorManager::CreatePayloadFromParcel(*input_parcel, &display_id, &req_payload);
1307   if (!ret) {
1308     if (HWC_DISPLAY_PRIMARY == display_id && hwc_display_[HWC_DISPLAY_PRIMARY])
1309       ret = hwc_display_[HWC_DISPLAY_PRIMARY]->ColorSVCRequestRoute(req_payload, &resp_payload,
1310                                                                     &pending_action);
1311 
1312     if (HWC_DISPLAY_EXTERNAL == display_id && hwc_display_[HWC_DISPLAY_EXTERNAL])
1313       ret = hwc_display_[HWC_DISPLAY_EXTERNAL]->ColorSVCRequestRoute(req_payload, &resp_payload,
1314                                                                      &pending_action);
1315   }
1316 
1317   if (ret || pending_action.action == kNoAction) {
1318     output_parcel->writeInt32(ret);  // first field in out parcel indicates return code.
1319     if (pending_action.action == kNoAction) {
1320       HWCColorManager::MarshallStructIntoParcel(resp_payload, output_parcel);
1321     }
1322     req_payload.DestroyPayload();
1323     resp_payload.DestroyPayload();
1324     return ret;
1325   }
1326 
1327 
1328   int32_t action = pending_action.action;
1329   int count = -1;
1330   bool reset_validate = true;
1331   while (action > 0) {
1332     count++;
1333     int32_t bit = (action & 1);
1334     action = action >> 1;
1335 
1336     if (!bit)
1337       continue;
1338 
1339     DLOGV_IF(kTagQDCM, "pending action = %d", BITMAP(count));
1340     switch (BITMAP(count)) {
1341       case kInvalidating:
1342         Refresh(HWC_DISPLAY_PRIMARY);
1343         reset_validate = !disable_skip_validate_;
1344         break;
1345       case kEnterQDCMMode:
1346         ret = color_mgr_->EnableQDCMMode(true, hwc_display_[HWC_DISPLAY_PRIMARY]);
1347         break;
1348       case kExitQDCMMode:
1349         ret = color_mgr_->EnableQDCMMode(false, hwc_display_[HWC_DISPLAY_PRIMARY]);
1350         break;
1351       case kApplySolidFill:
1352         ret = color_mgr_->SetSolidFill(pending_action.params,
1353                                             true, hwc_display_[HWC_DISPLAY_PRIMARY]);
1354         Refresh(HWC_DISPLAY_PRIMARY);
1355         break;
1356       case kDisableSolidFill:
1357         ret = color_mgr_->SetSolidFill(pending_action.params,
1358                                             false, hwc_display_[HWC_DISPLAY_PRIMARY]);
1359         Refresh(HWC_DISPLAY_PRIMARY);
1360         break;
1361       case kSetPanelBrightness:
1362         brightness_value = reinterpret_cast<int32_t *>(resp_payload.payload);
1363         if (brightness_value == NULL) {
1364           DLOGE("Brightness value is Null");
1365           return -EINVAL;
1366         }
1367         if (HWC_DISPLAY_PRIMARY == display_id)
1368           ret = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(*brightness_value);
1369         break;
1370       case kEnableFrameCapture:
1371         ret = color_mgr_->SetFrameCapture(pending_action.params, true,
1372                                         hwc_display_[HWC_DISPLAY_PRIMARY]);
1373         Refresh(HWC_DISPLAY_PRIMARY);
1374         break;
1375       case kDisableFrameCapture:
1376         ret = color_mgr_->SetFrameCapture(pending_action.params, false,
1377                                         hwc_display_[HWC_DISPLAY_PRIMARY]);
1378         break;
1379       case kConfigureDetailedEnhancer:
1380         ret = color_mgr_->SetDetailedEnhancer(pending_action.params,
1381                                               hwc_display_[HWC_DISPLAY_PRIMARY]);
1382         Refresh(HWC_DISPLAY_PRIMARY);
1383         break;
1384       case kModeSet:
1385         ret = static_cast<int>
1386                  (hwc_display_[HWC_DISPLAY_PRIMARY]->RestoreColorTransform());
1387         Refresh(HWC_DISPLAY_PRIMARY);
1388         break;
1389       case kNoAction:
1390         break;
1391       default:
1392         DLOGW("Invalid pending action = %d!", pending_action.action);
1393         break;
1394     }
1395   }
1396   // for display API getter case, marshall returned params into out_parcel.
1397   output_parcel->writeInt32(ret);
1398   HWCColorManager::MarshallStructIntoParcel(resp_payload, output_parcel);
1399   req_payload.DestroyPayload();
1400   resp_payload.DestroyPayload();
1401   if (reset_validate) {
1402     hwc_display_[display_id]->ResetValidation();
1403   }
1404 
1405   return (ret ? -EINVAL : 0);
1406 }
1407 
UEventHandler(const char * uevent_data,int length)1408 void HWCSession::UEventHandler(const char *uevent_data, int length) {
1409   if (!strcasecmp(uevent_data, HWC_UEVENT_SWITCH_HDMI)) {
1410     DLOGI("Uevent HDMI = %s", uevent_data);
1411     int connected = GetEventValue(uevent_data, length, "SWITCH_STATE=");
1412     if (connected >= 0) {
1413       DLOGI("HDMI = %s", connected ? "connected" : "disconnected");
1414       if (HotPlugHandler(connected) == -1) {
1415         DLOGE("Failed handling Hotplug = %s", connected ? "connected" : "disconnected");
1416       }
1417     }
1418   } else if (!strcasecmp(uevent_data, HWC_UEVENT_GRAPHICS_FB0)) {
1419     DLOGI("Uevent FB0 = %s", uevent_data);
1420     int panel_reset = GetEventValue(uevent_data, length, "PANEL_ALIVE=");
1421     if (panel_reset == 0) {
1422       Refresh(0);
1423       reset_panel_ = true;
1424     }
1425   }
1426 }
1427 
GetEventValue(const char * uevent_data,int length,const char * event_info)1428 int HWCSession::GetEventValue(const char *uevent_data, int length, const char *event_info) {
1429   const char *iterator_str = uevent_data;
1430   while (((iterator_str - uevent_data) <= length) && (*iterator_str)) {
1431     const char *pstr = strstr(iterator_str, event_info);
1432     if (pstr != NULL) {
1433       return (atoi(iterator_str + strlen(event_info)));
1434     }
1435     iterator_str += strlen(iterator_str) + 1;
1436   }
1437 
1438   return -1;
1439 }
1440 
ResetPanel()1441 void HWCSession::ResetPanel() {
1442   HWC2::Error status;
1443 
1444   DLOGI("Powering off primary");
1445   status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(HWC2::PowerMode::Off);
1446   if (status != HWC2::Error::None) {
1447     DLOGE("power-off on primary failed with error = %d", status);
1448   }
1449 
1450   DLOGI("Restoring power mode on primary");
1451   HWC2::PowerMode mode = hwc_display_[HWC_DISPLAY_PRIMARY]->GetLastPowerMode();
1452   status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(mode);
1453   if (status != HWC2::Error::None) {
1454     DLOGE("Setting power mode = %d on primary failed with error = %d", mode, status);
1455   }
1456 
1457   status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetVsyncEnabled(HWC2::Vsync::Enable);
1458   if (status != HWC2::Error::None) {
1459     DLOGE("enabling vsync failed for primary with error = %d", status);
1460   }
1461 
1462   reset_panel_ = false;
1463 }
1464 
HotPlugHandler(bool connected)1465 int HWCSession::HotPlugHandler(bool connected) {
1466   int status = 0;
1467   bool notify_hotplug = false;
1468 
1469   // To prevent sending events to client while a lock is held, acquire scope locks only within
1470   // below scope so that those get automatically unlocked after the scope ends.
1471   do {
1472     // If HDMI is primary but not created yet (first time), create it and notify surfaceflinger.
1473     //    if it is already created, but got disconnected/connected again,
1474     //    just toggle display status and do not notify surfaceflinger.
1475     // If HDMI is not primary, create/destroy external display normally.
1476     if (hdmi_is_primary_) {
1477       SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1478       if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
1479         status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetState(connected);
1480       } else {
1481         status = CreateExternalDisplay(HWC_DISPLAY_PRIMARY);
1482         notify_hotplug = true;
1483       }
1484 
1485       break;
1486     }
1487 
1488     {
1489       SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
1490       // Primary display must be connected for HDMI as secondary cases.
1491       if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
1492         DLOGE("Primary display is not connected.");
1493         return -1;
1494       }
1495     }
1496 
1497     if (connected) {
1498       SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
1499       Locker::ScopeLock lock_v(locker_[HWC_DISPLAY_VIRTUAL]);
1500       // Connect external display if virtual display is not connected.
1501       // Else, defer external display connection and process it when virtual display
1502       // tears down; Do not notify SurfaceFlinger since connection is deferred now.
1503       if (!hwc_display_[HWC_DISPLAY_VIRTUAL]) {
1504         status = ConnectDisplay(HWC_DISPLAY_EXTERNAL);
1505         if (status) {
1506           return status;
1507         }
1508         notify_hotplug = true;
1509       } else {
1510         DLOGI("Virtual display is connected, pending connection");
1511         external_pending_connect_ = true;
1512       }
1513     } else {
1514       SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
1515       // Do not return error if external display is not in connected status.
1516       // Due to virtual display concurrency, external display connection might be still pending
1517       // but hdmi got disconnected before pending connection could be processed.
1518       if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
1519         status = DisconnectDisplay(HWC_DISPLAY_EXTERNAL);
1520         notify_hotplug = true;
1521       }
1522       external_pending_connect_ = false;
1523     }
1524   } while (0);
1525 
1526   if (connected) {
1527     Refresh(0);
1528 
1529     if (!hdmi_is_primary_) {
1530       // wait for sufficient time to ensure sufficient resources are available to process new
1531       // new display connection.
1532       uint32_t vsync_period = UINT32(GetVsyncPeriod(HWC_DISPLAY_PRIMARY));
1533       usleep(vsync_period * 2 / 1000);
1534     }
1535   }
1536 
1537   // notify client
1538   if (notify_hotplug) {
1539     HotPlug(hdmi_is_primary_ ? HWC_DISPLAY_PRIMARY : HWC_DISPLAY_EXTERNAL,
1540             connected ? HWC2::Connection::Connected : HWC2::Connection::Disconnected);
1541   }
1542 
1543   qservice_->onHdmiHotplug(INT(connected));
1544 
1545   return 0;
1546 }
1547 
GetVsyncPeriod(int disp)1548 int HWCSession::GetVsyncPeriod(int disp) {
1549   SCOPE_LOCK(locker_[disp]);
1550   // default value
1551   int32_t vsync_period = 1000000000l / 60;
1552   auto attribute = HWC2::Attribute::VsyncPeriod;
1553 
1554   if (hwc_display_[disp]) {
1555     hwc_display_[disp]->GetDisplayAttribute(0, attribute, &vsync_period);
1556   }
1557 
1558   return vsync_period;
1559 }
1560 
GetVisibleDisplayRect(const android::Parcel * input_parcel,android::Parcel * output_parcel)1561 android::status_t HWCSession::GetVisibleDisplayRect(const android::Parcel *input_parcel,
1562                                                     android::Parcel *output_parcel) {
1563   int dpy = input_parcel->readInt32();
1564   if (dpy < HWC_DISPLAY_PRIMARY || dpy >= HWC_NUM_DISPLAY_TYPES) {
1565     return android::BAD_VALUE;
1566   }
1567 
1568   SEQUENCE_WAIT_SCOPE_LOCK(locker_[dpy]);
1569   if (!hwc_display_[dpy]) {
1570     return android::NO_INIT;
1571   }
1572 
1573   hwc_rect_t visible_rect = {0, 0, 0, 0};
1574   int error = hwc_display_[dpy]->GetVisibleDisplayRect(&visible_rect);
1575   if (error < 0) {
1576     return error;
1577   }
1578 
1579   output_parcel->writeInt32(visible_rect.left);
1580   output_parcel->writeInt32(visible_rect.top);
1581   output_parcel->writeInt32(visible_rect.right);
1582   output_parcel->writeInt32(visible_rect.bottom);
1583 
1584   return android::NO_ERROR;
1585 }
1586 
Refresh(hwc2_display_t display)1587 void HWCSession::Refresh(hwc2_display_t display) {
1588   SCOPE_LOCK(callbacks_lock_);
1589    callbacks_.Refresh(display);
1590 }
1591 
HotPlug(hwc2_display_t display,HWC2::Connection state)1592 void HWCSession::HotPlug(hwc2_display_t display, HWC2::Connection state) {
1593   SCOPE_LOCK(callbacks_lock_);
1594   HWC2::Error err = callbacks_.Hotplug(display, state);
1595   while (err != HWC2::Error::None) {
1596     callbacks_lock_.Wait();
1597     err = callbacks_.Hotplug(display, state);
1598   }
1599 }
1600 
CreateExternalDisplay(int disp,uint32_t primary_width,uint32_t primary_height,bool use_primary_res)1601 int HWCSession::CreateExternalDisplay(int disp, uint32_t primary_width,
1602                                       uint32_t primary_height, bool use_primary_res) {
1603     uint32_t panel_bpp = 0;
1604     uint32_t pattern_type = 0;
1605     if (qdutils::isDPConnected()) {
1606         qdutils::getDPTestConfig(&panel_bpp, &pattern_type);
1607     }
1608     if (panel_bpp && pattern_type) {
1609         return HWCDisplayExternalTest::Create(core_intf_, &buffer_allocator_, &callbacks_,
1610                                               qservice_, panel_bpp,
1611                                               pattern_type, &hwc_display_[disp]);
1612     }
1613     if (use_primary_res) {
1614       return  HWCDisplayExternal::Create(core_intf_, &buffer_allocator_, &callbacks_,
1615                                          primary_width, primary_height, qservice_,
1616                                          use_primary_res, &hwc_display_[disp]);
1617     } else {
1618       return  HWCDisplayExternal::Create(core_intf_, &buffer_allocator_, &callbacks_,
1619                                          qservice_, &hwc_display_[disp]);
1620     }
1621 }
1622 
1623 }  // namespace sdm
1624