Merge "libgrallocutils: Support defaults in AdrenoMemInfo"
diff --git a/gpu_tonemapper/Tonemapper.cpp b/gpu_tonemapper/Tonemapper.cpp
index 981863d..811e091 100644
--- a/gpu_tonemapper/Tonemapper.cpp
+++ b/gpu_tonemapper/Tonemapper.cpp
@@ -45,7 +45,6 @@
Tonemapper::~Tonemapper()
//-----------------------------------------------------------------------------
{
- void* caller_context = engine_backup();
engine_bind(engineContext);
engine_deleteInputBuffer(tonemapTexture);
engine_deleteInputBuffer(lutXformTexture);
@@ -58,9 +57,6 @@
}
engine_shutdown(engineContext);
- // restore the caller context
- engine_bind(caller_context);
- engine_free_backup(caller_context);
}
//-----------------------------------------------------------------------------
@@ -78,7 +74,6 @@
tonemapper->engineContext = engine_initialize(isSecure);
- void* caller_context = engine_backup();
engine_bind(tonemapper->engineContext);
// load the 3d lut
@@ -117,10 +112,6 @@
tonemapper->programID =
engine_loadProgram(1, &fullscreen_vertex_shader, fragmentShaderCount, fragmentShaders);
- // restore the caller context
- engine_bind(caller_context);
- engine_free_backup(caller_context);
-
return tonemapper;
}
@@ -128,7 +119,6 @@
int Tonemapper::blit(const void *dst, const void *src, int srcFenceFd)
//-----------------------------------------------------------------------------
{
- void* caller_context = engine_backup();
// make current
engine_bind(engineContext);
@@ -159,10 +149,5 @@
// perform
int fenceFD = engine_blit(srcFenceFd);
- // restore the caller context
- engine_bind(caller_context);
- engine_free_backup(caller_context);
-
-
return fenceFD;
}
diff --git a/gpu_tonemapper/engine.h b/gpu_tonemapper/engine.h
index e0bf2aa..8fb9452 100644
--- a/gpu_tonemapper/engine.h
+++ b/gpu_tonemapper/engine.h
@@ -22,8 +22,6 @@
void* engine_initialize(bool isSecure);
void engine_bind(void*);
-void* engine_backup();
-void engine_free_backup(void*);
void engine_shutdown(void*);
unsigned int engine_loadProgram(int, const char **, int, const char **);
diff --git a/gpu_tonemapper/glengine.cpp b/gpu_tonemapper/glengine.cpp
index 6cfe15f..6c94c23 100644
--- a/gpu_tonemapper/glengine.cpp
+++ b/gpu_tonemapper/glengine.cpp
@@ -47,27 +47,6 @@
}
//-----------------------------------------------------------------------------
-// store the current context(caller)
-void* engine_backup()
-{
- EngineContext* callerContext = new EngineContext();
- // store the previous display/context
- callerContext->eglDisplay = eglGetCurrentDisplay();
- callerContext->eglContext = eglGetCurrentContext();
- callerContext->eglSurface = eglGetCurrentSurface(EGL_DRAW);
-
- return (void*)callerContext;
-}
-//-----------------------------------------------------------------------------
-// frees the backed up caller context
-void engine_free_backup(void* context)
-{
- EngineContext* callerContext = (EngineContext*)(context);
-
- delete callerContext;
-}
-
-//-----------------------------------------------------------------------------
// initialize GL
//
void* engine_initialize(bool isSecure)
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index 35285ee..6e07445 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -422,6 +422,7 @@
bool roi_merge;
DRMRotation panel_orientation;
drm_panel_hdr_properties panel_hdr_prop;
+ uint32_t transfer_time_us;
};
/* Identifier token for a display */
diff --git a/libgralloc1/gr_utils.cpp b/libgralloc1/gr_utils.cpp
index b3056e1..560bb08 100644
--- a/libgralloc1/gr_utils.cpp
+++ b/libgralloc1/gr_utils.cpp
@@ -509,7 +509,9 @@
// Query GPU for UBWC only if buffer is intended to be used by GPU.
if ((cons_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) ||
(prod_usage & GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET)) {
- enable = AdrenoMemInfo::GetInstance()->IsUBWCSupportedByGPU(format);
+ if (AdrenoMemInfo::GetInstance()) {
+ enable = AdrenoMemInfo::GetInstance()->IsUBWCSupportedByGPU(format);
+ }
}
// Allow UBWC, only if CPU usage flags are not set
@@ -675,8 +677,10 @@
int tile = ubwc_enabled;
if (IsUncompressedRGBFormat(format)) {
- AdrenoMemInfo::GetInstance()->AlignUnCompressedRGB(width, height, format, tile, alignedw,
- alignedh);
+ if (AdrenoMemInfo::GetInstance()) {
+ AdrenoMemInfo::GetInstance()->AlignUnCompressedRGB(width, height, format, tile, alignedw,
+ alignedh);
+ }
return;
}
@@ -686,7 +690,9 @@
}
if (IsCompressedRGBFormat(format)) {
- AdrenoMemInfo::GetInstance()->AlignCompressedRGB(width, height, format, alignedw, alignedh);
+ if (AdrenoMemInfo::GetInstance()) {
+ AdrenoMemInfo::GetInstance()->AlignCompressedRGB(width, height, format, alignedw, alignedh);
+ }
return;
}
@@ -698,6 +704,9 @@
switch (format) {
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+ if (AdrenoMemInfo::GetInstance() == nullptr) {
+ return;
+ }
alignment = AdrenoMemInfo::GetInstance()->GetGpuPixelAlignment();
aligned_w = ALIGN(width, alignment);
break;
diff --git a/libgralloc1/gralloc_priv.h b/libgralloc1/gralloc_priv.h
index d8dfbf3..87604c6 100644
--- a/libgralloc1/gralloc_priv.h
+++ b/libgralloc1/gralloc_priv.h
@@ -65,7 +65,7 @@
#define GRALLOC1_CONSUMER_USAGE_PRIVATE_WFD 0x00200000
/* This flag is used for SECURE display usecase */
-#define GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY 0x00800000
+#define GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY 0x01000000
/* Unused flag */
#define GRALLOC1_USAGE_PRIVATE_UNUSED1 0x04000000
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
index 752d0c4..763e68d 100644
--- a/sdm/include/private/hw_info_types.h
+++ b/sdm/include/private/hw_info_types.h
@@ -274,6 +274,7 @@
uint32_t blackness_level = 0; // 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
bool operator !=(const HWPanelInfo &panel_info) {
return ((port != panel_info.port) || (mode != panel_info.mode) ||
@@ -289,7 +290,8 @@
(max_fps != panel_info.max_fps) || (is_primary_panel != panel_info.is_primary_panel) ||
(split_info != panel_info.split_info) || (s3d_mode != panel_info.s3d_mode) ||
(left_roi_count != panel_info.left_roi_count) ||
- (right_roi_count != panel_info.right_roi_count));
+ (right_roi_count != panel_info.right_roi_count) ||
+ (transfer_time_us != panel_info.transfer_time_us));
}
bool operator ==(const HWPanelInfo &panel_info) {
diff --git a/sdm/include/utils/debug.h b/sdm/include/utils/debug.h
index 0b40e7b..d5974d9 100644
--- a/sdm/include/utils/debug.h
+++ b/sdm/include/utils/debug.h
@@ -78,6 +78,7 @@
static bool IsAVRDisabled();
static bool IsExtAnimDisabled();
static bool IsPartialSplitDisabled();
+ static bool IsSrcSplitPreferred();
static DisplayError GetMixerResolution(uint32_t *width, uint32_t *height);
static DisplayError GetReducedConfig(uint32_t *num_vig_pipes, uint32_t *num_dma_pipes);
static int GetExtMaxlayers();
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index 1ed9042..cd036a9 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -494,6 +494,7 @@
hw_panel_info_.primaries.green[1] = connector_info_.panel_hdr_prop.display_primaries[5];
hw_panel_info_.primaries.blue[0] = connector_info_.panel_hdr_prop.display_primaries[6];
hw_panel_info_.primaries.blue[1] = connector_info_.panel_hdr_prop.display_primaries[7];
+ hw_panel_info_.transfer_time_us = connector_info_.transfer_time_us;
// no supprt for 90 rotation only flips or 180 supported
hw_panel_info_.panel_orientation.rotation = 0;
@@ -519,6 +520,7 @@
DLOGI("FPS: min = %d, max =%d", hw_panel_info_.min_fps, hw_panel_info_.max_fps);
DLOGI("Left Split = %d, Right Split = %d", hw_panel_info_.split_info.left_split,
hw_panel_info_.split_info.right_split);
+ DLOGI("Panel Transfer time = %d us", hw_panel_info_.transfer_time_us);
}
void HWDeviceDRM::GetHWDisplayPortAndMode() {
diff --git a/sdm/libs/hwc2/hwc_buffer_allocator.cpp b/sdm/libs/hwc2/hwc_buffer_allocator.cpp
index 3c8d460..4865e08 100644
--- a/sdm/libs/hwc2/hwc_buffer_allocator.cpp
+++ b/sdm/libs/hwc2/hwc_buffer_allocator.cpp
@@ -41,23 +41,43 @@
namespace sdm {
-HWCBufferAllocator::HWCBufferAllocator() {
+DisplayError HWCBufferAllocator::Init() {
int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module_);
if (err != 0) {
- DLOGE("FATAL: can not open GRALLOC module");
- } else {
- gralloc1_open(module_, &gralloc_device_);
+ DLOGE("FATAL: can not get GRALLOC module");
+ return kErrorResources;
}
+
+ err = gralloc1_open(module_, &gralloc_device_);
+ if (err != 0) {
+ DLOGE("FATAL: can not open GRALLOC device");
+ return kErrorResources;
+ }
+
+ if (gralloc_device_ == nullptr) {
+ DLOGE("FATAL: gralloc device is null");
+ return kErrorResources;
+ }
+
ReleaseBuffer_ = reinterpret_cast<GRALLOC1_PFN_RELEASE>(
gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_RELEASE));
Perform_ = reinterpret_cast<GRALLOC1_PFN_PERFORM>(
gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_PERFORM));
+ Lock_ = reinterpret_cast<GRALLOC1_PFN_LOCK>(
+ gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_LOCK));
+
+ return kErrorNone;
}
-HWCBufferAllocator::~HWCBufferAllocator() {
+DisplayError HWCBufferAllocator::Deinit() {
if (gralloc_device_ != nullptr) {
- gralloc1_close(gralloc_device_);
+ int err = gralloc1_close(gralloc_device_);
+ if (err != 0) {
+ DLOGE("FATAL: can not close GRALLOC device");
+ return kErrorResources;
+ }
}
+ return kErrorNone;
}
DisplayError HWCBufferAllocator::AllocateBuffer(BufferInfo *buffer_info) {
@@ -354,4 +374,21 @@
return kErrorNone;
}
+DisplayError HWCBufferAllocator::MapBuffer(const private_handle_t *handle, int acquire_fence) {
+ void* buffer_ptr = NULL;
+ const gralloc1_rect_t accessRegion = {
+ .left = 0,
+ .top = 0,
+ .width = 0,
+ .height = 0
+ };
+ Lock_(gralloc_device_, handle, GRALLOC1_PRODUCER_USAGE_CPU_READ, GRALLOC1_CONSUMER_USAGE_NONE,
+ &accessRegion, &buffer_ptr, acquire_fence);
+ if (!buffer_ptr) {
+ return kErrorUndefined;
+ }
+
+ return kErrorNone;
+}
+
} // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_buffer_allocator.h b/sdm/libs/hwc2/hwc_buffer_allocator.h
index d574401..8101d85 100644
--- a/sdm/libs/hwc2/hwc_buffer_allocator.h
+++ b/sdm/libs/hwc2/hwc_buffer_allocator.h
@@ -45,9 +45,8 @@
class HWCBufferAllocator : public BufferAllocator {
public:
- HWCBufferAllocator();
- ~HWCBufferAllocator();
-
+ DisplayError Init();
+ DisplayError Deinit();
DisplayError AllocateBuffer(BufferInfo *buffer_info);
DisplayError FreeBuffer(BufferInfo *buffer_info);
uint32_t GetBufferSize(BufferInfo *buffer_info);
@@ -61,12 +60,14 @@
uint32_t stride[4], uint32_t offset[4],
uint32_t *num_planes);
int SetBufferInfo(LayerBufferFormat format, int *target, uint64_t *flags);
+ DisplayError MapBuffer(const private_handle_t *handle, int acquire_fence);
private:
gralloc1_device_t *gralloc_device_ = nullptr;
const hw_module_t *module_;
GRALLOC1_PFN_RELEASE ReleaseBuffer_ = nullptr;
GRALLOC1_PFN_PERFORM Perform_ = nullptr;
+ GRALLOC1_PFN_LOCK Lock_ = nullptr;
};
} // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index 34ff7e3..f7a9dec 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -363,11 +363,18 @@
// TODO(user): Add blit engine when needed
}
+ error = display_intf_->GetNumVariableInfoConfigs(&num_configs_);
+ if (error != kErrorNone) {
+ DLOGE("Getting config count failed. Error = %d", error);
+ return -EINVAL;
+ }
+
tone_mapper_ = new HWCToneMapper(buffer_allocator_);
display_intf_->GetRefreshRateRange(&min_refresh_rate_, &max_refresh_rate_);
current_refresh_rate_ = max_refresh_rate_;
DLOGI("Display created with id: %d", id_);
+
return 0;
}
@@ -716,12 +723,15 @@
}
HWC2::Error HWCDisplay::GetDisplayConfigs(uint32_t *out_num_configs, hwc2_config_t *out_configs) {
- // TODO(user): Actually handle multiple configs
if (out_configs == nullptr) {
- *out_num_configs = 1;
- } else {
- *out_num_configs = 1;
- out_configs[0] = 0;
+ *out_num_configs = num_configs_;
+ return HWC2::Error::None;
+ }
+
+ *out_num_configs = num_configs_;
+
+ for (uint32_t i = 0; i < num_configs_; i++) {
+ out_configs[i] = i;
}
return HWC2::Error::None;
@@ -730,16 +740,11 @@
HWC2::Error HWCDisplay::GetDisplayAttribute(hwc2_config_t config, HWC2::Attribute attribute,
int32_t *out_value) {
DisplayConfigVariableInfo variable_config;
- DisplayError error = display_intf_->GetFrameBufferConfig(&variable_config);
- if (error != kErrorNone) {
- DLOGV("Get variable config failed. Error = %d", error);
+ if (GetDisplayAttributesForConfig(INT(config), &variable_config) != kErrorNone) {
+ DLOGE("Get variable config failed");
return HWC2::Error::BadDisplay;
}
- if (config != 0) { // We only use config[0] - see TODO above
- return HWC2::Error::BadConfig;
- }
-
switch (attribute) {
case HWC2::Attribute::VsyncPeriod:
*out_value = INT32(variable_config.vsync_period_ns);
@@ -804,14 +809,19 @@
}
}
-// TODO(user): Store configurations and hook them up here
HWC2::Error HWCDisplay::GetActiveConfig(hwc2_config_t *out_config) {
- if (out_config != nullptr) {
- *out_config = 0;
- return HWC2::Error::None;
- } else {
- return HWC2::Error::BadParameter;
+ if (out_config == nullptr) {
+ return HWC2::Error::BadDisplay;
}
+
+ uint32_t active_index = 0;
+ if (GetActiveDisplayConfig(&active_index) != kErrorNone) {
+ return HWC2::Error::BadConfig;
+ }
+
+ *out_config = active_index;
+
+ return HWC2::Error::None;
}
HWC2::Error HWCDisplay::SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
@@ -836,10 +846,10 @@
}
HWC2::Error HWCDisplay::SetActiveConfig(hwc2_config_t config) {
- if (config != 0) {
+ if (SetActiveDisplayConfig(config) != kErrorNone) {
return HWC2::Error::BadConfig;
}
- // We have only one config right now - do nothing
+
return HWC2::Error::None;
}
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index b70f160..e773e91 100644
--- a/sdm/libs/hwc2/hwc_display.h
+++ b/sdm/libs/hwc2/hwc_display.h
@@ -299,6 +299,7 @@
bool color_tranform_failed_ = false;
HWCColorMode *color_mode_ = NULL;
HWCToneMapper *tone_mapper_ = nullptr;
+ uint32_t num_configs_ = 0;
int disable_hdr_handling_ = 0; // disables HDR handling.
private:
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index 7f39d7f..293ffce 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -35,6 +35,8 @@
#include <algorithm>
#include <string>
#include <bitset>
+#include <thread>
+#include <memory>
#include "hwc_buffer_allocator.h"
#include "hwc_buffer_sync_handler.h"
@@ -66,8 +68,63 @@
};
namespace sdm {
+
+static HWCUEvent g_hwc_uevent_;
Locker HWCSession::locker_;
+void HWCUEvent::UEventThread(HWCUEvent *hwc_uevent) {
+ const char *uevent_thread_name = "HWC_UeventThread";
+
+ prctl(PR_SET_NAME, uevent_thread_name, 0, 0, 0);
+ setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
+
+ int status = uevent_init();
+ if (!status) {
+ std::unique_lock<std::mutex> caller_lock(hwc_uevent->mutex_);
+ hwc_uevent->caller_cv_.notify_one();
+ DLOGE("Failed to init uevent with err %d", status);
+ return;
+ }
+
+ {
+ // Signal caller thread that worker thread is ready to listen to events.
+ std::unique_lock<std::mutex> caller_lock(hwc_uevent->mutex_);
+ hwc_uevent->init_done_ = true;
+ hwc_uevent->caller_cv_.notify_one();
+ }
+
+ while (1) {
+ char uevent_data[PAGE_SIZE] = {};
+
+ // keep last 2 zeroes to ensure double 0 termination
+ int length = uevent_next_event(uevent_data, INT32(sizeof(uevent_data)) - 2);
+
+ // scope of lock to this block only, so that caller is free to set event handler to nullptr;
+ {
+ std::lock_guard<std::mutex> guard(hwc_uevent->mutex_);
+ if (hwc_uevent->uevent_listener_) {
+ hwc_uevent->uevent_listener_->UEventHandler(uevent_data, length);
+ } else {
+ DLOGW("UEvent dropped. No uevent listener.");
+ }
+ }
+ }
+}
+
+HWCUEvent::HWCUEvent() {
+ std::unique_lock<std::mutex> caller_lock(mutex_);
+ std::thread thread(HWCUEvent::UEventThread, this);
+ thread.detach();
+ caller_cv_.wait(caller_lock);
+}
+
+void HWCUEvent::Register(HWCUEventListener *uevent_listener) {
+ DLOGI("Set uevent listener = %p", uevent_listener);
+
+ std::lock_guard<std::mutex> obj(mutex_);
+ uevent_listener_ = uevent_listener;
+}
+
HWCSession::HWCSession(const hw_module_t *module) {
hwc2_device_t::common.tag = HARDWARE_DEVICE_TAG;
hwc2_device_t::common.version = HWC_DEVICE_API_VERSION_2_0;
@@ -81,6 +138,10 @@
int status = -EINVAL;
const char *qservice_name = "display.qservice";
+ if (!g_hwc_uevent_.InitDone()) {
+ return status;
+ }
+
// Start QService and connect to it.
qService::QService::init();
android::sp<qService::IQService> iqservice = android::interface_cast<qService::IQService>(
@@ -96,19 +157,29 @@
StartServices();
- DisplayError error = CoreInterface::CreateCore(HWCDebugHandler::Get(), &buffer_allocator_,
- &buffer_sync_handler_, &socket_handler_,
- &core_intf_);
+ DisplayError error = buffer_allocator_.Init();
if (error != kErrorNone) {
+ DLOGE("Buffer allocaor initialization failed. Error = %d", error);
+ return -EINVAL;
+ }
+
+ error = CoreInterface::CreateCore(HWCDebugHandler::Get(), &buffer_allocator_,
+ &buffer_sync_handler_, &socket_handler_, &core_intf_);
+ if (error != kErrorNone) {
+ buffer_allocator_.Deinit();
DLOGE("Display core initialization failed. Error = %d", error);
return -EINVAL;
}
+ g_hwc_uevent_.Register(this);
+
// If HDMI display is primary display, defer display creation until hotplug event is received.
HWDisplayInterfaceInfo hw_disp_info = {};
error = core_intf_->GetFirstDisplayInterfaceType(&hw_disp_info);
if (error != kErrorNone) {
+ g_hwc_uevent_.Register(nullptr);
CoreInterface::DestroyCore();
+ buffer_allocator_.Deinit();
DLOGE("Primary display type not recognized. Error = %d", error);
return -EINVAL;
}
@@ -132,7 +203,9 @@
}
if (status) {
+ g_hwc_uevent_.Register(nullptr);
CoreInterface::DestroyCore();
+ buffer_allocator_.Deinit();
return status;
}
@@ -146,9 +219,6 @@
}
}
- std::thread uevent_thread(HWCUeventThread, this);
- uevent_thread_.swap(uevent_thread);
-
return 0;
}
@@ -167,10 +237,7 @@
color_mgr_->DestroyColorManager();
}
- DLOGD("Terminating uevent thread");
- uevent_thread_exit_ = true;
- // todo(user): add a local event to interrupt thread execution and join.
- uevent_thread_.detach();
+ g_hwc_uevent_.Register(nullptr);
DisplayError error = CoreInterface::DestroyCore();
if (error != kErrorNone) {
@@ -1238,52 +1305,26 @@
return (ret ? -EINVAL : 0);
}
-void *HWCSession::HWCUeventThread(void *context) {
- if (context) {
- return reinterpret_cast<HWCSession *>(context)->HWCUeventThreadHandler();
- }
-
- return NULL;
-}
-
-void *HWCSession::HWCUeventThreadHandler() {
- static char uevent_data[PAGE_SIZE];
- int length = 0;
- prctl(PR_SET_NAME, uevent_thread_name_, 0, 0, 0);
- setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
- if (!uevent_init()) {
- DLOGE("Failed to init uevent");
- pthread_exit(0);
- return NULL;
- }
-
- while (!uevent_thread_exit_) {
- // keep last 2 zeroes to ensure double 0 termination
- length = uevent_next_event(uevent_data, INT32(sizeof(uevent_data)) - 2);
-
- if (strcasestr(HWC_UEVENT_SWITCH_HDMI, uevent_data)) {
- DLOGI("Uevent HDMI = %s", uevent_data);
- int connected = GetEventValue(uevent_data, length, "SWITCH_STATE=");
- if (connected >= 0) {
- DLOGI("HDMI = %s", connected ? "connected" : "disconnected");
- if (HotPlugHandler(connected) == -1) {
- DLOGE("Failed handling Hotplug = %s", connected ? "connected" : "disconnected");
- }
+void HWCSession::UEventHandler(const char *uevent_data, int length) {
+ if (strcasestr(uevent_data, HWC_UEVENT_SWITCH_HDMI)) {
+ DLOGI("Uevent HDMI = %s", uevent_data);
+ int connected = GetEventValue(uevent_data, length, "SWITCH_STATE=");
+ if (connected >= 0) {
+ DLOGI("HDMI = %s", connected ? "connected" : "disconnected");
+ if (HotPlugHandler(connected) == -1) {
+ DLOGE("Failed handling Hotplug = %s", connected ? "connected" : "disconnected");
}
- } else if (strcasestr(HWC_UEVENT_GRAPHICS_FB0, uevent_data)) {
- DLOGI("Uevent FB0 = %s", uevent_data);
- int panel_reset = GetEventValue(uevent_data, length, "PANEL_ALIVE=");
- if (panel_reset == 0) {
- callbacks_.Refresh(0);
- reset_panel_ = true;
- }
- } else if (strcasestr(uevent_data, HWC_UEVENT_DRM_EXT_HOTPLUG)) {
- HandleExtHPD(uevent_data, length);
}
+ } else if (strcasestr(uevent_data, HWC_UEVENT_GRAPHICS_FB0)) {
+ DLOGI("Uevent FB0 = %s", uevent_data);
+ int panel_reset = GetEventValue(uevent_data, length, "PANEL_ALIVE=");
+ if (panel_reset == 0) {
+ callbacks_.Refresh(0);
+ reset_panel_ = true;
+ }
+ } else if (strcasestr(uevent_data, HWC_UEVENT_DRM_EXT_HOTPLUG)) {
+ HandleExtHPD(uevent_data, length);
}
- pthread_exit(0);
-
- return NULL;
}
void HWCSession::HandleExtHPD(const char *uevent_data, int length) {
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
index cd9831d..7d2a30c 100644
--- a/sdm/libs/hwc2/hwc_session.h
+++ b/sdm/libs/hwc2/hwc_session.h
@@ -23,7 +23,6 @@
#include <vendor/display/config/1.0/IDisplayConfig.h>
#include <core/core_interface.h>
#include <utils/locker.h>
-#include <thread>
#include "hwc_callbacks.h"
#include "hwc_layers.h"
@@ -39,7 +38,32 @@
using ::vendor::display::config::V1_0::IDisplayConfig;
using ::android::hardware::Return;
-class HWCSession : hwc2_device_t, public IDisplayConfig, public qClient::BnQClient {
+// Create a singleton uevent listener thread valid for life of hardware composer process.
+// This thread blocks on uevents poll inside uevent library implementation. This poll exits
+// only when there is a valid uevent, it can not be interrupted otherwise. Tieing life cycle
+// of this thread with HWC session cause HWC deinitialization to wait infinitely for the
+// thread to exit.
+class HWCUEventListener {
+ public:
+ virtual ~HWCUEventListener() {}
+ virtual void UEventHandler(const char *uevent_data, int length) = 0;
+};
+
+class HWCUEvent {
+ public:
+ HWCUEvent();
+ static void UEventThread(HWCUEvent *hwc_event);
+ void Register(HWCUEventListener *uevent_listener);
+ inline bool InitDone() { return init_done_; }
+
+ private:
+ std::mutex mutex_;
+ std::condition_variable caller_cv_;
+ HWCUEventListener *uevent_listener_ = nullptr;
+ bool init_done_ = false;
+};
+
+class HWCSession : hwc2_device_t, HWCUEventListener, IDisplayConfig, public qClient::BnQClient {
public:
struct HWCModuleMethods : public hw_module_methods_t {
HWCModuleMethods() { hw_module_methods_t::open = HWCSession::Open; }
@@ -120,9 +144,8 @@
int32_t *outCapabilities);
static hwc2_function_pointer_t GetFunction(struct hwc2_device *device, int32_t descriptor);
- // Uevent thread
- static void *HWCUeventThread(void *context);
- void *HWCUeventThreadHandler();
+ // Uevent handler
+ virtual void UEventHandler(const char *uevent_data, int length);
int GetEventValue(const char *uevent_data, int length, const char *event_info);
void HandleExtHPD(const char *uevent_data, int length);
int HotPlugHandler(bool connected);
@@ -192,9 +215,6 @@
CoreInterface *core_intf_ = nullptr;
HWCDisplay *hwc_display_[HWC_NUM_DISPLAY_TYPES] = {nullptr};
HWCCallbacks callbacks_;
- std::thread uevent_thread_;
- bool uevent_thread_exit_ = false;
- const char *uevent_thread_name_ = "HWC_UeventThread";
HWCBufferAllocator buffer_allocator_;
HWCBufferSyncHandler buffer_sync_handler_;
HWCColorManager *color_mgr_ = nullptr;
diff --git a/sdm/libs/hwc2/hwc_tonemapper.cpp b/sdm/libs/hwc2/hwc_tonemapper.cpp
index 3086fb4..a224e8d 100644
--- a/sdm/libs/hwc2/hwc_tonemapper.cpp
+++ b/sdm/libs/hwc2/hwc_tonemapper.cpp
@@ -188,8 +188,8 @@
// then SDM marks them for SDE Composition because the cached FB layer gets displayed.
// GPU count will be 0 in this case. Try to use the existing tone-mapped frame buffer.
// No ToneMap/Blit is required. Just update the buffer & acquire fence fd of FB layer.
- if (!tone_map_sessions_.empty()) {
- ToneMapSession *fb_tone_map_session = tone_map_sessions_.at(fb_session_index_);
+ if (!tone_map_sessions_.empty() && (fb_session_index_ >= 0)) {
+ ToneMapSession *fb_tone_map_session = tone_map_sessions_.at(UINT32(fb_session_index_));
fb_tone_map_session->UpdateBuffer(-1 /* acquire_fence */, &layer->input_buffer);
fb_tone_map_session->layer_index_ = INT(i);
fb_tone_map_session->acquired_ = true;
@@ -197,7 +197,7 @@
}
}
error = AcquireToneMapSession(layer, &session_index);
- fb_session_index_ = session_index;
+ fb_session_index_ = INT(session_index);
break;
default:
error = AcquireToneMapSession(layer, &session_index);
@@ -261,6 +261,13 @@
} else {
delete session;
it = tone_map_sessions_.erase(it);
+ int deleted_session = INT(session_index);
+ // If FB tonemap session gets deleted, reset fb_session_index_, else update it.
+ if (deleted_session == fb_session_index_) {
+ fb_session_index_ = -1;
+ } else if (deleted_session < fb_session_index_) {
+ fb_session_index_--;
+ }
}
}
}
@@ -271,7 +278,7 @@
delete tone_map_sessions_.back();
tone_map_sessions_.pop_back();
}
- fb_session_index_ = 0;
+ fb_session_index_ = -1;
}
}
@@ -282,6 +289,7 @@
}
void HWCToneMapper::DumpToneMapOutput(ToneMapSession *session, int *acquire_fd) {
+ DisplayError error = kErrorNone;
if (!dump_frame_count_) {
return;
}
@@ -297,6 +305,12 @@
}
}
+ error = buffer_allocator_->MapBuffer(target_buffer, *acquire_fd);
+ if (error != kErrorNone) {
+ DLOGE("MapBuffer failed, base addr = %x", target_buffer->base);
+ return;
+ }
+
size_t result = 0;
char dump_file_name[PATH_MAX];
snprintf(dump_file_name, sizeof(dump_file_name), "%s/frame_dump_primary"
diff --git a/sdm/libs/hwc2/hwc_tonemapper.h b/sdm/libs/hwc2/hwc_tonemapper.h
index e2c8ef4..8bef3b1 100644
--- a/sdm/libs/hwc2/hwc_tonemapper.h
+++ b/sdm/libs/hwc2/hwc_tonemapper.h
@@ -118,7 +118,7 @@
HWCBufferAllocator *buffer_allocator_ = nullptr;
uint32_t dump_frame_count_ = 0;
uint32_t dump_frame_index_ = 0;
- uint32_t fb_session_index_ = 0;
+ int fb_session_index_ = -1;
};
} // namespace sdm
diff --git a/sdm/libs/utils/debug.cpp b/sdm/libs/utils/debug.cpp
index 60ce0ac..ee881ef 100644
--- a/sdm/libs/utils/debug.cpp
+++ b/sdm/libs/utils/debug.cpp
@@ -177,6 +177,13 @@
return (value == 1);
}
+bool Debug::IsSrcSplitPreferred() {
+ int value = 0;
+ debug_.debug_handler_->GetProperty("sdm.debug.prefersplit", &value);
+
+ return (value == 1);
+}
+
DisplayError Debug::GetMixerResolution(uint32_t *width, uint32_t *height) {
char value[64] = {};