1 /*
2  * Copyright (c) 2014-2018, 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/formats.h>
29 #include <utils/rect.h>
30 #include <qd_utils.h>
31 
32 #include <algorithm>
33 #include <iomanip>
34 #include <map>
35 #include <sstream>
36 #include <string>
37 #include <utility>
38 #include <vector>
39 
40 #include "hwc_display.h"
41 #include "hwc_debugger.h"
42 #include "blit_engine_c2d.h"
43 #include "hwc_tonemapper.h"
44 
45 #ifndef USE_GRALLOC1
46 #include <gr.h>
47 #endif
48 
49 #ifdef QTI_BSP
50 #include <hardware/display_defs.h>
51 #endif
52 
53 #define __CLASS__ "HWCDisplay"
54 
55 namespace sdm {
56 
57 std::bitset<kDisplayMax> HWCDisplay::validated_ = 0;
58 
59 // This weight function is needed because the color primaries are not sorted by gamut size
WidestPrimaries(ColorPrimaries p1,ColorPrimaries p2)60 static ColorPrimaries WidestPrimaries(ColorPrimaries p1, ColorPrimaries p2) {
61   int weight = 10;
62   int lp1 = p1, lp2 = p2;
63   // TODO(user) add weight to other wide gamut primaries
64   if (lp1 == ColorPrimaries_BT2020) {
65     lp1 *= weight;
66   }
67   if (lp1 == ColorPrimaries_BT2020) {
68     lp2 *= weight;
69   }
70   if (lp1 >= lp2) {
71     return p1;
72   } else {
73     return p2;
74   }
75 }
76 
HWCColorMode(DisplayInterface * display_intf)77 HWCColorMode::HWCColorMode(DisplayInterface *display_intf) : display_intf_(display_intf) {}
78 
Init()79 HWC2::Error HWCColorMode::Init() {
80   PopulateColorModes();
81   return ApplyDefaultColorMode();
82 }
83 
DeInit()84 HWC2::Error HWCColorMode::DeInit() {
85   color_mode_transform_map_.clear();
86   return HWC2::Error::None;
87 }
88 
GetColorModeCount()89 uint32_t HWCColorMode::GetColorModeCount() {
90   uint32_t count = UINT32(color_mode_transform_map_.size());
91   DLOGI("Supported color mode count = %d", count);
92 #ifdef EXCLUDE_DISPLAY_PP
93   return count;
94 #else
95   return std::max(1U, count);
96 #endif
97 }
98 
GetColorModes(uint32_t * out_num_modes,android_color_mode_t * out_modes)99 HWC2::Error HWCColorMode::GetColorModes(uint32_t *out_num_modes,
100                                         android_color_mode_t *out_modes) {
101   auto it = color_mode_transform_map_.begin();
102   for (auto i = 0; it != color_mode_transform_map_.end(); it++, i++) {
103     out_modes[i] = it->first;
104     DLOGI("Supports color mode[%d] = %d", i, it->first);
105   }
106   *out_num_modes = UINT32(color_mode_transform_map_.size());
107   return HWC2::Error::None;
108 }
109 
SetColorMode(android_color_mode_t mode)110 HWC2::Error HWCColorMode::SetColorMode(android_color_mode_t mode) {
111   // first mode in 2D matrix is the mode (identity)
112   if (mode < HAL_COLOR_MODE_NATIVE || mode > HAL_COLOR_MODE_DISPLAY_P3) {
113     DLOGE("Could not find mode: %d", mode);
114     return HWC2::Error::BadParameter;
115   }
116   if (color_mode_transform_map_.find(mode) == color_mode_transform_map_.end()) {
117     return HWC2::Error::Unsupported;
118   }
119 
120   auto status = HandleColorModeTransform(mode, current_color_transform_, color_matrix_);
121   if (status != HWC2::Error::None) {
122     DLOGE("failed for mode = %d", mode);
123   }
124 
125   return status;
126 }
127 
SetColorTransform(const float * matrix,android_color_transform_t hint)128 HWC2::Error HWCColorMode::SetColorTransform(const float *matrix, android_color_transform_t hint) {
129   if (!matrix || (hint < HAL_COLOR_TRANSFORM_IDENTITY ||
130       hint > HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA)) {
131     return HWC2::Error::BadParameter;
132   }
133 
134   double color_matrix[kColorTransformMatrixCount] = {0};
135   CopyColorTransformMatrix(matrix, color_matrix);
136 
137   auto status = HandleColorModeTransform(current_color_mode_, hint, color_matrix);
138   if (status != HWC2::Error::None) {
139     DLOGE("failed for hint = %d", hint);
140   }
141 
142   return status;
143 }
144 
HandleColorModeTransform(android_color_mode_t mode,android_color_transform_t hint,const double * matrix)145 HWC2::Error HWCColorMode::HandleColorModeTransform(android_color_mode_t mode,
146                                                    android_color_transform_t hint,
147                                                    const double *matrix) {
148   android_color_transform_t transform_hint = hint;
149   std::string color_mode_transform;
150   bool use_matrix = false;
151   if (hint != HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX) {
152     // if the mode + transfrom request from HWC matches one mode in SDM, set that
153     if (color_mode_transform.empty()) {
154       transform_hint = HAL_COLOR_TRANSFORM_IDENTITY;
155       use_matrix = true;
156     } else {
157       color_mode_transform = color_mode_transform_map_[mode][hint];
158     }
159   } else {
160     use_matrix = true;
161     transform_hint = HAL_COLOR_TRANSFORM_IDENTITY;
162   }
163 
164   // if the mode count is 1, then only native mode is supported, so just apply matrix w/o
165   // setting mode
166   if (color_mode_transform_map_.size() > 1U && current_color_mode_ != mode) {
167     color_mode_transform = color_mode_transform_map_[mode][transform_hint];
168     DisplayError error = display_intf_->SetColorMode(color_mode_transform);
169     if (error != kErrorNone) {
170       DLOGE("Failed to set color_mode  = %d transform_hint = %d", mode, hint);
171       // failure to force client composition
172       return HWC2::Error::Unsupported;
173     }
174     DLOGI("Setting Color Mode = %d Transform Hint = %d Success", mode, hint);
175   }
176 
177   if (use_matrix) {
178     DisplayError error = display_intf_->SetColorTransform(kColorTransformMatrixCount, matrix);
179     if (error != kErrorNone) {
180       DLOGE("Failed to set Color Transform Matrix");
181       // failure to force client composition
182       return HWC2::Error::Unsupported;
183     }
184   }
185 
186   current_color_mode_ = mode;
187   current_color_transform_ = hint;
188   CopyColorTransformMatrix(matrix, color_matrix_);
189 
190   return HWC2::Error::None;
191 }
192 
PopulateColorModes()193 void HWCColorMode::PopulateColorModes() {
194   uint32_t color_mode_count = 0;
195   // SDM returns modes which is string combination of mode + transform.
196   DisplayError error = display_intf_->GetColorModeCount(&color_mode_count);
197   if (error != kErrorNone || (color_mode_count == 0)) {
198 #ifndef EXCLUDE_DISPLAY_PP
199     DLOGW("GetColorModeCount failed, use native color mode");
200     PopulateTransform(HAL_COLOR_MODE_NATIVE, "native", "identity");
201 #endif
202     return;
203   }
204 
205   DLOGV_IF(kTagQDCM, "Color Modes supported count = %d", color_mode_count);
206 
207   const std::string color_transform = "identity";
208   std::vector<std::string> color_modes(color_mode_count);
209   error = display_intf_->GetColorModes(&color_mode_count, &color_modes);
210   for (uint32_t i = 0; i < color_mode_count; i++) {
211     std::string &mode_string = color_modes.at(i);
212     DLOGV_IF(kTagQDCM, "Color Mode[%d] = %s", i, mode_string.c_str());
213     AttrVal attr;
214     error = display_intf_->GetColorModeAttr(mode_string, &attr);
215     std::string color_gamut, dynamic_range, pic_quality;
216     if (!attr.empty()) {
217       for (auto &it : attr) {
218         if (it.first.find(kColorGamutAttribute) != std::string::npos) {
219           color_gamut = it.second;
220         } else if (it.first.find(kDynamicRangeAttribute) != std::string::npos) {
221           dynamic_range = it.second;
222         } else if (it.first.find(kPictureQualityAttribute) != std::string::npos) {
223           pic_quality = it.second;
224         }
225       }
226       if (dynamic_range == kHdr) {
227         continue;
228       }
229       if ((color_gamut == kNative) &&
230           (pic_quality.empty() || pic_quality == kStandard)) {
231         PopulateTransform(HAL_COLOR_MODE_NATIVE, mode_string, color_transform);
232       } else if ((color_gamut == kSrgb) &&
233                  (pic_quality.empty() || pic_quality == kStandard)) {
234         PopulateTransform(HAL_COLOR_MODE_SRGB, mode_string, color_transform);
235       } else if ((color_gamut == kDcip3) &&
236                  (pic_quality.empty() || pic_quality == kStandard)) {
237         PopulateTransform(HAL_COLOR_MODE_DISPLAY_P3, mode_string, color_transform);
238       } else if ((color_gamut == kDisplayP3) &&
239                  (pic_quality.empty() || pic_quality == kStandard)) {
240         PopulateTransform(HAL_COLOR_MODE_DISPLAY_P3, mode_string, color_transform);
241       }
242     }
243 
244     // Look at the mode name, if no color gamut is found
245     if (color_gamut.empty()) {
246       if (mode_string.find("hal_native") != std::string::npos) {
247         PopulateTransform(HAL_COLOR_MODE_NATIVE, mode_string, mode_string);
248       } else if (mode_string.find("hal_srgb") != std::string::npos) {
249         PopulateTransform(HAL_COLOR_MODE_SRGB, mode_string, mode_string);
250       } else if (mode_string.find("hal_adobe") != std::string::npos) {
251         PopulateTransform(HAL_COLOR_MODE_ADOBE_RGB, mode_string, mode_string);
252       } else if (mode_string.find("hal_dci_p3") != std::string::npos) {
253         PopulateTransform(HAL_COLOR_MODE_DCI_P3, mode_string, mode_string);
254       } else if (mode_string.find("hal_display_p3") != std::string::npos) {
255         PopulateTransform(HAL_COLOR_MODE_DISPLAY_P3, mode_string, mode_string);
256       }
257     }
258   }
259 }
260 
PopulateTransform(const android_color_mode_t & mode,const std::string & color_mode,const std::string & color_transform)261 void HWCColorMode::PopulateTransform(const android_color_mode_t &mode,
262                                      const std::string &color_mode,
263                                      const std::string &color_transform) {
264   // TODO(user): Check the substring from QDCM
265   if (color_transform.find("identity") != std::string::npos) {
266     color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_IDENTITY] = color_mode;
267   } else if (color_transform.find("arbitrary") != std::string::npos) {
268     // no color mode for arbitrary
269   } else if (color_transform.find("inverse") != std::string::npos) {
270     color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_VALUE_INVERSE] = color_mode;
271   } else if (color_transform.find("grayscale") != std::string::npos) {
272     color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_GRAYSCALE] = color_mode;
273   } else if (color_transform.find("correct_protonopia") != std::string::npos) {
274     color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_CORRECT_PROTANOPIA] = color_mode;
275   } else if (color_transform.find("correct_deuteranopia") != std::string::npos) {
276     color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_CORRECT_DEUTERANOPIA] = color_mode;
277   } else if (color_transform.find("correct_tritanopia") != std::string::npos) {
278     color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA] = color_mode;
279   } else {
280     color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_IDENTITY] = color_mode;
281   }
282 }
283 
ApplyDefaultColorMode()284 HWC2::Error HWCColorMode::ApplyDefaultColorMode() {
285   android_color_mode_t color_mode = HAL_COLOR_MODE_NATIVE;
286   if (color_mode_transform_map_.size() == 1U) {
287     color_mode = color_mode_transform_map_.begin()->first;
288   } else if (color_mode_transform_map_.size() > 1U) {
289     std::string default_color_mode;
290     bool found = false;
291     DisplayError error = display_intf_->GetDefaultColorMode(&default_color_mode);
292     if (error == kErrorNone) {
293       // get the default mode corresponding android_color_mode_t
294       for (auto &it_mode : color_mode_transform_map_) {
295         for (auto &it : it_mode.second) {
296           if (it.second == default_color_mode) {
297             found = true;
298             break;
299           }
300         }
301         if (found) {
302           color_mode = it_mode.first;
303           break;
304         }
305       }
306     }
307 
308     // return the first andrid_color_mode_t when we encouter if not found
309     if (!found) {
310       color_mode = color_mode_transform_map_.begin()->first;
311     }
312   }
313   return SetColorMode(color_mode);
314 }
315 
Dump(std::ostringstream * os)316 void HWCColorMode::Dump(std::ostringstream* os) {
317   *os << "color modes supported: ";
318   for (auto it : color_mode_transform_map_) {
319     *os << it.first <<" ";
320   }
321   *os << "current mode: " << current_color_mode_ << std::endl;
322   *os << "current transform: ";
323   for (uint32_t i = 0; i < kColorTransformMatrixCount; i++) {
324     if (i % 4 == 0) {
325      *os << std::endl;
326     }
327     *os << std::fixed << std::setprecision(2) << std::setw(6) << std::setfill(' ')
328         << color_matrix_[i] << " ";
329   }
330   *os << std::endl;
331 }
332 
HWCDisplay(CoreInterface * core_intf,HWCCallbacks * callbacks,DisplayType type,hwc2_display_t id,bool needs_blit,qService::QService * qservice,DisplayClass display_class,BufferAllocator * buffer_allocator)333 HWCDisplay::HWCDisplay(CoreInterface *core_intf, HWCCallbacks *callbacks, DisplayType type,
334                        hwc2_display_t id, bool needs_blit, qService::QService *qservice,
335                        DisplayClass display_class, BufferAllocator *buffer_allocator)
336     : core_intf_(core_intf),
337       callbacks_(callbacks),
338       type_(type),
339       id_(id),
340       needs_blit_(needs_blit),
341       qservice_(qservice),
342       display_class_(display_class) {
343   buffer_allocator_ = static_cast<HWCBufferAllocator *>(buffer_allocator);
344 }
345 
Init()346 int HWCDisplay::Init() {
347   DisplayError error = core_intf_->CreateDisplay(type_, this, &display_intf_);
348   if (error != kErrorNone) {
349     DLOGE("Display create failed. Error = %d display_type %d event_handler %p disp_intf %p", error,
350           type_, this, &display_intf_);
351     return -EINVAL;
352   }
353 
354   validated_.reset();
355   HWCDebugHandler::Get()->GetProperty("sys.hwc_disable_hdr", &disable_hdr_handling_);
356   if (disable_hdr_handling_) {
357     DLOGI("HDR Handling disabled");
358   }
359 
360   int property_swap_interval = 1;
361   HWCDebugHandler::Get()->GetProperty("debug.egl.swapinterval", &property_swap_interval);
362   if (property_swap_interval == 0) {
363     swap_interval_zero_ = true;
364   }
365 
366   client_target_ = new HWCLayer(id_, buffer_allocator_);
367 
368   int blit_enabled = 0;
369   HWCDebugHandler::Get()->GetProperty("persist.hwc.blit.comp", &blit_enabled);
370   if (needs_blit_ && blit_enabled) {
371     // TODO(user): Add blit engine when needed
372   }
373 
374   error = display_intf_->GetNumVariableInfoConfigs(&num_configs_);
375   if (error != kErrorNone) {
376     DLOGE("Getting config count failed. Error = %d", error);
377     return -EINVAL;
378   }
379 
380   tone_mapper_ = new HWCToneMapper(buffer_allocator_);
381 
382   display_intf_->GetRefreshRateRange(&min_refresh_rate_, &max_refresh_rate_);
383   current_refresh_rate_ = max_refresh_rate_;
384 
385   GetUnderScanConfig();
386   DLOGI("Display created with id: %d", id_);
387 
388   return 0;
389 }
390 
Deinit()391 int HWCDisplay::Deinit() {
392   DisplayError error = core_intf_->DestroyDisplay(display_intf_);
393   if (error != kErrorNone) {
394     DLOGE("Display destroy failed. Error = %d", error);
395     return -EINVAL;
396   }
397 
398   delete client_target_;
399 
400   if (color_mode_) {
401     color_mode_->DeInit();
402     delete color_mode_;
403   }
404 
405   delete tone_mapper_;
406   tone_mapper_ = nullptr;
407 
408   return 0;
409 }
410 
411 // LayerStack operations
CreateLayer(hwc2_layer_t * out_layer_id)412 HWC2::Error HWCDisplay::CreateLayer(hwc2_layer_t *out_layer_id) {
413   HWCLayer *layer = *layer_set_.emplace(new HWCLayer(id_, buffer_allocator_));
414   layer_map_.emplace(std::make_pair(layer->GetId(), layer));
415   *out_layer_id = layer->GetId();
416   geometry_changes_ |= GeometryChanges::kAdded;
417   validated_.reset();
418   return HWC2::Error::None;
419 }
420 
GetHWCLayer(hwc2_layer_t layer_id)421 HWCLayer *HWCDisplay::GetHWCLayer(hwc2_layer_t layer_id) {
422   const auto map_layer = layer_map_.find(layer_id);
423   if (map_layer == layer_map_.end()) {
424     DLOGE("[%" PRIu64 "] GetLayer(%" PRIu64 ") failed: no such layer", id_, layer_id);
425     return nullptr;
426   } else {
427     return map_layer->second;
428   }
429 }
430 
DestroyLayer(hwc2_layer_t layer_id)431 HWC2::Error HWCDisplay::DestroyLayer(hwc2_layer_t layer_id) {
432   const auto map_layer = layer_map_.find(layer_id);
433   if (map_layer == layer_map_.end()) {
434     DLOGE("[%" PRIu64 "] destroyLayer(%" PRIu64 ") failed: no such layer", id_, layer_id);
435     return HWC2::Error::BadLayer;
436   }
437   const auto layer = map_layer->second;
438   layer_map_.erase(map_layer);
439   const auto z_range = layer_set_.equal_range(layer);
440   for (auto current = z_range.first; current != z_range.second; ++current) {
441     if (*current == layer) {
442       current = layer_set_.erase(current);
443       delete layer;
444       break;
445     }
446   }
447 
448   geometry_changes_ |= GeometryChanges::kRemoved;
449   validated_.reset();
450   return HWC2::Error::None;
451 }
452 
453 
BuildLayerStack()454 void HWCDisplay::BuildLayerStack() {
455   layer_stack_ = LayerStack();
456   display_rect_ = LayerRect();
457   metadata_refresh_rate_ = 0;
458   auto working_primaries = ColorPrimaries_BT709_5;
459 
460   uint32_t color_mode_count = 0;
461   display_intf_->GetColorModeCount(&color_mode_count);
462 
463   // Add one layer for fb target
464   // TODO(user): Add blit target layers
465   for (auto hwc_layer : layer_set_) {
466     Layer *layer = hwc_layer->GetSDMLayer();
467     layer->flags = {};   // Reset earlier flags
468     if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::Client) {
469       layer->flags.skip = true;
470     } else if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::SolidColor) {
471       layer->flags.solid_fill = true;
472     }
473 
474 #ifdef FEATURE_WIDE_COLOR
475     if (!hwc_layer->SupportedDataspace()) {
476         layer->flags.skip = true;
477         DLOGW_IF(kTagStrategy, "Unsupported dataspace: 0x%x", hwc_layer->GetLayerDataspace());
478     }
479 #endif
480 
481     working_primaries = WidestPrimaries(working_primaries,
482                                         layer->input_buffer.color_metadata.colorPrimaries);
483 
484     // set default composition as GPU for SDM
485     layer->composition = kCompositionGPU;
486 
487     if (swap_interval_zero_) {
488       if (layer->input_buffer.acquire_fence_fd >= 0) {
489         close(layer->input_buffer.acquire_fence_fd);
490         layer->input_buffer.acquire_fence_fd = -1;
491       }
492     }
493 
494     const private_handle_t *handle =
495         reinterpret_cast<const private_handle_t *>(layer->input_buffer.buffer_id);
496     if (handle) {
497 #ifdef USE_GRALLOC1
498       if (handle->buffer_type == BUFFER_TYPE_VIDEO) {
499 #else
500       if (handle->bufferType == BUFFER_TYPE_VIDEO) {
501 #endif
502         layer_stack_.flags.video_present = true;
503       }
504       // TZ Protected Buffer - L1
505       if (handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
506         layer_stack_.flags.secure_present = true;
507       }
508       // Gralloc Usage Protected Buffer - L3 - which needs to be treated as Secure & avoid fallback
509       if (handle->flags & private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER) {
510         layer_stack_.flags.secure_present = true;
511       }
512     }
513 
514     if (layer->flags.skip) {
515       layer_stack_.flags.skip_present = true;
516     }
517 
518     if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::Cursor) {
519       // Currently we support only one HWCursor & only at top most z-order
520       if ((*layer_set_.rbegin())->GetId() == hwc_layer->GetId()) {
521         layer->flags.cursor = true;
522         layer_stack_.flags.cursor_present = true;
523       }
524     }
525 
526     bool hdr_layer = layer->input_buffer.color_metadata.colorPrimaries == ColorPrimaries_BT2020 &&
527                      (layer->input_buffer.color_metadata.transfer == Transfer_SMPTE_ST2084 ||
528                      layer->input_buffer.color_metadata.transfer == Transfer_HLG);
529     if (hdr_layer && !disable_hdr_handling_ && color_mode_count) {
530       // dont honor HDR when its handling is disabled
531       layer->input_buffer.flags.hdr = true;
532       layer_stack_.flags.hdr_present = true;
533     }
534 
535     // TODO(user): Move to a getter if this is needed at other places
536     hwc_rect_t scaled_display_frame = {INT(layer->dst_rect.left), INT(layer->dst_rect.top),
537                                        INT(layer->dst_rect.right), INT(layer->dst_rect.bottom)};
538     ApplyScanAdjustment(&scaled_display_frame);
539     hwc_layer->SetLayerDisplayFrame(scaled_display_frame);
540     // SDM requires these details even for solid fill
541     if (layer->flags.solid_fill) {
542       LayerBuffer *layer_buffer = &layer->input_buffer;
543       layer_buffer->width = UINT32(layer->dst_rect.right - layer->dst_rect.left);
544       layer_buffer->height = UINT32(layer->dst_rect.bottom - layer->dst_rect.top);
545       layer_buffer->unaligned_width = layer_buffer->width;
546       layer_buffer->unaligned_height = layer_buffer->height;
547       layer_buffer->acquire_fence_fd = -1;
548       layer_buffer->release_fence_fd = -1;
549       layer->src_rect.left = 0;
550       layer->src_rect.top = 0;
551       layer->src_rect.right = layer_buffer->width;
552       layer->src_rect.bottom = layer_buffer->height;
553     }
554 
555     if (layer->frame_rate > metadata_refresh_rate_) {
556       metadata_refresh_rate_ = SanitizeRefreshRate(layer->frame_rate);
557     } else {
558       layer->frame_rate = current_refresh_rate_;
559     }
560     display_rect_ = Union(display_rect_, layer->dst_rect);
561     geometry_changes_ |= hwc_layer->GetGeometryChanges();
562 
563     layer->flags.updating = true;
564     if (layer_set_.size() <= kMaxLayerCount) {
565       layer->flags.updating = IsLayerUpdating(layer);
566     }
567 
568     layer_stack_.layers.push_back(layer);
569   }
570 
571 
572 #ifdef FEATURE_WIDE_COLOR
573   for (auto hwc_layer : layer_set_) {
574     auto layer = hwc_layer->GetSDMLayer();
575     if (layer->input_buffer.color_metadata.colorPrimaries != working_primaries &&
576         !hwc_layer->SupportLocalConversion(working_primaries)) {
577       layer->flags.skip = true;
578     }
579     if (layer->flags.skip) {
580       layer_stack_.flags.skip_present = true;
581     }
582   }
583 #endif
584 
585   // TODO(user): Set correctly when SDM supports geometry_changes as bitmask
586   layer_stack_.flags.geometry_changed = UINT32(geometry_changes_ > 0);
587   // Append client target to the layer stack
588   layer_stack_.layers.push_back(client_target_->GetSDMLayer());
589 }
590 
591 void HWCDisplay::BuildSolidFillStack() {
592   layer_stack_ = LayerStack();
593   display_rect_ = LayerRect();
594 
595   layer_stack_.layers.push_back(solid_fill_layer_);
596   layer_stack_.flags.geometry_changed = 1U;
597   // Append client target to the layer stack
598   layer_stack_.layers.push_back(client_target_->GetSDMLayer());
599 }
600 
601 HWC2::Error HWCDisplay::SetLayerZOrder(hwc2_layer_t layer_id, uint32_t z) {
602   const auto map_layer = layer_map_.find(layer_id);
603   if (map_layer == layer_map_.end()) {
604     DLOGE("[%" PRIu64 "] updateLayerZ failed to find layer", id_);
605     return HWC2::Error::BadLayer;
606   }
607 
608   const auto layer = map_layer->second;
609   const auto z_range = layer_set_.equal_range(layer);
610   bool layer_on_display = false;
611   for (auto current = z_range.first; current != z_range.second; ++current) {
612     if (*current == layer) {
613       if ((*current)->GetZ() == z) {
614         // Don't change anything if the Z hasn't changed
615         return HWC2::Error::None;
616       }
617       current = layer_set_.erase(current);
618       layer_on_display = true;
619       break;
620     }
621   }
622 
623   if (!layer_on_display) {
624     DLOGE("[%" PRIu64 "] updateLayerZ failed to find layer on display", id_);
625     return HWC2::Error::BadLayer;
626   }
627 
628   layer->SetLayerZOrder(z);
629   layer_set_.emplace(layer);
630   return HWC2::Error::None;
631 }
632 
633 HWC2::Error HWCDisplay::SetVsyncEnabled(HWC2::Vsync enabled) {
634   DLOGV("Display ID: %d enabled: %s", id_, to_string(enabled).c_str());
635   DisplayError error = kErrorNone;
636 
637   if (shutdown_pending_ || !callbacks_->VsyncCallbackRegistered()) {
638     return HWC2::Error::None;
639   }
640 
641   bool state;
642   if (enabled == HWC2::Vsync::Enable)
643     state = true;
644   else if (enabled == HWC2::Vsync::Disable)
645     state = false;
646   else
647     return HWC2::Error::BadParameter;
648 
649   error = display_intf_->SetVSyncState(state);
650 
651   if (error != kErrorNone) {
652     if (error == kErrorShutDown) {
653       shutdown_pending_ = true;
654       return HWC2::Error::None;
655     }
656     DLOGE("Failed. enabled = %s, error = %d", to_string(enabled).c_str(), error);
657     return HWC2::Error::BadDisplay;
658   }
659 
660   return HWC2::Error::None;
661 }
662 
663 HWC2::Error HWCDisplay::SetPowerMode(HWC2::PowerMode mode) {
664   DLOGV("display = %d, mode = %s", id_, to_string(mode).c_str());
665   DisplayState state = kStateOff;
666   bool flush_on_error = flush_on_error_;
667 
668   if (shutdown_pending_) {
669     return HWC2::Error::None;
670   }
671 
672   switch (mode) {
673     case HWC2::PowerMode::Off:
674       // During power off, all of the buffers are released.
675       // Do not flush until a buffer is successfully submitted again.
676       flush_on_error = false;
677       state = kStateOff;
678       if (tone_mapper_) {
679         tone_mapper_->Terminate();
680       }
681       break;
682     case HWC2::PowerMode::On:
683       state = kStateOn;
684       last_power_mode_ = HWC2::PowerMode::On;
685       break;
686     case HWC2::PowerMode::Doze:
687       state = kStateDoze;
688       last_power_mode_ = HWC2::PowerMode::Doze;
689       break;
690     case HWC2::PowerMode::DozeSuspend:
691       state = kStateDozeSuspend;
692       last_power_mode_ = HWC2::PowerMode::DozeSuspend;
693       break;
694     default:
695       return HWC2::Error::BadParameter;
696   }
697 
698   DisplayError error = display_intf_->SetDisplayState(state);
699   validated_.reset();
700 
701   if (error == kErrorNone) {
702     flush_on_error_ = flush_on_error;
703   } else {
704     if (error == kErrorShutDown) {
705       shutdown_pending_ = true;
706       return HWC2::Error::None;
707     }
708     DLOGE("Set state failed. Error = %d", error);
709     return HWC2::Error::BadParameter;
710   }
711 
712   return HWC2::Error::None;
713 }
714 
715 HWC2::Error HWCDisplay::GetClientTargetSupport(uint32_t width, uint32_t height, int32_t format,
716                                                int32_t dataspace) {
717   DisplayConfigVariableInfo variable_config;
718   display_intf_->GetFrameBufferConfig(&variable_config);
719   // TODO(user): Support scaled configurations, other formats and other dataspaces
720   if (format != HAL_PIXEL_FORMAT_RGBA_8888 || dataspace != HAL_DATASPACE_UNKNOWN ||
721       width != variable_config.x_pixels || height != variable_config.y_pixels) {
722     return HWC2::Error::Unsupported;
723   } else {
724     return HWC2::Error::None;
725   }
726 }
727 
728 HWC2::Error HWCDisplay::GetColorModes(uint32_t *out_num_modes, android_color_mode_t *out_modes) {
729   if (out_modes) {
730     out_modes[0] = HAL_COLOR_MODE_NATIVE;
731   }
732   *out_num_modes = 1;
733 
734   return HWC2::Error::None;
735 }
736 
737 HWC2::Error HWCDisplay::GetDisplayConfigs(uint32_t *out_num_configs, hwc2_config_t *out_configs) {
738   if (out_configs == nullptr) {
739     *out_num_configs = num_configs_;
740     return HWC2::Error::None;
741   }
742 
743   *out_num_configs = num_configs_;
744 
745   for (uint32_t i = 0; i < num_configs_; i++) {
746     out_configs[i] = i;
747   }
748 
749   return HWC2::Error::None;
750 }
751 
752 HWC2::Error HWCDisplay::GetDisplayAttribute(hwc2_config_t config, HWC2::Attribute attribute,
753                                             int32_t *out_value) {
754   DisplayConfigVariableInfo variable_config;
755   if (GetDisplayAttributesForConfig(INT(config), &variable_config) != kErrorNone) {
756     DLOGE("Get variable config failed");
757     return HWC2::Error::BadDisplay;
758   }
759 
760   switch (attribute) {
761     case HWC2::Attribute::VsyncPeriod:
762       *out_value = INT32(variable_config.vsync_period_ns);
763       break;
764     case HWC2::Attribute::Width:
765       *out_value = INT32(variable_config.x_pixels);
766       break;
767     case HWC2::Attribute::Height:
768       *out_value = INT32(variable_config.y_pixels);
769       break;
770     case HWC2::Attribute::DpiX:
771       *out_value = INT32(variable_config.x_dpi * 1000.0f);
772       break;
773     case HWC2::Attribute::DpiY:
774       *out_value = INT32(variable_config.y_dpi * 1000.0f);
775       break;
776     default:
777       DLOGW("Spurious attribute type = %s", to_string(attribute).c_str());
778       *out_value = -1;
779       return HWC2::Error::BadConfig;
780   }
781 
782   return HWC2::Error::None;
783 }
784 
785 HWC2::Error HWCDisplay::GetDisplayName(uint32_t *out_size, char *out_name) {
786   // TODO(user): Get panel name and EDID name and populate it here
787   if (out_name == nullptr) {
788     *out_size = 32;
789   } else {
790     std::string name;
791     switch (id_) {
792       case HWC_DISPLAY_PRIMARY:
793         name = "Primary Display";
794         break;
795       case HWC_DISPLAY_EXTERNAL:
796         name = "External Display";
797         break;
798       case HWC_DISPLAY_VIRTUAL:
799         name = "Virtual Display";
800         break;
801       default:
802         name = "Unknown";
803         break;
804     }
805     std::strncpy(out_name, name.c_str(), name.size());
806     *out_size = UINT32(name.size());
807   }
808   return HWC2::Error::None;
809 }
810 
811 HWC2::Error HWCDisplay::GetDisplayType(int32_t *out_type) {
812   if (out_type != nullptr) {
813     if (id_ == HWC_DISPLAY_VIRTUAL) {
814       *out_type = HWC2_DISPLAY_TYPE_VIRTUAL;
815     } else {
816       *out_type = HWC2_DISPLAY_TYPE_PHYSICAL;
817     }
818     return HWC2::Error::None;
819   } else {
820     return HWC2::Error::BadParameter;
821   }
822 }
823 
824 HWC2::Error HWCDisplay::GetActiveConfig(hwc2_config_t *out_config) {
825   if (out_config == nullptr) {
826     return HWC2::Error::BadDisplay;
827   }
828 
829   uint32_t active_index = 0;
830   if (GetActiveDisplayConfig(&active_index) != kErrorNone) {
831     return HWC2::Error::BadConfig;
832   }
833 
834   *out_config = active_index;
835 
836   return HWC2::Error::None;
837 }
838 
839 HWC2::Error HWCDisplay::SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
840                                         int32_t dataspace, hwc_region_t damage) {
841   // TODO(user): SurfaceFlinger gives us a null pointer here when doing full SDE composition
842   // The error is problematic for layer caching as it would overwrite our cached client target.
843   // Reported bug 28569722 to resolve this.
844   // For now, continue to use the last valid buffer reported to us for layer caching.
845   if (target == nullptr) {
846     return HWC2::Error::None;
847   }
848 
849   if (acquire_fence == 0) {
850     DLOGE("acquire_fence is zero");
851     return HWC2::Error::BadParameter;
852   }
853 
854   client_target_->SetLayerBuffer(target, acquire_fence);
855   client_target_->SetLayerSurfaceDamage(damage);
856   // Ignoring dataspace for now
857   return HWC2::Error::None;
858 }
859 
860 HWC2::Error HWCDisplay::SetActiveConfig(hwc2_config_t config) {
861   if (SetActiveDisplayConfig(config) != kErrorNone) {
862     return HWC2::Error::BadConfig;
863   }
864 
865   validated_.reset();
866   return HWC2::Error::None;
867 }
868 
869 DisplayError HWCDisplay::SetMixerResolution(uint32_t width, uint32_t height) {
870   return kErrorNotSupported;
871 }
872 
873 void HWCDisplay::SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type) {
874   dump_frame_count_ = count;
875   dump_frame_index_ = 0;
876   dump_input_layers_ = ((bit_mask_layer_type & (1 << INPUT_LAYER_DUMP)) != 0);
877 
878   if (tone_mapper_) {
879     tone_mapper_->SetFrameDumpConfig(count);
880   }
881 
882   DLOGI("num_frame_dump %d, input_layer_dump_enable %d", dump_frame_count_, dump_input_layers_);
883   validated_.reset();
884 }
885 
886 HWC2::PowerMode HWCDisplay::GetLastPowerMode() {
887   return last_power_mode_;
888 }
889 
890 DisplayError HWCDisplay::VSync(const DisplayEventVSync &vsync) {
891   callbacks_->Vsync(id_, vsync.timestamp);
892   return kErrorNone;
893 }
894 
895 DisplayError HWCDisplay::Refresh() {
896   return kErrorNotSupported;
897 }
898 
899 DisplayError HWCDisplay::CECMessage(char *message) {
900   if (qservice_) {
901     qservice_->onCECMessageReceived(message, 0);
902   } else {
903     DLOGW("Qservice instance not available.");
904   }
905 
906   return kErrorNone;
907 }
908 
909 DisplayError HWCDisplay::HandleEvent(DisplayEvent event) {
910   switch (event) {
911     case kIdleTimeout:
912     case kThermalEvent:
913       validated_.reset();
914       break;
915     default:
916       DLOGW("Unknown event: %d", event);
917       break;
918   }
919 
920   return kErrorNone;
921 }
922 
923 HWC2::Error HWCDisplay::PrepareLayerStack(uint32_t *out_num_types, uint32_t *out_num_requests) {
924   layer_changes_.clear();
925   layer_requests_.clear();
926   if (shutdown_pending_) {
927     return HWC2::Error::BadDisplay;
928   }
929 
930   if (!skip_prepare_) {
931     DisplayError error = display_intf_->Prepare(&layer_stack_);
932     if (error != kErrorNone) {
933       if (error == kErrorShutDown) {
934         shutdown_pending_ = true;
935       } else if (error != kErrorPermission) {
936         DLOGE("Prepare failed. Error = %d", error);
937         // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
938         // so that previous buffer and fences are released, and override the error.
939         flush_ = true;
940       }
941       return HWC2::Error::BadDisplay;
942     } else {
943       validated_.set(type_);
944     }
945   } else {
946     // Skip is not set
947     MarkLayersForGPUBypass();
948     skip_prepare_ = false;
949     DLOGI("SecureDisplay %s, Skip Prepare/Commit and Flush",
950           secure_display_active_ ? "Starting" : "Stopping");
951     flush_ = true;
952   }
953 
954   for (auto hwc_layer : layer_set_) {
955     Layer *layer = hwc_layer->GetSDMLayer();
956     LayerComposition &composition = layer->composition;
957 
958     if ((composition == kCompositionSDE) || (composition == kCompositionHybrid) ||
959         (composition == kCompositionBlit)) {
960       layer_requests_[hwc_layer->GetId()] = HWC2::LayerRequest::ClearClientTarget;
961     }
962 
963     HWC2::Composition requested_composition = hwc_layer->GetClientRequestedCompositionType();
964     // Set SDM composition to HWC2 type in HWCLayer
965     hwc_layer->SetComposition(composition);
966     HWC2::Composition device_composition  = hwc_layer->GetDeviceSelectedCompositionType();
967     // Update the changes list only if the requested composition is different from SDM comp type
968     // TODO(user): Take Care of other comptypes(BLIT)
969     if (requested_composition != device_composition) {
970       layer_changes_[hwc_layer->GetId()] = device_composition;
971     }
972     hwc_layer->ResetValidation();
973   }
974   *out_num_types = UINT32(layer_changes_.size());
975   *out_num_requests = UINT32(layer_requests_.size());
976   skip_validate_ = false;
977   if (*out_num_types > 0) {
978     return HWC2::Error::HasChanges;
979   } else {
980     return HWC2::Error::None;
981   }
982 }
983 
984 HWC2::Error HWCDisplay::AcceptDisplayChanges() {
985   if (layer_set_.empty()) {
986     return HWC2::Error::None;
987   }
988 
989   if (!validated_.test(type_)) {
990     return HWC2::Error::NotValidated;
991   }
992 
993   for (const auto& change : layer_changes_) {
994     auto hwc_layer = layer_map_[change.first];
995     auto composition = change.second;
996     if (hwc_layer != nullptr) {
997       hwc_layer->UpdateClientCompositionType(composition);
998     } else {
999       DLOGW("Invalid layer: %" PRIu64, change.first);
1000     }
1001   }
1002   return HWC2::Error::None;
1003 }
1004 
1005 HWC2::Error HWCDisplay::GetChangedCompositionTypes(uint32_t *out_num_elements,
1006                                                    hwc2_layer_t *out_layers, int32_t *out_types) {
1007   if (layer_set_.empty()) {
1008     return HWC2::Error::None;
1009   }
1010 
1011   if (!validated_.test(type_)) {
1012     DLOGW("Display is not validated");
1013     return HWC2::Error::NotValidated;
1014   }
1015 
1016   *out_num_elements = UINT32(layer_changes_.size());
1017   if (out_layers != nullptr && out_types != nullptr) {
1018     int i = 0;
1019     for (auto change : layer_changes_) {
1020       out_layers[i] = change.first;
1021       out_types[i] = INT32(change.second);
1022       i++;
1023     }
1024   }
1025   return HWC2::Error::None;
1026 }
1027 
1028 HWC2::Error HWCDisplay::GetReleaseFences(uint32_t *out_num_elements, hwc2_layer_t *out_layers,
1029                                          int32_t *out_fences) {
1030   if (out_layers != nullptr && out_fences != nullptr) {
1031     int i = 0;
1032     for (auto hwc_layer : layer_set_) {
1033       out_layers[i] = hwc_layer->GetId();
1034       out_fences[i] = hwc_layer->PopReleaseFence();
1035       i++;
1036     }
1037   }
1038   *out_num_elements = UINT32(layer_set_.size());
1039   return HWC2::Error::None;
1040 }
1041 
1042 HWC2::Error HWCDisplay::GetDisplayRequests(int32_t *out_display_requests,
1043                                            uint32_t *out_num_elements, hwc2_layer_t *out_layers,
1044                                            int32_t *out_layer_requests) {
1045   if (layer_set_.empty()) {
1046     return HWC2::Error::None;
1047   }
1048 
1049   // No display requests for now
1050   // Use for sharing blit buffers and
1051   // writing wfd buffer directly to output if there is full GPU composition
1052   // and no color conversion needed
1053   if (!validated_.test(type_)) {
1054     DLOGW("Display is not validated");
1055     return HWC2::Error::NotValidated;
1056   }
1057 
1058   *out_display_requests = 0;
1059   *out_num_elements = UINT32(layer_requests_.size());
1060   if (out_layers != nullptr && out_layer_requests != nullptr) {
1061     int i = 0;
1062     for (auto &request : layer_requests_) {
1063       out_layers[i] = request.first;
1064       out_layer_requests[i] = INT32(request.second);
1065       i++;
1066     }
1067   }
1068 
1069   auto client_target_layer = client_target_->GetSDMLayer();
1070   if (client_target_layer->request.flags.flip_buffer) {
1071     *out_display_requests = INT32(HWC2::DisplayRequest::FlipClientTarget);
1072   }
1073 
1074   return HWC2::Error::None;
1075 }
1076 
1077 HWC2::Error HWCDisplay::GetHdrCapabilities(uint32_t *out_num_types, int32_t *out_types,
1078                                            float *out_max_luminance,
1079                                            float *out_max_average_luminance,
1080                                            float *out_min_luminance) {
1081   DisplayConfigFixedInfo fixed_info = {};
1082   display_intf_->GetConfig(&fixed_info);
1083 
1084   if (!fixed_info.hdr_supported) {
1085     *out_num_types = 0;
1086     DLOGI("HDR is not supported");
1087     return HWC2::Error::None;
1088   }
1089 
1090   if (out_types == nullptr) {
1091     // 1(now) - because we support only HDR10, change when HLG & DOLBY vision are supported
1092     *out_num_types  = 1;
1093   } else {
1094     // Only HDR10 supported
1095     *out_types = HAL_HDR_HDR10;
1096     static const float kLuminanceFactor = 10000.0;
1097     // luminance is expressed in the unit of 0.0001 cd/m2, convert it to 1cd/m2.
1098     *out_max_luminance = FLOAT(fixed_info.max_luminance)/kLuminanceFactor;
1099     *out_max_average_luminance = FLOAT(fixed_info.average_luminance)/kLuminanceFactor;
1100     *out_min_luminance = FLOAT(fixed_info.min_luminance)/kLuminanceFactor;
1101   }
1102 
1103   return HWC2::Error::None;
1104 }
1105 
1106 
1107 HWC2::Error HWCDisplay::CommitLayerStack(void) {
1108   if (skip_validate_ && !CanSkipValidate()) {
1109     validated_.reset(type_);
1110   }
1111 
1112   if (!validated_.test(type_)) {
1113     DLOGV_IF(kTagCompManager, "Display %d is not validated", id_);
1114     return HWC2::Error::NotValidated;
1115   }
1116 
1117   if (shutdown_pending_ || layer_set_.empty()) {
1118     return HWC2::Error::None;
1119   }
1120 
1121   DumpInputBuffers();
1122 
1123   if (!flush_) {
1124     DisplayError error = kErrorUndefined;
1125     int status = 0;
1126     if (tone_mapper_) {
1127       if (layer_stack_.flags.hdr_present) {
1128         status = tone_mapper_->HandleToneMap(&layer_stack_);
1129         if (status != 0) {
1130           DLOGE("Error handling HDR in ToneMapper");
1131         }
1132       } else {
1133         tone_mapper_->Terminate();
1134       }
1135     }
1136     error = display_intf_->Commit(&layer_stack_);
1137 
1138     if (error == kErrorNone) {
1139       // A commit is successfully submitted, start flushing on failure now onwards.
1140       flush_on_error_ = true;
1141     } else {
1142       if (error == kErrorShutDown) {
1143         shutdown_pending_ = true;
1144         return HWC2::Error::Unsupported;
1145       } else if (error == kErrorNotValidated) {
1146         validated_.reset(type_);
1147         return HWC2::Error::NotValidated;
1148       } else if (error != kErrorPermission) {
1149         DLOGE("Commit failed. Error = %d", error);
1150         // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
1151         // so that previous buffer and fences are released, and override the error.
1152         flush_ = true;
1153       }
1154     }
1155   }
1156 
1157   skip_validate_ = true;
1158   return HWC2::Error::None;
1159 }
1160 
1161 HWC2::Error HWCDisplay::PostCommitLayerStack(int32_t *out_retire_fence) {
1162   auto status = HWC2::Error::None;
1163 
1164   // Do no call flush on errors, if a successful buffer is never submitted.
1165   if (flush_ && flush_on_error_) {
1166     display_intf_->Flush();
1167     validated_.reset();
1168   }
1169 
1170   if (tone_mapper_ && tone_mapper_->IsActive()) {
1171      tone_mapper_->PostCommit(&layer_stack_);
1172   }
1173 
1174   // TODO(user): No way to set the client target release fence on SF
1175   int32_t &client_target_release_fence =
1176       client_target_->GetSDMLayer()->input_buffer.release_fence_fd;
1177   if (client_target_release_fence >= 0) {
1178     close(client_target_release_fence);
1179     client_target_release_fence = -1;
1180   }
1181 
1182   for (auto hwc_layer : layer_set_) {
1183     hwc_layer->ResetGeometryChanges();
1184     Layer *layer = hwc_layer->GetSDMLayer();
1185     LayerBuffer *layer_buffer = &layer->input_buffer;
1186 
1187     if (!flush_) {
1188       // If swapinterval property is set to 0 or for single buffer layers, do not update f/w
1189       // release fences and discard fences from driver
1190       if (swap_interval_zero_ || layer->flags.single_buffer) {
1191         close(layer_buffer->release_fence_fd);
1192         layer_buffer->release_fence_fd = -1;
1193       } else if (layer->composition != kCompositionGPU) {
1194         hwc_layer->PushReleaseFence(layer_buffer->release_fence_fd);
1195         layer_buffer->release_fence_fd = -1;
1196       } else {
1197         hwc_layer->PushReleaseFence(-1);
1198       }
1199     }
1200 
1201     if (layer_buffer->acquire_fence_fd >= 0) {
1202       close(layer_buffer->acquire_fence_fd);
1203       layer_buffer->acquire_fence_fd = -1;
1204     }
1205     layer->request.flags = {};
1206   }
1207 
1208   client_target_->GetSDMLayer()->request.flags = {};
1209   *out_retire_fence = -1;
1210   if (!flush_) {
1211     // if swapinterval property is set to 0 then close and reset the list retire fence
1212     if (swap_interval_zero_) {
1213       close(layer_stack_.retire_fence_fd);
1214       layer_stack_.retire_fence_fd = -1;
1215     }
1216     *out_retire_fence = layer_stack_.retire_fence_fd;
1217     layer_stack_.retire_fence_fd = -1;
1218 
1219     if (dump_frame_count_) {
1220       dump_frame_count_--;
1221       dump_frame_index_++;
1222     }
1223   }
1224 
1225   geometry_changes_ = GeometryChanges::kNone;
1226   flush_ = false;
1227 
1228   return status;
1229 }
1230 
1231 void HWCDisplay::SetIdleTimeoutMs(uint32_t timeout_ms) {
1232   return;
1233 }
1234 
1235 DisplayError HWCDisplay::SetMaxMixerStages(uint32_t max_mixer_stages) {
1236   DisplayError error = kErrorNone;
1237 
1238   if (display_intf_) {
1239     error = display_intf_->SetMaxMixerStages(max_mixer_stages);
1240     validated_.reset();
1241   }
1242 
1243   return error;
1244 }
1245 
1246 LayerBufferFormat HWCDisplay::GetSDMFormat(const int32_t &source, const int flags) {
1247   LayerBufferFormat format = kFormatInvalid;
1248   if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
1249     switch (source) {
1250       case HAL_PIXEL_FORMAT_RGBA_8888:
1251         format = kFormatRGBA8888Ubwc;
1252         break;
1253       case HAL_PIXEL_FORMAT_RGBX_8888:
1254         format = kFormatRGBX8888Ubwc;
1255         break;
1256       case HAL_PIXEL_FORMAT_BGR_565:
1257         format = kFormatBGR565Ubwc;
1258         break;
1259       case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1260       case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1261       case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
1262         format = kFormatYCbCr420SPVenusUbwc;
1263         break;
1264       case HAL_PIXEL_FORMAT_RGBA_1010102:
1265         format = kFormatRGBA1010102Ubwc;
1266         break;
1267       case HAL_PIXEL_FORMAT_RGBX_1010102:
1268         format = kFormatRGBX1010102Ubwc;
1269         break;
1270       case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
1271         format = kFormatYCbCr420TP10Ubwc;
1272         break;
1273       case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
1274         format = kFormatYCbCr420P010Ubwc;
1275         break;
1276       default:
1277         DLOGE("Unsupported format type for UBWC %d", source);
1278         return kFormatInvalid;
1279     }
1280     return format;
1281   }
1282 
1283   switch (source) {
1284     case HAL_PIXEL_FORMAT_RGBA_8888:
1285       format = kFormatRGBA8888;
1286       break;
1287     case HAL_PIXEL_FORMAT_RGBA_5551:
1288       format = kFormatRGBA5551;
1289       break;
1290     case HAL_PIXEL_FORMAT_RGBA_4444:
1291       format = kFormatRGBA4444;
1292       break;
1293     case HAL_PIXEL_FORMAT_BGRA_8888:
1294       format = kFormatBGRA8888;
1295       break;
1296     case HAL_PIXEL_FORMAT_RGBX_8888:
1297       format = kFormatRGBX8888;
1298       break;
1299     case HAL_PIXEL_FORMAT_BGRX_8888:
1300       format = kFormatBGRX8888;
1301       break;
1302     case HAL_PIXEL_FORMAT_RGB_888:
1303       format = kFormatRGB888;
1304       break;
1305     case HAL_PIXEL_FORMAT_RGB_565:
1306       format = kFormatRGB565;
1307       break;
1308     case HAL_PIXEL_FORMAT_BGR_565:
1309       format = kFormatBGR565;
1310       break;
1311     case HAL_PIXEL_FORMAT_BGR_888:
1312       format = kFormatBGR888;
1313       break;
1314     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
1315     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1316       format = kFormatYCbCr420SemiPlanarVenus;
1317       break;
1318     case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
1319       format = kFormatYCrCb420SemiPlanarVenus;
1320       break;
1321     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1322       format = kFormatYCbCr420SPVenusUbwc;
1323       break;
1324     case HAL_PIXEL_FORMAT_YV12:
1325       format = kFormatYCrCb420PlanarStride16;
1326       break;
1327     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1328       format = kFormatYCrCb420SemiPlanar;
1329       break;
1330     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
1331       format = kFormatYCbCr420SemiPlanar;
1332       break;
1333     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
1334       format = kFormatYCbCr422H2V1SemiPlanar;
1335       break;
1336     case HAL_PIXEL_FORMAT_YCbCr_422_I:
1337       format = kFormatYCbCr422H2V1Packed;
1338       break;
1339     case HAL_PIXEL_FORMAT_CbYCrY_422_I:
1340       format = kFormatCbYCrY422H2V1Packed;
1341       break;
1342     case HAL_PIXEL_FORMAT_RGBA_1010102:
1343       format = kFormatRGBA1010102;
1344       break;
1345     case HAL_PIXEL_FORMAT_ARGB_2101010:
1346       format = kFormatARGB2101010;
1347       break;
1348     case HAL_PIXEL_FORMAT_RGBX_1010102:
1349       format = kFormatRGBX1010102;
1350       break;
1351     case HAL_PIXEL_FORMAT_XRGB_2101010:
1352       format = kFormatXRGB2101010;
1353       break;
1354     case HAL_PIXEL_FORMAT_BGRA_1010102:
1355       format = kFormatBGRA1010102;
1356       break;
1357     case HAL_PIXEL_FORMAT_ABGR_2101010:
1358       format = kFormatABGR2101010;
1359       break;
1360     case HAL_PIXEL_FORMAT_BGRX_1010102:
1361       format = kFormatBGRX1010102;
1362       break;
1363     case HAL_PIXEL_FORMAT_XBGR_2101010:
1364       format = kFormatXBGR2101010;
1365       break;
1366     case HAL_PIXEL_FORMAT_YCbCr_420_P010:
1367       format = kFormatYCbCr420P010;
1368       break;
1369     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
1370       format = kFormatYCbCr420TP10Ubwc;
1371       break;
1372     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
1373       format = kFormatYCbCr420P010Ubwc;
1374       break;
1375     default:
1376       DLOGW("Unsupported format type = %d", source);
1377       return kFormatInvalid;
1378   }
1379 
1380   return format;
1381 }
1382 
1383 void HWCDisplay::DumpInputBuffers() {
1384   char dir_path[PATH_MAX];
1385 
1386   if (!dump_frame_count_ || flush_ || !dump_input_layers_) {
1387     return;
1388   }
1389 
1390   snprintf(dir_path, sizeof(dir_path), "%s/frame_dump_%s", HWCDebugHandler::DumpDir(),
1391            GetDisplayString());
1392 
1393   if (mkdir(dir_path, 0777) != 0 && errno != EEXIST) {
1394     DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno));
1395     return;
1396   }
1397 
1398   // if directory exists already, need to explicitly change the permission.
1399   if (errno == EEXIST && chmod(dir_path, 0777) != 0) {
1400     DLOGW("Failed to change permissions on %s directory", dir_path);
1401     return;
1402   }
1403 
1404   for (uint32_t i = 0; i < layer_stack_.layers.size(); i++) {
1405     auto layer = layer_stack_.layers.at(i);
1406     const private_handle_t *pvt_handle =
1407         reinterpret_cast<const private_handle_t *>(layer->input_buffer.buffer_id);
1408     auto acquire_fence_fd = layer->input_buffer.acquire_fence_fd;
1409 
1410     if (acquire_fence_fd >= 0) {
1411       int error = sync_wait(acquire_fence_fd, 1000);
1412       if (error < 0) {
1413         DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
1414         return;
1415       }
1416     }
1417 
1418     if (pvt_handle && pvt_handle->base) {
1419       char dump_file_name[PATH_MAX];
1420       size_t result = 0;
1421 
1422       snprintf(dump_file_name, sizeof(dump_file_name), "%s/input_layer%d_%dx%d_%s_frame%d.raw",
1423                dir_path, i, pvt_handle->width, pvt_handle->height,
1424                qdutils::GetHALPixelFormatString(pvt_handle->format), dump_frame_index_);
1425 
1426       FILE *fp = fopen(dump_file_name, "w+");
1427       if (fp) {
1428         result = fwrite(reinterpret_cast<void *>(pvt_handle->base), pvt_handle->size, 1, fp);
1429         fclose(fp);
1430       }
1431 
1432       DLOGI("Frame Dump %s: is %s", dump_file_name, result ? "Successful" : "Failed");
1433     }
1434   }
1435 }
1436 
1437 void HWCDisplay::DumpOutputBuffer(const BufferInfo &buffer_info, void *base, int fence) {
1438   char dir_path[PATH_MAX];
1439 
1440   snprintf(dir_path, sizeof(dir_path), "%s/frame_dump_%s", HWCDebugHandler::DumpDir(),
1441            GetDisplayString());
1442 
1443   if (mkdir(dir_path, 777) != 0 && errno != EEXIST) {
1444     DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno));
1445     return;
1446   }
1447 
1448   // if directory exists already, need to explicitly change the permission.
1449   if (errno == EEXIST && chmod(dir_path, 0777) != 0) {
1450     DLOGW("Failed to change permissions on %s directory", dir_path);
1451     return;
1452   }
1453 
1454   if (base) {
1455     char dump_file_name[PATH_MAX];
1456     size_t result = 0;
1457 
1458     if (fence >= 0) {
1459       int error = sync_wait(fence, 1000);
1460       if (error < 0) {
1461         DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
1462         return;
1463       }
1464     }
1465 
1466     snprintf(dump_file_name, sizeof(dump_file_name), "%s/output_layer_%dx%d_%s_frame%d.raw",
1467              dir_path, buffer_info.buffer_config.width, buffer_info.buffer_config.height,
1468              GetFormatString(buffer_info.buffer_config.format), dump_frame_index_);
1469 
1470     FILE *fp = fopen(dump_file_name, "w+");
1471     if (fp) {
1472       result = fwrite(base, buffer_info.alloc_buffer_info.size, 1, fp);
1473       fclose(fp);
1474     }
1475 
1476     DLOGI("Frame Dump of %s is %s", dump_file_name, result ? "Successful" : "Failed");
1477   }
1478 }
1479 
1480 const char *HWCDisplay::GetDisplayString() {
1481   switch (type_) {
1482     case kPrimary:
1483       return "primary";
1484     case kHDMI:
1485       return "hdmi";
1486     case kVirtual:
1487       return "virtual";
1488     default:
1489       return "invalid";
1490   }
1491 }
1492 
1493 int HWCDisplay::SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels) {
1494   if (x_pixels <= 0 || y_pixels <= 0) {
1495     DLOGW("Unsupported config: x_pixels=%d, y_pixels=%d", x_pixels, y_pixels);
1496     return -EINVAL;
1497   }
1498 
1499   DisplayConfigVariableInfo fb_config;
1500   DisplayError error = display_intf_->GetFrameBufferConfig(&fb_config);
1501   if (error != kErrorNone) {
1502     DLOGV("Get frame buffer config failed. Error = %d", error);
1503     return -EINVAL;
1504   }
1505 
1506   fb_config.x_pixels = x_pixels;
1507   fb_config.y_pixels = y_pixels;
1508 
1509   error = display_intf_->SetFrameBufferConfig(fb_config);
1510   if (error != kErrorNone) {
1511     DLOGV("Set frame buffer config failed. Error = %d", error);
1512     return -EINVAL;
1513   }
1514 
1515   // Create rects to represent the new source and destination crops
1516   LayerRect crop = LayerRect(0, 0, FLOAT(x_pixels), FLOAT(y_pixels));
1517   LayerRect dst = LayerRect(0, 0, FLOAT(fb_config.x_pixels), FLOAT(fb_config.y_pixels));
1518   auto client_target_layer = client_target_->GetSDMLayer();
1519   client_target_layer->src_rect = crop;
1520   client_target_layer->dst_rect = dst;
1521 
1522   int aligned_width;
1523   int aligned_height;
1524   uint32_t usage = GRALLOC_USAGE_HW_FB;
1525   int format = HAL_PIXEL_FORMAT_RGBA_8888;
1526   int ubwc_disabled = 0;
1527   int flags = 0;
1528 
1529   // By default UBWC is enabled and below property is global enable/disable for all
1530   // buffers allocated through gralloc , including framebuffer targets.
1531   HWCDebugHandler::Get()->GetProperty("debug.gralloc.gfx_ubwc_disable", &ubwc_disabled);
1532   if (!ubwc_disabled) {
1533     usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
1534     flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
1535   }
1536 
1537 #ifdef USE_GRALLOC1
1538   buffer_allocator_->GetAlignedWidthAndHeight(INT(x_pixels), INT(y_pixels), format, usage,
1539                                               &aligned_width, &aligned_height);
1540 #else
1541   AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(INT(x_pixels), INT(y_pixels), format,
1542                                                         INT(usage), aligned_width, aligned_height);
1543 #endif
1544 
1545   // TODO(user): How does the dirty region get set on the client target? File bug on Google
1546   client_target_layer->composition = kCompositionGPUTarget;
1547   client_target_layer->input_buffer.format = GetSDMFormat(format, flags);
1548   client_target_layer->input_buffer.width = UINT32(aligned_width);
1549   client_target_layer->input_buffer.height = UINT32(aligned_height);
1550   client_target_layer->input_buffer.unaligned_width = x_pixels;
1551   client_target_layer->input_buffer.unaligned_height = y_pixels;
1552   client_target_layer->plane_alpha = 255;
1553 
1554   DLOGI("New framebuffer resolution (%dx%d)", fb_config.x_pixels, fb_config.y_pixels);
1555 
1556   return 0;
1557 }
1558 
1559 void HWCDisplay::GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
1560   DisplayConfigVariableInfo fb_config;
1561   display_intf_->GetFrameBufferConfig(&fb_config);
1562 
1563   *x_pixels = fb_config.x_pixels;
1564   *y_pixels = fb_config.y_pixels;
1565 }
1566 
1567 DisplayError HWCDisplay::GetMixerResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
1568   return display_intf_->GetMixerResolution(x_pixels, y_pixels);
1569 }
1570 
1571 void HWCDisplay::GetPanelResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
1572   DisplayConfigVariableInfo display_config;
1573   uint32_t active_index = 0;
1574 
1575   display_intf_->GetActiveConfig(&active_index);
1576   display_intf_->GetConfig(active_index, &display_config);
1577 
1578   *x_pixels = display_config.x_pixels;
1579   *y_pixels = display_config.y_pixels;
1580 }
1581 
1582 int HWCDisplay::SetDisplayStatus(DisplayStatus display_status) {
1583   int status = 0;
1584 
1585   switch (display_status) {
1586     case kDisplayStatusResume:
1587       display_paused_ = false;
1588     case kDisplayStatusOnline:
1589       status = INT32(SetPowerMode(HWC2::PowerMode::On));
1590       break;
1591     case kDisplayStatusPause:
1592       display_paused_ = true;
1593     case kDisplayStatusOffline:
1594       status = INT32(SetPowerMode(HWC2::PowerMode::Off));
1595       break;
1596     default:
1597       DLOGW("Invalid display status %d", display_status);
1598       return -EINVAL;
1599   }
1600 
1601   if (display_status == kDisplayStatusResume || display_status == kDisplayStatusPause) {
1602     callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
1603     validated_.reset();
1604   }
1605 
1606   return status;
1607 }
1608 
1609 HWC2::Error HWCDisplay::SetCursorPosition(hwc2_layer_t layer, int x, int y) {
1610   if (shutdown_pending_) {
1611     return HWC2::Error::None;
1612   }
1613 
1614   HWCLayer *hwc_layer = GetHWCLayer(layer);
1615   if (hwc_layer == nullptr) {
1616     return HWC2::Error::BadLayer;
1617   }
1618   if (hwc_layer->GetDeviceSelectedCompositionType() != HWC2::Composition::Cursor) {
1619     return HWC2::Error::None;
1620   }
1621   if (!skip_validate_ && validated_.test(type_)) {
1622     // the device is currently in the middle of the validate/present sequence,
1623     // cannot set the Position(as per HWC2 spec)
1624     return HWC2::Error::NotValidated;
1625   }
1626 
1627   DisplayState state;
1628   if (display_intf_->GetDisplayState(&state) == kErrorNone) {
1629     if (state != kStateOn) {
1630       return HWC2::Error::None;
1631     }
1632   }
1633 
1634   // TODO(user): HWC1.5 was not letting SetCursorPosition before validateDisplay,
1635   // but HWC2.0 doesn't let setting cursor position after validate before present.
1636   // Need to revisit.
1637 
1638   auto error = display_intf_->SetCursorPosition(x, y);
1639   if (error != kErrorNone) {
1640     if (error == kErrorShutDown) {
1641       shutdown_pending_ = true;
1642       return HWC2::Error::None;
1643     }
1644 
1645     DLOGE("Failed for x = %d y = %d, Error = %d", x, y, error);
1646     return HWC2::Error::BadDisplay;
1647   }
1648 
1649   return HWC2::Error::None;
1650 }
1651 
1652 int HWCDisplay::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) {
1653   DisplayError error = display_intf_->OnMinHdcpEncryptionLevelChange(min_enc_level);
1654   if (error != kErrorNone) {
1655     DLOGE("Failed. Error = %d", error);
1656     return -1;
1657   }
1658 
1659   validated_.reset();
1660   return 0;
1661 }
1662 
1663 void HWCDisplay::MarkLayersForGPUBypass() {
1664   for (auto hwc_layer : layer_set_) {
1665     auto layer = hwc_layer->GetSDMLayer();
1666     layer->composition = kCompositionSDE;
1667   }
1668   validated_.set(type_);
1669 }
1670 
1671 void HWCDisplay::MarkLayersForClientComposition() {
1672   // ClientComposition - GPU comp, to acheive this, set skip flag so that
1673   // SDM does not handle this layer and hwc_layer composition will be
1674   // set correctly at the end of Prepare.
1675   for (auto hwc_layer : layer_set_) {
1676     Layer *layer = hwc_layer->GetSDMLayer();
1677     layer->flags.skip = true;
1678   }
1679 }
1680 
1681 void HWCDisplay::ApplyScanAdjustment(hwc_rect_t *display_frame) {
1682 }
1683 
1684 int HWCDisplay::SetPanelBrightness(int level) {
1685   int ret = 0;
1686   if (display_intf_) {
1687     ret = display_intf_->SetPanelBrightness(level);
1688     validated_.reset();
1689   } else {
1690     ret = -EINVAL;
1691   }
1692 
1693   return ret;
1694 }
1695 
1696 int HWCDisplay::GetPanelBrightness(int *level) {
1697   return display_intf_->GetPanelBrightness(level);
1698 }
1699 
1700 int HWCDisplay::ToggleScreenUpdates(bool enable) {
1701   display_paused_ = enable ? false : true;
1702   callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
1703   validated_.reset();
1704   return 0;
1705 }
1706 
1707 int HWCDisplay::ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
1708                                      PPDisplayAPIPayload *out_payload,
1709                                      PPPendingParams *pending_action) {
1710   int ret = 0;
1711 
1712   if (display_intf_)
1713     ret = display_intf_->ColorSVCRequestRoute(in_payload, out_payload, pending_action);
1714   else
1715     ret = -EINVAL;
1716 
1717   return ret;
1718 }
1719 
1720 void HWCDisplay::SolidFillPrepare() {
1721   if (solid_fill_enable_) {
1722     if (solid_fill_layer_ == NULL) {
1723       // Create a dummy layer here
1724       solid_fill_layer_ = new Layer();
1725     }
1726     uint32_t primary_width = 0, primary_height = 0;
1727     GetMixerResolution(&primary_width, &primary_height);
1728 
1729     LayerBuffer *layer_buffer = &solid_fill_layer_->input_buffer;
1730     layer_buffer->width = primary_width;
1731     layer_buffer->height = primary_height;
1732     layer_buffer->unaligned_width = primary_width;
1733     layer_buffer->unaligned_height = primary_height;
1734     layer_buffer->acquire_fence_fd = -1;
1735     layer_buffer->release_fence_fd = -1;
1736 
1737     LayerRect rect;
1738     rect.top = 0; rect.left = 0;
1739     rect.right = primary_width;
1740     rect.bottom = primary_height;
1741 
1742     solid_fill_layer_->composition = kCompositionGPU;
1743     solid_fill_layer_->src_rect = rect;
1744     solid_fill_layer_->dst_rect = rect;
1745 
1746     solid_fill_layer_->blending = kBlendingPremultiplied;
1747     solid_fill_layer_->solid_fill_color = solid_fill_color_;
1748     solid_fill_layer_->frame_rate = 60;
1749     solid_fill_layer_->visible_regions.push_back(solid_fill_layer_->dst_rect);
1750     solid_fill_layer_->flags.updating = 1;
1751     solid_fill_layer_->flags.solid_fill = true;
1752   } else {
1753     // delete the dummy layer
1754     delete solid_fill_layer_;
1755     solid_fill_layer_ = NULL;
1756   }
1757 
1758   if (solid_fill_enable_ && solid_fill_layer_) {
1759     BuildSolidFillStack();
1760     MarkLayersForGPUBypass();
1761   }
1762 
1763   return;
1764 }
1765 
1766 void HWCDisplay::SolidFillCommit() {
1767   if (solid_fill_enable_ && solid_fill_layer_) {
1768     LayerBuffer *layer_buffer = &solid_fill_layer_->input_buffer;
1769     if (layer_buffer->release_fence_fd > 0) {
1770       close(layer_buffer->release_fence_fd);
1771       layer_buffer->release_fence_fd = -1;
1772     }
1773     if (layer_stack_.retire_fence_fd > 0) {
1774       close(layer_stack_.retire_fence_fd);
1775       layer_stack_.retire_fence_fd = -1;
1776     }
1777   }
1778 }
1779 
1780 int HWCDisplay::GetVisibleDisplayRect(hwc_rect_t *visible_rect) {
1781   if (!IsValid(display_rect_)) {
1782     return -EINVAL;
1783   }
1784 
1785   visible_rect->left = INT(display_rect_.left);
1786   visible_rect->top = INT(display_rect_.top);
1787   visible_rect->right = INT(display_rect_.right);
1788   visible_rect->bottom = INT(display_rect_.bottom);
1789   DLOGI("Dpy = %d Visible Display Rect(%d %d %d %d)", visible_rect->left, visible_rect->top,
1790         visible_rect->right, visible_rect->bottom);
1791 
1792   return 0;
1793 }
1794 
1795 void HWCDisplay::SetSecureDisplay(bool secure_display_active) {
1796   secure_display_active_ = secure_display_active;
1797   return;
1798 }
1799 
1800 int HWCDisplay::SetActiveDisplayConfig(uint32_t config) {
1801   int status = (display_intf_->SetActiveConfig(config) == kErrorNone) ? 0 : -1;
1802   validated_.reset();
1803   return status;
1804 }
1805 
1806 int HWCDisplay::GetActiveDisplayConfig(uint32_t *config) {
1807   return display_intf_->GetActiveConfig(config) == kErrorNone ? 0 : -1;
1808 }
1809 
1810 int HWCDisplay::GetDisplayConfigCount(uint32_t *count) {
1811   return display_intf_->GetNumVariableInfoConfigs(count) == kErrorNone ? 0 : -1;
1812 }
1813 
1814 int HWCDisplay::GetDisplayAttributesForConfig(int config,
1815                                             DisplayConfigVariableInfo *display_attributes) {
1816   return display_intf_->GetConfig(UINT32(config), display_attributes) == kErrorNone ? 0 : -1;
1817 }
1818 
1819 bool HWCDisplay::SingleLayerUpdating(void) {
1820   uint32_t updating_count = 0;
1821 
1822   for (uint i = 0; i < layer_stack_.layers.size(); i++) {
1823     auto layer = layer_stack_.layers.at(i);
1824     if (layer->flags.updating) {
1825       updating_count++;
1826     }
1827   }
1828 
1829   return (updating_count == 1);
1830 }
1831 
1832 bool HWCDisplay::IsLayerUpdating(const Layer *layer) {
1833   // Layer should be considered updating if
1834   //   a) layer is in single buffer mode, or
1835   //   b) valid dirty_regions(android specific hint for updating status), or
1836   //   c) layer stack geometry has changed (TODO(user): Remove when SDM accepts
1837   //      geometry_changed as bit fields).
1838   return (layer->flags.single_buffer || IsSurfaceUpdated(layer->dirty_regions) ||
1839           geometry_changes_);
1840 }
1841 
1842 bool HWCDisplay::IsSurfaceUpdated(const std::vector<LayerRect> &dirty_regions) {
1843   // based on dirty_regions determine if its updating
1844   // dirty_rect count = 0 - whole layer - updating.
1845   // dirty_rect count = 1 or more valid rects - updating.
1846   // dirty_rect count = 1 with (0,0,0,0) - not updating.
1847   return (dirty_regions.empty() || IsValid(dirty_regions.at(0)));
1848 }
1849 
1850 uint32_t HWCDisplay::SanitizeRefreshRate(uint32_t req_refresh_rate) {
1851   uint32_t refresh_rate = req_refresh_rate;
1852 
1853   if (refresh_rate < min_refresh_rate_) {
1854     // Pick the next multiple of request which is within the range
1855     refresh_rate =
1856         (((min_refresh_rate_ / refresh_rate) + ((min_refresh_rate_ % refresh_rate) ? 1 : 0)) *
1857          refresh_rate);
1858   }
1859 
1860   if (refresh_rate > max_refresh_rate_) {
1861     refresh_rate = max_refresh_rate_;
1862   }
1863 
1864   return refresh_rate;
1865 }
1866 
1867 DisplayClass HWCDisplay::GetDisplayClass() {
1868   return display_class_;
1869 }
1870 
1871 void HWCDisplay::CloseAcquireFds() {
1872   for (auto hwc_layer : layer_set_) {
1873     auto layer = hwc_layer->GetSDMLayer();
1874     if (layer->input_buffer.acquire_fence_fd >= 0) {
1875       close(layer->input_buffer.acquire_fence_fd);
1876       layer->input_buffer.acquire_fence_fd = -1;
1877     }
1878   }
1879   int32_t &client_target_acquire_fence =
1880       client_target_->GetSDMLayer()->input_buffer.acquire_fence_fd;
1881   if (client_target_acquire_fence >= 0) {
1882     close(client_target_acquire_fence);
1883     client_target_acquire_fence = -1;
1884   }
1885 }
1886 
1887 std::string HWCDisplay::Dump() {
1888   std::ostringstream os;
1889   os << "-------------------------------" << std::endl;
1890   os << "HWC2 display_id: " << id_ << std::endl;
1891   for (auto layer : layer_set_) {
1892     auto sdm_layer = layer->GetSDMLayer();
1893     auto transform = sdm_layer->transform;
1894     os << "layer: " << std::setw(4) << layer->GetId();
1895     os << " z: " << layer->GetZ();
1896     os << " compositon: " <<
1897           to_string(layer->GetClientRequestedCompositionType()).c_str();
1898     os << "/" <<
1899           to_string(layer->GetDeviceSelectedCompositionType()).c_str();
1900     os << " alpha: " << std::to_string(sdm_layer->plane_alpha).c_str();
1901     os << " format: " << std::setw(22) << GetFormatString(sdm_layer->input_buffer.format);
1902     os << " dataspace:" << std::hex << "0x" << std::setw(8) << std::setfill('0')
1903        << layer->GetLayerDataspace() << std::dec << std::setfill(' ');
1904     os << " transform: " << transform.rotation << "/" << transform.flip_horizontal <<
1905           "/"<< transform.flip_vertical;
1906     os << " buffer_id: " << std::hex << "0x" << sdm_layer->input_buffer.buffer_id << std::dec
1907        << std::endl;
1908   }
1909   if (color_mode_) {
1910     color_mode_->Dump(&os);
1911   }
1912   os << "-------------------------------" << std::endl;
1913   return os.str();
1914 }
1915 
1916 bool HWCDisplay::CanSkipValidate() {
1917   // Layer Stack checks
1918   if (layer_stack_.flags.hdr_present && (tone_mapper_ && tone_mapper_->IsActive())) {
1919     return false;
1920   }
1921 
1922   for (auto hwc_layer : layer_set_) {
1923     if (hwc_layer->NeedsValidation()) {
1924       return false;
1925     }
1926 
1927     // Do not allow Skip Validate, if any layer needs GPU Composition.
1928     if (hwc_layer->GetDeviceSelectedCompositionType() == HWC2::Composition::Client) {
1929       return false;
1930     }
1931   }
1932 
1933   return true;
1934 }
1935 
1936 }  // namespace sdm
1937