Merge remote-tracking branch 'quic/display.lnx.5.0' into tip
2/7/2019 FF
Change-Id: I78cdd49ab0f4da7ec24e9009ee5dd2cf0cb94ada
CRs-Fixed: 2395201
diff --git a/common.mk b/common.mk
index 0d81828..e2f3c4c 100644
--- a/common.mk
+++ b/common.mk
@@ -3,8 +3,13 @@
#Get the highest display config version available
display_config_version := $(shell \
+ if [ -d "$(TOP)/vendor/qcom/opensource/interfaces/display/config/1.8" ];\
+ then echo DISPLAY_CONFIG_1_8; fi)
+ifeq ($(display_config_version),)
+display_config_version := $(shell \
if [ -d "$(TOP)/vendor/qcom/opensource/interfaces/display/config/1.7" ];\
then echo DISPLAY_CONFIG_1_7; fi)
+endif
ifeq ($(display_config_version),)
display_config_version := $(shell \
if [ -d "$(TOP)/vendor/qcom/opensource/interfaces/display/config/1.6" ];\
@@ -71,6 +76,11 @@
common_flags += -DDISPLAY_CONFIG_1_6 -DDISPLAY_CONFIG_1_5 -DDISPLAY_CONFIG_1_4
common_flags += -DDISPLAY_CONFIG_1_3 -DDISPLAY_CONFIG_1_2 -DDISPLAY_CONFIG_1_1
endif
+ifeq ($(display_config_version), DISPLAY_CONFIG_1_8)
+ common_flags += -DDISPLAY_CONFIG_1_1 -DDISPLAY_CONFIG_1_2 -DDISPLAY_CONFIG_1_3
+ common_flags += -DDISPLAY_CONFIG_1_4 -DDISPLAY_CONFIG_1_5 -DDISPLAY_CONFIG_1_6
+ common_flags += -DDISPLAY_CONFIG_1_7 -DDISPLAY_CONFIG_1_8
+endif
ifeq ($(TARGET_USES_COLOR_METADATA), true)
common_flags += -DUSE_COLOR_METADATA
diff --git a/config/msmnile.mk b/config/msmnile.mk
index 8ffac4b..70e755d 100644
--- a/config/msmnile.mk
+++ b/config/msmnile.mk
@@ -28,6 +28,13 @@
PRODUCT_COPY_FILES += hardware/qcom/display/config/qdcm_calib_data_sw43404_amoled_cmd_mode_dsi_boe_panel_with_DSC.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_sw43404_amoled_cmd_mode_dsi_boe_panel_with_DSC.xml
PRODUCT_COPY_FILES += hardware/qcom/display/config/qdcm_calib_data_sw43404_amoled_cmd_mode_dsi_boe_panel_with_DSC.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_sw43404_amoled_video_mode_dsi_boe_panel_with_DSC.xml
+#QDCM calibration xml file for primary panel sharp 1080p
+PRODUCT_COPY_FILES += hardware/qcom/display/config/qdcm_calib_data_nt35597_cmd_mode_dsi_truly_panel_with_DSC.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_sharp_1080p_cmd_mode_dsi_panel.xml
+
+#QDCM calibration xml file for secondary panel nt35695b
+PRODUCT_COPY_FILES += hardware/qcom/display/config/qdcm_calib_data_nt35597_cmd_mode_dsi_truly_panel_with_DSC.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_nt35695b_truly_fhd_command_mode_dsi_panel.xml
+PRODUCT_COPY_FILES += hardware/qcom/display/config/qdcm_calib_data_nt35597_cmd_mode_dsi_truly_panel_with_DSC.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_nt35695b_truly_fhd_video_mode_dsi_panel.xml
+
#Enable Charging Icon
TARGET_RECOVERY_PIXEL_FORMAT := RGBX_8888
diff --git a/config/talos.mk b/config/talos.mk
index ba58459..ba69f37 100644
--- a/config/talos.mk
+++ b/config/talos.mk
@@ -30,6 +30,10 @@
PRODUCT_COPY_FILES += hardware/qcom/display/config/qdcm_calib_data_nt35597_cmd_mode_dsi_truly_panel_with_DSC.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_sw43404_amoled_cmd_mode_dsi_boe_panel_with_DSC.xml
PRODUCT_COPY_FILES += hardware/qcom/display/config/qdcm_calib_data_nt35597_cmd_mode_dsi_truly_panel_with_DSC.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_sw43404_amoled_video_mode_dsi_boe_panel_with_DSC.xml
+#QDCM calibration xml file for secondary panel nt35695b
+PRODUCT_COPY_FILES += hardware/qcom/display/config/qdcm_calib_data_nt35597_cmd_mode_dsi_truly_panel_with_DSC.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_nt35695b_truly_fhd_command_mode_dsi_panel.xml
+PRODUCT_COPY_FILES += hardware/qcom/display/config/qdcm_calib_data_nt35597_cmd_mode_dsi_truly_panel_with_DSC.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_nt35695b_truly_fhd_video_mode_dsi_panel.xml
+
#Enable Charging Icon
TARGET_RECOVERY_PIXEL_FORMAT := RGBX_8888
diff --git a/config/trinket.mk b/config/trinket.mk
index 3f0cce5..d56de38 100644
--- a/config/trinket.mk
+++ b/config/trinket.mk
@@ -19,7 +19,8 @@
modetest
#QDCM calibration xml file
-PRODUCT_COPY_FILES += hardware/qcom/display/config/qdcm_calib_data_nt35597_cmd_mode_dsi_truly_panel_with_DSC.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_hx83112a_video_mode_dsi_truly_panel.xml
+PRODUCT_COPY_FILES += hardware/qcom/display/config/qdcm_calib_data_nt35597_cmd_mode_dsi_truly_panel_with_DSC.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_td4330_cmd_mode_dsi_truly_panel.xml
+PRODUCT_COPY_FILES += hardware/qcom/display/config/qdcm_calib_data_nt35597_cmd_mode_dsi_truly_panel_with_DSC.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_td4330_video_mode_dsi_truly_panel.xml
#Enable Charging Icon
TARGET_RECOVERY_PIXEL_FORMAT := RGBX_8888
diff --git a/gralloc/gr_priv_handle.h b/gralloc/gr_priv_handle.h
index ace762e..0968c5c 100644
--- a/gralloc/gr_priv_handle.h
+++ b/gralloc/gr_priv_handle.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2019, The Linux Foundation. All rights reserved.
* Not a Contribution
*
* Copyright (C) 2008 The Android Open Source Project
@@ -23,7 +23,9 @@
#include <log/log.h>
#include <hardware/gralloc.h>
#include <hardware/gralloc1.h>
+#ifdef __cplusplus
#include <cinttypes>
+#endif
#define GRALLOC1_FUNCTION_PERFORM 0x00001000
@@ -34,7 +36,12 @@
#define PRIV_HANDLE_CONST(exp) static_cast<const private_handle_t *>(exp)
#pragma pack(push, 4)
+#ifdef __cplusplus
struct private_handle_t : public native_handle_t {
+#else
+struct private_handle_t {
+ native_handle_t nativeHandle;
+#endif
enum {
PRIV_FLAGS_FRAMEBUFFER = 0x00000001,
PRIV_FLAGS_USES_ION = 0x00000008,
@@ -85,7 +92,7 @@
uint64_t base;
uint64_t base_metadata;
uint64_t gpuaddr;
-
+#ifdef __cplusplus
static const int kNumFds = 2;
static const int kMagic = 'gmsm';
@@ -175,6 +182,7 @@
uint64_t GetUsage() const { return usage; }
uint64_t GetBackingstore() const { return id; }
+#endif
};
#pragma pack(pop)
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index 20e3abc..4a47469 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+* Copyright (c) 2017-2019, 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
@@ -585,6 +585,7 @@
int hmin;
bool roi_merge;
uint64_t bit_clk_rate;
+ uint32_t transfer_time_us;
};
/* Per Connector Info*/
@@ -604,7 +605,6 @@
uint32_t max_linewidth;
DRMRotation panel_orientation;
drm_panel_hdr_properties panel_hdr_prop;
- uint32_t transfer_time_us;
drm_msm_ext_hdr_properties ext_hdr_prop;
bool qsync_support;
// Connection status of this connector
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index 569c4ea..e19eccc 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2014, 2016-2018 The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2014, 2016-2019 The Linux Foundation. All rights reserved.
*
* Not a Contribution, Apache license notifications and license are
* retained for attribution purposes only.
@@ -84,6 +84,7 @@
SET_DSI_CLK = 42, // Set DSI Clk.
GET_DSI_CLK = 43, // Get DSI Clk.
GET_SUPPORTED_DSI_CLK = 44, // Get supported DSI Clk.
+ SET_COLOR_MODE_FROM_CLIENT = 45, // Overrides the QDCM mode using the given mode ID
COMMAND_LIST_END = 400,
};
diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h
index 7ef2f6f..1b4d063 100644
--- a/sdm/include/core/display_interface.h
+++ b/sdm/include/core/display_interface.h
@@ -797,6 +797,11 @@
*/
virtual bool IsSupportSsppTonemap() = 0;
+ /*! @brief Method to free concurrent writeback resoures for primary display.
+ @return \link DisplayError \endlink
+ */
+ virtual DisplayError TeardownConcurrentWriteback(void) = 0;
+
/*
* Returns a string consisting of a dump of SDM's display and layer related state
* as programmed to driver
diff --git a/sdm/include/private/resource_interface.h b/sdm/include/private/resource_interface.h
index 14f156b..fa4efb6 100644
--- a/sdm/include/private/resource_interface.h
+++ b/sdm/include/private/resource_interface.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2015 - 2018, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015 - 2019, 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:
@@ -36,6 +36,7 @@
kCmdResetLUT,
kCmdGetDefaultClk,
kCmdDisableRotatorOneFrame,
+ kCmdSetDisplayState,
kCmdMax,
};
diff --git a/sdm/libs/core/comp_manager.cpp b/sdm/libs/core/comp_manager.cpp
index d053c84..eadb497 100644
--- a/sdm/libs/core/comp_manager.cpp
+++ b/sdm/libs/core/comp_manager.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2019, 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:
@@ -545,6 +545,9 @@
DisplayCompositionContext *display_comp_ctx =
reinterpret_cast<DisplayCompositionContext *>(display_ctx);
+ resource_intf_->Perform(ResourceInterface::kCmdSetDisplayState,
+ display_comp_ctx->display_resource_ctx, state);
+
switch (state) {
case kStateOff:
Purge(display_ctx);
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 1db20ba..fb88ae3 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -1423,7 +1423,8 @@
uint32_t hw_layers_count = UINT32(hw_layers_.info.hw_layers.size());
for (uint32_t i = 0; i < hw_layers_count; i++) {
- Layer *sdm_layer = layer_stack->layers.at(hw_layers_.info.index.at(i));
+ uint32_t sdm_layer_index = hw_layers_.info.index.at(i);
+ Layer *sdm_layer = layer_stack->layers.at(sdm_layer_index);
Layer &hw_layer = hw_layers_.info.hw_layers.at(i);
hw_layer.input_buffer.planes[0].fd = sdm_layer->input_buffer.planes[0].fd;
@@ -1432,6 +1433,12 @@
hw_layer.input_buffer.size = sdm_layer->input_buffer.size;
hw_layer.input_buffer.acquire_fence_fd = sdm_layer->input_buffer.acquire_fence_fd;
hw_layer.input_buffer.handle_id = sdm_layer->input_buffer.handle_id;
+ // TODO(user): Other FBT layer attributes like surface damage, dataspace, secure camera and
+ // secure display flags are also updated during SetClientTarget() called between validate and
+ // commit. Need to revist this and update it accordingly for FBT layer.
+ if (hw_layers_.info.gpu_target_index == sdm_layer_index) {
+ hw_layer.input_buffer.flags.secure = sdm_layer->input_buffer.flags.secure;
+ }
}
return;
diff --git a/sdm/libs/core/display_builtin.cpp b/sdm/libs/core/display_builtin.cpp
index ab6ec16..c8496ac 100644
--- a/sdm/libs/core/display_builtin.cpp
+++ b/sdm/libs/core/display_builtin.cpp
@@ -275,6 +275,12 @@
return error;
}
+DisplayError DisplayBuiltIn::TeardownConcurrentWriteback(void) {
+ lock_guard<recursive_mutex> obj(recursive_mutex_);
+
+ return hw_intf_->TeardownConcurrentWriteback();
+}
+
DisplayError DisplayBuiltIn::SetRefreshRate(uint32_t refresh_rate, bool final_rate) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
diff --git a/sdm/libs/core/display_builtin.h b/sdm/libs/core/display_builtin.h
index ffebcb3..a399a67 100644
--- a/sdm/libs/core/display_builtin.h
+++ b/sdm/libs/core/display_builtin.h
@@ -88,6 +88,7 @@
virtual void PingPongTimeout();
virtual void PanelDead();
virtual void HwRecovery(const HWRecoveryEvent sdm_event_code);
+ virtual DisplayError TeardownConcurrentWriteback(void);
// Implement the DppsPropIntf
virtual DisplayError DppsProcessOps(enum DppsOps op, void *payload, size_t size);
diff --git a/sdm/libs/core/display_pluggable.h b/sdm/libs/core/display_pluggable.h
index d15129c..7716da3 100644
--- a/sdm/libs/core/display_pluggable.h
+++ b/sdm/libs/core/display_pluggable.h
@@ -56,6 +56,7 @@
virtual DisplayError SetColorTransform(const uint32_t length, const double *color_transform) {
return kErrorNone;
}
+ virtual DisplayError TeardownConcurrentWriteback(void) { return kErrorNotSupported; }
// Implement the HWEventHandlers
virtual DisplayError VSync(int64_t timestamp);
diff --git a/sdm/libs/core/display_virtual.cpp b/sdm/libs/core/display_virtual.cpp
index 21a7890..bf53c66 100644
--- a/sdm/libs/core/display_virtual.cpp
+++ b/sdm/libs/core/display_virtual.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2019, 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:
@@ -131,16 +131,16 @@
fb_config = display_attributes;
}
- // if display is already connected, unregister display from composition manager and register
- // the display with new configuration.
- if (display_comp_ctx_) {
- comp_manager_->UnregisterDisplay(display_comp_ctx_);
+ // if display is already connected, reconfigure the display with new configuration.
+ if (!display_comp_ctx_) {
+ error = comp_manager_->RegisterDisplay(display_id_, display_type_, display_attributes,
+ hw_panel_info, mixer_attributes, fb_config,
+ &display_comp_ctx_, &(default_qos_data_.clock_hz));
+ } else {
+ error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes, hw_panel_info,
+ mixer_attributes, fb_config,
+ &(default_qos_data_.clock_hz));
}
-
- error =
- comp_manager_->RegisterDisplay(display_id_, display_type_, display_attributes, hw_panel_info,
- mixer_attributes, fb_config, &display_comp_ctx_,
- &(default_qos_data_.clock_hz));
if (error != kErrorNone) {
return error;
}
diff --git a/sdm/libs/core/display_virtual.h b/sdm/libs/core/display_virtual.h
index e3daec6..1a672e1 100644
--- a/sdm/libs/core/display_virtual.h
+++ b/sdm/libs/core/display_virtual.h
@@ -69,6 +69,7 @@
virtual DisplayError SetColorTransform(const uint32_t length, const double *color_transform) {
return kErrorNone;
}
+ virtual DisplayError TeardownConcurrentWriteback(void) { return kErrorNotSupported; }
virtual DisplayError GetColorModeCount(uint32_t *mode_count);
};
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index d8a82f7..51a47c8 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+* Copyright (c) 2017-2019, 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
@@ -648,6 +648,7 @@
hw_panel_info_.min_roi_width = connector_info_.modes[index].wmin;
hw_panel_info_.min_roi_height = connector_info_.modes[index].hmin;
hw_panel_info_.needs_roi_merge = connector_info_.modes[index].roi_merge;
+ hw_panel_info_.transfer_time_us = connector_info_.modes[index].transfer_time_us;
hw_panel_info_.dynamic_fps = connector_info_.dynamic_fps;
hw_panel_info_.qsync_support = connector_info_.qsync_support;
drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
@@ -686,7 +687,6 @@
hw_panel_info_.primaries.green[1] = connector_info_.panel_hdr_prop.display_primaries[5];
hw_panel_info_.primaries.blue[0] = connector_info_.panel_hdr_prop.display_primaries[6];
hw_panel_info_.primaries.blue[1] = connector_info_.panel_hdr_prop.display_primaries[7];
- hw_panel_info_.transfer_time_us = connector_info_.transfer_time_us;
hw_panel_info_.dyn_bitclk_support = connector_info_.dyn_bitclk_support;
// no supprt for 90 rotation only flips or 180 supported
@@ -1940,6 +1940,11 @@
AddSolidfillStage(sf, 0xFF);
SetSolidfillStages();
}
+
+ if (!secure_display_active_) {
+ DRMSecurityLevel crtc_security_level = DRMSecurityLevel::SECURE_NON_SECURE;
+ drm_atomic_intf_->Perform(DRMOps::CRTC_SET_SECURITY_LEVEL, token_.crtc_id, crtc_security_level);
+ }
}
DisplayError HWDeviceDRM::NullCommit(bool synchronous, bool retain_planes) {
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index f8ae241..5be5fad 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -113,6 +113,7 @@
virtual void PopulateHWPanelInfo();
virtual DisplayError SetDppsFeature(void *payload, size_t size) { return kErrorNotSupported; }
virtual DisplayError GetDppsFeatureInfo(void *payload, size_t size) { return kErrorNotSupported; }
+ virtual DisplayError TeardownConcurrentWriteback(void) { return kErrorNotSupported; }
virtual DisplayError HandleSecureEvent(SecureEvent secure_event, HWLayers *hw_layers) {
return kErrorNotSupported;
}
diff --git a/sdm/libs/core/drm/hw_peripheral_drm.cpp b/sdm/libs/core/drm/hw_peripheral_drm.cpp
index ecd0651..0bc95cd 100644
--- a/sdm/libs/core/drm/hw_peripheral_drm.cpp
+++ b/sdm/libs/core/drm/hw_peripheral_drm.cpp
@@ -334,6 +334,16 @@
}
}
+DisplayError HWPeripheralDRM::TeardownConcurrentWriteback(void) {
+ if (cwb_config_.enabled) {
+ drm_mgr_intf_->UnregisterDisplay(cwb_config_.token);
+ cwb_config_.enabled = false;
+ registry_.Clear();
+ }
+
+ return kErrorNone;
+}
+
DisplayError HWPeripheralDRM::SetupConcurrentWritebackModes() {
// To setup Concurrent Writeback topology, get the Connector ID of Virtual display
if (drm_mgr_intf_->RegisterDisplay(DRMDisplayType::VIRTUAL, &cwb_config_.token)) {
@@ -402,9 +412,7 @@
bool enabled = hw_resource_.has_concurrent_writeback && output_buffer;
if (!enabled) {
- drm_mgr_intf_->UnregisterDisplay(cwb_config_.token);
- cwb_config_.enabled = false;
- registry_.Clear();
+ TeardownConcurrentWriteback();
}
}
diff --git a/sdm/libs/core/drm/hw_peripheral_drm.h b/sdm/libs/core/drm/hw_peripheral_drm.h
index 12d2e6c..518657d 100644
--- a/sdm/libs/core/drm/hw_peripheral_drm.h
+++ b/sdm/libs/core/drm/hw_peripheral_drm.h
@@ -60,6 +60,7 @@
virtual DisplayError SetDynamicDSIClock(uint64_t bit_clk_rate);
virtual DisplayError GetDynamicDSIClock(uint64_t *bit_clk_rate);
virtual DisplayError SetDisplayAttributes(uint32_t index);
+ virtual DisplayError TeardownConcurrentWriteback(void);
private:
void SetDestScalarData(HWLayersInfo hw_layer_info, bool validate);
diff --git a/sdm/libs/core/fb/hw_device.h b/sdm/libs/core/fb/hw_device.h
index dad5fe5..5f451dc 100644
--- a/sdm/libs/core/fb/hw_device.h
+++ b/sdm/libs/core/fb/hw_device.h
@@ -112,6 +112,7 @@
virtual DisplayError SetDisplayDppsAdROI(void *payload) { return kErrorNotSupported; }
virtual DisplayError SetDynamicDSIClock(uint64_t bit_clk_rate);
virtual DisplayError GetDynamicDSIClock(uint64_t *bit_clk_rate);
+ virtual DisplayError TeardownConcurrentWriteback(void) { return kErrorNotSupported; }
enum {
kHWEventVSync,
diff --git a/sdm/libs/core/hw_interface.h b/sdm/libs/core/hw_interface.h
index 119a95f..240517a 100644
--- a/sdm/libs/core/hw_interface.h
+++ b/sdm/libs/core/hw_interface.h
@@ -123,6 +123,7 @@
virtual DisplayError SetDisplayDppsAdROI(void *payload) = 0;
virtual DisplayError SetDynamicDSIClock(uint64_t bit_clk_rate) = 0;
virtual DisplayError GetDynamicDSIClock(uint64_t *bit_clk_rate) = 0;
+ virtual DisplayError TeardownConcurrentWriteback(void) = 0;
protected:
virtual ~HWInterface() { }
diff --git a/sdm/libs/hwc2/Android.mk b/sdm/libs/hwc2/Android.mk
index 14ae3ba..a9052e0 100644
--- a/sdm/libs/hwc2/Android.mk
+++ b/sdm/libs/hwc2/Android.mk
@@ -69,7 +69,16 @@
LOCAL_SHARED_LIBRARIES += vendor.display.config@1.6
LOCAL_SHARED_LIBRARIES += vendor.display.config@1.7
endif
-
+ifeq ($(display_config_version), DISPLAY_CONFIG_1_8)
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.1
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.2
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.3
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.4
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.5
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.6
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.7
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.8
+endif
LOCAL_SRC_FILES := hwc_session.cpp \
hwc_session_services.cpp \
diff --git a/sdm/libs/hwc2/display_null.h b/sdm/libs/hwc2/display_null.h
index 29f31b0..2dcb9c9 100644
--- a/sdm/libs/hwc2/display_null.h
+++ b/sdm/libs/hwc2/display_null.h
@@ -58,6 +58,7 @@
virtual std::string Dump() { return ""; }
virtual bool IsSupportSsppTonemap() { return false; }
+ MAKE_NO_OP(TeardownConcurrentWriteback(void))
MAKE_NO_OP(Commit(LayerStack *))
MAKE_NO_OP(GetDisplayState(DisplayState *))
MAKE_NO_OP(SetDisplayState(DisplayState, bool, int*))
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index 0e2e117..d49da4c 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -802,6 +802,9 @@
// Append client target to the layer stack
Layer *sdm_client_target = client_target_->GetSDMLayer();
sdm_client_target->flags.updating = IsLayerUpdating(client_target_);
+ // Derive client target dataspace based on the color mode - bug/115482728
+ int32_t client_target_dataspace = GetDataspaceFromColorMode(GetCurrentColorMode());
+ SetClientTargetDataSpace(client_target_dataspace);
layer_stack_.layers.push_back(sdm_client_target);
// fall back frame composition to GPU when client target is 10bit
@@ -826,7 +829,7 @@
HWC2::Error HWCDisplay::SetLayerZOrder(hwc2_layer_t layer_id, uint32_t z) {
const auto map_layer = layer_map_.find(layer_id);
if (map_layer == layer_map_.end()) {
- DLOGE("[%" PRIu64 "] updateLayerZ failed to find layer", id_);
+ DLOGW("[%" PRIu64 "] updateLayerZ failed to find layer", id_);
return HWC2::Error::BadLayer;
}
@@ -1154,12 +1157,11 @@
Layer *sdm_layer = client_target_->GetSDMLayer();
sdm_layer->frame_rate = std::min(current_refresh_rate_, HWCDisplay::GetThrottlingRefreshRate());
client_target_->SetLayerSurfaceDamage(damage);
- if (client_target_->GetLayerDataspace() != dataspace) {
- client_target_->SetLayerDataspace(dataspace);
- Layer *sdm_layer = client_target_->GetSDMLayer();
- // Data space would be validated at GetClientTargetSupport, so just use here.
- sdm::GetSDMColorSpace(client_target_->GetLayerDataspace(),
- &sdm_layer->input_buffer.color_metadata);
+ int translated_dataspace = TranslateFromLegacyDataspace(dataspace);
+ if (client_target_->GetLayerDataspace() != translated_dataspace) {
+ DLOGW("New Dataspace = %d not matching Dataspace from color mode = %d",
+ translated_dataspace, client_target_->GetLayerDataspace());
+ return HWC2::Error::BadParameter;
}
client_target_->SetLayerBuffer(target, acquire_fence);
@@ -1847,11 +1849,6 @@
return -EINVAL;
}
- if (display_status == kDisplayStatusResume || display_status == kDisplayStatusPause) {
- callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
- validated_ = false;
- }
-
return status;
}
@@ -2305,4 +2302,16 @@
}
}
+int32_t HWCDisplay::SetClientTargetDataSpace(int32_t dataspace) {
+ if (client_target_->GetLayerDataspace() != dataspace) {
+ client_target_->SetLayerDataspace(dataspace);
+ Layer *sdm_layer = client_target_->GetSDMLayer();
+ // Data space would be validated at GetClientTargetSupport, so just use here.
+ sdm::GetSDMColorSpace(client_target_->GetLayerDataspace(),
+ &sdm_layer->input_buffer.color_metadata);
+ }
+
+ return 0;
+}
+
} // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index dd89f97..c38c6bb 100644
--- a/sdm/libs/hwc2/hwc_display.h
+++ b/sdm/libs/hwc2/hwc_display.h
@@ -157,6 +157,9 @@
virtual DisplayError GetMixerResolution(uint32_t *width, uint32_t *height);
virtual void GetPanelResolution(uint32_t *width, uint32_t *height);
virtual std::string Dump();
+ virtual DisplayError TeardownConcurrentWriteback(void) {
+ return kErrorNotSupported;
+ }
// Captures frame output in the buffer specified by output_buffer_info. The API is
// non-blocking and the client is expected to check operation status later on.
@@ -339,6 +342,7 @@
bool IsLayerUpdating(HWCLayer *layer);
uint32_t SanitizeRefreshRate(uint32_t req_refresh_rate);
virtual void GetUnderScanConfig() { }
+ int32_t SetClientTargetDataSpace(int32_t dataspace);
enum {
INPUT_LAYER_DUMP,
diff --git a/sdm/libs/hwc2/hwc_display_builtin.cpp b/sdm/libs/hwc2/hwc_display_builtin.cpp
index dbac21a..4948c14 100644
--- a/sdm/libs/hwc2/hwc_display_builtin.cpp
+++ b/sdm/libs/hwc2/hwc_display_builtin.cpp
@@ -287,7 +287,7 @@
DLOGE("failed for mode = %d intent = %d", mode, intent);
return status;
}
- callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
+ callbacks_->Refresh(id_);
validated_ = false;
return status;
}
@@ -299,7 +299,7 @@
return status;
}
- callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
+ callbacks_->Refresh(id_);
validated_ = false;
return status;
@@ -331,7 +331,7 @@
return status;
}
- callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
+ callbacks_->Refresh(id_);
return status;
}
@@ -349,7 +349,7 @@
return status;
}
- callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
+ callbacks_->Refresh(id_);
color_tranform_failed_ = false;
validated_ = false;
@@ -402,6 +402,28 @@
return status;
}
+DisplayError HWCDisplayBuiltIn::TeardownConcurrentWriteback(void) {
+ DisplayError error = kErrorNotSupported;
+
+ if (output_buffer_.release_fence_fd >= 0) {
+ int32_t release_fence_fd = dup(output_buffer_.release_fence_fd);
+ int ret = sync_wait(output_buffer_.release_fence_fd, 1000);
+ if (ret < 0) {
+ DLOGE("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
+ }
+
+ ::close(release_fence_fd);
+ if (ret)
+ return kErrorResources;
+ }
+
+ if (display_intf_) {
+ error = display_intf_->TeardownConcurrentWriteback();
+ }
+
+ return error;
+}
+
HWC2::Error HWCDisplayBuiltIn::SetDisplayDppsAdROI(uint32_t h_start, uint32_t h_end,
uint32_t v_start, uint32_t v_end,
uint32_t factor_in, uint32_t factor_out) {
@@ -437,7 +459,7 @@
if (error)
return HWC2::Error::BadConfig;
- callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
+ callbacks_->Refresh(id_);
return HWC2::Error::None;
}
@@ -538,6 +560,10 @@
return -EINVAL;
}
+ if (current_power_mode_ != HWC2::PowerMode::On) {
+ return 0;
+ }
+
if (active_secure_sessions_[kSecureDisplay] != secure_sessions[kSecureDisplay]) {
SecureEvent secure_event =
secure_sessions.test(kSecureDisplay) ? kSecureDisplayStart : kSecureDisplayEnd;
@@ -565,7 +591,7 @@
force_refresh_rate_ = refresh_rate;
- callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
+ callbacks_->Refresh(id_);
return;
}
@@ -583,7 +609,7 @@
DisplayError HWCDisplayBuiltIn::Refresh() {
DisplayError error = kErrorNone;
- callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
+ callbacks_->Refresh(id_);
return error;
}
diff --git a/sdm/libs/hwc2/hwc_display_builtin.h b/sdm/libs/hwc2/hwc_display_builtin.h
index 682e54f..d4c81e2 100644
--- a/sdm/libs/hwc2/hwc_display_builtin.h
+++ b/sdm/libs/hwc2/hwc_display_builtin.h
@@ -87,6 +87,7 @@
virtual DisplayError SetDynamicDSIClock(uint64_t bitclk);
virtual DisplayError GetDynamicDSIClock(uint64_t *bitclk);
virtual DisplayError GetSupportedDSIClock(std::vector<uint64_t> *bitclk_rates);
+ virtual DisplayError TeardownConcurrentWriteback(void);
private:
HWCDisplayBuiltIn(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
diff --git a/sdm/libs/hwc2/hwc_display_virtual.cpp b/sdm/libs/hwc2/hwc_display_virtual.cpp
index 7e9deb9..acad061 100644
--- a/sdm/libs/hwc2/hwc_display_virtual.cpp
+++ b/sdm/libs/hwc2/hwc_display_virtual.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014-2019, 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
@@ -104,6 +104,9 @@
int HWCDisplayVirtual::Deinit() {
int status = 0;
if (output_buffer_) {
+ if (output_buffer_->acquire_fence_fd >= 0) {
+ close(output_buffer_->acquire_fence_fd);
+ }
delete output_buffer_;
output_buffer_ = nullptr;
}
@@ -195,10 +198,6 @@
status = HWCDisplay::PostCommitLayerStack(out_retire_fence);
- if (output_buffer_->acquire_fence_fd >= 0) {
- close(output_buffer_->acquire_fence_fd);
- output_buffer_->acquire_fence_fd = -1;
- }
return status;
}
@@ -221,6 +220,11 @@
}
const private_handle_t *output_handle = static_cast<const private_handle_t *>(buf);
+ // Close the previous acquire fence and update with the latest release fence to avoid fence leak
+ // in case if this function gets invoked multiple times from the client.
+ if (output_buffer_->acquire_fence_fd >= 0) {
+ close(output_buffer_->acquire_fence_fd);
+ }
// Fill output buffer parameters (width, height, format, plane information, fence)
output_buffer_->acquire_fence_fd = dup(release_fence);
diff --git a/sdm/libs/hwc2/hwc_layers.cpp b/sdm/libs/hwc2/hwc_layers.cpp
index 45cfb16..4caad2a 100644
--- a/sdm/libs/hwc2/hwc_layers.cpp
+++ b/sdm/libs/hwc2/hwc_layers.cpp
@@ -182,6 +182,10 @@
}
}
+ if (dataspace == HAL_DATASPACE_UNKNOWN) {
+ dataspace = HAL_DATASPACE_V0_SRGB;
+ }
+
return dataspace;
}
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index 6c6e56f..cf52eec 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -77,7 +77,7 @@
int HWCSession::null_display_mode_ = 0;
// Map the known color modes to dataspace.
-static int32_t GetDataspace(ColorMode mode) {
+int32_t GetDataspaceFromColorMode(ColorMode mode) {
switch (mode) {
case ColorMode::SRGB:
case ColorMode::NATIVE:
@@ -449,15 +449,15 @@
return HWC2_ERROR_BAD_DISPLAY;
}
- Locker::ScopeLock lock_p(locker_[HWC_DISPLAY_PRIMARY]);
auto *hwc_session = static_cast<HWCSession *>(device);
+ hwc2_display_t active_builtin_disp_id = hwc_session->GetActiveBuiltinDisplay();
- if (hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ if (active_builtin_disp_id < kNumDisplays) {
+ Locker::ScopeLock lock_a(locker_[active_builtin_disp_id]);
std::bitset<kSecureMax> secure_sessions = 0;
- hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY]->GetActiveSecureSession(&secure_sessions);
+ hwc_session->hwc_display_[active_builtin_disp_id]->GetActiveSecureSession(&secure_sessions);
if (secure_sessions.any()) {
- DLOGI("Destroying virtual display id:%" PRIu64, display);
- DLOGW("Secure session is active, deferring destruction of virtual display");
+ DLOGW("Secure session is active, defer destruction of virtual display id:%" PRIu64, display);
hwc_session->destroy_virtual_disp_pending_ = true;
return HWC2_ERROR_NONE;
}
@@ -682,7 +682,7 @@
return HWC2_ERROR_BAD_DISPLAY;
}
- hwc_session->HandleSecureSession(display);
+ hwc_session->HandleSecureSession();
{
SEQUENCE_EXIT_SCOPE_LOCK(locker_[display]);
if (!hwc_session->hwc_display_[display]) {
@@ -1003,7 +1003,7 @@
HWCSession *hwc_session = static_cast<HWCSession *>(device);
// TODO(user): Handle secure session, handle QDCM solid fill
auto status = HWC2::Error::BadDisplay;
- hwc_session->HandleSecureSession(display);
+ hwc_session->HandleSecureSession();
{
SEQUENCE_ENTRY_SCOPE_LOCK(locker_[display]);
if (power_on_pending_[display]) {
@@ -1157,10 +1157,13 @@
return HWC2::Error::NoResources;
}
- if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
- SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
+ hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
+ if (active_builtin_disp_id < kNumDisplays) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[active_builtin_disp_id]);
std::bitset<kSecureMax> secure_sessions = 0;
- hwc_display_[HWC_DISPLAY_PRIMARY]->GetActiveSecureSession(&secure_sessions);
+ if (hwc_display_[active_builtin_disp_id]) {
+ hwc_display_[active_builtin_disp_id]->GetActiveSecureSession(&secure_sessions);
+ }
if (secure_sessions.any()) {
DLOGE("Secure session is active, cannot create virtual display.");
return HWC2::Error::Unsupported;
@@ -1196,6 +1199,13 @@
continue;
}
+ if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ error = hwc_display_[HWC_DISPLAY_PRIMARY]->TeardownConcurrentWriteback();
+ if (error) {
+ return HWC2::Error::NoResources;
+ }
+ }
+
status = HWCDisplayVirtual::Create(core_intf_, &buffer_allocator_, &callbacks_, client_id,
info.display_id, width, height, format, &hwc_display);
// TODO(user): validate width and height support
@@ -1210,12 +1220,14 @@
}
if (status) {
- return HWC2::Error::BadDisplay;
+ return HWC2::Error::NoResources;
}
}
- SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
- hwc_display_[HWC_DISPLAY_PRIMARY]->ResetValidation();
+ if (active_builtin_disp_id < kNumDisplays) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[active_builtin_disp_id]);
+ hwc_display_[active_builtin_disp_id]->ResetValidation();
+ }
return HWC2::Error::None;
}
@@ -1546,6 +1558,14 @@
status = GetSupportedDsiClk(input_parcel, output_parcel);
break;
+ case qService::IQService::SET_COLOR_MODE_FROM_CLIENT:
+ if (!input_parcel) {
+ DLOGE("QService command = %d: input_parcel needed.", command);
+ break;
+ }
+ status = SetColorModeFromClient(input_parcel);
+ break;
+
default:
DLOGW("QService command = %d is not supported.", command);
break;
@@ -1818,6 +1838,27 @@
return 0;
}
+android::status_t HWCSession::SetColorModeFromClient(const android::Parcel *input_parcel) {
+ int display = input_parcel->readInt32();
+ auto mode = input_parcel->readInt32();
+ auto device = static_cast<hwc2_device_t *>(this);
+
+ int disp_idx = GetDisplayIndex(display);
+ if (disp_idx == -1) {
+ DLOGE("Invalid display = %d", display);
+ return -EINVAL;
+ }
+
+ auto err = CallDisplayFunction(device, static_cast<hwc2_display_t>(disp_idx),
+ &HWCDisplay::SetColorModeFromClientApi, mode);
+ if (err != HWC2_ERROR_NONE)
+ return -EINVAL;
+
+ Refresh(static_cast<hwc2_display_t>(disp_idx));
+
+ return 0;
+}
+
android::status_t HWCSession::RefreshScreen(const android::Parcel *input_parcel) {
int display = input_parcel->readInt32();
@@ -2185,9 +2226,10 @@
(hwc2_display_t)GetDisplayIndex(qdutils::DISPLAY_VIRTUAL);
std::bitset<kSecureMax> secure_sessions = 0;
- {
- Locker::ScopeLock lock_p(locker_[HWC_DISPLAY_PRIMARY]);
- hwc_display_[HWC_DISPLAY_PRIMARY]->GetActiveSecureSession(&secure_sessions);
+ hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
+ if (active_builtin_disp_id < kNumDisplays) {
+ Locker::ScopeLock lock_a(locker_[active_builtin_disp_id]);
+ hwc_display_[active_builtin_disp_id]->GetActiveSecureSession(&secure_sessions);
}
if (secure_sessions[kSecureDisplay] || hwc_display_[virtual_display_index]) {
// Defer hotplug events.
@@ -2518,20 +2560,23 @@
return status;
}
- // Primary display needs revalidation
- {
- SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
- hwc_display_[HWC_DISPLAY_PRIMARY]->ResetValidation();
- }
+ // Active builtin display needs revalidation
+ hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
+ if (active_builtin_disp_id < kNumDisplays) {
+ {
+ SCOPE_LOCK(locker_[active_builtin_disp_id]);
+ hwc_display_[active_builtin_disp_id]->ResetValidation();
+ }
- if (client_connected_) {
- Refresh(HWC_DISPLAY_PRIMARY);
- }
+ if (client_connected_) {
+ Refresh(active_builtin_disp_id);
+ }
- // Do not sleep if this method is called from client thread.
- if (delay_hotplug) {
- // wait sufficient time to ensure resources are available for new display connection.
- usleep(UINT32(GetVsyncPeriod(HWC_DISPLAY_PRIMARY)) * 2 / 1000);
+ // Do not sleep if this method is called from client thread.
+ if (delay_hotplug) {
+ // wait sufficient time to ensure resources are available for new display connection.
+ usleep(UINT32(GetVsyncPeriod(INT32(active_builtin_disp_id))) * 2 / 1000);
+ }
}
for (auto client_id : pending_hotplugs) {
@@ -2723,16 +2768,18 @@
Refresh(HWC_DISPLAY_PRIMARY);
}
-void HWCSession::HandleSecureSession(hwc2_display_t disp_id) {
+void HWCSession::HandleSecureSession() {
std::bitset<kSecureMax> secure_sessions = 0;
{
- Locker::ScopeLock lock_p(locker_[HWC_DISPLAY_PRIMARY]);
- if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
- hwc_display_[HWC_DISPLAY_PRIMARY]->GetActiveSecureSession(&secure_sessions);
+ hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
+ if (active_builtin_disp_id >= kNumDisplays) {
+ return;
}
+ Locker::ScopeLock lock_a(locker_[active_builtin_disp_id]);
+ hwc_display_[active_builtin_disp_id]->GetActiveSecureSession(&secure_sessions);
}
- // If it is called during primary prepare/commit, we need to pause any onging commit on
+ // If it is called during primary prepare/commit, we need to pause any ongoing commit on
// external/virtual display.
for (hwc2_display_t display = HWC_DISPLAY_PRIMARY; display < kNumDisplays; display++) {
Locker::ScopeLock lock_d(locker_[display]);
@@ -2743,17 +2790,20 @@
}
void HWCSession::HandlePowerOnPending(hwc2_display_t disp_id, int retire_fence) {
- if (disp_id != HWC_DISPLAY_PRIMARY) {
+ hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
+ if (disp_id != active_builtin_disp_id) {
return;
}
- Locker::ScopeLock lock_p(locker_[HWC_DISPLAY_PRIMARY]);
+ Locker::ScopeLock lock_a(locker_[active_builtin_disp_id]);
bool power_on_pending = false;
- for (hwc2_display_t display = HWC_DISPLAY_PRIMARY + 1; display < kNumDisplays; display++) {
- Locker::ScopeLock lock_d(locker_[display]);
- if (power_on_pending_[display]) {
- power_on_pending = true;
- break;
+ for (hwc2_display_t display = HWC_DISPLAY_PRIMARY; display < kNumDisplays; display++) {
+ if (display != active_builtin_disp_id) {
+ Locker::ScopeLock lock_d(locker_[display]);
+ if (power_on_pending_[display]) {
+ power_on_pending = true;
+ break;
+ }
}
}
if (power_on_pending) {
@@ -2771,56 +2821,59 @@
return;
}
- for (hwc2_display_t display = HWC_DISPLAY_PRIMARY + 1; display < kNumDisplays; display++) {
- Locker::ScopeLock lock_d(locker_[display]);
- if (power_on_pending_[display] && hwc_display_[display]) {
- HWC2::Error status =
+ for (hwc2_display_t display = HWC_DISPLAY_PRIMARY; display < kNumDisplays; display++) {
+ if (display != active_builtin_disp_id) {
+ Locker::ScopeLock lock_d(locker_[display]);
+ if (power_on_pending_[display] && hwc_display_[display]) {
+ HWC2::Error status =
hwc_display_[display]->SetPowerMode(HWC2::PowerMode::On, false /* teardown */);
- if (status == HWC2::Error::None) {
- power_on_pending_[display] = false;
+ if (status == HWC2::Error::None) {
+ power_on_pending_[display] = false;
+ }
}
}
}
}
void HWCSession::HandleHotplugPending(hwc2_display_t disp_id, int retire_fence) {
- if (disp_id != HWC_DISPLAY_PRIMARY ||
+ hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
+ if (disp_id != active_builtin_disp_id ||
(kHotPlugNone == hotplug_pending_event_ && !destroy_virtual_disp_pending_)) {
return;
}
std :: bitset < kSecureMax > secure_sessions = 0;
- {
- Locker::ScopeLock lock_p(locker_[HWC_DISPLAY_PRIMARY]);
- if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
- if (!hwc_display_[HWC_DISPLAY_PRIMARY]->IsDisplayCommandMode()) {
- if (destroy_virtual_disp_pending_ || kHotPlugEvent == hotplug_pending_event_) {
- if (retire_fence >= 0) {
- int error = sync_wait(retire_fence, 1000);
- if (error < 0) {
- DLOGE("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
- }
- }
- }
+ if (active_builtin_disp_id < kNumDisplays) {
+ Locker::ScopeLock lock_a(locker_[active_builtin_disp_id]);
+ hwc_display_[active_builtin_disp_id]->GetActiveSecureSession(&secure_sessions);
+ }
+
+ if (secure_sessions.any() || active_builtin_disp_id == kNumDisplays) {
+ return;
+ }
+
+ if (destroy_virtual_disp_pending_ || kHotPlugEvent == hotplug_pending_event_) {
+ if (retire_fence >= 0) {
+ int error = sync_wait(retire_fence, 1000);
+ if (error < 0) {
+ DLOGE("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
}
- hwc_display_[HWC_DISPLAY_PRIMARY]->GetActiveSecureSession(&secure_sessions);
}
- }
- // Destroy the pending virtual display if secure session not present.
- if (!secure_sessions.any() && destroy_virtual_disp_pending_) {
- for (auto &map_info : map_info_virtual_) {
- DestroyDisplay(&map_info);
- destroy_virtual_disp_pending_ = false;
+ // Destroy the pending virtual display if secure session not present.
+ if (destroy_virtual_disp_pending_) {
+ for (auto &map_info : map_info_virtual_) {
+ DestroyDisplay(&map_info);
+ destroy_virtual_disp_pending_ = false;
+ }
}
- }
- // Handle connect/disconnect hotplugs if secure session is not present.
- hwc2_display_t virtual_display_index = (hwc2_display_t)GetDisplayIndex(qdutils::DISPLAY_VIRTUAL);
- if (!secure_sessions.any() && !hwc_display_[virtual_display_index] &&
- kHotPlugEvent == hotplug_pending_event_) {
- if (HandlePluggableDisplays(true)) {
- DLOGE("Could not handle hotplug. Event dropped.");
+ // Handle connect/disconnect hotplugs if secure session is not present.
+ hwc2_display_t virtual_display_idx = (hwc2_display_t)GetDisplayIndex(qdutils::DISPLAY_VIRTUAL);
+ if (!hwc_display_[virtual_display_idx] && kHotPlugEvent == hotplug_pending_event_) {
+ if (HandlePluggableDisplays(true)) {
+ DLOGE("Could not handle hotplug. Event dropped.");
+ }
+ hotplug_pending_event_ = kHotPlugNone;
}
- hotplug_pending_event_ = kHotPlugNone;
}
}
@@ -2839,7 +2892,7 @@
if (hwc_display) {
*format = HAL_PIXEL_FORMAT_RGB_888;
- *dataspace = GetDataspace(hwc_display->GetCurrentColorMode());
+ *dataspace = GetDataspaceFromColorMode(hwc_display->GetCurrentColorMode());
return HWC2_ERROR_NONE;
}
@@ -2976,18 +3029,23 @@
return static_cast<android::status_t>(controlIdlePowerCollapse(enable, synchronous));
#else
{
- SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
- if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
+ if (active_builtin_disp_id >= kNumDisplays) {
+ DLOGE("No active displays");
+ return -EINVAL;
+ }
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[active_builtin_disp_id]);
+ if (hwc_display_[active_builtin_disp_id]) {
DLOGE("Primary display is not ready");
return -EINVAL;
}
- auto error = hwc_display_[HWC_DISPLAY_PRIMARY]->ControlIdlePowerCollapse(enable, synchronous);
- if (error != kErrorNone) {
- return (error == kErrorNotSupported) ? 0 : -EINVAL;
+ auto err = hwc_display_[active_builtin_disp_id]->ControlIdlePowerCollapse(enable, synchronous);
+ if (err != kErrorNone) {
+ return (err == kErrorNotSupported) ? 0 : -EINVAL;
}
if (!enable) {
- Refresh(HWC_DISPLAY_PRIMARY);
- int32_t error = locker_[HWC_DISPLAY_PRIMARY].WaitFinite(kCommitDoneTimeoutMs);
+ Refresh(active_builtin_disp_id);
+ int32_t error = locker_[active_builtin_disp_id].WaitFinite(kCommitDoneTimeoutMs);
if (error == ETIMEDOUT) {
DLOGE("Timed out!! Next frame commit done event not received!!");
return error;
@@ -2999,4 +3057,18 @@
#endif
}
+hwc2_display_t HWCSession::GetActiveBuiltinDisplay() {
+ hwc2_display_t disp_id = kNumDisplays;
+ Locker::ScopeLock lock_p(locker_[HWC_DISPLAY_PRIMARY]);
+ Locker::ScopeLock lock_b2(locker_[HWC_DISPLAY_BUILTIN_2]);
+ if (hwc_display_[HWC_DISPLAY_PRIMARY] &&
+ hwc_display_[HWC_DISPLAY_PRIMARY]->GetCurrentPowerMode() == HWC2::PowerMode::On) {
+ disp_id = HWC_DISPLAY_PRIMARY;
+ } else if (hwc_display_[HWC_DISPLAY_BUILTIN_2] &&
+ hwc_display_[HWC_DISPLAY_BUILTIN_2]->GetCurrentPowerMode() == HWC2::PowerMode::On) {
+ disp_id = HWC_DISPLAY_BUILTIN_2;
+ }
+ return disp_id;
+}
+
} // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
index bf66507..676d3a1 100644
--- a/sdm/libs/hwc2/hwc_session.h
+++ b/sdm/libs/hwc2/hwc_session.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright 2015 The Android Open Source Project
@@ -20,7 +20,9 @@
#ifndef __HWC_SESSION_H__
#define __HWC_SESSION_H__
-#ifdef DISPLAY_CONFIG_1_7
+#ifdef DISPLAY_CONFIG_1_8
+#include <vendor/display/config/1.8/IDisplayConfig.h>
+#elif DISPLAY_CONFIG_1_7
#include <vendor/display/config/1.7/IDisplayConfig.h>
#elif DISPLAY_CONFIG_1_6
#include <vendor/display/config/1.6/IDisplayConfig.h>
@@ -59,7 +61,9 @@
namespace sdm {
-#ifdef DISPLAY_CONFIG_1_7
+#ifdef DISPLAY_CONFIG_1_8
+using vendor::display::config::V1_8::IDisplayConfig;
+#elif DISPLAY_CONFIG_1_7
using vendor::display::config::V1_7::IDisplayConfig;
#elif DISPLAY_CONFIG_1_6
using vendor::display::config::V1_6::IDisplayConfig;
@@ -79,6 +83,8 @@
using ::android::hardware::Return;
using ::android::hardware::hidl_string;
+int32_t GetDataspaceFromColorMode(ColorMode mode);
+
// Create a singleton uevent listener thread valid for life of hardware composer process.
// This thread blocks on uevents poll inside uevent library implementation. This poll exits
// only when there is a valid uevent, it can not be interrupted otherwise. Tieing life cycle
@@ -339,6 +345,10 @@
getDebugProperty_cb _hidl_cb) override;
#endif
+#ifdef DISPLAY_CONFIG_1_8
+ Return<void> getActiveBuiltinDisplayAttributes(getDisplayAttributes_cb _hidl_cb) override;
+#endif
+
// QClient methods
virtual android::status_t notifyCallback(uint32_t command, const android::Parcel *input_parcel,
android::Parcel *output_parcel);
@@ -362,6 +372,7 @@
android::status_t SetColorModeWithRenderIntentOverride(const android::Parcel *input_parcel);
android::status_t SetColorModeById(const android::Parcel *input_parcel);
+ android::status_t SetColorModeFromClient(const android::Parcel *input_parcel);
android::status_t getComposerStatus();
android::status_t SetQSyncMode(const android::Parcel *input_parcel);
android::status_t SetIdlePC(const android::Parcel *input_parcel);
@@ -379,13 +390,14 @@
HWC2::Error ValidateDisplayInternal(hwc2_display_t display, uint32_t *out_num_types,
uint32_t *out_num_requests);
HWC2::Error PresentDisplayInternal(hwc2_display_t display, int32_t *out_retire_fence);
- void HandleSecureSession(hwc2_display_t display);
+ void HandleSecureSession();
void HandlePowerOnPending(hwc2_display_t display, int retire_fence);
void HandleHotplugPending(hwc2_display_t disp_id, int retire_fence);
void UpdateVsyncSource();
hwc2_display_t GetNextVsyncSource();
DisplayClass GetDisplayClass(hwc2_display_t display_id);
bool IsPluggableDisplayConnected();
+ hwc2_display_t GetActiveBuiltinDisplay();
CoreInterface *core_intf_ = nullptr;
HWCDisplay *hwc_display_[kNumDisplays] = {nullptr};
diff --git a/sdm/libs/hwc2/hwc_session_services.cpp b/sdm/libs/hwc2/hwc_session_services.cpp
index 940a55c..30a0863 100644
--- a/sdm/libs/hwc2/hwc_session_services.cpp
+++ b/sdm/libs/hwc2/hwc_session_services.cpp
@@ -126,7 +126,21 @@
} else if (!hwc_display_[disp_idx]) {
DLOGW("Display is not connected");
} else {
- return hwc_display_[disp_idx]->SetDisplayStatus(status);
+ int err = hwc_display_[disp_idx]->SetDisplayStatus(status);
+ if (err != 0) {
+ return err;
+ }
+
+ if (status == HWCDisplay::kDisplayStatusResume || status == HWCDisplay::kDisplayStatusPause) {
+ hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
+ if (active_builtin_disp_id < kNumDisplays) {
+ {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[active_builtin_disp_id]);
+ hwc_display_[active_builtin_disp_id]->ResetValidation();
+ }
+ callbacks_.Refresh(active_builtin_disp_id);
+ }
+ }
}
return -EINVAL;
@@ -465,7 +479,12 @@
}
Return<int32_t> HWCSession::setCameraLaunchStatus(uint32_t on) {
- SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
+ hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
+ if (active_builtin_disp_id >= kNumDisplays) {
+ DLOGE("No active displays");
+ return -EINVAL;
+ }
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[active_builtin_disp_id]);
if (null_display_mode_) {
return 0;
@@ -476,15 +495,15 @@
return -ENOENT;
}
- if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
- DLOGW("Display = %d is not connected.", HWC_DISPLAY_PRIMARY);
+ if (!hwc_display_[active_builtin_disp_id]) {
+ DLOGW("Display = %d is not connected.", active_builtin_disp_id);
return -ENODEV;
}
HWBwModes mode = on > 0 ? kBwCamera : kBwDefault;
// trigger invalidate to apply new bw caps.
- Refresh(HWC_DISPLAY_PRIMARY);
+ Refresh(active_builtin_disp_id);
if (core_intf_->SetMaxBandwidthMode(mode) != kErrorNone) {
return -EINVAL;
@@ -492,7 +511,7 @@
new_bw_mode_ = true;
need_invalidate_ = true;
- hwc_display_[HWC_DISPLAY_PRIMARY]->ResetValidation();
+ hwc_display_[active_builtin_disp_id]->ResetValidation();
return 0;
}
@@ -597,17 +616,23 @@
#ifdef DISPLAY_CONFIG_1_3
Return<int32_t> HWCSession::controlIdlePowerCollapse(bool enable, bool synchronous) {
- SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
+ hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
+ if (active_builtin_disp_id >= kNumDisplays) {
+ DLOGE("No active displays");
+ return -EINVAL;
+ }
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[active_builtin_disp_id]);
- if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ if (hwc_display_[active_builtin_disp_id]) {
if (!enable) {
if (!idle_pc_ref_cnt_) {
- auto err = hwc_display_[HWC_DISPLAY_PRIMARY]->ControlIdlePowerCollapse(enable, synchronous);
+ auto err = hwc_display_[active_builtin_disp_id]->ControlIdlePowerCollapse(enable,
+ synchronous);
if (err != kErrorNone) {
return (err == kErrorNotSupported) ? 0 : -EINVAL;
}
- Refresh(HWC_DISPLAY_PRIMARY);
- int32_t error = locker_[HWC_DISPLAY_PRIMARY].WaitFinite(kCommitDoneTimeoutMs);
+ Refresh(active_builtin_disp_id);
+ int32_t error = locker_[active_builtin_disp_id].WaitFinite(kCommitDoneTimeoutMs);
if (error == ETIMEDOUT) {
DLOGE("Timed out!! Next frame commit done event not received!!");
return error;
@@ -617,7 +642,8 @@
idle_pc_ref_cnt_++;
} else if (idle_pc_ref_cnt_ > 0) {
if (!(idle_pc_ref_cnt_ - 1)) {
- auto err = hwc_display_[HWC_DISPLAY_PRIMARY]->ControlIdlePowerCollapse(enable, synchronous);
+ auto err = hwc_display_[active_builtin_disp_id]->ControlIdlePowerCollapse(enable,
+ synchronous);
if (err != kErrorNone) {
return (err == kErrorNotSupported) ? 0 : -EINVAL;
}
@@ -628,7 +654,7 @@
return 0;
}
- DLOGW("Display = %d is not connected.", HWC_DISPLAY_PRIMARY);
+ DLOGW("Display = %d is not connected.", active_builtin_disp_id);
return -ENODEV;
}
#endif // DISPLAY_CONFIG_1_3
@@ -742,4 +768,41 @@
}
#endif
+#ifdef DISPLAY_CONFIG_1_8
+Return<void> HWCSession::getActiveBuiltinDisplayAttributes(
+ getDisplayAttributes_cb _hidl_cb) {
+ int32_t error = -EINVAL;
+ IDisplayConfig::DisplayAttributes display_attributes = {};
+ hwc2_display_t disp_id = GetActiveBuiltinDisplay();
+
+ if (disp_id >= kNumDisplays) {
+ DLOGE("Invalid display = %d", disp_id);
+ } else {
+ if (hwc_display_[disp_id]) {
+ uint32_t config_index = 0;
+ HWC2::Error ret = hwc_display_[disp_id]->GetActiveConfig(&config_index);
+ if (ret != HWC2::Error::None) {
+ goto err;
+ }
+ DisplayConfigVariableInfo var_info;
+ error = hwc_display_[disp_id]->GetDisplayAttributesForConfig(INT(config_index), &var_info);
+ if (!error) {
+ display_attributes.vsyncPeriod = var_info.vsync_period_ns;
+ display_attributes.xRes = var_info.x_pixels;
+ display_attributes.yRes = var_info.y_pixels;
+ display_attributes.xDpi = var_info.x_dpi;
+ display_attributes.yDpi = var_info.y_dpi;
+ display_attributes.panelType = IDisplayConfig::DisplayPortType::DISPLAY_PORT_DEFAULT;
+ display_attributes.isYuv = var_info.is_yuv;
+ }
+ }
+ }
+
+err:
+ _hidl_cb(error, display_attributes);
+
+ return Void();
+}
+#endif // DISPLAY_CONFIG_1_8
+
} // namespace sdm