display: msm8996: Update display HAL to SU27 + HWC2 specific commits
display_hal:
75f1caf sdm: hwc2: Handle Tranform::None
2857687 hwc2: Ignore empty layer sets
da95cbe hwc2: Always set the retire fence in present()
f50eda4 sdm: hwc2: Set transform correctly
0d4053d sdm: Move HPD enable to Primary device Initialization
a4ebb36 sdm: Reserve one byte for NULL terminating character.
9a3dde8 Promotion of display.lnx.3.0-00027.
Bug: 29463310
Change-Id: I1dfd2b58b7587ee0b2ebc6e1c3d6ed0640405296
diff --git a/msm8996/common.mk b/msm8996/common.mk
index 228f742..6b3e2e9 100644
--- a/msm8996/common.mk
+++ b/msm8996/common.mk
@@ -2,6 +2,9 @@
display_top := $(call my-dir)
use_hwc2 := false
+ifeq ($(TARGET_USES_HWC2), true)
+ use_hwc2 := true
+endif
common_includes := $(display_top)/libqdutils
common_includes += $(display_top)/libqservice
diff --git a/msm8996/sdm/libs/core/display_base.cpp b/msm8996/sdm/libs/core/display_base.cpp
index d9583b7..aa50b7a 100644
--- a/msm8996/sdm/libs/core/display_base.cpp
+++ b/msm8996/sdm/libs/core/display_base.cpp
@@ -920,6 +920,10 @@
return SetMixerResolutionLocked(width, height);
}
+DisplayError DisplayBase::SetMixerResolutionLocked(uint32_t width, uint32_t height) {
+ return ReconfigureMixer(width, height);
+}
+
DisplayError DisplayBase::GetMixerResolution(uint32_t *width, uint32_t *height) {
SCOPE_LOCK(locker_);
return GetMixerResolutionLocked(width, height);
@@ -936,6 +940,89 @@
return kErrorNone;
}
+DisplayError DisplayBase::ReconfigureMixer(uint32_t width, uint32_t height) {
+ DisplayError error = kErrorNone;
+
+ HWMixerAttributes mixer_attributes;
+ mixer_attributes.width = width;
+ mixer_attributes.height = height;
+
+ error = hw_intf_->SetMixerAttributes(mixer_attributes);
+ if (error != kErrorNone) {
+ return error;
+ }
+
+ return ReconfigureDisplay();
+}
+
+bool DisplayBase::NeedsMixerReconfiguration(LayerStack *layer_stack, uint32_t *new_mixer_width,
+ uint32_t *new_mixer_height) {
+ uint32_t layer_count = UINT32(layer_stack->layers.size());
+
+ uint32_t fb_width = fb_config_.x_pixels;
+ uint32_t fb_height = fb_config_.y_pixels;
+ uint32_t fb_area = fb_width * fb_height;
+ LayerRect fb_rect = (LayerRect) {0.0f, 0.0f, FLOAT(fb_width), FLOAT(fb_height)};
+ uint32_t mixer_width = mixer_attributes_.width;
+ uint32_t mixer_height = mixer_attributes_.height;
+
+ RectOrientation fb_orientation = GetOrientation(fb_rect);
+ uint32_t max_layer_area = 0;
+ uint32_t max_area_layer_index = 0;
+ std::vector<Layer *> layers = layer_stack->layers;
+
+ for (uint32_t i = 0; i < layer_count; i++) {
+ Layer *layer = layers.at(i);
+ LayerBuffer *layer_buffer = layer->input_buffer;
+
+ if (!layer_buffer->flags.video) {
+ continue;
+ }
+
+ uint32_t layer_width = UINT32(layer->src_rect.right - layer->src_rect.left);
+ uint32_t layer_height = UINT32(layer->src_rect.bottom - layer->src_rect.top);
+ uint32_t layer_area = layer_width * layer_height;
+
+ if (layer_area > max_layer_area) {
+ max_layer_area = layer_area;
+ max_area_layer_index = i;
+ }
+ }
+
+ if (max_layer_area > fb_area) {
+ Layer *layer = layers.at(max_area_layer_index);
+
+ uint32_t layer_width = UINT32(layer->src_rect.right - layer->src_rect.left);
+ uint32_t layer_height = UINT32(layer->src_rect.bottom - layer->src_rect.top);
+ LayerRect layer_rect = (LayerRect){0.0f, 0.0f, FLOAT(layer_width), FLOAT(layer_height)};
+
+ RectOrientation layer_orientation = GetOrientation(layer_rect);
+ if (layer_orientation != kOrientationUnknown &&
+ fb_orientation != kOrientationUnknown) {
+ if (layer_orientation != fb_orientation) {
+ Swap(layer_width, layer_height);
+ }
+ }
+
+ // Align the width and height according to fb's aspect ratio
+ layer_width = UINT32((FLOAT(fb_width) / FLOAT(fb_height)) * layer_height);
+
+ *new_mixer_width = layer_width;
+ *new_mixer_height = layer_height;
+
+ return true;
+ } else {
+ if (fb_width != mixer_width || fb_height != mixer_height) {
+ *new_mixer_width = fb_width;
+ *new_mixer_height = fb_height;
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
DisplayError DisplayBase::SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info) {
SCOPE_LOCK(locker_);
return SetFrameBufferConfigLocked(variable_info);
@@ -997,4 +1084,15 @@
return SetDetailEnhancerDataLocked(de_data);
}
+DisplayError DisplayBase::SetDetailEnhancerDataLocked(const DisplayDetailEnhancerData &de_data) {
+ DisplayError error = comp_manager_->SetDetailEnhancerData(display_comp_ctx_, de_data);
+ if (error != kErrorNone) {
+ return error;
+ }
+
+ DisablePartialUpdateOneFrameLocked();
+
+ return kErrorNone;
+}
+
} // namespace sdm
diff --git a/msm8996/sdm/libs/core/display_base.h b/msm8996/sdm/libs/core/display_base.h
index 1672351..a9f1c3d 100644
--- a/msm8996/sdm/libs/core/display_base.h
+++ b/msm8996/sdm/libs/core/display_base.h
@@ -103,15 +103,11 @@
virtual DisplayError DisablePartialUpdateOneFrameLocked() {
return kErrorNotSupported;
}
- virtual DisplayError SetMixerResolutionLocked(uint32_t width, uint32_t height) {
- return kErrorNotSupported;
- }
+ virtual DisplayError SetMixerResolutionLocked(uint32_t width, uint32_t height);
virtual DisplayError GetMixerResolutionLocked(uint32_t *width, uint32_t *height);
virtual DisplayError SetFrameBufferConfigLocked(const DisplayConfigVariableInfo &variable_info);
virtual DisplayError GetFrameBufferConfigLocked(DisplayConfigVariableInfo *variable_info);
- virtual DisplayError SetDetailEnhancerDataLocked(const DisplayDetailEnhancerData &de_data) {
- return kErrorNotSupported;
- }
+ virtual DisplayError SetDetailEnhancerDataLocked(const DisplayDetailEnhancerData &de_data);
// DumpImpl method
void AppendDump(char *buffer, uint32_t length);
@@ -120,6 +116,10 @@
const char *GetName(const LayerComposition &composition);
DisplayError ValidateGPUTarget(LayerStack *layer_stack);
DisplayError ReconfigureDisplay();
+ bool NeedsMixerReconfiguration(LayerStack *layer_stack, uint32_t *new_mixer_width,
+ uint32_t *new_mixer_height);
+ DisplayError ReconfigureMixer(uint32_t width, uint32_t height);
+
Locker locker_;
DisplayType display_type_;
diff --git a/msm8996/sdm/libs/core/display_hdmi.cpp b/msm8996/sdm/libs/core/display_hdmi.cpp
index 11c268a..0eeff0a 100644
--- a/msm8996/sdm/libs/core/display_hdmi.cpp
+++ b/msm8996/sdm/libs/core/display_hdmi.cpp
@@ -107,6 +107,19 @@
}
DisplayError DisplayHDMI::PrepareLocked(LayerStack *layer_stack) {
+ DisplayError error = kErrorNone;
+ uint32_t new_mixer_width = 0;
+ uint32_t new_mixer_height = 0;
+ uint32_t display_width = display_attributes_.x_pixels;
+ uint32_t display_height = display_attributes_.y_pixels;
+
+ if (NeedsMixerReconfiguration(layer_stack, &new_mixer_width, &new_mixer_height)) {
+ error = ReconfigureMixer(new_mixer_width, new_mixer_height);
+ if (error != kErrorNone) {
+ ReconfigureMixer(display_width, display_height);
+ }
+ }
+
SetS3DMode(layer_stack);
return DisplayBase::PrepareLocked(layer_stack);
diff --git a/msm8996/sdm/libs/core/display_primary.cpp b/msm8996/sdm/libs/core/display_primary.cpp
index 70b96fe..41e4c29 100644
--- a/msm8996/sdm/libs/core/display_primary.cpp
+++ b/msm8996/sdm/libs/core/display_primary.cpp
@@ -361,103 +361,5 @@
return kErrorNone;
}
-DisplayError DisplayPrimary::SetMixerResolutionLocked(uint32_t width, uint32_t height) {
- return ReconfigureMixer(width, height);
-}
-
-DisplayError DisplayPrimary::ReconfigureMixer(uint32_t width, uint32_t height) {
- DisplayError error = kErrorNone;
-
- HWMixerAttributes mixer_attributes;
- mixer_attributes.width = width;
- mixer_attributes.height = height;
-
- error = hw_intf_->SetMixerAttributes(mixer_attributes);
- if (error != kErrorNone) {
- return error;
- }
-
- return DisplayBase::ReconfigureDisplay();
-}
-
-bool DisplayPrimary::NeedsMixerReconfiguration(LayerStack *layer_stack, uint32_t *new_mixer_width,
- uint32_t *new_mixer_height) {
- uint32_t layer_count = UINT32(layer_stack->layers.size());
-
- uint32_t fb_width = fb_config_.x_pixels;
- uint32_t fb_height = fb_config_.y_pixels;
- uint32_t fb_area = fb_width * fb_height;
- LayerRect fb_rect = (LayerRect) {0.0f, 0.0f, FLOAT(fb_width), FLOAT(fb_height)};
- uint32_t mixer_width = mixer_attributes_.width;
- uint32_t mixer_height = mixer_attributes_.height;
-
- RectOrientation fb_orientation = GetOrientation(fb_rect);
- uint32_t max_layer_area = 0;
- uint32_t max_area_layer_index = 0;
- std::vector<Layer *> layers = layer_stack->layers;
-
- for (uint32_t i = 0; i < layer_count; i++) {
- Layer *layer = layers.at(i);
- LayerBuffer *layer_buffer = layer->input_buffer;
-
- if (!layer_buffer->flags.video) {
- continue;
- }
-
- uint32_t layer_width = UINT32(layer->src_rect.right - layer->src_rect.left);
- uint32_t layer_height = UINT32(layer->src_rect.bottom - layer->src_rect.top);
- uint32_t layer_area = layer_width * layer_height;
-
- if (layer_area > max_layer_area) {
- max_layer_area = layer_area;
- max_area_layer_index = i;
- }
- }
-
- if (max_layer_area > fb_area) {
- Layer *layer = layers.at(max_area_layer_index);
-
- uint32_t layer_width = UINT32(layer->src_rect.right - layer->src_rect.left);
- uint32_t layer_height = UINT32(layer->src_rect.bottom - layer->src_rect.top);
- LayerRect layer_rect = (LayerRect){0.0f, 0.0f, FLOAT(layer_width), FLOAT(layer_height)};
-
- RectOrientation layer_orientation = GetOrientation(layer_rect);
- if (layer_orientation != kOrientationUnknown &&
- fb_orientation != kOrientationUnknown) {
- if (layer_orientation != fb_orientation) {
- Swap(layer_width, layer_height);
- }
- }
-
- // Align the width and height according to fb's aspect ratio
- layer_width = UINT32((FLOAT(fb_width) / FLOAT(fb_height)) * layer_height);
-
- *new_mixer_width = layer_width;
- *new_mixer_height = layer_height;
-
- return true;
- } else {
- if (fb_width != mixer_width || fb_height != mixer_height) {
- *new_mixer_width = fb_width;
- *new_mixer_height = fb_height;
-
- return true;
- }
- }
-
- return false;
-}
-
-DisplayError DisplayPrimary::SetDetailEnhancerDataLocked(const DisplayDetailEnhancerData &de_data) {
- DisplayError error = comp_manager_->SetDetailEnhancerData(display_comp_ctx_, de_data);
- if (error != kErrorNone) {
- return error;
- }
-
- DisablePartialUpdateOneFrameLocked();
-
- return kErrorNone;
-}
-
} // namespace sdm
diff --git a/msm8996/sdm/libs/core/display_primary.h b/msm8996/sdm/libs/core/display_primary.h
index f029961..92e6c88 100644
--- a/msm8996/sdm/libs/core/display_primary.h
+++ b/msm8996/sdm/libs/core/display_primary.h
@@ -72,12 +72,6 @@
virtual DisplayError CommitLocked(LayerStack *layer_stack);
virtual DisplayError ControlPartialUpdateLocked(bool enable, uint32_t *pending);
virtual DisplayError DisablePartialUpdateOneFrameLocked();
- virtual DisplayError SetMixerResolutionLocked(uint32_t width, uint32_t height);
- virtual DisplayError SetDetailEnhancerDataLocked(const DisplayDetailEnhancerData &de_data);
-
- bool NeedsMixerReconfiguration(LayerStack *layer_stack, uint32_t *new_mixer_width,
- uint32_t *new_mixer_height);
- DisplayError ReconfigureMixer(uint32_t width, uint32_t height);
uint32_t idle_timeout_ms_ = 0;
std::vector<const char *> event_list_ = {"vsync_event", "show_blank_event", "idle_notify",
diff --git a/msm8996/sdm/libs/core/display_virtual.h b/msm8996/sdm/libs/core/display_virtual.h
index ba164ae..59334a7 100644
--- a/msm8996/sdm/libs/core/display_virtual.h
+++ b/msm8996/sdm/libs/core/display_virtual.h
@@ -63,6 +63,15 @@
return kErrorNotSupported;
}
virtual DisplayError SetActiveConfigLocked(DisplayConfigVariableInfo *variable_info);
+ virtual DisplayError SetMixerResolutionLocked(uint32_t width, uint32_t height) {
+ return kErrorNotSupported;
+ }
+ virtual DisplayError GetMixerResolutionLocked(uint32_t *width, uint32_t *height) {
+ return kErrorNotSupported;
+ }
+ virtual DisplayError SetDetailEnhancerDataLocked(const DisplayDetailEnhancerData &de_data) {
+ return kErrorNotSupported;
+ }
};
} // namespace sdm
diff --git a/msm8996/sdm/libs/core/dump_impl.cpp b/msm8996/sdm/libs/core/dump_impl.cpp
index 0d6c9b2..655b210 100644
--- a/msm8996/sdm/libs/core/dump_impl.cpp
+++ b/msm8996/sdm/libs/core/dump_impl.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014, 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
@@ -59,14 +59,15 @@
void DumpImpl::AppendString(char *buffer, uint32_t length, const char *format, ...) {
uint32_t filled = UINT32(strlen(buffer));
- if (filled >= length) {
+ // Reserve one byte for null terminating character
+ if ((filled + 1) >= length) {
return;
}
buffer += filled;
va_list list;
va_start(list, format);
- vsnprintf(buffer, length - filled, format, list);
+ vsnprintf(buffer, length - filled -1, format, list);
}
// Every object is created or destroyed through display core only, which itself protects the
diff --git a/msm8996/sdm/libs/core/fb/hw_device.cpp b/msm8996/sdm/libs/core/fb/hw_device.cpp
index 6b7dd2e..641a27e 100644
--- a/msm8996/sdm/libs/core/fb/hw_device.cpp
+++ b/msm8996/sdm/libs/core/fb/hw_device.cpp
@@ -54,7 +54,7 @@
namespace sdm {
HWDevice::HWDevice(BufferSyncHandler *buffer_sync_handler)
- : fb_node_index_(-1), fb_path_("/sys/devices/virtual/graphics/fb"), hotplug_enabled_(false),
+ : fb_node_index_(-1), fb_path_("/sys/devices/virtual/graphics/fb"),
buffer_sync_handler_(buffer_sync_handler), synchronous_commit_(false) {
}
@@ -135,11 +135,6 @@
return kErrorHardware;
}
- // Need to turn on HPD
- if (!hotplug_enabled_) {
- hotplug_enabled_ = EnableHotPlugDetection(1);
- }
-
return kErrorNone;
}
@@ -282,6 +277,40 @@
DLOGI_IF(kTagDriverConfig, "*****************************************************************");
}
+ uint32_t index = 0;
+ for (uint32_t i = 0; i < hw_resource_.hw_dest_scalar_info.count; i++) {
+ DestScaleInfoMap::iterator it = hw_layer_info.dest_scale_info_map.find(i);
+
+ if (it == hw_layer_info.dest_scale_info_map.end()) {
+ continue;
+ }
+
+ HWDestScaleInfo *dest_scale_info = it->second;
+
+ mdp_destination_scaler_data *dest_scalar_data = &mdp_dest_scalar_data_[index];
+ hw_scale_->SetHWScaleData(dest_scale_info->scale_data, index, &mdp_commit,
+ kHWDestinationScalar);
+
+ if (dest_scale_info->scale_update) {
+ dest_scalar_data->flags |= MDP_DESTSCALER_SCALE_UPDATE;
+ }
+
+ dest_scalar_data->dest_scaler_ndx = i;
+ dest_scalar_data->lm_width = dest_scale_info->mixer_width;
+ dest_scalar_data->lm_height = dest_scale_info->mixer_height;
+ dest_scalar_data->scale = reinterpret_cast <uint64_t>
+ (hw_scale_->GetScaleDataRef(index, kHWDestinationScalar));
+
+ index++;
+
+ DLOGV_IF(kTagDriverConfig, "************************ DestScalar[%d] **************************",
+ dest_scalar_data->dest_scaler_ndx);
+ DLOGV_IF(kTagDriverConfig, "Mixer WxH %dx%d", dest_scalar_data->lm_width,
+ dest_scalar_data->lm_height);
+ DLOGI_IF(kTagDriverConfig, "*****************************************************************");
+ }
+ mdp_commit.dest_scaler_cnt = UINT32(hw_layer_info.dest_scale_info_map.size());
+
mdp_commit.flags |= MDP_VALIDATE_LAYER;
if (Sys::ioctl_(device_fd_, INT(MSMFB_ATOMIC_COMMIT), &mdp_disp_commit_) < 0) {
if (errno == ESHUTDOWN) {
@@ -947,6 +976,7 @@
}
void HWDevice::ResetDisplayParams() {
+ uint32_t dst_scalar_cnt = hw_resource_.hw_dest_scalar_info.count;
memset(&mdp_disp_commit_, 0, sizeof(mdp_disp_commit_));
memset(&mdp_in_layers_, 0, sizeof(mdp_in_layers_));
memset(&mdp_out_layer_, 0, sizeof(mdp_out_layer_));
@@ -955,6 +985,10 @@
memset(&pp_params_, 0, sizeof(pp_params_));
memset(&igc_lut_data_, 0, sizeof(igc_lut_data_));
+ if (mdp_dest_scalar_data_) {
+ memset(mdp_dest_scalar_data_, 0, sizeof(mdp_dest_scalar_data_) * dst_scalar_cnt);
+ }
+
for (uint32_t i = 0; i < kMaxSDELayers * 2; i++) {
mdp_in_layers_[i].buffer.fence = -1;
}
@@ -964,6 +998,7 @@
mdp_disp_commit_.commit_v1.output_layer = &mdp_out_layer_;
mdp_disp_commit_.commit_v1.release_fence = -1;
mdp_disp_commit_.commit_v1.retire_fence = -1;
+ mdp_disp_commit_.commit_v1.dest_scaler = mdp_dest_scalar_data_;
}
void HWDevice::SetCSC(LayerCSC source, mdp_color_space *color_space) {
@@ -1135,5 +1170,69 @@
return kErrorNone;
}
+DisplayError HWDevice::SetMixerAttributes(const HWMixerAttributes &mixer_attributes) {
+ if (!hw_resource_.hw_dest_scalar_info.count) {
+ return kErrorNotSupported;
+ }
+
+ if (mixer_attributes.width > display_attributes_.x_pixels ||
+ mixer_attributes.height > display_attributes_.y_pixels) {
+ DLOGW("Input resolution exceeds display resolution! input: res %dx%d display: res %dx%d",
+ mixer_attributes.width, mixer_attributes.height, display_attributes_.x_pixels,
+ display_attributes_.y_pixels);
+ return kErrorNotSupported;
+ }
+
+ uint32_t max_input_width = hw_resource_.hw_dest_scalar_info.max_input_width;
+ if (display_attributes_.is_device_split) {
+ max_input_width *= 2;
+ }
+
+ if (mixer_attributes.width > max_input_width) {
+ DLOGW("Input width exceeds width limit! input_width %d width_limit %d", mixer_attributes.width,
+ max_input_width);
+ return kErrorNotSupported;
+ }
+
+ float mixer_aspect_ratio = FLOAT(mixer_attributes.width) / FLOAT(mixer_attributes.height);
+ float display_aspect_ratio =
+ FLOAT(display_attributes_.x_pixels) / FLOAT(display_attributes_.y_pixels);
+
+ if (display_aspect_ratio != mixer_aspect_ratio) {
+ DLOGW("Aspect ratio mismatch! input: res %dx%d display: res %dx%d", mixer_attributes.width,
+ mixer_attributes.height, display_attributes_.x_pixels, display_attributes_.y_pixels);
+ return kErrorNotSupported;
+ }
+
+ float scale_x = FLOAT(display_attributes_.x_pixels) / FLOAT(mixer_attributes.width);
+ float scale_y = FLOAT(display_attributes_.y_pixels) / FLOAT(mixer_attributes.height);
+ float max_scale_up = hw_resource_.hw_dest_scalar_info.max_scale_up;
+ if (scale_x > max_scale_up || scale_y > max_scale_up) {
+ DLOGW("Up scaling ratio exceeds for destination scalar upscale limit scale_x %f scale_y %f " \
+ "max_scale_up %f", scale_x, scale_y, max_scale_up);
+ return kErrorNotSupported;
+ }
+
+ float mixer_split_ratio = FLOAT(mixer_attributes_.split_left) / FLOAT(mixer_attributes_.width);
+
+ mixer_attributes_ = mixer_attributes;
+ mixer_attributes_.split_left = mixer_attributes_.width;
+ if (display_attributes_.is_device_split) {
+ mixer_attributes_.split_left = UINT32(FLOAT(mixer_attributes.width) * mixer_split_ratio);
+ }
+
+ return kErrorNone;
+}
+
+DisplayError HWDevice::GetMixerAttributes(HWMixerAttributes *mixer_attributes) {
+ if (!mixer_attributes) {
+ return kErrorParameters;
+ }
+
+ *mixer_attributes = mixer_attributes_;
+
+ return kErrorNone;
+}
+
} // namespace sdm
diff --git a/msm8996/sdm/libs/core/fb/hw_device.h b/msm8996/sdm/libs/core/fb/hw_device.h
index d5b18de..fc473ff 100644
--- a/msm8996/sdm/libs/core/fb/hw_device.h
+++ b/msm8996/sdm/libs/core/fb/hw_device.h
@@ -84,12 +84,8 @@
virtual DisplayError SetAutoRefresh(bool enable) { return kErrorNone; }
virtual DisplayError SetS3DMode(HWS3DMode s3d_mode);
virtual DisplayError SetScaleLutConfig(HWScaleLutInfo *lut_info);
- virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes) {
- return kErrorNotSupported;
- }
- virtual DisplayError GetMixerAttributes(HWMixerAttributes *mixer_attributes) {
- return kErrorNotSupported;
- }
+ virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes);
+ virtual DisplayError GetMixerAttributes(HWMixerAttributes *mixer_attributes);
// For HWDevice derivatives
virtual DisplayError Init();
@@ -135,7 +131,6 @@
HWInfoInterface *hw_info_intf_;
int fb_node_index_;
const char *fb_path_;
- bool hotplug_enabled_;
BufferSyncHandler *buffer_sync_handler_;
int device_fd_;
HWDeviceType device_type_;
@@ -147,6 +142,9 @@
mdp_output_layer mdp_out_layer_;
const char *device_name_;
bool synchronous_commit_;
+ HWDisplayAttributes display_attributes_ = {};
+ HWMixerAttributes mixer_attributes_ = {};
+ mdp_destination_scaler_data *mdp_dest_scalar_data_ = NULL;
};
} // namespace sdm
diff --git a/msm8996/sdm/libs/core/fb/hw_hdmi.cpp b/msm8996/sdm/libs/core/fb/hw_hdmi.cpp
index 3dfac8a..ab4e2ba 100644
--- a/msm8996/sdm/libs/core/fb/hw_hdmi.cpp
+++ b/msm8996/sdm/libs/core/fb/hw_hdmi.cpp
@@ -119,6 +119,11 @@
return error;
}
+ uint32_t dest_scalar_count = hw_resource_.hw_dest_scalar_info.count;
+ if (dest_scalar_count) {
+ mdp_dest_scalar_data_ = new mdp_destination_scaler_data[dest_scalar_count];
+ }
+
error = ReadEDIDInfo();
if (error != kErrorNone) {
Deinit();
@@ -165,6 +170,8 @@
delete[] supported_video_modes_;
}
+ delete [] mdp_dest_scalar_data_;
+
return HWDevice::Deinit();
}
@@ -252,6 +259,7 @@
display_attributes->y_dpi = 0;
display_attributes->fps = timing_mode->refresh_rate / 1000;
display_attributes->vsync_period_ns = UINT32(1000000000L / display_attributes->fps);
+ display_attributes->is_device_split = false;
if (display_attributes->x_pixels > hw_resource_.max_mixer_width) {
display_attributes->is_device_split = true;
display_attributes->h_total += h_blanking;
@@ -318,13 +326,14 @@
frame_rate_ = timing_mode->refresh_rate;
- // Get the supported s3d modes for current active config index
- HWDisplayAttributes attrib;
- GetDisplayS3DSupport(index, &attrib);
+ // Get the display attributes for current active config index
+ GetDisplayAttributes(active_config_index_, &display_attributes_);
+ UpdateMixerAttributes();
+
supported_s3d_modes_.clear();
supported_s3d_modes_.push_back(kS3DModeNone);
for (uint32_t mode = kS3DModeNone + 1; mode < kS3DModeMax; mode ++) {
- if (IS_BIT_SET(attrib.s3d_config, (HWS3DMode)mode)) {
+ if (IS_BIT_SET(display_attributes_.s3d_config, (HWS3DMode)mode)) {
supported_s3d_modes_.push_back((HWS3DMode)mode);
}
}
@@ -748,25 +757,19 @@
return error;
}
+ GetDisplayAttributes(active_config_index_, &display_attributes_);
+ UpdateMixerAttributes();
+
frame_rate_ = refresh_rate;
return kErrorNone;
}
-DisplayError HWHDMI::GetMixerAttributes(HWMixerAttributes *mixer_attributes) {
- if (!mixer_attributes) {
- return kErrorParameters;
- }
-
- HWDisplayAttributes display_attributes;
- GetDisplayAttributes(active_config_index_, &display_attributes);
-
- mixer_attributes->width = display_attributes.x_pixels;
- mixer_attributes->height = display_attributes.y_pixels;
- mixer_attributes->split_left = display_attributes.is_device_split ?
- (display_attributes.x_pixels / 2) : mixer_attributes->width;
-
- return kErrorNone;
+void HWHDMI::UpdateMixerAttributes() {
+ mixer_attributes_.width = display_attributes_.x_pixels;
+ mixer_attributes_.height = display_attributes_.y_pixels;
+ mixer_attributes_.split_left = display_attributes_.is_device_split ?
+ (display_attributes_.x_pixels / 2) : mixer_attributes_.width;
}
} // namespace sdm
diff --git a/msm8996/sdm/libs/core/fb/hw_hdmi.h b/msm8996/sdm/libs/core/fb/hw_hdmi.h
index 833b3d3..2845708 100644
--- a/msm8996/sdm/libs/core/fb/hw_hdmi.h
+++ b/msm8996/sdm/libs/core/fb/hw_hdmi.h
@@ -69,7 +69,6 @@
virtual DisplayError Validate(HWLayers *hw_layers);
virtual DisplayError SetS3DMode(HWS3DMode s3d_mode);
virtual DisplayError SetRefreshRate(uint32_t refresh_rate);
- virtual DisplayError GetMixerAttributes(HWMixerAttributes *mixer_attributes);
private:
DisplayError ReadEDIDInfo();
@@ -84,6 +83,7 @@
DisplayError GetDisplayS3DSupport(uint32_t num_modes,
HWDisplayAttributes *attrib);
bool IsSupportedS3DMode(HWS3DMode s3d_mode);
+ void UpdateMixerAttributes();
uint32_t hdmi_mode_count_;
uint32_t hdmi_modes_[256];
diff --git a/msm8996/sdm/libs/core/fb/hw_info.cpp b/msm8996/sdm/libs/core/fb/hw_info.cpp
index 25bb01c..a1a928c 100644
--- a/msm8996/sdm/libs/core/fb/hw_info.cpp
+++ b/msm8996/sdm/libs/core/fb/hw_info.cpp
@@ -554,7 +554,7 @@
size_t len = kMaxStringLength;
ssize_t read;
- FILE *fileptr = Sys::fopen_("/sys/class/graphics/fb0/msm_fb_type", "r");
+ FILE *fileptr = Sys::fopen_("/sys/devices/virtual/graphics/fb0/msm_fb_type", "r");
if (!fileptr) {
free(stringbuffer);
return kErrorHardware;
@@ -570,13 +570,13 @@
}
} else {
free(stringbuffer);
- fclose(fileptr);
+ Sys::fclose_(fileptr);
return kErrorHardware;
}
- fclose(fileptr);
+ Sys::fclose_(fileptr);
- fileptr = Sys::fopen_("/sys/class/graphics/fb0/connected", "r");
+ fileptr = Sys::fopen_("/sys/devices/virtual/graphics/fb0/connected", "r");
if (!fileptr) {
// If fb0 is for a DSI/connected panel, then connected node will not exist
hw_disp_info->is_connected = true;
@@ -584,11 +584,11 @@
if ((read = Sys::getline_(&line, &len, fileptr)) != -1) {
hw_disp_info->is_connected = (!strncmp(line, "1", strlen("1")));
} else {
- fclose(fileptr);
+ Sys::fclose_(fileptr);
free(stringbuffer);
return kErrorHardware;
}
- fclose(fileptr);
+ Sys::fclose_(fileptr);
}
free(stringbuffer);
diff --git a/msm8996/sdm/libs/core/fb/hw_primary.cpp b/msm8996/sdm/libs/core/fb/hw_primary.cpp
index 3d0c776..115a9c8 100644
--- a/msm8996/sdm/libs/core/fb/hw_primary.cpp
+++ b/msm8996/sdm/libs/core/fb/hw_primary.cpp
@@ -112,9 +112,10 @@
UpdateMixerAttributes();
- // Disable HPD at start if HDMI is external, it will be enabled later when the display powers on
+ // Need to enable HPD, but toggle at start when HDMI is external
// This helps for framework reboot or adb shell stop/start
EnableHotPlugDetection(0);
+ EnableHotPlugDetection(1);
InitializeConfigs();
return error;
@@ -390,22 +391,11 @@
return kErrorNone;
}
-void HWPrimary::ResetDisplayParams() {
- uint32_t dst_scalar_cnt = hw_resource_.hw_dest_scalar_info.count;
-
- HWDevice::ResetDisplayParams();
-
- if (mdp_dest_scalar_data_) {
- memset(mdp_dest_scalar_data_, 0, sizeof(mdp_dest_scalar_data_) * dst_scalar_cnt);
- mdp_disp_commit_.commit_v1.dest_scaler = mdp_dest_scalar_data_;
- }
-}
-
DisplayError HWPrimary::Validate(HWLayers *hw_layers) {
HWLayersInfo &hw_layer_info = hw_layers->info;
LayerStack *stack = hw_layer_info.stack;
- ResetDisplayParams();
+ HWDevice::ResetDisplayParams();
mdp_layer_commit_v1 &mdp_commit = mdp_disp_commit_.commit_v1;
@@ -445,40 +435,6 @@
DLOGI_IF(kTagDriverConfig, "****************************************************************");
}
- uint32_t index = 0;
- for (uint32_t i = 0; i < hw_resource_.hw_dest_scalar_info.count; i++) {
- DestScaleInfoMap::iterator it = hw_layer_info.dest_scale_info_map.find(i);
-
- if (it == hw_layer_info.dest_scale_info_map.end()) {
- continue;
- }
-
- HWDestScaleInfo *dest_scale_info = it->second;
-
- mdp_destination_scaler_data *dest_scalar_data = &mdp_dest_scalar_data_[index];
- hw_scale_->SetHWScaleData(dest_scale_info->scale_data, index, &mdp_commit,
- kHWDestinationScalar);
-
- if (dest_scale_info->scale_update) {
- dest_scalar_data->flags |= MDP_DESTSCALER_SCALE_UPDATE;
- }
-
- dest_scalar_data->dest_scaler_ndx = i;
- dest_scalar_data->lm_width = dest_scale_info->mixer_width;
- dest_scalar_data->lm_height = dest_scale_info->mixer_height;
- dest_scalar_data->scale = reinterpret_cast <uint64_t>
- (hw_scale_->GetScaleDataRef(index, kHWDestinationScalar));
-
- index++;
-
- DLOGV_IF(kTagDriverConfig, "************************ DestScalar[%d] **************************",
- dest_scalar_data->dest_scaler_ndx);
- DLOGV_IF(kTagDriverConfig, "Mixer WxH %dx%d", dest_scalar_data->lm_width,
- dest_scalar_data->lm_height);
- DLOGI_IF(kTagDriverConfig, "*****************************************************************");
- }
- mdp_commit.dest_scaler_cnt = UINT32(hw_layer_info.dest_scale_info_map.size());
-
return HWDevice::Validate(hw_layers);
}
@@ -696,67 +652,11 @@
}
DisplayError HWPrimary::SetMixerAttributes(const HWMixerAttributes &mixer_attributes) {
- if (IsResolutionSwitchEnabled() || !hw_resource_.hw_dest_scalar_info.count) {
+ if (IsResolutionSwitchEnabled()) {
return kErrorNotSupported;
}
- if (mixer_attributes.width > display_attributes_.x_pixels ||
- mixer_attributes.height > display_attributes_.y_pixels) {
- DLOGW("Input resolution exceeds display resolution! input: res %dx%d display: res %dx%d",
- mixer_attributes.width, mixer_attributes.height, display_attributes_.x_pixels,
- display_attributes_.y_pixels);
- return kErrorNotSupported;
- }
-
- uint32_t max_input_width = hw_resource_.hw_dest_scalar_info.max_input_width;
- if (display_attributes_.is_device_split) {
- max_input_width *= 2;
- }
-
- if (mixer_attributes.width > max_input_width) {
- DLOGW("Input width exceeds width limit! input_width %d width_limit %d", mixer_attributes.width,
- max_input_width);
- return kErrorNotSupported;
- }
-
- float mixer_aspect_ratio = FLOAT(mixer_attributes.width) / FLOAT(mixer_attributes.height);
- float display_aspect_ratio =
- FLOAT(display_attributes_.x_pixels) / FLOAT(display_attributes_.y_pixels);
-
- if (display_aspect_ratio != mixer_aspect_ratio) {
- DLOGW("Aspect ratio mismatch! input: res %dx%d display: res %dx%d", mixer_attributes.width,
- mixer_attributes.height, display_attributes_.x_pixels, display_attributes_.y_pixels);
- return kErrorNotSupported;
- }
-
- float scale_x = FLOAT(display_attributes_.x_pixels) / FLOAT(mixer_attributes.width);
- float scale_y = FLOAT(display_attributes_.y_pixels) / FLOAT(mixer_attributes.height);
- float max_scale_up = hw_resource_.hw_dest_scalar_info.max_scale_up;
- if (scale_x > max_scale_up || scale_y > max_scale_up) {
- DLOGW("Up scaling ratio exceeds for destination scalar upscale limit scale_x %f scale_y %f " \
- "max_scale_up %f", scale_x, scale_y, max_scale_up);
- return kErrorNotSupported;
- }
-
- float mixer_split_ratio = FLOAT(mixer_attributes_.split_left) / FLOAT(mixer_attributes_.width);
-
- mixer_attributes_ = mixer_attributes;
- mixer_attributes_.split_left = mixer_attributes_.width;
- if (display_attributes_.is_device_split) {
- mixer_attributes_.split_left = UINT32(FLOAT(mixer_attributes.width) * mixer_split_ratio);
- }
-
- return kErrorNone;
-}
-
-DisplayError HWPrimary::GetMixerAttributes(HWMixerAttributes *mixer_attributes) {
- if (!mixer_attributes) {
- return kErrorParameters;
- }
-
- *mixer_attributes = mixer_attributes_;
-
- return kErrorNone;
+ return HWDevice::SetMixerAttributes(mixer_attributes);
}
void HWPrimary::UpdateMixerAttributes() {
diff --git a/msm8996/sdm/libs/core/fb/hw_primary.h b/msm8996/sdm/libs/core/fb/hw_primary.h
index 36b3f63..18e9d72 100644
--- a/msm8996/sdm/libs/core/fb/hw_primary.h
+++ b/msm8996/sdm/libs/core/fb/hw_primary.h
@@ -66,7 +66,6 @@
virtual DisplayError GetPanelBrightness(int *level);
virtual DisplayError SetAutoRefresh(bool enable);
virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes);
- virtual DisplayError GetMixerAttributes(HWMixerAttributes *mixer_attributes);
private:
// Panel modes for the MSMFB_LPM_ENABLE ioctl
@@ -80,17 +79,13 @@
bool IsResolutionSwitchEnabled() { return !display_configs_.empty(); }
bool GetCurrentModeFromSysfs(size_t *curr_x_pixels, size_t *curr_y_pixels);
void UpdateMixerAttributes();
- void ResetDisplayParams();
- HWDisplayAttributes display_attributes_;
std::vector<DisplayConfigVariableInfo> display_configs_;
std::vector<std::string> display_config_strings_;
uint32_t active_config_index_ = 0;
const char *kBrightnessNode = "/sys/class/leds/lcd-backlight/brightness";
const char *kAutoRefreshNode = "/sys/devices/virtual/graphics/fb0/msm_cmd_autorefresh_en";
bool auto_refresh_ = false;
- HWMixerAttributes mixer_attributes_ = {};
- mdp_destination_scaler_data *mdp_dest_scalar_data_ = NULL;
};
} // namespace sdm
diff --git a/msm8996/sdm/libs/core/fb/hw_virtual.h b/msm8996/sdm/libs/core/fb/hw_virtual.h
index 330a067..5ecec34 100644
--- a/msm8996/sdm/libs/core/fb/hw_virtual.h
+++ b/msm8996/sdm/libs/core/fb/hw_virtual.h
@@ -35,6 +35,12 @@
BufferSyncHandler *buffer_sync_handler);
static DisplayError Destroy(HWInterface *intf);
virtual DisplayError SetVSyncState(bool enable) { return kErrorNotSupported; }
+ virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes) {
+ return kErrorNotSupported;
+ }
+ virtual DisplayError GetMixerAttributes(HWMixerAttributes *mixer_attributes) {
+ return kErrorNotSupported;
+ }
protected:
HWVirtual(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info_intf);
diff --git a/msm8996/sdm/libs/hwc/hwc_session.cpp b/msm8996/sdm/libs/hwc/hwc_session.cpp
index 8d12aee..a31c331 100644
--- a/msm8996/sdm/libs/hwc/hwc_session.cpp
+++ b/msm8996/sdm/libs/hwc/hwc_session.cpp
@@ -487,6 +487,11 @@
if (hwc_session->hwc_display_[disp]) {
status = hwc_session->hwc_display_[disp]->SetPowerMode(mode);
}
+ if (disp == HWC_DISPLAY_PRIMARY && hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL]) {
+ // Set the power mode for virtual display while setting power mode for primary, as SF
+ // does not invoke SetPowerMode() for virtual display.
+ status = hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL]->SetPowerMode(mode);
+ }
return status;
}
diff --git a/msm8996/sdm/libs/hwc2/hwc_color_manager.cpp b/msm8996/sdm/libs/hwc2/hwc_color_manager.cpp
index 0be9724..89b4918 100644
--- a/msm8996/sdm/libs/hwc2/hwc_color_manager.cpp
+++ b/msm8996/sdm/libs/hwc2/hwc_color_manager.cpp
@@ -257,7 +257,7 @@
uint32_t primary_width = 0;
uint32_t primary_height = 0;
- hwc_display->GetPanelResolution(&primary_width, &primary_height);
+ hwc_display->GetMixerResolution(&primary_width, &primary_height);
uint8_t *buf = new uint8_t[size]();
// handle for solid fill layer with fd = -1.
private_handle_t *handle = new private_handle_t(-1, 0, private_handle_t::PRIV_FLAGS_FRAMEBUFFER,
diff --git a/msm8996/sdm/libs/hwc2/hwc_display.cpp b/msm8996/sdm/libs/hwc2/hwc_display.cpp
index f687731..d6e6518 100644
--- a/msm8996/sdm/libs/hwc2/hwc_display.cpp
+++ b/msm8996/sdm/libs/hwc2/hwc_display.cpp
@@ -231,12 +231,6 @@
swap_interval_zero_ = true;
}
- framebuffer_config_ = new DisplayConfigVariableInfo();
- if (!framebuffer_config_) {
- DLOGV("Failed to allocate memory for custom framebuffer config.");
- core_intf_->DestroyDisplay(display_intf_);
- return -EINVAL;
- }
client_target_ = new HWCLayer(id_);
int blit_enabled = 0;
@@ -267,7 +261,6 @@
return -EINVAL;
}
- delete framebuffer_config_;
delete client_target_;
if (blit_engine_) {
@@ -332,6 +325,8 @@
// TODO(user): Add blit target layers
for (auto hwc_layer : layer_set_) {
Layer *layer = hwc_layer->GetSDMLayer();
+ // set default composition as GPU for SDM
+ layer->composition = kCompositionGPU;
if (swap_interval_zero_) {
if (layer->input_buffer->acquire_fence_fd >= 0) {
@@ -366,7 +361,6 @@
// TODO(user): Move to a getter if this is needed at other places
hwc_rect_t scaled_display_frame = {INT(layer->dst_rect.left), INT(layer->dst_rect.top),
INT(layer->dst_rect.right), INT(layer->dst_rect.bottom)};
- ScaleDisplayFrame(&scaled_display_frame);
ApplyScanAdjustment(&scaled_display_frame);
hwc_layer->SetLayerDisplayFrame(scaled_display_frame);
ApplyDeInterlaceAdjustment(layer);
@@ -379,12 +373,12 @@
layer->frame_rate = current_refresh_rate_;
}
display_rect_ = Union(display_rect_, layer->dst_rect);
- // TODO(user): Set correctly when implementing caching
- layer->flags.updating = true;
geometry_changes_ |= hwc_layer->GetGeometryChanges();
+ layer->flags.updating = IsLayerUpdating(layer);
layer_stack_.layers.push_back(layer);
}
+ // TODO(user): Set correctly when SDM supports geometry_changes as bitmask
layer_stack_.flags.geometry_changed = UINT32(geometry_changes_ > 0);
// Append client target to the layer stack
layer_stack_.layers.push_back(client_target_->GetSDMLayer());
@@ -501,9 +495,11 @@
HWC2::Error HWCDisplay::GetClientTargetSupport(uint32_t width, uint32_t height, int32_t format,
int32_t dataspace) {
+ DisplayConfigVariableInfo variable_config;
+ display_intf_->GetFrameBufferConfig(&variable_config);
// TODO(user): Support scaled configurations, other formats and other dataspaces
if (format != HAL_PIXEL_FORMAT_RGBA_8888 || dataspace != HAL_DATASPACE_UNKNOWN ||
- width != framebuffer_config_->x_pixels || height != framebuffer_config_->y_pixels) {
+ width != variable_config.x_pixels || height != variable_config.y_pixels) {
return HWC2::Error::Unsupported;
} else {
return HWC2::Error::None;
@@ -533,7 +529,12 @@
HWC2::Error HWCDisplay::GetDisplayAttribute(hwc2_config_t config, HWC2::Attribute attribute,
int32_t *out_value) {
- DisplayConfigVariableInfo variable_config = *framebuffer_config_;
+ DisplayConfigVariableInfo variable_config;
+ DisplayError error = display_intf_->GetFrameBufferConfig(&variable_config);
+ if (error != kErrorNone) {
+ DLOGV("Get variable config failed. Error = %d", error);
+ return HWC2::Error::BadDisplay;
+ }
switch (attribute) {
case HWC2::Attribute::VsyncPeriod:
@@ -609,7 +610,7 @@
}
HWC2::Error HWCDisplay::SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
- int32_t dataspace) {
+ int32_t dataspace, hwc_region_t damage) {
// TODO(user): SurfaceFlinger gives us a null pointer here when doing full SDE composition
// The error is problematic for layer caching as it would overwrite our cached client target.
// Reported bug 28569722 to resolve this.
@@ -617,7 +618,14 @@
if (target == nullptr) {
return HWC2::Error::None;
}
+
+ if (acquire_fence == 0) {
+ DLOGE("acquire_fence is zero");
+ return HWC2::Error::BadParameter;
+ }
+
client_target_->SetLayerBuffer(target, acquire_fence);
+ client_target_->SetLayerSurfaceDamage(damage);
// Ignoring dataspace for now
return HWC2::Error::None;
}
@@ -627,6 +635,10 @@
return HWC2::Error::None;
}
+DisplayError HWCDisplay::SetMixerResolution(uint32_t width, uint32_t height) {
+ return kErrorNotSupported;
+}
+
void HWCDisplay::SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type) {
dump_frame_count_ = count;
dump_frame_index_ = 0;
@@ -691,11 +703,6 @@
flush_ = true;
}
- // If current draw cycle has different set of layers updating in comparison to previous cycle,
- // cache content using GPU again.
- // If set of updating layers remains same, use cached buffer and replace layers marked for GPU
- // composition with SDE so that SurfaceFlinger does not compose them. Set cache inuse here.
- bool needs_fb_refresh = NeedsFrameBufferRefresh();
for (auto hwc_layer : layer_set_) {
Layer *layer = hwc_layer->GetSDMLayer();
LayerComposition &composition = layer->composition;
@@ -705,25 +712,28 @@
layer_requests_[hwc_layer->GetId()] = HWC2::LayerRequest::ClearClientTarget;
}
- if (!needs_fb_refresh && composition == kCompositionGPU) {
- composition = kCompositionSDE;
- }
- HWC2::Composition current_hwc_composition = hwc_layer->GetCompositionType();
- // Convert the SDM layer composition to HWC2 type
+ HWC2::Composition requested_composition = hwc_layer->GetClientRequestedCompositionType();
+ // Set SDM composition to HWC2 type in HWCLayer
hwc_layer->SetComposition(composition);
- // Update the changes list only if the HWC2 comp type changed from the previous cycle
- if (current_hwc_composition != hwc_layer->GetCompositionType()) {
- layer_changes_[hwc_layer->GetId()] = hwc_layer->GetCompositionType();
+ HWC2::Composition device_composition = hwc_layer->GetDeviceSelectedCompositionType();
+ // Update the changes list only if the requested composition is different from SDM comp type
+ // TODO(user): Take Care of other comptypes(BLIT)
+ if (requested_composition != device_composition) {
+ layer_changes_[hwc_layer->GetId()] = device_composition;
}
}
*out_num_types = UINT32(layer_changes_.size());
*out_num_requests = UINT32(layer_requests_.size());
validated_ = true;
- return HWC2::Error::None;
+ if (*out_num_types > 0) {
+ return HWC2::Error::HasChanges;
+ } else {
+ return HWC2::Error::None;
+ }
}
HWC2::Error HWCDisplay::AcceptDisplayChanges() {
- if (!validated_) {
+ if (!validated_ && !layer_set_.empty()) {
return HWC2::Error::NotValidated;
}
return HWC2::Error::None;
@@ -731,6 +741,14 @@
HWC2::Error HWCDisplay::GetChangedCompositionTypes(uint32_t *out_num_elements,
hwc2_layer_t *out_layers, int32_t *out_types) {
+ if (layer_set_.empty()) {
+ return HWC2::Error::None;
+ }
+
+ if (!validated_) {
+ DLOGW("Display is not validated");
+ return HWC2::Error::NotValidated;
+ }
*out_num_elements = UINT32(layer_changes_.size());
if (out_layers != nullptr && out_types != nullptr) {
int i = 0;
@@ -764,6 +782,10 @@
// Use for sharing blit buffers and
// writing wfd buffer directly to output if there is full GPU composition
// and no color conversion needed
+ if (layer_set_.empty()) {
+ return HWC2::Error::None;
+ }
+
if (!validated_) {
DLOGW("Display is not validated");
return HWC2::Error::NotValidated;
@@ -782,7 +804,7 @@
}
HWC2::Error HWCDisplay::CommitLayerStack(void) {
- if (shutdown_pending_) {
+ if (shutdown_pending_ || layer_set_.empty()) {
return HWC2::Error::None;
}
@@ -846,6 +868,7 @@
layer_buffer->release_fence_fd = -1;
} else if (layer->composition != kCompositionGPU) {
hwc_layer->PushReleaseFence(layer_buffer->release_fence_fd);
+ layer_buffer->release_fence_fd = -1;
}
}
@@ -855,19 +878,21 @@
}
}
+ *out_retire_fence = stored_retire_fence_;
if (!flush_) {
// if swapinterval property is set to 0 then close and reset the list retire fence
if (swap_interval_zero_) {
close(layer_stack_.retire_fence_fd);
layer_stack_.retire_fence_fd = -1;
}
- *out_retire_fence = stored_retire_fence_;
stored_retire_fence_ = layer_stack_.retire_fence_fd;
if (dump_frame_count_) {
dump_frame_count_--;
dump_frame_index_++;
}
+ } else {
+ stored_retire_fence_ = -1;
}
geometry_changes_ = GeometryChanges::kNone;
flush_ = false;
@@ -875,31 +900,6 @@
return status;
}
-bool HWCDisplay::NeedsFrameBufferRefresh(void) {
- // Frame buffer needs to be refreshed for the following reasons:
- // 1. Any layer is marked skip in the current layer stack.
- // 2. Any layer is added/removed/layer properties changes in the current layer stack.
- // 3. Any layer handle is changed and it is marked for GPU composition
- // 4. Any layer's current composition is different from previous composition.
- if (layer_stack_.flags.skip_present || layer_stack_.flags.geometry_changed) {
- return true;
- }
-
- for (auto layer : layer_stack_.layers) {
- // need FB refresh for s3d case
- if (layer->input_buffer->s3d_format != kS3dFormatNone) {
- return true;
- }
-
- if (layer->composition == kCompositionGPUTarget ||
- layer->composition == kCompositionBlitTarget) {
- continue;
- }
- }
-
- return false;
-}
-
void HWCDisplay::SetIdleTimeoutMs(uint32_t timeout_ms) {
return;
}
@@ -914,16 +914,6 @@
return error;
}
-DisplayError HWCDisplay::ControlPartialUpdate(bool enable, uint32_t *pending) {
- DisplayError error = kErrorNone;
-
- if (display_intf_) {
- error = display_intf_->ControlPartialUpdate(enable, pending);
- }
-
- return error;
-}
-
LayerBufferFormat HWCDisplay::GetSDMFormat(const int32_t &source, const int flags) {
LayerBufferFormat format = kFormatInvalid;
if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
@@ -1234,45 +1224,29 @@
int HWCDisplay::SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels) {
if (x_pixels <= 0 || y_pixels <= 0) {
- DLOGV("Unsupported config: x_pixels=%d, y_pixels=%d", x_pixels, y_pixels);
+ DLOGW("Unsupported config: x_pixels=%d, y_pixels=%d", x_pixels, y_pixels);
return -EINVAL;
}
- if (framebuffer_config_->x_pixels == x_pixels && framebuffer_config_->y_pixels == y_pixels) {
- return 0;
- }
-
- DisplayConfigVariableInfo active_config;
- uint32_t active_config_index = 0;
- display_intf_->GetActiveConfig(&active_config_index);
- DisplayError error = display_intf_->GetConfig(active_config_index, &active_config);
+ DisplayConfigVariableInfo fb_config;
+ DisplayError error = display_intf_->GetFrameBufferConfig(&fb_config);
if (error != kErrorNone) {
- DLOGV("GetConfig variable info failed. Error = %d", error);
+ DLOGV("Get frame buffer config failed. Error = %d", error);
return -EINVAL;
}
- if (active_config.x_pixels <= 0 || active_config.y_pixels <= 0) {
- DLOGV("Invalid panel resolution (%dx%d)", active_config.x_pixels, active_config.y_pixels);
+ fb_config.x_pixels = x_pixels;
+ fb_config.y_pixels = y_pixels;
+
+ error = display_intf_->SetFrameBufferConfig(fb_config);
+ if (error != kErrorNone) {
+ DLOGV("Set frame buffer config failed. Error = %d", error);
return -EINVAL;
}
// Create rects to represent the new source and destination crops
LayerRect crop = LayerRect(0, 0, FLOAT(x_pixels), FLOAT(y_pixels));
- LayerRect dst = LayerRect(0, 0, FLOAT(active_config.x_pixels), FLOAT(active_config.y_pixels));
- // Set rotate90 to false since this is taken care of during regular composition.
- bool rotate90 = false;
- error = display_intf_->IsScalingValid(crop, dst, rotate90);
- if (error != kErrorNone) {
- DLOGV("Unsupported resolution: (%dx%d)", x_pixels, y_pixels);
- return -EINVAL;
- }
-
- framebuffer_config_->x_pixels = x_pixels;
- framebuffer_config_->y_pixels = y_pixels;
- framebuffer_config_->vsync_period_ns = active_config.vsync_period_ns;
- framebuffer_config_->x_dpi = active_config.x_dpi;
- framebuffer_config_->y_dpi = active_config.y_dpi;
-
+ LayerRect dst = LayerRect(0, 0, FLOAT(fb_config.x_pixels), FLOAT(fb_config.y_pixels));
auto client_target_layer = client_target_->GetSDMLayer();
client_target_layer->src_rect = crop;
client_target_layer->dst_rect = dst;
@@ -1298,68 +1272,32 @@
client_target_layer->input_buffer->height = UINT32(aligned_height);
client_target_layer->plane_alpha = 255;
- DLOGI("New framebuffer resolution (%dx%d)", framebuffer_config_->x_pixels,
- framebuffer_config_->y_pixels);
+ DLOGI("New framebuffer resolution (%dx%d)", fb_config.x_pixels, fb_config.y_pixels);
return 0;
}
void HWCDisplay::GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
- *x_pixels = framebuffer_config_->x_pixels;
- *y_pixels = framebuffer_config_->y_pixels;
+ DisplayConfigVariableInfo fb_config;
+ display_intf_->GetFrameBufferConfig(&fb_config);
+
+ *x_pixels = fb_config.x_pixels;
+ *y_pixels = fb_config.y_pixels;
}
-void HWCDisplay::ScaleDisplayFrame(hwc_rect_t *display_frame) {
- if (!IsFrameBufferScaled()) {
- return;
- }
-
- uint32_t active_config_index = 0;
- display_intf_->GetActiveConfig(&active_config_index);
- DisplayConfigVariableInfo active_config;
- DisplayError error = display_intf_->GetConfig(active_config_index, &active_config);
- if (error != kErrorNone) {
- DLOGE("GetConfig variable info failed. Error = %d", error);
- return;
- }
-
- float custom_x_pixels = FLOAT(framebuffer_config_->x_pixels);
- float custom_y_pixels = FLOAT(framebuffer_config_->y_pixels);
- float active_x_pixels = FLOAT(active_config.x_pixels);
- float active_y_pixels = FLOAT(active_config.y_pixels);
- float x_pixels_ratio = active_x_pixels / custom_x_pixels;
- float y_pixels_ratio = active_y_pixels / custom_y_pixels;
- float layer_width = FLOAT(display_frame->right - display_frame->left);
- float layer_height = FLOAT(display_frame->bottom - display_frame->top);
-
- display_frame->left = INT(x_pixels_ratio * FLOAT(display_frame->left));
- display_frame->top = INT(y_pixels_ratio * FLOAT(display_frame->top));
- display_frame->right = INT(FLOAT(display_frame->left) + layer_width * x_pixels_ratio);
- display_frame->bottom = INT(FLOAT(display_frame->top) + layer_height * y_pixels_ratio);
-}
-
-bool HWCDisplay::IsFrameBufferScaled() {
- if (framebuffer_config_->x_pixels == 0 || framebuffer_config_->y_pixels == 0) {
- return false;
- }
- uint32_t panel_x_pixels = 0;
- uint32_t panel_y_pixels = 0;
- GetPanelResolution(&panel_x_pixels, &panel_y_pixels);
- return (framebuffer_config_->x_pixels != panel_x_pixels) ||
- (framebuffer_config_->y_pixels != panel_y_pixels);
+DisplayError HWCDisplay::GetMixerResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
+ return display_intf_->GetMixerResolution(x_pixels, y_pixels);
}
void HWCDisplay::GetPanelResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
- DisplayConfigVariableInfo active_config;
- uint32_t active_config_index = 0;
- display_intf_->GetActiveConfig(&active_config_index);
- DisplayError error = display_intf_->GetConfig(active_config_index, &active_config);
- if (error != kErrorNone) {
- DLOGE("GetConfig variable info failed. Error = %d", error);
- return;
- }
- *x_pixels = active_config.x_pixels;
- *y_pixels = active_config.y_pixels;
+ DisplayConfigVariableInfo display_config;
+ uint32_t active_index = 0;
+
+ display_intf_->GetActiveConfig(&active_index);
+ display_intf_->GetConfig(active_index, &display_config);
+
+ *x_pixels = display_config.x_pixels;
+ *y_pixels = display_config.y_pixels;
}
int HWCDisplay::SetDisplayStatus(uint32_t display_status) {
@@ -1505,8 +1443,9 @@
return display_intf_->GetNumVariableInfoConfigs(count) == kErrorNone ? 0 : -1;
}
-int HWCDisplay::GetDisplayAttributesForConfig(int config, DisplayConfigVariableInfo *attributes) {
- return display_intf_->GetConfig(UINT32(config), attributes) == kErrorNone ? 0 : -1;
+int HWCDisplay::GetDisplayAttributesForConfig(int config,
+ DisplayConfigVariableInfo *display_attributes) {
+ return display_intf_->GetConfig(UINT32(config), display_attributes) == kErrorNone ? 0 : -1;
}
bool HWCDisplay::SingleLayerUpdating(void) {
@@ -1522,6 +1461,24 @@
return (updating_count == 1);
}
+bool HWCDisplay::IsLayerUpdating(const Layer *layer) {
+ // Layer should be considered updating if
+ // a) layer is in single buffer mode, or
+ // b) valid dirty_regions(android specific hint for updating status), or
+ // c) layer stack geometry has changed (TODO(user): Remove when SDM accepts
+ // geometry_changed as bit fields).
+ return (layer->flags.single_buffer || IsSurfaceUpdated(layer->dirty_regions) ||
+ geometry_changes_);
+}
+
+bool HWCDisplay::IsSurfaceUpdated(const std::vector<LayerRect> &dirty_regions) {
+ // based on dirty_regions determine if its updating
+ // dirty_rect count = 0 - whole layer - updating.
+ // dirty_rect count = 1 or more valid rects - updating.
+ // dirty_rect count = 1 with (0,0,0,0) - not updating.
+ return (dirty_regions.empty() || IsValid(dirty_regions.at(0)));
+}
+
uint32_t HWCDisplay::SanitizeRefreshRate(uint32_t req_refresh_rate) {
uint32_t refresh_rate = req_refresh_rate;
@@ -1565,12 +1522,18 @@
os << "HWC2 LayerDump:" << std::endl;
for (auto layer : layer_set_) {
auto sdm_layer = layer->GetSDMLayer();
+ auto transform = sdm_layer->transform;
os << "-------------------------------" << std::endl;
os << "layer_id: " << layer->GetId() << std::endl;
os << "\tz: " << layer->GetZ() << std::endl;
- os << "\tcomposition: " << to_string(layer->GetCompositionType()).c_str() << std::endl;
+ os << "\tclient(SF) composition: " <<
+ to_string(layer->GetClientRequestedCompositionType()).c_str() << std::endl;
+ os << "\tdevice(SDM) composition: " <<
+ to_string(layer->GetDeviceSelectedCompositionType()).c_str() << std::endl;
os << "\tplane_alpha: " << std::to_string(sdm_layer->plane_alpha).c_str() << std::endl;
os << "\tformat: " << GetFormatString(sdm_layer->input_buffer->format) << std::endl;
+ os << "\ttransform: rot: " << transform.rotation << " flip_h: " << transform.flip_horizontal <<
+ " flip_v: "<< transform.flip_vertical << std::endl;
os << "\tbuffer_id: " << std::hex << "0x" << sdm_layer->input_buffer->buffer_id << std::dec
<< std::endl;
}
diff --git a/msm8996/sdm/libs/hwc2/hwc_display.h b/msm8996/sdm/libs/hwc2/hwc_display.h
index c3ffcb4..69a2dea 100644
--- a/msm8996/sdm/libs/hwc2/hwc_display.h
+++ b/msm8996/sdm/libs/hwc2/hwc_display.h
@@ -92,15 +92,19 @@
virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
virtual void SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type);
virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages);
- virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending);
+ virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending) {
+ return kErrorNotSupported;
+ }
virtual HWC2::PowerMode GetLastPowerMode();
virtual int SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels);
virtual void GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels);
- virtual void GetPanelResolution(uint32_t *x_pixels, uint32_t *y_pixels);
virtual int SetDisplayStatus(uint32_t display_status);
virtual int OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level);
virtual int Perform(uint32_t operation, ...);
virtual void SetSecureDisplay(bool secure_display_active);
+ virtual DisplayError SetMixerResolution(uint32_t width, uint32_t height);
+ virtual DisplayError GetMixerResolution(uint32_t *width, uint32_t *height);
+ virtual void GetPanelResolution(uint32_t *width, uint32_t *height);
virtual std::string Dump(void);
// Captures frame output in the buffer specified by output_buffer_info. The API is
@@ -119,7 +123,8 @@
virtual int SetActiveDisplayConfig(int config);
virtual int GetActiveDisplayConfig(uint32_t *config);
virtual int GetDisplayConfigCount(uint32_t *count);
- virtual int GetDisplayAttributesForConfig(int config, DisplayConfigVariableInfo *attributes);
+ virtual int GetDisplayAttributesForConfig(int config,
+ DisplayConfigVariableInfo *display_attributes);
int SetPanelBrightness(int level);
int GetPanelBrightness(int *level);
@@ -136,7 +141,7 @@
virtual HWC2::Error GetActiveConfig(hwc2_config_t *out_config);
virtual HWC2::Error SetActiveConfig(hwc2_config_t config);
virtual HWC2::Error SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
- int32_t dataspace);
+ int32_t dataspace, hwc_region_t damage);
virtual HWC2::Error SetColorMode(int32_t /*android_color_mode_t*/ mode) {
return HWC2::Error::Unsupported;
}
@@ -193,15 +198,18 @@
virtual HWC2::Error PrepareLayerStack(uint32_t *out_num_types, uint32_t *out_num_requests);
virtual HWC2::Error CommitLayerStack(void);
virtual HWC2::Error PostCommitLayerStack(int32_t *out_retire_fence);
+ virtual DisplayError DisablePartialUpdateOneFrame() {
+ return kErrorNotSupported;
+ }
LayerBufferFormat GetSDMFormat(const int32_t &source, const int flags);
const char *GetHALPixelFormatString(int format);
const char *GetDisplayString();
- void ScaleDisplayFrame(hwc_rect_t *display_frame);
void MarkLayersForGPUBypass(void);
void MarkLayersForClientComposition(void);
virtual void ApplyScanAdjustment(hwc_rect_t *display_frame);
- bool NeedsFrameBufferRefresh(void);
bool SingleLayerUpdating(void);
+ bool IsSurfaceUpdated(const std::vector<LayerRect> &dirty_regions);
+ bool IsLayerUpdating(const Layer *layer);
uint32_t SanitizeRefreshRate(uint32_t req_refresh_rate);
virtual void CloseAcquireFds();
@@ -229,7 +237,6 @@
bool dump_input_layers_ = false;
HWC2::PowerMode last_power_mode_;
bool swap_interval_zero_ = false;
- DisplayConfigVariableInfo *framebuffer_config_ = NULL;
bool display_paused_ = false;
uint32_t min_refresh_rate_ = 0;
uint32_t max_refresh_rate_ = 0;
@@ -248,14 +255,13 @@
bool validated_ = false;
bool color_tranform_failed_ = false;
HWCColorMode *color_mode_ = NULL;
+ int32_t stored_retire_fence_ = -1;
private:
- bool IsFrameBufferScaled();
void DumpInputBuffers(void);
BlitEngine *blit_engine_ = NULL;
qService::QService *qservice_ = NULL;
DisplayClass display_class_;
- int32_t stored_retire_fence_ = -1;
uint32_t geometry_changes_ = GeometryChanges::kNone;
};
diff --git a/msm8996/sdm/libs/hwc2/hwc_display_external.cpp b/msm8996/sdm/libs/hwc2/hwc_display_external.cpp
index 73ed0e8..caacb11 100644
--- a/msm8996/sdm/libs/hwc2/hwc_display_external.cpp
+++ b/msm8996/sdm/libs/hwc2/hwc_display_external.cpp
@@ -49,6 +49,7 @@
HWCDisplay **hwc_display) {
uint32_t external_width = 0;
uint32_t external_height = 0;
+ DisplayError error = kErrorNone;
HWCDisplay *hwc_display_external = new HWCDisplayExternal(core_intf, callbacks, qservice);
int status = hwc_display_external->Init();
@@ -57,7 +58,10 @@
return status;
}
- hwc_display_external->GetPanelResolution(&external_width, &external_height);
+ error = hwc_display_external->GetMixerResolution(&external_width, &external_height);
+ if (error != kErrorNone) {
+ return -EINVAL;
+ }
if (primary_width && primary_height) {
// use_primary_res means HWCDisplayExternal should directly set framebuffer resolution to the
@@ -144,29 +148,29 @@
return;
}
- uint32_t panel_width = 0;
- uint32_t panel_height = 0;
- GetPanelResolution(&panel_width, &panel_height);
+ uint32_t mixer_width = 0;
+ uint32_t mixer_height = 0;
+ GetMixerResolution(&mixer_width, &mixer_height);
- if (panel_width == 0 || panel_height == 0) {
- DLOGV("Invalid panel dimensions (%d, %d)", panel_width, panel_height);
+ if (mixer_width == 0 || mixer_height == 0) {
+ DLOGV("Invalid mixer dimensions (%d, %d)", mixer_width, mixer_height);
return;
}
- uint32_t new_panel_width = UINT32(panel_width * FLOAT(1.0f - width_ratio));
- uint32_t new_panel_height = UINT32(panel_height * FLOAT(1.0f - height_ratio));
+ uint32_t new_mixer_width = UINT32(mixer_width * FLOAT(1.0f - width_ratio));
+ uint32_t new_mixer_height = UINT32(mixer_height * FLOAT(1.0f - height_ratio));
- int x_offset = INT((FLOAT(panel_width) * width_ratio) / 2.0f);
- int y_offset = INT((FLOAT(panel_height) * height_ratio) / 2.0f);
+ int x_offset = INT((FLOAT(mixer_width) * width_ratio) / 2.0f);
+ int y_offset = INT((FLOAT(mixer_height) * height_ratio) / 2.0f);
- display_frame->left =
- (display_frame->left * INT32(new_panel_width) / INT32(panel_width)) + x_offset;
- display_frame->top =
- (display_frame->top * INT32(new_panel_height) / INT32(panel_height)) + y_offset;
- display_frame->right =
- ((display_frame->right * INT32(new_panel_width)) / INT32(panel_width)) + x_offset;
- display_frame->bottom =
- ((display_frame->bottom * INT32(new_panel_height)) / INT32(panel_height)) + y_offset;
+ display_frame->left = (display_frame->left * INT32(new_mixer_width) / INT32(mixer_width))
+ + x_offset;
+ display_frame->top = (display_frame->top * INT32(new_mixer_height) / INT32(mixer_height)) +
+ y_offset;
+ display_frame->right = ((display_frame->right * INT32(new_mixer_width)) / INT32(mixer_width)) +
+ x_offset;
+ display_frame->bottom = ((display_frame->bottom * INT32(new_mixer_height)) / INT32(mixer_height))
+ + y_offset;
}
void HWCDisplayExternal::SetSecureDisplay(bool secure_display_active) {
diff --git a/msm8996/sdm/libs/hwc2/hwc_display_primary.cpp b/msm8996/sdm/libs/hwc2/hwc_display_primary.cpp
index 517959e..eeb7dbb 100644
--- a/msm8996/sdm/libs/hwc2/hwc_display_primary.cpp
+++ b/msm8996/sdm/libs/hwc2/hwc_display_primary.cpp
@@ -60,7 +60,7 @@
return status;
}
- hwc_display_primary->GetPanelResolution(&primary_width, &primary_height);
+ hwc_display_primary->GetMixerResolution(&primary_width, &primary_height);
int width = 0, height = 0;
HWCDebugHandler::Get()->GetProperty("sdm.fb_size_width", &width);
HWCDebugHandler::Get()->GetProperty("sdm.fb_size_height", &height);
@@ -197,7 +197,6 @@
handle_idle_timeout_ = false;
}
- // TODO(user): Validate this
if (layer_set_.empty()) {
flush_ = true;
return status;
@@ -412,9 +411,6 @@
frame_capture_buffer_queued_ = false;
post_processed_output_ = false;
output_buffer_ = {};
-
- uint32_t pending = 0; // Just a temporary to satisfy the API
- ControlPartialUpdate(true /* enable */, &pending);
}
void HWCDisplayPrimary::HandleFrameDump() {
@@ -443,9 +439,6 @@
output_buffer_ = {};
output_buffer_info_ = {};
output_buffer_base_ = nullptr;
-
- uint32_t pending = 0; // Just a temporary to satisfy the API
- ControlPartialUpdate(true /* enable */, &pending);
}
}
@@ -483,8 +476,7 @@
output_buffer_base_ = buffer;
post_processed_output_ = true;
- uint32_t pending = 0; // Just a temporary to satisfy the API
- ControlPartialUpdate(false /* enable */, &pending);
+ DisablePartialUpdateOneFrame();
}
int HWCDisplayPrimary::FrameCaptureAsync(const BufferInfo &output_buffer_info,
@@ -518,11 +510,38 @@
frame_capture_buffer_queued_ = true;
// Status is only cleared on a new call to dump and remains valid otherwise
frame_capture_status_ = -EAGAIN;
-
- uint32_t pending = 0; // Just a temporary to satisfy the API
- ControlPartialUpdate(false /* enable */, &pending);
+ DisablePartialUpdateOneFrame();
return 0;
}
+DisplayError HWCDisplayPrimary::ControlPartialUpdate(bool enable, uint32_t *pending) {
+ DisplayError error = kErrorNone;
+
+ if (display_intf_) {
+ error = display_intf_->ControlPartialUpdate(enable, pending);
+ }
+
+ return error;
+}
+
+DisplayError HWCDisplayPrimary::DisablePartialUpdateOneFrame() {
+ DisplayError error = kErrorNone;
+
+ if (display_intf_) {
+ error = display_intf_->DisablePartialUpdateOneFrame();
+ }
+
+ return error;
+}
+
+
+DisplayError HWCDisplayPrimary::SetMixerResolution(uint32_t width, uint32_t height) {
+ return display_intf_->SetMixerResolution(width, height);
+}
+
+DisplayError HWCDisplayPrimary::GetMixerResolution(uint32_t *width, uint32_t *height) {
+ return display_intf_->GetMixerResolution(width, height);
+}
+
} // namespace sdm
diff --git a/msm8996/sdm/libs/hwc2/hwc_display_primary.h b/msm8996/sdm/libs/hwc2/hwc_display_primary.h
index 62b311e..41b0c9f 100644
--- a/msm8996/sdm/libs/hwc2/hwc_display_primary.h
+++ b/msm8996/sdm/libs/hwc2/hwc_display_primary.h
@@ -64,12 +64,14 @@
virtual void SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type);
virtual int FrameCaptureAsync(const BufferInfo &output_buffer_info, bool post_processed);
virtual int GetFrameCaptureStatus() { return frame_capture_status_; }
+ virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending);
private:
HWCDisplayPrimary(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
HWCCallbacks *callbacks, qService::QService *qservice);
void SetMetaDataRefreshRateFlag(bool enable);
virtual DisplayError SetDisplayMode(uint32_t mode);
+ virtual DisplayError DisablePartialUpdateOneFrame();
void ProcessBootAnimCompleted(void);
void SetQDCMSolidFillInfo(bool enable, uint32_t color);
void ToggleCPUHint(bool set);
@@ -78,6 +80,8 @@
void HandleFrameOutput();
void HandleFrameCapture();
void HandleFrameDump();
+ DisplayError SetMixerResolution(uint32_t width, uint32_t height);
+ DisplayError GetMixerResolution(uint32_t *width, uint32_t *height);
BufferAllocator *buffer_allocator_ = nullptr;
CPUHint *cpu_hint_ = nullptr;
diff --git a/msm8996/sdm/libs/hwc2/hwc_display_virtual.cpp b/msm8996/sdm/libs/hwc2/hwc_display_virtual.cpp
index 6c7edfb..89f313a 100644
--- a/msm8996/sdm/libs/hwc2/hwc_display_virtual.cpp
+++ b/msm8996/sdm/libs/hwc2/hwc_display_virtual.cpp
@@ -41,28 +41,32 @@
namespace sdm {
int HWCDisplayVirtual::Create(CoreInterface *core_intf, HWCCallbacks *callbacks, uint32_t width,
- uint32_t height, HWCDisplay **hwc_display) {
+ uint32_t height, int32_t *format, HWCDisplay **hwc_display) {
int status = 0;
HWCDisplayVirtual *hwc_display_virtual = new HWCDisplayVirtual(core_intf, callbacks);
- uint32_t virtual_width = 0, virtual_height = 0;
+
+ // TODO(user): Populate format correctly
+ DLOGI("Creating virtual display: w: %d h:%d format:0x%x", width, height, *format);
status = hwc_display_virtual->Init();
if (status) {
+ DLOGW("Failed to initialize virtual display");
delete hwc_display_virtual;
return status;
}
status = INT32(hwc_display_virtual->SetPowerMode(HWC2::PowerMode::On));
if (status) {
+ DLOGW("Failed to set power mode on virtual display");
Destroy(hwc_display_virtual);
return status;
}
- hwc_display_virtual->GetPanelResolution(&virtual_width, &virtual_height);
-
+ // TODO(user): Validate that we support this width/height
status = hwc_display_virtual->SetFrameBufferResolution(width, height);
if (status) {
+ DLOGW("Failed to set virtual display FB resolution");
Destroy(hwc_display_virtual);
return status;
}
@@ -83,12 +87,16 @@
}
int HWCDisplayVirtual::Init() {
+ output_buffer_ = new LayerBuffer();
return HWCDisplay::Init();
}
int HWCDisplayVirtual::Deinit() {
int status = 0;
-
+ if (output_buffer_) {
+ delete output_buffer_;
+ output_buffer_ = nullptr;
+ }
status = HWCDisplay::Deinit();
return status;
@@ -103,6 +111,7 @@
}
BuildLayerStack();
+ layer_stack_.output_buffer = output_buffer_;
status = PrepareLayerStack(out_num_types, out_num_requests);
return status;
}
@@ -133,6 +142,13 @@
}
status = HWCDisplay::PostCommitLayerStack(out_retire_fence);
+ // On Virtual displays, use the output buffer release fence as the retire fence
+ // Close the layer stack retire fence as it is unused
+ if (layer_stack_.output_buffer) {
+ stored_retire_fence_ = layer_stack_.output_buffer->release_fence_fd;
+ close(layer_stack_.retire_fence_fd);
+ layer_stack_.retire_fence_fd = -1;
+ }
}
}
CloseAcquireFds();
@@ -140,6 +156,9 @@
}
HWC2::Error HWCDisplayVirtual::SetOutputBuffer(buffer_handle_t buf, int32_t release_fence) {
+ if (buf == nullptr || release_fence == 0) {
+ return HWC2::Error::BadParameter;
+ }
const private_handle_t *output_handle = static_cast<const private_handle_t *>(buf);
// Fill output buffer parameters (width, height, format, plane information, fence)
@@ -180,7 +199,6 @@
output_buffer_->planes[0].stride = UINT32(output_handle->width);
}
- layer_stack_.output_buffer = output_buffer_;
return HWC2::Error::None;
}
diff --git a/msm8996/sdm/libs/hwc2/hwc_display_virtual.h b/msm8996/sdm/libs/hwc2/hwc_display_virtual.h
index 271d15d..a68ac65 100644
--- a/msm8996/sdm/libs/hwc2/hwc_display_virtual.h
+++ b/msm8996/sdm/libs/hwc2/hwc_display_virtual.h
@@ -38,8 +38,8 @@
class HWCDisplayVirtual : public HWCDisplay {
public:
- static int Create(CoreInterface *core_intf, HWCCallbacks *callbacks, uint32_t primary_width,
- uint32_t primary_height, HWCDisplay **hwc_display);
+ static int Create(CoreInterface *core_intf, HWCCallbacks *callbacks, uint32_t width,
+ uint32_t height, int32_t *format, HWCDisplay **hwc_display);
static void Destroy(HWCDisplay *hwc_display);
virtual int Init();
virtual int Deinit();
diff --git a/msm8996/sdm/libs/hwc2/hwc_layers.cpp b/msm8996/sdm/libs/hwc2/hwc_layers.cpp
index 2591898..b9f7a6e 100644
--- a/msm8996/sdm/libs/hwc2/hwc_layers.cpp
+++ b/msm8996/sdm/libs/hwc2/hwc_layers.cpp
@@ -58,6 +58,11 @@
return HWC2::Error::BadParameter;
}
+ if (acquire_fence == 0) {
+ DLOGE("acquire_fence is zero");
+ return HWC2::Error::BadParameter;
+ }
+
const private_handle_t *handle = static_cast<const private_handle_t *>(buffer);
LayerBuffer *layer_buffer = layer_->input_buffer;
layer_buffer->width = UINT32(handle->width);
@@ -89,6 +94,7 @@
HWC2::Error HWCLayer::SetLayerSurfaceDamage(hwc_region_t damage) {
auto num_dirty_rects = damage.numRects;
+ layer_->dirty_regions.clear();
if (num_dirty_rects > 0) {
for (uint32_t i = 0; i <= damage.numRects; i++) {
LayerRect rect;
@@ -100,20 +106,25 @@
}
HWC2::Error HWCLayer::SetLayerBlendMode(HWC2::BlendMode mode) {
+ LayerBlending blending = kBlendingPremultiplied;
switch (mode) {
case HWC2::BlendMode::Coverage:
- layer_->blending = kBlendingCoverage;
+ blending = kBlendingCoverage;
break;
case HWC2::BlendMode::Premultiplied:
- layer_->blending = kBlendingPremultiplied;
+ blending = kBlendingPremultiplied;
break;
case HWC2::BlendMode::None:
- layer_->blending = kBlendingOpaque;
+ blending = kBlendingOpaque;
break;
default:
return HWC2::Error::BadParameter;
}
- geometry_changes_ |= kBlendMode;
+
+ if (layer_->blending != blending) {
+ geometry_changes_ |= kBlendMode;
+ layer_->blending = blending;
+ }
return HWC2::Error::None;
}
@@ -128,7 +139,7 @@
HWC2::Error HWCLayer::SetLayerCompositionType(HWC2::Composition type) {
layer_->flags = {}; // Reset earlier flags
- composition_ = type; // Used to compute changes
+ client_requested_ = type;
switch (type) {
case HWC2::Composition::Client:
layer_->flags.skip = true;
@@ -147,8 +158,7 @@
default:
return HWC2::Error::Unsupported;
}
- // TODO(user): Check if this should be set here or somewhere else
- layer_->flags.updating = true;
+
return HWC2::Error::None;
}
@@ -159,60 +169,81 @@
}
HWC2::Error HWCLayer::SetLayerDisplayFrame(hwc_rect_t frame) {
- SetRect(frame, &layer_->dst_rect);
- geometry_changes_ |= kDisplayFrame;
+ LayerRect dst_rect = {};
+ SetRect(frame, &dst_rect);
+ if (layer_->dst_rect != dst_rect) {
+ geometry_changes_ |= kDisplayFrame;
+ layer_->dst_rect = dst_rect;
+ }
return HWC2::Error::None;
}
HWC2::Error HWCLayer::SetLayerPlaneAlpha(float alpha) {
// Conversion of float alpha in range 0.0 to 1.0 similar to the HWC Adapter
- layer_->plane_alpha = static_cast<uint8_t>(std::round(255.0f * alpha));
- geometry_changes_ |= kPlaneAlpha;
+ uint8_t plane_alpha = static_cast<uint8_t>(std::round(255.0f * alpha));
+ if (layer_->plane_alpha != plane_alpha) {
+ geometry_changes_ |= kPlaneAlpha;
+ layer_->plane_alpha = plane_alpha;
+ }
+
return HWC2::Error::None;
}
HWC2::Error HWCLayer::SetLayerSourceCrop(hwc_frect_t crop) {
- SetRect(crop, &layer_->src_rect);
- geometry_changes_ |= kSourceCrop;
+ LayerRect src_rect = {};
+ SetRect(crop, &src_rect);
+ if (layer_->src_rect != src_rect) {
+ geometry_changes_ |= kSourceCrop;
+ layer_->src_rect = src_rect;
+ }
+
return HWC2::Error::None;
}
HWC2::Error HWCLayer::SetLayerTransform(HWC2::Transform transform) {
+ LayerTransform layer_transform = {};
switch (transform) {
case HWC2::Transform::FlipH:
- layer_->transform.flip_horizontal = true;
+ layer_transform.flip_horizontal = true;
break;
case HWC2::Transform::FlipV:
- layer_->transform.flip_vertical = true;
+ layer_transform.flip_vertical = true;
break;
case HWC2::Transform::Rotate90:
- layer_->transform.rotation = 90.0f;
+ layer_transform.rotation = 90.0f;
break;
case HWC2::Transform::Rotate180:
- layer_->transform.rotation = 180.0f;
+ layer_transform.flip_horizontal = true;
+ layer_transform.flip_vertical = true;
break;
case HWC2::Transform::Rotate270:
- layer_->transform.rotation = 270.0f;
+ layer_transform.rotation = 90.0f;
+ layer_transform.flip_horizontal = true;
+ layer_transform.flip_vertical = true;
break;
case HWC2::Transform::FlipHRotate90:
- layer_->transform.rotation = 90.0f;
- layer_->transform.flip_horizontal = true;
+ layer_transform.rotation = 90.0f;
+ layer_transform.flip_horizontal = true;
break;
case HWC2::Transform::FlipVRotate90:
- layer_->transform.rotation = 90.0f;
- layer_->transform.flip_vertical = true;
+ layer_transform.rotation = 90.0f;
+ layer_transform.flip_vertical = true;
break;
- default:
- layer_->transform.rotation = 0.0f;
- layer_->transform.flip_horizontal = false;
- layer_->transform.flip_vertical = false;
+ case HWC2::Transform::None:
+ // do nothing
+ break;
}
- geometry_changes_ |= kTransform;
+
+ if (layer_->transform != layer_transform) {
+ geometry_changes_ |= kTransform;
+ layer_->transform = layer_transform;
+ }
return HWC2::Error::None;
}
HWC2::Error HWCLayer::SetLayerVisibleRegion(hwc_region_t visible) {
auto num_dirty_rects = visible.numRects;
+ layer_->visible_regions.clear();
if (num_dirty_rects > 0) {
for (uint32_t i = 0; i <= visible.numRects; i++) {
LayerRect rect;
@@ -225,8 +256,10 @@
}
HWC2::Error HWCLayer::SetLayerZOrder(uint32_t z) {
- z_ = z;
- geometry_changes_ |= kZOrder;
+ if (z_ != z) {
+ geometry_changes_ |= kZOrder;
+ z_ = z;
+ }
return HWC2::Error::None;
}
@@ -490,24 +523,26 @@
return frame_rate;
}
-void HWCLayer::SetComposition(const LayerComposition &source) {
- auto composition = HWC2::Composition::Invalid;
- switch (source) {
+void HWCLayer::SetComposition(const LayerComposition &sdm_composition) {
+ auto hwc_composition = HWC2::Composition::Invalid;
+ switch (sdm_composition) {
case kCompositionGPU:
- composition = HWC2::Composition::Client;
+ hwc_composition = HWC2::Composition::Client;
break;
case kCompositionHWCursor:
- composition = HWC2::Composition::Cursor;
+ hwc_composition = HWC2::Composition::Cursor;
break;
default:
- composition = HWC2::Composition::Device;
+ hwc_composition = HWC2::Composition::Device;
break;
}
// Update solid fill composition
- if (layer_->composition == kCompositionSDE && layer_->flags.solid_fill != 0) {
- composition = HWC2::Composition::SolidColor;
+ if (sdm_composition == kCompositionSDE && layer_->flags.solid_fill != 0) {
+ hwc_composition = HWC2::Composition::SolidColor;
}
- composition_ = composition;
+ device_selected_ = hwc_composition;
+
+ return;
}
void HWCLayer::PushReleaseFence(int32_t fence) {
release_fences_.push(fence);
diff --git a/msm8996/sdm/libs/hwc2/hwc_layers.h b/msm8996/sdm/libs/hwc2/hwc_layers.h
index 1026ff2..56e0336 100644
--- a/msm8996/sdm/libs/hwc2/hwc_layers.h
+++ b/msm8996/sdm/libs/hwc2/hwc_layers.h
@@ -70,8 +70,9 @@
HWC2::Error SetLayerTransform(HWC2::Transform transform);
HWC2::Error SetLayerVisibleRegion(hwc_region_t visible);
HWC2::Error SetLayerZOrder(uint32_t z);
- void SetComposition(const LayerComposition &source);
- HWC2::Composition GetCompositionType() { return composition_; }
+ void SetComposition(const LayerComposition &sdm_composition);
+ HWC2::Composition GetClientRequestedCompositionType() { return client_requested_; }
+ HWC2::Composition GetDeviceSelectedCompositionType() { return device_selected_; }
uint32_t GetGeometryChanges() { return geometry_changes_; }
void ResetGeometryChanges() { geometry_changes_ = GeometryChanges::kNone; }
void PushReleaseFence(int32_t fence);
@@ -85,7 +86,10 @@
static std::atomic<hwc2_layer_t> next_id_;
std::queue<int32_t> release_fences_;
- HWC2::Composition composition_ = HWC2::Composition::Device;
+ // Composition requested by client(SF)
+ HWC2::Composition client_requested_ = HWC2::Composition::Device;
+ // Composition selected by SDM
+ HWC2::Composition device_selected_ = HWC2::Composition::Device;
uint32_t geometry_changes_ = GeometryChanges::kNone;
void SetRect(const hwc_rect_t &source, LayerRect *target);
diff --git a/msm8996/sdm/libs/hwc2/hwc_session.cpp b/msm8996/sdm/libs/hwc2/hwc_session.cpp
index 28e0206..f75e6b8 100644
--- a/msm8996/sdm/libs/hwc2/hwc_session.cpp
+++ b/msm8996/sdm/libs/hwc2/hwc_session.cpp
@@ -236,15 +236,18 @@
}
int32_t HWCSession::CreateVirtualDisplay(hwc2_device_t *device, uint32_t width, uint32_t height,
- hwc2_display_t *out_display_id) {
+ int32_t *format, hwc2_display_t *out_display_id) {
+ // TODO(user): Handle concurrency with HDMI
+ SCOPE_LOCK(locker_);
if (!device) {
return HWC2_ERROR_BAD_DISPLAY;
}
HWCSession *hwc_session = static_cast<HWCSession *>(device);
- auto status = hwc_session->CreateVirtualDisplayObject(width, height);
+ auto status = hwc_session->CreateVirtualDisplayObject(width, height, format);
if (status == HWC2::Error::None)
*out_display_id = HWC_DISPLAY_VIRTUAL;
+ DLOGI("Created virtual display id:% " PRIu64 " with res: %dx%d", *out_display_id, width, height);
return INT32(status);
}
@@ -255,10 +258,12 @@
}
int32_t HWCSession::DestroyVirtualDisplay(hwc2_device_t *device, hwc2_display_t display) {
+ SCOPE_LOCK(locker_);
if (!device) {
return HWC2_ERROR_BAD_DISPLAY;
}
+ DLOGI("Destroying virtual display id:%" PRIu64, display);
auto *hwc_session = static_cast<HWCSession *>(device);
if (hwc_session->hwc_display_[display]) {
@@ -417,9 +422,10 @@
}
static int32_t SetClientTarget(hwc2_device_t *device, hwc2_display_t display,
- buffer_handle_t target, int32_t acquire_fence, int32_t dataspace) {
+ buffer_handle_t target, int32_t acquire_fence,
+ int32_t dataspace, hwc_region_t damage) {
return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetClientTarget, target,
- acquire_fence, dataspace);
+ acquire_fence, dataspace, damage);
}
int32_t HWCSession::SetColorMode(hwc2_device_t *device, hwc2_display_t display,
@@ -571,7 +577,7 @@
}
// If validate fails, cancel the sequence lock so that other operations
// (such as Dump or SetPowerMode) may succeed without blocking on the condition
- if (status != HWC2::Error::None) {
+ if (status == HWC2::Error::BadDisplay) {
SEQUENCE_CANCEL_SCOPE_LOCK(locker_);
}
return INT32(status);
@@ -678,11 +684,12 @@
// TODO(user): handle locking
-HWC2::Error HWCSession::CreateVirtualDisplayObject(uint32_t width, uint32_t height) {
+HWC2::Error HWCSession::CreateVirtualDisplayObject(uint32_t width, uint32_t height,
+ int32_t *format) {
if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
return HWC2::Error::NoResources;
}
- auto status = HWCDisplayVirtual::Create(core_intf_, &callbacks_, width, height,
+ auto status = HWCDisplayVirtual::Create(core_intf_, &callbacks_, width, height, format,
&hwc_display_[HWC_DISPLAY_VIRTUAL]);
// TODO(user): validate width and height support
if (status)
@@ -830,6 +837,10 @@
status = GetBWTransactionStatus(input_parcel, output_parcel);
break;
+ case qService::IQService::SET_LAYER_MIXER_RESOLUTION:
+ status = SetMixerResolution(input_parcel);
+ break;
+
default:
DLOGW("QService command = %d is not supported", command);
return -EINVAL;
@@ -996,25 +1007,26 @@
return error;
}
-android::status_t HWCSession::HandleGetDisplayAttributesForConfig(
- const android::Parcel *input_parcel, android::Parcel *output_parcel) {
+android::status_t HWCSession::HandleGetDisplayAttributesForConfig(const android::Parcel
+ *input_parcel,
+ android::Parcel *output_parcel) {
int config = input_parcel->readInt32();
int dpy = input_parcel->readInt32();
int error = android::BAD_VALUE;
- DisplayConfigVariableInfo attributes;
+ DisplayConfigVariableInfo display_attributes;
if (dpy > HWC_DISPLAY_VIRTUAL) {
return android::BAD_VALUE;
}
if (hwc_display_[dpy]) {
- error = hwc_display_[dpy]->GetDisplayAttributesForConfig(config, &attributes);
+ error = hwc_display_[dpy]->GetDisplayAttributesForConfig(config, &display_attributes);
if (error == 0) {
- output_parcel->writeInt32(INT(attributes.vsync_period_ns));
- output_parcel->writeInt32(INT(attributes.x_pixels));
- output_parcel->writeInt32(INT(attributes.y_pixels));
- output_parcel->writeFloat(attributes.x_dpi);
- output_parcel->writeFloat(attributes.y_dpi);
+ output_parcel->writeInt32(INT(display_attributes.vsync_period_ns));
+ output_parcel->writeInt32(INT(display_attributes.x_pixels));
+ output_parcel->writeInt32(INT(display_attributes.y_pixels));
+ output_parcel->writeFloat(display_attributes.x_dpi);
+ output_parcel->writeFloat(display_attributes.y_dpi);
output_parcel->writeInt32(0); // Panel type, unsupported.
}
}
@@ -1167,6 +1179,31 @@
}
}
+android::status_t HWCSession::SetMixerResolution(const android::Parcel *input_parcel) {
+ DisplayError error = kErrorNone;
+ uint32_t dpy = UINT32(input_parcel->readInt32());
+
+ if (dpy != HWC_DISPLAY_PRIMARY) {
+ DLOGI("Resoulution change not supported for this display %d", dpy);
+ return -EINVAL;
+ }
+
+ if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ DLOGI("Primary display is not initialized");
+ return -EINVAL;
+ }
+
+ uint32_t width = UINT32(input_parcel->readInt32());
+ uint32_t height = UINT32(input_parcel->readInt32());
+
+ error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetMixerResolution(width, height);
+ if (error != kErrorNone) {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
void HWCSession::DynamicDebug(const android::Parcel *input_parcel) {
int type = input_parcel->readInt32();
bool enable = (input_parcel->readInt32() > 0);
diff --git a/msm8996/sdm/libs/hwc2/hwc_session.h b/msm8996/sdm/libs/hwc2/hwc_session.h
index a713ab0..63cce84 100644
--- a/msm8996/sdm/libs/hwc2/hwc_session.h
+++ b/msm8996/sdm/libs/hwc2/hwc_session.h
@@ -42,7 +42,7 @@
explicit HWCSession(const hw_module_t *module);
int Init();
int Deinit();
- HWC2::Error CreateVirtualDisplayObject(uint32_t width, uint32_t height);
+ HWC2::Error CreateVirtualDisplayObject(uint32_t width, uint32_t height, int32_t *format);
template <typename... Args>
static int32_t CallDisplayFunction(hwc2_device_t *device, hwc2_display_t display,
@@ -85,7 +85,7 @@
static int32_t CreateLayer(hwc2_device_t *device, hwc2_display_t display,
hwc2_layer_t *out_layer_id);
static int32_t CreateVirtualDisplay(hwc2_device_t *device, uint32_t width, uint32_t height,
- hwc2_display_t *out_display_id);
+ int32_t *format, hwc2_display_t *out_display_id);
static int32_t DestroyLayer(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer);
static int32_t DestroyVirtualDisplay(hwc2_device_t *device, hwc2_display_t display);
static void Dump(hwc2_device_t *device, uint32_t *out_size, char *out_buffer);
@@ -164,6 +164,8 @@
android::Parcel *output_parcel);
android::status_t GetBWTransactionStatus(const android::Parcel *input_parcel,
android::Parcel *output_parcel);
+ android::status_t SetMixerResolution(const android::Parcel *input_parcel);
+
static Locker locker_;
CoreInterface *core_intf_ = NULL;
HWCDisplay *hwc_display_[HWC_NUM_DISPLAY_TYPES] = {NULL};