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