Merge "gralloc1: Get aligned width and height for ubwc interlaced layout"
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index 866ade6..97c8ad8 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -155,19 +155,48 @@
* uint32_t - core_clk
*/
CRTC_SET_CORE_CLK,
- /*
- * Op: Sets overall SDE core average bandwidth
+ /*
+ * Op: Sets MNOC bus average bandwidth
* Arg: uint32_t - CRTC ID
* uint32_t - core_ab
*/
CRTC_SET_CORE_AB,
/*
- * Op: Sets overall SDE core instantaneous bandwidth
+ * Op: Sets MNOC bus instantaneous bandwidth
* Arg: uint32_t - CRTC ID
* uint32_t - core_ib
*/
CRTC_SET_CORE_IB,
/*
+ * Op: Sets LLCC Bus average bandwidth
+ * Arg: uint32_t - CRTC ID
+ * uint32_t - llcc_ab
+ */
+ CRTC_SET_LLCC_AB,
+ /*
+ * Op: Sets LLCC Bus instantaneous bandwidth
+ * Arg: uint32_t - CRTC ID
+ * uint32_t - llcc_ib
+ */
+ CRTC_SET_LLCC_IB,
+ /*
+ * Op: Sets DRAM bus average bandwidth
+ * Arg: uint32_t - CRTC ID
+ * uint32_t - dram_ab
+ */
+ CRTC_SET_DRAM_AB,
+ /*
+ * Op: Sets DRAM bus instantaneous bandwidth
+ * Arg: uint32_t - CRTC ID
+ * uint32_t - dram_ib
+ */
+ CRTC_SET_DRAM_IB,
+ /*
+ * Op: Sets rotator clock for inline rotation
+ * Arg: uint32_t - CRTC ID
+ * uint32_t - rot_clk
+ */
+ CRTC_SET_ROT_CLK, /*
* Op: Returns release fence for this frame. Should be called after Commit() on
* DRMAtomicReqInterface.
* Arg: uint32_t - CRTC ID
diff --git a/libgralloc1/gr_buf_mgr.cpp b/libgralloc1/gr_buf_mgr.cpp
index bcd3d7a..2d8a558 100644
--- a/libgralloc1/gr_buf_mgr.cpp
+++ b/libgralloc1/gr_buf_mgr.cpp
@@ -497,14 +497,14 @@
BufferInfo info = GetBufferInfo(descriptor);
GetBufferSizeAndDimensions(info, &size, &alignedw, &alignedh);
size = (bufferSize >= size) ? bufferSize : size;
- size = size * layer_count;
int err = 0;
int flags = 0;
auto page_size = UINT(getpagesize());
AllocData data;
data.align = GetDataAlignment(format, prod_usage, cons_usage);
- data.size = ALIGN(size, data.align);
+ size = ALIGN(size, data.align) * layer_count;
+ data.size = size;
data.handle = (uintptr_t) handle;
data.uncached = allocator_->UseUncached(prod_usage, cons_usage);
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
index 64e8454..78dbfad 100644
--- a/sdm/include/private/hw_info_types.h
+++ b/sdm/include/private/hw_info_types.h
@@ -507,13 +507,22 @@
Handle pvt_data = NULL; // Private data used by sdm extension only.
};
+struct HWQosData {
+ uint64_t core_ab_bps = 0;
+ uint64_t core_ib_bps = 0;
+ uint64_t llcc_ab_bps = 0;
+ uint64_t llcc_ib_bps = 0;
+ uint64_t dram_ab_bps = 0;
+ uint64_t dram_ib_bps = 0;
+ uint32_t clock_hz = 0;
+ uint32_t rot_clock_hz = 0;
+};
+
struct HWLayers {
HWLayersInfo info;
HWLayerConfig config[kMaxSDELayers];
float output_compression = 1.0f;
- uint64_t ab_bps = 0;
- uint64_t ib_bps = 0;
- uint32_t clock_hz = 0;
+ HWQosData qos_data = {};
HWAVRInfo hw_avr_info = {};
};
diff --git a/sdm/libs/core/Android.mk b/sdm/libs/core/Android.mk
index c5002a9..991cfac 100644
--- a/sdm/libs/core/Android.mk
+++ b/sdm/libs/core/Android.mk
@@ -49,6 +49,7 @@
ifneq ($(TARGET_IS_HEADLESS), true)
LOCAL_SRC_FILES += $(LOCAL_HW_INTF_PATH_2)/hw_info_drm.cpp \
$(LOCAL_HW_INTF_PATH_2)/hw_device_drm.cpp \
+ $(LOCAL_HW_INTF_PATH_2)/hw_hdmi_drm.cpp \
$(LOCAL_HW_INTF_PATH_2)/hw_events_drm.cpp \
$(LOCAL_HW_INTF_PATH_2)/hw_scale_drm.cpp \
$(LOCAL_HW_INTF_PATH_2)/hw_virtual_drm.cpp \
diff --git a/sdm/libs/core/drm/hw_color_manager_drm.cpp b/sdm/libs/core/drm/hw_color_manager_drm.cpp
index 640a843..3438e77 100644
--- a/sdm/libs/core/drm/hw_color_manager_drm.cpp
+++ b/sdm/libs/core/drm/hw_color_manager_drm.cpp
@@ -270,9 +270,14 @@
return kErrorParameters;
}
- if (sde_gamut->map_en)
- std::memcpy(mdp_gamut->scale_off, sde_gamut->scale_off_data,
- sizeof(uint32_t) * GAMUT_3D_SCALE_OFF_SZ * GAMUT_3D_SCALE_OFF_TBL_NUM);
+ if (sde_gamut->map_en) {
+ std::memcpy(&mdp_gamut->scale_off[0][0], sde_gamut->scale_off_data[0],
+ sizeof(uint32_t) * GAMUT_3D_SCALE_OFF_SZ);
+ std::memcpy(&mdp_gamut->scale_off[1][0], sde_gamut->scale_off_data[1],
+ sizeof(uint32_t) * GAMUT_3D_SCALE_OFF_SZ);
+ std::memcpy(&mdp_gamut->scale_off[2][0], sde_gamut->scale_off_data[2],
+ sizeof(uint32_t) * GAMUT_3D_SCALE_OFF_SZ);
+ }
for (uint32_t row = 0; row < GAMUT_3D_TBL_NUM; row++) {
for (uint32_t col = 0; col < size; col++) {
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index a6ed929..b244a2a 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -577,6 +577,11 @@
DisplayError HWDeviceDRM::PowerOn() {
DTRACE_SCOPED();
+ if (!drm_atomic_intf_) {
+ DLOGE("DRM Atomic Interface is null!");
+ return kErrorUndefined;
+ }
+
drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::ON);
int ret = drm_atomic_intf_->Commit(false /* synchronous */);
@@ -588,6 +593,11 @@
}
DisplayError HWDeviceDRM::PowerOff() {
+ if (!drm_atomic_intf_) {
+ DLOGE("DRM Atomic Interface is null!");
+ return kErrorUndefined;
+ }
+
drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::OFF);
drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 0);
int ret = drm_atomic_intf_->Commit(false /* synchronous */);
@@ -620,6 +630,7 @@
HWLayersInfo &hw_layer_info = hw_layers->info;
uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size());
+ HWQosData &qos_data = hw_layers->qos_data;
// TODO(user): Once destination scalar is enabled we can always send ROIs if driver allows
if (hw_panel_info_.partial_update) {
@@ -712,12 +723,20 @@
}
}
- drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_CLK, token_.crtc_id, hw_layers->clock_hz);
- drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_AB, token_.crtc_id, hw_layers->ab_bps);
- drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_IB, token_.crtc_id, hw_layers->ib_bps);
+ drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_CLK, token_.crtc_id, qos_data.clock_hz);
+ drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_AB, token_.crtc_id, qos_data.core_ab_bps);
+ drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_IB, token_.crtc_id, qos_data.core_ib_bps);
+ drm_atomic_intf_->Perform(DRMOps::CRTC_SET_LLCC_AB, token_.crtc_id, qos_data.llcc_ab_bps);
+ drm_atomic_intf_->Perform(DRMOps::CRTC_SET_LLCC_IB, token_.crtc_id, qos_data.llcc_ib_bps);
+ drm_atomic_intf_->Perform(DRMOps::CRTC_SET_DRAM_AB, token_.crtc_id, qos_data.dram_ab_bps);
+ drm_atomic_intf_->Perform(DRMOps::CRTC_SET_DRAM_IB, token_.crtc_id, qos_data.dram_ib_bps);
+ drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ROT_CLK, token_.crtc_id, qos_data.rot_clock_hz);
- DLOGI_IF(kTagDriverConfig, "System: clock=%d Hz, ab=%llu Bps ib=%llu Bps", hw_layers->clock_hz,
- hw_layers->ab_bps, hw_layers->ib_bps);
+ DLOGI_IF(kTagDriverConfig, "System Clock=%d Hz, Core: AB=%llu Bps, IB=%llu Bps, " \
+ "LLCC: AB=%llu Bps, IB=%llu Bps, DRAM AB=%llu Bps, IB=%llu Bps Rot Clock=%d",
+ qos_data.clock_hz, qos_data.core_ab_bps, qos_data.core_ib_bps, qos_data.llcc_ab_bps,
+ qos_data.llcc_ib_bps, qos_data.dram_ab_bps, qos_data.dram_ib_bps,
+ qos_data.rot_clock_hz);
}
}
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index 2199426..1c4f517 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -151,6 +151,7 @@
protected:
const char *device_name_ = {};
bool deferred_initialize_ = false;
+ bool default_mode_ = false;
sde_drm::DRMDisplayType disp_type_ = {};
HWInfoInterface *hw_info_intf_ = {};
BufferSyncHandler *buffer_sync_handler_ = {};
@@ -169,7 +170,6 @@
private:
bool synchronous_commit_ = false;
HWMixerAttributes mixer_attributes_ = {};
- bool default_mode_ = false;
std::string interface_str_ = "DSI";
HWScaleDRM *hw_scale_ = {};
};
diff --git a/sdm/libs/core/drm/hw_hdmi_drm.cpp b/sdm/libs/core/drm/hw_hdmi_drm.cpp
new file mode 100644
index 0000000..27419c7
--- /dev/null
+++ b/sdm/libs/core/drm/hw_hdmi_drm.cpp
@@ -0,0 +1,163 @@
+/*
+* Copyright (c) 2017, 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:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <drm_lib_loader.h>
+#include <drm_master.h>
+#include <drm_res_mgr.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <utils/debug.h>
+#include <utils/sys.h>
+#include <utils/formats.h>
+
+#include <vector>
+#include <map>
+#include <utility>
+
+#include "hw_hdmi_drm.h"
+
+#define __CLASS__ "HWHDMIDRM"
+
+using drm_utils::DRMMaster;
+using drm_utils::DRMResMgr;
+using drm_utils::DRMLibLoader;
+using drm_utils::DRMBuffer;
+using sde_drm::GetDRMManager;
+using sde_drm::DestroyDRMManager;
+using sde_drm::DRMDisplayType;
+using sde_drm::DRMDisplayToken;
+using sde_drm::DRMConnectorInfo;
+using sde_drm::DRMPPFeatureInfo;
+using sde_drm::DRMOps;
+using sde_drm::DRMTopology;
+
+namespace sdm {
+
+HWHDMIDRM::HWHDMIDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
+ HWInfoInterface *hw_info_intf)
+ : HWDeviceDRM(buffer_sync_handler, buffer_allocator, hw_info_intf),
+ active_config_index_(0) {
+ HWDeviceDRM::device_type_ = kDeviceHDMI;
+ HWDeviceDRM::device_name_ = "HDMI Display Device";
+}
+
+// TODO(user) : split function in base class and avoid code duplicacy
+// by using base implementation for this basic stuff
+DisplayError HWHDMIDRM::Init() {
+ DisplayError error = kErrorNone;
+
+ default_mode_ = (DRMLibLoader::GetInstance()->IsLoaded() == false);
+
+ if (!default_mode_) {
+ DRMMaster *drm_master = {};
+ int dev_fd = -1;
+ DRMMaster::GetInstance(&drm_master);
+ drm_master->GetHandle(&dev_fd);
+ DRMLibLoader::GetInstance()->FuncGetDRMManager()(dev_fd, &drm_mgr_intf_);
+ if (drm_mgr_intf_->RegisterDisplay(DRMDisplayType::TV, &token_)) {
+ DLOGE("RegisterDisplay failed");
+ return kErrorResources;
+ }
+
+ drm_mgr_intf_->CreateAtomicReq(token_, &drm_atomic_intf_);
+ drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
+ InitializeConfigs();
+ drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, ¤t_mode_);
+ drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
+
+ if (drm_atomic_intf_->Commit(true /* synchronous */)) {
+ DLOGE("Setting up CRTC %d, Connector %d for %s failed", token_.crtc_id, token_.conn_id,
+ device_name_);
+ return kErrorResources;
+ }
+
+ // Reload connector info for updated info after 1st commit
+ drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
+ DLOGI("Setup CRTC %d, Connector %d for %s", token_.crtc_id, token_.conn_id, device_name_);
+ }
+
+ PopulateDisplayAttributes();
+ PopulateHWPanelInfo();
+ UpdateMixerAttributes();
+
+ return error;
+}
+
+DisplayError HWHDMIDRM::GetNumDisplayAttributes(uint32_t *count) {
+ *count = connector_info_.num_modes;
+ if (*count <= 0) {
+ return kErrorHardware;
+ }
+
+ return kErrorNone;
+}
+
+DisplayError HWHDMIDRM::GetActiveConfig(uint32_t *active_config_index) {
+ *active_config_index = active_config_index_;
+ return kErrorNone;
+}
+
+DisplayError HWHDMIDRM::SetDisplayAttributes(uint32_t index) {
+ DTRACE_SCOPED();
+
+ if (index >= connector_info_.num_modes) {
+ return kErrorNotSupported;
+ }
+
+ active_config_index_ = index;
+
+ // TODO(user): fix this hard coding
+ frame_rate_ = 60;
+
+ // Get the display attributes for current active config index
+ GetDisplayAttributes(active_config_index_, &display_attributes_);
+ UpdateMixerAttributes();
+
+ return kErrorNone;
+}
+
+DisplayError HWHDMIDRM::GetConfigIndex(uint32_t mode, uint32_t *index) {
+ *index = mode;
+
+ return kErrorNone;
+}
+
+DisplayError HWHDMIDRM::Validate(HWLayers *hw_layers) {
+ HWDeviceDRM::ResetDisplayParams();
+
+ return HWDeviceDRM::Validate(hw_layers);
+}
+
+DisplayError HWHDMIDRM::Commit(HWLayers *hw_layers) {
+ return HWDeviceDRM::Commit(hw_layers);
+}
+
+} // namespace sdm
+
diff --git a/sdm/libs/core/drm/hw_hdmi_drm.h b/sdm/libs/core/drm/hw_hdmi_drm.h
new file mode 100644
index 0000000..7e11e5e
--- /dev/null
+++ b/sdm/libs/core/drm/hw_hdmi_drm.h
@@ -0,0 +1,60 @@
+/*
+* Copyright (c) 2017, 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:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __HW_HDMI_DRM_H__
+#define __HW_HDMI_DRM_H__
+
+#include <map>
+#include <vector>
+
+#include "hw_device_drm.h"
+
+namespace sdm {
+
+using std::vector;
+
+class HWHDMIDRM : public HWDeviceDRM {
+ public:
+ explicit HWHDMIDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
+ HWInfoInterface *hw_info_intf);
+
+ protected:
+ virtual DisplayError Init();
+ virtual DisplayError GetNumDisplayAttributes(uint32_t *count);
+ // Requirement to call this only after the first config has been explicitly set by client
+ virtual DisplayError GetActiveConfig(uint32_t *active_config);
+ virtual DisplayError SetDisplayAttributes(uint32_t index);
+ virtual DisplayError GetConfigIndex(uint32_t mode, uint32_t *index);
+ virtual DisplayError Validate(HWLayers *hw_layers);
+ virtual DisplayError Commit(HWLayers *hw_layers);
+
+ private:
+ uint32_t active_config_index_;
+ uint32_t frame_rate_ = 0;
+};
+
+} // namespace sdm
+
+#endif // __HW_HDMI_DRM_H__
+
diff --git a/sdm/libs/core/drm/hw_info_drm.cpp b/sdm/libs/core/drm/hw_info_drm.cpp
index d5bd5cf..8843924 100644
--- a/sdm/libs/core/drm/hw_info_drm.cpp
+++ b/sdm/libs/core/drm/hw_info_drm.cpp
@@ -413,8 +413,7 @@
case SDE_PIX_FMT_RGBX_1010102_UBWC: *sdm_format = kFormatRGBX1010102Ubwc; break;
case SDE_PIX_FMT_Y_CBCR_H2V2_P010: *sdm_format = kFormatYCbCr420P010; break;
case SDE_PIX_FMT_Y_CBCR_H2V2_TP10_UBWC: *sdm_format = kFormatYCbCr420TP10Ubwc; break;
- /* TODO(user) : enable when defined in uapi
- case SDE_PIX_FMT_Y_CBCR_H2V2_P010_UBWC: *sdm_format = kFormatYCbCr420P010Ubwc; break; */
+ case SDE_PIX_FMT_Y_CBCR_H2V2_P010_UBWC: *sdm_format = kFormatYCbCr420P010Ubwc; break;
default: *sdm_format = kFormatInvalid;
}
}
diff --git a/sdm/libs/core/hw_interface.cpp b/sdm/libs/core/hw_interface.cpp
index a7bcabd..f05aa0c 100644
--- a/sdm/libs/core/hw_interface.cpp
+++ b/sdm/libs/core/hw_interface.cpp
@@ -38,6 +38,7 @@
#ifdef COMPILE_DRM
#include "drm/hw_device_drm.h"
#include "drm/hw_virtual_drm.h"
+#include "drm/hw_hdmi_drm.h"
#endif
#define __CLASS__ "HWInterface"
@@ -65,7 +66,9 @@
if (driver_type == DriverType::FB) {
hw = new HWHDMI(buffer_sync_handler, hw_info_intf);
} else {
- return kErrorNotSupported;
+#ifdef COMPILE_DRM
+ hw = new HWHDMIDRM(buffer_sync_handler, buffer_allocator, hw_info_intf);
+#endif
}
break;
case kVirtual:
diff --git a/sdm/libs/hwc2/hwc_color_manager.cpp b/sdm/libs/hwc2/hwc_color_manager.cpp
index b58acc6..afa9a4e 100644
--- a/sdm/libs/hwc2/hwc_color_manager.cpp
+++ b/sdm/libs/hwc2/hwc_color_manager.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2015 - 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015 - 2017, 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
@@ -271,7 +271,6 @@
PPDETuningCfgData *de_tuning_cfg_data = reinterpret_cast<PPDETuningCfgData*>(params);
if (de_tuning_cfg_data->cfg_pending == true) {
if (!de_tuning_cfg_data->cfg_en) {
- de_data.override_flags = kOverrideDEEnable;
de_data.enable = 0;
} else {
de_data.override_flags = kOverrideDEEnable;
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index 2bf7d4d..7b68eb8 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -47,6 +47,7 @@
#define HWC_UEVENT_SWITCH_HDMI "change@/devices/virtual/switch/hdmi"
#define HWC_UEVENT_GRAPHICS_FB0 "change@/devices/virtual/graphics/fb0"
+#define HWC_UEVENT_DRM_EXT_HOTPLUG "mdss_mdp/drm/card"
static sdm::HWCSession::HWCModuleMethods g_hwc_module_methods;
@@ -1453,6 +1454,8 @@
callbacks_.Refresh(0);
reset_panel_ = true;
}
+ } else if (strcasestr(uevent_data, HWC_UEVENT_DRM_EXT_HOTPLUG)) {
+ HandleExtHPD(uevent_data, length);
}
}
pthread_exit(0);
@@ -1460,6 +1463,29 @@
return NULL;
}
+void HWCSession::HandleExtHPD(const char *uevent_data, int length) {
+ const char *iterator_str = uevent_data;
+ const char *event_info = "status=";
+ const char *pstr = NULL;
+ while (((iterator_str - uevent_data) <= length) && (*iterator_str)) {
+ pstr = strstr(iterator_str, event_info);
+ if (pstr != NULL) {
+ break;
+ }
+ iterator_str += strlen(iterator_str) + 1;
+ }
+
+ if (pstr) {
+ bool connected = false;
+ if (strcmp(pstr+strlen(event_info), "connected") == 0) {
+ connected = true;
+ }
+
+ DLOGI("Recived Ext HPD, connected:%d status=%s", connected, pstr+strlen(event_info));
+ HotPlugHandler(connected);
+ }
+}
+
int HWCSession::GetEventValue(const char *uevent_data, int length, const char *event_info) {
const char *iterator_str = uevent_data;
while (((iterator_str - uevent_data) <= length) && (*iterator_str)) {
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
index 7d31a3a..c4c38a5 100644
--- a/sdm/libs/hwc2/hwc_session.h
+++ b/sdm/libs/hwc2/hwc_session.h
@@ -119,6 +119,7 @@
static void *HWCUeventThread(void *context);
void *HWCUeventThreadHandler();
int GetEventValue(const char *uevent_data, int length, const char *event_info);
+ void HandleExtHPD(const char *uevent_data, int length);
int HotPlugHandler(bool connected);
void ResetPanel();
int32_t ConnectDisplay(int disp);
diff --git a/sdm/libs/hwc2/hwc_tonemapper.cpp b/sdm/libs/hwc2/hwc_tonemapper.cpp
index 7bda725..74f4c6a 100644
--- a/sdm/libs/hwc2/hwc_tonemapper.cpp
+++ b/sdm/libs/hwc2/hwc_tonemapper.cpp
@@ -49,18 +49,57 @@
namespace sdm {
-ToneMapSession::ToneMapSession(HWCBufferAllocator *buffer_allocator) :
- buffer_allocator_(buffer_allocator) {
+ToneMapSession::ToneMapSession(HWCBufferAllocator *buffer_allocator)
+ : tone_map_task_(*this), buffer_allocator_(buffer_allocator) {
buffer_info_.resize(kNumIntermediateBuffers);
}
ToneMapSession::~ToneMapSession() {
- delete gpu_tone_mapper_;
- gpu_tone_mapper_ = nullptr;
+ tone_map_task_.PerformTask(ToneMapTaskCode::kCodeDestroy, nullptr);
FreeIntermediateBuffers();
buffer_info_.clear();
}
+void ToneMapSession::OnTask(const ToneMapTaskCode &task_code,
+ SyncTask<ToneMapTaskCode>::TaskContext *task_context) {
+ switch (task_code) {
+ case ToneMapTaskCode::kCodeGetInstance: {
+ ToneMapGetInstanceContext *ctx = static_cast<ToneMapGetInstanceContext *>(task_context);
+ Lut3d &lut_3d = ctx->layer->lut_3d;
+ Color10Bit *grid_entries = NULL;
+ int grid_size = 0;
+ if (lut_3d.validGridEntries) {
+ grid_entries = lut_3d.gridEntries;
+ grid_size = INT(lut_3d.gridSize);
+ }
+ gpu_tone_mapper_ = TonemapperFactory_GetInstance(tone_map_config_.type,
+ lut_3d.lutEntries, lut_3d.dim,
+ grid_entries, grid_size,
+ tone_map_config_.secure);
+ }
+ break;
+
+ case ToneMapTaskCode::kCodeBlit: {
+ ToneMapBlitContext *ctx = static_cast<ToneMapBlitContext *>(task_context);
+ uint8_t buffer_index = current_buffer_index_;
+ const void *dst_hnd = reinterpret_cast<const void *>
+ (buffer_info_[buffer_index].private_data);
+ const void *src_hnd = reinterpret_cast<const void *>
+ (ctx->layer->input_buffer.buffer_id);
+ ctx->fence_fd = gpu_tone_mapper_->blit(dst_hnd, src_hnd, ctx->merged_fd);
+ }
+ break;
+
+ case ToneMapTaskCode::kCodeDestroy: {
+ delete gpu_tone_mapper_;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
DisplayError ToneMapSession::AllocateIntermediateBuffers(const Layer *layer) {
DisplayError error = kErrorNone;
for (uint8_t i = 0; i < kNumIntermediateBuffers; i++) {
@@ -180,35 +219,30 @@
}
void HWCToneMapper::ToneMap(Layer* layer, ToneMapSession *session) {
- int fence_fd = -1;
- int acquire_fd = -1;
- int merged_fd = -1;
+ ToneMapBlitContext ctx = {};
+ ctx.layer = layer;
uint8_t buffer_index = session->current_buffer_index_;
- const private_handle_t *dst_hnd = static_cast<private_handle_t *>
- (session->buffer_info_[buffer_index].private_data);
- const private_handle_t *src_hnd = reinterpret_cast<const private_handle_t *>
- (layer->input_buffer.buffer_id);
+ int &release_fence_fd = session->release_fence_fd_[buffer_index];
// use and close the layer->input_buffer acquire fence fd.
- acquire_fd = layer->input_buffer.acquire_fence_fd;
- buffer_sync_handler_.SyncMerge(session->release_fence_fd_[buffer_index], acquire_fd, &merged_fd);
+ int acquire_fd = layer->input_buffer.acquire_fence_fd;
+ buffer_sync_handler_.SyncMerge(release_fence_fd, acquire_fd, &ctx.merged_fd);
if (acquire_fd >= 0) {
CloseFd(&acquire_fd);
}
- if (session->release_fence_fd_[buffer_index] >= 0) {
- CloseFd(&session->release_fence_fd_[buffer_index]);
+ if (release_fence_fd >= 0) {
+ CloseFd(&release_fence_fd);
}
DTRACE_BEGIN("GPU_TM_BLIT");
- fence_fd = session->gpu_tone_mapper_->blit(reinterpret_cast<const void *>(dst_hnd),
- reinterpret_cast<const void *>(src_hnd), merged_fd);
+ session->tone_map_task_.PerformTask(ToneMapTaskCode::kCodeBlit, &ctx);
DTRACE_END();
- DumpToneMapOutput(session, &fence_fd);
- session->UpdateBuffer(fence_fd, &layer->input_buffer);
+ DumpToneMapOutput(session, &ctx.fence_fd);
+ session->UpdateBuffer(ctx.fence_fd, &layer->input_buffer);
}
void HWCToneMapper::PostCommit(LayerStack *layer_stack) {
@@ -281,14 +315,6 @@
}
DisplayError HWCToneMapper::AcquireToneMapSession(Layer *layer, uint32_t *session_index) {
- Color10Bit *grid_entries = NULL;
- int grid_size = 0;
-
- if (layer->lut_3d.validGridEntries) {
- grid_entries = layer->lut_3d.gridEntries;
- grid_size = INT(layer->lut_3d.gridSize);
- }
-
// When the property sdm.disable_hdr_lut_gen is set, the lutEntries and gridEntries in
// the Lut3d will be NULL, clients needs to allocate the memory and set correct 3D Lut
// for Tonemapping.
@@ -311,13 +337,15 @@
}
ToneMapSession *session = new ToneMapSession(buffer_allocator_);
+ if (!session) {
+ return kErrorMemory;
+ }
session->SetToneMapConfig(layer);
- session->gpu_tone_mapper_ = TonemapperFactory_GetInstance(session->tone_map_config_.type,
- layer->lut_3d.lutEntries,
- layer->lut_3d.dim,
- grid_entries, grid_size,
- session->tone_map_config_.secure);
+
+ ToneMapGetInstanceContext ctx;
+ ctx.layer = layer;
+ session->tone_map_task_.PerformTask(ToneMapTaskCode::kCodeGetInstance, &ctx);
if (session->gpu_tone_mapper_ == NULL) {
DLOGE("Get Tonemapper failed!");
diff --git a/sdm/libs/hwc2/hwc_tonemapper.h b/sdm/libs/hwc2/hwc_tonemapper.h
index 8367c3e..e2c8ef4 100644
--- a/sdm/libs/hwc2/hwc_tonemapper.h
+++ b/sdm/libs/hwc2/hwc_tonemapper.h
@@ -37,6 +37,7 @@
#include <core/layer_stack.h>
#include <utils/sys.h>
+#include <utils/sync_task.h>
#include <vector>
#include "hwc_buffer_sync_handler.h"
#include "hwc_buffer_allocator.h"
@@ -45,6 +46,22 @@
namespace sdm {
+enum class ToneMapTaskCode : int32_t {
+ kCodeGetInstance,
+ kCodeBlit,
+ kCodeDestroy,
+};
+
+struct ToneMapGetInstanceContext : public SyncTask<ToneMapTaskCode>::TaskContext {
+ Layer *layer = nullptr;
+};
+
+struct ToneMapBlitContext : public SyncTask<ToneMapTaskCode>::TaskContext {
+ Layer *layer = nullptr;
+ int merged_fd = -1;
+ int fence_fd = -1;
+};
+
struct ToneMapConfig {
int type = 0;
ColorPrimaries colorPrimaries = ColorPrimaries_Max;
@@ -53,7 +70,7 @@
bool secure = false;
};
-class ToneMapSession {
+class ToneMapSession : public SyncTask<ToneMapTaskCode>::TaskHandler {
public:
explicit ToneMapSession(HWCBufferAllocator *buffer_allocator);
~ToneMapSession();
@@ -64,7 +81,12 @@
void SetToneMapConfig(Layer *layer);
bool IsSameToneMapConfig(Layer *layer);
+ // TaskHandler methods implementation.
+ virtual void OnTask(const ToneMapTaskCode &task_code,
+ SyncTask<ToneMapTaskCode>::TaskContext *task_context);
+
static const uint8_t kNumIntermediateBuffers = 2;
+ SyncTask<ToneMapTaskCode> tone_map_task_;
Tonemapper *gpu_tone_mapper_ = nullptr;
HWCBufferAllocator *buffer_allocator_ = nullptr;
ToneMapConfig tone_map_config_ = {};