• 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 
371     if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::Cursor) {
372       // Currently we support only one HWCursor & only at top most z-order
373       if ((*layer_set_.rbegin())->GetId() == hwc_layer->GetId()) {
374         layer->flags.cursor = true;
375         layer_stack_.flags.cursor_present = true;
376       }
377     }
378 
379     // TODO(user): Move to a getter if this is needed at other places
380     hwc_rect_t scaled_display_frame = {INT(layer->dst_rect.left), INT(layer->dst_rect.top),
381                                        INT(layer->dst_rect.right), INT(layer->dst_rect.bottom)};
382     ApplyScanAdjustment(&scaled_display_frame);
383     hwc_layer->SetLayerDisplayFrame(scaled_display_frame);
384     ApplyDeInterlaceAdjustment(layer);
385     // SDM requires these details even for solid fill
386     if (layer->flags.solid_fill) {
387       LayerBuffer *layer_buffer = layer->input_buffer;
388       uint32_t display_width = 0, display_height = 0;
389       GetMixerResolution(&display_width, &display_height);
390       layer_buffer->width = display_width;
391       layer_buffer->height = display_height;
392       layer_buffer->acquire_fence_fd = -1;
393       layer_buffer->release_fence_fd = -1;
394       layer->src_rect = layer->dst_rect;
395     }
396 
397     if (layer->frame_rate > metadata_refresh_rate_) {
398       metadata_refresh_rate_ = SanitizeRefreshRate(layer->frame_rate);
399     } else {
400       layer->frame_rate = current_refresh_rate_;
401     }
402     display_rect_ = Union(display_rect_, layer->dst_rect);
403     geometry_changes_ |= hwc_layer->GetGeometryChanges();
404     layer->flags.updating = IsLayerUpdating(layer);
405 
406     layer_stack_.layers.push_back(layer);
407   }
408   // TODO(user): Set correctly when SDM supports geometry_changes as bitmask
409   layer_stack_.flags.geometry_changed = UINT32(geometry_changes_ > 0);
410   // Append client target to the layer stack
411   layer_stack_.layers.push_back(client_target_->GetSDMLayer());
412 }
413 
BuildSolidFillStack()414 void HWCDisplay::BuildSolidFillStack() {
415   layer_stack_ = LayerStack();
416   display_rect_ = LayerRect();
417 
418   layer_stack_.layers.push_back(solid_fill_layer_);
419   layer_stack_.flags.geometry_changed = 1U;
420   // Append client target to the layer stack
421   layer_stack_.layers.push_back(client_target_->GetSDMLayer());
422 }
423 
SetLayerZOrder(hwc2_layer_t layer_id,uint32_t z)424 HWC2::Error HWCDisplay::SetLayerZOrder(hwc2_layer_t layer_id, uint32_t z) {
425   const auto map_layer = layer_map_.find(layer_id);
426   if (map_layer == layer_map_.end()) {
427     DLOGE("[%" PRIu64 "] updateLayerZ failed to find layer", id_);
428     return HWC2::Error::BadLayer;
429   }
430 
431   const auto layer = map_layer->second;
432   const auto z_range = layer_set_.equal_range(layer);
433   bool layer_on_display = false;
434   for (auto current = z_range.first; current != z_range.second; ++current) {
435     if (*current == layer) {
436       if ((*current)->GetZ() == z) {
437         // Don't change anything if the Z hasn't changed
438         return HWC2::Error::None;
439       }
440       current = layer_set_.erase(current);
441       layer_on_display = true;
442       break;
443     }
444   }
445 
446   if (!layer_on_display) {
447     DLOGE("[%" PRIu64 "] updateLayerZ failed to find layer on display", id_);
448     return HWC2::Error::BadLayer;
449   }
450 
451   layer->SetLayerZOrder(z);
452   layer_set_.emplace(layer);
453   return HWC2::Error::None;
454 }
455 
SetVsyncEnabled(HWC2::Vsync enabled)456 HWC2::Error HWCDisplay::SetVsyncEnabled(HWC2::Vsync enabled) {
457   DLOGV("Display ID: %d enabled: %s", id_, to_string(enabled).c_str());
458   DisplayError error = kErrorNone;
459 
460   if (shutdown_pending_) {
461     return HWC2::Error::None;
462   }
463 
464   bool state;
465   if (enabled == HWC2::Vsync::Enable)
466     state = true;
467   else if (enabled == HWC2::Vsync::Disable)
468     state = false;
469   else
470     return HWC2::Error::BadParameter;
471 
472   error = display_intf_->SetVSyncState(state);
473 
474   if (error != kErrorNone) {
475     if (error == kErrorShutDown) {
476       shutdown_pending_ = true;
477       return HWC2::Error::None;
478     }
479     DLOGE("Failed. enabled = %s, error = %d", to_string(enabled).c_str(), error);
480     return HWC2::Error::BadDisplay;
481   }
482 
483   return HWC2::Error::None;
484 }
485 
SetPowerMode(HWC2::PowerMode mode)486 HWC2::Error HWCDisplay::SetPowerMode(HWC2::PowerMode mode) {
487   DLOGV("display = %d, mode = %s", id_, to_string(mode).c_str());
488   DisplayState state = kStateOff;
489   bool flush_on_error = flush_on_error_;
490 
491   if (shutdown_pending_) {
492     return HWC2::Error::None;
493   }
494 
495   switch (mode) {
496     case HWC2::PowerMode::Off:
497       // During power off, all of the buffers are released.
498       // Do not flush until a buffer is successfully submitted again.
499       flush_on_error = false;
500       state = kStateOff;
501       break;
502     case HWC2::PowerMode::On:
503       state = kStateOn;
504       last_power_mode_ = HWC2::PowerMode::On;
505       break;
506     case HWC2::PowerMode::Doze:
507       state = kStateDoze;
508       last_power_mode_ = HWC2::PowerMode::Doze;
509       break;
510     case HWC2::PowerMode::DozeSuspend:
511       state = kStateDozeSuspend;
512       last_power_mode_ = HWC2::PowerMode::DozeSuspend;
513       break;
514     default:
515       return HWC2::Error::BadParameter;
516   }
517 
518   DisplayError error = display_intf_->SetDisplayState(state);
519   if (error == kErrorNone) {
520     flush_on_error_ = flush_on_error;
521   } else {
522     if (error == kErrorShutDown) {
523       shutdown_pending_ = true;
524       return HWC2::Error::None;
525     }
526     DLOGE("Set state failed. Error = %d", error);
527     return HWC2::Error::BadParameter;
528   }
529 
530   return HWC2::Error::None;
531 }
532 
GetClientTargetSupport(uint32_t width,uint32_t height,int32_t format,int32_t dataspace)533 HWC2::Error HWCDisplay::GetClientTargetSupport(uint32_t width, uint32_t height, int32_t format,
534                                                int32_t dataspace) {
535   DisplayConfigVariableInfo variable_config;
536   display_intf_->GetFrameBufferConfig(&variable_config);
537   // TODO(user): Support scaled configurations, other formats and other dataspaces
538   if (format != HAL_PIXEL_FORMAT_RGBA_8888 || dataspace != HAL_DATASPACE_UNKNOWN ||
539       width != variable_config.x_pixels || height != variable_config.y_pixels) {
540     return HWC2::Error::Unsupported;
541   } else {
542     return HWC2::Error::None;
543   }
544 }
545 
GetColorModes(uint32_t * out_num_modes,android_color_mode_t * out_modes)546 HWC2::Error HWCDisplay::GetColorModes(uint32_t *out_num_modes, android_color_mode_t *out_modes) {
547   if (out_modes) {
548     out_modes[0] = HAL_COLOR_MODE_NATIVE;
549   }
550   *out_num_modes = 1;
551 
552   return HWC2::Error::None;
553 }
554 
GetDisplayConfigs(uint32_t * out_num_configs,hwc2_config_t * out_configs)555 HWC2::Error HWCDisplay::GetDisplayConfigs(uint32_t *out_num_configs, hwc2_config_t *out_configs) {
556   // TODO(user): Actually handle multiple configs
557   if (out_configs == nullptr) {
558     *out_num_configs = 1;
559   } else {
560     *out_num_configs = 1;
561     out_configs[0] = 0;
562   }
563 
564   return HWC2::Error::None;
565 }
566 
GetDisplayAttribute(hwc2_config_t config,HWC2::Attribute attribute,int32_t * out_value)567 HWC2::Error HWCDisplay::GetDisplayAttribute(hwc2_config_t config, HWC2::Attribute attribute,
568                                             int32_t *out_value) {
569   DisplayConfigVariableInfo variable_config;
570   DisplayError error = display_intf_->GetFrameBufferConfig(&variable_config);
571   if (error != kErrorNone) {
572     DLOGV("Get variable config failed. Error = %d", error);
573     return HWC2::Error::BadDisplay;
574   }
575 
576   switch (attribute) {
577     case HWC2::Attribute::VsyncPeriod:
578       *out_value = INT32(variable_config.vsync_period_ns);
579       break;
580     case HWC2::Attribute::Width:
581       *out_value = INT32(variable_config.x_pixels);
582       break;
583     case HWC2::Attribute::Height:
584       *out_value = INT32(variable_config.y_pixels);
585       break;
586     case HWC2::Attribute::DpiX:
587       *out_value = INT32(variable_config.x_dpi * 1000.0f);
588       break;
589     case HWC2::Attribute::DpiY:
590       *out_value = INT32(variable_config.y_dpi * 1000.0f);
591       break;
592     default:
593       DLOGW("Spurious attribute type = %s", to_string(attribute).c_str());
594       return HWC2::Error::BadConfig;
595   }
596 
597   return HWC2::Error::None;
598 }
599 
GetDisplayName(uint32_t * out_size,char * out_name)600 HWC2::Error HWCDisplay::GetDisplayName(uint32_t *out_size, char *out_name) {
601   // TODO(user): Get panel name and EDID name and populate it here
602   if (out_name == nullptr) {
603     *out_size = 32;
604   } else {
605     std::string name;
606     switch (id_) {
607       case HWC_DISPLAY_PRIMARY:
608         name = "Primary Display";
609         break;
610       case HWC_DISPLAY_EXTERNAL:
611         name = "External Display";
612         break;
613       case HWC_DISPLAY_VIRTUAL:
614         name = "Virtual Display";
615         break;
616       default:
617         name = "Unknown";
618         break;
619     }
620     std::strncpy(out_name, name.c_str(), name.size());
621     *out_size = UINT32(name.size());
622   }
623   return HWC2::Error::None;
624 }
625 
GetDisplayType(int32_t * out_type)626 HWC2::Error HWCDisplay::GetDisplayType(int32_t *out_type) {
627   if (out_type != nullptr) {
628     if (id_ == HWC_DISPLAY_VIRTUAL) {
629       *out_type = HWC2_DISPLAY_TYPE_VIRTUAL;
630     } else {
631       *out_type = HWC2_DISPLAY_TYPE_PHYSICAL;
632     }
633     return HWC2::Error::None;
634   } else {
635     return HWC2::Error::BadParameter;
636   }
637 }
638 
639 // TODO(user): Store configurations and hook them up here
GetActiveConfig(hwc2_config_t * out_config)640 HWC2::Error HWCDisplay::GetActiveConfig(hwc2_config_t *out_config) {
641   if (out_config != nullptr) {
642     *out_config = 0;
643     return HWC2::Error::None;
644   } else {
645     return HWC2::Error::BadParameter;
646   }
647 }
648 
SetClientTarget(buffer_handle_t target,int32_t acquire_fence,int32_t dataspace,hwc_region_t damage)649 HWC2::Error HWCDisplay::SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
650                                         int32_t dataspace, hwc_region_t damage) {
651   // TODO(user): SurfaceFlinger gives us a null pointer here when doing full SDE composition
652   // The error is problematic for layer caching as it would overwrite our cached client target.
653   // Reported bug 28569722 to resolve this.
654   // For now, continue to use the last valid buffer reported to us for layer caching.
655   if (target == nullptr) {
656     return HWC2::Error::None;
657   }
658 
659   if (acquire_fence == 0) {
660     DLOGE("acquire_fence is zero");
661     return HWC2::Error::BadParameter;
662   }
663 
664   client_target_->SetLayerBuffer(target, acquire_fence);
665   client_target_->SetLayerSurfaceDamage(damage);
666   // Ignoring dataspace for now
667   return HWC2::Error::None;
668 }
669 
SetActiveConfig(hwc2_config_t config)670 HWC2::Error HWCDisplay::SetActiveConfig(hwc2_config_t config) {
671   // We have only one config right now - do nothing
672   return HWC2::Error::None;
673 }
674 
SetMixerResolution(uint32_t width,uint32_t height)675 DisplayError HWCDisplay::SetMixerResolution(uint32_t width, uint32_t height) {
676   return kErrorNotSupported;
677 }
678 
SetFrameDumpConfig(uint32_t count,uint32_t bit_mask_layer_type)679 void HWCDisplay::SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type) {
680   dump_frame_count_ = count;
681   dump_frame_index_ = 0;
682   dump_input_layers_ = ((bit_mask_layer_type & (1 << INPUT_LAYER_DUMP)) != 0);
683 
684   if (blit_engine_) {
685     blit_engine_->SetFrameDumpConfig(count);
686   }
687 
688   DLOGI("num_frame_dump %d, input_layer_dump_enable %d", dump_frame_count_, dump_input_layers_);
689 }
690 
GetLastPowerMode()691 HWC2::PowerMode HWCDisplay::GetLastPowerMode() {
692   return last_power_mode_;
693 }
694 
VSync(const DisplayEventVSync & vsync)695 DisplayError HWCDisplay::VSync(const DisplayEventVSync &vsync) {
696   callbacks_->Vsync(id_, vsync.timestamp);
697   return kErrorNone;
698 }
699 
Refresh()700 DisplayError HWCDisplay::Refresh() {
701   return kErrorNotSupported;
702 }
703 
CECMessage(char * message)704 DisplayError HWCDisplay::CECMessage(char *message) {
705   if (qservice_) {
706     qservice_->onCECMessageReceived(message, 0);
707   } else {
708     DLOGW("Qservice instance not available.");
709   }
710 
711   return kErrorNone;
712 }
713 
PrepareLayerStack(uint32_t * out_num_types,uint32_t * out_num_requests)714 HWC2::Error HWCDisplay::PrepareLayerStack(uint32_t *out_num_types, uint32_t *out_num_requests) {
715   layer_changes_.clear();
716   layer_requests_.clear();
717   if (shutdown_pending_) {
718     return HWC2::Error::BadDisplay;
719   }
720 
721   if (!skip_prepare_) {
722     DisplayError error = display_intf_->Prepare(&layer_stack_);
723     if (error != kErrorNone) {
724       if (error == kErrorShutDown) {
725         shutdown_pending_ = true;
726       } else if (error != kErrorPermission) {
727         DLOGE("Prepare failed. Error = %d", error);
728         // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
729         // so that previous buffer and fences are released, and override the error.
730         flush_ = true;
731       }
732       return HWC2::Error::BadDisplay;
733     }
734   } else {
735     // Skip is not set
736     MarkLayersForGPUBypass();
737     skip_prepare_ = false;
738     DLOGI("SecureDisplay %s, Skip Prepare/Commit and Flush",
739           secure_display_active_ ? "Starting" : "Stopping");
740     flush_ = true;
741   }
742 
743   for (auto hwc_layer : layer_set_) {
744     Layer *layer = hwc_layer->GetSDMLayer();
745     LayerComposition &composition = layer->composition;
746 
747     if ((composition == kCompositionSDE) || (composition == kCompositionHybrid) ||
748         (composition == kCompositionBlit)) {
749       layer_requests_[hwc_layer->GetId()] = HWC2::LayerRequest::ClearClientTarget;
750     }
751 
752     HWC2::Composition requested_composition = hwc_layer->GetClientRequestedCompositionType();
753     // Set SDM composition to HWC2 type in HWCLayer
754     hwc_layer->SetComposition(composition);
755     HWC2::Composition device_composition  = hwc_layer->GetDeviceSelectedCompositionType();
756     // Update the changes list only if the requested composition is different from SDM comp type
757     // TODO(user): Take Care of other comptypes(BLIT)
758     if (requested_composition != device_composition) {
759       layer_changes_[hwc_layer->GetId()] = device_composition;
760     }
761   }
762   *out_num_types = UINT32(layer_changes_.size());
763   *out_num_requests = UINT32(layer_requests_.size());
764   validated_ = true;
765   if (*out_num_types > 0) {
766     return HWC2::Error::HasChanges;
767   } else {
768     return HWC2::Error::None;
769   }
770 }
771 
AcceptDisplayChanges()772 HWC2::Error HWCDisplay::AcceptDisplayChanges() {
773   if (!validated_ && !layer_set_.empty()) {
774     return HWC2::Error::NotValidated;
775   }
776 
777   for (const auto& change : layer_changes_) {
778     auto hwc_layer = layer_map_[change.first];
779     auto composition = change.second;
780     hwc_layer->UpdateClientCompositionType(composition);
781   }
782   return HWC2::Error::None;
783 }
784 
GetChangedCompositionTypes(uint32_t * out_num_elements,hwc2_layer_t * out_layers,int32_t * out_types)785 HWC2::Error HWCDisplay::GetChangedCompositionTypes(uint32_t *out_num_elements,
786                                                    hwc2_layer_t *out_layers, int32_t *out_types) {
787   if (layer_set_.empty()) {
788     return HWC2::Error::None;
789   }
790 
791   if (!validated_) {
792     DLOGW("Display is not validated");
793     return HWC2::Error::NotValidated;
794   }
795   *out_num_elements = UINT32(layer_changes_.size());
796   if (out_layers != nullptr && out_types != nullptr) {
797     int i = 0;
798     for (auto change : layer_changes_) {
799       out_layers[i] = change.first;
800       out_types[i] = INT32(change.second);
801       i++;
802     }
803   }
804   return HWC2::Error::None;
805 }
806 
GetReleaseFences(uint32_t * out_num_elements,hwc2_layer_t * out_layers,int32_t * out_fences)807 HWC2::Error HWCDisplay::GetReleaseFences(uint32_t *out_num_elements, hwc2_layer_t *out_layers,
808                                          int32_t *out_fences) {
809   if (out_layers != nullptr && out_fences != nullptr) {
810     int i = 0;
811     for (auto hwc_layer : layer_set_) {
812       out_layers[i] = hwc_layer->GetId();
813       out_fences[i] = hwc_layer->PopReleaseFence();
814       i++;
815     }
816   }
817   *out_num_elements = UINT32(layer_set_.size());
818   return HWC2::Error::None;
819 }
820 
GetDisplayRequests(int32_t * out_display_requests,uint32_t * out_num_elements,hwc2_layer_t * out_layers,int32_t * out_layer_requests)821 HWC2::Error HWCDisplay::GetDisplayRequests(int32_t *out_display_requests,
822                                            uint32_t *out_num_elements, hwc2_layer_t *out_layers,
823                                            int32_t *out_layer_requests) {
824   // No display requests for now
825   // Use for sharing blit buffers and
826   // writing wfd buffer directly to output if there is full GPU composition
827   // and no color conversion needed
828   if (layer_set_.empty()) {
829     return HWC2::Error::None;
830   }
831 
832   if (!validated_) {
833     DLOGW("Display is not validated");
834     return HWC2::Error::NotValidated;
835   }
836   *out_display_requests = 0;
837   *out_num_elements = UINT32(layer_requests_.size());
838   if (out_layers != nullptr && out_layer_requests != nullptr) {
839     int i = 0;
840     for (auto &request : layer_requests_) {
841       out_layers[i] = request.first;
842       out_layer_requests[i] = INT32(request.second);
843       i++;
844     }
845   }
846   return HWC2::Error::None;
847 }
848 
CommitLayerStack(void)849 HWC2::Error HWCDisplay::CommitLayerStack(void) {
850   if (shutdown_pending_ || layer_set_.empty()) {
851     return HWC2::Error::None;
852   }
853 
854   if (!validated_) {
855     DLOGW("Display is not validated");
856     return HWC2::Error::NotValidated;
857   }
858 
859   DumpInputBuffers();
860 
861   if (!flush_) {
862     DisplayError error = kErrorUndefined;
863     error = display_intf_->Commit(&layer_stack_);
864     validated_ = false;
865 
866     if (error == kErrorNone) {
867       // A commit is successfully submitted, start flushing on failure now onwards.
868       flush_on_error_ = true;
869     } else {
870       if (error == kErrorShutDown) {
871         shutdown_pending_ = true;
872         return HWC2::Error::Unsupported;
873       } else if (error != kErrorPermission) {
874         DLOGE("Commit failed. Error = %d", error);
875         // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
876         // so that previous buffer and fences are released, and override the error.
877         flush_ = true;
878       }
879     }
880   }
881 
882   return HWC2::Error::None;
883 }
884 
PostCommitLayerStack(int32_t * out_retire_fence)885 HWC2::Error HWCDisplay::PostCommitLayerStack(int32_t *out_retire_fence) {
886   auto status = HWC2::Error::None;
887 
888   // Do no call flush on errors, if a successful buffer is never submitted.
889   if (flush_ && flush_on_error_) {
890     display_intf_->Flush();
891   }
892 
893   // TODO(user): No way to set the client target release fence on SF
894   int32_t &client_target_release_fence =
895       client_target_->GetSDMLayer()->input_buffer->release_fence_fd;
896   if (client_target_release_fence >= 0) {
897     close(client_target_release_fence);
898     client_target_release_fence = -1;
899   }
900 
901   for (auto hwc_layer : layer_set_) {
902     hwc_layer->ResetGeometryChanges();
903     Layer *layer = hwc_layer->GetSDMLayer();
904     LayerBuffer *layer_buffer = layer->input_buffer;
905 
906     if (!flush_) {
907       // If swapinterval property is set to 0 or for single buffer layers, do not update f/w
908       // release fences and discard fences from driver
909       if (swap_interval_zero_ || layer->flags.single_buffer) {
910         close(layer_buffer->release_fence_fd);
911         layer_buffer->release_fence_fd = -1;
912       } else if (layer->composition != kCompositionGPU) {
913         hwc_layer->PushReleaseFence(layer_buffer->release_fence_fd);
914         layer_buffer->release_fence_fd = -1;
915       } else {
916         hwc_layer->PushReleaseFence(-1);
917       }
918     }
919 
920     if (layer_buffer->acquire_fence_fd >= 0) {
921       close(layer_buffer->acquire_fence_fd);
922       layer_buffer->acquire_fence_fd = -1;
923     }
924   }
925 
926   *out_retire_fence = -1;
927   if (!flush_) {
928     // if swapinterval property is set to 0 then close and reset the list retire fence
929     if (swap_interval_zero_) {
930       close(layer_stack_.retire_fence_fd);
931       layer_stack_.retire_fence_fd = -1;
932     }
933     *out_retire_fence = layer_stack_.retire_fence_fd;
934 
935     if (dump_frame_count_) {
936       dump_frame_count_--;
937       dump_frame_index_++;
938     }
939   }
940 
941   geometry_changes_ = GeometryChanges::kNone;
942   flush_ = false;
943 
944   return status;
945 }
946 
SetIdleTimeoutMs(uint32_t timeout_ms)947 void HWCDisplay::SetIdleTimeoutMs(uint32_t timeout_ms) {
948   return;
949 }
950 
SetMaxMixerStages(uint32_t max_mixer_stages)951 DisplayError HWCDisplay::SetMaxMixerStages(uint32_t max_mixer_stages) {
952   DisplayError error = kErrorNone;
953 
954   if (display_intf_) {
955     error = display_intf_->SetMaxMixerStages(max_mixer_stages);
956   }
957 
958   return error;
959 }
960 
GetSDMFormat(const int32_t & source,const int flags)961 LayerBufferFormat HWCDisplay::GetSDMFormat(const int32_t &source, const int flags) {
962   LayerBufferFormat format = kFormatInvalid;
963   if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
964     switch (source) {
965       case HAL_PIXEL_FORMAT_RGBA_8888:
966         format = kFormatRGBA8888Ubwc;
967         break;
968       case HAL_PIXEL_FORMAT_RGBX_8888:
969         format = kFormatRGBX8888Ubwc;
970         break;
971       case HAL_PIXEL_FORMAT_BGR_565:
972         format = kFormatBGR565Ubwc;
973         break;
974       case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
975       case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
976       case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
977         format = kFormatYCbCr420SPVenusUbwc;
978         break;
979       case HAL_PIXEL_FORMAT_RGBA_1010102:
980         format = kFormatRGBA1010102Ubwc;
981         break;
982       case HAL_PIXEL_FORMAT_RGBX_1010102:
983         format = kFormatRGBX1010102Ubwc;
984         break;
985       case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
986         format = kFormatYCbCr420TP10Ubwc;
987         break;
988       default:
989         DLOGE("Unsupported format type for UBWC %d", source);
990         return kFormatInvalid;
991     }
992     return format;
993   }
994 
995   switch (source) {
996     case HAL_PIXEL_FORMAT_RGBA_8888:
997       format = kFormatRGBA8888;
998       break;
999     case HAL_PIXEL_FORMAT_RGBA_5551:
1000       format = kFormatRGBA5551;
1001       break;
1002     case HAL_PIXEL_FORMAT_RGBA_4444:
1003       format = kFormatRGBA4444;
1004       break;
1005     case HAL_PIXEL_FORMAT_BGRA_8888:
1006       format = kFormatBGRA8888;
1007       break;
1008     case HAL_PIXEL_FORMAT_RGBX_8888:
1009       format = kFormatRGBX8888;
1010       break;
1011     case HAL_PIXEL_FORMAT_BGRX_8888:
1012       format = kFormatBGRX8888;
1013       break;
1014     case HAL_PIXEL_FORMAT_RGB_888:
1015       format = kFormatRGB888;
1016       break;
1017     case HAL_PIXEL_FORMAT_RGB_565:
1018       format = kFormatRGB565;
1019       break;
1020     case HAL_PIXEL_FORMAT_BGR_565:
1021       format = kFormatBGR565;
1022       break;
1023     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
1024     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1025       format = kFormatYCbCr420SemiPlanarVenus;
1026       break;
1027     case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
1028       format = kFormatYCrCb420SemiPlanarVenus;
1029       break;
1030     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1031       format = kFormatYCbCr420SPVenusUbwc;
1032       break;
1033     case HAL_PIXEL_FORMAT_YV12:
1034       format = kFormatYCrCb420PlanarStride16;
1035       break;
1036     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1037       format = kFormatYCrCb420SemiPlanar;
1038       break;
1039     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
1040       format = kFormatYCbCr420SemiPlanar;
1041       break;
1042     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
1043       format = kFormatYCbCr422H2V1SemiPlanar;
1044       break;
1045     case HAL_PIXEL_FORMAT_YCbCr_422_I:
1046       format = kFormatYCbCr422H2V1Packed;
1047       break;
1048     case HAL_PIXEL_FORMAT_RGBA_1010102:
1049       format = kFormatRGBA1010102;
1050       break;
1051     case HAL_PIXEL_FORMAT_ARGB_2101010:
1052       format = kFormatARGB2101010;
1053       break;
1054     case HAL_PIXEL_FORMAT_RGBX_1010102:
1055       format = kFormatRGBX1010102;
1056       break;
1057     case HAL_PIXEL_FORMAT_XRGB_2101010:
1058       format = kFormatXRGB2101010;
1059       break;
1060     case HAL_PIXEL_FORMAT_BGRA_1010102:
1061       format = kFormatBGRA1010102;
1062       break;
1063     case HAL_PIXEL_FORMAT_ABGR_2101010:
1064       format = kFormatABGR2101010;
1065       break;
1066     case HAL_PIXEL_FORMAT_BGRX_1010102:
1067       format = kFormatBGRX1010102;
1068       break;
1069     case HAL_PIXEL_FORMAT_XBGR_2101010:
1070       format = kFormatXBGR2101010;
1071       break;
1072     case HAL_PIXEL_FORMAT_YCbCr_420_P010:
1073       format = kFormatYCbCr420P010;
1074       break;
1075     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
1076       format = kFormatYCbCr420TP10Ubwc;
1077       break;
1078     default:
1079       DLOGW("Unsupported format type = %d", source);
1080       return kFormatInvalid;
1081   }
1082 
1083   return format;
1084 }
1085 
DumpInputBuffers()1086 void HWCDisplay::DumpInputBuffers() {
1087   char dir_path[PATH_MAX];
1088 
1089   if (!dump_frame_count_ || flush_ || !dump_input_layers_) {
1090     return;
1091   }
1092 
1093   snprintf(dir_path, sizeof(dir_path), "/data/misc/display/frame_dump_%s", GetDisplayString());
1094 
1095   if (mkdir(dir_path, 0777) != 0 && errno != EEXIST) {
1096     DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno));
1097     return;
1098   }
1099 
1100   // if directory exists already, need to explicitly change the permission.
1101   if (errno == EEXIST && chmod(dir_path, 0777) != 0) {
1102     DLOGW("Failed to change permissions on %s directory", dir_path);
1103     return;
1104   }
1105 
1106   for (uint32_t i = 0; i < layer_stack_.layers.size(); i++) {
1107     auto layer = layer_stack_.layers.at(i);
1108     const private_handle_t *pvt_handle =
1109         reinterpret_cast<const private_handle_t *>(layer->input_buffer->buffer_id);
1110     auto acquire_fence_fd = layer->input_buffer->acquire_fence_fd;
1111 
1112     if (acquire_fence_fd >= 0) {
1113       int error = sync_wait(acquire_fence_fd, 1000);
1114       if (error < 0) {
1115         DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
1116         return;
1117       }
1118     }
1119 
1120     if (pvt_handle && pvt_handle->base) {
1121       char dump_file_name[PATH_MAX];
1122       size_t result = 0;
1123 
1124       snprintf(dump_file_name, sizeof(dump_file_name), "%s/input_layer%d_%dx%d_%s_frame%d.raw",
1125                dir_path, i, pvt_handle->width, pvt_handle->height,
1126                GetHALPixelFormatString(pvt_handle->format), dump_frame_index_);
1127 
1128       FILE *fp = fopen(dump_file_name, "w+");
1129       if (fp) {
1130         result = fwrite(reinterpret_cast<void *>(pvt_handle->base), pvt_handle->size, 1, fp);
1131         fclose(fp);
1132       }
1133 
1134       DLOGI("Frame Dump %s: is %s", dump_file_name, result ? "Successful" : "Failed");
1135     }
1136   }
1137 }
1138 
DumpOutputBuffer(const BufferInfo & buffer_info,void * base,int fence)1139 void HWCDisplay::DumpOutputBuffer(const BufferInfo &buffer_info, void *base, int fence) {
1140   char dir_path[PATH_MAX];
1141 
1142   snprintf(dir_path, sizeof(dir_path), "/data/misc/display/frame_dump_%s", GetDisplayString());
1143 
1144   if (mkdir(dir_path, 777) != 0 && errno != EEXIST) {
1145     DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno));
1146     return;
1147   }
1148 
1149   // if directory exists already, need to explicitly change the permission.
1150   if (errno == EEXIST && chmod(dir_path, 0777) != 0) {
1151     DLOGW("Failed to change permissions on %s directory", dir_path);
1152     return;
1153   }
1154 
1155   if (base) {
1156     char dump_file_name[PATH_MAX];
1157     size_t result = 0;
1158 
1159     if (fence >= 0) {
1160       int error = sync_wait(fence, 1000);
1161       if (error < 0) {
1162         DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
1163         return;
1164       }
1165     }
1166 
1167     snprintf(dump_file_name, sizeof(dump_file_name), "%s/output_layer_%dx%d_%s_frame%d.raw",
1168              dir_path, buffer_info.buffer_config.width, buffer_info.buffer_config.height,
1169              GetFormatString(buffer_info.buffer_config.format), dump_frame_index_);
1170 
1171     FILE *fp = fopen(dump_file_name, "w+");
1172     if (fp) {
1173       result = fwrite(base, buffer_info.alloc_buffer_info.size, 1, fp);
1174       fclose(fp);
1175     }
1176 
1177     DLOGI("Frame Dump of %s is %s", dump_file_name, result ? "Successful" : "Failed");
1178   }
1179 }
1180 
GetHALPixelFormatString(int format)1181 const char *HWCDisplay::GetHALPixelFormatString(int format) {
1182   switch (format) {
1183     case HAL_PIXEL_FORMAT_RGBA_8888:
1184       return "RGBA_8888";
1185     case HAL_PIXEL_FORMAT_RGBX_8888:
1186       return "RGBX_8888";
1187     case HAL_PIXEL_FORMAT_RGB_888:
1188       return "RGB_888";
1189     case HAL_PIXEL_FORMAT_RGB_565:
1190       return "RGB_565";
1191     case HAL_PIXEL_FORMAT_BGR_565:
1192       return "BGR_565";
1193     case HAL_PIXEL_FORMAT_BGRA_8888:
1194       return "BGRA_8888";
1195     case HAL_PIXEL_FORMAT_RGBA_5551:
1196       return "RGBA_5551";
1197     case HAL_PIXEL_FORMAT_RGBA_4444:
1198       return "RGBA_4444";
1199     case HAL_PIXEL_FORMAT_YV12:
1200       return "YV12";
1201     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
1202       return "YCbCr_422_SP_NV16";
1203     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1204       return "YCrCb_420_SP_NV21";
1205     case HAL_PIXEL_FORMAT_YCbCr_422_I:
1206       return "YCbCr_422_I_YUY2";
1207     case HAL_PIXEL_FORMAT_YCrCb_422_I:
1208       return "YCrCb_422_I_YVYU";
1209     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
1210       return "NV12_ENCODEABLE";
1211     case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
1212       return "YCbCr_420_SP_TILED_TILE_4x2";
1213     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
1214       return "YCbCr_420_SP";
1215     case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
1216       return "YCrCb_420_SP_ADRENO";
1217     case HAL_PIXEL_FORMAT_YCrCb_422_SP:
1218       return "YCrCb_422_SP";
1219     case HAL_PIXEL_FORMAT_R_8:
1220       return "R_8";
1221     case HAL_PIXEL_FORMAT_RG_88:
1222       return "RG_88";
1223     case HAL_PIXEL_FORMAT_INTERLACE:
1224       return "INTERLACE";
1225     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1226       return "YCbCr_420_SP_VENUS";
1227     case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
1228       return "YCrCb_420_SP_VENUS";
1229     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1230       return "YCbCr_420_SP_VENUS_UBWC";
1231     case HAL_PIXEL_FORMAT_RGBA_1010102:
1232       return "RGBA_1010102";
1233     case HAL_PIXEL_FORMAT_ARGB_2101010:
1234       return "ARGB_2101010";
1235     case HAL_PIXEL_FORMAT_RGBX_1010102:
1236       return "RGBX_1010102";
1237     case HAL_PIXEL_FORMAT_XRGB_2101010:
1238       return "XRGB_2101010";
1239     case HAL_PIXEL_FORMAT_BGRA_1010102:
1240       return "BGRA_1010102";
1241     case HAL_PIXEL_FORMAT_ABGR_2101010:
1242       return "ABGR_2101010";
1243     case HAL_PIXEL_FORMAT_BGRX_1010102:
1244       return "BGRX_1010102";
1245     case HAL_PIXEL_FORMAT_XBGR_2101010:
1246       return "XBGR_2101010";
1247     case HAL_PIXEL_FORMAT_YCbCr_420_P010:
1248       return "YCbCr_420_P010";
1249     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
1250       return "YCbCr_420_TP10_UBWC";
1251     default:
1252       return "Unknown_format";
1253   }
1254 }
1255 
GetDisplayString()1256 const char *HWCDisplay::GetDisplayString() {
1257   switch (type_) {
1258     case kPrimary:
1259       return "primary";
1260     case kHDMI:
1261       return "hdmi";
1262     case kVirtual:
1263       return "virtual";
1264     default:
1265       return "invalid";
1266   }
1267 }
1268 
SetFrameBufferResolution(uint32_t x_pixels,uint32_t y_pixels)1269 int HWCDisplay::SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels) {
1270   if (x_pixels <= 0 || y_pixels <= 0) {
1271     DLOGW("Unsupported config: x_pixels=%d, y_pixels=%d", x_pixels, y_pixels);
1272     return -EINVAL;
1273   }
1274 
1275   DisplayConfigVariableInfo fb_config;
1276   DisplayError error = display_intf_->GetFrameBufferConfig(&fb_config);
1277   if (error != kErrorNone) {
1278     DLOGV("Get frame buffer config failed. Error = %d", error);
1279     return -EINVAL;
1280   }
1281 
1282   fb_config.x_pixels = x_pixels;
1283   fb_config.y_pixels = y_pixels;
1284 
1285   error = display_intf_->SetFrameBufferConfig(fb_config);
1286   if (error != kErrorNone) {
1287     DLOGV("Set frame buffer config failed. Error = %d", error);
1288     return -EINVAL;
1289   }
1290 
1291   // Create rects to represent the new source and destination crops
1292   LayerRect crop = LayerRect(0, 0, FLOAT(x_pixels), FLOAT(y_pixels));
1293   LayerRect dst = LayerRect(0, 0, FLOAT(fb_config.x_pixels), FLOAT(fb_config.y_pixels));
1294   auto client_target_layer = client_target_->GetSDMLayer();
1295   client_target_layer->src_rect = crop;
1296   client_target_layer->dst_rect = dst;
1297 
1298   int aligned_width;
1299   int aligned_height;
1300   int usage = GRALLOC_USAGE_HW_FB;
1301   int format = HAL_PIXEL_FORMAT_RGBA_8888;
1302   int ubwc_enabled = 0;
1303   int flags = 0;
1304   HWCDebugHandler::Get()->GetProperty("debug.gralloc.enable_fb_ubwc", &ubwc_enabled);
1305   if (ubwc_enabled == 1) {
1306     usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
1307     flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
1308   }
1309   AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(INT(x_pixels), INT(y_pixels), format, usage,
1310                                                         aligned_width, aligned_height);
1311 
1312   // TODO(user): How does the dirty region get set on the client target? File bug on Google
1313   client_target_layer->composition = kCompositionGPUTarget;
1314   client_target_layer->input_buffer->format = GetSDMFormat(format, flags);
1315   client_target_layer->input_buffer->width = UINT32(aligned_width);
1316   client_target_layer->input_buffer->height = UINT32(aligned_height);
1317   client_target_layer->plane_alpha = 255;
1318 
1319   DLOGI("New framebuffer resolution (%dx%d)", fb_config.x_pixels, fb_config.y_pixels);
1320 
1321   return 0;
1322 }
1323 
GetFrameBufferResolution(uint32_t * x_pixels,uint32_t * y_pixels)1324 void HWCDisplay::GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
1325   DisplayConfigVariableInfo fb_config;
1326   display_intf_->GetFrameBufferConfig(&fb_config);
1327 
1328   *x_pixels = fb_config.x_pixels;
1329   *y_pixels = fb_config.y_pixels;
1330 }
1331 
GetMixerResolution(uint32_t * x_pixels,uint32_t * y_pixels)1332 DisplayError HWCDisplay::GetMixerResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
1333   return display_intf_->GetMixerResolution(x_pixels, y_pixels);
1334 }
1335 
GetPanelResolution(uint32_t * x_pixels,uint32_t * y_pixels)1336 void HWCDisplay::GetPanelResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
1337   DisplayConfigVariableInfo display_config;
1338   uint32_t active_index = 0;
1339 
1340   display_intf_->GetActiveConfig(&active_index);
1341   display_intf_->GetConfig(active_index, &display_config);
1342 
1343   *x_pixels = display_config.x_pixels;
1344   *y_pixels = display_config.y_pixels;
1345 }
1346 
SetDisplayStatus(uint32_t display_status)1347 int HWCDisplay::SetDisplayStatus(uint32_t display_status) {
1348   int status = 0;
1349 
1350   switch (display_status) {
1351     case kDisplayStatusResume:
1352       display_paused_ = false;
1353     case kDisplayStatusOnline:
1354       status = INT32(SetPowerMode(HWC2::PowerMode::On));
1355       break;
1356     case kDisplayStatusPause:
1357       display_paused_ = true;
1358     case kDisplayStatusOffline:
1359       status = INT32(SetPowerMode(HWC2::PowerMode::Off));
1360       break;
1361     default:
1362       DLOGW("Invalid display status %d", display_status);
1363       return -EINVAL;
1364   }
1365 
1366   if (display_status == kDisplayStatusResume || display_status == kDisplayStatusPause) {
1367     callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
1368   }
1369 
1370   return status;
1371 }
1372 
SetCursorPosition(hwc2_layer_t layer,int x,int y)1373 HWC2::Error HWCDisplay::SetCursorPosition(hwc2_layer_t layer, int x, int y) {
1374   if (shutdown_pending_) {
1375     return HWC2::Error::None;
1376   }
1377 
1378   // TODO(user): Validate layer
1379   // TODO(user): Check if we're in a validate/present cycle
1380 
1381   auto error = display_intf_->SetCursorPosition(x, y);
1382   if (error != kErrorNone) {
1383     if (error == kErrorShutDown) {
1384       shutdown_pending_ = true;
1385       return HWC2::Error::None;
1386     }
1387 
1388     DLOGE("Failed for x = %d y = %d, Error = %d", x, y, error);
1389     return HWC2::Error::BadDisplay;
1390   }
1391 
1392   return HWC2::Error::None;
1393 }
1394 
OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level)1395 int HWCDisplay::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) {
1396   DisplayError error = display_intf_->OnMinHdcpEncryptionLevelChange(min_enc_level);
1397   if (error != kErrorNone) {
1398     DLOGE("Failed. Error = %d", error);
1399     return -1;
1400   }
1401 
1402   return 0;
1403 }
1404 
MarkLayersForGPUBypass()1405 void HWCDisplay::MarkLayersForGPUBypass() {
1406   for (auto hwc_layer : layer_set_) {
1407     auto layer = hwc_layer->GetSDMLayer();
1408     layer->composition = kCompositionSDE;
1409   }
1410 }
1411 
MarkLayersForClientComposition()1412 void HWCDisplay::MarkLayersForClientComposition() {
1413   // ClientComposition - GPU comp, to acheive this, set skip flag so that
1414   // SDM does not handle this layer and hwc_layer composition will be
1415   // set correctly at the end of Prepare.
1416   for (auto hwc_layer : layer_set_) {
1417     Layer *layer = hwc_layer->GetSDMLayer();
1418     layer->flags.skip = true;
1419   }
1420 }
1421 
ApplyScanAdjustment(hwc_rect_t * display_frame)1422 void HWCDisplay::ApplyScanAdjustment(hwc_rect_t *display_frame) {
1423 }
1424 
SetPanelBrightness(int level)1425 int HWCDisplay::SetPanelBrightness(int level) {
1426   int ret = 0;
1427   if (display_intf_)
1428     ret = display_intf_->SetPanelBrightness(level);
1429   else
1430     ret = -EINVAL;
1431 
1432   return ret;
1433 }
1434 
GetPanelBrightness(int * level)1435 int HWCDisplay::GetPanelBrightness(int *level) {
1436   return display_intf_->GetPanelBrightness(level);
1437 }
1438 
ToggleScreenUpdates(bool enable)1439 int HWCDisplay::ToggleScreenUpdates(bool enable) {
1440   display_paused_ = enable ? false : true;
1441   callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
1442   return 0;
1443 }
1444 
ColorSVCRequestRoute(const PPDisplayAPIPayload & in_payload,PPDisplayAPIPayload * out_payload,PPPendingParams * pending_action)1445 int HWCDisplay::ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
1446                                      PPDisplayAPIPayload *out_payload,
1447                                      PPPendingParams *pending_action) {
1448   int ret = 0;
1449 
1450   if (display_intf_)
1451     ret = display_intf_->ColorSVCRequestRoute(in_payload, out_payload, pending_action);
1452   else
1453     ret = -EINVAL;
1454 
1455   return ret;
1456 }
1457 
SolidFillPrepare()1458 void HWCDisplay::SolidFillPrepare() {
1459   if (solid_fill_enable_) {
1460     if (solid_fill_layer_ == NULL) {
1461       // Create a dummy layer here
1462       solid_fill_layer_ = new Layer();
1463       solid_fill_layer_->input_buffer = new LayerBuffer();
1464     }
1465     uint32_t primary_width = 0, primary_height = 0;
1466     GetMixerResolution(&primary_width, &primary_height);
1467 
1468     LayerBuffer *layer_buffer = solid_fill_layer_->input_buffer;
1469     layer_buffer->width = primary_width;
1470     layer_buffer->height = primary_height;
1471     layer_buffer->acquire_fence_fd = -1;
1472     layer_buffer->release_fence_fd = -1;
1473 
1474     LayerRect rect;
1475     rect.top = 0; rect.left = 0;
1476     rect.right = primary_width;
1477     rect.bottom = primary_height;
1478 
1479     solid_fill_layer_->composition = kCompositionGPU;
1480     solid_fill_layer_->src_rect = rect;
1481     solid_fill_layer_->dst_rect = rect;
1482 
1483     solid_fill_layer_->blending = kBlendingPremultiplied;
1484     solid_fill_layer_->solid_fill_color = solid_fill_color_;
1485     solid_fill_layer_->frame_rate = 60;
1486     solid_fill_layer_->visible_regions.push_back(solid_fill_layer_->dst_rect);
1487     solid_fill_layer_->flags.updating = 1;
1488     solid_fill_layer_->flags.solid_fill = true;
1489   } else {
1490     // delete the dummy layer
1491     if (solid_fill_layer_) {
1492       delete solid_fill_layer_->input_buffer;
1493     }
1494     delete solid_fill_layer_;
1495     solid_fill_layer_ = NULL;
1496   }
1497 
1498   if (solid_fill_enable_ && solid_fill_layer_) {
1499     BuildSolidFillStack();
1500     MarkLayersForGPUBypass();
1501   }
1502 
1503   return;
1504 }
1505 
SolidFillCommit()1506 void HWCDisplay::SolidFillCommit() {
1507   if (solid_fill_enable_ && solid_fill_layer_) {
1508     LayerBuffer *layer_buffer = solid_fill_layer_->input_buffer;
1509     if (layer_buffer->release_fence_fd > 0) {
1510       close(layer_buffer->release_fence_fd);
1511       layer_buffer->release_fence_fd = -1;
1512     }
1513     if (layer_stack_.retire_fence_fd > 0) {
1514       close(layer_stack_.retire_fence_fd);
1515       layer_stack_.retire_fence_fd = -1;
1516     }
1517   }
1518 }
1519 
GetVisibleDisplayRect(hwc_rect_t * visible_rect)1520 int HWCDisplay::GetVisibleDisplayRect(hwc_rect_t *visible_rect) {
1521   if (!IsValid(display_rect_)) {
1522     return -EINVAL;
1523   }
1524 
1525   visible_rect->left = INT(display_rect_.left);
1526   visible_rect->top = INT(display_rect_.top);
1527   visible_rect->right = INT(display_rect_.right);
1528   visible_rect->bottom = INT(display_rect_.bottom);
1529   DLOGI("Dpy = %d Visible Display Rect(%d %d %d %d)", visible_rect->left, visible_rect->top,
1530         visible_rect->right, visible_rect->bottom);
1531 
1532   return 0;
1533 }
1534 
SetSecureDisplay(bool secure_display_active)1535 void HWCDisplay::SetSecureDisplay(bool secure_display_active) {
1536   secure_display_active_ = secure_display_active;
1537   return;
1538 }
1539 
SetActiveDisplayConfig(int config)1540 int HWCDisplay::SetActiveDisplayConfig(int config) {
1541   return display_intf_->SetActiveConfig(UINT32(config)) == kErrorNone ? 0 : -1;
1542 }
1543 
GetActiveDisplayConfig(uint32_t * config)1544 int HWCDisplay::GetActiveDisplayConfig(uint32_t *config) {
1545   return display_intf_->GetActiveConfig(config) == kErrorNone ? 0 : -1;
1546 }
1547 
GetDisplayConfigCount(uint32_t * count)1548 int HWCDisplay::GetDisplayConfigCount(uint32_t *count) {
1549   return display_intf_->GetNumVariableInfoConfigs(count) == kErrorNone ? 0 : -1;
1550 }
1551 
GetDisplayAttributesForConfig(int config,DisplayConfigVariableInfo * display_attributes)1552 int HWCDisplay::GetDisplayAttributesForConfig(int config,
1553                                             DisplayConfigVariableInfo *display_attributes) {
1554   return display_intf_->GetConfig(UINT32(config), display_attributes) == kErrorNone ? 0 : -1;
1555 }
1556 
SingleLayerUpdating(void)1557 bool HWCDisplay::SingleLayerUpdating(void) {
1558   uint32_t updating_count = 0;
1559 
1560   for (uint i = 0; i < layer_stack_.layers.size(); i++) {
1561     auto layer = layer_stack_.layers.at(i);
1562     if (layer->flags.updating) {
1563       updating_count++;
1564     }
1565   }
1566 
1567   return (updating_count == 1);
1568 }
1569 
IsLayerUpdating(const Layer * layer)1570 bool HWCDisplay::IsLayerUpdating(const Layer *layer) {
1571   // Layer should be considered updating if
1572   //   a) layer is in single buffer mode, or
1573   //   b) valid dirty_regions(android specific hint for updating status), or
1574   //   c) layer stack geometry has changed (TODO(user): Remove when SDM accepts
1575   //      geometry_changed as bit fields).
1576   return (layer->flags.single_buffer || IsSurfaceUpdated(layer->dirty_regions) ||
1577           geometry_changes_);
1578 }
1579 
IsSurfaceUpdated(const std::vector<LayerRect> & dirty_regions)1580 bool HWCDisplay::IsSurfaceUpdated(const std::vector<LayerRect> &dirty_regions) {
1581   // based on dirty_regions determine if its updating
1582   // dirty_rect count = 0 - whole layer - updating.
1583   // dirty_rect count = 1 or more valid rects - updating.
1584   // dirty_rect count = 1 with (0,0,0,0) - not updating.
1585   return (dirty_regions.empty() || IsValid(dirty_regions.at(0)));
1586 }
1587 
SanitizeRefreshRate(uint32_t req_refresh_rate)1588 uint32_t HWCDisplay::SanitizeRefreshRate(uint32_t req_refresh_rate) {
1589   uint32_t refresh_rate = req_refresh_rate;
1590 
1591   if (refresh_rate < min_refresh_rate_) {
1592     // Pick the next multiple of request which is within the range
1593     refresh_rate =
1594         (((min_refresh_rate_ / refresh_rate) + ((min_refresh_rate_ % refresh_rate) ? 1 : 0)) *
1595          refresh_rate);
1596   }
1597 
1598   if (refresh_rate > max_refresh_rate_) {
1599     refresh_rate = max_refresh_rate_;
1600   }
1601 
1602   return refresh_rate;
1603 }
1604 
GetDisplayClass()1605 DisplayClass HWCDisplay::GetDisplayClass() {
1606   return display_class_;
1607 }
1608 
CloseAcquireFds()1609 void HWCDisplay::CloseAcquireFds() {
1610   for (auto hwc_layer : layer_set_) {
1611     auto layer = hwc_layer->GetSDMLayer();
1612     if (layer->input_buffer->acquire_fence_fd >= 0) {
1613       close(layer->input_buffer->acquire_fence_fd);
1614       layer->input_buffer->acquire_fence_fd = -1;
1615     }
1616   }
1617   int32_t &client_target_acquire_fence =
1618       client_target_->GetSDMLayer()->input_buffer->acquire_fence_fd;
1619   if (client_target_acquire_fence >= 0) {
1620     close(client_target_acquire_fence);
1621     client_target_acquire_fence = -1;
1622   }
1623 }
1624 
Dump()1625 std::string HWCDisplay::Dump() {
1626   std::ostringstream os;
1627   os << "-------------------------------" << std::endl;
1628   os << "HWC2 LayerDump display_id: " << id_ << std::endl;
1629   for (auto layer : layer_set_) {
1630     auto sdm_layer = layer->GetSDMLayer();
1631     auto transform = sdm_layer->transform;
1632     os << "-------------------------------" << std::endl;
1633     os << "layer_id: " << layer->GetId() << std::endl;
1634     os << "\tz: " << layer->GetZ() << std::endl;
1635     os << "\tclient(SF) composition: " <<
1636           to_string(layer->GetClientRequestedCompositionType()).c_str() << std::endl;
1637     os << "\tdevice(SDM) composition: " <<
1638           to_string(layer->GetDeviceSelectedCompositionType()).c_str() << std::endl;
1639     os << "\tplane_alpha: " << std::to_string(sdm_layer->plane_alpha).c_str() << std::endl;
1640     os << "\tformat: " << GetFormatString(sdm_layer->input_buffer->format) << std::endl;
1641     os << "\ttransform: rot: " << transform.rotation << " flip_h: " << transform.flip_horizontal <<
1642           " flip_v: "<< transform.flip_vertical << std::endl;
1643     os << "\tbuffer_id: " << std::hex << "0x" << sdm_layer->input_buffer->buffer_id << std::dec
1644        << std::endl;
1645   }
1646   return os.str();
1647 }
1648 }  // namespace sdm
1649