• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
3  * Not a Contribution.
4  *
5  * Copyright 2015 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #include <cutils/properties.h>
21 #include <errno.h>
22 #include <math.h>
23 #include <sync/sync.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <utils/constants.h>
27 #include <utils/debug.h>
28 #include <utils/utils.h>
29 #include <utils/formats.h>
30 #include <utils/rect.h>
31 #include <qd_utils.h>
32 #include <vendor/qti/hardware/display/composer/3.0/IQtiComposerClient.h>
33 
34 #include <algorithm>
35 #include <iomanip>
36 #include <map>
37 #include <sstream>
38 #include <string>
39 #include <utility>
40 #include <vector>
41 
42 #include "hwc_display.h"
43 #include "hwc_debugger.h"
44 #include "hwc_tonemapper.h"
45 #include "hwc_session.h"
46 
47 #ifdef QTI_BSP
48 #include <hardware/display_defs.h>
49 #endif
50 
51 #define __CLASS__ "HWCDisplay"
52 
53 namespace sdm {
54 
55 uint32_t HWCDisplay::throttling_refresh_rate_ = 60;
56 constexpr uint32_t kVsyncTimeDriftNs = 1000000;
57 
NeedsToneMap(const LayerStack & layer_stack)58 bool NeedsToneMap(const LayerStack &layer_stack) {
59   for (Layer *layer : layer_stack.layers) {
60     if (layer->request.flags.tone_map) {
61       return true;
62     }
63   }
64   return false;
65 }
66 
IsTimeAfterOrEqualVsyncTime(int64_t time,int64_t vsync_time)67 bool IsTimeAfterOrEqualVsyncTime(int64_t time, int64_t vsync_time) {
68   return ((vsync_time != INT64_MAX) && ((time - (vsync_time - kVsyncTimeDriftNs)) >= 0));
69 }
70 
HWCColorMode(DisplayInterface * display_intf)71 HWCColorMode::HWCColorMode(DisplayInterface *display_intf) : display_intf_(display_intf) {}
72 
Init()73 HWC2::Error HWCColorMode::Init() {
74   PopulateColorModes();
75   return HWC2::Error::None;
76 }
77 
DeInit()78 HWC2::Error HWCColorMode::DeInit() {
79   color_mode_map_.clear();
80   return HWC2::Error::None;
81 }
82 
GetColorModeCount()83 uint32_t HWCColorMode::GetColorModeCount() {
84   uint32_t count = UINT32(color_mode_map_.size());
85   DLOGI("Supported color mode count = %d", count);
86   return std::max(1U, count);
87 }
88 
GetRenderIntentCount(ColorMode mode)89 uint32_t HWCColorMode::GetRenderIntentCount(ColorMode mode) {
90   uint32_t count = UINT32(color_mode_map_[mode].size());
91   DLOGI("mode: %d supported rendering intent count = %d", mode, count);
92   return std::max(1U, count);
93 }
94 
GetColorModes(uint32_t * out_num_modes,ColorMode * out_modes)95 HWC2::Error HWCColorMode::GetColorModes(uint32_t *out_num_modes, ColorMode *out_modes) {
96   auto it = color_mode_map_.begin();
97   *out_num_modes = std::min(*out_num_modes, UINT32(color_mode_map_.size()));
98   for (uint32_t i = 0; i < *out_num_modes; it++, i++) {
99     out_modes[i] = it->first;
100     DLOGI("Color mode = %d is supported", out_modes[i]);
101   }
102   return HWC2::Error::None;
103 }
104 
GetRenderIntents(ColorMode mode,uint32_t * out_num_intents,RenderIntent * out_intents)105 HWC2::Error HWCColorMode::GetRenderIntents(ColorMode mode, uint32_t *out_num_intents,
106                                            RenderIntent *out_intents) {
107   if (color_mode_map_.find(mode) == color_mode_map_.end()) {
108     return HWC2::Error::BadParameter;
109   }
110   auto it = color_mode_map_[mode].begin();
111   *out_num_intents = std::min(*out_num_intents, UINT32(color_mode_map_[mode].size()));
112   for (uint32_t i = 0; i < *out_num_intents; it++, i++) {
113     out_intents[i] = it->first;
114     DLOGI("Color mode = %d is supported with render intent = %d", mode, out_intents[i]);
115   }
116   return HWC2::Error::None;
117 }
118 
ValidateColorModeWithRenderIntent(ColorMode mode,RenderIntent intent)119 HWC2::Error HWCColorMode::ValidateColorModeWithRenderIntent(ColorMode mode, RenderIntent intent) {
120   if (mode < ColorMode::NATIVE || mode > ColorMode::DISPLAY_BT2020) {
121     DLOGE("Invalid mode: %d", mode);
122     return HWC2::Error::BadParameter;
123   }
124   if (color_mode_map_.find(mode) == color_mode_map_.end()) {
125     DLOGE("Could not find mode: %d", mode);
126     return HWC2::Error::Unsupported;
127   }
128   if (color_mode_map_[mode].find(intent) == color_mode_map_[mode].end()) {
129     DLOGE("Could not find render intent %d in mode %d", intent, mode);
130     return HWC2::Error::Unsupported;
131   }
132 
133   return HWC2::Error::None;
134 }
135 
SetColorModeWithRenderIntent(ColorMode mode,RenderIntent intent)136 HWC2::Error HWCColorMode::SetColorModeWithRenderIntent(ColorMode mode, RenderIntent intent) {
137   DTRACE_SCOPED();
138   HWC2::Error hwc_error = ValidateColorModeWithRenderIntent(mode, intent);
139   if (hwc_error != HWC2::Error::None) {
140     return hwc_error;
141   }
142 
143   if (current_color_mode_ == mode && current_render_intent_ == intent) {
144     return HWC2::Error::None;
145   }
146 
147   auto mode_string = color_mode_map_[mode][intent][kSdrType];
148   DisplayError error = display_intf_->SetColorMode(mode_string);
149   if (error != kErrorNone) {
150     DLOGE("failed for mode = %d intent = %d name = %s", mode, intent, mode_string.c_str());
151     return HWC2::Error::Unsupported;
152   }
153   // The mode does not have the PCC configured, restore the transform
154   RestoreColorTransform();
155 
156   current_color_mode_ = mode;
157   current_render_intent_ = intent;
158   DLOGV_IF(kTagClient, "Successfully applied mode = %d intent = %d name = %s", mode, intent,
159            mode_string.c_str());
160   return HWC2::Error::None;
161 }
162 
CacheColorModeWithRenderIntent(ColorMode mode,RenderIntent intent)163 HWC2::Error HWCColorMode::CacheColorModeWithRenderIntent(ColorMode mode, RenderIntent intent) {
164   HWC2::Error error = ValidateColorModeWithRenderIntent(mode, intent);
165   if (error != HWC2::Error::None) {
166     return error;
167   }
168 
169   if (current_color_mode_ == mode && current_render_intent_ == intent) {
170     return HWC2::Error::None;
171   }
172 
173   current_color_mode_ = mode;
174   current_render_intent_ = intent;
175   apply_mode_ = true;
176 
177   return HWC2::Error::None;
178 }
179 
SetApplyMode(bool enable)180 void HWCColorMode::SetApplyMode(bool enable) {
181   apply_mode_ = enable;
182 }
183 
ApplyCurrentColorModeWithRenderIntent(bool hdr_present)184 HWC2::Error HWCColorMode::ApplyCurrentColorModeWithRenderIntent(bool hdr_present) {
185   // If panel does not support color modes, do not set color mode.
186   if (color_mode_map_.size() <= 1) {
187     return HWC2::Error::None;
188   }
189   if (!apply_mode_) {
190     if ((hdr_present && curr_dynamic_range_ == kHdrType) ||
191       (!hdr_present && curr_dynamic_range_ == kSdrType))
192       return HWC2::Error::None;
193   }
194 
195   apply_mode_ = false;
196   curr_dynamic_range_ = (hdr_present)? kHdrType : kSdrType;
197 
198   // select mode according to the blend space and dynamic range
199   std::string mode_string = preferred_mode_[current_color_mode_][curr_dynamic_range_];
200   if (mode_string.empty()) {
201     mode_string = color_mode_map_[current_color_mode_][current_render_intent_][curr_dynamic_range_];
202     if (mode_string.empty() && hdr_present) {
203       // Use the colorimetric HDR mode, if an HDR mode with the current render intent is not present
204       mode_string = color_mode_map_[current_color_mode_][RenderIntent::COLORIMETRIC][kHdrType];
205     }
206     if (mode_string.empty() &&
207        (current_color_mode_ == ColorMode::DISPLAY_P3 ||
208        current_color_mode_ == ColorMode::DISPLAY_BT2020) &&
209        curr_dynamic_range_ == kHdrType) {
210       // fall back to display_p3/display_bt2020 SDR mode if there is no HDR mode
211       mode_string = color_mode_map_[current_color_mode_][current_render_intent_][kSdrType];
212     }
213   }
214 
215   auto error = SetPreferredColorModeInternal(mode_string, false, NULL, NULL);
216   if (error == HWC2::Error::None) {
217     // The mode does not have the PCC configured, restore the transform
218     RestoreColorTransform();
219     DLOGV_IF(kTagClient, "Successfully applied mode = %d intent = %d range = %d name = %s",
220              current_color_mode_, current_render_intent_, curr_dynamic_range_, mode_string.c_str());
221   }
222 
223   return error;
224 }
225 
SetColorModeById(int32_t color_mode_id)226 HWC2::Error HWCColorMode::SetColorModeById(int32_t color_mode_id) {
227   DLOGI("Applying mode: %d", color_mode_id);
228   DisplayError error = display_intf_->SetColorModeById(color_mode_id);
229   if (error != kErrorNone) {
230     DLOGI_IF(kTagClient, "Failed to apply mode: %d", color_mode_id);
231     return HWC2::Error::BadParameter;
232   }
233   return HWC2::Error::None;
234 }
235 
SetPreferredColorModeInternal(const std::string & mode_string,bool from_client,ColorMode * color_mode,DynamicRangeType * dynamic_range)236 HWC2::Error HWCColorMode::SetPreferredColorModeInternal(const std::string &mode_string,
237               bool from_client, ColorMode *color_mode, DynamicRangeType *dynamic_range) {
238   DisplayError error = kErrorNone;
239   ColorMode mode = ColorMode::NATIVE;
240   DynamicRangeType range = kSdrType;
241 
242   if (from_client) {
243     // get blend space and dynamic range of the mode
244     AttrVal attr;
245     std::string color_gamut_string, dynamic_range_string;
246     error = display_intf_->GetColorModeAttr(mode_string, &attr);
247     if (error) {
248       DLOGE("Failed to get mode attributes for mode %s", mode_string.c_str());
249       return HWC2::Error::BadParameter;
250     }
251 
252     if (!attr.empty()) {
253       for (auto &it : attr) {
254         if (it.first.find(kColorGamutAttribute) != std::string::npos) {
255           color_gamut_string = it.second;
256         } else if (it.first.find(kDynamicRangeAttribute) != std::string::npos) {
257           dynamic_range_string = it.second;
258         }
259       }
260     }
261 
262     if (color_gamut_string.empty() || dynamic_range_string.empty()) {
263       DLOGE("Invalid attributes for mode %s: color_gamut = %s, dynamic_range = %s",
264             mode_string.c_str(), color_gamut_string.c_str(), dynamic_range_string.c_str());
265       return HWC2::Error::BadParameter;
266     }
267 
268     if (color_gamut_string == kDcip3) {
269       mode = ColorMode::DISPLAY_P3;
270     } else if (color_gamut_string == kSrgb) {
271       mode = ColorMode::SRGB;
272     }
273     if (dynamic_range_string == kHdr) {
274       range = kHdrType;
275     }
276 
277     if (color_mode) {
278       *color_mode = mode;
279     }
280     if (dynamic_range) {
281       *dynamic_range = range;
282     }
283   }
284 
285   // apply the mode from client if it matches
286   // the current blend space and dynamic range,
287   // skip the check for the mode from SF.
288   if ((!from_client) || (current_color_mode_ == mode && curr_dynamic_range_ == range)) {
289     DLOGI("Applying mode: %s", mode_string.c_str());
290     error = display_intf_->SetColorMode(mode_string);
291     if (error != kErrorNone) {
292       DLOGE("Failed to apply mode: %s", mode_string.c_str());
293       return HWC2::Error::BadParameter;
294     }
295   }
296 
297   return HWC2::Error::None;
298 }
299 
SetColorModeFromClientApi(std::string mode_string)300 HWC2::Error HWCColorMode::SetColorModeFromClientApi(std::string mode_string) {
301   ColorMode mode = ColorMode::NATIVE;
302   DynamicRangeType range = kSdrType;
303 
304   auto error = SetPreferredColorModeInternal(mode_string, true, &mode, &range);
305   if (error == HWC2::Error::None) {
306     preferred_mode_[mode][range] = mode_string;
307     DLOGV_IF(kTagClient, "Put mode %s(mode %d, range %d) into preferred_mode",
308              mode_string.c_str(), mode, range);
309   }
310 
311   return error;
312 }
313 
RestoreColorTransform()314 HWC2::Error HWCColorMode::RestoreColorTransform() {
315   DisplayError error = display_intf_->SetColorTransform(kColorTransformMatrixCount, color_matrix_);
316   if (error != kErrorNone) {
317     DLOGE("Failed to set Color Transform");
318     return HWC2::Error::BadParameter;
319   }
320 
321   return HWC2::Error::None;
322 }
323 
SetColorTransform(const float * matrix,android_color_transform_t)324 HWC2::Error HWCColorMode::SetColorTransform(const float *matrix,
325                                             android_color_transform_t /*hint*/) {
326   DTRACE_SCOPED();
327   auto status = HWC2::Error::None;
328   double color_matrix[kColorTransformMatrixCount] = {0};
329   CopyColorTransformMatrix(matrix, color_matrix);
330 
331   DisplayError error = display_intf_->SetColorTransform(kColorTransformMatrixCount, color_matrix);
332   if (error != kErrorNone) {
333     DLOGE("Failed to set Color Transform Matrix");
334     status = HWC2::Error::Unsupported;
335   }
336   CopyColorTransformMatrix(matrix, color_matrix_);
337   return status;
338 }
339 
PopulateColorModes()340 void HWCColorMode::PopulateColorModes() {
341   uint32_t color_mode_count = 0;
342   // SDM returns modes which have attributes defining mode and rendering intent
343   DisplayError error = display_intf_->GetColorModeCount(&color_mode_count);
344   if (error != kErrorNone || (color_mode_count == 0)) {
345     DLOGW("GetColorModeCount failed, use native color mode");
346     color_mode_map_[ColorMode::NATIVE][RenderIntent::COLORIMETRIC]
347                    [kSdrType] = "hal_native_identity";
348     return;
349   }
350 
351   DLOGV_IF(kTagClient, "Color Modes supported count = %d", color_mode_count);
352 
353   std::vector<std::string> color_modes(color_mode_count);
354   error = display_intf_->GetColorModes(&color_mode_count, &color_modes);
355   for (uint32_t i = 0; i < color_mode_count; i++) {
356     std::string &mode_string = color_modes.at(i);
357     DLOGV_IF(kTagClient, "Color Mode[%d] = %s", i, mode_string.c_str());
358     AttrVal attr;
359     error = display_intf_->GetColorModeAttr(mode_string, &attr);
360     std::string color_gamut = kNative, dynamic_range = kSdr, pic_quality = kStandard, transfer;
361     int int_render_intent = -1;
362     if (!attr.empty()) {
363       for (auto &it : attr) {
364         if (it.first.find(kColorGamutAttribute) != std::string::npos) {
365           color_gamut = it.second;
366         } else if (it.first.find(kDynamicRangeAttribute) != std::string::npos) {
367           dynamic_range = it.second;
368         } else if (it.first.find(kPictureQualityAttribute) != std::string::npos) {
369           pic_quality = it.second;
370         } else if (it.first.find(kGammaTransferAttribute) != std::string::npos) {
371           transfer = it.second;
372         } else if (it.first.find(kRenderIntentAttribute) != std::string::npos) {
373           int_render_intent = std::stoi(it.second);
374         }
375       }
376 
377       if (int_render_intent < 0 || int_render_intent > MAX_EXTENDED_RENDER_INTENT) {
378         DLOGW("Invalid render intent %d for mode %s", int_render_intent, mode_string.c_str());
379         continue;
380       }
381       DLOGV_IF(kTagClient, "color_gamut : %s, dynamic_range : %s, pic_quality : %s, "
382                "render_intent : %d", color_gamut.c_str(), dynamic_range.c_str(),
383                pic_quality.c_str(), int_render_intent);
384 
385       auto render_intent = static_cast<RenderIntent>(int_render_intent);
386       if (color_gamut == kNative) {
387         color_mode_map_[ColorMode::NATIVE][render_intent][kSdrType] = mode_string;
388       }
389 
390       if (color_gamut == kSrgb && dynamic_range == kSdr) {
391         color_mode_map_[ColorMode::SRGB][render_intent][kSdrType] = mode_string;
392       }
393 
394       if (color_gamut == kDcip3 && dynamic_range == kSdr) {
395         color_mode_map_[ColorMode::DISPLAY_P3][render_intent][kSdrType] = mode_string;
396       }
397       if (color_gamut == kDcip3 && dynamic_range == kHdr) {
398         if (display_intf_->IsSupportSsppTonemap()) {
399           color_mode_map_[ColorMode::DISPLAY_P3][render_intent][kHdrType] = mode_string;
400         } else if (pic_quality == kStandard) {
401           color_mode_map_[ColorMode::BT2100_PQ][render_intent]
402                          [kHdrType] = mode_string;
403           color_mode_map_[ColorMode::BT2100_HLG][render_intent]
404                          [kHdrType] = mode_string;
405         }
406       } else if (color_gamut == kBt2020) {
407         if (transfer == kSt2084) {
408           color_mode_map_[ColorMode::BT2100_PQ][RenderIntent::COLORIMETRIC]
409                          [kHdrType] = mode_string;
410         } else if (transfer == kHlg) {
411           color_mode_map_[ColorMode::BT2100_HLG][RenderIntent::COLORIMETRIC]
412                          [kHdrType] = mode_string;
413         } else if (transfer == kSrgb) {
414           color_mode_map_[ColorMode::DISPLAY_BT2020][RenderIntent::COLORIMETRIC]
415                          [kSdrType] = mode_string;
416         }
417       }
418     } else {
419       // Look at the mode names, if no attributes are found
420       if (mode_string.find("hal_native") != std::string::npos) {
421         color_mode_map_[ColorMode::NATIVE][RenderIntent::COLORIMETRIC]
422                        [kSdrType] = mode_string;
423       }
424     }
425   }
426 }
427 
Dump(std::ostringstream * os)428 void HWCColorMode::Dump(std::ostringstream* os) {
429   *os << "color modes supported: \n";
430   for (auto it : color_mode_map_) {
431     *os << "mode: " << static_cast<int32_t>(it.first) << " RIs { ";
432     for (auto render_intent_it : color_mode_map_[it.first]) {
433       *os << static_cast<int32_t>(render_intent_it.first) << " dynamic_range [ ";
434       for (auto range_it : color_mode_map_[it.first][render_intent_it.first]) {
435         *os << static_cast<int32_t>(range_it.first) << " ";
436       }
437       *os << "] ";
438     }
439     *os << "} \n";
440   }
441   *os << "current mode: " << static_cast<uint32_t>(current_color_mode_) << std::endl;
442   *os << "current render_intent: " << static_cast<uint32_t>(current_render_intent_) << std::endl;
443   if (curr_dynamic_range_ == kHdrType) {
444     *os << "current dynamic_range: HDR" << std::endl;
445   } else {
446     *os << "current dynamic_range: SDR" << std::endl;
447   }
448   *os << "current transform: ";
449   for (uint32_t i = 0; i < kColorTransformMatrixCount; i++) {
450     if (i % 4 == 0) {
451      *os << std::endl;
452     }
453     *os << std::fixed << std::setprecision(2) << std::setw(6) << std::setfill(' ')
454         << color_matrix_[i] << " ";
455   }
456   *os << std::endl;
457 }
458 
HWCDisplay(CoreInterface * core_intf,BufferAllocator * buffer_allocator,HWCCallbacks * callbacks,HWCDisplayEventHandler * event_handler,qService::QService * qservice,DisplayType type,hwc2_display_t id,int32_t sdm_id,DisplayClass display_class)459 HWCDisplay::HWCDisplay(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
460                        HWCCallbacks *callbacks, HWCDisplayEventHandler* event_handler,
461                        qService::QService *qservice, DisplayType type, hwc2_display_t id,
462                        int32_t sdm_id, DisplayClass display_class)
463     : core_intf_(core_intf),
464       callbacks_(callbacks),
465       event_handler_(event_handler),
466       type_(type),
467       id_(id),
468       sdm_id_(sdm_id),
469       qservice_(qservice),
470       display_class_(display_class) {
471   buffer_allocator_ = static_cast<HWCBufferAllocator *>(buffer_allocator);
472 }
473 
Init()474 int HWCDisplay::Init() {
475   DisplayError error = kErrorNone;
476 
477   HWCDebugHandler::Get()->GetProperty(ENABLE_NULL_DISPLAY_PROP, &null_display_mode_);
478   HWCDebugHandler::Get()->GetProperty(ENABLE_ASYNC_POWERMODE, &async_power_mode_);
479 
480   if (null_display_mode_) {
481     DisplayNull *disp_null = new DisplayNull();
482     disp_null->Init();
483     use_metadata_refresh_rate_ = false;
484     display_intf_ = disp_null;
485     DLOGI("Enabling null display mode for display type %d", type_);
486   } else {
487     error = core_intf_->CreateDisplay(sdm_id_, this, &display_intf_);
488     if (error != kErrorNone) {
489       if (kErrorDeviceRemoved == error) {
490         DLOGW("Display creation cancelled. Display %d-%d removed.", sdm_id_, type_);
491         return -ENODEV;
492       } else {
493         DLOGE("Display create failed. Error = %d display_id = %d event_handler = %p disp_intf = %p",
494               error, sdm_id_, this, &display_intf_);
495         return -EINVAL;
496       }
497     }
498   }
499 
500   validated_ = false;
501   HWCDebugHandler::Get()->GetProperty(DISABLE_HDR, &disable_hdr_handling_);
502   if (disable_hdr_handling_) {
503     DLOGI("HDR Handling disabled");
504   }
505 
506   int property_swap_interval = 1;
507   HWCDebugHandler::Get()->GetProperty(ZERO_SWAP_INTERVAL, &property_swap_interval);
508   if (property_swap_interval == 0) {
509     swap_interval_zero_ = true;
510   }
511 
512   client_target_ = new HWCLayer(id_, buffer_allocator_);
513 
514   error = display_intf_->GetNumVariableInfoConfigs(&num_configs_);
515   if (error != kErrorNone) {
516     DLOGE("Getting config count failed. Error = %d", error);
517     return -EINVAL;
518   }
519 
520   UpdateConfigs();
521 
522   tone_mapper_ = new HWCToneMapper(buffer_allocator_);
523 
524   display_intf_->GetRefreshRateRange(&min_refresh_rate_, &max_refresh_rate_);
525   current_refresh_rate_ = max_refresh_rate_;
526 
527   GetUnderScanConfig();
528 
529   DisplayConfigFixedInfo fixed_info = {};
530   display_intf_->GetConfig(&fixed_info);
531   is_cmd_mode_ = fixed_info.is_cmdmode;
532   partial_update_enabled_ = fixed_info.partial_update || (!fixed_info.is_cmdmode);
533   client_target_->SetPartialUpdate(partial_update_enabled_);
534 
535   int disable_fast_path = 0;
536   HWCDebugHandler::Get()->GetProperty(DISABLE_FAST_PATH, &disable_fast_path);
537   fast_path_enabled_ = !(disable_fast_path == 1);
538 
539   game_supported_ = display_intf_->GameEnhanceSupported();
540 
541   SetCurrentPanelGammaSource(kGammaCalibration);
542 
543   DLOGI("Display created with id: %" PRIu64 ", game_supported_: %d", id_, game_supported_);
544 
545   return 0;
546 }
547 
UpdateConfigs()548 void HWCDisplay::UpdateConfigs() {
549   // SF doesnt care about dynamic bit clk support.
550   // Exposing all configs will result in getting/setting of redundant configs.
551 
552   // For each config store the corresponding index which client understands.
553   hwc_config_map_.resize(num_configs_);
554 
555   for (uint32_t i = 0; i < num_configs_; i++) {
556     DisplayConfigVariableInfo info = {};
557     GetDisplayAttributesForConfig(INT(i), &info);
558     bool config_exists = false;
559     for (auto &config : variable_config_map_) {
560       if (config.second == info) {
561         config_exists = true;
562         hwc_config_map_.at(i) = config.first;
563         break;
564       }
565     }
566 
567     if (!config_exists) {
568       variable_config_map_[i] = info;
569       hwc_config_map_.at(i) = i;
570     }
571   }
572 
573   // Update num config count.
574   num_configs_ = UINT32(variable_config_map_.size());
575   DLOGI("num_configs = %d", num_configs_);
576 }
577 
Deinit()578 int HWCDisplay::Deinit() {
579   if (null_display_mode_) {
580     delete static_cast<DisplayNull *>(display_intf_);
581     display_intf_ = nullptr;
582   } else {
583     DisplayError error = core_intf_->DestroyDisplay(display_intf_);
584     if (error != kErrorNone) {
585       DLOGE("Display destroy failed. Error = %d", error);
586       return -EINVAL;
587     }
588   }
589 
590   delete client_target_;
591   for (auto hwc_layer : layer_set_) {
592     delete hwc_layer;
593   }
594 
595   if (color_mode_) {
596     color_mode_->DeInit();
597     delete color_mode_;
598   }
599 
600   if (tone_mapper_) {
601     delete tone_mapper_;
602     tone_mapper_ = nullptr;
603   }
604 
605   return 0;
606 }
607 
608 // LayerStack operations
CreateLayer(hwc2_layer_t * out_layer_id)609 HWC2::Error HWCDisplay::CreateLayer(hwc2_layer_t *out_layer_id) {
610   HWCLayer *layer = *layer_set_.emplace(new HWCLayer(id_, buffer_allocator_));
611   layer_map_.emplace(std::make_pair(layer->GetId(), layer));
612   *out_layer_id = layer->GetId();
613   geometry_changes_ |= GeometryChanges::kAdded;
614   validated_ = false;
615   layer_stack_invalid_ = true;
616   layer->SetPartialUpdate(partial_update_enabled_);
617 
618   return HWC2::Error::None;
619 }
620 
GetHWCLayer(hwc2_layer_t layer_id)621 HWCLayer *HWCDisplay::GetHWCLayer(hwc2_layer_t layer_id) {
622   const auto map_layer = layer_map_.find(layer_id);
623   if (map_layer == layer_map_.end()) {
624     DLOGW("[%" PRIu64 "] GetLayer(%" PRIu64 ") failed: no such layer", id_, layer_id);
625     return nullptr;
626   } else {
627     return map_layer->second;
628   }
629 }
630 
DestroyLayer(hwc2_layer_t layer_id)631 HWC2::Error HWCDisplay::DestroyLayer(hwc2_layer_t layer_id) {
632   const auto map_layer = layer_map_.find(layer_id);
633   if (map_layer == layer_map_.end()) {
634     DLOGW("[%" PRIu64 "] destroyLayer(%" PRIu64 ") failed: no such layer", id_, layer_id);
635     return HWC2::Error::BadLayer;
636   }
637   const auto layer = map_layer->second;
638   layer_map_.erase(map_layer);
639   const auto z_range = layer_set_.equal_range(layer);
640   for (auto current = z_range.first; current != z_range.second; ++current) {
641     if (*current == layer) {
642       current = layer_set_.erase(current);
643       delete layer;
644       break;
645     }
646   }
647 
648   geometry_changes_ |= GeometryChanges::kRemoved;
649   validated_ = false;
650   layer_stack_invalid_ = true;
651 
652   return HWC2::Error::None;
653 }
654 
655 
BuildLayerStack()656 void HWCDisplay::BuildLayerStack() {
657   layer_stack_ = LayerStack();
658   display_rect_ = LayerRect();
659   metadata_refresh_rate_ = 0;
660   layer_stack_.flags.animating = animating_;
661   layer_stack_.flags.fast_path = fast_path_enabled_ && fast_path_composition_;
662   hdr_largest_layer_px_ = 0.0f;
663 
664   DTRACE_SCOPED();
665   // Add one layer for fb target
666   for (auto hwc_layer : layer_set_) {
667     // Reset layer data which SDM may change
668     hwc_layer->ResetPerFrameData();
669 
670     Layer *layer = hwc_layer->GetSDMLayer();
671     layer->flags = {};   // Reset earlier flags
672     // Mark all layers to skip, when client target handle is NULL
673     if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::Client ||
674         !client_target_->GetSDMLayer()->input_buffer.buffer_id) {
675       layer->flags.skip = true;
676     } else if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::SolidColor) {
677       layer->flags.solid_fill = true;
678     }
679 
680     if (!hwc_layer->IsDataSpaceSupported()) {
681       layer->flags.skip = true;
682     }
683 
684     if (hwc_layer->IsColorTransformSet()) {
685       layer->flags.skip = true;
686     }
687 
688     // set default composition as GPU for SDM
689     layer->composition = kCompositionGPU;
690 
691     if (swap_interval_zero_) {
692       layer->input_buffer.acquire_fence = nullptr;
693     }
694 
695     bool is_secure = false;
696     bool is_video = false;
697     const private_handle_t *handle =
698         reinterpret_cast<const private_handle_t *>(layer->input_buffer.buffer_id);
699     if (handle) {
700       if (handle->buffer_type == BUFFER_TYPE_VIDEO) {
701         layer_stack_.flags.video_present = true;
702         is_video = true;
703       }
704       // TZ Protected Buffer - L1
705       // Gralloc Usage Protected Buffer - L3 - which needs to be treated as Secure & avoid fallback
706       if (handle->flags & private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER ||
707           handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
708         layer_stack_.flags.secure_present = true;
709         is_secure = true;
710       }
711       // UBWC PI format
712       if (handle->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED_PI) {
713         layer->input_buffer.flags.ubwc_pi = true;
714       }
715     }
716 
717     if (layer->input_buffer.flags.secure_display) {
718       layer_stack_.flags.secure_present = true;
719       is_secure = true;
720     }
721 
722     if (hwc_layer->IsSingleBuffered() &&
723        !(hwc_layer->IsRotationPresent() || hwc_layer->IsScalingPresent())) {
724       layer->flags.single_buffer = true;
725       layer_stack_.flags.single_buffered_layer_present = true;
726     }
727 
728     bool hdr_layer = layer->input_buffer.color_metadata.colorPrimaries == ColorPrimaries_BT2020 &&
729                      (layer->input_buffer.color_metadata.transfer == Transfer_SMPTE_ST2084 ||
730                      layer->input_buffer.color_metadata.transfer == Transfer_HLG);
731     if (hdr_layer && !disable_hdr_handling_) {
732       // Dont honor HDR when its handling is disabled
733       layer->input_buffer.flags.hdr = true;
734       layer_stack_.flags.hdr_present = true;
735 
736       // HDR area
737       auto hdr_layer_area = (layer->dst_rect.right - layer->dst_rect.left) *
738                             (layer->dst_rect.bottom - layer->dst_rect.top);
739       hdr_largest_layer_px_ = std::max(hdr_largest_layer_px_, hdr_layer_area);
740     }
741 
742     if (hwc_layer->IsNonIntegralSourceCrop() && !is_secure && !hdr_layer &&
743         !layer->flags.single_buffer && !layer->flags.solid_fill && !is_video) {
744       layer->flags.skip = true;
745     }
746 
747     if (!layer->flags.skip &&
748         (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::Cursor)) {
749       // Currently we support only one HWCursor & only at top most z-order
750       if ((*layer_set_.rbegin())->GetId() == hwc_layer->GetId()) {
751         layer->flags.cursor = true;
752         layer_stack_.flags.cursor_present = true;
753       }
754     }
755 
756     if (layer->flags.skip) {
757       layer_stack_.flags.skip_present = true;
758     }
759 
760     // TODO(user): Move to a getter if this is needed at other places
761     hwc_rect_t scaled_display_frame = {INT(layer->dst_rect.left), INT(layer->dst_rect.top),
762                                        INT(layer->dst_rect.right), INT(layer->dst_rect.bottom)};
763     if (hwc_layer->GetGeometryChanges() & kDisplayFrame) {
764       ApplyScanAdjustment(&scaled_display_frame);
765     }
766     hwc_layer->SetLayerDisplayFrame(scaled_display_frame);
767     hwc_layer->ResetPerFrameData();
768     // SDM requires these details even for solid fill
769     if (layer->flags.solid_fill) {
770       LayerBuffer *layer_buffer = &layer->input_buffer;
771       layer_buffer->width = UINT32(layer->dst_rect.right - layer->dst_rect.left);
772       layer_buffer->height = UINT32(layer->dst_rect.bottom - layer->dst_rect.top);
773       layer_buffer->unaligned_width = layer_buffer->width;
774       layer_buffer->unaligned_height = layer_buffer->height;
775       layer->src_rect.left = 0;
776       layer->src_rect.top = 0;
777       layer->src_rect.right = layer_buffer->width;
778       layer->src_rect.bottom = layer_buffer->height;
779     }
780 
781     if (hwc_layer->HasMetaDataRefreshRate() && layer->frame_rate > metadata_refresh_rate_) {
782       metadata_refresh_rate_ = SanitizeRefreshRate(layer->frame_rate);
783     }
784 
785     display_rect_ = Union(display_rect_, layer->dst_rect);
786     geometry_changes_ |= hwc_layer->GetGeometryChanges();
787 
788     layer->flags.updating = true;
789     if (layer_set_.size() <= kMaxLayerCount) {
790       layer->flags.updating = IsLayerUpdating(hwc_layer);
791     }
792 
793     if (hwc_layer->IsColorTransformSet()) {
794       layer->flags.color_transform = true;
795     }
796 
797     layer_stack_.flags.mask_present |= layer->input_buffer.flags.mask_layer;
798 
799     if ((hwc_layer->GetDeviceSelectedCompositionType() != HWC2::Composition::Device) ||
800         (hwc_layer->GetClientRequestedCompositionType() != HWC2::Composition::Device) ||
801         layer->flags.skip) {
802       layer->update_mask.set(kClientCompRequest);
803     }
804 
805     if (game_supported_ && (hwc_layer->GetType() == kLayerGame)) {
806       layer->flags.is_game = true;
807       layer->input_buffer.flags.game = true;
808     }
809 
810     layer_stack_.layers.push_back(layer);
811   }
812 
813   // If layer stack needs Client composition, HWC display gets into InternalValidate state. If
814   // validation gets reset by any other thread in this state, enforce Geometry change to ensure
815   // that Client target gets composed by SF.
816   bool enforce_geometry_change = (validate_state_ == kInternalValidate) && !validated_;
817 
818   // TODO(user): Set correctly when SDM supports geometry_changes as bitmask
819 
820   layer_stack_.flags.geometry_changed = UINT32((geometry_changes_ || enforce_geometry_change ||
821                                                 geometry_changes_on_doze_suspend_) > 0);
822   layer_stack_.flags.config_changed = !validated_;
823   // Append client target to the layer stack
824   Layer *sdm_client_target = client_target_->GetSDMLayer();
825   sdm_client_target->flags.updating = IsLayerUpdating(client_target_);
826   // Derive client target dataspace based on the color mode - bug/115482728
827   int32_t client_target_dataspace = GetDataspaceFromColorMode(GetCurrentColorMode());
828   SetClientTargetDataSpace(client_target_dataspace);
829   layer_stack_.layers.push_back(sdm_client_target);
830 
831   // fall back frame composition to GPU when client target is 10bit
832   // TODO(user): clarify the behaviour from Client(SF) and SDM Extn -
833   // when handling 10bit FBT, as it would affect blending
834   if (Is10BitFormat(sdm_client_target->input_buffer.format)) {
835     // Must fall back to client composition
836     MarkLayersForClientComposition();
837   }
838 }
839 
BuildSolidFillStack()840 void HWCDisplay::BuildSolidFillStack() {
841   layer_stack_ = LayerStack();
842   display_rect_ = LayerRect();
843 
844   layer_stack_.layers.push_back(solid_fill_layer_);
845   layer_stack_.flags.geometry_changed = 1U;
846   // Append client target to the layer stack
847   layer_stack_.layers.push_back(client_target_->GetSDMLayer());
848 }
849 
SetLayerType(hwc2_layer_t layer_id,IQtiComposerClient::LayerType type)850 HWC2::Error HWCDisplay::SetLayerType(hwc2_layer_t layer_id, IQtiComposerClient::LayerType type) {
851   const auto map_layer = layer_map_.find(layer_id);
852   if (map_layer == layer_map_.end()) {
853     DLOGE("[%" PRIu64 "] SetLayerType failed to find layer", id_);
854     return HWC2::Error::BadLayer;
855   }
856 
857   const auto layer = map_layer->second;
858   layer->SetLayerType(type);
859   return HWC2::Error::None;
860 }
861 
SetLayerZOrder(hwc2_layer_t layer_id,uint32_t z)862 HWC2::Error HWCDisplay::SetLayerZOrder(hwc2_layer_t layer_id, uint32_t z) {
863   const auto map_layer = layer_map_.find(layer_id);
864   if (map_layer == layer_map_.end()) {
865     DLOGW("[%" PRIu64 "] updateLayerZ failed to find layer", id_);
866     return HWC2::Error::BadLayer;
867   }
868 
869   const auto layer = map_layer->second;
870   const auto z_range = layer_set_.equal_range(layer);
871   bool layer_on_display = false;
872   for (auto current = z_range.first; current != z_range.second; ++current) {
873     if (*current == layer) {
874       if ((*current)->GetZ() == z) {
875         // Don't change anything if the Z hasn't changed
876         return HWC2::Error::None;
877       }
878       current = layer_set_.erase(current);
879       layer_on_display = true;
880       break;
881     }
882   }
883 
884   if (!layer_on_display) {
885     DLOGE("[%" PRIu64 "] updateLayerZ failed to find layer on display", id_);
886     return HWC2::Error::BadLayer;
887   }
888 
889   layer->SetLayerZOrder(z);
890   layer_set_.emplace(layer);
891   return HWC2::Error::None;
892 }
893 
SetVsyncEnabled(HWC2::Vsync enabled)894 HWC2::Error HWCDisplay::SetVsyncEnabled(HWC2::Vsync enabled) {
895   DLOGV("Display ID: %" PRIu64 " enabled: %s", id_, to_string(enabled).c_str());
896   ATRACE_INT("SetVsyncState ", enabled == HWC2::Vsync::Enable ? 1 : 0);
897   DisplayError error = kErrorNone;
898 
899   if (shutdown_pending_ ||
900       (!callbacks_->VsyncCallbackRegistered() && !callbacks_->Vsync_2_4CallbackRegistered())) {
901     return HWC2::Error::None;
902   }
903 
904   bool state;
905   if (enabled == HWC2::Vsync::Enable)
906     state = true;
907   else if (enabled == HWC2::Vsync::Disable)
908     state = false;
909   else
910     return HWC2::Error::BadParameter;
911 
912   error = display_intf_->SetVSyncState(state);
913 
914   if (error != kErrorNone) {
915     if (error == kErrorShutDown) {
916       shutdown_pending_ = true;
917       return HWC2::Error::None;
918     }
919     DLOGE("Failed. enabled = %s, error = %d", to_string(enabled).c_str(), error);
920     return HWC2::Error::BadDisplay;
921   }
922 
923   return HWC2::Error::None;
924 }
925 
PostPowerMode()926 void HWCDisplay::PostPowerMode() {
927   if (release_fence_ == nullptr) {
928     return;
929   }
930 
931   for (auto hwc_layer : layer_set_) {
932     shared_ptr<Fence> fence = nullptr;
933     shared_ptr<Fence> merged_fence = nullptr;
934 
935     hwc_layer->PopBackReleaseFence(&fence);
936     if (fence) {
937       merged_fence = Fence::Merge(release_fence_, fence);
938     } else {
939       merged_fence = release_fence_;
940     }
941     hwc_layer->PushBackReleaseFence(merged_fence);
942   }
943 
944   fbt_release_fence_ = release_fence_;
945 }
946 
SetPowerMode(HWC2::PowerMode mode,bool teardown)947 HWC2::Error HWCDisplay::SetPowerMode(HWC2::PowerMode mode, bool teardown) {
948   DLOGV("display = %" PRIu64 ", mode = %s", id_, to_string(mode).c_str());
949   DisplayState state = kStateOff;
950   bool flush_on_error = flush_on_error_;
951 
952   if (shutdown_pending_) {
953     return HWC2::Error::None;
954   }
955 
956   switch (mode) {
957     case HWC2::PowerMode::Off:
958       // During power off, all of the buffers are released.
959       // Do not flush until a buffer is successfully submitted again.
960       flush_on_error = false;
961       state = kStateOff;
962       if (tone_mapper_) {
963         tone_mapper_->Terminate();
964       }
965       break;
966     case HWC2::PowerMode::On:
967       if (color_mode_) {
968         color_mode_->SetApplyMode(true);
969       }
970       state = kStateOn;
971       break;
972     case HWC2::PowerMode::Doze:
973       if (color_mode_) {
974         color_mode_->SetApplyMode(true);
975       }
976       state = kStateDoze;
977       break;
978     case HWC2::PowerMode::DozeSuspend:
979       state = kStateDozeSuspend;
980       break;
981     default:
982       return HWC2::Error::BadParameter;
983   }
984   shared_ptr<Fence> release_fence = nullptr;
985 
986   ATRACE_INT("SetPowerMode ", state);
987   DisplayError error = display_intf_->SetDisplayState(state, teardown, &release_fence);
988   validated_ = false;
989 
990   if (error == kErrorNone) {
991     flush_on_error_ = flush_on_error;
992   } else {
993     if (error == kErrorShutDown) {
994       shutdown_pending_ = true;
995       return HWC2::Error::None;
996     }
997     DLOGE("Set state failed. Error = %d", error);
998     return HWC2::Error::BadParameter;
999   }
1000 
1001   // Update release fence.
1002   release_fence_ = release_fence;
1003   current_power_mode_ = mode;
1004 
1005   // Close the release fences in synchronous power updates
1006   if (!async_power_mode_) {
1007     PostPowerMode();
1008   }
1009   return HWC2::Error::None;
1010 }
1011 
GetClientTargetSupport(uint32_t width,uint32_t height,int32_t format,int32_t dataspace)1012 HWC2::Error HWCDisplay::GetClientTargetSupport(uint32_t width, uint32_t height, int32_t format,
1013                                                int32_t dataspace) {
1014   ColorMetaData color_metadata = {};
1015   if (dataspace != HAL_DATASPACE_UNKNOWN) {
1016     dataspace = TranslateFromLegacyDataspace(dataspace);
1017     GetColorPrimary(dataspace, &(color_metadata.colorPrimaries));
1018     GetTransfer(dataspace, &(color_metadata.transfer));
1019     GetRange(dataspace, &(color_metadata.range));
1020   }
1021 
1022   LayerBufferFormat sdm_format = HWCLayer::GetSDMFormat(format, 0);
1023   if (display_intf_->GetClientTargetSupport(width, height, sdm_format,
1024                                             color_metadata) != kErrorNone) {
1025     return HWC2::Error::Unsupported;
1026   }
1027 
1028   return HWC2::Error::None;
1029 }
1030 
GetColorModes(uint32_t * out_num_modes,ColorMode * out_modes)1031 HWC2::Error HWCDisplay::GetColorModes(uint32_t *out_num_modes, ColorMode *out_modes) {
1032   if (out_modes == nullptr) {
1033     *out_num_modes = 1;
1034   } else if (out_modes && *out_num_modes > 0) {
1035     *out_num_modes = 1;
1036     out_modes[0] = ColorMode::NATIVE;
1037   }
1038   return HWC2::Error::None;
1039 }
1040 
GetRenderIntents(ColorMode mode,uint32_t * out_num_intents,RenderIntent * out_intents)1041 HWC2::Error HWCDisplay::GetRenderIntents(ColorMode mode, uint32_t *out_num_intents,
1042                                          RenderIntent *out_intents) {
1043   if (mode != ColorMode::NATIVE) {
1044     return HWC2::Error::Unsupported;
1045   }
1046   if (out_intents == nullptr) {
1047     *out_num_intents = 1;
1048   } else if (out_intents && *out_num_intents > 0) {
1049     *out_num_intents = 1;
1050     out_intents[0] = RenderIntent::COLORIMETRIC;
1051   }
1052   return HWC2::Error::None;
1053 }
1054 
GetDisplayConfigs(uint32_t * out_num_configs,hwc2_config_t * out_configs)1055 HWC2::Error HWCDisplay::GetDisplayConfigs(uint32_t *out_num_configs, hwc2_config_t *out_configs) {
1056   if (out_num_configs == nullptr) {
1057     return HWC2::Error::BadParameter;
1058   }
1059 
1060   if (out_configs == nullptr) {
1061     *out_num_configs = num_configs_;
1062     return HWC2::Error::None;
1063   }
1064 
1065   *out_num_configs = std::min(*out_num_configs, num_configs_);
1066 
1067   // Expose all unique config ids to cleint.
1068   uint32_t i = 0;
1069   for (auto &info : variable_config_map_) {
1070     if (i == *out_num_configs) {
1071       break;
1072     }
1073     out_configs[i++] = info.first;
1074   }
1075 
1076   return HWC2::Error::None;
1077 }
1078 
GetDisplayAttribute(hwc2_config_t config,HwcAttribute attribute,int32_t * out_value)1079 HWC2::Error HWCDisplay::GetDisplayAttribute(hwc2_config_t config, HwcAttribute attribute,
1080                                             int32_t *out_value) {
1081   if (variable_config_map_.find(config) == variable_config_map_.end()) {
1082     DLOGE("Get variable config failed");
1083     return HWC2::Error::BadConfig;
1084   }
1085 
1086   DisplayConfigVariableInfo variable_config = variable_config_map_.at(config);
1087 
1088   variable_config.x_pixels -= UINT32(window_rect_.right + window_rect_.left);
1089   variable_config.y_pixels -= UINT32(window_rect_.bottom + window_rect_.top);
1090   if (variable_config.x_pixels <= 0 || variable_config.y_pixels <= 0) {
1091     DLOGE("window rects are not within the supported range");
1092     return HWC2::Error::BadDisplay;
1093   }
1094 
1095   switch (attribute) {
1096     case HwcAttribute::VSYNC_PERIOD:
1097       *out_value = INT32(variable_config.vsync_period_ns);
1098       break;
1099     case HwcAttribute::WIDTH:
1100       *out_value = INT32(variable_config.x_pixels);
1101       break;
1102     case HwcAttribute::HEIGHT:
1103       *out_value = INT32(variable_config.y_pixels);
1104       break;
1105     case HwcAttribute::DPI_X:
1106       *out_value = INT32(variable_config.x_dpi * 1000.0f);
1107       break;
1108     case HwcAttribute::DPI_Y:
1109       *out_value = INT32(variable_config.y_dpi * 1000.0f);
1110       break;
1111     case HwcAttribute::CONFIG_GROUP:
1112       *out_value = GetDisplayConfigGroup(variable_config);
1113       break;
1114     default:
1115       DLOGW("Spurious attribute type = %s", composer_V2_4::toString(attribute).c_str());
1116       *out_value = -1;
1117       return HWC2::Error::BadParameter;
1118   }
1119 
1120   return HWC2::Error::None;
1121 }
1122 
GetDisplayName(uint32_t * out_size,char * out_name)1123 HWC2::Error HWCDisplay::GetDisplayName(uint32_t *out_size, char *out_name) {
1124   // TODO(user): Get panel name and EDID name and populate it here
1125   if (out_size == nullptr) {
1126     return HWC2::Error::BadParameter;
1127   }
1128 
1129   std::string name;
1130   switch (type_) {
1131     case kBuiltIn:
1132       name = "Built-in Display";
1133       break;
1134     case kPluggable:
1135       name = "Pluggable Display";
1136       break;
1137     case kVirtual:
1138       name = "Virtual Display";
1139       break;
1140     default:
1141       name = "Unknown";
1142       break;
1143   }
1144 
1145   if (out_name == nullptr) {
1146     *out_size = UINT32(name.size()) + 1;
1147   } else {
1148     *out_size = std::min((UINT32(name.size()) + 1), *out_size);
1149     if (*out_size > 0) {
1150       strlcpy(out_name, name.c_str(), *out_size);
1151       out_name[*out_size - 1] = '\0';
1152     } else {
1153       DLOGW("Invalid size requested");
1154     }
1155   }
1156 
1157   return HWC2::Error::None;
1158 }
1159 
GetDisplayType(int32_t * out_type)1160 HWC2::Error HWCDisplay::GetDisplayType(int32_t *out_type) {
1161   if (out_type == nullptr) {
1162     return HWC2::Error::BadParameter;
1163   }
1164 
1165   *out_type = HWC2_DISPLAY_TYPE_PHYSICAL;
1166 
1167   return HWC2::Error::None;
1168 }
1169 
GetPerFrameMetadataKeys(uint32_t * out_num_keys,PerFrameMetadataKey * out_keys)1170 HWC2::Error HWCDisplay::GetPerFrameMetadataKeys(uint32_t *out_num_keys,
1171                                                 PerFrameMetadataKey *out_keys) {
1172   if (out_num_keys == nullptr) {
1173     return HWC2::Error::BadParameter;
1174   }
1175 
1176   DisplayConfigFixedInfo fixed_info = {};
1177   display_intf_->GetConfig(&fixed_info);
1178   uint32_t num_keys = 0;
1179   if (fixed_info.hdr_plus_supported) {
1180     num_keys = UINT32(PerFrameMetadataKey::HDR10_PLUS_SEI) + 1;
1181   } else {
1182     num_keys = UINT32(PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL) + 1;
1183   }
1184   if (out_keys == nullptr) {
1185     *out_num_keys = num_keys;
1186   } else {
1187     uint32_t max_out_key_elements = std::min(*out_num_keys, num_keys);
1188     for (int32_t i = 0; i < max_out_key_elements; i++) {
1189       out_keys[i] = static_cast<PerFrameMetadataKey>(i);
1190     }
1191   }
1192   return HWC2::Error::None;
1193 }
1194 
GetActiveConfig(hwc2_config_t * out_config)1195 HWC2::Error HWCDisplay::GetActiveConfig(hwc2_config_t *out_config) {
1196   if (out_config == nullptr) {
1197     return HWC2::Error::BadDisplay;
1198   }
1199 
1200   if (pending_config_) {
1201     *out_config = pending_config_index_;
1202   } else {
1203     GetActiveDisplayConfig(out_config);
1204   }
1205 
1206   if (*out_config < hwc_config_map_.size()) {
1207     *out_config = hwc_config_map_.at(*out_config);
1208   }
1209   return HWC2::Error::None;
1210 }
1211 
SetClientTarget(buffer_handle_t target,shared_ptr<Fence> acquire_fence,int32_t dataspace,hwc_region_t damage)1212 HWC2::Error HWCDisplay::SetClientTarget(buffer_handle_t target, shared_ptr<Fence> acquire_fence,
1213                                         int32_t dataspace, hwc_region_t damage) {
1214   // TODO(user): SurfaceFlinger gives us a null pointer here when doing full SDE composition
1215   // The error is problematic for layer caching as it would overwrite our cached client target.
1216   // Reported bug 28569722 to resolve this.
1217   // For now, continue to use the last valid buffer reported to us for layer caching.
1218   if (target == nullptr) {
1219     return HWC2::Error::None;
1220   }
1221 
1222   // The fence is null if the client composition result is used in
1223   // SurfaceFlinger. To align the behavior of sm8150, the null check
1224   // (acquire_fence == nullptr) should be removed so that the invalid fence
1225   // could be sent to SetLayerBuffer and avoid flicker issues.
1226 
1227   Layer *sdm_layer = client_target_->GetSDMLayer();
1228   sdm_layer->frame_rate = std::min(current_refresh_rate_, HWCDisplay::GetThrottlingRefreshRate());
1229   client_target_->SetLayerSurfaceDamage(damage);
1230   int translated_dataspace = TranslateFromLegacyDataspace(dataspace);
1231   if (client_target_->GetLayerDataspace() != translated_dataspace) {
1232     DLOGW("New Dataspace = %d not matching Dataspace from color mode = %d",
1233            translated_dataspace, client_target_->GetLayerDataspace());
1234     return HWC2::Error::BadParameter;
1235   }
1236   client_target_->SetLayerBuffer(target, acquire_fence);
1237 
1238   return HWC2::Error::None;
1239 }
1240 
SetActiveConfig(hwc2_config_t config)1241 HWC2::Error HWCDisplay::SetActiveConfig(hwc2_config_t config) {
1242   DTRACE_SCOPED();
1243 
1244   // Cache refresh rate set by client.
1245   DisplayConfigVariableInfo info = {};
1246   GetDisplayAttributesForConfig(INT(config), &info);
1247   active_refresh_rate_ = info.fps;
1248 
1249   hwc2_config_t current_config = 0;
1250   GetActiveConfig(&current_config);
1251   if (current_config == config) {
1252     return HWC2::Error::None;
1253   }
1254   DLOGI("Active configuration changed to: %d", config);
1255 
1256   // Store config index to be applied upon refresh.
1257   pending_config_ = true;
1258   pending_config_index_ = config;
1259 
1260   validated_ = false;
1261 
1262   // Trigger refresh. This config gets applied on next commit.
1263   callbacks_->Refresh(id_);
1264 
1265   return HWC2::Error::None;
1266 }
1267 
SetMixerResolution(uint32_t width,uint32_t height)1268 DisplayError HWCDisplay::SetMixerResolution(uint32_t width, uint32_t height) {
1269   return kErrorNotSupported;
1270 }
1271 
SetFrameDumpConfig(uint32_t count,uint32_t bit_mask_layer_type,int32_t format,bool post_processed)1272 HWC2::Error HWCDisplay::SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type,
1273                                            int32_t format, bool post_processed) {
1274   dump_frame_count_ = count;
1275   dump_frame_index_ = 0;
1276   dump_input_layers_ = ((bit_mask_layer_type & (1 << INPUT_LAYER_DUMP)) != 0);
1277 
1278   if (tone_mapper_) {
1279     tone_mapper_->SetFrameDumpConfig(count);
1280   }
1281 
1282   DLOGI("num_frame_dump %d, input_layer_dump_enable %d", dump_frame_count_, dump_input_layers_);
1283   validated_ = false;
1284   return HWC2::Error::None;
1285 }
1286 
GetCurrentPowerMode()1287 HWC2::PowerMode HWCDisplay::GetCurrentPowerMode() {
1288   return current_power_mode_;
1289 }
1290 
VSync(const DisplayEventVSync & vsync)1291 DisplayError HWCDisplay::VSync(const DisplayEventVSync &vsync) {
1292   if (callbacks_->Vsync_2_4CallbackRegistered()) {
1293     VsyncPeriodNanos vsync_period;
1294     if (GetDisplayVsyncPeriod(&vsync_period) != HWC2::Error::None) {
1295       vsync_period = 0;
1296     }
1297     ATRACE_INT("VsyncPeriod", INT32(vsync_period));
1298     callbacks_->Vsync_2_4(id_, vsync.timestamp, vsync_period);
1299   } else {
1300     callbacks_->Vsync(id_, vsync.timestamp);
1301   }
1302 
1303   return kErrorNone;
1304 }
1305 
Refresh()1306 DisplayError HWCDisplay::Refresh() {
1307   callbacks_->Refresh(id_);
1308   return kErrorNone;
1309 }
1310 
CECMessage(char * message)1311 DisplayError HWCDisplay::CECMessage(char *message) {
1312   if (qservice_) {
1313     qservice_->onCECMessageReceived(message, 0);
1314   } else {
1315     DLOGW("Qservice instance not available.");
1316   }
1317 
1318   return kErrorNone;
1319 }
1320 
HandleEvent(DisplayEvent event)1321 DisplayError HWCDisplay::HandleEvent(DisplayEvent event) {
1322   switch (event) {
1323     case kIdleTimeout: {
1324       SCOPE_LOCK(HWCSession::locker_[id_]);
1325       if (pending_commit_) {
1326         // If idle timeout event comes in between prepare
1327         // and commit, drop it since device is not really
1328         // idle.
1329         return kErrorNotSupported;
1330       }
1331       validated_ = false;
1332       break;
1333     }
1334     case kSyncInvalidateDisplay:
1335     case kThermalEvent: {
1336       SEQUENCE_WAIT_SCOPE_LOCK(HWCSession::locker_[id_]);
1337       validated_ = false;
1338     } break;
1339     case kPanelDeadEvent:
1340     case kDisplayPowerResetEvent: {
1341       // Mutex scope
1342       {
1343         SEQUENCE_WAIT_SCOPE_LOCK(HWCSession::locker_[id_]);
1344         validated_ = false;
1345       }
1346       // TODO(user): Following scenario need to be addressed
1347       // If panel or HW is in bad state for either ESD or HWR, there is no acquired lock between
1348       // this scope and call to DisplayPowerReset.
1349       // Prepare or commit could operate on the display since locker_[id_] is free and most likely
1350       // result in a failure since ESD/HWR has been requested during this time period.
1351       if (event_handler_) {
1352         event_handler_->DisplayPowerReset();
1353       } else {
1354         DLOGW("Cannot execute DisplayPowerReset (client_id = %" PRIu64 "), event_handler_ is null",
1355               id_);
1356       }
1357     } break;
1358     case kIdlePowerCollapse:
1359       break;
1360     case kInvalidateDisplay:
1361       validated_ = false;
1362       break;
1363     default:
1364       DLOGW("Unknown event: %d", event);
1365       break;
1366   }
1367 
1368   return kErrorNone;
1369 }
1370 
HistogramEvent(int,uint32_t)1371 DisplayError HWCDisplay::HistogramEvent(int /* fd */, uint32_t /* blob_fd */) {
1372   return kErrorNone;
1373 }
1374 
PrepareLayerStack(uint32_t * out_num_types,uint32_t * out_num_requests)1375 HWC2::Error HWCDisplay::PrepareLayerStack(uint32_t *out_num_types, uint32_t *out_num_requests) {
1376   layer_changes_.clear();
1377   layer_requests_.clear();
1378   has_client_composition_ = false;
1379 
1380   DTRACE_SCOPED();
1381   if (shutdown_pending_) {
1382     validated_ = false;
1383     return HWC2::Error::BadDisplay;
1384   }
1385 
1386   if (CanSkipSdmPrepare(out_num_types, out_num_requests)) {
1387     return ((*out_num_types > 0) ? HWC2::Error::HasChanges : HWC2::Error::None);
1388   }
1389 
1390   UpdateRefreshRate();
1391   UpdateActiveConfig();
1392   DisplayError error = display_intf_->Prepare(&layer_stack_);
1393   if (error != kErrorNone) {
1394     if (error == kErrorShutDown) {
1395       shutdown_pending_ = true;
1396     } else if (error == kErrorPermission) {
1397       WaitOnPreviousFence();
1398       MarkLayersForGPUBypass();
1399       geometry_changes_on_doze_suspend_ |= geometry_changes_;
1400     } else {
1401       DLOGW("Prepare failed. Error = %d", error);
1402       // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
1403       // so that previous buffer and fences are released, and override the error.
1404       flush_ = true;
1405       validated_ = false;
1406       // Prepare cycle can fail on a newly connected display if insufficient pipes
1407       // are available at this moment. Trigger refresh so that the other displays
1408       // can free up pipes and a valid content can be attached to virtual display.
1409       callbacks_->Refresh(id_);
1410       return HWC2::Error::BadDisplay;
1411     }
1412   } else {
1413     // clear geometry_changes_on_doze_suspend_ on successful prepare.
1414     geometry_changes_on_doze_suspend_ = GeometryChanges::kNone;
1415   }
1416 
1417   for (auto hwc_layer : layer_set_) {
1418     Layer *layer = hwc_layer->GetSDMLayer();
1419     LayerComposition &composition = layer->composition;
1420 
1421     if (composition == kCompositionSDE || composition == kCompositionStitch) {
1422       layer_requests_[hwc_layer->GetId()] = HWC2::LayerRequest::ClearClientTarget;
1423     }
1424 
1425     HWC2::Composition requested_composition = hwc_layer->GetClientRequestedCompositionType();
1426     // Set SDM composition to HWC2 type in HWCLayer
1427     hwc_layer->SetComposition(composition);
1428     HWC2::Composition device_composition  = hwc_layer->GetDeviceSelectedCompositionType();
1429     if (device_composition == HWC2::Composition::Client) {
1430       has_client_composition_ = true;
1431     }
1432     // Update the changes list only if the requested composition is different from SDM comp type
1433     if (requested_composition != device_composition) {
1434       layer_changes_[hwc_layer->GetId()] = device_composition;
1435     }
1436     hwc_layer->ResetValidation();
1437   }
1438 
1439   client_target_->ResetValidation();
1440   *out_num_types = UINT32(layer_changes_.size());
1441   *out_num_requests = UINT32(layer_requests_.size());
1442   validate_state_ = kNormalValidate;
1443   validated_ = true;
1444   layer_stack_invalid_ = false;
1445 
1446   return ((*out_num_types > 0) ? HWC2::Error::HasChanges : HWC2::Error::None);
1447 }
1448 
AcceptDisplayChanges()1449 HWC2::Error HWCDisplay::AcceptDisplayChanges() {
1450   if (layer_set_.empty()) {
1451     return HWC2::Error::None;
1452   }
1453 
1454   if (!validated_) {
1455     return HWC2::Error::NotValidated;
1456   }
1457 
1458   for (const auto& change : layer_changes_) {
1459     auto hwc_layer = layer_map_[change.first];
1460     auto composition = change.second;
1461     if (hwc_layer != nullptr) {
1462       hwc_layer->UpdateClientCompositionType(composition);
1463     } else {
1464       DLOGW("Invalid layer: %" PRIu64, change.first);
1465     }
1466   }
1467   return HWC2::Error::None;
1468 }
1469 
GetChangedCompositionTypes(uint32_t * out_num_elements,hwc2_layer_t * out_layers,int32_t * out_types)1470 HWC2::Error HWCDisplay::GetChangedCompositionTypes(uint32_t *out_num_elements,
1471                                                    hwc2_layer_t *out_layers, int32_t *out_types) {
1472   if (layer_set_.empty()) {
1473     return HWC2::Error::None;
1474   }
1475 
1476   if (!validated_) {
1477     DLOGW("Display is not validated");
1478     return HWC2::Error::NotValidated;
1479   }
1480 
1481   *out_num_elements = UINT32(layer_changes_.size());
1482   if (out_layers != nullptr && out_types != nullptr) {
1483     int i = 0;
1484     for (auto change : layer_changes_) {
1485       out_layers[i] = change.first;
1486       out_types[i] = INT32(change.second);
1487       i++;
1488     }
1489   }
1490   return HWC2::Error::None;
1491 }
1492 
GetReleaseFences(uint32_t * out_num_elements,hwc2_layer_t * out_layers,std::vector<shared_ptr<Fence>> * out_fences)1493 HWC2::Error HWCDisplay::GetReleaseFences(uint32_t *out_num_elements, hwc2_layer_t *out_layers,
1494                                          std::vector<shared_ptr<Fence>> *out_fences) {
1495   if (out_num_elements == nullptr) {
1496     return HWC2::Error::BadParameter;
1497   }
1498 
1499   if (out_layers != nullptr && out_fences != nullptr) {
1500     *out_num_elements = std::min(*out_num_elements, UINT32(layer_set_.size()));
1501     auto it = layer_set_.begin();
1502     for (uint32_t i = 0; i < *out_num_elements; i++, it++) {
1503       auto hwc_layer = *it;
1504       out_layers[i] = hwc_layer->GetId();
1505 
1506       shared_ptr<Fence> &fence = (*out_fences)[i];
1507       hwc_layer->PopFrontReleaseFence(&fence);
1508     }
1509   } else {
1510     *out_num_elements = UINT32(layer_set_.size());
1511   }
1512 
1513   return HWC2::Error::None;
1514 }
1515 
GetDisplayRequests(int32_t * out_display_requests,uint32_t * out_num_elements,hwc2_layer_t * out_layers,int32_t * out_layer_requests)1516 HWC2::Error HWCDisplay::GetDisplayRequests(int32_t *out_display_requests,
1517                                            uint32_t *out_num_elements, hwc2_layer_t *out_layers,
1518                                            int32_t *out_layer_requests) {
1519   if (layer_set_.empty()) {
1520     return HWC2::Error::None;
1521   }
1522 
1523   if (out_display_requests == nullptr || out_num_elements == nullptr) {
1524     return HWC2::Error::BadParameter;
1525   }
1526 
1527   // No display requests for now
1528   // Use for sharing blit buffers and
1529   // writing wfd buffer directly to output if there is full GPU composition
1530   // and no color conversion needed
1531   if (!validated_) {
1532     DLOGW("Display is not validated");
1533     return HWC2::Error::NotValidated;
1534   }
1535 
1536   *out_display_requests = 0;
1537   if (out_layers != nullptr && out_layer_requests != nullptr) {
1538     *out_num_elements = std::min(*out_num_elements, UINT32(layer_requests_.size()));
1539     auto it = layer_requests_.begin();
1540     for (uint32_t i = 0; i < *out_num_elements; i++, it++) {
1541       out_layers[i] = it->first;
1542       out_layer_requests[i] = INT32(it->second);
1543     }
1544   } else {
1545     *out_num_elements = UINT32(layer_requests_.size());
1546   }
1547 
1548   auto client_target_layer = client_target_->GetSDMLayer();
1549   if (client_target_layer->request.flags.flip_buffer) {
1550     *out_display_requests = INT32(HWC2::DisplayRequest::FlipClientTarget);
1551   }
1552 
1553   return HWC2::Error::None;
1554 }
1555 
GetHdrCapabilities(uint32_t * out_num_types,int32_t * out_types,float * out_max_luminance,float * out_max_average_luminance,float * out_min_luminance)1556 HWC2::Error HWCDisplay::GetHdrCapabilities(uint32_t *out_num_types, int32_t *out_types,
1557                                            float *out_max_luminance,
1558                                            float *out_max_average_luminance,
1559                                            float *out_min_luminance) {
1560   if (out_num_types == nullptr || out_max_luminance == nullptr ||
1561       out_max_average_luminance == nullptr || out_min_luminance == nullptr) {
1562     return HWC2::Error::BadParameter;
1563   }
1564 
1565   DisplayConfigFixedInfo fixed_info = {};
1566   display_intf_->GetConfig(&fixed_info);
1567 
1568   if (!fixed_info.hdr_supported) {
1569     *out_num_types = 0;
1570     DLOGI("HDR is not supported");
1571     return HWC2::Error::None;
1572   }
1573 
1574   uint32_t num_types = 0;
1575   if (fixed_info.hdr_plus_supported) {
1576     num_types = UINT32(Hdr::HDR10_PLUS) - 1;
1577   } else {
1578     num_types = UINT32(Hdr::HLG) - 1;
1579   }
1580 
1581   // We support HDR10, HLG and HDR10_PLUS.
1582   if (out_types == nullptr) {
1583     *out_num_types = num_types;
1584   } else {
1585     uint32_t max_out_types = std::min(*out_num_types, num_types);
1586     int32_t type = static_cast<int32_t>(Hdr::DOLBY_VISION);
1587     for (int32_t i = 0; i < max_out_types; i++) {
1588       while (type == static_cast<int32_t>(Hdr::DOLBY_VISION) /* Skip list */) {
1589         // Skip the type
1590         type++;
1591       }
1592       if (type > (num_types + 1)) {
1593         break;
1594       }
1595       out_types[i] = type++;
1596     }
1597     *out_max_luminance = fixed_info.max_luminance;
1598     *out_max_average_luminance = fixed_info.average_luminance;
1599     *out_min_luminance = fixed_info.min_luminance;
1600   }
1601 
1602   return HWC2::Error::None;
1603 }
1604 
1605 
CommitLayerStack(void)1606 HWC2::Error HWCDisplay::CommitLayerStack(void) {
1607   if (flush_) {
1608     return HWC2::Error::None;
1609   }
1610 
1611   DTRACE_SCOPED();
1612 
1613   if (!validated_) {
1614     DLOGV_IF(kTagClient, "Display %" PRIu64 "is not validated", id_);
1615     return HWC2::Error::NotValidated;
1616   }
1617 
1618   if (shutdown_pending_ || layer_set_.empty()) {
1619     return HWC2::Error::None;
1620   }
1621 
1622   if (skip_commit_) {
1623     DLOGV_IF(kTagClient, "Skipping Refresh on display %" PRIu64 , id_);
1624     return HWC2::Error::None;
1625   }
1626 
1627   DumpInputBuffers();
1628 
1629   DisplayError error = kErrorUndefined;
1630   int status = 0;
1631   if (tone_mapper_) {
1632     if (NeedsToneMap(layer_stack_)) {
1633       status = tone_mapper_->HandleToneMap(&layer_stack_);
1634       if (status != 0) {
1635         DLOGE("Error handling HDR in ToneMapper");
1636       }
1637     } else {
1638       tone_mapper_->Terminate();
1639     }
1640   }
1641 
1642   if (elapse_timestamp_) {
1643     layer_stack_.elapse_timestamp = elapse_timestamp_;
1644   }
1645 
1646   error = display_intf_->Commit(&layer_stack_);
1647 
1648   if (error == kErrorNone) {
1649     // A commit is successfully submitted, start flushing on failure now onwards.
1650     flush_on_error_ = true;
1651     first_cycle_ = false;
1652   } else {
1653     if (error == kErrorShutDown) {
1654       shutdown_pending_ = true;
1655       return HWC2::Error::Unsupported;
1656     } else if (error == kErrorNotValidated) {
1657       validated_ = false;
1658       return HWC2::Error::NotValidated;
1659     } else if (error != kErrorPermission) {
1660       DLOGE("Commit failed. Error = %d", error);
1661       // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
1662       // so that previous buffer and fences are released, and override the error.
1663       flush_ = true;
1664     }
1665   }
1666 
1667   validate_state_ = kSkipValidate;
1668   return HWC2::Error::None;
1669 }
1670 
PostCommitLayerStack(shared_ptr<Fence> * out_retire_fence)1671 HWC2::Error HWCDisplay::PostCommitLayerStack(shared_ptr<Fence> *out_retire_fence) {
1672   auto status = HWC2::Error::None;
1673 
1674   // Do no call flush on errors, if a successful buffer is never submitted.
1675   if (flush_ && flush_on_error_) {
1676     display_intf_->Flush(&layer_stack_);
1677     validated_ = false;
1678   }
1679 
1680   if (tone_mapper_ && tone_mapper_->IsActive()) {
1681      tone_mapper_->PostCommit(&layer_stack_);
1682   }
1683 
1684   // TODO(user): No way to set the client target release fence on SF
1685   shared_ptr<Fence> client_target_release_fence =
1686       client_target_->GetSDMLayer()->input_buffer.release_fence;
1687   if (client_target_release_fence) {
1688     fbt_release_fence_ = client_target_release_fence;
1689   }
1690   client_target_->ResetGeometryChanges();
1691 
1692   for (auto hwc_layer : layer_set_) {
1693     hwc_layer->ResetGeometryChanges();
1694     Layer *layer = hwc_layer->GetSDMLayer();
1695     LayerBuffer *layer_buffer = &layer->input_buffer;
1696 
1697     if (!flush_) {
1698       // If swapinterval property is set to 0 or for single buffer layers, do not update f/w
1699       // release fences and discard fences from driver
1700       if (!swap_interval_zero_ && !layer->flags.single_buffer) {
1701         // It may so happen that layer gets marked to GPU & app layer gets queued
1702         // to MDP for composition. In those scenarios, release fence of buffer should
1703         // have mdp and gpu sync points merged.
1704         hwc_layer->PushBackReleaseFence(layer_buffer->release_fence);
1705       }
1706     } else {
1707       // In case of flush or display paused, we don't return an error to f/w, so it will
1708       // get a release fence out of the hwc_layer's release fence queue
1709       // We should push a -1 to preserve release fence circulation semantics.
1710       hwc_layer->PushBackReleaseFence(nullptr);
1711     }
1712 
1713     layer->request.flags = {};
1714     layer_buffer->acquire_fence = nullptr;
1715   }
1716 
1717   client_target_->GetSDMLayer()->request.flags = {};
1718   // if swapinterval property is set to 0 then close and reset the list retire fence
1719   if (!swap_interval_zero_) {
1720     *out_retire_fence = layer_stack_.retire_fence;
1721   }
1722 
1723   if (dump_frame_count_) {
1724     dump_frame_count_--;
1725     dump_frame_index_++;
1726   }
1727 
1728   layer_stack_.flags.geometry_changed = false;
1729   geometry_changes_ = GeometryChanges::kNone;
1730   flush_ = false;
1731   skip_commit_ = false;
1732 
1733   return status;
1734 }
1735 
SetIdleTimeoutMs(uint32_t timeout_ms)1736 void HWCDisplay::SetIdleTimeoutMs(uint32_t timeout_ms) {
1737   return;
1738 }
1739 
SetMaxMixerStages(uint32_t max_mixer_stages)1740 DisplayError HWCDisplay::SetMaxMixerStages(uint32_t max_mixer_stages) {
1741   DisplayError error = kErrorNone;
1742 
1743   if (display_intf_) {
1744     error = display_intf_->SetMaxMixerStages(max_mixer_stages);
1745     validated_ = false;
1746   }
1747 
1748   return error;
1749 }
1750 
DumpInputBuffers()1751 void HWCDisplay::DumpInputBuffers() {
1752   char dir_path[PATH_MAX];
1753   int  status;
1754 
1755   if (!dump_frame_count_ || flush_ || !dump_input_layers_) {
1756     return;
1757   }
1758 
1759   DLOGI("dump_frame_count %d dump_input_layers %d", dump_frame_count_, dump_input_layers_);
1760   snprintf(dir_path, sizeof(dir_path), "%s/frame_dump_disp_id_%02u_%s", HWCDebugHandler::DumpDir(),
1761            UINT32(id_), GetDisplayString());
1762 
1763   status = mkdir(dir_path, 777);
1764   if ((status != 0) && errno != EEXIST) {
1765     DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno));
1766     return;
1767   }
1768 
1769   // Even if directory exists already, need to explicitly change the permission.
1770   if (chmod(dir_path, 0777) != 0) {
1771     DLOGW("Failed to change permissions on %s directory", dir_path);
1772     return;
1773   }
1774 
1775   for (uint32_t i = 0; i < layer_stack_.layers.size(); i++) {
1776     auto layer = layer_stack_.layers.at(i);
1777     const private_handle_t *pvt_handle =
1778         reinterpret_cast<const private_handle_t *>(layer->input_buffer.buffer_id);
1779     Fence::Wait(layer->input_buffer.acquire_fence);
1780 
1781     DLOGI("Dump layer[%d] of %d pvt_handle %p pvt_handle->base %" PRIx64, i,
1782           UINT32(layer_stack_.layers.size()), pvt_handle, pvt_handle? pvt_handle->base : 0);
1783 
1784     if (!pvt_handle) {
1785       DLOGE("Buffer handle is null");
1786       continue;
1787     }
1788 
1789     if (!pvt_handle->base) {
1790       DisplayError error = buffer_allocator_->MapBuffer(pvt_handle, nullptr);
1791       if (error != kErrorNone) {
1792         DLOGE("Failed to map buffer, error = %d", error);
1793         continue;
1794       }
1795     }
1796 
1797     char dump_file_name[PATH_MAX];
1798     size_t result = 0;
1799 
1800     snprintf(dump_file_name, sizeof(dump_file_name), "%s/input_layer%d_%dx%d_%s_frame%d.raw",
1801              dir_path, i, pvt_handle->width, pvt_handle->height,
1802              qdutils::GetHALPixelFormatString(pvt_handle->format), dump_frame_index_);
1803 
1804     FILE *fp = fopen(dump_file_name, "w+");
1805     if (fp) {
1806       result = fwrite(reinterpret_cast<void *>(pvt_handle->base), pvt_handle->size, 1, fp);
1807       fclose(fp);
1808     }
1809 
1810     int release_fence = -1;
1811     DisplayError error = buffer_allocator_->UnmapBuffer(pvt_handle, &release_fence);
1812     if (error != kErrorNone) {
1813       DLOGE("Failed to unmap buffer, error = %d", error);
1814       continue;
1815     }
1816 
1817     DLOGI("Frame Dump %s: is %s", dump_file_name, result ? "Successful" : "Failed");
1818   }
1819 }
1820 
DumpOutputBuffer(const BufferInfo & buffer_info,void * base,shared_ptr<Fence> & retire_fence)1821 void HWCDisplay::DumpOutputBuffer(const BufferInfo &buffer_info, void *base,
1822                                   shared_ptr<Fence> &retire_fence) {
1823   char dir_path[PATH_MAX];
1824   int  status;
1825 
1826   snprintf(dir_path, sizeof(dir_path), "%s/frame_dump_disp_id_%02u_%s", HWCDebugHandler::DumpDir(),
1827            UINT32(id_), GetDisplayString());
1828 
1829   status = mkdir(dir_path, 777);
1830   if ((status != 0) && errno != EEXIST) {
1831     DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno));
1832     return;
1833   }
1834 
1835   // Even if directory exists already, need to explicitly change the permission.
1836   if (chmod(dir_path, 0777) != 0) {
1837     DLOGW("Failed to change permissions on %s directory", dir_path);
1838     return;
1839   }
1840 
1841   if (base) {
1842     char dump_file_name[PATH_MAX];
1843     size_t result = 0;
1844 
1845     if (Fence::Wait(retire_fence) != kErrorNone) {
1846       DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
1847       return;
1848     }
1849 
1850     snprintf(dump_file_name, sizeof(dump_file_name), "%s/output_layer_%dx%d_%s_frame%d.raw",
1851              dir_path, buffer_info.alloc_buffer_info.aligned_width,
1852              buffer_info.alloc_buffer_info.aligned_height,
1853              GetFormatString(buffer_info.buffer_config.format), dump_frame_index_);
1854 
1855     FILE *fp = fopen(dump_file_name, "w+");
1856     if (fp) {
1857       result = fwrite(base, buffer_info.alloc_buffer_info.size, 1, fp);
1858       fclose(fp);
1859     }
1860 
1861     DLOGI("Frame Dump of %s is %s", dump_file_name, result ? "Successful" : "Failed");
1862   }
1863 }
1864 
GetDisplayString()1865 const char *HWCDisplay::GetDisplayString() {
1866   switch (type_) {
1867     case kBuiltIn:
1868       return "builtin";
1869     case kPluggable:
1870       return "pluggable";
1871     case kVirtual:
1872       return "virtual";
1873     default:
1874       return "invalid";
1875   }
1876 }
1877 
SetFrameBufferConfig(uint32_t x_pixels,uint32_t y_pixels)1878 int HWCDisplay::SetFrameBufferConfig(uint32_t x_pixels, uint32_t y_pixels) {
1879   if (x_pixels <= 0 || y_pixels <= 0) {
1880     DLOGW("Unsupported config: x_pixels=%d, y_pixels=%d", x_pixels, y_pixels);
1881     return -EINVAL;
1882   }
1883 
1884   DisplayConfigVariableInfo fb_config;
1885   DisplayError error = display_intf_->GetFrameBufferConfig(&fb_config);
1886   if (error != kErrorNone) {
1887     DLOGV("Get frame buffer config failed. Error = %d", error);
1888     return -EINVAL;
1889   }
1890 
1891   fb_config.x_pixels = x_pixels;
1892   fb_config.y_pixels = y_pixels;
1893 
1894   error = display_intf_->SetFrameBufferConfig(fb_config);
1895   if (error != kErrorNone) {
1896     DLOGV("Set frame buffer config failed. Error = %d", error);
1897     return -EINVAL;
1898   }
1899 
1900   // Reduce the src_rect and dst_rect as per FBT config.
1901   // SF sending reduced FBT but here the src_rect is equal to mixer which is
1902   // higher than allocated buffer of FBT.
1903   if (windowed_display_) {
1904     x_pixels -= UINT32(window_rect_.right + window_rect_.left);
1905     y_pixels -= UINT32(window_rect_.bottom + window_rect_.top);
1906   }
1907 
1908   if (x_pixels <= 0 || y_pixels <= 0) {
1909     DLOGE("window rects are not within the supported range");
1910     return -EINVAL;
1911   }
1912 
1913   // Create rects to represent the new source and destination crops
1914   LayerRect crop = LayerRect(0, 0, FLOAT(x_pixels), FLOAT(y_pixels));
1915   hwc_rect_t scaled_display_frame = {0, 0, INT(x_pixels), INT(y_pixels)};
1916   auto client_target_layer = client_target_->GetSDMLayer();
1917   client_target_layer->src_rect = crop;
1918   ApplyScanAdjustment(&scaled_display_frame);
1919   client_target_->SetLayerDisplayFrame(scaled_display_frame);
1920   client_target_->ResetPerFrameData();
1921 
1922   DLOGI("New framebuffer resolution (%dx%d)", fb_config.x_pixels, fb_config.y_pixels);
1923 
1924   return 0;
1925 }
1926 
SetFrameBufferResolution(uint32_t x_pixels,uint32_t y_pixels)1927 int HWCDisplay::SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels) {
1928   int error = SetFrameBufferConfig(x_pixels, y_pixels);
1929   if (error < 0) {
1930     DLOGV("SetFrameBufferConfig failed. Error = %d", error);
1931     return error;
1932   }
1933 
1934   if (windowed_display_) {
1935     x_pixels -= UINT32(window_rect_.right + window_rect_.left);
1936     y_pixels -= UINT32(window_rect_.bottom + window_rect_.top);
1937   }
1938   auto client_target_layer = client_target_->GetSDMLayer();
1939 
1940   int aligned_width;
1941   int aligned_height;
1942   uint32_t usage = GRALLOC_USAGE_HW_FB;
1943   int format = HAL_PIXEL_FORMAT_RGBA_8888;
1944   int ubwc_disabled = 0;
1945   int flags = 0;
1946 
1947   // By default UBWC is enabled and below property is global enable/disable for all
1948   // buffers allocated through gralloc , including framebuffer targets.
1949   HWCDebugHandler::Get()->GetProperty(DISABLE_UBWC_PROP, &ubwc_disabled);
1950   if (!ubwc_disabled) {
1951     usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
1952     flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
1953   }
1954 
1955   buffer_allocator_->GetAlignedWidthAndHeight(INT(x_pixels), INT(y_pixels), format, usage,
1956                                               &aligned_width, &aligned_height);
1957 
1958   // TODO(user): How does the dirty region get set on the client target? File bug on Google
1959   client_target_layer->composition = kCompositionGPUTarget;
1960   client_target_layer->input_buffer.format = HWCLayer::GetSDMFormat(format, flags);
1961   client_target_layer->input_buffer.width = UINT32(aligned_width);
1962   client_target_layer->input_buffer.height = UINT32(aligned_height);
1963   client_target_layer->input_buffer.unaligned_width = x_pixels;
1964   client_target_layer->input_buffer.unaligned_height = y_pixels;
1965   client_target_layer->plane_alpha = 255;
1966 
1967   return 0;
1968 }
1969 
GetFrameBufferResolution(uint32_t * x_pixels,uint32_t * y_pixels)1970 void HWCDisplay::GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
1971   DisplayConfigVariableInfo fb_config;
1972   display_intf_->GetFrameBufferConfig(&fb_config);
1973 
1974   *x_pixels = fb_config.x_pixels;
1975   *y_pixels = fb_config.y_pixels;
1976 }
1977 
GetMixerResolution(uint32_t * x_pixels,uint32_t * y_pixels)1978 DisplayError HWCDisplay::GetMixerResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
1979   return display_intf_->GetMixerResolution(x_pixels, y_pixels);
1980 }
1981 
GetPanelResolution(uint32_t * x_pixels,uint32_t * y_pixels)1982 void HWCDisplay::GetPanelResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
1983   DisplayConfigVariableInfo display_config;
1984   uint32_t active_index = 0;
1985 
1986   display_intf_->GetActiveConfig(&active_index);
1987   display_intf_->GetConfig(active_index, &display_config);
1988 
1989   *x_pixels = display_config.x_pixels;
1990   *y_pixels = display_config.y_pixels;
1991 }
1992 
SetDisplayStatus(DisplayStatus display_status)1993 int HWCDisplay::SetDisplayStatus(DisplayStatus display_status) {
1994   int status = 0;
1995 
1996   switch (display_status) {
1997     case kDisplayStatusResume:
1998       display_paused_ = false;
1999       status = INT32(SetPowerMode(HWC2::PowerMode::On, false /* teardown */));
2000       break;
2001     case kDisplayStatusOnline:
2002       status = INT32(SetPowerMode(HWC2::PowerMode::On, false /* teardown */));
2003       break;
2004     case kDisplayStatusPause:
2005       display_paused_ = true;
2006       status = INT32(SetPowerMode(HWC2::PowerMode::Off, false /* teardown */));
2007       break;
2008     case kDisplayStatusOffline:
2009       status = INT32(SetPowerMode(HWC2::PowerMode::Off, false /* teardown */));
2010       break;
2011     default:
2012       DLOGW("Invalid display status %d", display_status);
2013       return -EINVAL;
2014   }
2015 
2016   return status;
2017 }
2018 
SetCursorPosition(hwc2_layer_t layer,int x,int y)2019 HWC2::Error HWCDisplay::SetCursorPosition(hwc2_layer_t layer, int x, int y) {
2020   if (shutdown_pending_) {
2021     return HWC2::Error::None;
2022   }
2023 
2024   if (!layer_stack_.flags.cursor_present) {
2025     DLOGW("Cursor layer not present");
2026     return HWC2::Error::BadLayer;
2027   }
2028 
2029   HWCLayer *hwc_layer = GetHWCLayer(layer);
2030   if (hwc_layer == nullptr) {
2031     return HWC2::Error::BadLayer;
2032   }
2033   if (hwc_layer->GetDeviceSelectedCompositionType() != HWC2::Composition::Cursor) {
2034     return HWC2::Error::None;
2035   }
2036   if ((validate_state_ != kSkipValidate) && validated_) {
2037     // the device is currently in the middle of the validate/present sequence,
2038     // cannot set the Position(as per HWC2 spec)
2039     return HWC2::Error::NotValidated;
2040   }
2041 
2042   DisplayState state;
2043   if (display_intf_->GetDisplayState(&state) == kErrorNone) {
2044     if (state != kStateOn) {
2045       return HWC2::Error::None;
2046     }
2047   }
2048 
2049   // TODO(user): HWC1.5 was not letting SetCursorPosition before validateDisplay,
2050   // but HWC2.0 doesn't let setting cursor position after validate before present.
2051   // Need to revisit.
2052 
2053   auto error = display_intf_->SetCursorPosition(x, y);
2054   if (error != kErrorNone) {
2055     if (error == kErrorShutDown) {
2056       shutdown_pending_ = true;
2057       return HWC2::Error::None;
2058     }
2059 
2060     DLOGE("Failed for x = %d y = %d, Error = %d", x, y, error);
2061     return HWC2::Error::BadDisplay;
2062   }
2063 
2064   return HWC2::Error::None;
2065 }
2066 
OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level)2067 int HWCDisplay::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) {
2068   DisplayError error = display_intf_->OnMinHdcpEncryptionLevelChange(min_enc_level);
2069   if (error != kErrorNone) {
2070     DLOGE("Failed. Error = %d", error);
2071     return -1;
2072   }
2073 
2074   validated_ = false;
2075   return 0;
2076 }
2077 
MarkLayersForGPUBypass()2078 void HWCDisplay::MarkLayersForGPUBypass() {
2079   for (auto hwc_layer : layer_set_) {
2080     auto layer = hwc_layer->GetSDMLayer();
2081     layer->composition = kCompositionSDE;
2082   }
2083   validated_ = true;
2084 }
2085 
MarkLayersForClientComposition()2086 void HWCDisplay::MarkLayersForClientComposition() {
2087   // ClientComposition - GPU comp, to acheive this, set skip flag so that
2088   // SDM does not handle this layer and hwc_layer composition will be
2089   // set correctly at the end of Prepare.
2090   DLOGV_IF(kTagClient, "HWC Layers marked for GPU comp");
2091   for (auto hwc_layer : layer_set_) {
2092     Layer *layer = hwc_layer->GetSDMLayer();
2093     layer->flags.skip = true;
2094   }
2095   layer_stack_.flags.skip_present = true;
2096 }
2097 
ApplyScanAdjustment(hwc_rect_t * display_frame)2098 void HWCDisplay::ApplyScanAdjustment(hwc_rect_t *display_frame) {
2099 }
2100 
ToggleScreenUpdates(bool enable)2101 int HWCDisplay::ToggleScreenUpdates(bool enable) {
2102   display_paused_ = enable ? false : true;
2103   callbacks_->Refresh(id_);
2104   validated_ = false;
2105   return 0;
2106 }
2107 
ColorSVCRequestRoute(const PPDisplayAPIPayload & in_payload,PPDisplayAPIPayload * out_payload,PPPendingParams * pending_action)2108 int HWCDisplay::ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
2109                                      PPDisplayAPIPayload *out_payload,
2110                                      PPPendingParams *pending_action) {
2111   int ret = 0;
2112 
2113   if (display_intf_)
2114     ret = display_intf_->ColorSVCRequestRoute(in_payload, out_payload, pending_action);
2115   else
2116     ret = -EINVAL;
2117 
2118   return ret;
2119 }
2120 
SolidFillPrepare()2121 void HWCDisplay::SolidFillPrepare() {
2122   if (solid_fill_enable_) {
2123     if (solid_fill_layer_ == NULL) {
2124       // Create a dummy layer here
2125       solid_fill_layer_ = new Layer();
2126     }
2127     uint32_t primary_width = 0, primary_height = 0;
2128     GetMixerResolution(&primary_width, &primary_height);
2129 
2130     LayerBuffer *layer_buffer = &solid_fill_layer_->input_buffer;
2131     layer_buffer->width = primary_width;
2132     layer_buffer->height = primary_height;
2133     layer_buffer->unaligned_width = primary_width;
2134     layer_buffer->unaligned_height = primary_height;
2135 
2136     solid_fill_layer_->composition = kCompositionGPU;
2137     solid_fill_layer_->src_rect = solid_fill_rect_;
2138     solid_fill_layer_->dst_rect = solid_fill_rect_;
2139 
2140     solid_fill_layer_->blending = kBlendingPremultiplied;
2141     solid_fill_layer_->solid_fill_color = 0;
2142     solid_fill_layer_->solid_fill_info.bit_depth = solid_fill_color_.bit_depth;
2143     solid_fill_layer_->solid_fill_info.red = solid_fill_color_.red;
2144     solid_fill_layer_->solid_fill_info.blue = solid_fill_color_.blue;
2145     solid_fill_layer_->solid_fill_info.green = solid_fill_color_.green;
2146     solid_fill_layer_->solid_fill_info.alpha = solid_fill_color_.alpha;
2147     solid_fill_layer_->frame_rate = 60;
2148     solid_fill_layer_->visible_regions.push_back(solid_fill_layer_->dst_rect);
2149     solid_fill_layer_->flags.updating = 1;
2150     solid_fill_layer_->flags.solid_fill = true;
2151   } else {
2152     // delete the dummy layer
2153     delete solid_fill_layer_;
2154     solid_fill_layer_ = NULL;
2155   }
2156 
2157   if (solid_fill_enable_ && solid_fill_layer_) {
2158     BuildSolidFillStack();
2159     MarkLayersForGPUBypass();
2160   }
2161 
2162   return;
2163 }
2164 
GetVisibleDisplayRect(hwc_rect_t * visible_rect)2165 int HWCDisplay::GetVisibleDisplayRect(hwc_rect_t *visible_rect) {
2166   if (!IsValid(display_rect_)) {
2167     return -EINVAL;
2168   }
2169 
2170   visible_rect->left = INT(display_rect_.left);
2171   visible_rect->top = INT(display_rect_.top);
2172   visible_rect->right = INT(display_rect_.right);
2173   visible_rect->bottom = INT(display_rect_.bottom);
2174   DLOGI("Visible Display Rect(%d %d %d %d)", visible_rect->left, visible_rect->top,
2175         visible_rect->right, visible_rect->bottom);
2176 
2177   return 0;
2178 }
2179 
HandleSecureSession(const std::bitset<kSecureMax> & secure_sessions,bool * power_on_pending)2180 int HWCDisplay::HandleSecureSession(const std::bitset<kSecureMax> &secure_sessions,
2181                                     bool *power_on_pending) {
2182   if (!power_on_pending) {
2183     return -EINVAL;
2184   }
2185 
2186   if (active_secure_sessions_[kSecureDisplay] != secure_sessions[kSecureDisplay]) {
2187     if (secure_sessions[kSecureDisplay]) {
2188       pending_power_mode_ = current_power_mode_;
2189       HWC2::Error error = SetPowerMode(HWC2::PowerMode::Off, true /* teardown */);
2190       if (error != HWC2::Error::None) {
2191         DLOGE("SetPowerMode failed. Error = %d", error);
2192       }
2193     } else {
2194       *power_on_pending = true;
2195     }
2196 
2197     DLOGI("SecureDisplay state changed from %d to %d for display %" PRIu64 "-%d",
2198           active_secure_sessions_.test(kSecureDisplay), secure_sessions.test(kSecureDisplay),
2199           id_, type_);
2200   }
2201   active_secure_sessions_ = secure_sessions;
2202   return 0;
2203 }
2204 
GetActiveSecureSession(std::bitset<kSecureMax> * secure_sessions)2205 int HWCDisplay::GetActiveSecureSession(std::bitset<kSecureMax> *secure_sessions) {
2206   if (!secure_sessions) {
2207     return -1;
2208   }
2209   secure_sessions->reset();
2210   for (auto hwc_layer : layer_set_) {
2211     Layer *layer = hwc_layer->GetSDMLayer();
2212     if (layer->input_buffer.flags.secure_camera) {
2213       secure_sessions->set(kSecureCamera);
2214     }
2215     if (layer->input_buffer.flags.secure_display) {
2216       secure_sessions->set(kSecureDisplay);
2217     }
2218   }
2219   return 0;
2220 }
2221 
SetActiveDisplayConfig(uint32_t config)2222 int HWCDisplay::SetActiveDisplayConfig(uint32_t config) {
2223   uint32_t current_config = 0;
2224   display_intf_->GetActiveConfig(&current_config);
2225   if (config == current_config) {
2226     return 0;
2227   }
2228 
2229   validated_ = false;
2230   display_intf_->SetActiveConfig(config);
2231 
2232   return 0;
2233 }
2234 
GetActiveDisplayConfig(uint32_t * config)2235 int HWCDisplay::GetActiveDisplayConfig(uint32_t *config) {
2236   return display_intf_->GetActiveConfig(config) == kErrorNone ? 0 : -1;
2237 }
2238 
GetDisplayConfigCount(uint32_t * count)2239 int HWCDisplay::GetDisplayConfigCount(uint32_t *count) {
2240   return display_intf_->GetNumVariableInfoConfigs(count) == kErrorNone ? 0 : -1;
2241 }
2242 
GetDisplayAttributesForConfig(int config,DisplayConfigVariableInfo * display_attributes)2243 int HWCDisplay::GetDisplayAttributesForConfig(int config,
2244                                             DisplayConfigVariableInfo *display_attributes) {
2245   return display_intf_->GetConfig(UINT32(config), display_attributes) == kErrorNone ? 0 : -1;
2246 }
2247 
GetUpdatingLayersCount(void)2248 uint32_t HWCDisplay::GetUpdatingLayersCount(void) {
2249   uint32_t updating_count = 0;
2250 
2251   for (uint i = 0; i < layer_stack_.layers.size(); i++) {
2252     auto layer = layer_stack_.layers.at(i);
2253     if (layer->flags.updating) {
2254       updating_count++;
2255     }
2256   }
2257 
2258   return updating_count;
2259 }
2260 
IsLayerUpdating(HWCLayer * hwc_layer)2261 bool HWCDisplay::IsLayerUpdating(HWCLayer *hwc_layer) {
2262   auto layer = hwc_layer->GetSDMLayer();
2263   // Layer should be considered updating if
2264   //   a) layer is in single buffer mode, or
2265   //   b) valid dirty_regions(android specific hint for updating status), or
2266   //   c) layer stack geometry has changed (TODO(user): Remove when SDM accepts
2267   //      geometry_changed as bit fields).
2268   return (layer->flags.single_buffer || hwc_layer->IsSurfaceUpdated() ||
2269           geometry_changes_);
2270 }
2271 
SanitizeRefreshRate(uint32_t req_refresh_rate)2272 uint32_t HWCDisplay::SanitizeRefreshRate(uint32_t req_refresh_rate) {
2273   uint32_t refresh_rate = req_refresh_rate;
2274 
2275   if (refresh_rate < min_refresh_rate_) {
2276     // Pick the next multiple of request which is within the range
2277     refresh_rate =
2278         (((min_refresh_rate_ / refresh_rate) + ((min_refresh_rate_ % refresh_rate) ? 1 : 0)) *
2279          refresh_rate);
2280   }
2281 
2282   if (refresh_rate > max_refresh_rate_) {
2283     refresh_rate = max_refresh_rate_;
2284   }
2285 
2286   return refresh_rate;
2287 }
2288 
GetDisplayClass()2289 DisplayClass HWCDisplay::GetDisplayClass() {
2290   return display_class_;
2291 }
2292 
Dump(std::ostringstream * os)2293 void HWCDisplay::Dump(std::ostringstream *os) {
2294   *os << "\n------------HWC----------------\n";
2295   *os << "HWC2 display_id: " << id_ << std::endl;
2296   for (auto layer : layer_set_) {
2297     auto sdm_layer = layer->GetSDMLayer();
2298     auto transform = sdm_layer->transform;
2299     *os << "layer: " << std::setw(4) << layer->GetId();
2300     *os << " z: " << layer->GetZ();
2301     *os << " composition: " <<
2302           to_string(layer->GetClientRequestedCompositionType()).c_str();
2303     *os << "/" <<
2304           to_string(layer->GetDeviceSelectedCompositionType()).c_str();
2305     *os << " alpha: " << std::to_string(sdm_layer->plane_alpha).c_str();
2306     *os << " format: " << std::setw(22) << GetFormatString(sdm_layer->input_buffer.format);
2307     *os << " dataspace:" << std::hex << "0x" << std::setw(8) << std::setfill('0')
2308         << layer->GetLayerDataspace() << std::dec << std::setfill(' ');
2309     *os << " transform: " << transform.rotation << "/" << transform.flip_horizontal <<
2310           "/"<< transform.flip_vertical;
2311     *os << " buffer_id: " << std::hex << "0x" << sdm_layer->input_buffer.buffer_id << std::dec;
2312     *os << " secure: " << layer->IsProtected()
2313         << std::endl;
2314   }
2315 
2316   if (has_client_composition_) {
2317     *os << "\n---------client target---------\n";
2318     auto sdm_layer = client_target_->GetSDMLayer();
2319     *os << "format: " << std::setw(14) << GetFormatString(sdm_layer->input_buffer.format);
2320     *os << " dataspace:" << std::hex << "0x" << std::setw(8) << std::setfill('0')
2321         << client_target_->GetLayerDataspace() << std::dec << std::setfill(' ');
2322     *os << "  buffer_id: " << std::hex << "0x" << sdm_layer->input_buffer.buffer_id << std::dec;
2323     *os << " secure: " << client_target_->IsProtected()
2324         << std::endl;
2325   }
2326 
2327   *os << "\npanel gamma source: " << GetCurrentPanelGammaSource() << std::endl;
2328 
2329   if (layer_stack_invalid_) {
2330     *os << "\n Layers added or removed but not reflected to SDM's layer stack yet\n";
2331     return;
2332   }
2333 
2334   if (color_mode_) {
2335     *os << "\n----------Color Modes---------\n";
2336     color_mode_->Dump(os);
2337   }
2338 
2339   if (display_intf_) {
2340     *os << "\n------------SDM----------------\n";
2341     *os << display_intf_->Dump();
2342   }
2343 
2344   *os << "\n";
2345 }
2346 
CanSkipValidate()2347 bool HWCDisplay::CanSkipValidate() {
2348   if (!validated_ || solid_fill_enable_) {
2349     return false;
2350   }
2351 
2352   if ((tone_mapper_ && tone_mapper_->IsActive()) ||
2353       layer_stack_.flags.single_buffered_layer_present) {
2354     DLOGV_IF(kTagClient, "Tonemapping enabled or single buffer layer present = %d"
2355              " Returning false.", layer_stack_.flags.single_buffered_layer_present);
2356     return false;
2357   }
2358 
2359   if (client_target_->NeedsValidation()) {
2360     DLOGV_IF(kTagClient, "Framebuffer target needs validation. Returning false.");
2361     return false;
2362   }
2363 
2364   for (auto hwc_layer : layer_set_) {
2365     Layer *layer = hwc_layer->GetSDMLayer();
2366     if (hwc_layer->NeedsValidation()) {
2367       DLOGV_IF(kTagClient, "hwc_layer[%" PRIu64 "] needs validation. Returning false.",
2368                hwc_layer->GetId());
2369       return false;
2370     }
2371 
2372     // Do not allow Skip Validate, if any layer needs GPU Composition.
2373     if (layer->composition == kCompositionGPU || layer->composition == kCompositionNone) {
2374       DLOGV_IF(kTagClient, "hwc_layer[%" PRIu64 "] is %s. Returning false.", hwc_layer->GetId(),
2375                (layer->composition == kCompositionGPU) ? "GPU composed": "Dropped");
2376       return false;
2377     }
2378   }
2379 
2380   if (!layer_set_.empty() && !display_intf_->CanSkipValidate()) {
2381     return false;
2382   }
2383 
2384   return true;
2385 }
2386 
GetValidateDisplayOutput(uint32_t * out_num_types,uint32_t * out_num_requests)2387 HWC2::Error HWCDisplay::GetValidateDisplayOutput(uint32_t *out_num_types,
2388                                                  uint32_t *out_num_requests) {
2389   *out_num_types = UINT32(layer_changes_.size());
2390   *out_num_requests = UINT32(layer_requests_.size());
2391 
2392   return ((*out_num_types > 0) ? HWC2::Error::HasChanges : HWC2::Error::None);
2393 }
2394 
GetDisplayIdentificationData(uint8_t * out_port,uint32_t * out_data_size,uint8_t * out_data)2395 HWC2::Error HWCDisplay::GetDisplayIdentificationData(uint8_t *out_port, uint32_t *out_data_size,
2396                                                      uint8_t *out_data) {
2397   DisplayError ret = display_intf_->GetDisplayIdentificationData(out_port, out_data_size, out_data);
2398   if (ret != kErrorNone) {
2399     DLOGE("Failed due to SDM/Driver (err = %d, disp id = %" PRIu64
2400           " %d-%d", ret, id_, sdm_id_, type_);
2401   }
2402 
2403   return HWC2::Error::None;
2404 }
2405 
SetDisplayElapseTime(uint64_t time)2406 HWC2::Error HWCDisplay::SetDisplayElapseTime(uint64_t time) {
2407   elapse_timestamp_ = time;
2408   return HWC2::Error::None;
2409 }
2410 
IsDisplayCommandMode()2411 bool HWCDisplay::IsDisplayCommandMode() {
2412   return is_cmd_mode_;
2413 }
2414 
SetDisplayedContentSamplingEnabledVndService(bool enabled)2415 HWC2::Error HWCDisplay::SetDisplayedContentSamplingEnabledVndService(bool enabled) {
2416   return HWC2::Error::Unsupported;
2417 }
2418 
SetDisplayedContentSamplingEnabled(int32_t enabled,uint8_t component_mask,uint64_t max_frames)2419 HWC2::Error HWCDisplay::SetDisplayedContentSamplingEnabled(int32_t enabled, uint8_t component_mask,
2420                                                            uint64_t max_frames) {
2421   DLOGV("Request to start/stop histogram thread not supported on this display");
2422   return HWC2::Error::Unsupported;
2423 }
2424 
GetDisplayedContentSamplingAttributes(int32_t * format,int32_t * dataspace,uint8_t * supported_components)2425 HWC2::Error HWCDisplay::GetDisplayedContentSamplingAttributes(int32_t *format, int32_t *dataspace,
2426                                                               uint8_t *supported_components) {
2427   return HWC2::Error::Unsupported;
2428 }
2429 
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])2430 HWC2::Error HWCDisplay::GetDisplayedContentSample(
2431     uint64_t max_frames, uint64_t timestamp, uint64_t *numFrames,
2432     int32_t samples_size[NUM_HISTOGRAM_COLOR_COMPONENTS],
2433     uint64_t *samples[NUM_HISTOGRAM_COLOR_COMPONENTS]) {
2434   return HWC2::Error::Unsupported;
2435 }
2436 
2437 // Skip SDM prepare if all the layers in the current draw cycle are marked as Skip and
2438 // previous draw cycle had GPU Composition, as the resources for GPU Target layer have
2439 // already been validated and configured to the driver.
CanSkipSdmPrepare(uint32_t * num_types,uint32_t * num_requests)2440 bool HWCDisplay::CanSkipSdmPrepare(uint32_t *num_types, uint32_t *num_requests) {
2441   if (!validated_ || layer_set_.empty()) {
2442     return false;
2443   }
2444 
2445   bool skip_prepare = true;
2446   for (auto hwc_layer : layer_set_) {
2447     if (!hwc_layer->GetSDMLayer()->flags.skip ||
2448         (hwc_layer->GetDeviceSelectedCompositionType() != HWC2::Composition::Client)) {
2449       skip_prepare = false;
2450       layer_changes_.clear();
2451       break;
2452     }
2453     if (hwc_layer->GetClientRequestedCompositionType() != HWC2::Composition::Client) {
2454       layer_changes_[hwc_layer->GetId()] = HWC2::Composition::Client;
2455     }
2456   }
2457 
2458   if (skip_prepare) {
2459     *num_types = UINT32(layer_changes_.size());
2460     *num_requests = 0;
2461     layer_stack_invalid_ = false;
2462     has_client_composition_ = true;
2463     client_target_->ResetValidation();
2464     validate_state_ = kNormalValidate;
2465   }
2466 
2467   return skip_prepare;
2468 }
2469 
UpdateRefreshRate()2470 void HWCDisplay::UpdateRefreshRate() {
2471   for (auto hwc_layer : layer_set_) {
2472     if (hwc_layer->HasMetaDataRefreshRate()) {
2473       continue;
2474     }
2475     auto layer = hwc_layer->GetSDMLayer();
2476     layer->frame_rate = std::min(current_refresh_rate_, HWCDisplay::GetThrottlingRefreshRate());
2477   }
2478 }
2479 
SetClientTargetDataSpace(int32_t dataspace)2480 int32_t HWCDisplay::SetClientTargetDataSpace(int32_t dataspace) {
2481   if (client_target_->GetLayerDataspace() != dataspace) {
2482     client_target_->SetLayerDataspace(dataspace);
2483     Layer *sdm_layer = client_target_->GetSDMLayer();
2484     // Data space would be validated at GetClientTargetSupport, so just use here.
2485     sdm::GetSDMColorSpace(client_target_->GetLayerDataspace(),
2486                           &sdm_layer->input_buffer.color_metadata);
2487   }
2488 
2489   return 0;
2490 }
2491 
WaitOnPreviousFence()2492 void HWCDisplay::WaitOnPreviousFence() {
2493   DisplayConfigFixedInfo display_config;
2494   display_intf_->GetConfig(&display_config);
2495   if (!display_config.is_cmdmode) {
2496     return;
2497   }
2498 
2499   // Since prepare failed commit would follow the same.
2500   // Wait for previous rel fence.
2501   for (auto hwc_layer : layer_set_) {
2502     shared_ptr<Fence> fence = nullptr;
2503 
2504     hwc_layer->PopBackReleaseFence(&fence);
2505     if (Fence::Wait(fence) != kErrorNone) {
2506       DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
2507       return;
2508     }
2509     hwc_layer->PushBackReleaseFence(fence);
2510   }
2511 
2512   if (Fence::Wait(fbt_release_fence_) != kErrorNone) {
2513     DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
2514     return;
2515   }
2516 }
2517 
GetLayerStack(HWCLayerStack * stack)2518 void HWCDisplay::GetLayerStack(HWCLayerStack *stack) {
2519   stack->client_target = client_target_;
2520   stack->layer_map = layer_map_;
2521   stack->layer_set = layer_set_;
2522 }
2523 
SetLayerStack(HWCLayerStack * stack)2524 void HWCDisplay::SetLayerStack(HWCLayerStack *stack) {
2525   client_target_ = stack->client_target;
2526   layer_map_ = stack->layer_map;
2527   layer_set_ = stack->layer_set;
2528 }
2529 
CheckResourceState()2530 bool HWCDisplay::CheckResourceState() {
2531   if (display_intf_) {
2532     return display_intf_->CheckResourceState();
2533   }
2534 
2535   return false;
2536 }
2537 
UpdateActiveConfig()2538 void HWCDisplay::UpdateActiveConfig() {
2539   if (!pending_config_) {
2540     return;
2541   }
2542 
2543   DisplayError error = display_intf_->SetActiveConfig(pending_config_index_);
2544   if (error != kErrorNone) {
2545     DLOGI("Failed to set %d config", INT(pending_config_index_));
2546   }
2547 
2548   // Reset pending config.
2549   pending_config_ = false;
2550 }
2551 
GetDisplayConfigGroup(DisplayConfigGroupInfo variable_config)2552 int32_t HWCDisplay::GetDisplayConfigGroup(DisplayConfigGroupInfo variable_config) {
2553   for (auto &config : variable_config_map_) {
2554     DisplayConfigGroupInfo const &group_info = config.second;
2555     if (group_info == variable_config) {
2556       return INT32(config.first);
2557     }
2558   }
2559 
2560   return -1;
2561 }
2562 
GetDisplayVsyncPeriod(VsyncPeriodNanos * vsync_period)2563 HWC2::Error HWCDisplay::GetDisplayVsyncPeriod(VsyncPeriodNanos *vsync_period) {
2564   if (GetTransientVsyncPeriod(vsync_period)) {
2565     return HWC2::Error::None;
2566   }
2567 
2568   return GetVsyncPeriodByActiveConfig(vsync_period);
2569 }
2570 
SetActiveConfigWithConstraints(hwc2_config_t config,const VsyncPeriodChangeConstraints * vsync_period_change_constraints,VsyncPeriodChangeTimeline * out_timeline)2571 HWC2::Error HWCDisplay::SetActiveConfigWithConstraints(
2572     hwc2_config_t config, const VsyncPeriodChangeConstraints *vsync_period_change_constraints,
2573     VsyncPeriodChangeTimeline *out_timeline) {
2574   if (variable_config_map_.find(config) == variable_config_map_.end()) {
2575     DLOGE("Invalid config: %d", config);
2576     return HWC2::Error::BadConfig;
2577   }
2578 
2579   if (vsync_period_change_constraints->seamlessRequired && !AllowSeamless(config)) {
2580     DLOGE("Seamless switch to the config: %d, is not allowed!", config);
2581     return HWC2::Error::SeamlessNotAllowed;
2582   }
2583 
2584   VsyncPeriodNanos vsync_period;
2585   if (GetDisplayVsyncPeriod(&vsync_period) != HWC2::Error::None) {
2586     return HWC2::Error::BadConfig;
2587   }
2588 
2589   std::tie(out_timeline->refreshTimeNanos, out_timeline->newVsyncAppliedTimeNanos) =
2590       RequestActiveConfigChange(config, vsync_period,
2591                                 vsync_period_change_constraints->desiredTimeNanos);
2592 
2593   out_timeline->refreshRequired = true;
2594   return HWC2::Error::None;
2595 }
2596 
ProcessActiveConfigChange()2597 void HWCDisplay::ProcessActiveConfigChange() {
2598   if (!IsActiveConfigReadyToSubmit(systemTime(SYSTEM_TIME_MONOTONIC))) {
2599     return;
2600   }
2601 
2602   DTRACE_SCOPED();
2603   VsyncPeriodNanos vsync_period;
2604   if (GetVsyncPeriodByActiveConfig(&vsync_period) == HWC2::Error::None) {
2605     SubmitActiveConfigChange(vsync_period);
2606   }
2607 }
2608 
GetVsyncPeriodByActiveConfig(VsyncPeriodNanos * vsync_period)2609 HWC2::Error HWCDisplay::GetVsyncPeriodByActiveConfig(VsyncPeriodNanos *vsync_period) {
2610   hwc2_config_t active_config;
2611 
2612   auto error = GetActiveConfig(&active_config);
2613   if (error != HWC2::Error::None) {
2614     DLOGE("Failed to get active config!");
2615     return error;
2616   }
2617 
2618   int32_t active_vsync_period;
2619   error = GetDisplayAttribute(active_config, HwcAttribute::VSYNC_PERIOD, &active_vsync_period);
2620   if (error != HWC2::Error::None) {
2621     DLOGE("Failed to get VsyncPeriod of config: %d", active_config);
2622     return error;
2623   }
2624 
2625   *vsync_period = static_cast<VsyncPeriodNanos>(active_vsync_period);
2626   return HWC2::Error::None;
2627 }
2628 
GetTransientVsyncPeriod(VsyncPeriodNanos * vsync_period)2629 bool HWCDisplay::GetTransientVsyncPeriod(VsyncPeriodNanos *vsync_period) {
2630   std::lock_guard<std::mutex> lock(transient_refresh_rate_lock_);
2631   auto now = systemTime(SYSTEM_TIME_MONOTONIC);
2632 
2633   while (!transient_refresh_rate_info_.empty()) {
2634     if (IsActiveConfigApplied(now, transient_refresh_rate_info_.front().vsync_applied_time)) {
2635       transient_refresh_rate_info_.pop_front();
2636     } else {
2637       *vsync_period = transient_refresh_rate_info_.front().transient_vsync_period;
2638       return true;
2639     }
2640   }
2641 
2642   return false;
2643 }
2644 
RequestActiveConfigChange(hwc2_config_t config,VsyncPeriodNanos current_vsync_period,int64_t desired_time)2645 std::tuple<int64_t, int64_t> HWCDisplay::RequestActiveConfigChange(
2646     hwc2_config_t config, VsyncPeriodNanos current_vsync_period, int64_t desired_time) {
2647   int64_t refresh_time, applied_time;
2648   std::tie(refresh_time, applied_time) =
2649       EstimateVsyncPeriodChangeTimeline(current_vsync_period, desired_time);
2650 
2651   pending_refresh_rate_config_ = config;
2652   pending_refresh_rate_refresh_time_ = refresh_time;
2653   pending_refresh_rate_applied_time_ = applied_time;
2654 
2655   return std::make_tuple(refresh_time, applied_time);
2656 }
2657 
EstimateVsyncPeriodChangeTimeline(VsyncPeriodNanos current_vsync_period,int64_t desired_time)2658 std::tuple<int64_t, int64_t> HWCDisplay::EstimateVsyncPeriodChangeTimeline(
2659     VsyncPeriodNanos current_vsync_period, int64_t desired_time) {
2660   const auto now = systemTime(SYSTEM_TIME_MONOTONIC);
2661   const auto delta = desired_time - now;
2662   const auto refresh_rate_activate_period = current_vsync_period * vsyncs_to_apply_rate_change_;
2663   nsecs_t refresh_time;
2664 
2665   if (delta < 0) {
2666     refresh_time = now + (delta % current_vsync_period);
2667   } else if (delta < refresh_rate_activate_period) {
2668     refresh_time = now + (delta % current_vsync_period) - current_vsync_period;
2669   } else {
2670     refresh_time = desired_time - refresh_rate_activate_period;
2671   }
2672 
2673   const auto applied_time = refresh_time + refresh_rate_activate_period;
2674   return std::make_tuple(refresh_time, applied_time);
2675 }
2676 
SubmitActiveConfigChange(VsyncPeriodNanos current_vsync_period)2677 void HWCDisplay::SubmitActiveConfigChange(VsyncPeriodNanos current_vsync_period) {
2678   HWC2::Error error = SubmitDisplayConfig(pending_refresh_rate_config_);
2679   if (error != HWC2::Error::None) {
2680     return;
2681   }
2682 
2683   std::lock_guard<std::mutex> lock(transient_refresh_rate_lock_);
2684   hwc_vsync_period_change_timeline_t timeline;
2685   std::tie(timeline.refreshTimeNanos, timeline.newVsyncAppliedTimeNanos) =
2686       EstimateVsyncPeriodChangeTimeline(current_vsync_period, pending_refresh_rate_refresh_time_);
2687 
2688   transient_refresh_rate_info_.push_back({current_vsync_period, timeline.newVsyncAppliedTimeNanos});
2689   if (timeline.newVsyncAppliedTimeNanos != pending_refresh_rate_applied_time_) {
2690     timeline.refreshRequired = false;
2691     callbacks_->VsyncPeriodTimingChanged(id_, &timeline);
2692   }
2693 
2694   pending_refresh_rate_config_ = UINT_MAX;
2695   pending_refresh_rate_refresh_time_ = INT64_MAX;
2696   pending_refresh_rate_applied_time_ = INT64_MAX;
2697 }
2698 
IsActiveConfigReadyToSubmit(int64_t time)2699 bool HWCDisplay::IsActiveConfigReadyToSubmit(int64_t time) {
2700   return ((pending_refresh_rate_config_ != UINT_MAX) &&
2701           IsTimeAfterOrEqualVsyncTime(time, pending_refresh_rate_refresh_time_));
2702 }
2703 
IsActiveConfigApplied(int64_t time,int64_t vsync_applied_time)2704 bool HWCDisplay::IsActiveConfigApplied(int64_t time, int64_t vsync_applied_time) {
2705   return IsTimeAfterOrEqualVsyncTime(time, vsync_applied_time);
2706 }
2707 
IsSameGroup(hwc2_config_t config_id1,hwc2_config_t config_id2)2708 bool HWCDisplay::IsSameGroup(hwc2_config_t config_id1, hwc2_config_t config_id2) {
2709   const auto &variable_config1 = variable_config_map_.find(config_id1);
2710   const auto &variable_config2 = variable_config_map_.find(config_id2);
2711 
2712   if ((variable_config1 == variable_config_map_.end()) ||
2713       (variable_config2 == variable_config_map_.end())) {
2714     DLOGE("Invalid config: %u, %u", config_id1, config_id2);
2715     return false;
2716   }
2717 
2718   const DisplayConfigGroupInfo &config_group1 = variable_config1->second;
2719   const DisplayConfigGroupInfo &config_group2 = variable_config2->second;
2720 
2721   return (config_group1 == config_group2);
2722 }
2723 
AllowSeamless(hwc2_config_t config)2724 bool HWCDisplay::AllowSeamless(hwc2_config_t config) {
2725   hwc2_config_t active_config;
2726   auto error = GetActiveConfig(&active_config);
2727   if (error != HWC2::Error::None) {
2728     DLOGE("Failed to get active config!");
2729     return false;
2730   }
2731 
2732   return IsSameGroup(active_config, config);
2733 }
2734 
SubmitDisplayConfig(hwc2_config_t config)2735 HWC2::Error HWCDisplay::SubmitDisplayConfig(hwc2_config_t config) {
2736   DTRACE_SCOPED();
2737 
2738   hwc2_config_t current_config = 0;
2739   GetActiveConfig(&current_config);
2740   if (current_config == config) {
2741     return HWC2::Error::None;
2742   }
2743 
2744   DisplayError error = display_intf_->SetActiveConfig(config);
2745   if (error != kErrorNone) {
2746     DLOGE("Failed to set %d config! Error: %d", config, error);
2747     return HWC2::Error::BadConfig;
2748   }
2749 
2750   validated_ = false;
2751 
2752   return HWC2::Error::None;
2753 }
2754 
GetSupportedContentTypes(hidl_vec<HwcContentType> * types)2755 HWC2::Error HWCDisplay::GetSupportedContentTypes(hidl_vec<HwcContentType> *types) {
2756   types = {};
2757 
2758   return HWC2::Error::None;
2759 }
2760 
SetContentType(HwcContentType type)2761 HWC2::Error HWCDisplay::SetContentType(HwcContentType type) {
2762   if (type == HwcContentType::NONE) {
2763     return HWC2::Error::None;
2764   }
2765 
2766   return HWC2::Error::Unsupported;
2767 }
2768 
2769 }  // namespace sdm
2770