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