Merge "hwc2: Clean up acquire fence handling"
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index 5051bed..87f7bcf 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -378,9 +378,6 @@
CompRatioMap comp_ratio_rt_map;
CompRatioMap comp_ratio_nrt_map;
uint32_t hw_version;
- uint64_t min_core_ib;
- uint64_t min_llcc_ib;
- uint64_t min_dram_ib;
uint32_t dest_scaler_count = 0;
uint32_t max_dest_scaler_input_width = 0;
uint32_t max_dest_scaler_output_width = 0;
diff --git a/libgralloc1/gr_buf_mgr.cpp b/libgralloc1/gr_buf_mgr.cpp
index 35c4b02..eb97f15 100644
--- a/libgralloc1/gr_buf_mgr.cpp
+++ b/libgralloc1/gr_buf_mgr.cpp
@@ -725,7 +725,7 @@
return GRALLOC1_ERROR_BAD_VALUE;
}
- if (getMetaData(hnd, GET_MAP_SECURE_BUFFER, map_secure_buffer) == 0) {
+ if (getMetaData(hnd, GET_MAP_SECURE_BUFFER, map_secure_buffer) != 0) {
*map_secure_buffer = 0;
}
} break;
@@ -853,8 +853,8 @@
return GRALLOC1_ERROR_UNSUPPORTED;
}
- android_ycbcr ycbcr;
- int err = GetYUVPlaneInfo(hnd, &ycbcr);
+ android_ycbcr yuvPlaneInfo[2];
+ int err = GetYUVPlaneInfo(hnd, yuvPlaneInfo);
if (err != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
@@ -872,6 +872,8 @@
layout->planes[i].v_subsampling = 2;
}
+ // We are only returning flex layout for progressive or single field formats.
+ struct android_ycbcr ycbcr = yuvPlaneInfo[0];
layout->planes[0].top_left = static_cast<uint8_t *>(ycbcr.y);
layout->planes[0].component = FLEX_COMPONENT_Y;
layout->planes[0].v_increment = static_cast<int32_t>(ycbcr.ystride);
diff --git a/libgralloc1/gr_utils.cpp b/libgralloc1/gr_utils.cpp
index 945dea4..a7e8c91 100644
--- a/libgralloc1/gr_utils.cpp
+++ b/libgralloc1/gr_utils.cpp
@@ -312,7 +312,7 @@
}
void GetYuvUbwcInterlacedSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
- int color_format, struct android_ycbcr *ycbcr) {
+ int color_format, struct android_ycbcr ycbcr[2]) {
unsigned int uv_stride, uv_height, uv_size;
unsigned int alignment = 4096;
uint64_t field_base;
@@ -329,6 +329,7 @@
field_base = base;
GetYuvUbwcSPPlaneInfo(field_base, width, height, COLOR_FMT_NV12_UBWC, &ycbcr[0]);
+ memset(ycbcr[1].reserved, 0, sizeof(ycbcr[1].reserved));
field_base = reinterpret_cast<uint64_t>(ycbcr[0].cb) + uv_size;
GetYuvUbwcSPPlaneInfo(field_base, width, height, COLOR_FMT_NV12_UBWC, &ycbcr[1]);
}
@@ -346,7 +347,7 @@
ycbcr->chroma_step = 2 * bpp;
}
-int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr *ycbcr) {
+int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr ycbcr[2]) {
int err = 0;
uint32_t width = UINT(hnd->width);
uint32_t height = UINT(hnd->height);
@@ -382,7 +383,7 @@
// Check metadata for interlaced content.
int interlace_flag = 0;
if (getMetaData(const_cast<private_handle_t *>(hnd),
- GET_PP_PARAM_INTERLACED, &interlace_flag) != 0) {
+ GET_PP_PARAM_INTERLACED, &interlace_flag) == 0) {
interlaced = interlace_flag;
}
@@ -772,7 +773,7 @@
return -EINVAL;
}
- struct android_ycbcr yuvInfo = {};
+ struct android_ycbcr yuvPlaneInfo[2] = {};
*num_planes = 1;
stride[0] = 0;
@@ -808,12 +809,14 @@
}
(*num_planes)++;
- int ret = GetYUVPlaneInfo(hnd, &yuvInfo);
+ int ret = GetYUVPlaneInfo(hnd, yuvPlaneInfo);
if (ret < 0) {
ALOGE("%s failed", __FUNCTION__);
return ret;
}
+ // We are only returning buffer layout for progressive or single field formats.
+ struct android_ycbcr yuvInfo = yuvPlaneInfo[0];
stride[0] = static_cast<uint32_t>(yuvInfo.ystride);
offset[0] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.y) - hnd->base);
stride[1] = static_cast<uint32_t>(yuvInfo.cstride);
diff --git a/libgralloc1/gr_utils.h b/libgralloc1/gr_utils.h
index 2a08539..4b2f136 100644
--- a/libgralloc1/gr_utils.h
+++ b/libgralloc1/gr_utils.h
@@ -71,7 +71,7 @@
unsigned int *alignedw, unsigned int *alignedh);
void GetAlignedWidthAndHeight(const BufferInfo &d, unsigned int *aligned_w,
unsigned int *aligned_h);
-int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr *ycbcr);
+int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr ycbcr[2]);
int GetRgbDataAddress(private_handle_t *hnd, void **rgb_data);
bool IsUBwcFormat(int format);
bool IsUBwcSupported(int format);
@@ -84,7 +84,7 @@
void GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, int color_format,
struct android_ycbcr *ycbcr);
void GetYuvUbwcInterlacedSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
- int color_format, struct android_ycbcr *ycbcr);
+ int color_format, struct android_ycbcr ycbcr[2]);
void GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height);
unsigned int GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp);
unsigned int GetUBwcSize(int width, int height, int format, unsigned int alignedw,
diff --git a/libqdutils/qdMetaData.cpp b/libqdutils/qdMetaData.cpp
index 0837c99..af2adf7 100644
--- a/libqdutils/qdMetaData.cpp
+++ b/libqdutils/qdMetaData.cpp
@@ -44,9 +44,8 @@
ALOGE("%s: Private handle is invalid - handle:%p", __func__, handle);
return -1;
}
- if (handle->fd_metadata == -1) {
- ALOGE("%s: Invalid metadata fd - handle:%p fd: %d",
- __func__, handle, handle->fd_metadata);
+ if (handle->fd_metadata < 0) {
+ // Silently return, metadata cannot be used
return -1;
}
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
index b6c4690..173dc4f 100644
--- a/sdm/include/private/hw_info_types.h
+++ b/sdm/include/private/hw_info_types.h
@@ -39,8 +39,10 @@
const int kMaxSDELayers = 16; // Maximum number of layers that can be handled by MDP5 hardware
// in a given layer stack.
#define MAX_PLANES 4
-
#define MAX_DETAIL_ENHANCE_CURVE 3
+#define MAJOR 28
+#define MINOR 16
+#define SDEVERSION(major, minor, hw_rev) ((major) << MAJOR) | ((minor) << MINOR) | (hw_rev)
enum HWDeviceType {
kDevicePrimary,
@@ -226,9 +228,6 @@
CompRatioMap comp_ratio_nrt_map;
uint32_t cache_size = 0; // cache size in bytes
HWQseedStepVersion pipe_qseed3_version = kQseed3v2; // only valid when has_qseed3=true
- uint64_t min_core_ib_kbps = 0;
- uint64_t min_llcc_ib_kbps = 0;
- uint64_t min_dram_ib_kbps = 0;
void Reset() { *this = HWResourceInfo(); }
};
diff --git a/sdm/libs/core/drm/hw_info_drm.cpp b/sdm/libs/core/drm/hw_info_drm.cpp
index 6f933eb..8c08451 100644
--- a/sdm/libs/core/drm/hw_info_drm.cpp
+++ b/sdm/libs/core/drm/hw_info_drm.cpp
@@ -193,7 +193,7 @@
hw_resource->has_concurrent_writeback = false;
hw_resource->has_hdr = true;
- hw_resource->hw_version = kHWMdssVersion5;
+ hw_resource->hw_version = SDEVERSION(4, 0, 1);
hw_resource->hw_revision = 0;
// TODO(user): Deprecate
@@ -286,10 +286,7 @@
hw_resource->max_bandwidth_low = info.max_bandwidth_low / kKiloUnit;
hw_resource->max_bandwidth_high = info.max_bandwidth_high / kKiloUnit;
hw_resource->max_sde_clk = info.max_sde_clk;
- hw_resource->hw_revision = info.hw_version;
- hw_resource->min_core_ib_kbps = info.min_core_ib / kKiloUnit;
- hw_resource->min_llcc_ib_kbps = info.min_llcc_ib / kKiloUnit;
- hw_resource->min_dram_ib_kbps = info.min_dram_ib / kKiloUnit;
+ hw_resource->hw_version = info.hw_version;
std::vector<LayerBufferFormat> sdm_format;
for (auto &it : info.comp_ratio_rt_map) {
diff --git a/sdm/libs/core/drm/hw_info_drm.h b/sdm/libs/core/drm/hw_info_drm.h
index 7883592..82fb175 100644
--- a/sdm/libs/core/drm/hw_info_drm.h
+++ b/sdm/libs/core/drm/hw_info_drm.h
@@ -67,8 +67,6 @@
sde_drm::DRMManagerInterface *drm_mgr_intf_ = {};
bool default_mode_ = false;
- // TODO(user): Read Mdss version from the driver
- static const int kHWMdssVersion5 = 500; // MDSS_V5
static const int kMaxStringLength = 1024;
static const int kKiloUnit = 1000;
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index ec16b79..0530db8 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -594,6 +594,7 @@
layer_stack_.flags.geometry_changed = UINT32(geometry_changes_ > 0);
// Append client target to the layer stack
Layer *sdm_client_target = client_target_->GetSDMLayer();
+ sdm_client_target->flags.updating = IsLayerUpdating(sdm_client_target);
layer_stack_.layers.push_back(sdm_client_target);
// fall back frame composition to GPU when client target is 10bit
// TODO(user): clarify the behaviour from Client(SF) and SDM Extn -
@@ -1956,6 +1957,10 @@
}
bool HWCDisplay::CanSkipValidate() {
+ if (solid_fill_enable_) {
+ return false;
+ }
+
// Layer Stack checks
if (layer_stack_.flags.hdr_present && (tone_mapper_ && tone_mapper_->IsActive())) {
return false;
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index 250b491..654cba5 100644
--- a/sdm/libs/hwc2/hwc_display.h
+++ b/sdm/libs/hwc2/hwc_display.h
@@ -160,7 +160,7 @@
int GetVisibleDisplayRect(hwc_rect_t *rect);
void BuildLayerStack(void);
void BuildSolidFillStack(void);
- HWCLayer *GetHWCLayer(hwc2_layer_t layer);
+ HWCLayer *GetHWCLayer(hwc2_layer_t layer_id);
void ResetValidation() { validated_ = false; }
uint32_t GetGeometryChanges() { return geometry_changes_; }
diff --git a/sdm/libs/hwc2/hwc_layers.cpp b/sdm/libs/hwc2/hwc_layers.cpp
index 7761791..6a33b8f 100644
--- a/sdm/libs/hwc2/hwc_layers.cpp
+++ b/sdm/libs/hwc2/hwc_layers.cpp
@@ -326,6 +326,10 @@
}
HWC2::Error HWCLayer::SetLayerCompositionType(HWC2::Composition type) {
+ // Validation is required when the client changes the composition type
+ if (client_requested_ != type) {
+ needs_validate_ = true;
+ }
client_requested_ = type;
switch (type) {
case HWC2::Composition::Client:
@@ -412,8 +416,13 @@
}
HWC2::Error HWCLayer::SetLayerPlaneAlpha(float alpha) {
- // Conversion of float alpha in range 0.0 to 1.0 similar to the HWC Adapter
+ if (alpha < 0.0f || alpha > 1.0f) {
+ return HWC2::Error::BadParameter;
+ }
+
+ // Conversion of float alpha in range 0.0 to 1.0 similar to the HWC Adapter
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;
@@ -463,8 +472,10 @@
layer_transform.flip_vertical = true;
break;
case HWC2::Transform::None:
- // do nothing
break;
+ default:
+ // bad transform
+ return HWC2::Error::BadParameter;
}
if (layer_transform_ != layer_transform) {
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index f8a0d28..99fbc1a 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -483,14 +483,20 @@
}
static int32_t GetDozeSupport(hwc2_device_t *device, hwc2_display_t display, int32_t *out_support) {
+ if (!device || !out_support) {
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
+
+ if (display >= HWC_NUM_DISPLAY_TYPES) {
+ return HWC2_ERROR_BAD_DISPLAY;
+ }
+
if (display == HWC_DISPLAY_PRIMARY) {
*out_support = 1;
} else {
- // TODO(user): Port over connect_display_ from HWC1
- // Return no error for connected displays
*out_support = 0;
- return HWC2_ERROR_BAD_DISPLAY;
}
+
return HWC2_ERROR_NONE;
}
@@ -663,14 +669,19 @@
int32_t HWCSession::SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display,
hwc2_layer_t layer, uint32_t z) {
+ if (display >= HWC_NUM_DISPLAY_TYPES) {
+ return HWC2_ERROR_BAD_DISPLAY;
+ }
+
SCOPE_LOCK(locker_[display]);
+
return CallDisplayFunction(device, display, &HWCDisplay::SetLayerZOrder, layer, z);
}
int32_t HWCSession::SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
buffer_handle_t buffer, int32_t releaseFence) {
if (!device) {
- return HWC2_ERROR_BAD_DISPLAY;
+ return HWC2_ERROR_BAD_PARAMETER;
}
if (display != HWC_DISPLAY_VIRTUAL) {
@@ -689,24 +700,51 @@
}
int32_t HWCSession::SetPowerMode(hwc2_device_t *device, hwc2_display_t display, int32_t int_mode) {
+ if (display >= HWC_NUM_DISPLAY_TYPES) {
+ return HWC2_ERROR_BAD_DISPLAY;
+ }
+
+ // validate device and also avoid undefined behavior in cast to HWC2::PowerMode
+ if (!device || int_mode < HWC2_POWER_MODE_OFF || int_mode > HWC2_POWER_MODE_DOZE_SUSPEND) {
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
+
auto mode = static_cast<HWC2::PowerMode>(int_mode);
+
+ // all displays support on/off. Check for doze modes
+ int support = 0;
+ GetDozeSupport(device, display, &support);
+ if (!support && (mode == HWC2::PowerMode::Doze || mode == HWC2::PowerMode::DozeSuspend)) {
+ return HWC2_ERROR_UNSUPPORTED;
+ }
+
SEQUENCE_WAIT_SCOPE_LOCK(locker_[display]);
return CallDisplayFunction(device, display, &HWCDisplay::SetPowerMode, mode);
}
static int32_t SetVsyncEnabled(hwc2_device_t *device, hwc2_display_t display, int32_t int_enabled) {
+ // avoid undefined behavior in cast to HWC2::Vsync
+ if (int_enabled < HWC2_VSYNC_INVALID || int_enabled > HWC2_VSYNC_DISABLE) {
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
+
auto enabled = static_cast<HWC2::Vsync>(int_enabled);
return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetVsyncEnabled, enabled);
}
int32_t HWCSession::ValidateDisplay(hwc2_device_t *device, hwc2_display_t display,
uint32_t *out_num_types, uint32_t *out_num_requests) {
- DTRACE_SCOPED();
- HWCSession *hwc_session = static_cast<HWCSession *>(device);
+ // out_num_types and out_num_requests will be non-NULL
if (!device) {
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
+
+ if (display >= HWC_NUM_DISPLAY_TYPES) {
return HWC2_ERROR_BAD_DISPLAY;
}
+ DTRACE_SCOPED();
+ HWCSession *hwc_session = static_cast<HWCSession *>(device);
// TODO(user): Handle secure session, handle QDCM solid fill
// Handle external_pending_connect_ in CreateVirtualDisplay
auto status = HWC2::Error::BadDisplay;
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
index 3659370..df58093 100644
--- a/sdm/libs/hwc2/hwc_session.h
+++ b/sdm/libs/hwc2/hwc_session.h
@@ -99,6 +99,10 @@
hwc2_layer_t layer, HWC2::Error (HWCLayer::*member)(Args...),
Args... args) {
if (!device) {
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
+
+ if (display >= HWC_NUM_DISPLAY_TYPES) {
return HWC2_ERROR_BAD_DISPLAY;
}
diff --git a/sdm/libs/hwc2/hwc_session_services.cpp b/sdm/libs/hwc2/hwc_session_services.cpp
index a5cf66a..52eaf7a 100644
--- a/sdm/libs/hwc2/hwc_session_services.cpp
+++ b/sdm/libs/hwc2/hwc_session_services.cpp
@@ -94,22 +94,25 @@
isDisplayConnected_cb _hidl_cb) {
int32_t error = -EINVAL;
bool connected = false;
-
int disp_id = MapDisplayType(dpy);
- SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
- if (disp_id >= 0) {
- connected = hwc_display_[disp_id];
- error = 0;
+ if (disp_id < HWC_DISPLAY_PRIMARY || disp_id >= HWC_NUM_DISPLAY_TYPES) {
+ _hidl_cb(error, connected);
+ return Void();
}
- _hidl_cb(error, connected);
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
+ connected = hwc_display_[disp_id];
+ error = 0;
+
+ _hidl_cb(error, connected);
return Void();
}
int32_t HWCSession::SetSecondaryDisplayStatus(int disp_id, HWCDisplay::DisplayStatus status) {
- if (disp_id < 0) {
+ if (disp_id < HWC_DISPLAY_PRIMARY || disp_id >= HWC_NUM_DISPLAY_TYPES) {
+ DLOGE("Invalid display = %d", disp_id);
return -EINVAL;
}