Merge "hwc2: Do not honor cursor position when cursor layer is not present"
diff --git a/common.mk b/common.mk
index a039e5f..bb0e83e 100644
--- a/common.mk
+++ b/common.mk
@@ -9,6 +9,9 @@
display_config_version := $(shell \
if [ -d "$(TOP)/vendor/qcom/opensource/interfaces/display/config/1.3" ];\
then echo DISPLAY_CONFIG_1_3; fi)
+display_config_version := $(shell \
+ if [ -d "$(TOP)/vendor/qcom/opensource/interfaces/display/config/1.4" ];\
+ then echo DISPLAY_CONFIG_1_4; fi)
#Common C flags
common_flags := -Wno-missing-field-initializers
common_flags += -Wconversion -Wall -Werror -std=c++14
@@ -27,6 +30,10 @@
ifeq ($(display_config_version), DISPLAY_CONFIG_1_3)
common_flags += -DDISPLAY_CONFIG_1_1 -DDISPLAY_CONFIG_1_2 -DDISPLAY_CONFIG_1_3
endif
+ifeq ($(display_config_version), DISPLAY_CONFIG_1_4)
+ common_flags += -DDISPLAY_CONFIG_1_1 -DDISPLAY_CONFIG_1_2
+ common_flags += -DDISPLAY_CONFIG_1_3 -DDISPLAY_CONFIG_1_4
+endif
ifeq ($(TARGET_USES_COLOR_METADATA), true)
common_flags += -DUSE_COLOR_METADATA
diff --git a/config/msmnile.mk b/config/msmnile.mk
index 053cfeb..8d14935 100644
--- a/config/msmnile.mk
+++ b/config/msmnile.mk
@@ -53,7 +53,6 @@
vendor.display.comp_mask=0 \
vendor.display.disable_hw_recovery=0 \
vendor.display.enable_default_color_mode=1
- vendor.display.disable_hw_recovery=1
# This matrix should be in column major order, per SurfaceFlinger requirement
# 1.16868 -0.16868 0.00000
diff --git a/config/talos.mk b/config/talos.mk
new file mode 100644
index 0000000..74d1f70
--- /dev/null
+++ b/config/talos.mk
@@ -0,0 +1,60 @@
+#Display related packages and configuration
+
+PRODUCT_PACKAGES += \
+ android.hardware.graphics.composer@2.1-impl \
+ android.hardware.graphics.composer@2.1-service \
+ android.hardware.graphics.mapper@2.0-impl-qti-display \
+ vendor.qti.hardware.display.allocator@1.0-service \
+ android.hardware.memtrack@1.0-impl \
+ android.hardware.memtrack@1.0-service \
+ android.hardware.light@2.0-impl \
+ android.hardware.light@2.0-service \
+ gralloc.talos \
+ lights.talos \
+ hwcomposer.talos \
+ memtrack.talos \
+ libqdutils \
+ libqdMetaData \
+ libqdMetaData.system \
+ 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
+
+#Enable Charging Icon
+TARGET_RECOVERY_PIXEL_FORMAT := RGBX_8888
+
+TARGET_USES_GRALLOC1 := true
+TARGET_USES_DRM_PP := true
+TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS := true
+MAX_VIRTUAL_DISPLAY_DIMENSION := 4096
+NUM_FRAMEBUFFER_SURFACE_BUFFERS := 3
+TARGET_USES_HWC2 := true
+TARGET_USES_QCOM_DISPLAY_BSP := true
+TARGET_USES_COLOR_METADATA := true
+TARGET_HAS_WIDE_COLOR_DISPLAY := true
+
+PRODUCT_PROPERTY_OVERRIDES += \
+ persist.demo.hdmirotationlock=false \
+ debug.sf.hw=0 \
+ debug.egl.hw=0 \
+ debug.sf.latch_unsignaled=1 \
+ debug.mdpcomp.logs=0 \
+ debug.sf.enable_hwc_vds=1 \
+ ro.vendor.display.cabl=2 \
+ vendor.gralloc.disable_ubwc=0 \
+ vendor.display.disable_scaler=0 \
+ vendor.display.disable_inline_rotator=1 \
+ vendor.display.disable_decimation=1 \
+ vendor.display.enable_null_display=0 \
+ vendor.display.disable_excl_rect=0 \
+ vendor.display.comp_mask=0 \
+ vendor.display.disable_hw_recovery=1 \
+ vendor.display.enable_default_color_mode=1
+
+# This matrix should be in column major order, per SurfaceFlinger requirement
+# 1.16868 -0.16868 0.00000
+# -0.03155 1.03155 0.00000
+# -0.01473 -0.05899 1.07372
+PRODUCT_PROPERTY_OVERRIDES += \
+ vendor.display.dataspace_saturation_matrix=1.16868,-0.03155,-0.01473,-0.16868,1.03155,-0.05899,0.00000,0.00000,1.07372
diff --git a/gralloc/QtiMapper.cpp b/gralloc/QtiMapper.cpp
index 3848878..14c788e 100644
--- a/gralloc/QtiMapper.cpp
+++ b/gralloc/QtiMapper.cpp
@@ -52,7 +52,7 @@
bool QtiMapper::ValidDescriptor(const BufferDescriptorInfo_2_1 &bd) {
if (bd.width == 0 || bd.height == 0 || (static_cast<int32_t>(bd.format) <= 0) ||
- bd.layerCount != 1) {
+ bd.layerCount <= 0) {
return false;
}
diff --git a/gralloc/gr_buf_mgr.cpp b/gralloc/gr_buf_mgr.cpp
index 3d4bfac..9a25a8e 100644
--- a/gralloc/gr_buf_mgr.cpp
+++ b/gralloc/gr_buf_mgr.cpp
@@ -101,6 +101,10 @@
}
Error BufferManager::ImportHandleLocked(private_handle_t *hnd) {
+ if (private_handle_t::validate(hnd) != 0) {
+ ALOGE("ImportHandleLocked: Invalid handle: %p", hnd);
+ return Error::BAD_BUFFER;
+ }
ALOGD_IF(DEBUG, "Importing handle:%p id: %" PRIu64, hnd, hnd->id);
int ion_handle = allocator_->ImportBuffer(hnd->fd);
if (ion_handle < 0) {
@@ -335,6 +339,7 @@
}
Error BufferManager::Dump(std::ostringstream *os) {
+ std::lock_guard<std::mutex> buffer_lock(buffer_lock_);
for (auto it : handles_map_) {
auto buf = it.second;
auto hnd = buf->handle;
diff --git a/gralloc/gr_priv_handle.h b/gralloc/gr_priv_handle.h
index 964bed0..ace762e 100644
--- a/gralloc/gr_priv_handle.h
+++ b/gralloc/gr_priv_handle.h
@@ -33,6 +33,7 @@
#define PRIV_HANDLE_CONST(exp) static_cast<const private_handle_t *>(exp)
+#pragma pack(push, 4)
struct private_handle_t : public native_handle_t {
enum {
PRIV_FLAGS_FRAMEBUFFER = 0x00000001,
@@ -75,15 +76,15 @@
int format;
int buffer_type;
unsigned int layer_count;
- uint64_t id __attribute__((aligned(8)));
- uint64_t usage __attribute__((aligned(8)));
+ uint64_t id;
+ uint64_t usage;
unsigned int size;
unsigned int offset;
unsigned int offset_metadata;
- uint64_t base __attribute__((aligned(8)));
- uint64_t base_metadata __attribute__((aligned(8)));
- uint64_t gpuaddr __attribute__((aligned(8)));
+ uint64_t base;
+ uint64_t base_metadata;
+ uint64_t gpuaddr;
static const int kNumFds = 2;
static const int kMagic = 'gmsm';
@@ -131,12 +132,14 @@
static int validate(const native_handle *h) {
auto *hnd = static_cast<const private_handle_t *>(h);
if (!h || h->version != sizeof(native_handle) || h->numInts != NumInts() ||
- h->numFds != kNumFds || hnd->magic != kMagic) {
- ALOGE(
- "Invalid gralloc handle (at %p): ver(%d/%zu) ints(%d/%d) fds(%d/%d) "
- "magic(%c%c%c%c/%c%c%c%c)",
+ h->numFds != kNumFds) {
+ ALOGE("Invalid gralloc handle (at %p): ver(%d/%zu) ints(%d/%d) fds(%d/%d) ",
h, h ? h->version : -1, sizeof(native_handle), h ? h->numInts : -1, NumInts(),
- h ? h->numFds : -1, kNumFds,
+ h ? h->numFds : -1, kNumFds);
+ return -EINVAL;
+ }
+ if (hnd->magic != kMagic) {
+ ALOGE("magic(%c%c%c%c/%c%c%c%c)",
hnd ? (((hnd->magic >> 24) & 0xFF) ? ((hnd->magic >> 24) & 0xFF) : '-') : '?',
hnd ? (((hnd->magic >> 16) & 0xFF) ? ((hnd->magic >> 16) & 0xFF) : '-') : '?',
hnd ? (((hnd->magic >> 8) & 0xFF) ? ((hnd->magic >> 8) & 0xFF) : '-') : '?',
@@ -173,5 +176,6 @@
uint64_t GetBackingstore() const { return id; }
};
+#pragma pack(pop)
#endif // __GR_PRIV_HANDLE_H__
diff --git a/include/display_properties.h b/include/display_properties.h
index ddcde64..9af7ddd 100644
--- a/include/display_properties.h
+++ b/include/display_properties.h
@@ -107,6 +107,7 @@
#define QDCM_DISABLE_TIMEOUT_PROP PERSIST_DISPLAY_PROP("qdcm.disable_timeout")
#define QDCM_MODE_COMBINE_PROP DISPLAY_PROP("qdcm.mode_combine")
#define PREFER_MULTIRECT_PROP DISPLAY_PROP("prefer_multirect")
+#define DROP_SKEWED_VSYNC DISPLAY_PROP("drop_skewed_vsync");
#define ZERO_SWAP_INTERVAL "vendor.debug.egl.swapinterval"
diff --git a/libdisplayconfig/DisplayConfig.h b/libdisplayconfig/DisplayConfig.h
index 17b6421..fbce8b6 100644
--- a/libdisplayconfig/DisplayConfig.h
+++ b/libdisplayconfig/DisplayConfig.h
@@ -83,6 +83,10 @@
float min_luminance = 0.0f;
};
+struct WriteBackCapabilities {
+ bool isWbUbwcSupported;
+};
+
//=============================================================================
// The functions below run in the client pocess and wherever necessary
// do a binder call to HWC to get/set data.
@@ -104,6 +108,7 @@
int getHDRCapabilities(int dpy, DisplayHDRCapabilities *caps);
int setCameraLaunchStatus(uint32_t on);
bool displayBWTransactionPending();
+int32_t getWriteBackCapabilities( WriteBackCapabilities *caps);
} // namespace display
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index c352839..0fe0d2c 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -38,6 +38,7 @@
#include "xf86drm.h"
#include "xf86drmMode.h"
#include <drm/msm_drm.h>
+#include <drm/msm_drm_pp.h>
namespace sde_drm {
@@ -601,6 +602,7 @@
bool qsync_support;
// Connection status of this connector
bool is_connected;
+ bool is_wb_ubwc_supported;
};
// All DRM Connectors as map<Connector_id , connector_info>
@@ -666,6 +668,7 @@
kFeatureAd4Init,
kFeatureAd4Cfg,
kFeatureAd4Input,
+ kFeatureAd4Roi,
kFeatureAd4Backlight,
kFeatureAd4Assertiveness,
kFeatureAd4ManualStrength,
diff --git a/libqdutils/display_config.cpp b/libqdutils/display_config.cpp
index 87ca401..964640f 100644
--- a/libqdutils/display_config.cpp
+++ b/libqdutils/display_config.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2013-2014, 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2013-2014, 2016, 2018, 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
@@ -342,9 +342,9 @@
return err;
}
-extern "C" int refreshScreen() {
+extern "C" int refreshScreen(int dpy) {
int ret = 0;
- ret = screenRefresh();
+ ret = screenRefresh(dpy);
return ret;
}
diff --git a/libqdutils/display_config.h b/libqdutils/display_config.h
index 1f5e5e8..8073bb1 100644
--- a/libqdutils/display_config.h
+++ b/libqdutils/display_config.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 - 2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013 - 2016, 2018, 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
@@ -47,9 +47,13 @@
// Use this enum to specify the dpy parameters where needed
enum {
+ // DO NOT CHANGE THE LEGACY DEFINES
DISPLAY_PRIMARY = 0, // = HWC_DISPLAY_PRIMARY
DISPLAY_EXTERNAL = 1, // = HWC_DISPLAY_EXTERNAL
DISPLAY_VIRTUAL = 2, // = HWC_DISPLAY_VIRTUAL
+
+ // Additional displays only for vendor client (e.g. pp) reference
+ DISPLAY_BUILTIN_2 = 3,
};
// External Display states - used in setSecondaryDisplayStatus()
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index 929f7b6..11cbf22 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -80,6 +80,7 @@
SET_QSYNC_MODE = 38, // Set qsync mode. 0 - (none)disable qsync, 1 - continuous mode.
SET_COLOR_MODE_WITH_RENDER_INTENT = 39,
SET_IDLE_PC = 40, // Enable/disable Idle power collapse
+ SET_DPPS_AD4_ROI_CONFIG = 41, // Set ad4 roi config for debug
COMMAND_LIST_END = 400,
};
diff --git a/libqservice/QServiceUtils.h b/libqservice/QServiceUtils.h
index 8f25253..61ff037 100644
--- a/libqservice/QServiceUtils.h
+++ b/libqservice/QServiceUtils.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2013-14 The Linux Foundation. All rights reserved.
+* Copyright (c) 2013-14, 2018, 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
@@ -62,8 +62,8 @@
// ----------------------------------------------------------------------------
// Convenience wrappers that clients can call
// ----------------------------------------------------------------------------
-inline android::status_t screenRefresh() {
- return sendSingleParam(qService::IQService::SCREEN_REFRESH, 1);
+inline android::status_t screenRefresh(int dpy) {
+ return sendSingleParam(qService::IQService::SCREEN_REFRESH, dpy);
}
inline android::status_t toggleScreenUpdate(uint32_t on) {
diff --git a/sdm/include/core/core_interface.h b/sdm/include/core/core_interface.h
index ba01175..2165155 100644
--- a/sdm/include/core/core_interface.h
+++ b/sdm/include/core/core_interface.h
@@ -109,6 +109,7 @@
bool is_connected = false; //!< Connection status of the display.
bool is_primary = false; //!< True only if this is the main display of the
//!< device.
+ bool is_wb_ubwc_supported = true; //!< check hardware wb ubwc support
};
/*! @brief Information on all displays as a map with display_id as key.
diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h
index 35eb366..7cac5e1 100644
--- a/sdm/include/core/display_interface.h
+++ b/sdm/include/core/display_interface.h
@@ -163,6 +163,16 @@
kQsyncModeOneShot, // This is set by client to enable qsync only for current frame.
};
+/*! @brief This structure defines configuration for display dpps ad4 region of interest. */
+struct DisplayDppsAd4RoiCfg {
+ uint32_t h_start; //!< start in hotizontal direction
+ uint32_t h_end; //!< end in hotizontal direction
+ uint32_t v_start; //!< start in vertical direction
+ uint32_t v_end; //!< end in vertical direction
+ uint32_t factor_in; //!< the strength factor of inside ROI region
+ uint32_t factor_out; //!< the strength factor of outside ROI region
+};
+
/*! @brief This structure defines configuration for fixed properties of a display device.
@sa DisplayInterface::GetConfig
@@ -175,9 +185,9 @@
bool hdr_supported = false; //!< if HDR is enabled
bool hdr_metadata_type_one = false; //!< Metadata type one obtained from HDR sink
uint32_t hdr_eotf = 0; //!< Electro optical transfer function
- uint32_t max_luminance = 0; //!< From Panel's peak luminance
- uint32_t average_luminance = 0; //!< From Panel's average luminance
- uint32_t min_luminance = 0; //!< From Panel's blackness level
+ float max_luminance = 0.0f; //!< From Panel's peak luminance
+ float average_luminance = 0.0f; //!< From Panel's average luminance
+ float min_luminance = 0.0f; //!< From Panel's blackness level
bool partial_update = false; //!< If display supports Partial Update.
};
@@ -409,13 +419,16 @@
/*! @brief Method to set current state of the display device.
@param[in] state \link DisplayState \endlink
+ @param[in] flag to force full bridge teardown for pluggable displays, no-op for other displays,
+ if requested state is kStateOff
@param[in] pointer to release fence
@return \link DisplayError \endlink
@sa SetDisplayState
*/
- virtual DisplayError SetDisplayState(DisplayState state, int *release_fence) = 0;
+ virtual DisplayError SetDisplayState(DisplayState state, bool teardown,
+ int *release_fence) = 0;
/*! @brief Method to set active configuration for variable properties of the display device.
@@ -730,6 +743,15 @@
*/
virtual DisplayError HandleSecureEvent(SecureEvent secure_event) = 0;
+ /*! @brief Method to set dpps ad roi.
+
+ @param[in] roi config parmas
+
+ @return \link DisplayError \endlink
+ */
+
+ virtual DisplayError SetDisplayDppsAdROI(void *payload) = 0;
+
/*! @brief Method to set the Qsync mode.
@param[in] qsync_mode: \link QSyncMode \endlink
diff --git a/sdm/include/private/color_interface.h b/sdm/include/private/color_interface.h
index 884df5e..feaea30 100644
--- a/sdm/include/private/color_interface.h
+++ b/sdm/include/private/color_interface.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundataion. All rights reserved.
+/* Copyright (c) 2015-2018, The Linux Foundataion. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -45,11 +45,12 @@
class ColorInterface;
-typedef DisplayError (*CreateColorInterface)(uint16_t version, DisplayType type,
+typedef DisplayError (*CreateColorInterface)(uint16_t version, int32_t display_id,
+ DisplayType type,
const PPHWAttributes &attributes,
ColorInterface **interface);
-typedef DisplayError (*DestroyColorInterface)(DisplayType type);
+typedef DisplayError (*DestroyColorInterface)(int32_t display_id);
class ColorModeInterface {
public:
@@ -63,8 +64,8 @@
virtual ~ColorModeInterface() {}
};
-extern "C" ColorModeInterface* GetColorModeInterface(DisplayType type);
-extern "C" void ReleaseColorModeInterface(DisplayType type);
+extern "C" ColorModeInterface* GetColorModeInterface(int32_t display_id, DisplayType type);
+extern "C" void ReleaseColorModeInterface(int32_t display_id);
class ColorInterface {
public:
diff --git a/sdm/include/private/color_params.h b/sdm/include/private/color_params.h
index 32f0505..7c2846f 100644
--- a/sdm/include/private/color_params.h
+++ b/sdm/include/private/color_params.h
@@ -55,6 +55,8 @@
kDisableFrameCapture = BITMAP(7),
kConfigureDetailedEnhancer = BITMAP(8),
kModeSet = BITMAP(10),
+ kMultiDispProc = BITMAP(11),
+ kMultiDispGetId = BITMAP(12),
kGetDetailedEnhancerData = BITMAP(21),
kNoAction = BITMAP(31),
};
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
index 47642b7..39ab20b 100644
--- a/sdm/include/private/hw_info_types.h
+++ b/sdm/include/private/hw_info_types.h
@@ -372,9 +372,9 @@
bool hdr_enabled = false; // HDR feature supported
bool hdr_metadata_type_one = false; // Static HDR metadata type one
uint32_t hdr_eotf = 0; // Electro optical transfer function
- uint32_t peak_luminance = 0; // Panel's peak luminance level
- uint32_t average_luminance = 0; // Panel's average luminance level
- uint32_t blackness_level = 0; // Panel's blackness level
+ float peak_luminance = 0.0f; // Panel's peak luminance level
+ float average_luminance = 0.0f; // Panel's average luminance level
+ float blackness_level = 0.0f; // Panel's blackness level
HWColorPrimaries primaries = {}; // WRGB color primaries
HWPanelOrientation panel_orientation = {}; // Panel Orientation
uint32_t transfer_time_us = 0; // transfer time in micro seconds to panel's active region
diff --git a/sdm/include/utils/locker.h b/sdm/include/utils/locker.h
index dabeb11..e0d91cb 100755
--- a/sdm/include/utils/locker.h
+++ b/sdm/include/utils/locker.h
@@ -127,15 +127,15 @@
Locker() : sequence_wait_(0) {
pthread_mutex_init(&mutex_, 0);
- pthread_condattr_init(&cond_attr);
- pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
- pthread_cond_init(&condition_, &cond_attr);
+ pthread_condattr_init(&cond_attr_);
+ pthread_condattr_setclock(&cond_attr_, CLOCK_MONOTONIC);
+ pthread_cond_init(&condition_, &cond_attr_);
}
~Locker() {
pthread_mutex_destroy(&mutex_);
pthread_cond_destroy(&condition_);
- pthread_condattr_destroy(&cond_attr);
+ pthread_condattr_destroy(&cond_attr_);
}
void Lock() { pthread_mutex_lock(&mutex_); }
@@ -157,7 +157,7 @@
private:
pthread_mutex_t mutex_;
pthread_cond_t condition_;
- pthread_condattr_t cond_attr;
+ pthread_condattr_t cond_attr_;
int sequence_wait_; // This flag is set to 1 on sequence entry, 0 on exit, and -1 on cancel.
// Some routines will wait for sequence of function calls to finish
// so that capturing a transitionary snapshot of context is prevented.
diff --git a/sdm/libs/core/color_manager.cpp b/sdm/libs/core/color_manager.cpp
index 694aada..d895bf7 100644
--- a/sdm/libs/core/color_manager.cpp
+++ b/sdm/libs/core/color_manager.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015 - 2017, The Linux Foundataion. All rights reserved.
+/* Copyright (c) 2015 - 2018, The Linux Foundataion. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -99,10 +99,11 @@
color_lib_.~DynLib();
}
-ColorManagerProxy::ColorManagerProxy(DisplayType type, HWInterface *intf,
+ColorManagerProxy::ColorManagerProxy(int32_t id, DisplayType type, HWInterface *intf,
const HWDisplayAttributes &attr,
const HWPanelInfo &info)
- : device_type_(type), pp_hw_attributes_(), hw_intf_(intf), color_intf_(NULL), pp_features_() {}
+ : display_id_(id), device_type_(type), pp_hw_attributes_(), hw_intf_(intf),
+ color_intf_(NULL), pp_features_() {}
ColorManagerProxy *ColorManagerProxy::CreateColorManagerProxy(DisplayType type,
HWInterface *hw_intf,
@@ -110,6 +111,8 @@
const HWPanelInfo &panel_info) {
DisplayError error = kErrorNone;
PPFeatureVersion versions;
+ int32_t display_id = -1;
+ ColorManagerProxy *color_manager_proxy = NULL;
// check if all resources are available before invoking factory method from libsdm-color.so.
if (!color_lib_ || !create_intf_ || !destroy_intf_) {
@@ -117,8 +120,9 @@
return NULL;
}
- ColorManagerProxy *color_manager_proxy =
- new ColorManagerProxy(type, hw_intf, attribute, panel_info);
+ hw_intf->GetDisplayId(&display_id);
+ color_manager_proxy = new ColorManagerProxy(display_id, type, hw_intf, attribute, panel_info);
+
if (color_manager_proxy) {
// 1. need query post-processing feature version from HWInterface.
error = color_manager_proxy->hw_intf_->GetPPFeaturesVersion(&versions);
@@ -133,7 +137,8 @@
}
// 2. instantiate concrete ColorInterface from libsdm-color.so, pass all hardware info in.
- error = create_intf_(COLOR_VERSION_TAG, color_manager_proxy->device_type_, hw_attr,
+ error = create_intf_(COLOR_VERSION_TAG, color_manager_proxy->display_id_,
+ color_manager_proxy->device_type_, hw_attr,
&color_manager_proxy->color_intf_);
if (error != kErrorNone) {
DLOGW("Unable to instantiate concrete ColorInterface from %s", COLORMGR_LIBRARY_NAME);
@@ -147,7 +152,7 @@
ColorManagerProxy::~ColorManagerProxy() {
if (destroy_intf_)
- destroy_intf_(device_type_);
+ destroy_intf_(display_id_);
color_intf_ = NULL;
}
diff --git a/sdm/libs/core/color_manager.h b/sdm/libs/core/color_manager.h
index db050af..74270e0 100644
--- a/sdm/libs/core/color_manager.h
+++ b/sdm/libs/core/color_manager.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundataion. All rights reserved.
+/* Copyright (c) 2015-2018, The Linux Foundataion. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -77,8 +77,8 @@
protected:
ColorManagerProxy() {}
- ColorManagerProxy(DisplayType type, HWInterface *intf, const HWDisplayAttributes &attr,
- const HWPanelInfo &info);
+ ColorManagerProxy(int32_t id, DisplayType type, HWInterface *intf,
+ const HWDisplayAttributes &attr, const HWPanelInfo &info);
private:
static DynLib color_lib_;
@@ -86,6 +86,7 @@
static DestroyColorInterface destroy_intf_;
static HWResourceInfo hw_res_info_;
+ int32_t display_id_;
DisplayType device_type_;
PPHWAttributes pp_hw_attributes_;
HWInterface *hw_intf_;
diff --git a/sdm/libs/core/comp_manager.cpp b/sdm/libs/core/comp_manager.cpp
index 9a9e75b..e07aae1 100644
--- a/sdm/libs/core/comp_manager.cpp
+++ b/sdm/libs/core/comp_manager.cpp
@@ -171,6 +171,7 @@
registered_displays_.erase(display_comp_ctx->display_id);
configured_displays_.erase(display_comp_ctx->display_id);
+ powered_on_displays_.erase(display_comp_ctx->display_id);
if (display_comp_ctx->display_type == kPluggable) {
max_layers_ = kMaxSDELayers;
@@ -249,7 +250,8 @@
if (!display_comp_ctx->is_primary_panel) {
bool low_end_hw = ((hw_res_info_.num_vig_pipe + hw_res_info_.num_rgb_pipe +
hw_res_info_.num_dma_pipe) <= kSafeModeThreshold);
- constraints->max_layers = max_sde_ext_layers_;
+ constraints->max_layers = display_comp_ctx->display_type == kBuiltIn ?
+ max_sde_builtin_layers_ : max_sde_ext_layers_;
constraints->safe_mode = (low_end_hw && !hw_res_info_.separate_rotator) ? true : safe_mode_;
}
@@ -379,8 +381,8 @@
reinterpret_cast<DisplayCompositionContext *>(display_ctx);
configured_displays_.insert(display_comp_ctx->display_id);
- // Check if all registered displays are in the configured display list.
- if ((registered_displays_.size() == configured_displays_.size())) {
+ // Check if all poweredon displays are in the configured display list.
+ if ((powered_on_displays_.size() == configured_displays_.size())) {
safe_mode_ = false;
}
@@ -549,19 +551,31 @@
configured_displays_.erase(display_comp_ctx->display_id);
DLOGV_IF(kTagCompManager, "Configured displays = [%s]",
StringDisplayList(configured_displays_));
+ powered_on_displays_.erase(display_comp_ctx->display_id);
break;
case kStateOn:
- if (registered_displays_.size() > 1) {
+ case kStateDoze:
+ // Get active display count.
+ if (powered_on_displays_.size()) {
safe_mode_ = true;
DLOGV_IF(kTagCompManager, "safe_mode = %d", safe_mode_);
}
+ powered_on_displays_.insert(display_comp_ctx->display_id);
+ break;
+
+ case kStateDozeSuspend:
+ configured_displays_.erase(display_comp_ctx->display_id);
+ powered_on_displays_.erase(display_comp_ctx->display_id);
break;
default:
break;
}
+ bool inactive = (state == kStateOff) || (state == kStateDozeSuspend);
+ UpdateStrategyConstraints(display_comp_ctx->is_primary_panel, inactive);
+
return true;
}
@@ -609,4 +623,14 @@
}
}
+void CompManager::UpdateStrategyConstraints(bool is_primary, bool disabled) {
+ if (!is_primary) {
+ return;
+ }
+
+ // Allow builtin display to use all pipes when primary is suspended.
+ // Restore it back to 2 after primary poweron.
+ max_sde_builtin_layers_ = (disabled && (powered_on_displays_.size() <= 1)) ? kMaxSDELayers : 2;
+}
+
} // namespace sdm
diff --git a/sdm/libs/core/comp_manager.h b/sdm/libs/core/comp_manager.h
index 7a5f77c..aba0b8b 100644
--- a/sdm/libs/core/comp_manager.h
+++ b/sdm/libs/core/comp_manager.h
@@ -88,6 +88,7 @@
static const int kSafeModeThreshold = 4;
void PrepareStrategyConstraints(Handle display_ctx, HWLayers *hw_layers);
+ void UpdateStrategyConstraints(bool is_primary, bool disabled);
const char *StringDisplayList(const std::set<int32_t> &displays);
struct DisplayCompositionContext {
@@ -111,6 +112,7 @@
ResourceInterface *resource_intf_ = NULL;
std::set<int32_t> registered_displays_; // List of registered displays
std::set<int32_t> configured_displays_; // List of sucessfully configured displays
+ std::set<int32_t> powered_on_displays_; // List of powered on displays.
bool safe_mode_ = false; // Flag to notify all displays to be in resource crunch
// mode, where strategy manager chooses the best strategy
// that uses optimal number of pipes for each display
@@ -119,6 +121,7 @@
ExtensionInterface *extension_intf_ = NULL;
uint32_t max_layers_ = kMaxSDELayers;
uint32_t max_sde_ext_layers_ = 0;
+ uint32_t max_sde_builtin_layers_ = 2;
DppsControlInterface *dpps_ctrl_intf_ = NULL;
};
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 6d54b4e..c646668 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -98,6 +98,7 @@
int property_value = Debug::GetMaxPipesPerMixer(display_type_);
uint32_t active_index = 0;
+ int drop_vsync = 0;
hw_intf_->GetActiveConfig(&active_index);
hw_intf_->GetDisplayAttributes(active_index, &display_attributes_);
fb_config_ = display_attributes_;
@@ -127,17 +128,15 @@
}
}
- if (!color_mgr_exists_) {
+ // ColorManager supported for built-in display.
+ if (kBuiltIn == display_type_) {
color_mgr_ = ColorManagerProxy::CreateColorManagerProxy(display_type_, hw_intf_,
display_attributes_, hw_panel_info_);
if (!color_mgr_) {
- DLOGW("Unable to create ColorManagerProxy for display = %d", display_type_);
- } else {
- color_mgr_exists_ = true;
- if (InitializeColorModes() != kErrorNone) {
- DLOGW("InitColorModes failed for display = %d", display_type_);
- }
+ DLOGW("Unable to create ColorManagerProxy for display %d-%d", display_id_, display_type_);
+ } else if (InitializeColorModes() != kErrorNone) {
+ DLOGW("InitColorModes failed for display %d-%d", display_id_, display_type_);
}
}
@@ -168,6 +167,9 @@
Debug::GetProperty(DISABLE_HW_RECOVERY_DUMP_PROP, &disable_hw_recovery_dump_);
DLOGI("disable_hw_recovery_dump_ set to %d", disable_hw_recovery_dump_);
+ Debug::Get()->GetProperty("DROP_SKEWED_VSYNC", &drop_vsync);
+ drop_skewed_vsync_ = (drop_vsync == 1);
+
return kErrorNone;
CleanupOnError:
@@ -390,7 +392,10 @@
return error;
}
+ // Stop dropping vsync when first commit is received after idle fallback.
+ drop_hw_vsync_ = false;
DLOGI_IF(kTagDisplay, "Exiting commit for display: %d-%d", display_id_, display_type_);
+
return kErrorNone;
}
@@ -484,12 +489,14 @@
return last_power_mode_;
}
-DisplayError DisplayBase::SetDisplayState(DisplayState state, int *release_fence) {
+DisplayError DisplayBase::SetDisplayState(DisplayState state, bool teardown,
+ int *release_fence) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
DisplayError error = kErrorNone;
bool active = false;
- DLOGI("Set state = %d, display %d-%d", state, display_id_, display_type_);
+ DLOGI("Set state = %d, display %d-%d, teardown = %d", state, display_id_,
+ display_type_, teardown);
if (state == state_) {
DLOGI("Same state transition is requested.");
@@ -501,7 +508,7 @@
hw_layers_.info.hw_layers.clear();
error = hw_intf_->Flush();
if (error == kErrorNone) {
- error = hw_intf_->PowerOff();
+ error = hw_intf_->PowerOff(teardown);
}
break;
@@ -1051,6 +1058,10 @@
if (vsync_enable_ != enable) {
error = hw_intf_->SetVSyncState(enable);
if (error == kErrorNotSupported) {
+ if (drop_skewed_vsync_ && (hw_panel_info_.mode == kModeVideo) &&
+ enable && (current_refresh_rate_ == hw_panel_info_.min_fps)) {
+ drop_hw_vsync_ = true;
+ }
error = hw_events_intf_->SetEventState(HWEvent::VSYNC, enable);
}
if (error == kErrorNone) {
@@ -1620,8 +1631,6 @@
mixer_height != display_height);
}
-bool DisplayBase::color_mgr_exists_ = false;
-
void DisplayBase::ClearColorInfo() {
color_modes_.clear();
color_mode_map_.clear();
@@ -1631,7 +1640,6 @@
if (color_mgr_) {
delete color_mgr_;
color_mgr_ = NULL;
- color_mgr_exists_ = false;
}
}
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index e4efb92..7f8e32d 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -66,7 +66,8 @@
virtual DisplayError GetConfig(DisplayConfigFixedInfo *variable_info);
virtual DisplayError GetActiveConfig(uint32_t *index);
virtual DisplayError GetVSyncState(bool *enabled);
- virtual DisplayError SetDisplayState(DisplayState state, int *release_fence);
+ virtual DisplayError SetDisplayState(DisplayState state, bool teardown,
+ int *release_fence);
virtual DisplayError SetActiveConfig(uint32_t index);
virtual DisplayError SetActiveConfig(DisplayConfigVariableInfo *variable_info) {
return kErrorNotSupported;
@@ -124,6 +125,9 @@
virtual DisplayError HandleSecureEvent(SecureEvent secure_event) {
return kErrorNotSupported;
}
+ virtual DisplayError SetDisplayDppsAdROI(void *payload) {
+ return kErrorNotSupported;
+ }
virtual DisplayError SetQSyncMode(QSyncMode qsync_mode) { return kErrorNotSupported; }
virtual std::string Dump();
virtual DisplayError InitializeColorModes();
@@ -185,8 +189,6 @@
uint32_t max_mixer_stages_ = 0;
HWInfoInterface *hw_info_intf_ = NULL;
ColorManagerProxy *color_mgr_ = NULL; // each display object owns its ColorManagerProxy
- // TODO(user): ColorManager supported only on a single built-in display.
- static bool color_mgr_exists_;
bool partial_update_control_ = true;
HWEventsInterface *hw_events_intf_ = NULL;
bool disable_pu_one_frame_ = false;
@@ -211,6 +213,9 @@
bool hw_recovery_logs_captured_ = false;
int disable_hw_recovery_dump_ = 0;
HWQosData default_qos_data_;
+ bool drop_hw_vsync_ = false;
+ uint32_t current_refresh_rate_ = 0;
+ bool drop_skewed_vsync_ = false;
static Locker display_power_reset_lock_;
static bool display_power_reset_pending_;
diff --git a/sdm/libs/core/display_builtin.cpp b/sdm/libs/core/display_builtin.cpp
index e4882b8..e617818 100644
--- a/sdm/libs/core/display_builtin.cpp
+++ b/sdm/libs/core/display_builtin.cpp
@@ -191,10 +191,11 @@
return error;
}
-DisplayError DisplayBuiltIn::SetDisplayState(DisplayState state, int *release_fence) {
+DisplayError DisplayBuiltIn::SetDisplayState(DisplayState state, bool teardown,
+ int *release_fence) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
DisplayError error = kErrorNone;
- error = DisplayBase::SetDisplayState(state, release_fence);
+ error = DisplayBase::SetDisplayState(state, teardown, release_fence);
if (error != kErrorNone) {
return error;
}
@@ -311,7 +312,7 @@
}
DisplayError DisplayBuiltIn::VSync(int64_t timestamp) {
- if (vsync_enable_) {
+ if (vsync_enable_ && !drop_hw_vsync_) {
DisplayEventVSync vsync;
vsync.timestamp = timestamp;
event_handler_->VSync(vsync);
@@ -322,7 +323,9 @@
void DisplayBuiltIn::IdleTimeout() {
if (hw_panel_info_.mode == kModeVideo) {
- event_handler_->HandleEvent(kIdleTimeout);
+ if (event_handler_->HandleEvent(kIdleTimeout) != kErrorNone) {
+ return;
+ }
handle_idle_timeout_ = true;
event_handler_->Refresh();
lock_guard<recursive_mutex> obj(recursive_mutex_);
@@ -425,7 +428,7 @@
int release_fence = -1;
DLOGI("Powering off built-in/primary %d", display_id_);
- status = SetDisplayState(kStateOff, &release_fence);
+ status = SetDisplayState(kStateOff, true /* teardown */, &release_fence);
if (status != kErrorNone) {
DLOGE("power-off on built-in/primary %d failed with error = %d", display_id_, status);
}
@@ -435,7 +438,7 @@
DLOGI("Restoring power mode on built-in/primary %d", display_id_);
DisplayState mode = GetLastPowerMode();
- status = SetDisplayState(mode, &release_fence);
+ status = SetDisplayState(mode, false /* teardown */, &release_fence);
if (status != kErrorNone) {
DLOGE("Setting power mode = %d on built-in/primary %d failed with error = %d", mode,
display_id_, status);
@@ -507,6 +510,17 @@
return error;
}
+DisplayError DisplayBuiltIn::SetDisplayDppsAdROI(void *payload) {
+ lock_guard<recursive_mutex> obj(recursive_mutex_);
+ DisplayError err = kErrorNone;
+
+ err = hw_intf_->SetDisplayDppsAdROI(payload);
+ if (err != kErrorNone)
+ DLOGE("Failed to set ad roi config, err %d", err);
+
+ return err;
+}
+
void DppsInfo::Init(DppsPropIntf *intf, const std::string &panel_name) {
int error = 0;
diff --git a/sdm/libs/core/display_builtin.h b/sdm/libs/core/display_builtin.h
index d4295fa..267267a 100644
--- a/sdm/libs/core/display_builtin.h
+++ b/sdm/libs/core/display_builtin.h
@@ -62,7 +62,8 @@
virtual DisplayError Commit(LayerStack *layer_stack);
virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending);
virtual DisplayError DisablePartialUpdateOneFrame();
- virtual DisplayError SetDisplayState(DisplayState state, int *release_fence);
+ virtual DisplayError SetDisplayState(DisplayState state, bool teardown,
+ int *release_fence);
virtual void SetIdleTimeoutMs(uint32_t active_ms);
virtual DisplayError SetDisplayMode(uint32_t mode);
virtual DisplayError GetRefreshRateRange(uint32_t *min_refresh_rate, uint32_t *max_refresh_rate);
@@ -70,6 +71,7 @@
virtual DisplayError SetPanelBrightness(int level);
virtual DisplayError GetPanelBrightness(int *level);
virtual DisplayError HandleSecureEvent(SecureEvent secure_event);
+ virtual DisplayError SetDisplayDppsAdROI(void *payload);
virtual DisplayError SetQSyncMode(QSyncMode qsync_mode);
virtual DisplayError ControlIdlePowerCollapse(bool enable, bool synchronous);
@@ -95,7 +97,6 @@
bool avr_prop_disabled_ = false;
bool switch_to_cmd_ = false;
bool handle_idle_timeout_ = false;
- uint32_t current_refresh_rate_ = 0;
bool reset_panel_ = false;
bool commit_event_enabled_ = false;
DppsInfo dpps_info_ = {};
diff --git a/sdm/libs/core/display_pluggable.cpp b/sdm/libs/core/display_pluggable.cpp
index a0b1aab..2aaa03a 100644
--- a/sdm/libs/core/display_pluggable.cpp
+++ b/sdm/libs/core/display_pluggable.cpp
@@ -65,22 +65,24 @@
hw_intf_->GetDisplayId(&display_id_);
}
- uint32_t active_mode_index;
- char value[64] = "0";
- Debug::GetProperty(HDMI_S3D_MODE_PROP, value);
- HWS3DMode mode = (HWS3DMode)atoi(value);
- if (mode > kS3DModeNone && mode < kS3DModeMax) {
- active_mode_index = GetBestConfig(mode);
- } else {
- active_mode_index = GetBestConfig(kS3DModeNone);
- }
-
- error = hw_intf_->SetDisplayAttributes(active_mode_index);
+ uint32_t active_mode_index = 0;
+ error = hw_intf_->GetActiveConfig(&active_mode_index);
if (error != kErrorNone) {
HWInterface::Destroy(hw_intf_);
return error;
}
+ uint32_t override_mode_index = active_mode_index;
+ error = GetOverrideConfig(&override_mode_index);
+ if (error == kErrorNone && override_mode_index != active_mode_index) {
+ DLOGI("Overriding display mode %d with mode %d.", active_mode_index, override_mode_index);
+ error = hw_intf_->SetDisplayAttributes(override_mode_index);
+ if (error != kErrorNone) {
+ DLOGI("Failed overriding display mode %d with mode %d. Continuing with display mode %d.",
+ active_mode_index, override_mode_index, active_mode_index);
+ }
+ }
+
error = DisplayBase::Init();
if (error != kErrorNone) {
HWInterface::Destroy(hw_intf_);
@@ -182,56 +184,29 @@
return hw_intf_->OnMinHdcpEncryptionLevelChange(min_enc_level);
}
-uint32_t DisplayPluggable::GetBestConfig(HWS3DMode s3d_mode) {
- uint32_t best_index = 0, index;
- uint32_t num_modes = 0;
+DisplayError DisplayPluggable::GetOverrideConfig(uint32_t *mode_index) {
+ DisplayError error = kErrorNone;
- hw_intf_->GetNumDisplayAttributes(&num_modes);
-
- // Get display attribute for each mode
- std::vector<HWDisplayAttributes> attrib(num_modes);
- for (index = 0; index < num_modes; index++) {
- hw_intf_->GetDisplayAttributes(index, &attrib[index]);
+ if (!mode_index) {
+ DLOGE("Invalid mode index parameter.");
+ return kErrorParameters;
}
- // Select best config for s3d_mode. If s3d is not enabled, s3d_mode is kS3DModeNone
- for (index = 0; index < num_modes; index++) {
- if (attrib[index].s3d_config[s3d_mode]) {
- break;
- }
- }
+ // TODO(user): Need to add support for S3D modes based on HDMI_S3D_MODE_PROP property.
- index = 0;
- best_index = UINT32(index);
- for (size_t index = best_index + 1; index < num_modes; index++) {
- // TODO(user): Need to add support to S3D modes
- // From the available configs, select the best
- // Ex: 1920x1080@60Hz is better than 1920x1080@30 and 1920x1080@30 is better than 1280x720@60
- if (attrib[index].x_pixels > attrib[best_index].x_pixels) {
- best_index = UINT32(index);
- } else if (attrib[index].x_pixels == attrib[best_index].x_pixels) {
- if (attrib[index].y_pixels > attrib[best_index].y_pixels) {
- best_index = UINT32(index);
- } else if (attrib[index].y_pixels == attrib[best_index].y_pixels) {
- if (attrib[index].vsync_period_ns < attrib[best_index].vsync_period_ns) {
- best_index = UINT32(index);
- }
- }
- }
- }
char val[kPropertyMax] = {};
- // Used for changing HDMI Resolution - override the best with user set config
- bool user_config = (Debug::GetExternalResolution(val));
-
+ // Used for changing HDMI Resolution - Override the preferred mode with user set config.
+ bool user_config = Debug::GetExternalResolution(val);
if (user_config) {
uint32_t config_index = 0;
// For the config, get the corresponding index
- DisplayError error = hw_intf_->GetConfigIndex(val, &config_index);
- if (error == kErrorNone)
- return config_index;
+ error = hw_intf_->GetConfigIndex(val, &config_index);
+ if (error == kErrorNone) {
+ *mode_index = config_index;
+ }
}
- return best_index;
+ return error;
}
void DisplayPluggable::GetScanSupport() {
@@ -334,6 +309,7 @@
var.push_back(std::make_pair(kDynamicRangeAttribute, kSdr));
var.push_back(std::make_pair(kPictureQualityAttribute, kStandard));
color_mode_attr_map_.insert(std::make_pair(kSrgb, var));
+ current_color_mode_ = kSrgb;
pt.primaries = ColorPrimaries_BT2020;
if (!hw_panel_info_.hdr_enabled) {
UpdateColorModes();
@@ -367,17 +343,6 @@
return kErrorNone;
}
-DisplayError DisplayPluggable::SetDisplayState(DisplayState state, int *release_fence) {
- lock_guard<recursive_mutex> obj(recursive_mutex_);
- DisplayError error = kErrorNone;
- error = DisplayBase::SetDisplayState(state, release_fence);
- if (error != kErrorNone) {
- return error;
- }
-
- return kErrorNone;
-}
-
static PrimariesTransfer GetBlendSpaceFromAttributes(const std::string &color_gamut,
const std::string &transfer) {
PrimariesTransfer blend_space_ = {};
@@ -427,6 +392,7 @@
if (error != kErrorNone) {
DLOGE("Failed Set blend space, error = %d display_type_=%d", error, display_type_);
}
+ current_color_mode_ = color_mode;
return kErrorNone;
}
@@ -481,10 +447,10 @@
for (ColorModeAttrMap::iterator it = color_mode_attr_map_.begin();
((i < num_color_modes_) && (it != color_mode_attr_map_.end())); i++, it++) {
color_modes_[i].id = INT32(i);
- std::size_t length = (it->first).copy(color_modes_[i].name, sizeof(it->first.c_str()));
+ std::size_t length = (it->first).copy(color_modes_[i].name, sizeof(SDEDisplayMode::name) - 1);
color_modes_[i].name[length] = '\0';
color_mode_map_.insert(std::make_pair(color_modes_[i].name, &color_modes_[i]));
- DLOGI("Color mode = %s", it->first.c_str());
+ DLOGI("Color mode = %s", color_modes_[i].name);
}
return;
}
diff --git a/sdm/libs/core/display_pluggable.h b/sdm/libs/core/display_pluggable.h
index 902ff92..d15129c 100644
--- a/sdm/libs/core/display_pluggable.h
+++ b/sdm/libs/core/display_pluggable.h
@@ -53,7 +53,6 @@
virtual DisplayError GetColorModeCount(uint32_t *mode_count);
virtual DisplayError GetColorModes(uint32_t *mode_count, std::vector<std::string> *color_modes);
virtual DisplayError GetColorModeAttr(const std::string &color_mode, AttrVal *attr);
- virtual DisplayError SetDisplayState(DisplayState state, int *release_fence);
virtual DisplayError SetColorTransform(const uint32_t length, const double *color_transform) {
return kErrorNone;
}
@@ -72,7 +71,7 @@
void UpdateColorModes();
private:
- uint32_t GetBestConfig(HWS3DMode s3d_mode);
+ DisplayError GetOverrideConfig(uint32_t *mode_index);
void GetScanSupport();
void SetS3DMode(LayerStack *layer_stack);
diff --git a/sdm/libs/core/display_virtual.cpp b/sdm/libs/core/display_virtual.cpp
index cff7519..21a7890 100644
--- a/sdm/libs/core/display_virtual.cpp
+++ b/sdm/libs/core/display_virtual.cpp
@@ -165,5 +165,14 @@
return DisplayBase::Prepare(layer_stack);
}
+DisplayError DisplayVirtual::GetColorModeCount(uint32_t *mode_count) {
+ lock_guard<recursive_mutex> obj(recursive_mutex_);
+
+ // Color Manager isn't supported for virtual displays.
+ *mode_count = 1;
+
+ return kErrorNone;
+}
+
} // namespace sdm
diff --git a/sdm/libs/core/display_virtual.h b/sdm/libs/core/display_virtual.h
index a651447..e3daec6 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 GetColorModeCount(uint32_t *mode_count);
};
} // namespace sdm
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index 5ac7fff..cd08e38 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -522,6 +522,8 @@
// Update current mode with preferred mode
for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) {
if (connector_info_.modes[mode_index].mode.type & DRM_MODE_TYPE_PREFERRED) {
+ DLOGI("Updating current display mode %d to preferred mode %d.", current_mode_index_,
+ mode_index);
current_mode_index_ = mode_index;
break;
}
@@ -664,8 +666,9 @@
hw_panel_info_.is_primary_panel = connector_info_.is_primary;
hw_panel_info_.is_pluggable = 0;
hw_panel_info_.hdr_enabled = connector_info_.panel_hdr_prop.hdr_enabled;
- hw_panel_info_.peak_luminance = connector_info_.panel_hdr_prop.peak_brightness;
- hw_panel_info_.blackness_level = connector_info_.panel_hdr_prop.blackness_level;
+ // Convert the luminance values to cd/m^2 units.
+ hw_panel_info_.peak_luminance = FLOAT(connector_info_.panel_hdr_prop.peak_brightness) / 10000.0f;
+ hw_panel_info_.blackness_level = FLOAT(connector_info_.panel_hdr_prop.blackness_level) / 10000.0f;
hw_panel_info_.primaries.white_point[0] = connector_info_.panel_hdr_prop.display_primaries[0];
hw_panel_info_.primaries.white_point[1] = connector_info_.panel_hdr_prop.display_primaries[1];
hw_panel_info_.primaries.red[0] = connector_info_.panel_hdr_prop.display_primaries[2];
@@ -860,7 +863,7 @@
return kErrorNone;
}
-DisplayError HWDeviceDRM::PowerOff() {
+DisplayError HWDeviceDRM::PowerOff(bool teardown) {
DTRACE_SCOPED();
if (!drm_atomic_intf_) {
DLOGE("DRM Atomic Interface is null!");
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index 6cfd51c..9bc02b6 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -80,7 +80,7 @@
virtual DisplayError SetDisplayAttributes(const HWDisplayAttributes &display_attributes);
virtual DisplayError GetConfigIndex(char *mode, uint32_t *index);
virtual DisplayError PowerOn(const HWQosData &qos_data, int *release_fence);
- virtual DisplayError PowerOff();
+ virtual DisplayError PowerOff(bool teardown);
virtual DisplayError Doze(const HWQosData &qos_data, int *release_fence);
virtual DisplayError DozeSuspend(const HWQosData &qos_data, int *release_fence);
virtual DisplayError Standby();
@@ -116,6 +116,7 @@
virtual DisplayError ControlIdlePowerCollapse(bool enable, bool synchronous) {
return kErrorNotSupported;
}
+ virtual DisplayError SetDisplayDppsAdROI(void *payload) { return kErrorNotSupported; }
enum {
kHWEventVSync,
diff --git a/sdm/libs/core/drm/hw_info_drm.cpp b/sdm/libs/core/drm/hw_info_drm.cpp
index 09903b9..c7ac2f0 100644
--- a/sdm/libs/core/drm/hw_info_drm.cpp
+++ b/sdm/libs/core/drm/hw_info_drm.cpp
@@ -781,6 +781,7 @@
}
hw_info.is_connected = iter.second.is_connected ? 1 : 0;
hw_info.is_primary = iter.second.is_primary ? 1 : 0;
+ hw_info.is_wb_ubwc_supported = iter.second.is_wb_ubwc_supported;
if (hw_info.display_id >= 0) {
(*hw_displays_info)[hw_info.display_id] = hw_info;
}
diff --git a/sdm/libs/core/drm/hw_peripheral_drm.cpp b/sdm/libs/core/drm/hw_peripheral_drm.cpp
index f35b11e..46e7b5a 100644
--- a/sdm/libs/core/drm/hw_peripheral_drm.cpp
+++ b/sdm/libs/core/drm/hw_peripheral_drm.cpp
@@ -109,8 +109,7 @@
return;
}
- uint32_t count = 0;
- for (uint32_t i = 0; i < hw_resource_.hw_dest_scalar_info.count; i++) {
+ for (uint32_t i = 0; i < hw_resource_.hw_dest_scalar_info.count && validate; i++) {
DestScaleInfoMap::iterator it = hw_layer_info.dest_scale_info_map.find(i);
if (it == hw_layer_info.dest_scale_info_map.end()) {
@@ -118,10 +117,10 @@
}
HWDestScaleInfo *dest_scale_info = it->second;
- SDEScaler *scale = &scalar_data_[count];
+ SDEScaler *scale = &scalar_data_[i];
hw_scale_->SetScaler(dest_scale_info->scale_data, scale);
- sde_drm_dest_scaler_cfg *dest_scalar_data = &sde_dest_scalar_data_.ds_cfg[count];
+ sde_drm_dest_scaler_cfg *dest_scalar_data = &sde_dest_scalar_data_.ds_cfg[i];
dest_scalar_data->flags = 0;
if (scale->scaler_v2.enable) {
dest_scalar_data->flags |= SDE_DRM_DESTSCALER_ENABLE;
@@ -135,24 +134,31 @@
if (hw_panel_info_.partial_update) {
dest_scalar_data->flags |= SDE_DRM_DESTSCALER_PU_ENABLE;
}
-
- if (!std::memcmp(&dest_scalar_cache_[count].scalar_data, scale, sizeof(SDEScaler)) &&
- dest_scalar_cache_[count].flags == dest_scalar_data->flags) {
- continue;
- }
-
dest_scalar_data->index = i;
dest_scalar_data->lm_width = dest_scale_info->mixer_width;
dest_scalar_data->lm_height = dest_scale_info->mixer_height;
dest_scalar_data->scaler_cfg = reinterpret_cast<uint64_t>(&scale->scaler_v2);
- if (!validate) {
- dest_scalar_cache_[count].flags = dest_scalar_data->flags;
- dest_scalar_cache_[count].scalar_data = *scale;
+
+ if (std::memcmp(&dest_scalar_cache_[i].scalar_data, scale, sizeof(SDEScaler)) ||
+ dest_scalar_cache_[i].flags != dest_scalar_data->flags) {
+ needs_ds_update_ = true;
}
- count++;
}
- if (count) {
- sde_dest_scalar_data_.num_dest_scaler = count;
+
+ if (needs_ds_update_) {
+ if (!validate) {
+ // Cache the destination scalar data during commit
+ 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;
+ }
+ dest_scalar_cache_[i].flags = sde_dest_scalar_data_.ds_cfg[i].flags;
+ dest_scalar_cache_[i].scalar_data = scalar_data_[i];
+ }
+ needs_ds_update_ = false;
+ }
+ sde_dest_scalar_data_.num_dest_scaler = UINT32(hw_layer_info.dest_scale_info_map.size());
drm_atomic_intf_->Perform(DRMOps::CRTC_SET_DEST_SCALER_CONFIG, token_.crtc_id,
reinterpret_cast<uint64_t>(&sde_dest_scalar_data_));
}
@@ -181,6 +187,27 @@
object_type = feature_payload->object_type;
feature_id = feature_payload->feature_id;
value = feature_payload->value;
+
+ if (feature_id == sde_drm::kFeatureAd4Roi) {
+ if (feature_payload->value) {
+ DisplayDppsAd4RoiCfg *params = reinterpret_cast<DisplayDppsAd4RoiCfg *>
+ (feature_payload->value);
+ if (!params) {
+ DLOGE("invalid playload value %d", feature_payload->value);
+ return kErrorNotSupported;
+ }
+
+ ad4_roi_cfg_.h_x = params->h_start;
+ ad4_roi_cfg_.h_y = params->h_end;
+ ad4_roi_cfg_.v_x = params->v_start;
+ ad4_roi_cfg_.v_y = params->v_end;
+ ad4_roi_cfg_.factor_in = params->factor_in;
+ ad4_roi_cfg_.factor_out = params->factor_out;
+
+ value = (uint64_t)&ad4_roi_cfg_;
+ }
+ }
+
if (object_type == DRM_MODE_OBJECT_CRTC) {
obj_id = token_.crtc_id;
} else if (object_type == DRM_MODE_OBJECT_CONNECTOR) {
@@ -336,6 +363,7 @@
if (!enabled) {
drm_mgr_intf_->UnregisterDisplay(cwb_config_.token);
cwb_config_.enabled = false;
+ registry_.Clear();
}
}
@@ -373,4 +401,26 @@
return kErrorNone;
}
+DisplayError HWPeripheralDRM::SetDisplayDppsAdROI(void *payload) {
+ DisplayError err = kErrorNone;
+ struct sde_drm::DppsFeaturePayload feature_payload = {};
+
+ if (!payload) {
+ DLOGE("Invalid payload parameter");
+ return kErrorParameters;
+ }
+
+ feature_payload.object_type = DRM_MODE_OBJECT_CRTC;
+ feature_payload.feature_id = sde_drm::kFeatureAd4Roi;
+ feature_payload.value = (uint64_t)(payload);
+
+ err = SetDppsFeature(&feature_payload, sizeof(feature_payload));
+ if (err != kErrorNone) {
+ DLOGE("Faid to SetDppsFeature feature_id = %d, err = %d",
+ sde_drm::kFeatureAd4Roi, err);
+ }
+
+ return err;
+}
+
} // namespace sdm
diff --git a/sdm/libs/core/drm/hw_peripheral_drm.h b/sdm/libs/core/drm/hw_peripheral_drm.h
index e693163..96889de 100644
--- a/sdm/libs/core/drm/hw_peripheral_drm.h
+++ b/sdm/libs/core/drm/hw_peripheral_drm.h
@@ -56,6 +56,7 @@
virtual DisplayError HandleSecureEvent(SecureEvent secure_event);
virtual DisplayError ControlIdlePowerCollapse(bool enable, bool synchronous);
virtual DisplayError PowerOn(const HWQosData &qos_data, int *release_fence);
+ virtual DisplayError SetDisplayDppsAdROI(void *payload);
private:
void SetDestScalarData(HWLayersInfo hw_layer_info, bool validate);
@@ -79,6 +80,8 @@
CWBConfig cwb_config_ = {};
sde_drm::DRMIdlePCState idle_pc_state_ = sde_drm::DRMIdlePCState::NONE;
std::vector<DestScalarCache> dest_scalar_cache_ = {};
+ drm_msm_ad4_roi_cfg ad4_roi_cfg_ = {};
+ bool needs_ds_update_ = false;
};
} // namespace sdm
diff --git a/sdm/libs/core/drm/hw_tv_drm.cpp b/sdm/libs/core/drm/hw_tv_drm.cpp
index cd1f4ce..6272fa7 100644
--- a/sdm/libs/core/drm/hw_tv_drm.cpp
+++ b/sdm/libs/core/drm/hw_tv_drm.cpp
@@ -28,6 +28,7 @@
*/
#include "hw_tv_drm.h"
+#include <math.h>
#include <sys/time.h>
#include <utils/debug.h>
#include <utils/sys.h>
@@ -89,6 +90,14 @@
return hdr_transfer;
}
+static float GetMaxOrAverageLuminance(float luminance) {
+ return (50.0f * powf(2.0f, (luminance / 32.0f)));
+}
+
+static float GetMinLuminance(float luminance, float max_luminance) {
+ return (max_luminance * ((luminance / 255.0f) * (luminance / 255.0f)) / 100.0f);
+}
+
HWTVDRM::HWTVDRM(int32_t display_id, BufferSyncHandler *buffer_sync_handler,
BufferAllocator *buffer_allocator, HWInfoInterface *hw_info_intf)
: HWDeviceDRM(buffer_sync_handler, buffer_allocator, hw_info_intf) {
@@ -154,9 +163,17 @@
return kErrorNone;
}
-DisplayError HWTVDRM::PowerOff() {
+DisplayError HWTVDRM::PowerOff(bool teardown) {
DTRACE_SCOPED();
+ if (!drm_atomic_intf_) {
+ DLOGE("DRM Atomic Interface is null!");
+ return kErrorUndefined;
+ }
+ if (teardown) {
+ // LP connecter prop N/A for External
+ drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 0);
+ }
int ret = drm_atomic_intf_->Commit(true /* synchronous */, false /* retain_planes*/);
if (ret) {
DLOGE("%s failed with error %d", __FUNCTION__, ret);
@@ -185,10 +202,30 @@
hw_panel_info_.hdr_enabled = connector_info_.ext_hdr_prop.hdr_supported;
hw_panel_info_.hdr_metadata_type_one = connector_info_.ext_hdr_prop.hdr_metadata_type_one;
hw_panel_info_.hdr_eotf = connector_info_.ext_hdr_prop.hdr_eotf;
- hw_panel_info_.peak_luminance = connector_info_.ext_hdr_prop.hdr_max_luminance;
- hw_panel_info_.average_luminance = connector_info_.ext_hdr_prop.hdr_avg_luminance;
- hw_panel_info_.blackness_level = connector_info_.ext_hdr_prop.hdr_min_luminance;
- DLOGI("TV Panel: %s, type_one = %d, eotf = %d, luminance[max = %d, min = %d, avg = %d]",
+
+ // Convert the raw luminance values from driver to Candela per meter^2 unit.
+ float max_luminance = FLOAT(connector_info_.ext_hdr_prop.hdr_max_luminance);
+ if (max_luminance != 0.0f) {
+ max_luminance = GetMaxOrAverageLuminance(max_luminance);
+ }
+ bool valid_luminance = (max_luminance > kMinPeakLuminance) && (max_luminance < kMaxPeakLuminance);
+ hw_panel_info_.peak_luminance = valid_luminance ? max_luminance : kDefaultMaxLuminance;
+
+ float min_luminance = FLOAT(connector_info_.ext_hdr_prop.hdr_min_luminance);
+ if (min_luminance != 0.0f) {
+ min_luminance = GetMinLuminance(min_luminance, hw_panel_info_.peak_luminance);
+ }
+ hw_panel_info_.blackness_level = (min_luminance < 1.0f) ? min_luminance : kDefaultMinLuminance;
+
+ float average_luminance = FLOAT(connector_info_.ext_hdr_prop.hdr_avg_luminance);
+ if (average_luminance != 0.0f) {
+ average_luminance = GetMaxOrAverageLuminance(average_luminance);
+ } else {
+ average_luminance = (hw_panel_info_.peak_luminance + hw_panel_info_.blackness_level) / 2.0f;
+ }
+ hw_panel_info_.average_luminance = average_luminance;
+
+ DLOGI("TV Panel: %s, type_one = %d, eotf = %d, luminance[max = %f, min = %f, avg = %f]",
hw_panel_info_.hdr_enabled ? "HDR" : "Non-HDR", hw_panel_info_.hdr_metadata_type_one,
hw_panel_info_.hdr_eotf, hw_panel_info_.peak_luminance, hw_panel_info_.blackness_level,
hw_panel_info_.average_luminance);
diff --git a/sdm/libs/core/drm/hw_tv_drm.h b/sdm/libs/core/drm/hw_tv_drm.h
index 46f3117..96d0746 100644
--- a/sdm/libs/core/drm/hw_tv_drm.h
+++ b/sdm/libs/core/drm/hw_tv_drm.h
@@ -42,7 +42,7 @@
protected:
virtual DisplayError SetDisplayAttributes(uint32_t index);
virtual DisplayError GetConfigIndex(char *mode, uint32_t *index);
- virtual DisplayError PowerOff();
+ virtual DisplayError PowerOff(bool teardown);
virtual DisplayError Doze(const HWQosData &qos_data, int *release_fence);
virtual DisplayError DozeSuspend(const HWQosData &qos_data, int *release_fence);
virtual DisplayError Standby();
@@ -57,6 +57,10 @@
static const int kBitRGB = 20;
static const int kBitYUV = 21;
+ const float kDefaultMinLuminance = 0.02f;
+ const float kDefaultMaxLuminance = 500.0f;
+ const float kMinPeakLuminance = 300.0f;
+ const float kMaxPeakLuminance = 1000.0f;
drm_msm_ext_hdr_metadata hdr_metadata_ = {};
};
diff --git a/sdm/libs/core/fb/hw_device.cpp b/sdm/libs/core/fb/hw_device.cpp
index 2dca3c2..9e3f2b9 100644
--- a/sdm/libs/core/fb/hw_device.cpp
+++ b/sdm/libs/core/fb/hw_device.cpp
@@ -182,7 +182,7 @@
return kErrorNone;
}
-DisplayError HWDevice::PowerOff() {
+DisplayError HWDevice::PowerOff(bool teardown) {
return kErrorNone;
}
@@ -881,11 +881,11 @@
} else if (!strncmp(tokens[0], "is_hdr_enabled", strlen("is_hdr_enabled"))) {
panel_info->hdr_enabled = atoi(tokens[1]);
} else if (!strncmp(tokens[0], "peak_brightness", strlen("peak_brightness"))) {
- panel_info->peak_luminance = UINT32(atoi(tokens[1]));
+ panel_info->peak_luminance = FLOAT(atoi(tokens[1]));
} else if (!strncmp(tokens[0], "average_brightness", strlen("average_brightness"))) {
- panel_info->average_luminance = UINT32(atoi(tokens[1]));
+ panel_info->average_luminance = FLOAT(atoi(tokens[1]));
} else if (!strncmp(tokens[0], "blackness_level", strlen("blackness_level"))) {
- panel_info->blackness_level = UINT32(atoi(tokens[1]));
+ panel_info->blackness_level = FLOAT(atoi(tokens[1]));
} else if (!strncmp(tokens[0], "white_chromaticity_x", strlen("white_chromaticity_x"))) {
panel_info->primaries.white_point[0] = UINT32(atoi(tokens[1]));
} else if (!strncmp(tokens[0], "white_chromaticity_y", strlen("white_chromaticity_y"))) {
diff --git a/sdm/libs/core/fb/hw_device.h b/sdm/libs/core/fb/hw_device.h
index 7504721..6adb93b 100644
--- a/sdm/libs/core/fb/hw_device.h
+++ b/sdm/libs/core/fb/hw_device.h
@@ -72,7 +72,7 @@
virtual DisplayError SetDisplayAttributes(const HWDisplayAttributes &display_attributes);
virtual DisplayError GetConfigIndex(char *mode, uint32_t *index);
virtual DisplayError PowerOn(const HWQosData &qos_data, int *release_fence);
- virtual DisplayError PowerOff();
+ virtual DisplayError PowerOff(bool teardown);
virtual DisplayError Doze(const HWQosData &qos_data, int *release_fence);
virtual DisplayError DozeSuspend(const HWQosData &qos_data, int *release_fence);
virtual DisplayError Standby();
@@ -106,6 +106,7 @@
virtual DisplayError ControlIdlePowerCollapse(bool enable, bool synchronous) {
return kErrorNotSupported;
}
+ virtual DisplayError SetDisplayDppsAdROI(void *payload) { return kErrorNotSupported; }
enum {
kHWEventVSync,
diff --git a/sdm/libs/core/fb/hw_hdmi.cpp b/sdm/libs/core/fb/hw_hdmi.cpp
index efbd4fb..b8b196d 100644
--- a/sdm/libs/core/fb/hw_hdmi.cpp
+++ b/sdm/libs/core/fb/hw_hdmi.cpp
@@ -126,6 +126,7 @@
return mdp_pixel_encoding;
}
+
static int32_t GetBitsPerComponent(const LayerBuffer &layer_buffer) {
bool is_yuv = layer_buffer.flags.video;
bool is_10_bit = Is10BitFormat(layer_buffer.format);
@@ -227,6 +228,12 @@
GetPanelS3DMode();
+ error = SetDisplayAttributes(active_config_index_);
+ if (error != kErrorNone) {
+ Deinit();
+ return error;
+ }
+
s3d_mode_sdm_to_mdp_.insert(std::pair<HWS3DMode, msm_hdmi_s3d_mode>
(kS3DModeNone, HDMI_S3D_NONE));
s3d_mode_sdm_to_mdp_.insert(std::pair<HWS3DMode, msm_hdmi_s3d_mode>
diff --git a/sdm/libs/core/fb/hw_primary.cpp b/sdm/libs/core/fb/hw_primary.cpp
index b58c5b5..d130d87 100644
--- a/sdm/libs/core/fb/hw_primary.cpp
+++ b/sdm/libs/core/fb/hw_primary.cpp
@@ -333,7 +333,7 @@
return HWDevice::GetConfigIndex(mode, index);
}
-DisplayError HWPrimary::PowerOff() {
+DisplayError HWPrimary::PowerOff(bool teardown) {
if (Sys::ioctl_(device_fd_, FBIOBLANK, FB_BLANK_POWERDOWN) < 0) {
IOCTL_LOGE(FB_BLANK_POWERDOWN, device_type_);
return kErrorHardware;
diff --git a/sdm/libs/core/fb/hw_primary.h b/sdm/libs/core/fb/hw_primary.h
index e2515d1..6d611a5 100644
--- a/sdm/libs/core/fb/hw_primary.h
+++ b/sdm/libs/core/fb/hw_primary.h
@@ -45,7 +45,7 @@
HWDisplayAttributes *display_attributes);
virtual DisplayError SetDisplayAttributes(uint32_t index);
virtual DisplayError GetConfigIndex(char *mode, uint32_t *index);
- virtual DisplayError PowerOff();
+ virtual DisplayError PowerOff(bool teardown);
virtual DisplayError Doze(const HWQosData &qos_data, int *release_fence);
virtual DisplayError DozeSuspend(const HWQosData &qos_data, int *release_fence);
virtual DisplayError Validate(HWLayers *hw_layers);
diff --git a/sdm/libs/core/hw_interface.h b/sdm/libs/core/hw_interface.h
index 06d166e..7980fdd 100644
--- a/sdm/libs/core/hw_interface.h
+++ b/sdm/libs/core/hw_interface.h
@@ -88,7 +88,7 @@
virtual DisplayError SetDisplayAttributes(const HWDisplayAttributes &display_attributes) = 0;
virtual DisplayError GetConfigIndex(char *mode, uint32_t *index) = 0;
virtual DisplayError PowerOn(const HWQosData &qos_data, int *release_fence) = 0;
- virtual DisplayError PowerOff() = 0;
+ virtual DisplayError PowerOff(bool teardown) = 0;
virtual DisplayError Doze(const HWQosData &qos_data, int *release_fence) = 0;
virtual DisplayError DozeSuspend(const HWQosData &qos_data, int *release_fence) = 0;
virtual DisplayError Standby() = 0;
@@ -119,6 +119,7 @@
virtual DisplayError GetDppsFeatureInfo(void *payload, size_t size) = 0;
virtual DisplayError HandleSecureEvent(SecureEvent secure_event) = 0;
virtual DisplayError ControlIdlePowerCollapse(bool enable, bool synchronous) = 0;
+ virtual DisplayError SetDisplayDppsAdROI(void *payload) = 0;
protected:
virtual ~HWInterface() { }
diff --git a/sdm/libs/core/strategy.cpp b/sdm/libs/core/strategy.cpp
index 1281545..5098b01 100644
--- a/sdm/libs/core/strategy.cpp
+++ b/sdm/libs/core/strategy.cpp
@@ -150,6 +150,11 @@
Layer layer = *gpu_target_layer;
hw_layers_info_->index.push_back(hw_layers_info_->gpu_target_index);
hw_layers_info_->roi_index.push_back(0);
+ layer.transform.flip_horizontal ^= hw_panel_info_.panel_orientation.flip_horizontal;
+ layer.transform.flip_vertical ^= hw_panel_info_.panel_orientation.flip_vertical;
+ // Flip rect to match transform.
+ TransformHV(src_domain, layer.dst_rect, layer.transform, &layer.dst_rect);
+ // Scale to mixer resolution.
MapRect(src_domain, dst_domain, layer.dst_rect, &layer.dst_rect);
hw_layers_info_->hw_layers.push_back(layer);
diff --git a/sdm/libs/hwc2/Android.mk b/sdm/libs/hwc2/Android.mk
index 6edbf5f..2ac716d 100644
--- a/sdm/libs/hwc2/Android.mk
+++ b/sdm/libs/hwc2/Android.mk
@@ -38,6 +38,12 @@
LOCAL_SHARED_LIBRARIES += vendor.display.config@1.2
LOCAL_SHARED_LIBRARIES += vendor.display.config@1.3
endif
+ifeq ($(display_config_version), DISPLAY_CONFIG_1_4)
+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
+endif
LOCAL_SRC_FILES := hwc_session.cpp \
hwc_session_services.cpp \
diff --git a/sdm/libs/hwc2/display_null.cpp b/sdm/libs/hwc2/display_null.cpp
index 99cd017..9076779 100644
--- a/sdm/libs/hwc2/display_null.cpp
+++ b/sdm/libs/hwc2/display_null.cpp
@@ -146,7 +146,8 @@
return kErrorNone;
}
-DisplayError DisplayNullExternal::SetDisplayState(DisplayState state, int *release_fence) {
+DisplayError DisplayNullExternal::SetDisplayState(DisplayState state, bool teardown,
+ int *release_fence) {
state_ = state;
return kErrorNone;
}
diff --git a/sdm/libs/hwc2/display_null.h b/sdm/libs/hwc2/display_null.h
index 82b7ed4..65096e1 100644
--- a/sdm/libs/hwc2/display_null.h
+++ b/sdm/libs/hwc2/display_null.h
@@ -59,7 +59,7 @@
MAKE_NO_OP(Commit(LayerStack *))
MAKE_NO_OP(GetDisplayState(DisplayState *))
- MAKE_NO_OP(SetDisplayState(DisplayState, int*))
+ MAKE_NO_OP(SetDisplayState(DisplayState, bool, int*))
MAKE_NO_OP(SetFrameBufferConfig(const DisplayConfigVariableInfo &))
MAKE_NO_OP(Flush())
MAKE_NO_OP(GetVSyncState(bool *))
@@ -97,6 +97,7 @@
MAKE_NO_OP(HandleSecureEvent(SecureEvent))
MAKE_NO_OP(SetQSyncMode(QSyncMode))
MAKE_NO_OP(ControlIdlePowerCollapse(bool, bool))
+ MAKE_NO_OP(SetDisplayDppsAdROI(void *))
DisplayConfigVariableInfo default_variable_config_ = {};
DisplayConfigFixedInfo default_fixed_config_ = {};
@@ -106,7 +107,8 @@
public:
virtual DisplayError Commit(LayerStack *layer_stack);
virtual DisplayError GetDisplayState(DisplayState *state);
- virtual DisplayError SetDisplayState(DisplayState state, int *release_fence);
+ virtual DisplayError SetDisplayState(DisplayState state, bool teardown,
+ int *release_fence);
virtual DisplayError SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info);
virtual DisplayError GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info);
void SetActive(bool active) { active_ = active; }
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index 75cea13..7c14b70 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -107,8 +107,7 @@
return HWC2::Error::None;
}
-HWC2::Error HWCColorMode::SetColorModeWithRenderIntent(ColorMode mode, RenderIntent intent) {
- DTRACE_SCOPED();
+HWC2::Error HWCColorMode::ValidateColorModeWithRenderIntent(ColorMode mode, RenderIntent intent) {
if (mode < ColorMode::NATIVE || mode > ColorMode::BT2100_HLG) {
DLOGE("Could not find mode: %d", mode);
return HWC2::Error::BadParameter;
@@ -120,6 +119,42 @@
return HWC2::Error::Unsupported;
}
+ return HWC2::Error::None;
+}
+
+HWC2::Error HWCColorMode::SetColorModeWithRenderIntent(ColorMode mode, RenderIntent intent) {
+ DTRACE_SCOPED();
+ HWC2::Error hwc_error = ValidateColorModeWithRenderIntent(mode, intent);
+ if (hwc_error != HWC2::Error::None) {
+ return hwc_error;
+ }
+
+ if (current_color_mode_ == mode && current_render_intent_ == intent) {
+ return HWC2::Error::None;
+ }
+
+ auto mode_string = color_mode_map_[mode][intent];
+ DisplayError error = display_intf_->SetColorMode(mode_string);
+ if (error != kErrorNone) {
+ DLOGE("failed for mode = %d intent = %d name = %s", mode, intent, mode_string.c_str());
+ return HWC2::Error::Unsupported;
+ }
+ // The mode does not have the PCC configured, restore the transform
+ RestoreColorTransform();
+
+ current_color_mode_ = mode;
+ current_render_intent_ = intent;
+ DLOGV_IF(kTagClient, "Successfully applied mode = %d intent = %d name = %s", mode, intent,
+ mode_string.c_str());
+ return HWC2::Error::None;
+}
+
+HWC2::Error HWCColorMode::CacheColorModeWithRenderIntent(ColorMode mode, RenderIntent intent) {
+ HWC2::Error error = ValidateColorModeWithRenderIntent(mode, intent);
+ if (error != HWC2::Error::None) {
+ return error;
+ }
+
if (current_color_mode_ == mode && current_render_intent_ == intent) {
return HWC2::Error::None;
}
@@ -453,7 +488,7 @@
HWCLayer *HWCDisplay::GetHWCLayer(hwc2_layer_t layer_id) {
const auto map_layer = layer_map_.find(layer_id);
if (map_layer == layer_map_.end()) {
- DLOGE("[%" PRIu64 "] GetLayer(%" PRIu64 ") failed: no such layer", id_, layer_id);
+ DLOGW("[%" PRIu64 "] GetLayer(%" PRIu64 ") failed: no such layer", id_, layer_id);
return nullptr;
} else {
return map_layer->second;
@@ -463,7 +498,7 @@
HWC2::Error HWCDisplay::DestroyLayer(hwc2_layer_t layer_id) {
const auto map_layer = layer_map_.find(layer_id);
if (map_layer == layer_map_.end()) {
- DLOGE("[%" PRIu64 "] destroyLayer(%" PRIu64 ") failed: no such layer", id_, layer_id);
+ DLOGW("[%" PRIu64 "] destroyLayer(%" PRIu64 ") failed: no such layer", id_, layer_id);
return HWC2::Error::BadLayer;
}
const auto layer = map_layer->second;
@@ -519,6 +554,7 @@
}
}
+ bool is_secure = false;
const private_handle_t *handle =
reinterpret_cast<const private_handle_t *>(layer->input_buffer.buffer_id);
if (handle) {
@@ -526,17 +562,16 @@
layer_stack_.flags.video_present = true;
}
// TZ Protected Buffer - L1
- if (handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
- layer_stack_.flags.secure_present = true;
- }
// Gralloc Usage Protected Buffer - L3 - which needs to be treated as Secure & avoid fallback
- if (handle->flags & private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER) {
+ if (handle->flags & private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER ||
+ handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
layer_stack_.flags.secure_present = true;
+ is_secure = true;
}
}
- if (layer->flags.skip) {
- layer_stack_.flags.skip_present = true;
+ if (layer->input_buffer.flags.secure_display) {
+ is_secure = true;
}
if (hwc_layer->IsSingleBuffered() &&
@@ -566,6 +601,15 @@
layer_stack_.flags.hdr_present = true;
}
+ if (hwc_layer->IsNonIntegralSourceCrop() && !is_secure && !hdr_layer &&
+ !layer->flags.single_buffer && !layer->flags.solid_fill) {
+ layer->flags.skip = true;
+ }
+
+ if (layer->flags.skip) {
+ layer_stack_.flags.skip_present = true;
+ }
+
// 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)};
@@ -589,11 +633,10 @@
layer->src_rect.bottom = layer_buffer->height;
}
- if (layer->frame_rate > metadata_refresh_rate_) {
+ if (hwc_layer->HasMetaDataRefreshRate() && layer->frame_rate > metadata_refresh_rate_) {
metadata_refresh_rate_ = SanitizeRefreshRate(layer->frame_rate);
- } else {
- layer->frame_rate = current_refresh_rate_;
}
+
display_rect_ = Union(display_rect_, layer->dst_rect);
geometry_changes_ |= hwc_layer->GetGeometryChanges();
@@ -612,14 +655,10 @@
sdm_client_target->flags.updating = IsLayerUpdating(client_target_);
layer_stack_.layers.push_back(sdm_client_target);
- // Apply current Color Mode and Render Intent.
- HWC2::Error error = color_mode_->ApplyCurrentColorModeWithRenderIntent();
-
// fall back frame composition to GPU when client target is 10bit
// TODO(user): clarify the behaviour from Client(SF) and SDM Extn -
// when handling 10bit FBT, as it would affect blending
- // Fallback to GPU Composition, if Color Mode can't be applied.
- if ((error != HWC2::Error::None) || Is10BitFormat(sdm_client_target->input_buffer.format)) {
+ if (Is10BitFormat(sdm_client_target->input_buffer.format)) {
// Must fall back to client composition
MarkLayersForClientComposition();
}
@@ -700,7 +739,7 @@
return HWC2::Error::None;
}
-HWC2::Error HWCDisplay::SetPowerMode(HWC2::PowerMode mode) {
+HWC2::Error HWCDisplay::SetPowerMode(HWC2::PowerMode mode, bool teardown) {
DLOGV("display = %d, mode = %s", id_, to_string(mode).c_str());
DisplayState state = kStateOff;
bool flush_on_error = flush_on_error_;
@@ -743,7 +782,7 @@
int release_fence = -1;
ATRACE_INT("SetPowerMode ", state);
- DisplayError error = display_intf_->SetDisplayState(state, &release_fence);
+ DisplayError error = display_intf_->SetDisplayState(state, teardown, &release_fence);
validated_ = false;
if (error == kErrorNone) {
@@ -904,7 +943,7 @@
} else {
*out_size = std::min((UINT32(name.size()) + 1), *out_size);
if (*out_size > 0) {
- std::strncpy(out_name, name.c_str(), *out_size);
+ strlcpy(out_name, name.c_str(), *out_size);
out_name[*out_size - 1] = '\0';
} else {
DLOGW("Invalid size requested");
@@ -1049,7 +1088,17 @@
DisplayError HWCDisplay::HandleEvent(DisplayEvent event) {
switch (event) {
- case kIdleTimeout:
+ case kIdleTimeout: {
+ SCOPE_LOCK(HWCSession::locker_[type_]);
+ if (pending_commit_) {
+ // If idle timeout event comes in between prepare
+ // and commit, drop it since device is not really
+ // idle.
+ return kErrorNotSupported;
+ }
+ validated_ = false;
+ break;
+ }
case kThermalEvent:
case kIdlePowerCollapse:
case kPanelDeadEvent: {
@@ -1087,6 +1136,7 @@
return ((*out_num_types > 0) ? HWC2::Error::HasChanges : HWC2::Error::None);
}
+ UpdateRefreshRate();
DisplayError error = display_intf_->Prepare(&layer_stack_);
if (error != kErrorNone) {
if (error == kErrorShutDown) {
@@ -1265,11 +1315,9 @@
// HDR10 and HLG are supported
out_types[0] = HAL_HDR_HDR10;
out_types[1] = HAL_HDR_HLG;
- static const float kLuminanceFactor = 10000.0;
- // luminance is expressed in the unit of 0.0001 cd/m2, convert it to 1cd/m2.
- *out_max_luminance = FLOAT(fixed_info.max_luminance)/kLuminanceFactor;
- *out_max_average_luminance = FLOAT(fixed_info.average_luminance)/kLuminanceFactor;
- *out_min_luminance = FLOAT(fixed_info.min_luminance)/kLuminanceFactor;
+ *out_max_luminance = fixed_info.max_luminance;
+ *out_max_average_luminance = fixed_info.average_luminance;
+ *out_min_luminance = fixed_info.min_luminance;
}
return HWC2::Error::None;
@@ -1277,6 +1325,10 @@
HWC2::Error HWCDisplay::CommitLayerStack(void) {
+ if (flush_) {
+ return HWC2::Error::None;
+ }
+
if (!validated_) {
DLOGV_IF(kTagClient, "Display %d is not validated", id_);
return HWC2::Error::NotValidated;
@@ -1288,37 +1340,35 @@
DumpInputBuffers();
- if (!flush_) {
- DisplayError error = kErrorUndefined;
- int status = 0;
- if (tone_mapper_) {
- if (NeedsToneMap(layer_stack_)) {
- status = tone_mapper_->HandleToneMap(&layer_stack_);
- if (status != 0) {
- DLOGE("Error handling HDR in ToneMapper");
- }
- } else {
- tone_mapper_->Terminate();
+ DisplayError error = kErrorUndefined;
+ int status = 0;
+ if (tone_mapper_) {
+ if (NeedsToneMap(layer_stack_)) {
+ status = tone_mapper_->HandleToneMap(&layer_stack_);
+ if (status != 0) {
+ DLOGE("Error handling HDR in ToneMapper");
}
- }
- error = display_intf_->Commit(&layer_stack_);
-
- if (error == kErrorNone) {
- // A commit is successfully submitted, start flushing on failure now onwards.
- flush_on_error_ = true;
} else {
- if (error == kErrorShutDown) {
- shutdown_pending_ = true;
- return HWC2::Error::Unsupported;
- } else if (error == kErrorNotValidated) {
- validated_ = false;
- return HWC2::Error::NotValidated;
- } else if (error != kErrorPermission) {
- DLOGE("Commit failed. Error = %d", error);
- // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
- // so that previous buffer and fences are released, and override the error.
- flush_ = true;
- }
+ tone_mapper_->Terminate();
+ }
+ }
+ error = display_intf_->Commit(&layer_stack_);
+
+ if (error == kErrorNone) {
+ // A commit is successfully submitted, start flushing on failure now onwards.
+ flush_on_error_ = true;
+ } else {
+ if (error == kErrorShutDown) {
+ shutdown_pending_ = true;
+ return HWC2::Error::Unsupported;
+ } else if (error == kErrorNotValidated) {
+ validated_ = false;
+ return HWC2::Error::NotValidated;
+ } else if (error != kErrorPermission) {
+ DLOGE("Commit failed. Error = %d", error);
+ // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
+ // so that previous buffer and fences are released, and override the error.
+ flush_ = true;
}
}
@@ -1649,12 +1699,12 @@
case kDisplayStatusResume:
display_paused_ = false;
case kDisplayStatusOnline:
- status = INT32(SetPowerMode(HWC2::PowerMode::On));
+ status = INT32(SetPowerMode(HWC2::PowerMode::On, false /* teardown */));
break;
case kDisplayStatusPause:
display_paused_ = true;
case kDisplayStatusOffline:
- status = INT32(SetPowerMode(HWC2::PowerMode::Off));
+ status = INT32(SetPowerMode(HWC2::PowerMode::Off, false /* teardown */));
break;
default:
DLOGW("Invalid display status %d", display_status);
@@ -1870,7 +1920,7 @@
if (active_secure_sessions_[kSecureDisplay] != secure_sessions[kSecureDisplay]) {
if (secure_sessions[kSecureDisplay]) {
- HWC2::Error error = SetPowerMode(HWC2::PowerMode::Off);
+ HWC2::Error error = SetPowerMode(HWC2::PowerMode::Off, true /* teardown */);
if (error != HWC2::Error::None) {
DLOGE("SetPowerMode failed. Error = %d", error);
}
@@ -2114,4 +2164,14 @@
return skip_prepare;
}
+void HWCDisplay::UpdateRefreshRate() {
+ for (auto hwc_layer : layer_set_) {
+ if (hwc_layer->HasMetaDataRefreshRate()) {
+ continue;
+ }
+ auto layer = hwc_layer->GetSDMLayer();
+ layer->frame_rate = current_refresh_rate_;
+ }
+}
+
} // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index 2fae7e7..f14c79f 100644
--- a/sdm/libs/hwc2/hwc_display.h
+++ b/sdm/libs/hwc2/hwc_display.h
@@ -82,6 +82,7 @@
HWC2::Error RestoreColorTransform();
ColorMode GetCurrentColorMode() { return current_color_mode_; }
HWC2::Error ApplyCurrentColorModeWithRenderIntent();
+ HWC2::Error CacheColorModeWithRenderIntent(ColorMode mode, RenderIntent intent);
private:
static const uint32_t kColorTransformMatrixCount = 16;
@@ -94,6 +95,7 @@
}
}
HWC2::Error ApplyDefaultColorMode();
+ HWC2::Error ValidateColorModeWithRenderIntent(ColorMode mode, RenderIntent intent);
DisplayInterface *display_intf_ = NULL;
bool apply_mode_ = false;
@@ -173,6 +175,12 @@
return HWC2::Error::Unsupported;
}
+ virtual HWC2::Error 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) {
+ return HWC2::Error::Unsupported;
+ }
+
// Display Configurations
virtual int SetActiveDisplayConfig(uint32_t config);
virtual int GetActiveDisplayConfig(uint32_t *config);
@@ -249,7 +257,7 @@
virtual HWC2::Error GetDisplayType(int32_t *out_type);
virtual HWC2::Error SetCursorPosition(hwc2_layer_t layer, int x, int y);
virtual HWC2::Error SetVsyncEnabled(HWC2::Vsync enabled);
- virtual HWC2::Error SetPowerMode(HWC2::PowerMode mode);
+ virtual HWC2::Error SetPowerMode(HWC2::PowerMode mode, bool teardown);
virtual HWC2::Error CreateLayer(hwc2_layer_t *out_layer_id);
virtual HWC2::Error DestroyLayer(hwc2_layer_t layer_id);
virtual HWC2::Error SetLayerZOrder(hwc2_layer_t layer_id, uint32_t z);
@@ -359,11 +367,12 @@
int disable_hdr_handling_ = 0; // disables HDR handling.
uint32_t display_config_ = 0;
bool config_pending_ = false;
+ bool pending_commit_ = false;
private:
void DumpInputBuffers(void);
bool CanSkipSdmPrepare(uint32_t *num_types, uint32_t *num_requests);
-
+ void UpdateRefreshRate();
qService::QService *qservice_ = NULL;
DisplayClass display_class_;
uint32_t geometry_changes_ = GeometryChanges::kNone;
diff --git a/sdm/libs/hwc2/hwc_display_builtin.cpp b/sdm/libs/hwc2/hwc_display_builtin.cpp
index cc02ad6..106b147 100644
--- a/sdm/libs/hwc2/hwc_display_builtin.cpp
+++ b/sdm/libs/hwc2/hwc_display_builtin.cpp
@@ -125,14 +125,8 @@
}
void HWCDisplayBuiltIn::ProcessBootAnimCompleted() {
- uint32_t numBootUpLayers = 0;
- // TODO(user): Remove this hack
+ bool bootanim_exit = false;
- numBootUpLayers = static_cast<uint32_t>(Debug::GetBootAnimLayerCount());
-
- if (numBootUpLayers == 0) {
- numBootUpLayers = 2;
- }
/* All other checks namely "init.svc.bootanim" or
* HWC_GEOMETRY_CHANGED fail in correctly identifying the
* exact bootup transition to homescreen
@@ -152,9 +146,14 @@
}
}
+ property_get("service.bootanim.exit", property, "0");
+ if (!strcmp(property, "1")) {
+ bootanim_exit = true;
+ }
+
if ((!isEncrypted || (isEncrypted && main_class_services_started)) &&
- (layer_set_.size() > numBootUpLayers)) {
- DLOGI("Applying default mode");
+ bootanim_exit) {
+ DLOGI("Applying default mode for display %d", sdm_id_);
boot_animation_completed_ = true;
// Applying default mode after bootanimation is finished And
// If Data is Encrypted, it is ready for access.
@@ -195,6 +194,12 @@
// Checks and replaces layer stack for solid fill
SolidFillPrepare();
+ // Apply current Color Mode and Render Intent.
+ if (color_mode_->ApplyCurrentColorModeWithRenderIntent() != HWC2::Error::None) {
+ // Fallback to GPU Composition, if Color Mode can't be applied.
+ MarkLayersForClientComposition();
+ }
+
bool pending_output_dump = dump_frame_count_ && dump_output_to_file_;
if (readback_buffer_queued_ || pending_output_dump) {
@@ -230,6 +235,7 @@
}
status = PrepareLayerStack(out_num_types, out_num_requests);
+ pending_commit_ = true;
return status;
}
@@ -251,6 +257,7 @@
}
CloseFd(&output_buffer_.acquire_fence_fd);
+ pending_commit_ = false;
return status;
}
@@ -279,7 +286,7 @@
}
HWC2::Error HWCDisplayBuiltIn::SetColorModeWithRenderIntent(ColorMode mode, RenderIntent intent) {
- auto status = color_mode_->SetColorModeWithRenderIntent(mode, intent);
+ auto status = color_mode_->CacheColorModeWithRenderIntent(mode, intent);
if (status != HWC2::Error::None) {
DLOGE("failed for mode = %d intent = %d", mode, intent);
return status;
@@ -352,6 +359,7 @@
output_buffer_.planes[0].stride = UINT32(handle->width);
output_buffer_.acquire_fence_fd = dup(acquire_fence);
output_buffer_.release_fence_fd = -1;
+ output_buffer_.handle_id = handle->id;
post_processed_output_ = post_processed_output;
readback_buffer_queued_ = true;
@@ -380,6 +388,46 @@
return status;
}
+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) {
+ DisplayError error = kErrorNone;
+ DisplayDppsAd4RoiCfg dpps_ad4_roi_cfg = {};
+ uint32_t panel_width = 0, panel_height = 0;
+ constexpr uint16_t kMaxFactorVal = 0xffff;
+
+ if (h_start >= h_end || v_start >= v_end || factor_in > kMaxFactorVal ||
+ factor_out > kMaxFactorVal) {
+ DLOGE("Invalid roi region = [%u, %u, %u, %u, %u, %u]",
+ h_start, h_end, v_start, v_end, factor_in, factor_out);
+ return HWC2::Error::BadParameter;
+ }
+
+ GetPanelResolution(&panel_width, &panel_height);
+
+ if (h_start >= panel_width || h_end > panel_width ||
+ v_start >= panel_height || v_end > panel_height) {
+ DLOGE("Invalid roi region = [%u, %u, %u, %u], panel resolution = [%u, %u]",
+ h_start, h_end, v_start, v_end, panel_width, panel_height);
+ return HWC2::Error::BadParameter;
+ }
+
+ dpps_ad4_roi_cfg.h_start = h_start;
+ dpps_ad4_roi_cfg.h_end = h_end;
+ dpps_ad4_roi_cfg.v_start = v_start;
+ dpps_ad4_roi_cfg.v_end = v_end;
+ dpps_ad4_roi_cfg.factor_in = factor_in;
+ dpps_ad4_roi_cfg.factor_out = factor_out;
+
+ error = display_intf_->SetDisplayDppsAdROI(&dpps_ad4_roi_cfg);
+ if (error)
+ return HWC2::Error::BadConfig;
+
+ callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
+
+ return HWC2::Error::None;
+}
+
int HWCDisplayBuiltIn::Perform(uint32_t operation, ...) {
va_list args;
va_start(args, operation);
@@ -575,13 +623,11 @@
dump_output_to_file_ = bit_mask_layer_type & (1 << OUTPUT_LAYER_DUMP);
DLOGI("output_layer_dump_enable %d", dump_output_to_file_);
- if (!count || !dump_output_to_file_) {
+ if (!count || !dump_output_to_file_ || (output_buffer_info_.alloc_buffer_info.fd >= 0)) {
return HWC2::Error::None;
}
// Allocate and map output buffer
- output_buffer_info_ = {};
-
if (post_processed) {
// To dump post-processed (DSPP) output, use Panel resolution.
GetPanelResolution(&output_buffer_info_.buffer_config.width,
diff --git a/sdm/libs/hwc2/hwc_display_builtin.h b/sdm/libs/hwc2/hwc_display_builtin.h
index 1f01723..6616255 100644
--- a/sdm/libs/hwc2/hwc_display_builtin.h
+++ b/sdm/libs/hwc2/hwc_display_builtin.h
@@ -80,6 +80,8 @@
virtual HWC2::Error GetReadbackBufferFence(int32_t *release_fence);
virtual HWC2::Error SetQSyncMode(QSyncMode qsync_mode);
virtual HWC2::Error ControlIdlePowerCollapse(bool enable, bool synchronous);
+ virtual HWC2::Error 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);
private:
HWCDisplayBuiltIn(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
diff --git a/sdm/libs/hwc2/hwc_display_pluggable.cpp b/sdm/libs/hwc2/hwc_display_pluggable.cpp
index 7d22642..9ac22be 100644
--- a/sdm/libs/hwc2/hwc_display_pluggable.cpp
+++ b/sdm/libs/hwc2/hwc_display_pluggable.cpp
@@ -137,6 +137,7 @@
if (layer_set_.empty()) {
flush_ = true;
+ validated_ = true;
return status;
}
@@ -235,7 +236,7 @@
}
int release_fence = -1;
display_null_.GetDisplayState(&state);
- display_intf_->SetDisplayState(state, &release_fence);
+ display_intf_->SetDisplayState(state, false /* teardown */, &release_fence);
if (release_fence >= 0) {
::close(release_fence);
}
@@ -254,7 +255,7 @@
// Preserve required attributes of HDMI display that surfaceflinger sees.
// Restore HDMI attributes when display is reconnected.
display_intf_->GetDisplayState(&state);
- display_null_.SetDisplayState(state, &release_fence);
+ display_null_.SetDisplayState(state, false /* teardown */, &release_fence);
if (release_fence >= 0) {
::close(release_fence);
}
diff --git a/sdm/libs/hwc2/hwc_display_virtual.cpp b/sdm/libs/hwc2/hwc_display_virtual.cpp
index 8454536..a05173f 100644
--- a/sdm/libs/hwc2/hwc_display_virtual.cpp
+++ b/sdm/libs/hwc2/hwc_display_virtual.cpp
@@ -63,7 +63,7 @@
return status;
}
- status = INT32(hwc_display_virtual->SetPowerMode(HWC2::PowerMode::On));
+ status = INT32(hwc_display_virtual->SetPowerMode(HWC2::PowerMode::On, false /* teardown */));
if (status) {
DLOGW("Failed to set power mode on virtual display");
Destroy(hwc_display_virtual);
diff --git a/sdm/libs/hwc2/hwc_layers.cpp b/sdm/libs/hwc2/hwc_layers.cpp
index 13c3f8d..9ba14a9 100644
--- a/sdm/libs/hwc2/hwc_layers.cpp
+++ b/sdm/libs/hwc2/hwc_layers.cpp
@@ -455,6 +455,13 @@
HWC2::Error HWCLayer::SetLayerSourceCrop(hwc_frect_t crop) {
LayerRect src_rect = {};
SetRect(crop, &src_rect);
+ non_integral_source_crop_ = ((crop.left != roundf(crop.left)) ||
+ (crop.top != roundf(crop.top)) ||
+ (crop.right != roundf(crop.right)) ||
+ (crop.bottom != roundf(crop.bottom)));
+ if (non_integral_source_crop_) {
+ DLOGV_IF(kTagClient, "Crop: LTRB %f %f %f %f", crop.left, crop.top, crop.right, crop.bottom);
+ }
if (layer_->src_rect != src_rect) {
geometry_changes_ |= kSourceCrop;
layer_->src_rect = src_rect;
@@ -770,6 +777,7 @@
// in layer_buffer or copy directly to Vector
if (cr_stats->bDataValid) {
switch (cr_stats->version) {
+ case UBWC_3_0:
case UBWC_2_0:
cr_vec->push_back(std::make_pair(32, cr_stats->ubwc_stats.nCRStatsTile32));
cr_vec->push_back(std::make_pair(64, cr_stats->ubwc_stats.nCRStatsTile64));
@@ -801,13 +809,13 @@
uint32_t frame_rate = layer->frame_rate;
if (getMetaData(handle, GET_REFRESH_RATE, &fps) == 0) {
frame_rate = (fps != 0) ? RoundToStandardFPS(fps) : layer->frame_rate;
+ has_metadata_refresh_rate_ = true;
}
int32_t interlaced = 0;
- bool interlace = layer_buffer->flags.interlace;
- if (getMetaData(handle, GET_PP_PARAM_INTERLACED, &interlaced) == 0) {
- interlace = interlaced ? true : false;
- }
+ getMetaData(handle, GET_PP_PARAM_INTERLACED, &interlaced);
+ bool interlace = interlaced ? true : false;
+
if (interlace != layer_buffer->flags.interlace) {
DLOGI("Layer buffer interlaced metadata has changed. old=%d, new=%d",
layer_buffer->flags.interlace, interlace);
diff --git a/sdm/libs/hwc2/hwc_layers.h b/sdm/libs/hwc2/hwc_layers.h
index 46e83cb..b5d5eaa 100644
--- a/sdm/libs/hwc2/hwc_layers.h
+++ b/sdm/libs/hwc2/hwc_layers.h
@@ -109,6 +109,8 @@
static LayerBufferFormat GetSDMFormat(const int32_t &source, const int flags);
bool IsSurfaceUpdated() { return surface_updated_; }
void SetPartialUpdate(bool enabled) { partial_update_enabled_ = enabled; }
+ bool IsNonIntegralSourceCrop() { return non_integral_source_crop_; }
+ bool HasMetaDataRefreshRate() { return has_metadata_refresh_rate_; }
private:
Layer *layer_ = nullptr;
@@ -127,6 +129,8 @@
bool dataspace_supported_ = false;
bool partial_update_enabled_ = false;
bool surface_updated_ = true;
+ bool non_integral_source_crop_ = false;
+ bool has_metadata_refresh_rate_ = false;
// Composition requested by client(SF)
HWC2::Composition client_requested_ = HWC2::Composition::Device;
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index 77f0e5e..ed72532 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -290,6 +290,9 @@
case qdutils::DISPLAY_VIRTUAL:
map_info = map_info_virtual_.size() ? &map_info_virtual_[0] : nullptr;
break;
+ case qdutils::DISPLAY_BUILTIN_2:
+ map_info = map_info_builtin_.size() ? &map_info_builtin_[0] : nullptr;
+ break;
}
if (!map_info) {
@@ -603,23 +606,6 @@
return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayType, out_type);
}
-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 >= HWCSession::kNumDisplays) {
- return HWC2_ERROR_BAD_DISPLAY;
- }
-
- if (display == HWC_DISPLAY_PRIMARY) {
- *out_support = 1;
- } else {
- *out_support = 0;
- }
-
- return HWC2_ERROR_NONE;
-}
static int32_t GetHdrCapabilities(hwc2_device_t* device, hwc2_display_t display,
uint32_t* out_num_types, int32_t* out_types,
@@ -683,7 +669,7 @@
if (!hwc_session->primary_ready_ && (display == HWC_DISPLAY_PRIMARY)) {
hwc_session->primary_ready_ = true;
hwc_session->CreateBuiltInDisplays();
- hwc_session->CreatePluggableDisplays(false);
+ hwc_session->HandlePluggableDisplays(false);
}
return INT32(status);
@@ -888,12 +874,13 @@
// all displays support on/off. Check for doze modes
int support = 0;
- GetDozeSupport(device, display, &support);
+ hwc_session->GetDozeSupport(device, display, &support);
if (!support && (mode == HWC2::PowerMode::Doze || mode == HWC2::PowerMode::DozeSuspend)) {
return HWC2_ERROR_UNSUPPORTED;
}
- auto error = CallDisplayFunction(device, display, &HWCDisplay::SetPowerMode, mode);
+ auto error = CallDisplayFunction(device, display, &HWCDisplay::SetPowerMode, mode,
+ false /* teardown */);
if (error != HWC2_ERROR_NONE) {
return error;
}
@@ -922,6 +909,25 @@
return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetVsyncEnabled, enabled);
}
+int32_t HWCSession::GetDozeSupport(hwc2_device_t *device, hwc2_display_t display,
+ int32_t *out_support) {
+ if (!device || !out_support) {
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
+
+ if (display >= HWCSession::kNumDisplays) {
+ return HWC2_ERROR_BAD_DISPLAY;
+ }
+
+ HWCSession *hwc_session = static_cast<HWCSession *>(device);
+ *out_support = 0;
+ if (display == HWC_DISPLAY_PRIMARY || display == hwc_session->GetNextBuiltinIndex()) {
+ *out_support = 1;
+ }
+
+ return HWC2_ERROR_NONE;
+}
+
int32_t HWCSession::ValidateDisplay(hwc2_device_t *device, hwc2_display_t display,
uint32_t *out_num_types, uint32_t *out_num_requests) {
// out_num_types and out_num_requests will be non-NULL
@@ -1142,6 +1148,16 @@
return HWC2::Error::None;
}
+hwc2_display_t HWCSession::GetNextBuiltinIndex() {
+ for (auto &map_info : map_info_builtin_) {
+ if (hwc_display_[map_info.client_id]) {
+ return map_info.client_id;
+ }
+ }
+
+ return 0;
+}
+
// Qclient methods
android::status_t HWCSession::notifyCallback(uint32_t command, const android::Parcel *input_parcel,
android::Parcel *output_parcel) {
@@ -1158,7 +1174,11 @@
break;
case qService::IQService::SCREEN_REFRESH:
- status = refreshScreen();
+ if (!input_parcel) {
+ DLOGE("QService command = %d: input_parcel needed.", command);
+ break;
+ }
+ status = RefreshScreen(input_parcel);
break;
case qService::IQService::SET_IDLE_TIMEOUT:
@@ -1412,6 +1432,14 @@
status = SetIdlePC(input_parcel);
break;
+ case qService::IQService::SET_DPPS_AD4_ROI_CONFIG:
+ if (!input_parcel) {
+ DLOGE("QService command = %d: input_parcel needed.", command);
+ break;
+ }
+ status = SetAd4RoiConfig(input_parcel);
+ break;
+
default:
DLOGW("QService command = %d is not supported.", command);
break;
@@ -1611,6 +1639,29 @@
return 0;
}
+android::status_t HWCSession::SetAd4RoiConfig(const android::Parcel *input_parcel) {
+ auto display_id = static_cast<uint32_t>(input_parcel->readInt32());
+ auto h_s = static_cast<uint32_t>(input_parcel->readInt32());
+ auto h_e = static_cast<uint32_t>(input_parcel->readInt32());
+ auto v_s = static_cast<uint32_t>(input_parcel->readInt32());
+ auto v_e = static_cast<uint32_t>(input_parcel->readInt32());
+ auto f_in = static_cast<uint32_t>(input_parcel->readInt32());
+ auto f_out = static_cast<uint32_t>(input_parcel->readInt32());
+
+#ifdef DISPLAY_CONFIG_1_5
+ return static_cast<android::status_t>(SetDisplayDppsAdROI(display_id, h_s, h_e, v_s,
+ v_e, f_in, f_out));
+#else
+ auto err = CallDisplayFunction(static_cast<hwc2_device_t *>(this), display_id,
+ &HWCDisplay::SetDisplayDppsAdROI, h_s, h_e, v_s, v_e,
+ f_in, f_out);
+ if (err != HWC2_ERROR_NONE)
+ return -EINVAL;
+
+ return 0;
+#endif
+}
+
android::status_t HWCSession::SetColorModeWithRenderIntentOverride(
const android::Parcel *input_parcel) {
auto display = static_cast<hwc2_display_t>(input_parcel->readInt32());
@@ -1626,7 +1677,7 @@
return 0;
}
android::status_t HWCSession::SetColorModeById(const android::Parcel *input_parcel) {
- int display = static_cast<int >(input_parcel->readInt32());
+ int display = input_parcel->readInt32();
auto mode = input_parcel->readInt32();
auto device = static_cast<hwc2_device_t *>(this);
@@ -1644,6 +1695,20 @@
return 0;
}
+android::status_t HWCSession::RefreshScreen(const android::Parcel *input_parcel) {
+ int display = input_parcel->readInt32();
+
+ int disp_idx = GetDisplayIndex(display);
+ if (disp_idx == -1) {
+ DLOGE("Invalid display = %d", display);
+ return -EINVAL;
+ }
+
+ Refresh(static_cast<hwc2_display_t>(disp_idx));
+
+ return 0;
+}
+
void HWCSession::DynamicDebug(const android::Parcel *input_parcel) {
int type = input_parcel->readInt32();
bool enable = (input_parcel->readInt32() > 0);
@@ -1695,6 +1760,41 @@
}
}
+android::status_t HWCSession::QdcmCMDDispatch(uint32_t display_id,
+ const PPDisplayAPIPayload &req_payload,
+ PPDisplayAPIPayload *resp_payload,
+ PPPendingParams *pending_action) {
+ int ret = 0;
+ bool is_physical_display = false;
+
+ if (display_id >= kNumDisplays || !hwc_display_[display_id]) {
+ DLOGW("Invalid display id or display = %d is not connected.", display_id);
+ return -ENODEV;
+ }
+
+ if (display_id == map_info_primary_.client_id) {
+ is_physical_display = true;
+ } else {
+ for (auto &map_info : map_info_builtin_) {
+ if (map_info.client_id == display_id) {
+ is_physical_display = true;
+ break;
+ }
+ }
+ }
+
+ if (!is_physical_display) {
+ DLOGW("Skipping QDCM command dispatch on display = %d", display_id);
+ return ret;
+ }
+
+ ret = hwc_display_[display_id]->ColorSVCRequestRoute(req_payload,
+ resp_payload,
+ pending_action);
+
+ return ret;
+}
+
android::status_t HWCSession::QdcmCMDHandler(const android::Parcel *input_parcel,
android::Parcel *output_parcel) {
int ret = 0;
@@ -1702,6 +1802,7 @@
uint32_t display_id(0);
PPPendingParams pending_action;
PPDisplayAPIPayload resp_payload, req_payload;
+ uint8_t *disp_id = NULL;
if (!color_mgr_) {
DLOGW("color_mgr_ not initialized.");
@@ -1714,21 +1815,7 @@
// Read display_id, payload_size and payload from in_parcel.
ret = HWCColorManager::CreatePayloadFromParcel(*input_parcel, &display_id, &req_payload);
if (!ret) {
- if (display_id >= kNumDisplays || !hwc_display_[display_id]) {
- DLOGW("Invalid display id or display = %d is not connected.", display_id);
- ret = -ENODEV;
- }
- }
-
- if (!ret) {
- if ((HWC_DISPLAY_PRIMARY == display_id) || (HWC_DISPLAY_EXTERNAL == display_id)) {
- ret = hwc_display_[display_id]->ColorSVCRequestRoute(req_payload, &resp_payload,
- &pending_action);
- } else {
- // Virtual, Tertiary etc. not supported.
- DLOGW("Operation not supported on display = %d.", display_id);
- ret = -EINVAL;
- }
+ ret = QdcmCMDDispatch(display_id, req_payload, &resp_payload, &pending_action);
}
if (ret) {
@@ -1739,12 +1826,6 @@
}
if (kNoAction != pending_action.action) {
- // Restrict pending actions to primary display.
- if (HWC_DISPLAY_PRIMARY != display_id) {
- DLOGW("Skipping pending action %d on display = %d.", pending_action.action, display_id);
- pending_action.action = kNoAction;
- }
-
int32_t action = pending_action.action;
int count = -1;
while (action > 0) {
@@ -1755,33 +1836,33 @@
if (!bit)
continue;
- DLOGV_IF(kTagQDCM, "pending action = %d", BITMAP(count));
+ DLOGV_IF(kTagQDCM, "pending action = %d, display_id = %d", BITMAP(count), display_id);
switch (BITMAP(count)) {
case kInvalidating:
- Refresh(HWC_DISPLAY_PRIMARY);
+ Refresh(display_id);
break;
case kEnterQDCMMode:
- ret = color_mgr_->EnableQDCMMode(true, hwc_display_[HWC_DISPLAY_PRIMARY]);
+ ret = color_mgr_->EnableQDCMMode(true, hwc_display_[display_id]);
break;
case kExitQDCMMode:
- ret = color_mgr_->EnableQDCMMode(false, hwc_display_[HWC_DISPLAY_PRIMARY]);
+ ret = color_mgr_->EnableQDCMMode(false, hwc_display_[display_id]);
break;
case kApplySolidFill:
{
- SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
+ SCOPE_LOCK(locker_[display_id]);
ret = color_mgr_->SetSolidFill(pending_action.params,
- true, hwc_display_[HWC_DISPLAY_PRIMARY]);
+ true, hwc_display_[display_id]);
}
- Refresh(HWC_DISPLAY_PRIMARY);
+ Refresh(display_id);
usleep(kSolidFillDelay);
break;
case kDisableSolidFill:
{
- SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
+ SCOPE_LOCK(locker_[display_id]);
ret = color_mgr_->SetSolidFill(pending_action.params,
- false, hwc_display_[HWC_DISPLAY_PRIMARY]);
+ false, hwc_display_[display_id]);
}
- Refresh(HWC_DISPLAY_PRIMARY);
+ Refresh(display_id);
usleep(kSolidFillDelay);
break;
case kSetPanelBrightness:
@@ -1790,30 +1871,65 @@
DLOGE("Brightness value is Null");
ret = -EINVAL;
} else {
- ret = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(*brightness_value);
+ ret = hwc_display_[display_id]->SetPanelBrightness(*brightness_value);
}
break;
case kEnableFrameCapture:
ret = color_mgr_->SetFrameCapture(pending_action.params, true,
- hwc_display_[HWC_DISPLAY_PRIMARY]);
- Refresh(HWC_DISPLAY_PRIMARY);
+ hwc_display_[display_id]);
+ Refresh(display_id);
break;
case kDisableFrameCapture:
ret = color_mgr_->SetFrameCapture(pending_action.params, false,
- hwc_display_[HWC_DISPLAY_PRIMARY]);
+ hwc_display_[display_id]);
break;
case kConfigureDetailedEnhancer:
ret = color_mgr_->SetDetailedEnhancer(pending_action.params,
- hwc_display_[HWC_DISPLAY_PRIMARY]);
- Refresh(HWC_DISPLAY_PRIMARY);
+ hwc_display_[display_id]);
+ Refresh(display_id);
break;
case kModeSet:
ret = static_cast<int>
- (hwc_display_[HWC_DISPLAY_PRIMARY]->RestoreColorTransform());
- Refresh(HWC_DISPLAY_PRIMARY);
+ (hwc_display_[display_id]->RestoreColorTransform());
+ Refresh(display_id);
break;
case kNoAction:
break;
+ case kMultiDispProc:
+ for (auto &map_info : map_info_builtin_) {
+ uint32_t id = UINT32(map_info.client_id);
+ if (id < kNumDisplays && hwc_display_[id]) {
+ int result = 0;
+ resp_payload.DestroyPayload();
+ result = hwc_display_[id]->ColorSVCRequestRoute(req_payload,
+ &resp_payload,
+ &pending_action);
+ if (result) {
+ DLOGW("Failed to dispatch action to disp %d ret %d", id, result);
+ ret = result;
+ }
+ }
+ }
+ break;
+ case kMultiDispGetId:
+ ret = resp_payload.CreatePayloadBytes(HWC_NUM_DISPLAY_TYPES, &disp_id);
+ if (ret) {
+ DLOGW("Unable to create response payload!");
+ } else {
+ for (int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
+ disp_id[i] = HWC_NUM_DISPLAY_TYPES;
+ }
+ if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ disp_id[HWC_DISPLAY_PRIMARY] = HWC_DISPLAY_PRIMARY;
+ }
+ for (auto &map_info : map_info_builtin_) {
+ uint64_t id = map_info.client_id;
+ if (id < kNumDisplays && hwc_display_[id]) {
+ disp_id[id] = (uint8_t)id;
+ }
+ }
+ }
+ break;
default:
DLOGW("Invalid pending action = %d!", pending_action.action);
break;
@@ -1882,8 +1998,9 @@
hpd_bpp_ = GetEventValue(uevent_data, length, "bpp=");
hpd_pattern_ = GetEventValue(uevent_data, length, "pattern=");
- DLOGI("Uevent = %s, bpp = %d, pattern = %d", uevent_data, hpd_bpp_, hpd_pattern_);
- if (CreatePluggableDisplays(true)) {
+ DLOGI("Uevent = %s, status = %s, MST_HOTPLUG = %s, bpp = %d, pattern = %d", uevent_data,
+ str_status ? str_status : "NULL", str_mst ? str_mst : "NULL", hpd_bpp_, hpd_pattern_);
+ if (HandlePluggableDisplays(true)) {
DLOGE("Could not handle hotplug. Event dropped.");
}
@@ -1899,14 +2016,15 @@
HWC2::Error status = HWC2::Error::None;
DLOGI("Powering off primary");
- status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(HWC2::PowerMode::Off);
+ status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(HWC2::PowerMode::Off,
+ false /* teardown */);
if (status != HWC2::Error::None) {
DLOGE("power-off on primary failed with error = %d", status);
}
DLOGI("Restoring power mode on primary");
HWC2::PowerMode mode = hwc_display_[HWC_DISPLAY_PRIMARY]->GetLastPowerMode();
- status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(mode);
+ status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(mode, false /* teardown */);
if (status != HWC2::Error::None) {
DLOGE("Setting power mode = %d on primary failed with error = %d", mode, status);
}
@@ -2089,7 +2207,7 @@
return status;
}
-int HWCSession::CreatePluggableDisplays(bool delay_hotplug) {
+int HWCSession::HandlePluggableDisplays(bool delay_hotplug) {
if (!primary_ready_) {
DLOGI("Primary display is not ready. Connect displays later if any.");
return 0;
@@ -2346,7 +2464,8 @@
for (hwc2_display_t display = HWC_DISPLAY_PRIMARY; display < HWC_NUM_DISPLAY_TYPES; display++) {
if (hwc_display_[display] != NULL) {
DLOGI("Powering off display = %d", display);
- status = hwc_display_[display]->SetPowerMode(HWC2::PowerMode::Off);
+ status = hwc_display_[display]->SetPowerMode(HWC2::PowerMode::Off,
+ true /* teardown */);
if (status != HWC2::Error::None) {
DLOGE("Power off for display = %d failed with error = %d", display, status);
}
@@ -2355,7 +2474,7 @@
for (hwc2_display_t display = HWC_DISPLAY_PRIMARY; display < HWC_NUM_DISPLAY_TYPES; display++) {
if (hwc_display_[display] != NULL) {
DLOGI("Powering on display = %d", display);
- status = hwc_display_[display]->SetPowerMode(HWC2::PowerMode::On);
+ status = hwc_display_[display]->SetPowerMode(HWC2::PowerMode::On, false /* teardown */);
if (status != HWC2::Error::None) {
DLOGE("Power on for display = %d failed with error = %d", display, status);
}
@@ -2422,7 +2541,8 @@
if (power_on_pending_[HWC_DISPLAY_EXTERNAL]) {
if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
- HWC2::Error status = hwc_display_[HWC_DISPLAY_EXTERNAL]->SetPowerMode(HWC2::PowerMode::On);
+ HWC2::Error status = hwc_display_[HWC_DISPLAY_EXTERNAL]->SetPowerMode(HWC2::PowerMode::On,
+ false /* teardown */);
if (status == HWC2::Error::None) {
power_on_pending_[HWC_DISPLAY_EXTERNAL] = false;
}
@@ -2431,7 +2551,8 @@
if (power_on_pending_[HWC_DISPLAY_VIRTUAL]) {
if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
- HWC2::Error status = hwc_display_[HWC_DISPLAY_VIRTUAL]->SetPowerMode(HWC2::PowerMode::On);
+ HWC2::Error status = hwc_display_[HWC_DISPLAY_VIRTUAL]->SetPowerMode(HWC2::PowerMode::On,
+ false /* teardown */);
if (status == HWC2::Error::None) {
power_on_pending_[HWC_DISPLAY_VIRTUAL] = false;
}
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
index 6387cd6..b2a4100 100644
--- a/sdm/libs/hwc2/hwc_session.h
+++ b/sdm/libs/hwc2/hwc_session.h
@@ -20,7 +20,11 @@
#ifndef __HWC_SESSION_H__
#define __HWC_SESSION_H__
-#ifdef DISPLAY_CONFIG_1_3
+#ifdef DISPLAY_CONFIG_1_5
+#include <vendor/display/config/1.5/IDisplayConfig.h>
+#elif DISPLAY_CONFIG_1_4
+#include <vendor/display/config/1.4/IDisplayConfig.h>
+#elif DISPLAY_CONFIG_1_3
#include <vendor/display/config/1.3/IDisplayConfig.h>
#elif DISPLAY_CONFIG_1_2
#include <vendor/display/config/1.2/IDisplayConfig.h>
@@ -49,7 +53,11 @@
namespace sdm {
-#ifdef DISPLAY_CONFIG_1_3
+#ifdef DISPLAY_CONFIG_1_5
+using vendor::display::config::V1_5::IDisplayConfig;
+#elif DISPLAY_CONFIG_1_4
+using vendor::display::config::V1_4::IDisplayConfig;
+#elif DISPLAY_CONFIG_1_3
using vendor::display::config::V1_3::IDisplayConfig;
#elif DISPLAY_CONFIG_1_2
using vendor::display::config::V1_2::IDisplayConfig;
@@ -202,6 +210,8 @@
static int32_t SetVsyncEnabled(hwc2_device_t *device, hwc2_display_t display,
int32_t int_enabled);
+ static int32_t GetDozeSupport(hwc2_device_t *device, hwc2_display_t display,
+ int32_t *out_support);
static Locker locker_[kNumDisplays];
@@ -236,7 +246,7 @@
int GetDisplayIndex(int dpy);
int CreatePrimaryDisplay();
int CreateBuiltInDisplays();
- int CreatePluggableDisplays(bool delay_hotplug);
+ int HandlePluggableDisplays(bool delay_hotplug);
int HandleConnectedDisplays(HWDisplaysInfo *hw_displays_info, bool delay_hotplug);
int HandleDisconnectedDisplays(HWDisplaysInfo *hw_displays_info);
void DestroyDisplay(DisplayMapInfo *map_info);
@@ -249,6 +259,7 @@
int32_t SetSecondaryDisplayStatus(int disp_id, HWCDisplay::DisplayStatus status);
int32_t GetPanelBrightness(int *level);
int32_t MinHdcpEncryptionLevelChanged(int disp_id, uint32_t min_enc_level);
+ int32_t IsWbUbwcSupported(int *value);
// service methods
void StartServices();
@@ -290,6 +301,14 @@
#ifdef DISPLAY_CONFIG_1_3
Return<int32_t> controlIdlePowerCollapse(bool enable, bool synchronous) override;
#endif
+#ifdef DISPLAY_CONFIG_1_4
+ Return<void> getWriteBackCapabilities(getWriteBackCapabilities_cb _hidl_cb) override;
+#endif
+#ifdef DISPLAY_CONFIG_1_5
+ Return<int32_t> SetDisplayDppsAdROI(uint32_t dispaly_id, uint32_t h_start, uint32_t h_end,
+ uint32_t v_start, uint32_t v_end, uint32_t factor_in,
+ uint32_t factor_out) override;
+#endif
// QClient methods
virtual android::status_t notifyCallback(uint32_t command, const android::Parcel *input_parcel,
@@ -301,6 +320,10 @@
android::status_t ConfigureRefreshRate(const android::Parcel *input_parcel);
android::status_t QdcmCMDHandler(const android::Parcel *input_parcel,
android::Parcel *output_parcel);
+ android::status_t QdcmCMDDispatch(uint32_t display_id,
+ const PPDisplayAPIPayload &req_payload,
+ PPDisplayAPIPayload *resp_payload,
+ PPPendingParams *pending_action);
android::status_t GetDisplayAttributesForConfig(const android::Parcel *input_parcel,
android::Parcel *output_parcel);
android::status_t GetVisibleDisplayRect(const android::Parcel *input_parcel,
@@ -313,6 +336,8 @@
android::status_t getComposerStatus();
android::status_t SetQSyncMode(const android::Parcel *input_parcel);
android::status_t SetIdlePC(const android::Parcel *input_parcel);
+ android::status_t RefreshScreen(const android::Parcel *input_parcel);
+ android::status_t SetAd4RoiConfig(const android::Parcel *input_parcel);
void Refresh(hwc2_display_t display);
void HotPlug(hwc2_display_t display, HWC2::Connection state);
@@ -323,6 +348,7 @@
void HandlePowerOnPending(hwc2_display_t display, int retire_fence);
void HandleHotplugPending(hwc2_display_t disp_id, int retire_fence);
void UpdateVsyncSource(hwc2_display_t display);
+ hwc2_display_t GetNextBuiltinIndex();
CoreInterface *core_intf_ = nullptr;
HWCDisplay *hwc_display_[kNumDisplays] = {nullptr};
@@ -348,7 +374,7 @@
int hpd_bpp_ = 0;
int hpd_pattern_ = 0;
int null_display_mode_ = 0;
- bool power_on_pending_[HWC_NUM_DISPLAY_TYPES] = {false};
+ bool power_on_pending_[kNumDisplays] = {false};
HotPlugEvent hotplug_pending_event_ = kHotPlugNone;
bool destroy_virtual_disp_pending_ = false;
uint32_t idle_pc_ref_cnt_ = 0;
diff --git a/sdm/libs/hwc2/hwc_session_services.cpp b/sdm/libs/hwc2/hwc_session_services.cpp
index 467da12..ff71e82 100644
--- a/sdm/libs/hwc2/hwc_session_services.cpp
+++ b/sdm/libs/hwc2/hwc_session_services.cpp
@@ -602,8 +602,8 @@
if (!idle_pc_ref_cnt_) {
HWC2::Error err =
hwc_display_[HWC_DISPLAY_PRIMARY]->ControlIdlePowerCollapse(enable, synchronous);
- if (err != HWC2::Error::None) {
- return -EINVAL;
+ if (err == HWC2::Error::Unsupported) {
+ return 0;
}
Refresh(HWC_DISPLAY_PRIMARY);
int32_t error = locker_[HWC_DISPLAY_PRIMARY].WaitFinite(kCommitDoneTimeoutMs);
@@ -618,8 +618,8 @@
if (!(idle_pc_ref_cnt_ - 1)) {
HWC2::Error err =
hwc_display_[HWC_DISPLAY_PRIMARY]->ControlIdlePowerCollapse(enable, synchronous);
- if (err != HWC2::Error::None) {
- return -EINVAL;
+ if (err == HWC2::Error::Unsupported) {
+ return 0;
}
DLOGI("Idle PC enabled!!");
}
@@ -633,4 +633,44 @@
}
#endif // DISPLAY_CONFIG_1_3
+
+int32_t HWCSession::IsWbUbwcSupported(int *value) {
+ HWDisplaysInfo hw_displays_info = {};
+ DisplayError error = core_intf_->GetDisplaysStatus(&hw_displays_info);
+ if (error != kErrorNone) {
+ return -EINVAL;
+ }
+
+ for (auto &iter : hw_displays_info) {
+ auto &info = iter.second;
+ if (info.display_type == kVirtual && info.is_wb_ubwc_supported) {
+ *value = 1;
+ }
+ }
+
+ return error;
+}
+
+#ifdef DISPLAY_CONFIG_1_4
+Return<void> HWCSession::getWriteBackCapabilities(getWriteBackCapabilities_cb _hidl_cb) {
+ int value = 0;
+ IDisplayConfig::WriteBackCapabilities wb_caps = {};
+ int32_t error = IsWbUbwcSupported(&value);
+ wb_caps.isWbUbwcSupported = value;
+ _hidl_cb(error, wb_caps);
+
+ return Void();
+}
+#endif // DISPLAY_CONFIG_1_4
+
+#ifdef DISPLAY_CONFIG_1_5
+Return<int32_t> HWCSession::SetDisplayDppsAdROI(uint32_t display_id, uint32_t h_start,
+ uint32_t h_end, uint32_t v_start, uint32_t v_end,
+ uint32_t factor_in, uint32_t factor_out) {
+ return CallDisplayFunction(static_cast<hwc2_device_t *>(this), display_id,
+ &HWCDisplay::SetDisplayDppsAdROI, h_start, h_end, v_start, v_end,
+ factor_in, factor_out);
+}
+#endif // DISPLAY_CONFIG_1_5
+
} // namespace sdm