• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *     * Redistributions of source code must retain the above copyright
8 *       notice, this list of conditions and the following disclaimer.
9 *     * Redistributions in binary form must reproduce the above
10 *       copyright notice, this list of conditions and the following
11 *       disclaimer in the documentation and/or other materials provided
12 *       with the distribution.
13 *     * Neither the name of The Linux Foundation nor the names of its
14 *       contributors may be used to endorse or promote products derived
15 *       from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 
30 #include <cutils/properties.h>
31 #include <sync/sync.h>
32 #include <utils/constants.h>
33 #include <utils/debug.h>
34 #include <utils/utils.h>
35 #include <stdarg.h>
36 #include <sys/mman.h>
37 
38 #include <map>
39 #include <string>
40 #include <vector>
41 
42 #include "hwc_display_primary.h"
43 #include "hwc_debugger.h"
44 
45 #define __CLASS__ "HWCDisplayPrimary"
46 
47 namespace sdm {
48 
Init()49 DisplayError HWCDisplayPrimary::PMICInterface::Init() {
50   std::string str_lcd_bias("/sys/class/lcd_bias/secure_mode");
51   fd_lcd_bias_ = ::open(str_lcd_bias.c_str(), O_WRONLY);
52   if (fd_lcd_bias_ < 0) {
53     DLOGE("File '%s' could not be opened. errno = %d, desc = %s", str_lcd_bias.c_str(), errno,
54           strerror(errno));
55     return kErrorHardware;
56   }
57 
58   std::string str_leds_wled("/sys/class/leds/wled/secure_mode");
59   fd_wled_ = ::open(str_leds_wled.c_str(), O_WRONLY);
60   if (fd_wled_ < 0) {
61     DLOGE("File '%s' could not be opened. errno = %d, desc = %s", str_leds_wled.c_str(), errno,
62           strerror(errno));
63     return kErrorHardware;
64   }
65 
66   return kErrorNone;
67 }
68 
Deinit()69 void HWCDisplayPrimary::PMICInterface::Deinit() {
70   ::close(fd_lcd_bias_);
71   ::close(fd_wled_);
72 }
73 
Notify(bool secure_display_start)74 DisplayError HWCDisplayPrimary::PMICInterface::Notify(bool secure_display_start) {
75   std::string str_sd_start = secure_display_start ? std::to_string(1) : std::to_string(0);
76   ssize_t err = ::pwrite(fd_lcd_bias_, str_sd_start.c_str(), str_sd_start.length(), 0);
77   if (err <= 0) {
78     DLOGE("Write failed for lcd_bias, Error = %s", strerror(errno));
79     return kErrorHardware;
80   }
81 
82   err = ::pwrite(fd_wled_, str_sd_start.c_str(), str_sd_start.length(), 0);
83   if (err <= 0) {
84     DLOGE("Write failed for wled, Error = %s", strerror(errno));
85     return kErrorHardware;
86   }
87 
88   DLOGI("Successfully notifed about secure display %s to PMIC driver",
89         secure_display_start ? "start": "end");
90   return kErrorNone;
91 }
92 
Create(CoreInterface * core_intf,BufferAllocator * buffer_allocator,HWCCallbacks * callbacks,qService::QService * qservice,HWCDisplay ** hwc_display)93 int HWCDisplayPrimary::Create(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
94                               HWCCallbacks *callbacks, qService::QService *qservice,
95                               HWCDisplay **hwc_display) {
96   int status = 0;
97   uint32_t primary_width = 0;
98   uint32_t primary_height = 0;
99 
100   HWCDisplay *hwc_display_primary =
101       new HWCDisplayPrimary(core_intf, buffer_allocator, callbacks, qservice);
102   status = hwc_display_primary->Init();
103   if (status) {
104     delete hwc_display_primary;
105     return status;
106   }
107 
108   hwc_display_primary->GetMixerResolution(&primary_width, &primary_height);
109   int width = 0, height = 0;
110   HWCDebugHandler::Get()->GetProperty(FB_WIDTH_PROP, &width);
111   HWCDebugHandler::Get()->GetProperty(FB_HEIGHT_PROP, &height);
112   if (width > 0 && height > 0) {
113     primary_width = UINT32(width);
114     primary_height = UINT32(height);
115   }
116 
117   status = hwc_display_primary->SetFrameBufferResolution(primary_width, primary_height);
118   if (status) {
119     Destroy(hwc_display_primary);
120     return status;
121   }
122 
123   *hwc_display = hwc_display_primary;
124 
125   return status;
126 }
127 
Destroy(HWCDisplay * hwc_display)128 void HWCDisplayPrimary::Destroy(HWCDisplay *hwc_display) {
129   hwc_display->Deinit();
130   delete hwc_display;
131 }
132 
HWCDisplayPrimary(CoreInterface * core_intf,BufferAllocator * buffer_allocator,HWCCallbacks * callbacks,qService::QService * qservice)133 HWCDisplayPrimary::HWCDisplayPrimary(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
134                                      HWCCallbacks *callbacks, qService::QService *qservice)
135     : HWCDisplay(core_intf, callbacks, kPrimary, HWC_DISPLAY_PRIMARY, true, qservice,
136                  DISPLAY_CLASS_PRIMARY, buffer_allocator),
137       buffer_allocator_(buffer_allocator),
138       cpu_hint_(NULL) {
139 }
140 
Init()141 int HWCDisplayPrimary::Init() {
142   cpu_hint_ = new CPUHint();
143   if (cpu_hint_->Init(static_cast<HWCDebugHandler *>(HWCDebugHandler::Get())) != kErrorNone) {
144     delete cpu_hint_;
145     cpu_hint_ = NULL;
146   }
147 
148   use_metadata_refresh_rate_ = true;
149   int disable_metadata_dynfps = 0;
150   HWCDebugHandler::Get()->GetProperty(DISABLE_METADATA_DYNAMIC_FPS_PROP, &disable_metadata_dynfps);
151   if (disable_metadata_dynfps) {
152     use_metadata_refresh_rate_ = false;
153   }
154 
155   int status = HWCDisplay::Init();
156   if (status) {
157     return status;
158   }
159   color_mode_ = new HWCColorMode(display_intf_);
160   color_mode_->Init();
161   HWCDebugHandler::Get()->GetProperty(ENABLE_DEFAULT_COLOR_MODE, &default_mode_status_);
162 
163   pmic_intf_ = new PMICInterface();
164   pmic_intf_->Init();
165 
166   return status;
167 }
168 
Deinit()169 int HWCDisplayPrimary::Deinit() {
170   histogram.stop();
171 
172   int status = HWCDisplay::Deinit();
173   if (status) {
174     return status;
175   }
176   pmic_intf_->Deinit();
177   delete pmic_intf_;
178 
179   return 0;
180 }
181 
Dump()182 std::string HWCDisplayPrimary::Dump() {
183   return HWCDisplay::Dump() + histogram.Dump();
184 }
185 
ProcessBootAnimCompleted()186 void HWCDisplayPrimary::ProcessBootAnimCompleted() {
187   uint32_t numBootUpLayers = 0;
188   // TODO(user): Remove this hack
189 
190   numBootUpLayers = static_cast<uint32_t>(Debug::GetBootAnimLayerCount());
191 
192   if (numBootUpLayers == 0) {
193     numBootUpLayers = 2;
194   }
195   /* All other checks namely "init.svc.bootanim" or
196   * HWC_GEOMETRY_CHANGED fail in correctly identifying the
197   * exact bootup transition to homescreen
198   */
199   char property[PROPERTY_VALUE_MAX];
200   bool isEncrypted = false;
201   bool main_class_services_started = false;
202   property_get("ro.crypto.state", property, "unencrypted");
203   if (!strcmp(property, "encrypted")) {
204     property_get("ro.crypto.type", property, "block");
205     if (!strcmp(property, "block")) {
206       isEncrypted = true;
207       property_get("vold.decrypt", property, "");
208       if (!strcmp(property, "trigger_restart_framework")) {
209         main_class_services_started = true;
210       }
211     }
212   }
213 
214   if ((!isEncrypted || (isEncrypted && main_class_services_started)) &&
215       (layer_set_.size() > numBootUpLayers)) {
216     DLOGI("Applying default mode");
217     boot_animation_completed_ = true;
218     // Applying default mode after bootanimation is finished And
219     // If Data is Encrypted, it is ready for access.
220     if (display_intf_) {
221       display_intf_->ApplyDefaultDisplayMode();
222       RestoreColorTransform();
223     }
224   }
225 }
226 
Validate(uint32_t * out_num_types,uint32_t * out_num_requests)227 HWC2::Error HWCDisplayPrimary::Validate(uint32_t *out_num_types, uint32_t *out_num_requests) {
228   auto status = HWC2::Error::None;
229   DisplayError error = kErrorNone;
230 
231   if (default_mode_status_ && !boot_animation_completed_) {
232     ProcessBootAnimCompleted();
233   }
234 
235   if (display_paused_) {
236     MarkLayersForGPUBypass();
237     return status;
238   }
239 
240   if (color_tranform_failed_) {
241     // Must fall back to client composition
242     MarkLayersForClientComposition();
243   }
244 
245   if (config_pending_) {
246     if (display_intf_->SetActiveConfig(display_config_) != kErrorNone) {
247       DLOGW("Invalid display config %d", display_config_);
248       // Reset the display config with active config
249       display_intf_->GetActiveConfig(&display_config_);
250     }
251   }
252   // Fill in the remaining blanks in the layers and add them to the SDM layerstack
253   BuildLayerStack();
254   // Checks and replaces layer stack for solid fill
255   SolidFillPrepare();
256 
257   bool pending_output_dump = dump_frame_count_ && dump_output_to_file_;
258 
259   if (readback_buffer_queued_ || pending_output_dump) {
260     CloseFd(&output_buffer_.release_fence_fd);
261     // RHS values were set in FrameCaptureAsync() called from a binder thread. They are picked up
262     // here in a subsequent draw round. Readback is not allowed for any secure use case.
263     readback_configured_ = !layer_stack_.flags.secure_present;
264     if (readback_configured_) {
265       DisablePartialUpdateOneFrame();
266       layer_stack_.output_buffer = &output_buffer_;
267       layer_stack_.flags.post_processed_output = post_processed_output_;
268     }
269   }
270 
271   uint32_t num_updating_layers = GetUpdatingLayersCount();
272   bool one_updating_layer = (num_updating_layers == 1);
273   if (num_updating_layers != 0) {
274     ToggleCPUHint(one_updating_layer);
275   }
276 
277   uint32_t refresh_rate = GetOptimalRefreshRate(one_updating_layer);
278   bool final_rate = force_refresh_rate_ ? true : false;
279   error = display_intf_->SetRefreshRate(refresh_rate, final_rate);
280   if (error == kErrorNone) {
281     // On success, set current refresh rate to new refresh rate
282     current_refresh_rate_ = refresh_rate;
283   }
284 
285   if (layer_set_.empty()) {
286     // Avoid flush for Command mode panel.
287     DisplayConfigFixedInfo display_config;
288     display_intf_->GetConfig(&display_config);
289     flush_ = !(display_config.is_cmdmode && secure_display_active_);
290     validated_ = true;
291     return status;
292   }
293 
294   status = PrepareLayerStack(out_num_types, out_num_requests);
295   pending_commit_ = true;
296   return status;
297 }
298 
Present(int32_t * out_retire_fence)299 HWC2::Error HWCDisplayPrimary::Present(int32_t *out_retire_fence) {
300   auto status = HWC2::Error::None;
301   if (display_paused_) {
302     // TODO(user): From old HWC implementation
303     // If we do not handle the frame set retireFenceFd to outbufAcquireFenceFd
304     // Revisit this when validating display_paused
305     DisplayError error = display_intf_->Flush();
306     validated_ = false;
307     if (error != kErrorNone) {
308       DLOGE("Flush failed. Error = %d", error);
309     }
310   } else {
311     status = HWCDisplay::CommitLayerStack();
312     if (status == HWC2::Error::None) {
313       HandleFrameOutput();
314       SolidFillCommit();
315       status = PostCommitLayerStack(out_retire_fence);
316     }
317   }
318 
319   if (CC_UNLIKELY(!has_init_light_server_)) {
320     using ILight = ::hardware::google::light::V1_0::ILight;
321     vendor_ILight_ = ILight::getService();
322     if (vendor_ILight_ != nullptr) {
323       vendor_ILight_->setHbm(false);
324     } else {
325       DLOGE("failed to get vendor light service");
326     }
327 
328     uint32_t panel_x, panel_y;
329     GetPanelResolution(&panel_x, &panel_y);
330     hbm_threshold_px_ = float(panel_x * panel_y) * hbm_threshold_pct_;
331     DLOGI("Configure hbm_threshold_px_ to %f", hbm_threshold_px_);
332 
333     has_init_light_server_ = true;
334   }
335 
336   const bool enable_hbm(hdr_largest_layer_px_ > hbm_threshold_px_);
337   if (high_brightness_mode_ != enable_hbm && vendor_ILight_ != nullptr) {
338     using ::android::hardware::light::V2_0::Status;
339     if (Status::SUCCESS == vendor_ILight_->setHbm(enable_hbm)) {
340       high_brightness_mode_ = enable_hbm;
341     } else {
342       DLOGE("failed to setHbm to %d", enable_hbm);
343     }
344   }
345 
346   CloseFd(&output_buffer_.acquire_fence_fd);
347   pending_commit_ = false;
348   return status;
349 }
350 
GetColorModes(uint32_t * out_num_modes,ColorMode * out_modes)351 HWC2::Error HWCDisplayPrimary::GetColorModes(uint32_t *out_num_modes, ColorMode *out_modes) {
352   if (out_modes == nullptr) {
353     *out_num_modes = color_mode_->GetColorModeCount();
354   } else {
355     color_mode_->GetColorModes(out_num_modes, out_modes);
356   }
357 
358   return HWC2::Error::None;
359 }
360 
GetRenderIntents(ColorMode mode,uint32_t * out_num_intents,RenderIntent * out_intents)361 HWC2::Error HWCDisplayPrimary::GetRenderIntents(ColorMode mode, uint32_t *out_num_intents,
362                                                 RenderIntent *out_intents) {
363   if (out_intents == nullptr) {
364     *out_num_intents = color_mode_->GetRenderIntentCount(mode);
365   } else {
366     color_mode_->GetRenderIntents(mode, out_num_intents, out_intents);
367   }
368   return HWC2::Error::None;
369 }
370 
SetColorMode(ColorMode mode)371 HWC2::Error HWCDisplayPrimary::SetColorMode(ColorMode mode) {
372   return SetColorModeWithRenderIntent(mode, RenderIntent::COLORIMETRIC);
373 }
374 
SetWhiteCompensation(bool enabled)375 HWC2::Error HWCDisplayPrimary::SetWhiteCompensation(bool enabled) {
376   auto status = color_mode_->SetWhiteCompensation(enabled);
377   if (status != HWC2::Error::None) {
378     DLOGE("failed for SetWhiteCompensation to %d", enabled);
379     return status;
380   }
381 
382   callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
383 
384   return status;
385 }
386 
SetColorModeWithRenderIntent(ColorMode mode,RenderIntent intent)387 HWC2::Error HWCDisplayPrimary::SetColorModeWithRenderIntent(ColorMode mode, RenderIntent intent) {
388   auto status = color_mode_->SetColorModeWithRenderIntent(mode, intent);
389   if (status != HWC2::Error::None) {
390     DLOGE("failed for mode = %d intent = %d", mode, intent);
391     return status;
392   }
393   callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
394   validated_ = false;
395   auto working_color_space = color_mode_->GetWorkingColorSpace();
396   working_primaries_ = working_color_space.first;
397   working_transfer_ = working_color_space.second;
398   current_color_mode_ = color_mode_->GetCurrentColorMode();
399   return status;
400 }
401 
SetColorModeById(int32_t color_mode_id)402 HWC2::Error HWCDisplayPrimary::SetColorModeById(int32_t color_mode_id) {
403   auto status = color_mode_->SetColorModeById(color_mode_id);
404   if (status != HWC2::Error::None) {
405     DLOGE("failed for mode = %d", color_mode_id);
406     return status;
407   }
408 
409   callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
410   validated_ = false;
411 
412   return status;
413 }
414 
RestoreColorTransform()415 HWC2::Error HWCDisplayPrimary::RestoreColorTransform() {
416   auto status = color_mode_->RestoreColorTransform();
417   if (status != HWC2::Error::None) {
418     DLOGE("failed to RestoreColorTransform");
419     return status;
420   }
421 
422   callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
423 
424   return status;
425 }
426 
SetColorTransform(const float * matrix,android_color_transform_t hint)427 HWC2::Error HWCDisplayPrimary::SetColorTransform(const float *matrix,
428                                                  android_color_transform_t hint) {
429   if (!matrix) {
430     return HWC2::Error::BadParameter;
431   }
432 
433   auto status = color_mode_->SetColorTransform(matrix, hint);
434   if (status != HWC2::Error::None) {
435     DLOGE("failed for hint = %d", hint);
436     color_tranform_failed_ = true;
437     return status;
438   }
439 
440   callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
441   color_tranform_failed_ = false;
442   validated_ = false;
443 
444   return status;
445 }
446 
SetReadbackBuffer(const native_handle_t * buffer,int32_t acquire_fence,bool post_processed_output)447 HWC2::Error HWCDisplayPrimary::SetReadbackBuffer(const native_handle_t *buffer,
448                                                  int32_t acquire_fence,
449                                                  bool post_processed_output) {
450   const private_handle_t *handle = reinterpret_cast<const private_handle_t *>(buffer);
451   if (!handle || (handle->fd < 0)) {
452     return HWC2::Error::BadParameter;
453   }
454 
455   // Configure the output buffer as Readback buffer
456   output_buffer_.width = UINT32(handle->width);
457   output_buffer_.height = UINT32(handle->height);
458   output_buffer_.unaligned_width = UINT32(handle->unaligned_width);
459   output_buffer_.unaligned_height = UINT32(handle->unaligned_height);
460   output_buffer_.format = GetSDMFormat(handle->format, handle->flags);
461   output_buffer_.planes[0].fd = handle->fd;
462   output_buffer_.planes[0].stride = UINT32(handle->width);
463   output_buffer_.acquire_fence_fd = dup(acquire_fence);
464   output_buffer_.release_fence_fd = -1;
465 
466   post_processed_output_ = post_processed_output;
467   readback_buffer_queued_ = true;
468   readback_configured_ = false;
469   validated_ = false;
470 
471   return HWC2::Error::None;
472 }
473 
GetReadbackBufferFence(int32_t * release_fence)474 HWC2::Error HWCDisplayPrimary::GetReadbackBufferFence(int32_t *release_fence) {
475   auto status = HWC2::Error::None;
476 
477   if (readback_configured_ && (output_buffer_.release_fence_fd >= 0)) {
478     *release_fence = output_buffer_.release_fence_fd;
479   } else {
480     status = HWC2::Error::Unsupported;
481     *release_fence = -1;
482   }
483 
484   post_processed_output_ = false;
485   readback_buffer_queued_ = false;
486   readback_configured_ = false;
487   output_buffer_ = {};
488 
489   return status;
490 }
491 
PostCommitLayerStack(int32_t * out_retire_fence)492 HWC2::Error HWCDisplayPrimary::PostCommitLayerStack(int32_t *out_retire_fence) {
493   auto status = HWCDisplay::PostCommitLayerStack(out_retire_fence);
494   if (status != HWC2::Error::None) {
495     return status;
496   }
497 
498   if (pmic_notification_pending_) {
499     // Wait for current commit to complete
500     if (*out_retire_fence >= 0) {
501       int ret = sync_wait(*out_retire_fence, 1000);
502       if (ret < 0) {
503         DLOGE("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
504       }
505     }
506     pmic_intf_->Notify(false /* secure_display_start */);
507     pmic_notification_pending_ = false;
508   }
509   return HWC2::Error::None;
510 }
511 
TeardownConcurrentWriteback(void)512 DisplayError HWCDisplayPrimary::TeardownConcurrentWriteback(void) {
513   DisplayError error = kErrorNotSupported;
514 
515   if (output_buffer_.release_fence_fd >= 0) {
516     int32_t release_fence_fd = dup(output_buffer_.release_fence_fd);
517     int ret = sync_wait(output_buffer_.release_fence_fd, 1000);
518     if (ret < 0) {
519       DLOGE("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
520     }
521 
522     ::close(release_fence_fd);
523     if (ret)
524       return kErrorResources;
525   }
526 
527   if (display_intf_) {
528     error = display_intf_->TeardownConcurrentWriteback();
529   }
530 
531   return error;
532 }
533 
Perform(uint32_t operation,...)534 int HWCDisplayPrimary::Perform(uint32_t operation, ...) {
535   va_list args;
536   va_start(args, operation);
537   int val = 0;
538   LayerSolidFill *solid_fill_color;
539   LayerRect *rect = NULL;
540 
541   switch (operation) {
542     case SET_METADATA_DYN_REFRESH_RATE:
543       val = va_arg(args, int32_t);
544       SetMetaDataRefreshRateFlag(val);
545       break;
546     case SET_BINDER_DYN_REFRESH_RATE:
547       val = va_arg(args, int32_t);
548       ForceRefreshRate(UINT32(val));
549       break;
550     case SET_DISPLAY_MODE:
551       val = va_arg(args, int32_t);
552       SetDisplayMode(UINT32(val));
553       break;
554     case SET_QDCM_SOLID_FILL_INFO:
555       solid_fill_color = va_arg(args, LayerSolidFill*);
556       SetQDCMSolidFillInfo(true, *solid_fill_color);
557       break;
558     case UNSET_QDCM_SOLID_FILL_INFO:
559       solid_fill_color = va_arg(args, LayerSolidFill*);
560       SetQDCMSolidFillInfo(false, *solid_fill_color);
561       break;
562     case SET_QDCM_SOLID_FILL_RECT:
563       rect = va_arg(args, LayerRect*);
564       solid_fill_rect_ = *rect;
565       break;
566     default:
567       DLOGW("Invalid operation %d", operation);
568       va_end(args);
569       return -EINVAL;
570   }
571   va_end(args);
572   validated_ = false;
573 
574   return 0;
575 }
576 
SetDisplayMode(uint32_t mode)577 DisplayError HWCDisplayPrimary::SetDisplayMode(uint32_t mode) {
578   DisplayError error = kErrorNone;
579 
580   if (display_intf_) {
581     error = display_intf_->SetDisplayMode(mode);
582   }
583 
584   return error;
585 }
586 
SetMetaDataRefreshRateFlag(bool enable)587 void HWCDisplayPrimary::SetMetaDataRefreshRateFlag(bool enable) {
588   int disable_metadata_dynfps = 0;
589 
590   HWCDebugHandler::Get()->GetProperty(DISABLE_METADATA_DYNAMIC_FPS_PROP, &disable_metadata_dynfps);
591   if (disable_metadata_dynfps) {
592     return;
593   }
594   use_metadata_refresh_rate_ = enable;
595 }
596 
SetQDCMSolidFillInfo(bool enable,const LayerSolidFill & color)597 void HWCDisplayPrimary::SetQDCMSolidFillInfo(bool enable, const LayerSolidFill &color) {
598   solid_fill_enable_ = enable;
599   solid_fill_color_ = color;
600 }
601 
ToggleCPUHint(bool set)602 void HWCDisplayPrimary::ToggleCPUHint(bool set) {
603   if (!cpu_hint_) {
604     return;
605   }
606 
607   if (set) {
608     cpu_hint_->Set();
609   } else {
610     cpu_hint_->Reset();
611   }
612 }
613 
SetSecureDisplay(bool secure_display_active)614 void HWCDisplayPrimary::SetSecureDisplay(bool secure_display_active) {
615   if (secure_display_active_ != secure_display_active) {
616     // Skip Prepare and call Flush for null commit
617     DLOGI("SecureDisplay state changed from %d to %d Needs Flush!!", secure_display_active_,
618           secure_display_active);
619     secure_display_active_ = secure_display_active;
620     if (secure_display_active_) {
621       pmic_intf_->Notify(true /* secure_display_start */);
622     } else {
623       pmic_notification_pending_ = true;
624     }
625 
626     // Avoid flush for Command mode panel.
627     DisplayConfigFixedInfo display_config;
628     display_intf_->GetConfig(&display_config);
629     skip_prepare_ = !display_config.is_cmdmode;
630   }
631 }
632 
ForceRefreshRate(uint32_t refresh_rate)633 void HWCDisplayPrimary::ForceRefreshRate(uint32_t refresh_rate) {
634   if ((refresh_rate && (refresh_rate < min_refresh_rate_ || refresh_rate > max_refresh_rate_)) ||
635       force_refresh_rate_ == refresh_rate) {
636     // Cannot honor force refresh rate, as its beyond the range or new request is same
637     return;
638   }
639 
640   force_refresh_rate_ = refresh_rate;
641 
642   callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
643 
644   return;
645 }
646 
GetOptimalRefreshRate(bool one_updating_layer)647 uint32_t HWCDisplayPrimary::GetOptimalRefreshRate(bool one_updating_layer) {
648   if (force_refresh_rate_) {
649     return force_refresh_rate_;
650   } else if (use_metadata_refresh_rate_ && one_updating_layer && metadata_refresh_rate_) {
651     return metadata_refresh_rate_;
652   }
653 
654   return max_refresh_rate_;
655 }
656 
Refresh()657 DisplayError HWCDisplayPrimary::Refresh() {
658   DisplayError error = kErrorNone;
659 
660   callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
661 
662   return error;
663 }
664 
SetIdleTimeoutMs(uint32_t timeout_ms)665 void HWCDisplayPrimary::SetIdleTimeoutMs(uint32_t timeout_ms) {
666   display_intf_->SetIdleTimeoutMs(timeout_ms);
667   validated_ = false;
668 }
669 
HandleFrameOutput()670 void HWCDisplayPrimary::HandleFrameOutput() {
671   if (readback_buffer_queued_) {
672     validated_ = false;
673   }
674 
675   if (dump_output_to_file_) {
676     HandleFrameDump();
677   }
678 }
679 
HandleFrameDump()680 void HWCDisplayPrimary::HandleFrameDump() {
681   if (!readback_configured_) {
682     dump_frame_count_ = 0;
683   }
684 
685   if (dump_frame_count_ && output_buffer_.release_fence_fd >= 0) {
686     int ret = sync_wait(output_buffer_.release_fence_fd, 1000);
687     ::close(output_buffer_.release_fence_fd);
688     output_buffer_.release_fence_fd = -1;
689     if (ret < 0) {
690       DLOGE("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
691     } else {
692       DumpOutputBuffer(output_buffer_info_, output_buffer_base_, layer_stack_.retire_fence_fd);
693       readback_buffer_queued_ = false;
694       validated_ = false;
695     }
696   }
697 
698   if (0 == dump_frame_count_) {
699     dump_output_to_file_ = false;
700     // Unmap and Free buffer
701     if (munmap(output_buffer_base_, output_buffer_info_.alloc_buffer_info.size) != 0) {
702       DLOGE("unmap failed with err %d", errno);
703     }
704     if (buffer_allocator_->FreeBuffer(&output_buffer_info_) != 0) {
705       DLOGE("FreeBuffer failed");
706     }
707 
708     readback_buffer_queued_ = false;
709     post_processed_output_ = false;
710     readback_configured_ = false;
711 
712     output_buffer_ = {};
713     output_buffer_info_ = {};
714     output_buffer_base_ = nullptr;
715   }
716 }
717 
SetFrameDumpConfig(uint32_t count,uint32_t bit_mask_layer_type,int32_t format,bool post_processed)718 HWC2::Error HWCDisplayPrimary::SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type,
719                                                   int32_t format, bool post_processed) {
720   HWCDisplay::SetFrameDumpConfig(count, bit_mask_layer_type, format, post_processed);
721   dump_output_to_file_ = bit_mask_layer_type & (1 << OUTPUT_LAYER_DUMP);
722   DLOGI("output_layer_dump_enable %d", dump_output_to_file_);
723 
724   if (!count || !dump_output_to_file_) {
725     return HWC2::Error::None;
726   }
727 
728   // Allocate and map output buffer
729   output_buffer_info_ = {};
730 
731   if (post_processed) {
732     // To dump post-processed (DSPP) output, use Panel resolution.
733     GetPanelResolution(&output_buffer_info_.buffer_config.width,
734                        &output_buffer_info_.buffer_config.height);
735   } else {
736     // To dump Layer Mixer output, use FrameBuffer resolution.
737     GetFrameBufferResolution(&output_buffer_info_.buffer_config.width,
738                              &output_buffer_info_.buffer_config.height);
739   }
740 
741   output_buffer_info_.buffer_config.format = GetSDMFormat(format, 0);
742   output_buffer_info_.buffer_config.buffer_count = 1;
743   if (buffer_allocator_->AllocateBuffer(&output_buffer_info_) != 0) {
744     DLOGE("Buffer allocation failed");
745     output_buffer_info_ = {};
746     return HWC2::Error::NoResources;
747   }
748 
749   void *buffer = mmap(NULL, output_buffer_info_.alloc_buffer_info.size, PROT_READ | PROT_WRITE,
750                       MAP_SHARED, output_buffer_info_.alloc_buffer_info.fd, 0);
751 
752   if (buffer == MAP_FAILED) {
753     DLOGE("mmap failed with err %d", errno);
754     buffer_allocator_->FreeBuffer(&output_buffer_info_);
755     output_buffer_info_ = {};
756     return HWC2::Error::NoResources;
757   }
758 
759   output_buffer_base_ = buffer;
760   const native_handle_t *handle = static_cast<native_handle_t *>(output_buffer_info_.private_data);
761   SetReadbackBuffer(handle, -1, post_processed);
762 
763   return HWC2::Error::None;
764 }
765 
FrameCaptureAsync(const BufferInfo & output_buffer_info,bool post_processed_output)766 int HWCDisplayPrimary::FrameCaptureAsync(const BufferInfo &output_buffer_info,
767                                          bool post_processed_output) {
768   // Note: This function is called in context of a binder thread and a lock is already held
769   if (output_buffer_info.alloc_buffer_info.fd < 0) {
770     DLOGE("Invalid fd %d", output_buffer_info.alloc_buffer_info.fd);
771     return -1;
772   }
773 
774   auto panel_width = 0u;
775   auto panel_height = 0u;
776   auto fb_width = 0u;
777   auto fb_height = 0u;
778 
779   GetPanelResolution(&panel_width, &panel_height);
780   GetFrameBufferResolution(&fb_width, &fb_height);
781 
782   if (post_processed_output && (output_buffer_info.buffer_config.width < panel_width ||
783                                 output_buffer_info.buffer_config.height < panel_height)) {
784     DLOGE("Buffer dimensions should not be less than panel resolution");
785     return -1;
786   } else if (!post_processed_output && (output_buffer_info.buffer_config.width < fb_width ||
787                                         output_buffer_info.buffer_config.height < fb_height)) {
788     DLOGE("Buffer dimensions should not be less than FB resolution");
789     return -1;
790   }
791 
792   const native_handle_t *buffer = static_cast<native_handle_t *>(output_buffer_info.private_data);
793   SetReadbackBuffer(buffer, -1, post_processed_output);
794 
795   return 0;
796 }
797 
GetFrameCaptureFence(int32_t * release_fence)798 bool HWCDisplayPrimary::GetFrameCaptureFence(int32_t *release_fence) {
799   return (GetReadbackBufferFence(release_fence) == HWC2::Error::None);
800 }
801 
SetDetailEnhancerConfig(const DisplayDetailEnhancerData & de_data)802 DisplayError HWCDisplayPrimary::SetDetailEnhancerConfig
803                                    (const DisplayDetailEnhancerData &de_data) {
804   DisplayError error = kErrorNotSupported;
805 
806   if (display_intf_) {
807     error = display_intf_->SetDetailEnhancerData(de_data);
808     validated_ = false;
809   }
810   return error;
811 }
812 
ControlPartialUpdate(bool enable,uint32_t * pending)813 DisplayError HWCDisplayPrimary::ControlPartialUpdate(bool enable, uint32_t *pending) {
814   DisplayError error = kErrorNone;
815 
816   if (display_intf_) {
817     error = display_intf_->ControlPartialUpdate(enable, pending);
818     validated_ = false;
819   }
820 
821   return error;
822 }
823 
DisablePartialUpdateOneFrame()824 DisplayError HWCDisplayPrimary::DisablePartialUpdateOneFrame() {
825   DisplayError error = kErrorNone;
826 
827   if (display_intf_) {
828     error = display_intf_->DisablePartialUpdateOneFrame();
829     validated_ = false;
830   }
831 
832   return error;
833 }
834 
SetDisplayedContentSamplingEnabledVndService(bool enabled)835 HWC2::Error HWCDisplayPrimary::SetDisplayedContentSamplingEnabledVndService(bool enabled) {
836   std::unique_lock<decltype(sampling_mutex)> lk(sampling_mutex);
837   vndservice_sampling_vote = enabled;
838   if (api_sampling_vote || vndservice_sampling_vote) {
839     histogram.start();
840   } else {
841     histogram.stop();
842   }
843   return HWC2::Error::None;
844 }
845 
SetDisplayedContentSamplingEnabled(int32_t enabled,uint8_t component_mask,uint64_t max_frames)846 HWC2::Error HWCDisplayPrimary::SetDisplayedContentSamplingEnabled(int32_t enabled, uint8_t component_mask, uint64_t max_frames) {
847     if ((enabled != HWC2_DISPLAYED_CONTENT_SAMPLING_ENABLE) &&
848         (enabled != HWC2_DISPLAYED_CONTENT_SAMPLING_DISABLE))
849       return HWC2::Error::BadParameter;
850 
851     std::unique_lock<decltype(sampling_mutex)> lk(sampling_mutex);
852     if (enabled == HWC2_DISPLAYED_CONTENT_SAMPLING_ENABLE) {
853       api_sampling_vote = true;
854     } else {
855       api_sampling_vote = false;
856     }
857 
858     auto start = api_sampling_vote || vndservice_sampling_vote;
859     if (start && max_frames == 0) {
860         histogram.start();
861     } else if (start) {
862         histogram.start(max_frames);
863     } else {
864         histogram.stop();
865     }
866     return HWC2::Error::None;
867 }
868 
GetDisplayedContentSamplingAttributes(int32_t * format,int32_t * dataspace,uint8_t * supported_components)869 HWC2::Error HWCDisplayPrimary::GetDisplayedContentSamplingAttributes(int32_t* format,
870                                                                      int32_t* dataspace,
871                                                                      uint8_t* supported_components) {
872     return histogram.getAttributes(format, dataspace, supported_components);
873 }
874 
GetDisplayedContentSample(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])875 HWC2::Error HWCDisplayPrimary::GetDisplayedContentSample(uint64_t max_frames,
876                                                          uint64_t timestamp,
877                                                          uint64_t* numFrames,
878                                                          int32_t samples_size[NUM_HISTOGRAM_COLOR_COMPONENTS],
879                                                          uint64_t* samples[NUM_HISTOGRAM_COLOR_COMPONENTS])
880 {
881     histogram.collect(max_frames, timestamp, samples_size, samples, numFrames);
882     return HWC2::Error::None;
883 }
884 
SetMixerResolution(uint32_t width,uint32_t height)885 DisplayError HWCDisplayPrimary::SetMixerResolution(uint32_t width, uint32_t height) {
886   DisplayError error = display_intf_->SetMixerResolution(width, height);
887   validated_ = false;
888   return error;
889 }
890 
GetMixerResolution(uint32_t * width,uint32_t * height)891 DisplayError HWCDisplayPrimary::GetMixerResolution(uint32_t *width, uint32_t *height) {
892   return display_intf_->GetMixerResolution(width, height);
893 }
894 
ControlIdlePowerCollapse(bool enable,bool synchronous)895 HWC2::Error HWCDisplayPrimary::ControlIdlePowerCollapse(bool enable, bool synchronous) {
896   DisplayError error = kErrorNone;
897 
898   if (display_intf_) {
899     error = display_intf_->ControlIdlePowerCollapse(enable, synchronous);
900     validated_ = false;
901   }
902 
903   return (error != kErrorNone) ?  HWC2::Error::Unsupported : HWC2::Error::None;
904 }
905 
906 }  // namespace sdm
907