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