1 /*
2 * Copyright (c) 2014-2021, 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 /*
31 * Changes from Qualcomm Innovation Center are provided under the following license:
32 *
33 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
34 *
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted (subject to the limitations in the
37 * disclaimer below) provided that the following conditions are met:
38 *
39 *    * Redistributions of source code must retain the above copyright
40 *      notice, this list of conditions and the following disclaimer.
41 *
42 *    * Redistributions in binary form must reproduce the above
43 *      copyright notice, this list of conditions and the following
44 *      disclaimer in the documentation and/or other materials provided
45 *      with the distribution.
46 *
47 *    * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
48 *      contributors may be used to endorse or promote products derived
49 *      from this software without specific prior written permission.
50 *
51 * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
52 * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
53 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
54 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
55 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
56 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
57 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
59 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
60 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
61 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
62 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
63 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64 */
65 
66 #include <android-base/file.h>
67 #include <cutils/properties.h>
68 #include <cutils/sockets.h>
69 #include <utils/constants.h>
70 #include <utils/debug.h>
71 #include <utils/utils.h>
72 #include <stdarg.h>
73 #include <sync/sync.h>
74 #include <sys/mman.h>
75 
76 #include <map>
77 #include <iostream>
78 #include <string>
79 #include <vector>
80 
81 #include "hwc_display_builtin.h"
82 #include "hwc_debugger.h"
83 #include "hwc_session.h"
84 
85 #define __CLASS__ "HWCDisplayBuiltIn"
86 
87 namespace sdm {
88 
SetRect(LayerRect & src_rect,GLRect * target)89 static void SetRect(LayerRect &src_rect, GLRect *target) {
90   target->left = src_rect.left;
91   target->top = src_rect.top;
92   target->right = src_rect.right;
93   target->bottom = src_rect.bottom;
94 }
95 
LoadPanelGammaCalibration()96 static std::string LoadPanelGammaCalibration() {
97   constexpr char file[] = "/mnt/vendor/persist/display/gamma_calib_data.cal";
98   std::ifstream ifs(file);
99 
100   if (!ifs.is_open()) {
101     DLOGW("Unable to open gamma calibration '%s', error = %s", file, strerror(errno));
102     return {};
103   }
104 
105   std::string raw_data, gamma;
106   while (std::getline(ifs, raw_data, '\r')) {
107     gamma.append(raw_data.c_str());
108     gamma.append(" ");
109     std::getline(ifs, raw_data);
110   }
111   ifs.close();
112 
113   /* eliminate space character in the last byte */
114   if (!gamma.empty()) {
115     gamma.pop_back();
116   }
117 
118   return gamma;
119 }
120 
WritePanelGammaTableToDriver(const std::string & gamma_data)121 static DisplayError WritePanelGammaTableToDriver(const std::string &gamma_data) {
122   constexpr char gamma_path[] = "/sys/devices/platform/soc/soc:qcom,dsi-display-primary/gamma";
123   int fd = open(gamma_path, O_WRONLY);
124   if (fd < 0) {
125     DLOGW("Unable to open gamma node '%s', error = %s", gamma_path, strerror(errno));
126     return kErrorFileDescriptor;
127   }
128 
129   constexpr int max_retries = 5;
130   ssize_t len;
131   int retry_count = 0;
132   DisplayError error = kErrorNone;
133   while ((len = pwrite(fd, gamma_data.c_str(), gamma_data.size(), 0)) != gamma_data.size()) {
134     if ((len == -1 && errno != EINTR && errno != EAGAIN) || (++retry_count > max_retries)) {
135       DLOGE("Failed to write gamma calibration(retry %d), error = %s", retry_count,
136             strerror(errno));
137       break;
138     }
139   }
140   close(fd);
141 
142   if (len != gamma_data.size()) {
143     error = kErrorResources;
144   }
145 
146   return error;
147 }
148 
UpdatePanelGammaTable(enum HWCDisplay::PanelGammaSource source)149 static DisplayError UpdatePanelGammaTable(enum HWCDisplay::PanelGammaSource source) {
150   std::string gamma_data = {};
151   DisplayError error;
152   if (source == HWCDisplay::kGammaDefault) {
153     gamma_data = "default";
154   } else if (source == HWCDisplay::kGammaCalibration) {
155     gamma_data = LoadPanelGammaCalibration();
156   }
157 
158   if (!gamma_data.empty()) {
159     error = WritePanelGammaTableToDriver(gamma_data);
160   } else {
161     error = kErrorParameters;
162   }
163 
164   return error;
165 }
166 
Create(CoreInterface * core_intf,BufferAllocator * buffer_allocator,HWCCallbacks * callbacks,HWCDisplayEventHandler * event_handler,qService::QService * qservice,hwc2_display_t id,int32_t sdm_id,HWCDisplay ** hwc_display)167 int HWCDisplayBuiltIn::Create(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
168                               HWCCallbacks *callbacks, HWCDisplayEventHandler *event_handler,
169                               qService::QService *qservice, hwc2_display_t id, int32_t sdm_id,
170                               HWCDisplay **hwc_display) {
171   int status = 0;
172   uint32_t builtin_width = 0;
173   uint32_t builtin_height = 0;
174 
175   HWCDisplay *hwc_display_builtin =
176       new HWCDisplayBuiltIn(core_intf, buffer_allocator, callbacks, event_handler, qservice, id,
177                             sdm_id);
178   status = hwc_display_builtin->Init();
179   if (status) {
180     delete hwc_display_builtin;
181     return status;
182   }
183 
184   hwc_display_builtin->GetMixerResolution(&builtin_width, &builtin_height);
185   int width = 0, height = 0;
186   HWCDebugHandler::Get()->GetProperty(FB_WIDTH_PROP, &width);
187   HWCDebugHandler::Get()->GetProperty(FB_HEIGHT_PROP, &height);
188   if (width > 0 && height > 0) {
189     builtin_width = UINT32(width);
190     builtin_height = UINT32(height);
191   }
192 
193   status = hwc_display_builtin->SetFrameBufferResolution(builtin_width, builtin_height);
194   if (status) {
195     Destroy(hwc_display_builtin);
196     return status;
197   }
198 
199   *hwc_display = hwc_display_builtin;
200 
201   return status;
202 }
203 
Destroy(HWCDisplay * hwc_display)204 void HWCDisplayBuiltIn::Destroy(HWCDisplay *hwc_display) {
205   hwc_display->Deinit();
206   delete hwc_display;
207 }
208 
HWCDisplayBuiltIn(CoreInterface * core_intf,BufferAllocator * buffer_allocator,HWCCallbacks * callbacks,HWCDisplayEventHandler * event_handler,qService::QService * qservice,hwc2_display_t id,int32_t sdm_id)209 HWCDisplayBuiltIn::HWCDisplayBuiltIn(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
210                                      HWCCallbacks *callbacks, HWCDisplayEventHandler *event_handler,
211                                      qService::QService *qservice, hwc2_display_t id,
212                                      int32_t sdm_id)
213     : HWCDisplay(core_intf, buffer_allocator, callbacks, event_handler, qservice, kBuiltIn, id,
214                  sdm_id, DISPLAY_CLASS_BUILTIN),
215       buffer_allocator_(buffer_allocator),
216       cpu_hint_(NULL), layer_stitch_task_(*this) {
217 }
218 
Init()219 int HWCDisplayBuiltIn::Init() {
220   cpu_hint_ = new CPUHint();
221   if (cpu_hint_->Init(static_cast<HWCDebugHandler *>(HWCDebugHandler::Get())) != kErrorNone) {
222     delete cpu_hint_;
223     cpu_hint_ = NULL;
224   }
225 
226   use_metadata_refresh_rate_ = true;
227   int disable_metadata_dynfps = 0;
228   HWCDebugHandler::Get()->GetProperty(DISABLE_METADATA_DYNAMIC_FPS_PROP, &disable_metadata_dynfps);
229   if (disable_metadata_dynfps) {
230     use_metadata_refresh_rate_ = false;
231   }
232 
233   int status = HWCDisplay::Init();
234   if (status) {
235     return status;
236   }
237   color_mode_ = new HWCColorMode(display_intf_);
238   color_mode_->Init();
239 
240   int value = 0;
241   HWCDebugHandler::Get()->GetProperty(ENABLE_OPTIMIZE_REFRESH, &value);
242   enable_optimize_refresh_ = (value == 1);
243   if (enable_optimize_refresh_) {
244     DLOGI("Drop redundant drawcycles %" PRIu64 , id_);
245   }
246 
247   int vsyncs = 0;
248   HWCDebugHandler::Get()->GetProperty(DEFER_FPS_FRAME_COUNT, &vsyncs);
249   if (vsyncs > 0) {
250     SetVsyncsApplyRateChange(UINT32(vsyncs));
251   }
252 
253   is_primary_ = display_intf_->IsPrimaryDisplay();
254 
255   if (is_primary_) {
256     int enable_bw_limits = 0;
257     HWCDebugHandler::Get()->GetProperty(ENABLE_BW_LIMITS, &enable_bw_limits);
258     enable_bw_limits_ = (enable_bw_limits == 1);
259     if (enable_bw_limits_) {
260       DLOGI("Enable BW Limits %" PRIu64, id_);
261     }
262     windowed_display_ = Debug::GetWindowRect(&window_rect_.left, &window_rect_.top,
263                       &window_rect_.right, &window_rect_.bottom) != kErrorUndefined;
264     DLOGI("Window rect : [%f %f %f %f]", window_rect_.left, window_rect_.top,
265           window_rect_.right, window_rect_.bottom);
266   }
267 
268   value = 0;
269   DebugHandler::Get()->GetProperty(DISABLE_DYNAMIC_FPS, &value);
270   disable_dyn_fps_ = (value == 1);
271   DLOGI("disable_dyn_fps_: %d", disable_dyn_fps_);
272 
273   uint32_t config_index = 0;
274   GetActiveDisplayConfig(&config_index);
275   DisplayConfigVariableInfo attr = {};
276   GetDisplayAttributesForConfig(INT(config_index), &attr);
277   active_refresh_rate_ = attr.fps;
278 
279   DLOGI("active_refresh_rate: %d", active_refresh_rate_);
280 
281   value = 0;
282   HWCDebugHandler::Get()->GetProperty(ENHANCE_IDLE_TIME, &value);
283   enhance_idle_time_ = (value == 1);
284   DLOGI("enhance_idle_time: %d", enhance_idle_time_);
285 
286   HWCDebugHandler::Get()->GetProperty(PERF_HINT_WINDOW_PROP, &perf_hint_window_);
287   HWCDebugHandler::Get()->GetProperty(ENABLE_PERF_HINT_LARGE_COMP_CYCLE,
288                                       &perf_hint_large_comp_cycle_);
289 
290   return status;
291 }
292 
Dump(std::ostringstream * os)293 void HWCDisplayBuiltIn::Dump(std::ostringstream *os) {
294   HWCDisplay::Dump(os);
295 #ifndef TARGET_HEADLESS
296   *os << histogram.Dump();
297 #endif
298 }
299 
ValidateUiScaling()300 void HWCDisplayBuiltIn::ValidateUiScaling() {
301   if (is_primary_ || !is_cmd_mode_) {
302     force_reset_validate_ = false;
303     return;
304   }
305 
306   for (auto &hwc_layer : layer_set_) {
307     Layer *layer = hwc_layer->GetSDMLayer();
308     if (hwc_layer->IsScalingPresent() && !layer->input_buffer.flags.video) {
309       force_reset_validate_ = true;
310       return;
311     }
312   }
313   force_reset_validate_ = false;
314 }
315 
Validate(uint32_t * out_num_types,uint32_t * out_num_requests)316 HWC2::Error HWCDisplayBuiltIn::Validate(uint32_t *out_num_types, uint32_t *out_num_requests) {
317   auto status = HWC2::Error::None;
318   DisplayError error = kErrorNone;
319 
320   DTRACE_SCOPED();
321 
322   if (display_paused_) {
323     MarkLayersForGPUBypass();
324     return status;
325   }
326 
327   if (color_tranform_failed_) {
328     // Must fall back to client composition
329     MarkLayersForClientComposition();
330   }
331 
332   // Fill in the remaining blanks in the layers and add them to the SDM layerstack
333   BuildLayerStack();
334 
335   // Check for scaling layers during Doze mode
336   ValidateUiScaling();
337 
338   // Add stitch layer to layer stack.
339   AppendStitchLayer();
340 
341   // Checks and replaces layer stack for solid fill
342   SolidFillPrepare();
343 
344   // Apply current Color Mode and Render Intent.
345   if (color_mode_->ApplyCurrentColorModeWithRenderIntent(
346       static_cast<bool>(layer_stack_.flags.hdr_present)) != HWC2::Error::None) {
347     // Fallback to GPU Composition, if Color Mode can't be applied.
348     MarkLayersForClientComposition();
349   }
350 
351   // apply pending DE config
352   PPPendingParams pending_action;
353   PPDisplayAPIPayload req_payload;
354   pending_action.action = kGetDetailedEnhancerData;
355   pending_action.params = NULL;
356   int err = display_intf_->ColorSVCRequestRoute(req_payload, NULL, &pending_action);
357   if (!err && pending_action.action == kConfigureDetailedEnhancer) {
358       err = SetHWDetailedEnhancerConfig(pending_action.params);
359   }
360 
361   bool pending_output_dump = dump_frame_count_ && dump_output_to_file_;
362 
363   if (readback_buffer_queued_ || pending_output_dump) {
364     // RHS values were set in FrameCaptureAsync() called from a binder thread. They are picked up
365     // here in a subsequent draw round. Readback is not allowed for any secure use case.
366     readback_configured_ = !layer_stack_.flags.secure_present;
367     if (readback_configured_) {
368       DisablePartialUpdateOneFrame();
369       layer_stack_.output_buffer = &output_buffer_;
370       layer_stack_.flags.post_processed_output = post_processed_output_;
371     }
372   }
373 
374   uint32_t num_updating_layers = GetUpdatingLayersCount();
375   bool one_updating_layer = (num_updating_layers == 1);
376   if (num_updating_layers != 0) {
377     ToggleCPUHint(one_updating_layer);
378   }
379 
380   uint32_t refresh_rate = GetOptimalRefreshRate(one_updating_layer);
381   bool idle_screen = GetUpdatingAppLayersCount() == 0;
382   error = display_intf_->SetRefreshRate(refresh_rate, force_refresh_rate_, idle_screen);
383 
384   // Get the refresh rate set.
385   display_intf_->GetRefreshRate(&refresh_rate);
386   bool vsync_source = (callbacks_->GetVsyncSource() == id_);
387 
388   if (error == kErrorNone) {
389     if (vsync_source && ((current_refresh_rate_ < refresh_rate) ||
390                          (enhance_idle_time_ && (current_refresh_rate_ != refresh_rate)))) {
391       DTRACE_BEGIN("HWC2::Vsync::Enable");
392       // Display is ramping up from idle.
393       // Client realizes need for resync upon change in config.
394       // Since we know config has changed, triggering vsync proactively
395       // can help in reducing pipeline delays to enable events.
396       SetVsyncEnabled(HWC2::Vsync::Enable);
397       DTRACE_END();
398     }
399     // On success, set current refresh rate to new refresh rate.
400     current_refresh_rate_ = refresh_rate;
401   }
402 
403   if (layer_set_.empty()) {
404     // Avoid flush for Command mode panel.
405     flush_ = !client_connected_;
406     validated_ = true;
407     layer_changes_.clear();
408     layer_requests_.clear();
409     DLOGV_IF(kTagDisplay, "layer_set is empty");
410     return status;
411   }
412 
413   status = PrepareLayerStack(out_num_types, out_num_requests);
414   pending_commit_ = true;
415   return status;
416 }
417 
CommitLayerStack()418 HWC2::Error HWCDisplayBuiltIn::CommitLayerStack() {
419   skip_commit_ = CanSkipCommit();
420   return HWCDisplay::CommitLayerStack();
421 }
422 
CanSkipCommit()423 bool HWCDisplayBuiltIn::CanSkipCommit() {
424   if (layer_stack_invalid_) {
425     return false;
426   }
427 
428   // Reject repeated drawcycle requests if it satisfies all conditions.
429   // 1. None of the layerstack attributes changed.
430   // 2. No new buffer latched.
431   // 3. No refresh request triggered by HWC.
432   // 4. This display is not source of vsync.
433   bool buffers_latched = false;
434   for (auto &hwc_layer : layer_set_) {
435     buffers_latched |= hwc_layer->BufferLatched();
436     hwc_layer->ResetBufferFlip();
437   }
438 
439   bool vsync_source = (callbacks_->GetVsyncSource() == id_);
440   bool skip_commit = enable_optimize_refresh_ && !pending_commit_ && !buffers_latched &&
441                      !pending_refresh_ && !vsync_source;
442   pending_refresh_ = false;
443 
444   return skip_commit;
445 }
446 
CommitStitchLayers()447 HWC2::Error HWCDisplayBuiltIn::CommitStitchLayers() {
448   if (disable_layer_stitch_) {
449     return HWC2::Error::None;
450   }
451 
452   if (!validated_ || skip_commit_) {
453     return HWC2::Error::None;
454   }
455 
456   LayerStitchContext ctx = {};
457   Layer *stitch_layer = stitch_target_->GetSDMLayer();
458   LayerBuffer &output_buffer = stitch_layer->input_buffer;
459   for (auto &layer : layer_stack_.layers) {
460     LayerComposition &composition = layer->composition;
461     if (composition != kCompositionStitch) {
462       continue;
463     }
464 
465     StitchParams params = {};
466     // Stitch target doesn't have an input fence.
467     // Render all layers at specified destination.
468     LayerBuffer &input_buffer = layer->input_buffer;
469     params.src_hnd = reinterpret_cast<const private_handle_t *>(input_buffer.buffer_id);
470     params.dst_hnd = reinterpret_cast<const private_handle_t *>(output_buffer.buffer_id);
471     SetRect(layer->stitch_info.dst_rect, &params.dst_rect);
472     SetRect(layer->stitch_info.slice_rect, &params.scissor_rect);
473     params.src_acquire_fence = input_buffer.acquire_fence;
474 
475     ctx.stitch_params.push_back(params);
476   }
477 
478   if (!ctx.stitch_params.size()) {
479     // No layers marked for stitch.
480     return HWC2::Error::None;
481   }
482 
483   layer_stitch_task_.PerformTask(LayerStitchTaskCode::kCodeStitch, &ctx);
484   // Set release fence.
485   output_buffer.acquire_fence = ctx.release_fence;
486 
487   return HWC2::Error::None;
488 }
489 
CacheAvrStatus()490 void HWCDisplayBuiltIn::CacheAvrStatus() {
491   QSyncMode qsync_mode = kQSyncModeNone;
492 
493   DisplayError error = display_intf_->GetQSyncMode(&qsync_mode);
494   if (error != kErrorNone) {
495     return;
496   }
497 
498   bool qsync_enabled = (qsync_mode != kQSyncModeNone);
499   if (qsync_enabled_ != qsync_enabled) {
500     qsync_reconfigured_ = true;
501     qsync_enabled_ = qsync_enabled;
502   } else {
503     qsync_reconfigured_ = false;
504   }
505 }
506 
IsQsyncCallbackNeeded(bool * qsync_enabled,int32_t * refresh_rate,int32_t * qsync_refresh_rate)507 bool HWCDisplayBuiltIn::IsQsyncCallbackNeeded(bool *qsync_enabled, int32_t *refresh_rate,
508                            int32_t *qsync_refresh_rate) {
509   if (!qsync_reconfigured_) {
510     return false;
511   }
512 
513   bool vsync_source = (callbacks_->GetVsyncSource() == id_);
514   // Qsync callback not needed if this display is not the source of vsync
515   if (!vsync_source) {
516     return false;
517   }
518 
519   *qsync_enabled = qsync_enabled_;
520   uint32_t current_rate = 0;
521   display_intf_->GetRefreshRate(&current_rate);
522   *refresh_rate = INT32(current_rate);
523   *qsync_refresh_rate = min_refresh_rate_;
524 
525   return true;
526 }
527 
GetBwCode(const DisplayConfigVariableInfo & attr)528 int HWCDisplayBuiltIn::GetBwCode(const DisplayConfigVariableInfo &attr) {
529   uint32_t min_refresh_rate = 0, max_refresh_rate = 0;
530   display_intf_->GetRefreshRateRange(&min_refresh_rate, &max_refresh_rate);
531   uint32_t fps = attr.smart_panel ? attr.fps : max_refresh_rate;
532 
533   if (fps <= 60) {
534     return kBwLow;
535   } else if (fps <= 90) {
536     return kBwMedium;
537   } else {
538     return kBwHigh;
539   }
540 }
541 
SetBwLimitHint(bool enable)542 void HWCDisplayBuiltIn::SetBwLimitHint(bool enable) {
543   if (!enable_bw_limits_) {
544     return;
545   }
546 
547   if (!enable) {
548     thermal_bandwidth_client_cancel_request(const_cast<char*>(kDisplayBwName));
549     curr_refresh_rate_ = 0;
550     return;
551   }
552 
553   uint32_t config_index = 0;
554   DisplayConfigVariableInfo attr = {};
555   GetActiveDisplayConfig(&config_index);
556   GetDisplayAttributesForConfig(INT(config_index), &attr);
557   if (attr.fps != curr_refresh_rate_ || attr.smart_panel != is_smart_panel_) {
558     int bw_code = GetBwCode(attr);
559     int req_data = thermal_bandwidth_client_merge_input_info(bw_code, 0);
560     int error = thermal_bandwidth_client_request(const_cast<char*>(kDisplayBwName), req_data);
561     if (error) {
562       DLOGE("Thermal bandwidth request failed %d", error);
563     }
564     curr_refresh_rate_ = attr.fps;
565     is_smart_panel_ = attr.smart_panel;
566   }
567 }
568 
SetPartialUpdate(DisplayConfigFixedInfo fixed_info)569 void HWCDisplayBuiltIn::SetPartialUpdate(DisplayConfigFixedInfo fixed_info) {
570   partial_update_enabled_ = fixed_info.partial_update || (!fixed_info.is_cmdmode);
571   for (auto hwc_layer : layer_set_) {
572     hwc_layer->SetPartialUpdate(partial_update_enabled_);
573   }
574   client_target_->SetPartialUpdate(partial_update_enabled_);
575 }
576 
SetPowerMode(HWC2::PowerMode mode,bool teardown)577 HWC2::Error HWCDisplayBuiltIn::SetPowerMode(HWC2::PowerMode mode, bool teardown) {
578   DisplayConfigFixedInfo fixed_info = {};
579   display_intf_->GetConfig(&fixed_info);
580   bool command_mode = fixed_info.is_cmdmode;
581 
582   auto status = HWCDisplay::SetPowerMode(mode, teardown);
583   if (status != HWC2::Error::None) {
584     return status;
585   }
586 
587   display_intf_->GetConfig(&fixed_info);
588   is_cmd_mode_ = fixed_info.is_cmdmode;
589   if (is_cmd_mode_ != command_mode) {
590     SetPartialUpdate(fixed_info);
591   }
592 
593   if (mode == HWC2::PowerMode::Off) {
594     SetBwLimitHint(false);
595   }
596 
597   return HWC2::Error::None;
598 }
599 
Present(shared_ptr<Fence> * out_retire_fence)600 HWC2::Error HWCDisplayBuiltIn::Present(shared_ptr<Fence> *out_retire_fence) {
601   auto status = HWC2::Error::None;
602 
603   DTRACE_SCOPED();
604 
605   if (display_paused_) {
606     DisplayError error = display_intf_->Flush(&layer_stack_);
607     validated_ = false;
608     if (error != kErrorNone) {
609       DLOGE("Flush failed. Error = %d", error);
610     }
611   } else {
612     CacheAvrStatus();
613     DisplayConfigFixedInfo fixed_info = {};
614     display_intf_->GetConfig(&fixed_info);
615     bool command_mode = fixed_info.is_cmdmode;
616 
617     status = CommitStitchLayers();
618     if (status != HWC2::Error::None) {
619       DLOGE("Stitch failed: %d", status);
620       return status;
621     }
622 
623     status = CommitLayerStack();
624     if (status == HWC2::Error::None) {
625       HandleFrameOutput();
626       PostCommitStitchLayers();
627       status = HWCDisplay::PostCommitLayerStack(out_retire_fence);
628       SetBwLimitHint(true);
629       display_intf_->GetConfig(&fixed_info);
630       is_cmd_mode_ = fixed_info.is_cmdmode;
631       if (is_cmd_mode_ != command_mode) {
632         SetPartialUpdate(fixed_info);
633       }
634 
635       // For video mode panel with dynamic fps, update the active mode index.
636       // This is needed to report the correct Vsync period when client queries
637       // using GetDisplayVsyncPeriod API.
638       if (!is_cmd_mode_ && !disable_dyn_fps_) {
639         hwc2_config_t active_config = hwc_config_map_.at(0);
640         GetActiveConfig(&active_config);
641         SetActiveConfigIndex(active_config);
642       }
643     }
644   }
645 
646   if (CC_UNLIKELY(!has_config_hbm_threshold_)) {
647     uint32_t panel_x, panel_y;
648     GetPanelResolution(&panel_x, &panel_y);
649     hbm_threshold_px_ = float(panel_x * panel_y) * hbm_threshold_pct_;
650     DLOGI("Configure hbm_threshold_px_ to %f", hbm_threshold_px_);
651 
652     has_config_hbm_threshold_ = true;
653   }
654 
655   const bool enable_hbm(hdr_largest_layer_px_ > hbm_threshold_px_);
656   if (high_brightness_mode_ != enable_hbm) {
657     HbmState state = enable_hbm ? HbmState::HDR : HbmState::OFF;
658     auto status = SetHbm(state, HWC);
659     if (status == HWC2::Error::None) {
660       high_brightness_mode_ = enable_hbm;
661     } else {
662       DLOGE("failed to setHbm to %d", enable_hbm);
663     }
664   }
665 
666   pending_commit_ = false;
667 
668   // In case of scaling UI layer for command mode, reset validate
669   if (force_reset_validate_) {
670     validated_ = false;
671     display_intf_->ClearLUTs();
672   }
673   return status;
674 }
675 
PostCommitStitchLayers()676 void HWCDisplayBuiltIn::PostCommitStitchLayers() {
677   if (disable_layer_stitch_) {
678     return;
679   }
680 
681   // Close Stitch buffer acquire fence.
682   Layer *stitch_layer = stitch_target_->GetSDMLayer();
683   LayerBuffer &output_buffer = stitch_layer->input_buffer;
684   for (auto &layer : layer_stack_.layers) {
685     LayerComposition &composition = layer->composition;
686     if (composition != kCompositionStitch) {
687       continue;
688     }
689     LayerBuffer &input_buffer = layer->input_buffer;
690     input_buffer.release_fence = output_buffer.acquire_fence;
691   }
692 }
693 
GetColorModes(uint32_t * out_num_modes,ColorMode * out_modes)694 HWC2::Error HWCDisplayBuiltIn::GetColorModes(uint32_t *out_num_modes, ColorMode *out_modes) {
695   if (out_modes == nullptr) {
696     *out_num_modes = color_mode_->GetColorModeCount();
697   } else {
698     color_mode_->GetColorModes(out_num_modes, out_modes);
699   }
700 
701   return HWC2::Error::None;
702 }
703 
GetRenderIntents(ColorMode mode,uint32_t * out_num_intents,RenderIntent * out_intents)704 HWC2::Error HWCDisplayBuiltIn::GetRenderIntents(ColorMode mode, uint32_t *out_num_intents,
705                                                 RenderIntent *out_intents) {
706   if (out_intents == nullptr) {
707     *out_num_intents = color_mode_->GetRenderIntentCount(mode);
708   } else {
709     color_mode_->GetRenderIntents(mode, out_num_intents, out_intents);
710   }
711   return HWC2::Error::None;
712 }
713 
SetColorMode(ColorMode mode)714 HWC2::Error HWCDisplayBuiltIn::SetColorMode(ColorMode mode) {
715   return SetColorModeWithRenderIntent(mode, RenderIntent::COLORIMETRIC);
716 }
717 
SetColorModeWithRenderIntent(ColorMode mode,RenderIntent intent)718 HWC2::Error HWCDisplayBuiltIn::SetColorModeWithRenderIntent(ColorMode mode, RenderIntent intent) {
719   auto status = color_mode_->CacheColorModeWithRenderIntent(mode, intent);
720   if (status != HWC2::Error::None) {
721     DLOGE("failed for mode = %d intent = %d", mode, intent);
722     return status;
723   }
724   callbacks_->Refresh(id_);
725   validated_ = false;
726   return status;
727 }
728 
SetColorModeById(int32_t color_mode_id)729 HWC2::Error HWCDisplayBuiltIn::SetColorModeById(int32_t color_mode_id) {
730   auto status = color_mode_->SetColorModeById(color_mode_id);
731   if (status != HWC2::Error::None) {
732     DLOGE("failed for mode = %d", color_mode_id);
733     return status;
734   }
735 
736   callbacks_->Refresh(id_);
737   validated_ = false;
738 
739   return status;
740 }
741 
SetColorModeFromClientApi(int32_t color_mode_id)742 HWC2::Error HWCDisplayBuiltIn::SetColorModeFromClientApi(int32_t color_mode_id) {
743   DisplayError error = kErrorNone;
744   std::string mode_string;
745 
746   error = display_intf_->GetColorModeName(color_mode_id, &mode_string);
747   if (error) {
748     DLOGE("Failed to get mode name for mode %d", color_mode_id);
749     return HWC2::Error::BadParameter;
750   }
751 
752   auto status = color_mode_->SetColorModeFromClientApi(mode_string);
753   if (status != HWC2::Error::None) {
754     DLOGE("Failed to set mode = %d", color_mode_id);
755     return status;
756   }
757 
758   return status;
759 }
760 
RestoreColorTransform()761 HWC2::Error HWCDisplayBuiltIn::RestoreColorTransform() {
762   auto status = color_mode_->RestoreColorTransform();
763   if (status != HWC2::Error::None) {
764     DLOGE("failed to RestoreColorTransform");
765     return status;
766   }
767 
768   callbacks_->Refresh(id_);
769 
770   return status;
771 }
772 
SetColorTransform(const float * matrix,android_color_transform_t hint)773 HWC2::Error HWCDisplayBuiltIn::SetColorTransform(const float *matrix,
774                                                  android_color_transform_t hint) {
775   if (!matrix) {
776     return HWC2::Error::BadParameter;
777   }
778 
779   auto status = color_mode_->SetColorTransform(matrix, hint);
780   if (status != HWC2::Error::None) {
781     DLOGE("failed for hint = %d", hint);
782     color_tranform_failed_ = true;
783     return status;
784   }
785 
786   callbacks_->Refresh(id_);
787   color_tranform_failed_ = false;
788   validated_ = false;
789 
790   return status;
791 }
792 
SetReadbackBuffer(const native_handle_t * buffer,shared_ptr<Fence> acquire_fence,bool post_processed_output,CWBClient client)793 HWC2::Error HWCDisplayBuiltIn::SetReadbackBuffer(const native_handle_t *buffer,
794                                                  shared_ptr<Fence> acquire_fence,
795                                                  bool post_processed_output, CWBClient client) {
796   if (cwb_client_ != client && cwb_client_ != kCWBClientNone) {
797     DLOGE("CWB is in use with client = %d", cwb_client_);
798     return HWC2::Error::NoResources;
799   }
800 
801   const private_handle_t *handle = reinterpret_cast<const private_handle_t *>(buffer);
802   if (!handle || (handle->fd < 0)) {
803     return HWC2::Error::BadParameter;
804   }
805 
806   // Configure the output buffer as Readback buffer
807   output_buffer_.width = UINT32(handle->width);
808   output_buffer_.height = UINT32(handle->height);
809   output_buffer_.unaligned_width = UINT32(handle->unaligned_width);
810   output_buffer_.unaligned_height = UINT32(handle->unaligned_height);
811   output_buffer_.format = HWCLayer::GetSDMFormat(handle->format, handle->flags);
812   output_buffer_.planes[0].fd = handle->fd;
813   output_buffer_.planes[0].stride = UINT32(handle->width);
814   output_buffer_.acquire_fence = acquire_fence;
815   output_buffer_.handle_id = handle->id;
816 
817   post_processed_output_ = post_processed_output;
818   readback_buffer_queued_ = true;
819   readback_configured_ = false;
820   validated_ = false;
821   cwb_client_ = client;
822 
823   return HWC2::Error::None;
824 }
825 
GetReadbackBufferFence(shared_ptr<Fence> * release_fence)826 HWC2::Error HWCDisplayBuiltIn::GetReadbackBufferFence(shared_ptr<Fence> *release_fence) {
827   auto status = HWC2::Error::None;
828 
829   if (readback_configured_ && output_buffer_.release_fence) {
830     *release_fence = output_buffer_.release_fence;
831   } else {
832     status = HWC2::Error::Unsupported;
833   }
834 
835   post_processed_output_ = false;
836   readback_buffer_queued_ = false;
837   readback_configured_ = false;
838   output_buffer_ = {};
839   cwb_client_ = kCWBClientNone;
840 
841   return status;
842 }
843 
TeardownConcurrentWriteback(void)844 DisplayError HWCDisplayBuiltIn::TeardownConcurrentWriteback(void) {
845   DisplayError error = kErrorNotSupported;
846   if (Fence::Wait(output_buffer_.release_fence) != kErrorNone) {
847     DLOGE("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
848     return kErrorResources;
849   }
850 
851   if (display_intf_) {
852     error = display_intf_->TeardownConcurrentWriteback();
853   }
854 
855   return error;
856 }
857 
SetDisplayDppsAdROI(uint32_t h_start,uint32_t h_end,uint32_t v_start,uint32_t v_end,uint32_t factor_in,uint32_t factor_out)858 HWC2::Error HWCDisplayBuiltIn::SetDisplayDppsAdROI(uint32_t h_start, uint32_t h_end,
859                                                    uint32_t v_start, uint32_t v_end,
860                                                    uint32_t factor_in, uint32_t factor_out) {
861   DisplayError error = kErrorNone;
862   DisplayDppsAd4RoiCfg dpps_ad4_roi_cfg = {};
863   uint32_t panel_width = 0, panel_height = 0;
864   constexpr uint16_t kMaxFactorVal = 0xffff;
865 
866   if (h_start >= h_end || v_start >= v_end || factor_in > kMaxFactorVal ||
867       factor_out > kMaxFactorVal) {
868     DLOGE("Invalid roi region = [%u, %u, %u, %u, %u, %u]",
869            h_start, h_end, v_start, v_end, factor_in, factor_out);
870     return HWC2::Error::BadParameter;
871   }
872 
873   GetPanelResolution(&panel_width, &panel_height);
874 
875   if (h_start >= panel_width || h_end > panel_width ||
876       v_start >= panel_height || v_end > panel_height) {
877     DLOGE("Invalid roi region = [%u, %u, %u, %u], panel resolution = [%u, %u]",
878            h_start, h_end, v_start, v_end, panel_width, panel_height);
879     return HWC2::Error::BadParameter;
880   }
881 
882   dpps_ad4_roi_cfg.h_start = h_start;
883   dpps_ad4_roi_cfg.h_end = h_end;
884   dpps_ad4_roi_cfg.v_start = v_start;
885   dpps_ad4_roi_cfg.v_end = v_end;
886   dpps_ad4_roi_cfg.factor_in = factor_in;
887   dpps_ad4_roi_cfg.factor_out = factor_out;
888 
889   error = display_intf_->SetDisplayDppsAdROI(&dpps_ad4_roi_cfg);
890   if (error)
891     return HWC2::Error::BadConfig;
892 
893   callbacks_->Refresh(id_);
894 
895   return HWC2::Error::None;
896 }
897 
SetFrameTriggerMode(uint32_t mode)898 HWC2::Error HWCDisplayBuiltIn::SetFrameTriggerMode(uint32_t mode) {
899   DisplayError error = kErrorNone;
900   FrameTriggerMode trigger_mode = kFrameTriggerDefault;
901 
902   if (mode >= kFrameTriggerMax) {
903     DLOGE("Invalid input mode %d", mode);
904     return HWC2::Error::BadParameter;
905   }
906 
907   trigger_mode = static_cast<FrameTriggerMode>(mode);
908   error = display_intf_->SetFrameTriggerMode(trigger_mode);
909   if (error)
910     return HWC2::Error::BadConfig;
911 
912   callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
913   validated_ = false;
914 
915   return HWC2::Error::None;
916 }
917 
Perform(uint32_t operation,...)918 int HWCDisplayBuiltIn::Perform(uint32_t operation, ...) {
919   va_list args;
920   va_start(args, operation);
921   int val = 0;
922   LayerSolidFill *solid_fill_color;
923   LayerRect *rect = NULL;
924 
925   switch (operation) {
926     case SET_METADATA_DYN_REFRESH_RATE:
927       val = va_arg(args, int32_t);
928       SetMetaDataRefreshRateFlag(val);
929       break;
930     case SET_BINDER_DYN_REFRESH_RATE:
931       val = va_arg(args, int32_t);
932       ForceRefreshRate(UINT32(val));
933       break;
934     case SET_DISPLAY_MODE:
935       val = va_arg(args, int32_t);
936       SetDisplayMode(UINT32(val));
937       break;
938     case SET_QDCM_SOLID_FILL_INFO:
939       solid_fill_color = va_arg(args, LayerSolidFill*);
940       SetQDCMSolidFillInfo(true, *solid_fill_color);
941       break;
942     case UNSET_QDCM_SOLID_FILL_INFO:
943       solid_fill_color = va_arg(args, LayerSolidFill*);
944       SetQDCMSolidFillInfo(false, *solid_fill_color);
945       break;
946     case SET_QDCM_SOLID_FILL_RECT:
947       rect = va_arg(args, LayerRect*);
948       solid_fill_rect_ = *rect;
949       break;
950     default:
951       DLOGW("Invalid operation %d", operation);
952       va_end(args);
953       return -EINVAL;
954   }
955   va_end(args);
956   validated_ = false;
957 
958   return 0;
959 }
960 
SetDisplayMode(uint32_t mode)961 DisplayError HWCDisplayBuiltIn::SetDisplayMode(uint32_t mode) {
962   DisplayError error = kErrorNone;
963 
964   if (display_intf_) {
965     error = display_intf_->SetDisplayMode(mode);
966     if (error == kErrorNone) {
967       DisplayConfigFixedInfo fixed_info = {};
968       display_intf_->GetConfig(&fixed_info);
969       is_cmd_mode_ = fixed_info.is_cmdmode;
970       partial_update_enabled_ = fixed_info.partial_update;
971       for (auto hwc_layer : layer_set_) {
972         hwc_layer->SetPartialUpdate(partial_update_enabled_);
973       }
974       client_target_->SetPartialUpdate(partial_update_enabled_);
975     }
976   }
977 
978   return error;
979 }
980 
SetMetaDataRefreshRateFlag(bool enable)981 void HWCDisplayBuiltIn::SetMetaDataRefreshRateFlag(bool enable) {
982   int disable_metadata_dynfps = 0;
983 
984   HWCDebugHandler::Get()->GetProperty(DISABLE_METADATA_DYNAMIC_FPS_PROP, &disable_metadata_dynfps);
985   if (disable_metadata_dynfps) {
986     return;
987   }
988   use_metadata_refresh_rate_ = enable;
989 }
990 
SetQDCMSolidFillInfo(bool enable,const LayerSolidFill & color)991 void HWCDisplayBuiltIn::SetQDCMSolidFillInfo(bool enable, const LayerSolidFill &color) {
992   solid_fill_enable_ = enable;
993   solid_fill_color_ = color;
994 }
995 
ToggleCPUHint(bool set)996 void HWCDisplayBuiltIn::ToggleCPUHint(bool set) {
997   if (!cpu_hint_ || !perf_hint_window_) {
998     return;
999   }
1000 
1001   if (set) {
1002     cpu_hint_->Set();
1003   } else {
1004     cpu_hint_->Reset();
1005   }
1006 }
1007 
HandleSecureSession(const std::bitset<kSecureMax> & secure_sessions,bool * power_on_pending,bool is_active_secure_display)1008 int HWCDisplayBuiltIn::HandleSecureSession(const std::bitset<kSecureMax> &secure_sessions,
1009                                            bool *power_on_pending, bool is_active_secure_display) {
1010   if (!power_on_pending) {
1011     return -EINVAL;
1012   }
1013 
1014   if (!is_active_secure_display) {
1015     // Do handling as done on non-primary displays.
1016     DLOGI("Default handling for display %" PRIu64 " %d-%d", id_, sdm_id_, type_);
1017     return HWCDisplay::HandleSecureSession(secure_sessions, power_on_pending,
1018                                            is_active_secure_display);
1019   }
1020 
1021   if (current_power_mode_ != HWC2::PowerMode::On) {
1022     return 0;
1023   }
1024 
1025   if (active_secure_sessions_[kSecureDisplay] != secure_sessions[kSecureDisplay]) {
1026     SecureEvent secure_event =
1027         secure_sessions.test(kSecureDisplay) ? kSecureDisplayStart : kSecureDisplayEnd;
1028     DisplayError err = display_intf_->HandleSecureEvent(secure_event, &layer_stack_);
1029     if (err != kErrorNone) {
1030       DLOGE("Set secure event failed");
1031       return err;
1032     }
1033 
1034     DLOGI("SecureDisplay state changed from %d to %d for display %" PRIu64 " %d-%d",
1035           active_secure_sessions_.test(kSecureDisplay), secure_sessions.test(kSecureDisplay),
1036           id_, sdm_id_, type_);
1037   }
1038   active_secure_sessions_ = secure_sessions;
1039   *power_on_pending = false;
1040   return 0;
1041 }
1042 
ForceRefreshRate(uint32_t refresh_rate)1043 void HWCDisplayBuiltIn::ForceRefreshRate(uint32_t refresh_rate) {
1044   if ((refresh_rate && (refresh_rate < min_refresh_rate_ || refresh_rate > max_refresh_rate_)) ||
1045       force_refresh_rate_ == refresh_rate) {
1046     // Cannot honor force refresh rate, as its beyond the range or new request is same
1047     return;
1048   }
1049 
1050   force_refresh_rate_ = refresh_rate;
1051 
1052   callbacks_->Refresh(id_);
1053 
1054   return;
1055 }
1056 
GetOptimalRefreshRate(bool one_updating_layer)1057 uint32_t HWCDisplayBuiltIn::GetOptimalRefreshRate(bool one_updating_layer) {
1058   if (force_refresh_rate_) {
1059     return force_refresh_rate_;
1060   } else if (use_metadata_refresh_rate_ && one_updating_layer && metadata_refresh_rate_) {
1061     return metadata_refresh_rate_;
1062   }
1063 
1064   DLOGV_IF(kTagClient, "active_refresh_rate_: %d", active_refresh_rate_);
1065   return active_refresh_rate_;
1066 }
1067 
SetIdleTimeoutMs(uint32_t timeout_ms,uint32_t inactive_ms)1068 void HWCDisplayBuiltIn::SetIdleTimeoutMs(uint32_t timeout_ms, uint32_t inactive_ms) {
1069   display_intf_->SetIdleTimeoutMs(timeout_ms, inactive_ms);
1070   validated_ = false;
1071 }
1072 
HandleFrameOutput()1073 void HWCDisplayBuiltIn::HandleFrameOutput() {
1074   if (readback_buffer_queued_) {
1075     validated_ = false;
1076   }
1077 
1078   if (frame_capture_buffer_queued_) {
1079     HandleFrameCapture();
1080   } else if (dump_output_to_file_) {
1081     HandleFrameDump();
1082   }
1083 }
1084 
HandleFrameCapture()1085 void HWCDisplayBuiltIn::HandleFrameCapture() {
1086   if (readback_configured_ && output_buffer_.release_fence) {
1087     frame_capture_status_ = Fence::Wait(output_buffer_.release_fence);
1088   }
1089 
1090   frame_capture_buffer_queued_ = false;
1091   readback_buffer_queued_ = false;
1092   post_processed_output_ = false;
1093   readback_configured_ = false;
1094   output_buffer_ = {};
1095   cwb_client_ = kCWBClientNone;
1096 }
1097 
HandleFrameDump()1098 void HWCDisplayBuiltIn::HandleFrameDump() {
1099   if (dump_frame_count_) {
1100     int ret = 0;
1101     ret = Fence::Wait(output_buffer_.release_fence);
1102     if (ret != kErrorNone) {
1103       DLOGE("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
1104     }
1105 
1106     if (!ret) {
1107       DumpOutputBuffer(output_buffer_info_, output_buffer_base_, layer_stack_.retire_fence);
1108       validated_ = false;
1109     }
1110 
1111     if (0 == (dump_frame_count_ - 1)) {
1112       dump_output_to_file_ = false;
1113       // Unmap and Free buffer
1114       if (munmap(output_buffer_base_, output_buffer_info_.alloc_buffer_info.size) != 0) {
1115         DLOGE("unmap failed with err %d", errno);
1116       }
1117       if (buffer_allocator_->FreeBuffer(&output_buffer_info_) != 0) {
1118         DLOGE("FreeBuffer failed");
1119       }
1120 
1121       readback_buffer_queued_ = false;
1122       post_processed_output_ = false;
1123       readback_configured_ = false;
1124 
1125       output_buffer_ = {};
1126       output_buffer_info_ = {};
1127       output_buffer_base_ = nullptr;
1128       cwb_client_ = kCWBClientNone;
1129     }
1130   }
1131 }
1132 
SetFrameDumpConfig(uint32_t count,uint32_t bit_mask_layer_type,int32_t format,bool post_processed)1133 HWC2::Error HWCDisplayBuiltIn::SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type,
1134                                                   int32_t format, bool post_processed) {
1135   HWCDisplay::SetFrameDumpConfig(count, bit_mask_layer_type, format, post_processed);
1136   dump_output_to_file_ = bit_mask_layer_type & (1 << OUTPUT_LAYER_DUMP);
1137   DLOGI("output_layer_dump_enable %d", dump_output_to_file_);
1138 
1139   if (dump_output_to_file_) {
1140     if (cwb_client_ != kCWBClientNone) {
1141       DLOGW("CWB is in use with client = %d", cwb_client_);
1142       return HWC2::Error::NoResources;
1143     }
1144   }
1145 
1146   if (!count || !dump_output_to_file_ || (output_buffer_info_.alloc_buffer_info.fd >= 0)) {
1147     return HWC2::Error::None;
1148   }
1149 
1150   // Allocate and map output buffer
1151   if (post_processed) {
1152     // To dump post-processed (DSPP) output, use Panel resolution.
1153     GetPanelResolution(&output_buffer_info_.buffer_config.width,
1154                        &output_buffer_info_.buffer_config.height);
1155   } else {
1156     // To dump Layer Mixer output, use FrameBuffer resolution.
1157     GetFrameBufferResolution(&output_buffer_info_.buffer_config.width,
1158                              &output_buffer_info_.buffer_config.height);
1159   }
1160 
1161   output_buffer_info_.buffer_config.format = HWCLayer::GetSDMFormat(format, 0);
1162   output_buffer_info_.buffer_config.buffer_count = 1;
1163   if (buffer_allocator_->AllocateBuffer(&output_buffer_info_) != 0) {
1164     DLOGE("Buffer allocation failed");
1165     output_buffer_info_ = {};
1166     return HWC2::Error::NoResources;
1167   }
1168 
1169   void *buffer = mmap(NULL, output_buffer_info_.alloc_buffer_info.size, PROT_READ | PROT_WRITE,
1170                       MAP_SHARED, output_buffer_info_.alloc_buffer_info.fd, 0);
1171 
1172   if (buffer == MAP_FAILED) {
1173     DLOGE("mmap failed with err %d", errno);
1174     buffer_allocator_->FreeBuffer(&output_buffer_info_);
1175     output_buffer_info_ = {};
1176     return HWC2::Error::NoResources;
1177   }
1178 
1179   output_buffer_base_ = buffer;
1180   const native_handle_t *handle = static_cast<native_handle_t *>(output_buffer_info_.private_data);
1181   SetReadbackBuffer(handle, nullptr, post_processed, kCWBClientFrameDump);
1182 
1183   return HWC2::Error::None;
1184 }
1185 
FrameCaptureAsync(const BufferInfo & output_buffer_info,bool post_processed_output)1186 int HWCDisplayBuiltIn::FrameCaptureAsync(const BufferInfo &output_buffer_info,
1187                                          bool post_processed_output) {
1188   if (cwb_client_ != kCWBClientNone) {
1189     DLOGE("CWB is in use with client = %d", cwb_client_);
1190     return -1;
1191   }
1192 
1193   // Note: This function is called in context of a binder thread and a lock is already held
1194   if (output_buffer_info.alloc_buffer_info.fd < 0) {
1195     DLOGE("Invalid fd %d", output_buffer_info.alloc_buffer_info.fd);
1196     return -1;
1197   }
1198 
1199   auto panel_width = 0u;
1200   auto panel_height = 0u;
1201   auto fb_width = 0u;
1202   auto fb_height = 0u;
1203 
1204   GetPanelResolution(&panel_width, &panel_height);
1205   GetFrameBufferResolution(&fb_width, &fb_height);
1206 
1207   if (post_processed_output && (output_buffer_info.buffer_config.width < panel_width ||
1208                                 output_buffer_info.buffer_config.height < panel_height)) {
1209     DLOGE("Buffer dimensions should not be less than panel resolution");
1210     return -1;
1211   } else if (!post_processed_output && (output_buffer_info.buffer_config.width < fb_width ||
1212                                         output_buffer_info.buffer_config.height < fb_height)) {
1213     DLOGE("Buffer dimensions should not be less than FB resolution");
1214     return -1;
1215   }
1216 
1217   const native_handle_t *buffer = static_cast<native_handle_t *>(output_buffer_info.private_data);
1218   SetReadbackBuffer(buffer, nullptr, post_processed_output, kCWBClientColor);
1219   frame_capture_buffer_queued_ = true;
1220   frame_capture_status_ = -EAGAIN;
1221 
1222   return 0;
1223 }
1224 
SetDetailEnhancerConfig(const DisplayDetailEnhancerData & de_data)1225 DisplayError HWCDisplayBuiltIn::SetDetailEnhancerConfig
1226                                    (const DisplayDetailEnhancerData &de_data) {
1227   DisplayError error = kErrorNotSupported;
1228 
1229   if (display_intf_) {
1230     error = display_intf_->SetDetailEnhancerData(de_data);
1231     validated_ = false;
1232   }
1233   return error;
1234 }
1235 
SetHWDetailedEnhancerConfig(void * params)1236 DisplayError HWCDisplayBuiltIn::SetHWDetailedEnhancerConfig(void *params) {
1237   DisplayError err = kErrorNone;
1238   DisplayDetailEnhancerData de_data;
1239 
1240   PPDETuningCfgData *de_tuning_cfg_data = reinterpret_cast<PPDETuningCfgData*>(params);
1241   if (de_tuning_cfg_data->cfg_pending) {
1242     if (!de_tuning_cfg_data->cfg_en) {
1243       de_data.enable = 0;
1244       DLOGV_IF(kTagQDCM, "Disable DE config");
1245     } else {
1246       de_data.override_flags = kOverrideDEEnable;
1247       de_data.enable = 1;
1248 
1249       DLOGV_IF(kTagQDCM, "Enable DE: flags %u, sharp_factor %d, thr_quiet %d, thr_dieout %d, "
1250         "thr_low %d, thr_high %d, clip %d, quality %d, content_type %d, de_blend %d",
1251         de_tuning_cfg_data->params.flags, de_tuning_cfg_data->params.sharp_factor,
1252         de_tuning_cfg_data->params.thr_quiet, de_tuning_cfg_data->params.thr_dieout,
1253         de_tuning_cfg_data->params.thr_low, de_tuning_cfg_data->params.thr_high,
1254         de_tuning_cfg_data->params.clip, de_tuning_cfg_data->params.quality,
1255         de_tuning_cfg_data->params.content_type, de_tuning_cfg_data->params.de_blend);
1256 
1257       if (de_tuning_cfg_data->params.flags & kDeTuningFlagSharpFactor) {
1258         de_data.override_flags |= kOverrideDESharpen1;
1259         de_data.sharp_factor = de_tuning_cfg_data->params.sharp_factor;
1260       }
1261 
1262       if (de_tuning_cfg_data->params.flags & kDeTuningFlagClip) {
1263         de_data.override_flags |= kOverrideDEClip;
1264         de_data.clip = de_tuning_cfg_data->params.clip;
1265       }
1266 
1267       if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrQuiet) {
1268         de_data.override_flags |= kOverrideDEThrQuiet;
1269         de_data.thr_quiet = de_tuning_cfg_data->params.thr_quiet;
1270       }
1271 
1272       if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrDieout) {
1273         de_data.override_flags |= kOverrideDEThrDieout;
1274         de_data.thr_dieout = de_tuning_cfg_data->params.thr_dieout;
1275       }
1276 
1277       if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrLow) {
1278         de_data.override_flags |= kOverrideDEThrLow;
1279         de_data.thr_low = de_tuning_cfg_data->params.thr_low;
1280       }
1281 
1282       if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrHigh) {
1283         de_data.override_flags |= kOverrideDEThrHigh;
1284         de_data.thr_high = de_tuning_cfg_data->params.thr_high;
1285       }
1286 
1287       if (de_tuning_cfg_data->params.flags & kDeTuningFlagContentQualLevel) {
1288         switch (de_tuning_cfg_data->params.quality) {
1289           case kDeContentQualLow:
1290             de_data.quality_level = kContentQualityLow;
1291             break;
1292           case kDeContentQualMedium:
1293             de_data.quality_level = kContentQualityMedium;
1294             break;
1295           case kDeContentQualHigh:
1296             de_data.quality_level = kContentQualityHigh;
1297             break;
1298           case kDeContentQualUnknown:
1299           default:
1300             de_data.quality_level = kContentQualityUnknown;
1301             break;
1302         }
1303       }
1304 
1305       if (de_tuning_cfg_data->params.flags & kDeTuningFlagDeBlend) {
1306         de_data.override_flags |= kOverrideDEBlend;
1307         de_data.de_blend = de_tuning_cfg_data->params.de_blend;
1308       }
1309     }
1310     err = SetDetailEnhancerConfig(de_data);
1311     if (err) {
1312       DLOGW("SetDetailEnhancerConfig failed. err = %d", err);
1313     }
1314     de_tuning_cfg_data->cfg_pending = false;
1315   }
1316   return err;
1317 }
1318 
ControlPartialUpdate(bool enable,uint32_t * pending)1319 DisplayError HWCDisplayBuiltIn::ControlPartialUpdate(bool enable, uint32_t *pending) {
1320   DisplayError error = kErrorNone;
1321 
1322   if (display_intf_) {
1323     error = display_intf_->ControlPartialUpdate(enable, pending);
1324     validated_ = false;
1325   }
1326 
1327   return error;
1328 }
1329 
DisablePartialUpdateOneFrame()1330 DisplayError HWCDisplayBuiltIn::DisablePartialUpdateOneFrame() {
1331   DisplayError error = kErrorNone;
1332 
1333   if (display_intf_) {
1334     error = display_intf_->DisablePartialUpdateOneFrame();
1335     validated_ = false;
1336   }
1337 
1338   return error;
1339 }
1340 
SetDisplayedContentSamplingEnabledVndService(bool enabled)1341 HWC2::Error HWCDisplayBuiltIn::SetDisplayedContentSamplingEnabledVndService(bool enabled) {
1342   std::unique_lock<decltype(sampling_mutex)> lk(sampling_mutex);
1343   vndservice_sampling_vote = enabled;
1344   if (api_sampling_vote || vndservice_sampling_vote) {
1345 #ifndef TARGET_HEADLESS
1346     histogram.start();
1347     display_intf_->colorSamplingOn();
1348   } else {
1349     display_intf_->colorSamplingOff();
1350     histogram.stop();
1351 #endif
1352   }
1353   return HWC2::Error::None;
1354 }
1355 
SetDisplayedContentSamplingEnabled(int32_t enabled,uint8_t component_mask,uint64_t max_frames)1356 HWC2::Error HWCDisplayBuiltIn::SetDisplayedContentSamplingEnabled(int32_t enabled,
1357                                                                   uint8_t component_mask,
1358                                                                   uint64_t max_frames) {
1359   if ((enabled != HWC2_DISPLAYED_CONTENT_SAMPLING_ENABLE) &&
1360       (enabled != HWC2_DISPLAYED_CONTENT_SAMPLING_DISABLE))
1361     return HWC2::Error::BadParameter;
1362 
1363   std::unique_lock<decltype(sampling_mutex)> lk(sampling_mutex);
1364   if (enabled == HWC2_DISPLAYED_CONTENT_SAMPLING_ENABLE) {
1365     api_sampling_vote = true;
1366   } else {
1367     api_sampling_vote = false;
1368   }
1369 
1370   auto start = api_sampling_vote || vndservice_sampling_vote;
1371   if (start && max_frames == 0) {
1372 #ifndef TARGET_HEADLESS
1373     histogram.start();
1374     display_intf_->colorSamplingOn();
1375   } else if (start) {
1376     histogram.start(max_frames);
1377     display_intf_->colorSamplingOn();
1378   } else {
1379     display_intf_->colorSamplingOff();
1380     histogram.stop();
1381 #endif
1382   }
1383   return HWC2::Error::None;
1384 }
1385 
GetDisplayedContentSamplingAttributes(int32_t * format,int32_t * dataspace,uint8_t * supported_components)1386 HWC2::Error HWCDisplayBuiltIn::GetDisplayedContentSamplingAttributes(
1387     int32_t *format, int32_t *dataspace, uint8_t *supported_components) {
1388 #ifndef TARGET_HEADLESS
1389  return histogram.getAttributes(format, dataspace, supported_components);
1390 #endif
1391  return HWC2::Error::None;
1392 }
1393 
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])1394 HWC2::Error HWCDisplayBuiltIn::GetDisplayedContentSample(
1395     uint64_t max_frames, uint64_t timestamp, uint64_t *numFrames,
1396     int32_t samples_size[NUM_HISTOGRAM_COLOR_COMPONENTS],
1397     uint64_t *samples[NUM_HISTOGRAM_COLOR_COMPONENTS]) {
1398 #ifndef TARGET_HEADLESS
1399   histogram.collect(max_frames, timestamp, samples_size, samples, numFrames);
1400 #endif
1401   return HWC2::Error::None;
1402 }
1403 
SetMixerResolution(uint32_t width,uint32_t height)1404 DisplayError HWCDisplayBuiltIn::SetMixerResolution(uint32_t width, uint32_t height) {
1405   DisplayError error = display_intf_->SetMixerResolution(width, height);
1406   callbacks_->Refresh(id_);
1407   validated_ = false;
1408   return error;
1409 }
1410 
GetMixerResolution(uint32_t * width,uint32_t * height)1411 DisplayError HWCDisplayBuiltIn::GetMixerResolution(uint32_t *width, uint32_t *height) {
1412   return display_intf_->GetMixerResolution(width, height);
1413 }
1414 
SetQSyncMode(QSyncMode qsync_mode)1415 HWC2::Error HWCDisplayBuiltIn::SetQSyncMode(QSyncMode qsync_mode) {
1416   // Client needs to ensure that config change and qsync mode change
1417   // are not triggered in the same drawcycle.
1418   if (pending_config_) {
1419     DLOGE("Failed to set qsync mode. Pending active config transition");
1420     return HWC2::Error::Unsupported;
1421   }
1422 
1423   auto err = display_intf_->SetQSyncMode(qsync_mode);
1424   if (err != kErrorNone) {
1425     return HWC2::Error::Unsupported;
1426   }
1427 
1428   validated_ = false;
1429   return HWC2::Error::None;
1430 }
1431 
ControlIdlePowerCollapse(bool enable,bool synchronous)1432 DisplayError HWCDisplayBuiltIn::ControlIdlePowerCollapse(bool enable, bool synchronous) {
1433   DisplayError error = kErrorNone;
1434 
1435   if (display_intf_) {
1436     error = display_intf_->ControlIdlePowerCollapse(enable, synchronous);
1437     validated_ = false;
1438   }
1439   return error;
1440 }
1441 
SetDynamicDSIClock(uint64_t bitclk)1442 DisplayError HWCDisplayBuiltIn::SetDynamicDSIClock(uint64_t bitclk) {
1443   DisablePartialUpdateOneFrame();
1444   DisplayError error = display_intf_->SetDynamicDSIClock(bitclk);
1445   if (error != kErrorNone) {
1446     DLOGE(" failed: Clk: %" PRIu64 " Error: %d", bitclk, error);
1447     return error;
1448   }
1449 
1450   callbacks_->Refresh(id_);
1451   validated_ = false;
1452 
1453   return kErrorNone;
1454 }
1455 
GetDynamicDSIClock(uint64_t * bitclk)1456 DisplayError HWCDisplayBuiltIn::GetDynamicDSIClock(uint64_t *bitclk) {
1457   if (display_intf_) {
1458     return display_intf_->GetDynamicDSIClock(bitclk);
1459   }
1460 
1461   return kErrorNotSupported;
1462 }
1463 
GetSupportedDSIClock(std::vector<uint64_t> * bitclk_rates)1464 DisplayError HWCDisplayBuiltIn::GetSupportedDSIClock(std::vector<uint64_t> *bitclk_rates) {
1465   if (display_intf_) {
1466     return display_intf_->GetSupportedDSIClock(bitclk_rates);
1467   }
1468 
1469   return kErrorNotSupported;
1470 }
1471 
SetStandByMode(bool enable,bool is_twm)1472 DisplayError HWCDisplayBuiltIn::SetStandByMode(bool enable, bool is_twm) {
1473   if (enable) {
1474     if (!display_null_.IsActive()) {
1475       stored_display_intf_ = display_intf_;
1476       display_intf_ = &display_null_;
1477       shared_ptr<Fence> release_fence = nullptr;
1478 
1479       if (is_twm && current_power_mode_ == HWC2::PowerMode::On) {
1480         DLOGD("Display is in ON state and device is entering TWM mode.");
1481         DisplayError error = stored_display_intf_->SetDisplayState(kStateDoze,
1482                                 false /* teardown */,
1483                                 &release_fence);
1484         if (error != kErrorNone) {
1485           if (error == kErrorShutDown) {
1486             shutdown_pending_ = true;
1487             return error;
1488           }
1489           DLOGE("Set state failed. Error = %d", error);
1490           return error;
1491         } else {
1492           current_power_mode_ = HWC2::PowerMode::Doze;
1493           DLOGD("Display moved to DOZE state.");
1494         }
1495       }
1496 
1497       display_null_.SetActive(true);
1498       DLOGD("Null display is connected successfully");
1499     } else {
1500       DLOGD("Null display is already connected.");
1501     }
1502   } else {
1503     if (display_null_.IsActive()) {
1504       if (is_twm) {
1505         DLOGE("Unexpected event. Display state may be inconsistent.");
1506         return kErrorNotSupported;
1507       }
1508       display_intf_ = stored_display_intf_;
1509       validated_ = false;
1510       display_null_.SetActive(false);
1511       DLOGD("Display is connected successfully");
1512     } else {
1513       DLOGD("Display is already connected.");
1514     }
1515   }
1516   return kErrorNone;
1517 }
1518 
DelayFirstCommit()1519 DisplayError HWCDisplayBuiltIn::DelayFirstCommit() {
1520   if (display_intf_) {
1521     return display_intf_->DelayFirstCommit();
1522   }
1523 
1524   return kErrorNotSupported;
1525 }
1526 
UpdateDisplayId(hwc2_display_t id)1527 HWC2::Error HWCDisplayBuiltIn::UpdateDisplayId(hwc2_display_t id) {
1528   id_ = id;
1529   return HWC2::Error::None;
1530 }
1531 
SetPendingRefresh()1532 HWC2::Error HWCDisplayBuiltIn::SetPendingRefresh() {
1533   pending_refresh_ = true;
1534   return HWC2::Error::None;
1535 }
1536 
SetPanelBrightness(float brightness)1537 HWC2::Error HWCDisplayBuiltIn::SetPanelBrightness(float brightness) {
1538   DisplayError ret = display_intf_->SetPanelBrightness(brightness);
1539   if (ret != kErrorNone) {
1540     return HWC2::Error::NoResources;
1541   }
1542 
1543   return HWC2::Error::None;
1544 }
1545 
GetPanelBrightness(float * brightness)1546 HWC2::Error HWCDisplayBuiltIn::GetPanelBrightness(float *brightness) {
1547   DisplayError ret = display_intf_->GetPanelBrightness(brightness);
1548   if (ret != kErrorNone) {
1549     return HWC2::Error::NoResources;
1550   }
1551 
1552   return HWC2::Error::None;
1553 }
1554 
GetPanelMaxBrightness(uint32_t * max_brightness_level)1555 HWC2::Error HWCDisplayBuiltIn::GetPanelMaxBrightness(uint32_t *max_brightness_level) {
1556   DisplayError ret = display_intf_->GetPanelMaxBrightness(max_brightness_level);
1557   if (ret != kErrorNone) {
1558     return HWC2::Error::NoResources;
1559   }
1560 
1561   return HWC2::Error::None;
1562 }
1563 
SetCurrentPanelGammaSource(enum PanelGammaSource source)1564 DisplayError HWCDisplayBuiltIn::SetCurrentPanelGammaSource(enum PanelGammaSource source) {
1565   DisplayError error = UpdatePanelGammaTable(source);
1566   if (error == kErrorNone) {
1567     current_panel_gamma_source_ = source;
1568   }
1569 
1570   return error;
1571 }
1572 
SetBLScale(uint32_t level)1573 HWC2::Error HWCDisplayBuiltIn::SetBLScale(uint32_t level) {
1574   DisplayError ret = display_intf_->SetBLScale(level);
1575   if (ret != kErrorNone) {
1576     return HWC2::Error::NoResources;
1577   }
1578   return HWC2::Error::None;
1579 }
1580 
UpdatePowerMode(HWC2::PowerMode mode)1581 HWC2::Error HWCDisplayBuiltIn::UpdatePowerMode(HWC2::PowerMode mode) {
1582   current_power_mode_ = mode;
1583   validated_ = false;
1584   return HWC2::Error::None;
1585 }
1586 
SetClientTarget(buffer_handle_t target,shared_ptr<Fence> acquire_fence,int32_t dataspace,hwc_region_t damage)1587 HWC2::Error HWCDisplayBuiltIn::SetClientTarget(buffer_handle_t target,
1588                                                shared_ptr<Fence> acquire_fence,
1589                                                int32_t dataspace, hwc_region_t damage) {
1590   HWC2::Error error = HWCDisplay::SetClientTarget(target, acquire_fence, dataspace, damage);
1591   if (error != HWC2::Error::None) {
1592     return error;
1593   }
1594 
1595   // windowed_display and dynamic scaling are not supported.
1596   if (windowed_display_) {
1597     return HWC2::Error::None;
1598   }
1599 
1600   Layer *sdm_layer = client_target_->GetSDMLayer();
1601   uint32_t fb_width = 0, fb_height = 0;
1602 
1603   GetFrameBufferResolution(&fb_width, &fb_height);
1604 
1605   if (fb_width != sdm_layer->input_buffer.unaligned_width ||
1606       fb_height != sdm_layer->input_buffer.unaligned_height) {
1607     if (SetFrameBufferConfig(sdm_layer->input_buffer.unaligned_width,
1608                              sdm_layer->input_buffer.unaligned_height)) {
1609       return HWC2::Error::BadParameter;
1610     }
1611   }
1612 
1613   return HWC2::Error::None;
1614 }
1615 
IsSmartPanelConfig(uint32_t config_id)1616 bool HWCDisplayBuiltIn::IsSmartPanelConfig(uint32_t config_id) {
1617   if (config_id < hwc_config_map_.size()) {
1618     uint32_t index = hwc_config_map_.at(config_id);
1619     return variable_config_map_.at(index).smart_panel;
1620   }
1621 
1622   return false;
1623 }
1624 
HasSmartPanelConfig(void)1625 bool HWCDisplayBuiltIn::HasSmartPanelConfig(void) {
1626   if (!enable_poms_during_doze_) {
1627     uint32_t config = 0;
1628     GetActiveDisplayConfig(&config);
1629     return IsSmartPanelConfig(config);
1630   }
1631 
1632   return smart_panel_config_;
1633 }
1634 
Deinit()1635 int HWCDisplayBuiltIn::Deinit() {
1636   // Destory color convert instance. This destroys thread and underlying GL resources.
1637   if (gl_layer_stitch_) {
1638     layer_stitch_task_.PerformTask(LayerStitchTaskCode::kCodeDestroyInstance, nullptr);
1639   }
1640 #ifndef TARGET_HEADLESS
1641   histogram.stop();
1642 #endif
1643   return HWCDisplay::Deinit();
1644 }
1645 
OnTask(const LayerStitchTaskCode & task_code,SyncTask<LayerStitchTaskCode>::TaskContext * task_context)1646 void HWCDisplayBuiltIn::OnTask(const LayerStitchTaskCode &task_code,
1647                                SyncTask<LayerStitchTaskCode>::TaskContext *task_context) {
1648   switch (task_code) {
1649     case LayerStitchTaskCode::kCodeGetInstance: {
1650         gl_layer_stitch_ = GLLayerStitch::GetInstance(false /* Non-secure */);
1651       }
1652       break;
1653     case LayerStitchTaskCode::kCodeStitch: {
1654         DTRACE_SCOPED();
1655         LayerStitchContext* ctx = reinterpret_cast<LayerStitchContext*>(task_context);
1656         gl_layer_stitch_->Blit(ctx->stitch_params, &(ctx->release_fence));
1657       }
1658       break;
1659     case LayerStitchTaskCode::kCodeDestroyInstance: {
1660         if (gl_layer_stitch_) {
1661           GLLayerStitch::Destroy(gl_layer_stitch_);
1662         }
1663       }
1664       break;
1665   }
1666 }
1667 
InitLayerStitch()1668 bool HWCDisplayBuiltIn::InitLayerStitch() {
1669   if (!is_primary_) {
1670     // Disable on all non-primary builtins.
1671     DLOGI("Non-primary builtin.");
1672     disable_layer_stitch_ = true;
1673     return true;
1674   }
1675 
1676   // Disable by default.
1677   int value = 1;
1678   Debug::Get()->GetProperty(DISABLE_LAYER_STITCH, &value);
1679   disable_layer_stitch_ = (value == 1);
1680 
1681   if (disable_layer_stitch_) {
1682     DLOGI("Layer Stitch Disabled !!!");
1683     return true;
1684   }
1685 
1686   // Initialize stitch context. This will be non-secure.
1687   layer_stitch_task_.PerformTask(LayerStitchTaskCode::kCodeGetInstance, nullptr);
1688   if (gl_layer_stitch_ == nullptr) {
1689     DLOGE("Failed to get LayerStitch Instance");
1690     return false;
1691   }
1692 
1693   if (!AllocateStitchBuffer()) {
1694     return true;
1695   }
1696 
1697   stitch_target_ = new HWCLayer(id_, static_cast<HWCBufferAllocator *>(buffer_allocator_));
1698 
1699   // Populate buffer params and pvt handle.
1700   InitStitchTarget();
1701 
1702   DLOGI("Created LayerStitch instance: %p", gl_layer_stitch_);
1703 
1704   return true;
1705 }
1706 
AllocateStitchBuffer()1707 bool HWCDisplayBuiltIn::AllocateStitchBuffer() {
1708   // Buffer dimensions: FB width * (1.5 * height)
1709 
1710   DisplayError error = display_intf_->GetFrameBufferConfig(&fb_config_);
1711   if (error != kErrorNone) {
1712     DLOGE("Get frame buffer config failed. Error = %d", error);
1713     return false;
1714   }
1715 
1716   BufferConfig &config = buffer_info_.buffer_config;
1717   config.width = fb_config_.x_pixels;
1718   config.height = fb_config_.y_pixels * kBufferHeightFactor;
1719 
1720   // By default UBWC is enabled and below property is global enable/disable for all
1721   // buffers allocated through gralloc , including framebuffer targets.
1722   int ubwc_disabled = 0;
1723   HWCDebugHandler::Get()->GetProperty(DISABLE_UBWC_PROP, &ubwc_disabled);
1724   config.format = ubwc_disabled ? kFormatRGBA8888 : kFormatRGBA8888Ubwc;
1725 
1726   config.gfx_client = true;
1727 
1728   // Populate default params.
1729   config.secure = false;
1730   config.cache = false;
1731   config.secure_camera = false;
1732 
1733   error = buffer_allocator_->AllocateBuffer(&buffer_info_);
1734 
1735   if (error != kErrorNone) {
1736     DLOGE("Failed to allocate buffer. Error: %d", error);
1737     return false;
1738   }
1739 
1740   return true;
1741 }
1742 
InitStitchTarget()1743 void HWCDisplayBuiltIn::InitStitchTarget() {
1744   LayerBuffer buffer = {};
1745   buffer.planes[0].fd = buffer_info_.alloc_buffer_info.fd;
1746   buffer.planes[0].offset = 0;
1747   buffer.planes[0].stride = buffer_info_.alloc_buffer_info.stride;
1748   buffer.size = buffer_info_.alloc_buffer_info.size;
1749   buffer.handle_id = buffer_info_.alloc_buffer_info.id;
1750   buffer.width = buffer_info_.alloc_buffer_info.aligned_width;
1751   buffer.height = buffer_info_.alloc_buffer_info.aligned_height;
1752   buffer.unaligned_width = fb_config_.x_pixels;
1753   buffer.unaligned_height = fb_config_.y_pixels * kBufferHeightFactor;
1754   buffer.format = buffer_info_.alloc_buffer_info.format;
1755 
1756   Layer *sdm_stitch_target = stitch_target_->GetSDMLayer();
1757   sdm_stitch_target->composition = kCompositionStitchTarget;
1758   sdm_stitch_target->input_buffer = buffer;
1759   sdm_stitch_target->input_buffer.buffer_id = reinterpret_cast<uint64_t>(buffer_info_.private_data);
1760 }
1761 
AppendStitchLayer()1762 void HWCDisplayBuiltIn::AppendStitchLayer() {
1763   if (disable_layer_stitch_) {
1764     return;
1765   }
1766 
1767   // Append stitch target buffer to layer stack.
1768   Layer *sdm_stitch_target = stitch_target_->GetSDMLayer();
1769   sdm_stitch_target->composition = kCompositionStitchTarget;
1770   sdm_stitch_target->dst_rect = {0, 0, FLOAT(fb_config_.x_pixels), FLOAT(fb_config_.y_pixels)};
1771   layer_stack_.layers.push_back(sdm_stitch_target);
1772 }
1773 
HistogramEvent(int fd,uint32_t blob_id)1774 DisplayError HWCDisplayBuiltIn::HistogramEvent(int fd, uint32_t blob_id) {
1775 #ifndef TARGET_HEADLESS
1776   histogram.notify_histogram_event(fd, blob_id);
1777 #endif
1778   return kErrorNone;
1779 }
1780 
PostInit()1781 int HWCDisplayBuiltIn::PostInit() {
1782   auto status = InitLayerStitch();
1783   if (!status) {
1784     DLOGW("Failed to initialize Layer Stitch context");
1785     // Disable layer stitch.
1786     disable_layer_stitch_ = true;
1787   }
1788 
1789   return 0;
1790 }
1791 
HasReadBackBufferSupport()1792 bool HWCDisplayBuiltIn::HasReadBackBufferSupport() {
1793   DisplayConfigFixedInfo fixed_info = {};
1794   display_intf_->GetConfig(&fixed_info);
1795 
1796   uint32_t width = UINT32(window_rect_.right + window_rect_.left);
1797   uint32_t height = UINT32(window_rect_.bottom + window_rect_.top);
1798   if (width > 0 || height > 0) {
1799      DLOGE("No ReadBackBuffersupport on window_rect width = %u - height = %u",width,height);
1800      return false;
1801   }
1802 
1803   return fixed_info.readback_supported;
1804 }
1805 
GetUpdatingAppLayersCount()1806 uint32_t HWCDisplayBuiltIn::GetUpdatingAppLayersCount() {
1807   uint32_t updating_count = 0;
1808 
1809   for (auto layer:layer_stack_.layers) {
1810     if (layer->composition == kCompositionGPUTarget) {
1811       break;
1812     }
1813     if (layer->flags.updating) {
1814       updating_count++;
1815     }
1816   }
1817 
1818   return updating_count;
1819 }
1820 
IsDisplayIdle()1821 bool HWCDisplayBuiltIn::IsDisplayIdle() {
1822   // Notify only if this display is source of vsync.
1823   bool vsync_source = (callbacks_->GetVsyncSource() == id_);
1824   return vsync_source && display_idle_;
1825 }
1826 
SetCpuPerfHintLargeCompCycle()1827 void HWCDisplayBuiltIn::SetCpuPerfHintLargeCompCycle() {
1828   if (!cpu_hint_ || !perf_hint_large_comp_cycle_) {
1829     DLOGV_IF(kTagResources, "cpu_hint_ not initialized or property not set");
1830     return;
1831   }
1832 
1833   //Send large comp cycle hint only for fps >= 90
1834   if (active_refresh_rate_ < 90) {
1835     DLOGV_IF(kTagResources, "Skip large comp cycle hint for current fps - %u",
1836              active_refresh_rate_);
1837     return;
1838   }
1839 
1840   for (auto hwc_layer : layer_set_) {
1841     Layer *layer = hwc_layer->GetSDMLayer();
1842     if (layer->composition == kCompositionGPU) {
1843       DLOGV_IF(kTagResources, "Set perf hint for large comp cycle");
1844       int hwc_tid = gettid();
1845       cpu_hint_->ReqHintsOffload(kPerfHintLargeCompCycle, hwc_tid);
1846       break;
1847     }
1848   }
1849 }
1850 
ApplyHbmLocked()1851 HWC2::Error HWCDisplayBuiltIn::ApplyHbmLocked() {
1852   if (!mHasHbmNode)
1853     return HWC2::Error::Unsupported;
1854 
1855   HbmState state = HbmState::OFF;
1856   for (auto req : mHbmSates) {
1857     if (req == HbmState::SUNLIGHT) {
1858       state = HbmState::SUNLIGHT;
1859       break;
1860     } else if (req == HbmState::HDR) {
1861       state = HbmState::HDR;
1862     }
1863   }
1864 
1865   if (state == mCurHbmState)
1866     return HWC2::Error::None;
1867 
1868   std::string action = std::to_string(static_cast<int>(state));
1869   if (!android::base::WriteStringToFile(action, kHighBrightnessModeNode)) {
1870     DLOGE("Failed to write hbm node = %s, error = %s ", kHighBrightnessModeNode, strerror(errno));
1871   } else {
1872     DLOGI("write %s to HBM sysfs file succeeded", action.c_str());
1873   }
1874 
1875   mCurHbmState = state;
1876 
1877   return HWC2::Error::None;
1878 }
1879 
IsHbmSupported()1880 bool HWCDisplayBuiltIn::IsHbmSupported() {
1881   if (!mHasHbmNode)
1882     return false;
1883 
1884   bool is_hbm_supported = false;
1885   std::string buffer;
1886   if (!android::base::ReadFileToString(kHighBrightnessModeNode, &buffer)) {
1887     DLOGE("Failed to read hbm node = %s, error = %s ", kHighBrightnessModeNode, strerror(errno));
1888   } else if (buffer == "unsupported") {
1889     DLOGI("kernel driver does not support hbm");
1890   } else {
1891     is_hbm_supported = true;
1892   }
1893 
1894   return is_hbm_supported;
1895 }
1896 
SetHbm(HbmState state,HbmClient client)1897 HWC2::Error HWCDisplayBuiltIn::SetHbm(HbmState state, HbmClient client) {
1898   auto status = HWC2::Error::None;
1899   if (client >= CLIENT_MAX)
1900     return HWC2::Error::BadParameter;
1901 
1902   std::unique_lock<decltype(hbm_mutex)> lk(hbm_mutex);
1903 
1904   /* save and apply the request state */
1905   if (mHbmSates[client] != state) {
1906     mHbmSates[client] = state;
1907 
1908     status = ApplyHbmLocked();
1909     if (INT32(status) != HWC2_ERROR_NONE)
1910       DLOGE("Failed to apply hbm node, error = %d", status);
1911   }
1912 
1913   return status;
1914 }
1915 
GetHbm()1916 HbmState HWCDisplayBuiltIn::GetHbm() {
1917   return mCurHbmState;
1918 }
1919 
1920 }  // namespace sdm
1921