Merge "gralloc1: Check linear format"
diff --git a/gpu_tonemapper/Android.mk b/gpu_tonemapper/Android.mk
index 769d0ab..89bad79 100644
--- a/gpu_tonemapper/Android.mk
+++ b/gpu_tonemapper/Android.mk
@@ -4,6 +4,7 @@
include $(CLEAR_VARS)
LOCAL_COPY_HEADERS_TO := $(common_header_export_path)
LOCAL_COPY_HEADERS := TonemapFactory.h Tonemapper.h
+LOCAL_VENDOR_MODULE := true
include $(BUILD_COPY_HEADERS)
include $(CLEAR_VARS)
diff --git a/include/Android.mk b/include/Android.mk
index 6aacfb8..a72d5c3 100644
--- a/include/Android.mk
+++ b/include/Android.mk
@@ -2,6 +2,7 @@
include $(LOCAL_PATH)/../common.mk
include $(CLEAR_VARS)
+LOCAL_VENDOR_MODULE := true
LOCAL_COPY_HEADERS_TO := $(common_header_export_path)
LOCAL_COPY_HEADERS := color_metadata.h
@@ -9,7 +10,8 @@
include $(CLEAR_VARS)
#TODO move all exported headers to this directory
-LOCAL_MODULE := display_headers
+LOCAL_MODULE := display_headers
+LOCAL_VENDOR_MODULE := true
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) \
$(display_top)/libcopybit \
$(display_top)/libdrmutils \
diff --git a/libcopybit/Android.mk b/libcopybit/Android.mk
index a363b85..8396d51 100644
--- a/libcopybit/Android.mk
+++ b/libcopybit/Android.mk
@@ -16,6 +16,7 @@
include $(LOCAL_PATH)/../common.mk
include $(CLEAR_VARS)
+LOCAL_VENDOR_MODULE := true
LOCAL_COPY_HEADERS_TO := $(common_header_export_path)
LOCAL_COPY_HEADERS := copybit.h copybit_priv.h c2d2.h
#Copy the headers regardless of whether copybit is built
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index 5dc5e4b..ca2f6ff 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -407,8 +407,7 @@
uint32_t mmWidth;
uint32_t mmHeight;
uint32_t type;
- uint32_t num_modes;
- drmModeModeInfo *modes;
+ std::vector<drmModeModeInfo> modes;
DRMTopology topology;
std::string panel_name;
DRMPanelMode panel_mode;
diff --git a/libgralloc1/gr_buf_mgr.cpp b/libgralloc1/gr_buf_mgr.cpp
index 0ce2e09..584737d 100644
--- a/libgralloc1/gr_buf_mgr.cpp
+++ b/libgralloc1/gr_buf_mgr.cpp
@@ -49,13 +49,6 @@
map_fb_mem_ = true;
}
- // Enable UBWC for framebuffer
- if ((property_get("debug.gralloc.enable_fb_ubwc", property, NULL) > 0) &&
- (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
- (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
- ubwc_for_fb_ = true;
- }
-
handles_map_.clear();
allocator_ = new Allocator();
allocator_->Init();
diff --git a/libgralloc1/gr_buf_mgr.h b/libgralloc1/gr_buf_mgr.h
index 4476eaf..861a7a7 100644
--- a/libgralloc1/gr_buf_mgr.h
+++ b/libgralloc1/gr_buf_mgr.h
@@ -118,7 +118,6 @@
std::shared_ptr<Buffer> GetBufferFromHandleLocked(const private_handle_t *hnd);
bool map_fb_mem_ = false;
- bool ubwc_for_fb_ = false;
Allocator *allocator_ = NULL;
std::mutex buffer_lock_;
std::mutex descriptor_lock_;
diff --git a/libgralloc1/gralloc_priv.h b/libgralloc1/gralloc_priv.h
index 87604c6..2abdd84 100644
--- a/libgralloc1/gralloc_priv.h
+++ b/libgralloc1/gralloc_priv.h
@@ -78,6 +78,7 @@
#define GRALLOC_USAGE_PRIVATE_IOMMU_HEAP GRALLOC1_PRODUCER_USAGE_PRIVATE_IOMMU_HEAP
#define GRALLOC_USAGE_PRIVATE_WFD GRALLOC1_CONSUMER_USAGE_PRIVATE_WFD
#define GRALLOC_USAGE_PRIVATE_CAMERA_HEAP GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_HEAP
+#define GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY
#define GRALLOC_USAGE_PRIVATE_MM_HEAP 0x0
diff --git a/libqdutils/Android.mk b/libqdutils/Android.mk
index 60efb3a..5dac581 100644
--- a/libqdutils/Android.mk
+++ b/libqdutils/Android.mk
@@ -8,6 +8,7 @@
LOCAL_SHARED_LIBRARIES := $(common_libs) libbinder libqservice
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
LOCAL_HEADER_LIBRARIES := display_headers
+LOCAL_HEADER_LIBRARIES += libhardware_headers
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdutils\" -Wno-sign-conversion
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_COPY_HEADERS_TO := $(common_header_export_path)
diff --git a/sdm/include/private/color_params.h b/sdm/include/private/color_params.h
index 14ec40f..fdab206 100644
--- a/sdm/include/private/color_params.h
+++ b/sdm/include/private/color_params.h
@@ -89,7 +89,7 @@
static const std::string kSdr = "sdr";
static const std::string kNative = "native";
-static const std::string kDcip3 = "dci_p3";
+static const std::string kDcip3 = "dcip3";
static const std::string kSrgb = "srgb";
static const std::string kDisplayP3 = "display_p3";
diff --git a/sdm/libs/core/Android.mk b/sdm/libs/core/Android.mk
index cf3543c..bb3b71d 100644
--- a/sdm/libs/core/Android.mk
+++ b/sdm/libs/core/Android.mk
@@ -60,6 +60,7 @@
SDM_HEADER_PATH := ../../include
include $(CLEAR_VARS)
+LOCAL_VENDOR_MODULE := true
LOCAL_COPY_HEADERS_TO := $(common_header_export_path)/sdm/core
LOCAL_COPY_HEADERS = $(SDM_HEADER_PATH)/core/buffer_allocator.h \
$(SDM_HEADER_PATH)/core/buffer_sync_handler.h \
@@ -74,6 +75,7 @@
include $(BUILD_COPY_HEADERS)
include $(CLEAR_VARS)
+LOCAL_VENDOR_MODULE := true
LOCAL_COPY_HEADERS_TO := $(common_header_export_path)/sdm/private
LOCAL_COPY_HEADERS = $(SDM_HEADER_PATH)/private/color_interface.h \
$(SDM_HEADER_PATH)/private/color_params.h \
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index 965ff3b..391e699 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -55,6 +55,7 @@
virtual DisplayError Init();
virtual DisplayError Deinit();
void GetDRMDisplayToken(sde_drm::DRMDisplayToken *token) const;
+ bool IsPrimaryDisplay() const { return hw_panel_info_.is_primary_panel; }
protected:
// From HWInterface
diff --git a/sdm/libs/core/drm/hw_events_drm.cpp b/sdm/libs/core/drm/hw_events_drm.cpp
index 7487c8a..33f4d3d 100644
--- a/sdm/libs/core/drm/hw_events_drm.cpp
+++ b/sdm/libs/core/drm/hw_events_drm.cpp
@@ -62,6 +62,11 @@
switch (event_data.event_type) {
case HWEvent::VSYNC: {
+ if (!is_primary_) {
+ // TODO(user): Once secondary support is added, use a different fd by calling drmOpen
+ break;
+ }
+
poll_fds_[i].events = POLLIN | POLLPRI | POLLERR;
DRMMaster *master = nullptr;
int ret = DRMMaster::GetInstance(&master);
@@ -146,6 +151,8 @@
return kErrorParameters;
static_cast<const HWDeviceDRM *>(hw_intf)->GetDRMDisplayToken(&token_);
+ is_primary_ = static_cast<const HWDeviceDRM *>(hw_intf)->IsPrimaryDisplay();
+ vsync_enabled_ = is_primary_;
DLOGI("Setup event handler for display %d, CRTC %d, Connector %d",
display_type, token_.crtc_id, token_.conn_id);
@@ -177,6 +184,9 @@
DisplayError HWEventsDRM::SetEventState(HWEvent event, bool enable, void *arg) {
switch (event) {
case HWEvent::VSYNC:
+ if (!is_primary_) {
+ break;
+ }
vsync_enabled_ = enable;
if (enable) {
WakeUpEventThread();
@@ -208,6 +218,7 @@
for (uint32_t i = 0; i < event_data_list_.size(); i++) {
switch (event_data_list_[i].event_type) {
case HWEvent::VSYNC:
+ // TODO(user): close for secondary
poll_fds_[i].fd = -1;
break;
case HWEvent::EXIT:
@@ -287,6 +298,7 @@
}
DisplayError HWEventsDRM::RegisterVSync() {
+ // TODO(user): For secondary use DRM_VBLANK_HIGH_CRTC_MASK and DRM_VBLANK_HIGH_CRTC_SHIFT
drmVBlank vblank{};
vblank.request.type = (drmVBlankSeqType)(DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT);
vblank.request.sequence = 1;
diff --git a/sdm/libs/core/drm/hw_events_drm.h b/sdm/libs/core/drm/hw_events_drm.h
index 206751b..1d04153 100644
--- a/sdm/libs/core/drm/hw_events_drm.h
+++ b/sdm/libs/core/drm/hw_events_drm.h
@@ -89,8 +89,9 @@
std::string event_thread_name_ = "SDM_EventThread";
bool exit_threads_ = false;
uint32_t vsync_index_ = 0;
- bool vsync_enabled_ = true;
+ bool vsync_enabled_ = false;
sde_drm::DRMDisplayToken token_ = {};
+ bool is_primary_ = false;
};
} // namespace sdm
diff --git a/sdm/libs/core/drm/hw_tv_drm.cpp b/sdm/libs/core/drm/hw_tv_drm.cpp
index 0262915..67485f1 100644
--- a/sdm/libs/core/drm/hw_tv_drm.cpp
+++ b/sdm/libs/core/drm/hw_tv_drm.cpp
@@ -104,7 +104,7 @@
}
DisplayError HWTVDRM::GetNumDisplayAttributes(uint32_t *count) {
- *count = connector_info_.num_modes;
+ *count = UINT32(connector_info_.modes.size());
if (*count <= 0) {
return kErrorHardware;
}
@@ -118,7 +118,7 @@
}
DisplayError HWTVDRM::SetDisplayAttributes(uint32_t index) {
- if (index >= connector_info_.num_modes) {
+ if (index >= connector_info_.modes.size()) {
return kErrorNotSupported;
}
@@ -162,7 +162,7 @@
format = UINT32(stoi(str4.substr(str4.find(':') + 1)));
}
- for (size_t idex = 0; idex < connector_info_.num_modes; idex ++) {
+ for (size_t idex = 0; idex < connector_info_.modes.size(); idex ++) {
if ((height == connector_info_.modes[idex].vdisplay) &&
(width == connector_info_.modes[idex].hdisplay) &&
(fps == connector_info_.modes[idex].vrefresh)) {
diff --git a/sdm/libs/core/drm/hw_virtual_drm.cpp b/sdm/libs/core/drm/hw_virtual_drm.cpp
index 8513e82..5ea76b0 100644
--- a/sdm/libs/core/drm/hw_virtual_drm.cpp
+++ b/sdm/libs/core/drm/hw_virtual_drm.cpp
@@ -121,7 +121,7 @@
}
void HWVirtualDRM::DumpConfigs() {
- for (uint32_t i = 0; i < (uint32_t)connector_info_.num_modes; i++) {
+ for (uint32_t i = 0; i < (uint32_t)connector_info_.modes.size(); i++) {
DLOGI(
"Name: %s\tvref: %d\thdisp: %d\t hsync_s: %d\thsync_e:%d\thtotal: %d\t"
"vdisp: %d\tvsync_s: %d\tvsync_e: %d\tvtotal: %d\n",
diff --git a/sdm/libs/core/fb/hw_device.cpp b/sdm/libs/core/fb/hw_device.cpp
index 4931e1b..eb0d17b 100644
--- a/sdm/libs/core/fb/hw_device.cpp
+++ b/sdm/libs/core/fb/hw_device.cpp
@@ -46,6 +46,7 @@
#include <vector>
#include <algorithm>
#include <string>
+#include <sstream>
#include "hw_device.h"
#include "hw_primary.h"
@@ -1363,7 +1364,14 @@
DLOGW("Pingpong timeout occurred in the driver.");
#ifdef USER_DEBUG
// Save the xlogs on ping pong time out
- std::ofstream dst("/data/vendor/display/mdp_xlog");
+ const char* xlog_path = "/data/vendor/display/mdp_xlog";
+ DLOGD("Dumping debugfs data to %s", xlog_path);
+ std::ostringstream dst;
+ auto file = open(xlog_path, O_CREAT | O_TRUNC | O_DSYNC | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP);
+ if (file < 0) {
+ DLOGE("Couldn't open file: err:%d (%s)", errno, strerror(errno));
+ return kErrorResources;
+ }
dst << "+++ MDP:XLOG +++" << std::endl;
std::ifstream src("/sys/kernel/debug/mdp/xlog/dump");
dst << src.rdbuf() << std::endl;
@@ -1383,6 +1391,14 @@
src.open("/sys/kernel/debug/mdp/xlog/vbif_dbgbus_xlog");
dst << src.rdbuf() << std::endl;
src.close();
+ auto ret = write(file, dst.str().c_str(), dst.str().size());
+ if (ret < 0) {
+ DLOGE("Failed to write xlog data err: %d (%s)", errno, strerror(errno));
+ } else {
+ fsync(file);
+ }
+ close(file);
+ DLOGD("Finished dumping xlogs");;
#endif
return kErrorNone;
}
diff --git a/sdm/libs/hwc2/hwc_buffer_allocator.cpp b/sdm/libs/hwc2/hwc_buffer_allocator.cpp
index 4865e08..eb932e3 100644
--- a/sdm/libs/hwc2/hwc_buffer_allocator.cpp
+++ b/sdm/libs/hwc2/hwc_buffer_allocator.cpp
@@ -153,6 +153,9 @@
if (alloc_type & GRALLOC_USAGE_HW_FB) {
consumer_usage = GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET;
}
+ if (alloc_type & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) {
+ producer_usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
+ }
Perform_(gralloc_device_, GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES, width, height, format,
producer_usage, consumer_usage, aligned_width, aligned_height, &tile_enabled);
diff --git a/sdm/libs/hwc2/hwc_callbacks.cpp b/sdm/libs/hwc2/hwc_callbacks.cpp
index 48ae398..48593f1 100644
--- a/sdm/libs/hwc2/hwc_callbacks.cpp
+++ b/sdm/libs/hwc2/hwc_callbacks.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-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
@@ -34,22 +34,29 @@
namespace sdm {
-void HWCCallbacks::Hotplug(hwc2_display_t display, HWC2::Connection state) {
- if (hotplug_) {
- hotplug_(hotplug_data_, display, INT32(state));
+HWC2::Error HWCCallbacks::Hotplug(hwc2_display_t display, HWC2::Connection state) {
+ if (!hotplug_) {
+ return HWC2::Error::NoResources;
}
+ hotplug_(hotplug_data_, display, INT32(state));
+ return HWC2::Error::None;
}
-void HWCCallbacks::Refresh(hwc2_display_t display) {
- if (refresh_) {
- refresh_(refresh_data_, display);
+HWC2::Error HWCCallbacks::Refresh(hwc2_display_t display) {
+ if (!refresh_) {
+ return HWC2::Error::NoResources;
}
+ refresh_(refresh_data_, display);
+ return HWC2::Error::None;
}
-void HWCCallbacks::Vsync(hwc2_display_t display, int64_t timestamp) {
- if (vsync_) {
- vsync_(vsync_data_, display, timestamp);
+HWC2::Error HWCCallbacks::Vsync(hwc2_display_t display, int64_t timestamp) {
+ if (!vsync_) {
+ return HWC2::Error::NoResources;
}
+ DTRACE_SCOPED();
+ vsync_(vsync_data_, display, timestamp);
+ return HWC2::Error::None;
}
HWC2::Error HWCCallbacks::Register(HWC2::Callback descriptor, hwc2_callback_data_t callback_data,
diff --git a/sdm/libs/hwc2/hwc_callbacks.h b/sdm/libs/hwc2/hwc_callbacks.h
index 015bf5d..d3f4e52 100644
--- a/sdm/libs/hwc2/hwc_callbacks.h
+++ b/sdm/libs/hwc2/hwc_callbacks.h
@@ -40,9 +40,9 @@
class HWCCallbacks {
public:
- void Hotplug(hwc2_display_t display, HWC2::Connection state);
- void Refresh(hwc2_display_t display);
- void Vsync(hwc2_display_t display, int64_t timestamp);
+ HWC2::Error Hotplug(hwc2_display_t display, HWC2::Connection state);
+ HWC2::Error Refresh(hwc2_display_t display);
+ HWC2::Error Vsync(hwc2_display_t display, int64_t timestamp);
HWC2::Error Register(HWC2::Callback, hwc2_callback_data_t callback_data,
hwc2_function_pointer_t pointer);
diff --git a/sdm/libs/hwc2/hwc_color_manager.cpp b/sdm/libs/hwc2/hwc_color_manager.cpp
index 6f33a6d..d753fdc 100644
--- a/sdm/libs/hwc2/hwc_color_manager.cpp
+++ b/sdm/libs/hwc2/hwc_color_manager.cpp
@@ -404,8 +404,8 @@
};
if (socket_fd_ < 0) {
- DLOGW("No socket connection available!");
- return -EFAULT;
+ DLOGW("No socket connection available - assuming dpps is not enabled");
+ return 0;
}
if (!enable) { // if client requesting to disable it.
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index f7a9dec..05840d3 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -102,11 +102,16 @@
}
HWC2::Error HWCColorMode::SetColorMode(android_color_mode_t mode) {
+ DTRACE_SCOPED();
// first mode in 2D matrix is the mode (identity)
- if (color_mode_transform_map_.find(mode) == color_mode_transform_map_.end()) {
+ if (mode < HAL_COLOR_MODE_NATIVE || mode > HAL_COLOR_MODE_DISPLAY_P3) {
DLOGE("Could not find mode: %d", mode);
return HWC2::Error::BadParameter;
}
+ if (color_mode_transform_map_.find(mode) == color_mode_transform_map_.end()) {
+ return HWC2::Error::Unsupported;
+ }
+
auto status = HandleColorModeTransform(mode, current_color_transform_, color_matrix_);
if (status != HWC2::Error::None) {
DLOGE("failed for mode = %d", mode);
@@ -125,10 +130,12 @@
}
HWC2::Error HWCColorMode::SetColorTransform(const float *matrix, android_color_transform_t hint) {
- if (!matrix) {
+ if (!matrix || (hint < HAL_COLOR_TRANSFORM_IDENTITY ||
+ hint > HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA)) {
return HWC2::Error::BadParameter;
}
+ DTRACE_SCOPED();
double color_matrix[kColorTransformMatrixCount] = {0};
CopyColorTransformMatrix(matrix, color_matrix);
@@ -208,8 +215,8 @@
DLOGV_IF(kTagQDCM, "Color Mode[%d] = %s", i, mode_string.c_str());
AttrVal attr;
error = display_intf_->GetColorModeAttr(mode_string, &attr);
+ std::string color_gamut, dynamic_range, pic_quality;
if (!attr.empty()) {
- std::string color_gamut, dynamic_range, pic_quality;
for (auto &it : attr) {
if (it.first.find(kColorGamutAttribute) != std::string::npos) {
color_gamut = it.second;
@@ -230,12 +237,15 @@
PopulateTransform(HAL_COLOR_MODE_SRGB, mode_string, color_transform);
} else if ((color_gamut == kDcip3) &&
(pic_quality.empty() || pic_quality == kStandard)) {
- PopulateTransform(HAL_COLOR_MODE_DCI_P3, mode_string, color_transform);
+ PopulateTransform(HAL_COLOR_MODE_DISPLAY_P3, mode_string, color_transform);
} else if ((color_gamut == kDisplayP3) &&
(pic_quality.empty() || pic_quality == kStandard)) {
PopulateTransform(HAL_COLOR_MODE_DISPLAY_P3, mode_string, color_transform);
}
- } else {
+ }
+
+ // Look at the mode name, if no color gamut is found
+ if (color_gamut.empty()) {
if (mode_string.find("hal_native") != std::string::npos) {
PopulateTransform(HAL_COLOR_MODE_NATIVE, mode_string, mode_string);
} else if (mode_string.find("hal_srgb") != std::string::npos) {
@@ -622,6 +632,7 @@
HWC2::Error HWCDisplay::SetVsyncEnabled(HWC2::Vsync enabled) {
DLOGV("Display ID: %d enabled: %s", id_, to_string(enabled).c_str());
+ ATRACE_INT("SetVsyncState ", enabled == HWC2::Vsync::Enable ? 1 : 0);
DisplayError error = kErrorNone;
if (shutdown_pending_ || !callbacks_->VsyncCallbackRegistered()) {
@@ -685,6 +696,7 @@
return HWC2::Error::BadParameter;
}
+ ATRACE_INT("SetPowerMode ", state);
DisplayError error = display_intf_->SetDisplayState(state);
if (error == kErrorNone) {
flush_on_error_ = flush_on_error;
@@ -740,9 +752,18 @@
HWC2::Error HWCDisplay::GetDisplayAttribute(hwc2_config_t config, HWC2::Attribute attribute,
int32_t *out_value) {
DisplayConfigVariableInfo variable_config;
- if (GetDisplayAttributesForConfig(INT(config), &variable_config) != kErrorNone) {
- DLOGE("Get variable config failed");
- return HWC2::Error::BadDisplay;
+ // Get display attributes from config index only if resolution switch is supported.
+ // Otherwise always send mixer attributes. This is to support destination scaler.
+ if (num_configs_ > 1) {
+ if (GetDisplayAttributesForConfig(INT(config), &variable_config) != kErrorNone) {
+ DLOGE("Get variable config failed");
+ return HWC2::Error::BadDisplay;
+ }
+ } else {
+ if (display_intf_->GetFrameBufferConfig(&variable_config) != kErrorNone) {
+ DLOGV("Get variable config failed");
+ return HWC2::Error::BadDisplay;
+ }
}
switch (attribute) {
@@ -981,6 +1002,7 @@
DLOGW("Display is not validated");
return HWC2::Error::NotValidated;
}
+
*out_num_elements = UINT32(layer_changes_.size());
if (out_layers != nullptr && out_types != nullptr) {
int i = 0;
@@ -1010,18 +1032,19 @@
HWC2::Error HWCDisplay::GetDisplayRequests(int32_t *out_display_requests,
uint32_t *out_num_elements, hwc2_layer_t *out_layers,
int32_t *out_layer_requests) {
- // No display requests for now
- // Use for sharing blit buffers and
- // writing wfd buffer directly to output if there is full GPU composition
- // and no color conversion needed
if (layer_set_.empty()) {
return HWC2::Error::None;
}
+ // No display requests for now
+ // Use for sharing blit buffers and
+ // writing wfd buffer directly to output if there is full GPU composition
+ // and no color conversion needed
if (!validated_) {
DLOGW("Display is not validated");
return HWC2::Error::NotValidated;
}
+
*out_display_requests = 0;
*out_num_elements = UINT32(layer_requests_.size());
if (out_layers != nullptr && out_layer_requests != nullptr) {
@@ -1480,10 +1503,13 @@
int aligned_height;
uint32_t usage = GRALLOC_USAGE_HW_FB;
int format = HAL_PIXEL_FORMAT_RGBA_8888;
- int ubwc_enabled = 0;
+ int ubwc_disabled = 0;
int flags = 0;
- HWCDebugHandler::Get()->GetProperty("debug.gralloc.enable_fb_ubwc", &ubwc_enabled);
- if (ubwc_enabled == 1) {
+
+ // By default UBWC is enabled and below property is global enable/disable for all
+ // buffers allocated through gralloc , including framebuffer targets.
+ HWCDebugHandler::Get()->GetProperty("debug.gralloc.gfx_ubwc_disable", &ubwc_disabled);
+ if (!ubwc_disabled) {
usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
}
@@ -1564,9 +1590,18 @@
return HWC2::Error::None;
}
- if (GetHWCLayer(layer) == nullptr) {
+ HWCLayer *hwc_layer = GetHWCLayer(layer);
+ if (hwc_layer == nullptr) {
return HWC2::Error::BadLayer;
}
+ if (hwc_layer->GetDeviceSelectedCompositionType() != HWC2::Composition::Cursor) {
+ return HWC2::Error::None;
+ }
+ if (validated_ == true) {
+ // the device is currently in the middle of the validate/present sequence,
+ // cannot set the Position(as per HWC2 spec)
+ return HWC2::Error::NotValidated;
+ }
DisplayState state;
if (display_intf_->GetDisplayState(&state) == kErrorNone) {
@@ -1575,9 +1610,9 @@
}
}
- if (!validated_) {
- return HWC2::Error::NotValidated;
- }
+ // TODO(user): HWC1.5 was not letting SetCursorPosition before validateDisplay,
+ // but HWC2.0 doesn't let setting cursor position after validate before present.
+ // Need to revisit.
auto error = display_intf_->SetCursorPosition(x, y);
if (error != kErrorNone) {
diff --git a/sdm/libs/hwc2/hwc_layers.cpp b/sdm/libs/hwc2/hwc_layers.cpp
index 6b5d470..dba00b4 100644
--- a/sdm/libs/hwc2/hwc_layers.cpp
+++ b/sdm/libs/hwc2/hwc_layers.cpp
@@ -198,6 +198,9 @@
}
HWC2::Error HWCLayer::SetLayerColor(hwc_color_t color) {
+ if (client_requested_ != HWC2::Composition::SolidColor) {
+ return HWC2::Error::None;
+ }
layer_->solid_fill_color = GetUint32Color(color);
layer_->input_buffer.format = kFormatARGB8888;
DLOGV_IF(kTagCompManager, "[%" PRIu64 "][%" PRIu64 "] Layer color set to %x", display_id_, id_,
@@ -582,7 +585,7 @@
}
}
- uint32_t fps = 0;
+ float fps = 0;
if (getMetaData(handle, GET_REFRESH_RATE , &fps) == 0) {
layer->frame_rate = RoundToStandardFPS(fps);
}
diff --git a/sdm/libs/hwc2/hwc_layers.h b/sdm/libs/hwc2/hwc_layers.h
index 30fc362..25ec4dc 100644
--- a/sdm/libs/hwc2/hwc_layers.h
+++ b/sdm/libs/hwc2/hwc_layers.h
@@ -119,7 +119,7 @@
};
struct SortLayersByZ {
- bool operator()(const HWCLayer *lhs, const HWCLayer *rhs) {
+ bool operator()(const HWCLayer *lhs, const HWCLayer *rhs) const {
return lhs->GetZ() < rhs->GetZ();
}
};
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index 293ffce..3fce394 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -344,7 +344,7 @@
int32_t HWCSession::DestroyVirtualDisplay(hwc2_device_t *device, hwc2_display_t display) {
SCOPE_LOCK(locker_);
- if (!device) {
+ if (!device || display != HWC_DISPLAY_VIRTUAL) {
return HWC2_ERROR_BAD_DISPLAY;
}
@@ -502,16 +502,16 @@
if (!device) {
return HWC2_ERROR_BAD_DISPLAY;
}
+ SCOPE_LOCK(hwc_session->callbacks_lock_);
auto desc = static_cast<HWC2::Callback>(descriptor);
auto error = hwc_session->callbacks_.Register(desc, callback_data, pointer);
DLOGD("Registering callback: %s", to_string(desc).c_str());
if (descriptor == HWC2_CALLBACK_HOTPLUG) {
- // If primary display (HDMI) is not created yet, wait for it to be hotplugged.
- if (hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ if (hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY] && !hwc_session->hdmi_is_primary_) {
hwc_session->callbacks_.Hotplug(HWC_DISPLAY_PRIMARY, HWC2::Connection::Connected);
}
}
-
+ hwc_session->callbacks_lock_.Broadcast();
return INT32(error);
}
@@ -633,8 +633,12 @@
return HWC2_ERROR_BAD_DISPLAY;
}
+ if (display != HWC_DISPLAY_VIRTUAL) {
+ return HWC2_ERROR_UNSUPPORTED;
+ }
+
auto *hwc_session = static_cast<HWCSession *>(device);
- if (display == HWC_DISPLAY_VIRTUAL && hwc_session->hwc_display_[display]) {
+ if (hwc_session->hwc_display_[display]) {
auto vds = reinterpret_cast<HWCDisplayVirtual *>(hwc_session->hwc_display_[display]);
auto status = vds->SetOutputBuffer(buffer, releaseFence);
return INT32(status);
@@ -675,7 +679,7 @@
}
if (hwc_session->need_invalidate_) {
- hwc_session->callbacks_.Refresh(display);
+ hwc_session->Refresh(display);
}
if (hwc_session->color_mgr_) {
@@ -1161,6 +1165,11 @@
auto display = static_cast<hwc2_display_t >(input_parcel->readInt32());
auto mode = input_parcel->readInt32();
auto device = static_cast<hwc2_device_t *>(this);
+
+ if (display > HWC_DISPLAY_VIRTUAL) {
+ return -EINVAL;
+ }
+
auto err = CallDisplayFunction(device, display, &HWCDisplay::SetColorModeById, mode);
if (err != HWC2_ERROR_NONE)
return -EINVAL;
@@ -1248,7 +1257,7 @@
switch (pending_action.action) {
case kInvalidating:
- callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+ Refresh(HWC_DISPLAY_PRIMARY);
break;
case kEnterQDCMMode:
ret = color_mgr_->EnableQDCMMode(true, hwc_display_[HWC_DISPLAY_PRIMARY]);
@@ -1259,12 +1268,12 @@
case kApplySolidFill:
ret =
color_mgr_->SetSolidFill(pending_action.params, true, hwc_display_[HWC_DISPLAY_PRIMARY]);
- callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+ Refresh(HWC_DISPLAY_PRIMARY);
break;
case kDisableSolidFill:
ret =
color_mgr_->SetSolidFill(pending_action.params, false, hwc_display_[HWC_DISPLAY_PRIMARY]);
- callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+ Refresh(HWC_DISPLAY_PRIMARY);
break;
case kSetPanelBrightness:
brightness_value = reinterpret_cast<int32_t *>(resp_payload.payload);
@@ -1278,7 +1287,7 @@
case kEnableFrameCapture:
ret = color_mgr_->SetFrameCapture(pending_action.params, true,
hwc_display_[HWC_DISPLAY_PRIMARY]);
- callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+ Refresh(HWC_DISPLAY_PRIMARY);
break;
case kDisableFrameCapture:
ret = color_mgr_->SetFrameCapture(pending_action.params, false,
@@ -1287,7 +1296,7 @@
case kConfigureDetailedEnhancer:
ret = color_mgr_->SetDetailedEnhancer(pending_action.params,
hwc_display_[HWC_DISPLAY_PRIMARY]);
- callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+ Refresh(HWC_DISPLAY_PRIMARY);
break;
case kNoAction:
break;
@@ -1319,7 +1328,7 @@
DLOGI("Uevent FB0 = %s", uevent_data);
int panel_reset = GetEventValue(uevent_data, length, "PANEL_ALIVE=");
if (panel_reset == 0) {
- callbacks_.Refresh(0);
+ Refresh(0);
reset_panel_ = true;
}
} else if (strcasestr(uevent_data, HWC_UEVENT_DRM_EXT_HOTPLUG)) {
@@ -1445,7 +1454,7 @@
} while (0);
if (connected) {
- callbacks_.Refresh(0);
+ Refresh(0);
if (!hdmi_is_primary_) {
// wait for sufficient time to ensure sufficient resources are available to process new
@@ -1457,8 +1466,8 @@
// notify client
if (notify_hotplug) {
- callbacks_.Hotplug(hdmi_is_primary_ ? HWC_DISPLAY_PRIMARY : HWC_DISPLAY_EXTERNAL,
- connected ? HWC2::Connection::Connected : HWC2::Connection::Disconnected);
+ HotPlug(hdmi_is_primary_ ? HWC_DISPLAY_PRIMARY : HWC_DISPLAY_EXTERNAL,
+ connected ? HWC2::Connection::Connected : HWC2::Connection::Disconnected);
}
qservice_->onHdmiHotplug(INT(connected));
@@ -1507,4 +1516,22 @@
return android::NO_ERROR;
}
+void HWCSession::Refresh(hwc2_display_t display) {
+ SCOPE_LOCK(callbacks_lock_);
+ HWC2::Error err = callbacks_.Refresh(display);
+ while (err != HWC2::Error::None) {
+ callbacks_lock_.Wait();
+ err = callbacks_.Refresh(display);
+ }
+}
+
+void HWCSession::HotPlug(hwc2_display_t display, HWC2::Connection state) {
+ SCOPE_LOCK(callbacks_lock_);
+ HWC2::Error err = callbacks_.Hotplug(display, state);
+ while (err != HWC2::Error::None) {
+ callbacks_lock_.Wait();
+ err = callbacks_.Hotplug(display, state);
+ }
+}
+
} // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
index 7d2a30c..288bbba 100644
--- a/sdm/libs/hwc2/hwc_session.h
+++ b/sdm/libs/hwc2/hwc_session.h
@@ -211,6 +211,9 @@
android::status_t SetColorModeById(const android::Parcel *input_parcel);
+ void Refresh(hwc2_display_t display);
+ void HotPlug(hwc2_display_t display, HWC2::Connection state);
+
static Locker locker_;
CoreInterface *core_intf_ = nullptr;
HWCDisplay *hwc_display_[HWC_NUM_DISPLAY_TYPES] = {nullptr};
@@ -227,6 +230,7 @@
qService::QService *qservice_ = nullptr;
HWCSocketHandler socket_handler_;
bool hdmi_is_primary_ = false;
+ Locker callbacks_lock_;
};
} // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_session_services.cpp b/sdm/libs/hwc2/hwc_session_services.cpp
index 5cb9cf7..383ec3b 100644
--- a/sdm/libs/hwc2/hwc_session_services.cpp
+++ b/sdm/libs/hwc2/hwc_session_services.cpp
@@ -208,7 +208,7 @@
if (hwc_display_[disp_id]) {
error = hwc_display_[disp_id]->SetActiveDisplayConfig(config);
if (!error) {
- callbacks_.Refresh(0);
+ Refresh(0);
}
}
@@ -312,7 +312,7 @@
Return<int32_t> HWCSession::refreshScreen() {
SCOPE_LOCK(locker_);
- callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+ Refresh(HWC_DISPLAY_PRIMARY);
return 0;
}
@@ -349,7 +349,7 @@
}
// Todo(user): Unlock it before sending events to client. It may cause deadlocks in future.
- callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+ Refresh(HWC_DISPLAY_PRIMARY);
// Wait until partial update control is complete
int32_t error = locker_.WaitFinite(kPartialUpdateControlTimeoutMs);
@@ -443,7 +443,7 @@
HWBwModes mode = on > 0 ? kBwCamera : kBwDefault;
// trigger invalidate to apply new bw caps.
- callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+ Refresh(HWC_DISPLAY_PRIMARY);
if (core_intf_->SetMaxBandwidthMode(mode) != kErrorNone) {
return -EINVAL;
diff --git a/sdm/libs/utils/Android.mk b/sdm/libs/utils/Android.mk
index 09e1414..481ea39 100644
--- a/sdm/libs/utils/Android.mk
+++ b/sdm/libs/utils/Android.mk
@@ -18,6 +18,7 @@
SDM_HEADER_PATH := ../../include
include $(CLEAR_VARS)
+LOCAL_VENDOR_MODULE := true
LOCAL_COPY_HEADERS_TO := $(common_header_export_path)/sdm/utils
LOCAL_COPY_HEADERS = $(SDM_HEADER_PATH)/utils/constants.h \
$(SDM_HEADER_PATH)/utils/debug.h \