display: Add API to set luminance
-Add API to set min/max luminance range for given display.
-using API via binder
adb shell "vndservice call display.qservice 46 i32 <display_id>
f <min_lum> f <max_lum>"
Change-Id: I97c31b18cac4ab8ac45518833d0964b7e54c9d58
diff --git a/common.mk b/common.mk
index e2f3c4c..eca4769 100644
--- a/common.mk
+++ b/common.mk
@@ -3,8 +3,13 @@
#Get the highest display config version available
display_config_version := $(shell \
+ if [ -d "$(TOP)/vendor/qcom/opensource/interfaces/display/config/1.9" ];\
+ then echo DISPLAY_CONFIG_1_9; fi)
+ifeq ($(display_config_version),)
+display_config_version := $(shell \
if [ -d "$(TOP)/vendor/qcom/opensource/interfaces/display/config/1.8" ];\
then echo DISPLAY_CONFIG_1_8; fi)
+endif
ifeq ($(display_config_version),)
display_config_version := $(shell \
if [ -d "$(TOP)/vendor/qcom/opensource/interfaces/display/config/1.7" ];\
@@ -81,6 +86,11 @@
common_flags += -DDISPLAY_CONFIG_1_4 -DDISPLAY_CONFIG_1_5 -DDISPLAY_CONFIG_1_6
common_flags += -DDISPLAY_CONFIG_1_7 -DDISPLAY_CONFIG_1_8
endif
+ifeq ($(display_config_version), DISPLAY_CONFIG_1_9)
+ common_flags += -DDISPLAY_CONFIG_1_1 -DDISPLAY_CONFIG_1_2 -DDISPLAY_CONFIG_1_3
+ common_flags += -DDISPLAY_CONFIG_1_4 -DDISPLAY_CONFIG_1_5 -DDISPLAY_CONFIG_1_6
+ common_flags += -DDISPLAY_CONFIG_1_7 -DDISPLAY_CONFIG_1_8 -DDISPLAY_CONFIG_1_9
+endif
ifeq ($(TARGET_USES_COLOR_METADATA), true)
common_flags += -DUSE_COLOR_METADATA
diff --git a/config/display-product.mk b/config/display-product.mk
index ef2585c..8d165e0 100644
--- a/config/display-product.mk
+++ b/config/display-product.mk
@@ -22,6 +22,7 @@
vendor.display.config@1.6.vendor \
vendor.display.config@1.7.vendor \
vendor.display.config@1.8.vendor \
+ vendor.display.config@1.9.vendor \
modetest
#QDCM calibration xml file for 2k panel
diff --git a/libqdutils/display_config.cpp b/libqdutils/display_config.cpp
index fc2e3dc..f9e7e33 100644
--- a/libqdutils/display_config.cpp
+++ b/libqdutils/display_config.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2013-2014, 2016, 2018, The Linux Foundation. All rights reserved.
+* Copyright (c) 2013-2014, 2016, 2018, 2019, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -370,6 +370,23 @@
return 0;
}
+int setPanelLuminanceAttributes(int dpy, float min_lum, float max_lum) {
+ status_t err = (status_t) FAILED_TRANSACTION;
+ sp<IQService> binder = getBinder();
+ Parcel inParcel, outParcel;
+
+ if(binder != NULL) {
+ inParcel.writeInt32(dpy);
+ inParcel.writeFloat(min_lum);
+ inParcel.writeFloat(max_lum);
+ status_t err = binder->dispatch(IQService::SET_PANEL_LUMINANCE, &inParcel, &outParcel);
+ if(err) {
+ ALOGE("%s() failed with err %d", __FUNCTION__, err);
+ }
+ }
+ return err;
+}
+
}// namespace
// ----------------------------------------------------------------------------
diff --git a/libqdutils/display_config.h b/libqdutils/display_config.h
index c0952b0..ad41ed7 100644
--- a/libqdutils/display_config.h
+++ b/libqdutils/display_config.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 - 2016, 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013 - 2016, 2018, 2019, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -171,6 +171,9 @@
// Get supported bit clk values.
int getSupportedBitClk(int dpy, std::vector<uint64_t>& bit_rates);
+// Sets the specified min and max luminance values.
+int setPanelLuminanceAttributes(int dpy, float min_lum, float max_lum);
+
}; //namespace
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index e19eccc..387eaca 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -85,6 +85,7 @@
GET_DSI_CLK = 43, // Get DSI Clk.
GET_SUPPORTED_DSI_CLK = 44, // Get supported DSI Clk.
SET_COLOR_MODE_FROM_CLIENT = 45, // Overrides the QDCM mode using the given mode ID
+ SET_PANEL_LUMINANCE = 46, // Set Panel Luminance attributes.
COMMAND_LIST_END = 400,
};
diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h
index 922d7ba..bfd4d64 100644
--- a/sdm/include/core/display_interface.h
+++ b/sdm/include/core/display_interface.h
@@ -837,6 +837,15 @@
virtual DisplayError GetDisplayIdentificationData(uint8_t *out_port, uint32_t *out_data_size,
uint8_t *out_data) = 0;
+ /*! @brief Method to set min/max luminance for dynamic tonemapping of external device over WFD.
+
+ @param[in] min_lum min luminance supported by external device.
+ @param[in] max_lum max luminance supported by external device.
+
+ @return \link DisplayError \endlink
+ */
+ virtual DisplayError SetPanelLuminanceAttributes(float min_lum, float max_lum) = 0;
+
protected:
virtual ~DisplayInterface() { }
};
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index 9039aff..6cdf6ff 100755
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -103,6 +103,9 @@
virtual DisplayError GetSupportedDSIClock(std::vector<uint64_t> *bitclk_rates) {
return kErrorNotSupported;
}
+ virtual DisplayError SetPanelLuminanceAttributes(float min_lum, float max_lum) {
+ return kErrorNotSupported;
+ }
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);
diff --git a/sdm/libs/core/display_virtual.cpp b/sdm/libs/core/display_virtual.cpp
index bf53c66..ad7dad6 100644
--- a/sdm/libs/core/display_virtual.cpp
+++ b/sdm/libs/core/display_virtual.cpp
@@ -121,6 +121,13 @@
hw_intf_->GetHWPanelInfo(&hw_panel_info);
+ if (set_max_lum_ != -1.0 || set_min_lum_ != -1.0) {
+ hw_panel_info.peak_luminance = set_max_lum_;
+ hw_panel_info.blackness_level = set_min_lum_;
+ DLOGI("set peak_luminance %f blackness_level %f", hw_panel_info.peak_luminance,
+ hw_panel_info.blackness_level);
+ }
+
error = hw_intf_->GetMixerAttributes(&mixer_attributes);
if (error != kErrorNone) {
return error;
@@ -174,5 +181,11 @@
return kErrorNone;
}
+DisplayError DisplayVirtual::SetPanelLuminanceAttributes(float min_lum, float max_lum) {
+ set_max_lum_ = max_lum;
+ set_min_lum_ = min_lum;
+ return kErrorNone;
+}
+
} // namespace sdm
diff --git a/sdm/libs/core/display_virtual.h b/sdm/libs/core/display_virtual.h
index 1a672e1..1ae469c 100644
--- a/sdm/libs/core/display_virtual.h
+++ b/sdm/libs/core/display_virtual.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2019, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
@@ -52,6 +52,7 @@
virtual DisplayError SetMixerResolution(uint32_t width, uint32_t height) {
return kErrorNotSupported;
}
+ virtual DisplayError SetPanelLuminanceAttributes(float min_lum, float max_lum);
virtual DisplayError SetVSyncState(bool enable) {
return kErrorNotSupported;
}
@@ -71,6 +72,10 @@
}
virtual DisplayError TeardownConcurrentWriteback(void) { return kErrorNotSupported; }
virtual DisplayError GetColorModeCount(uint32_t *mode_count);
+
+ protected:
+ float set_max_lum_ = -1.0;
+ float set_min_lum_ = -1.0;
};
} // namespace sdm
diff --git a/sdm/libs/hwc2/Android.mk b/sdm/libs/hwc2/Android.mk
index daca922..78bce5e 100644
--- a/sdm/libs/hwc2/Android.mk
+++ b/sdm/libs/hwc2/Android.mk
@@ -80,6 +80,17 @@
LOCAL_SHARED_LIBRARIES += vendor.display.config@1.7
LOCAL_SHARED_LIBRARIES += vendor.display.config@1.8
endif
+ifeq ($(display_config_version), DISPLAY_CONFIG_1_9)
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.1
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.2
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.3
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.4
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.5
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.6
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.7
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.8
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.9
+endif
ifeq ($(TARGET_BOARD_AUTO), true)
LOCAL_CFLAGS += -DCONFIG_BASEID_FROM_PROP
diff --git a/sdm/libs/hwc2/display_null.h b/sdm/libs/hwc2/display_null.h
index 7d31c6b..4390f4e 100644
--- a/sdm/libs/hwc2/display_null.h
+++ b/sdm/libs/hwc2/display_null.h
@@ -108,6 +108,7 @@
MAKE_NO_OP(SetDynamicDSIClock(uint64_t bit_clk_rate))
MAKE_NO_OP(GetDynamicDSIClock(uint64_t *bit_clk_rate))
MAKE_NO_OP(GetSupportedDSIClock(vector<uint64_t> *bitclk_rates))
+ MAKE_NO_OP(SetPanelLuminanceAttributes(float min_lum, float max_lum))
protected:
DisplayConfigVariableInfo default_variable_config_ = {};
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index b1951ef..11d2613 100644
--- a/sdm/libs/hwc2/hwc_display.h
+++ b/sdm/libs/hwc2/hwc_display.h
@@ -240,6 +240,9 @@
virtual HWC2::Error AcceptDisplayChanges(void);
virtual HWC2::Error GetActiveConfig(hwc2_config_t *out_config);
virtual HWC2::Error SetActiveConfig(hwc2_config_t config);
+ virtual HWC2::Error SetPanelLuminanceAttributes(float min_lum, float max_lum) {
+ return HWC2::Error::Unsupported;
+ }
virtual HWC2::Error SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
int32_t dataspace, hwc_region_t damage);
virtual HWC2::Error SetColorMode(ColorMode mode) { return HWC2::Error::Unsupported; }
diff --git a/sdm/libs/hwc2/hwc_display_virtual.cpp b/sdm/libs/hwc2/hwc_display_virtual.cpp
index d58ef2f..6930399 100644
--- a/sdm/libs/hwc2/hwc_display_virtual.cpp
+++ b/sdm/libs/hwc2/hwc_display_virtual.cpp
@@ -42,7 +42,7 @@
int HWCDisplayVirtual::Create(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator,
HWCCallbacks *callbacks, hwc2_display_t id, int32_t sdm_id,
uint32_t width, uint32_t height, int32_t *format,
- HWCDisplay **hwc_display) {
+ HWCDisplay **hwc_display, float min_lum, float max_lum) {
int status = 0;
HWCDisplayVirtual *hwc_display_virtual = new HWCDisplayVirtual(core_intf, buffer_allocator,
callbacks, id, sdm_id);
@@ -57,6 +57,10 @@
return status;
}
+ if (max_lum != -1.0 || min_lum != -1.0) {
+ hwc_display_virtual->SetPanelLuminanceAttributes(min_lum, max_lum);
+ }
+
status = hwc_display_virtual->SetConfig(width, height);
if (status) {
Destroy(hwc_display_virtual);
@@ -214,6 +218,15 @@
return 0;
}
+
+HWC2::Error HWCDisplayVirtual::SetPanelLuminanceAttributes(float min_lum, float max_lum) {
+ DisplayError err = display_intf_->SetPanelLuminanceAttributes(min_lum, max_lum);
+ if (err != kErrorNone) {
+ return HWC2::Error::BadParameter;
+ }
+ return HWC2::Error::None;
+}
+
HWC2::Error HWCDisplayVirtual::SetOutputBuffer(buffer_handle_t buf, int32_t release_fence) {
if (buf == nullptr || release_fence == 0) {
return HWC2::Error::BadParameter;
diff --git a/sdm/libs/hwc2/hwc_display_virtual.h b/sdm/libs/hwc2/hwc_display_virtual.h
index 6b39775..c325a7f 100644
--- a/sdm/libs/hwc2/hwc_display_virtual.h
+++ b/sdm/libs/hwc2/hwc_display_virtual.h
@@ -41,7 +41,8 @@
public:
static int Create(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator,
HWCCallbacks *callbacks, hwc2_display_t id, int32_t sdm_id, uint32_t width,
- uint32_t height, int32_t *format, HWCDisplay **hwc_display);
+ uint32_t height, int32_t *format, HWCDisplay **hwc_display, float min_lum,
+ float max_lum);
static void Destroy(HWCDisplay *hwc_display);
virtual int Init();
virtual int Deinit();
@@ -51,6 +52,7 @@
int32_t format, bool post_processed);
virtual HWC2::Error GetDisplayType(int32_t *out_type);
virtual HWC2::Error SetColorMode(ColorMode mode);
+ virtual HWC2::Error SetPanelLuminanceAttributes(float min_lum, float max_lum);
HWC2::Error SetOutputBuffer(buffer_handle_t buf, int32_t release_fence);
private:
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index 1c1ea99..674f666 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -1276,7 +1276,8 @@
}
status = HWCDisplayVirtual::Create(core_intf_, &buffer_allocator_, &callbacks_, client_id,
- info.display_id, width, height, format, &hwc_display);
+ info.display_id, width, height, format, &hwc_display,
+ set_min_lum_, set_max_lum_);
// TODO(user): validate width and height support
if (status) {
return HWC2::Error::NoResources;
@@ -1616,6 +1617,14 @@
status = GetSupportedDsiClk(input_parcel, output_parcel);
break;
+ case qService::IQService::SET_PANEL_LUMINANCE:
+ if (!input_parcel) {
+ DLOGE("QService command = %d: input_parcel needed.", command);
+ break;
+ }
+ status = SetPanelLuminanceAttributes(input_parcel);
+ break;
+
case qService::IQService::SET_COLOR_MODE_FROM_CLIENT:
if (!input_parcel) {
DLOGE("QService command = %d: input_parcel needed.", command);
@@ -2265,6 +2274,22 @@
return 0;
}
+android::status_t HWCSession::SetPanelLuminanceAttributes(const android::Parcel *input_parcel) {
+ int disp_id = input_parcel->readInt32();
+
+ // currently doing only for virtual display
+ if (disp_id != qdutils::DISPLAY_VIRTUAL) {
+ return -EINVAL;
+ }
+
+ std::lock_guard<std::mutex> obj(mutex_lum_);
+ set_min_lum_ = input_parcel->readFloat();
+ set_max_lum_ = input_parcel->readFloat();
+ DLOGI("set max_lum %f, min_lum %f", set_max_lum_, set_min_lum_);
+
+ return 0;
+}
+
void HWCSession::UEventHandler(const char *uevent_data, int length) {
// Drop hotplug uevents until SurfaceFlinger (the client) is connected. The equivalent of hotplug
// uevent handling will be done once when SurfaceFlinger connects, at RegisterCallback(). Since
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
index 1d546cc..a1bd80a 100644
--- a/sdm/libs/hwc2/hwc_session.h
+++ b/sdm/libs/hwc2/hwc_session.h
@@ -20,7 +20,9 @@
#ifndef __HWC_SESSION_H__
#define __HWC_SESSION_H__
-#ifdef DISPLAY_CONFIG_1_8
+#ifdef DISPLAY_CONFIG_1_9
+#include <vendor/display/config/1.9/IDisplayConfig.h>
+#elif DISPLAY_CONFIG_1_8
#include <vendor/display/config/1.8/IDisplayConfig.h>
#elif DISPLAY_CONFIG_1_7
#include <vendor/display/config/1.7/IDisplayConfig.h>
@@ -61,7 +63,9 @@
namespace sdm {
-#ifdef DISPLAY_CONFIG_1_8
+#ifdef DISPLAY_CONFIG_1_9
+using vendor::display::config::V1_9::IDisplayConfig;
+#elif DISPLAY_CONFIG_1_8
using vendor::display::config::V1_8::IDisplayConfig;
#elif DISPLAY_CONFIG_1_7
using vendor::display::config::V1_7::IDisplayConfig;
@@ -351,6 +355,12 @@
Return<void> getActiveBuiltinDisplayAttributes(getDisplayAttributes_cb _hidl_cb) override;
#endif
+#ifdef DISPLAY_CONFIG_1_9
+ Return<int32_t> setPanelLuminanceAttributes(uint32_t disp_id, float min_lum,
+ float max_lum) override;
+ Return<bool> isBuiltInDisplay(uint32_t disp_id) override;
+#endif
+
// QClient methods
virtual android::status_t notifyCallback(uint32_t command, const android::Parcel *input_parcel,
android::Parcel *output_parcel);
@@ -384,6 +394,7 @@
android::status_t GetDsiClk(const android::Parcel *input_parcel, android::Parcel *output_parcel);
android::status_t GetSupportedDsiClk(const android::Parcel *input_parcel,
android::Parcel *output_parcel);
+ android::status_t SetPanelLuminanceAttributes(const android::Parcel *input_parcel);
void Refresh(hwc2_display_t display);
void HotPlug(hwc2_display_t display, HWC2::Connection state);
@@ -420,6 +431,7 @@
bool hdmi_is_primary_ = false;
bool is_composer_up_ = false;
Locker callbacks_lock_;
+ std::mutex mutex_lum_;
int hpd_bpp_ = 0;
int hpd_pattern_ = 0;
static bool power_on_pending_[HWCCallbacks::kNumDisplays];
@@ -430,6 +442,8 @@
uint32_t idle_pc_ref_cnt_ = 0;
int32_t disable_hotplug_bwcheck_ = 0;
int32_t disable_mask_layer_hint_ = 0;
+ float set_max_lum_ = -1.0;
+ float set_min_lum_ = -1.0;
std::bitset<HWCCallbacks::kNumDisplays> pending_refresh_;
};
diff --git a/sdm/libs/hwc2/hwc_session_services.cpp b/sdm/libs/hwc2/hwc_session_services.cpp
index 2a8d631..60786e7 100644
--- a/sdm/libs/hwc2/hwc_session_services.cpp
+++ b/sdm/libs/hwc2/hwc_session_services.cpp
@@ -766,4 +766,34 @@
}
#endif // DISPLAY_CONFIG_1_8
+#ifdef DISPLAY_CONFIG_1_9
+Return<int32_t> HWCSession::setPanelLuminanceAttributes(uint32_t disp_id, float pan_min_lum,
+ float pan_max_lum) {
+ // currently doing only for virtual display
+ if (disp_id != qdutils::DISPLAY_VIRTUAL) {
+ return -EINVAL;
+ }
+
+ std::lock_guard<std::mutex> obj(mutex_lum_);
+ set_min_lum_ = pan_min_lum;
+ set_max_lum_ = pan_max_lum;
+ DLOGI("set max_lum %f, min_lum %f", set_max_lum_, set_min_lum_);
+
+ return 0;
+}
+
+Return<bool> HWCSession::isBuiltInDisplay(uint32_t disp_id) {
+ if ((map_info_primary_.client_id == disp_id) && (map_info_primary_.disp_type == kBuiltIn))
+ return true;
+
+ for (auto &info : map_info_builtin_) {
+ if (disp_id == info.client_id) {
+ return true;
+ }
+ }
+
+ return false;
+}
+#endif // DISPLAY_CONFIG_1_9
+
} // namespace sdm