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