Merge "gralloc1: Add support to provide interlace info"
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index 46ab782..71767e7 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -218,6 +218,7 @@
enum struct DRMRotation {
FLIP_H = 0x1,
FLIP_V = 0x2,
+ ROT_180 = FLIP_H | FLIP_V,
ROT_90 = 0x4,
};
@@ -358,6 +359,7 @@
int wmin;
int hmin;
bool roi_merge;
+ DRMRotation panel_orientation;
};
/* Identifier token for a display */
diff --git a/libgralloc/Makefile.am b/libgralloc/Makefile.am
index d57ad32..3cf3960 100644
--- a/libgralloc/Makefile.am
+++ b/libgralloc/Makefile.am
@@ -1,11 +1,12 @@
+HEADER_PATH := ${WORKSPACE}/display/display-hal/include
h_sources = alloc_controller.h \
memalloc.h
cpp_sources = ionalloc.cpp \
alloc_controller.cpp
-library_includedir = $(pkgincludedir)
-library_include_HEADERS = $(h_sources)
+memalloc_includedir = $(pkgincludedir)
+memalloc_include_HEADERS = $(h_sources)
lib_LTLIBRARIES = libmemalloc.la
libmemalloc_la_CC = @CC@
@@ -17,7 +18,9 @@
libmemalloc_la_LDFLAGS = -shared -avoid-version
header_sources = gralloc_priv.h \
- gr.h
+ gr.h \
+ adreno_utils.h \
+ $(HEADER_PATH)/color_metadata.h
c_sources = gpu.cpp \
gralloc.cpp \
@@ -36,4 +39,4 @@
libgralloc_la_LIBADD += ../libqdutils/libqdMetaData.la
libgralloc_la_LIBADD += -lhardware -lcutils -llog -lutils -lbinder
libgralloc_la_LIBADD += libmemalloc.la
-libgralloc_la_LDFLAGS = -shared -avoid-version
\ No newline at end of file
+libgralloc_la_LDFLAGS = -shared -avoid-version
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 1779312..d2a522e 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -247,6 +247,8 @@
aligned_w = ALIGN(width, alignment);
break;
case HAL_PIXEL_FORMAT_RAW16:
+ case HAL_PIXEL_FORMAT_Y16:
+ case HAL_PIXEL_FORMAT_Y8:
aligned_w = ALIGN(width, 16);
break;
case HAL_PIXEL_FORMAT_RAW12:
@@ -564,6 +566,7 @@
case HAL_PIXEL_FORMAT_RGBA_5551:
case HAL_PIXEL_FORMAT_RGBA_4444:
case HAL_PIXEL_FORMAT_RAW16:
+ case HAL_PIXEL_FORMAT_Y16:
size = alignedw * alignedh * 2;
break;
case HAL_PIXEL_FORMAT_RAW12:
@@ -573,6 +576,7 @@
size = ALIGN(alignedw * alignedh, 4096);
break;
case HAL_PIXEL_FORMAT_RAW8:
+ case HAL_PIXEL_FORMAT_Y8:
size = alignedw * alignedh;
break;
// adreno formats
@@ -815,9 +819,11 @@
case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
case HAL_PIXEL_FORMAT_NV21_ZSL:
case HAL_PIXEL_FORMAT_RAW16:
+ case HAL_PIXEL_FORMAT_Y16:
case HAL_PIXEL_FORMAT_RAW12:
case HAL_PIXEL_FORMAT_RAW10:
case HAL_PIXEL_FORMAT_RAW8:
+ case HAL_PIXEL_FORMAT_Y8:
getYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
std::swap(ycbcr->cb, ycbcr->cr);
break;
diff --git a/libgralloc1/gr_buf_mgr.cpp b/libgralloc1/gr_buf_mgr.cpp
index 72ff9dc..7e0ba14 100644
--- a/libgralloc1/gr_buf_mgr.cpp
+++ b/libgralloc1/gr_buf_mgr.cpp
@@ -211,11 +211,10 @@
return GRALLOC1_ERROR_BAD_HANDLE;
}
- // TODO(user): delete handle once framework bug around this is confirmed
- // to be resolved. This is tracked in bug 36355756
private_handle_t * handle = const_cast<private_handle_t *>(hnd);
handle->fd = -1;
handle->fd_metadata = -1;
+ delete handle;
return GRALLOC1_ERROR_NONE;
}
@@ -278,6 +277,10 @@
}
gralloc1_error_t BufferManager::RetainBuffer(private_handle_t const *hnd) {
+ if (hnd->flags & private_handle_t::PRIV_FLAGS_CLIENT_ALLOCATED) {
+ return GRALLOC1_ERROR_NONE;
+ }
+
ALOGD_IF(DEBUG, "Retain buffer handle:%p id: %" PRIu64, hnd, hnd->id);
gralloc1_error_t err = GRALLOC1_ERROR_NONE;
std::lock_guard<std::mutex> lock(buffer_lock_);
@@ -299,6 +302,10 @@
}
gralloc1_error_t BufferManager::ReleaseBuffer(private_handle_t const *hnd) {
+ if (hnd->flags & private_handle_t::PRIV_FLAGS_CLIENT_ALLOCATED) {
+ return GRALLOC1_ERROR_NONE;
+ }
+
ALOGD_IF(DEBUG, "Release buffer handle:%p id: %" PRIu64, hnd, hnd->id);
std::lock_guard<std::mutex> lock(buffer_lock_);
auto buf = GetBufferFromHandleLocked(hnd);
@@ -327,16 +334,16 @@
return GRALLOC1_ERROR_BAD_VALUE;
}
- if (hnd->base == 0) {
- // we need to map for real
- err = MapBuffer(hnd);
- }
-
auto buf = GetBufferFromHandleLocked(hnd);
if (buf == nullptr) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
+ if (hnd->base == 0) {
+ // we need to map for real
+ err = MapBuffer(hnd);
+ }
+
// Invalidate if CPU reads in software and there are non-CPU
// writers. No need to do this for the metadata buffer as it is
// only read/written in software.
@@ -793,9 +800,11 @@
case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
case HAL_PIXEL_FORMAT_NV21_ZSL:
case HAL_PIXEL_FORMAT_RAW16:
+ case HAL_PIXEL_FORMAT_Y16:
case HAL_PIXEL_FORMAT_RAW12:
case HAL_PIXEL_FORMAT_RAW10:
case HAL_PIXEL_FORMAT_YV12:
+ case HAL_PIXEL_FORMAT_Y8:
return true;
default:
return false;
diff --git a/libgralloc1/gr_device_impl.cpp b/libgralloc1/gr_device_impl.cpp
index b955e19..ee90090 100644
--- a/libgralloc1/gr_device_impl.cpp
+++ b/libgralloc1/gr_device_impl.cpp
@@ -106,11 +106,12 @@
void GrallocImpl::GetCapabilities(struct gralloc1_device *device, uint32_t *out_count,
int32_t /*gralloc1_capability_t*/ *out_capabilities) {
if (device != nullptr) {
- if (out_capabilities != nullptr && *out_count >= 2) {
+ if (out_capabilities != nullptr && *out_count >= 3) {
out_capabilities[0] = GRALLOC1_CAPABILITY_TEST_ALLOCATE;
out_capabilities[1] = GRALLOC1_CAPABILITY_LAYERED_BUFFERS;
+ out_capabilities[2] = GRALLOC1_CAPABILITY_RELEASE_IMPLY_DELETE;
}
- *out_count = 2;
+ *out_count = 3;
}
return;
}
diff --git a/libgralloc1/gr_utils.cpp b/libgralloc1/gr_utils.cpp
index 30afe4c..b3056e1 100644
--- a/libgralloc1/gr_utils.cpp
+++ b/libgralloc1/gr_utils.cpp
@@ -201,6 +201,7 @@
// Below switch should be for only YUV/custom formats
switch (format) {
case HAL_PIXEL_FORMAT_RAW16:
+ case HAL_PIXEL_FORMAT_Y16:
size = alignedw * alignedh * 2;
break;
case HAL_PIXEL_FORMAT_RAW10:
@@ -208,6 +209,7 @@
size = ALIGN(alignedw * alignedh, SIZE_4K);
break;
case HAL_PIXEL_FORMAT_RAW8:
+ case HAL_PIXEL_FORMAT_Y8:
size = alignedw * alignedh * 1;
break;
@@ -421,8 +423,10 @@
case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
case HAL_PIXEL_FORMAT_NV21_ZSL:
case HAL_PIXEL_FORMAT_RAW16:
+ case HAL_PIXEL_FORMAT_Y16:
case HAL_PIXEL_FORMAT_RAW10:
case HAL_PIXEL_FORMAT_RAW8:
+ case HAL_PIXEL_FORMAT_Y8:
GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
std::swap(ycbcr->cb, ycbcr->cr);
break;
@@ -701,6 +705,8 @@
aligned_w = ALIGN(width, alignment);
break;
case HAL_PIXEL_FORMAT_RAW16:
+ case HAL_PIXEL_FORMAT_Y16:
+ case HAL_PIXEL_FORMAT_Y8:
aligned_w = ALIGN(width, 16);
break;
case HAL_PIXEL_FORMAT_RAW12:
diff --git a/libqdutils/Android.mk b/libqdutils/Android.mk
index 7afd00f..60efb3a 100644
--- a/libqdutils/Android.mk
+++ b/libqdutils/Android.mk
@@ -20,12 +20,12 @@
include $(CLEAR_VARS)
LOCAL_COPY_HEADERS_TO := $(common_header_export_path)
-LOCAL_COPY_HEADERS := qdMetaData.h
+LOCAL_COPY_HEADERS := qdMetaData.h qd_utils.h
LOCAL_SHARED_LIBRARIES := liblog libcutils
LOCAL_C_INCLUDES := $(common_includes)
LOCAL_HEADER_LIBRARIES := display_headers
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
-LOCAL_SRC_FILES := qdMetaData.cpp
+LOCAL_SRC_FILES := qdMetaData.cpp qd_utils.cpp
LOCAL_CFLAGS := $(common_flags) -Wno-sign-conversion
LOCAL_CFLAGS += -DLOG_TAG=\"DisplayMetaData\"
@@ -34,3 +34,18 @@
LOCAL_VENDOR_MODULE := true
include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_SHARED_LIBRARIES := liblog libcutils
+LOCAL_C_INCLUDES := $(common_includes)
+LOCAL_HEADER_LIBRARIES := display_headers
+LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
+LOCAL_SRC_FILES := qdMetaData.cpp qd_utils.cpp
+LOCAL_CFLAGS := $(common_flags) -Wno-sign-conversion
+LOCAL_CFLAGS += -DLOG_TAG=\"DisplayMetaData\"
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libqdMetaData.system
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/sdm/libs/core/Android.mk b/sdm/libs/core/Android.mk
index 1d55d96..c5002a9 100644
--- a/sdm/libs/core/Android.mk
+++ b/sdm/libs/core/Android.mk
@@ -7,7 +7,7 @@
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
LOCAL_HEADER_LIBRARIES := display_headers
-LOCAL_CFLAGS := -Wno-unused-parameter -DLOG_TAG=\"SDM\" \
+LOCAL_CFLAGS := -fno-operator-names -Wno-unused-parameter -DLOG_TAG=\"SDM\" \
$(common_flags)
LOCAL_HW_INTF_PATH_1 := fb
LOCAL_SHARED_LIBRARIES := libdl libsdmutils
@@ -51,6 +51,7 @@
$(LOCAL_HW_INTF_PATH_2)/hw_device_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 \
$(LOCAL_HW_INTF_PATH_2)/hw_color_manager_drm.cpp
endif
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index 6bc4434..f6f0787 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -216,14 +216,6 @@
}
void HWDeviceDRM::Registry::RegisterCurrent(HWLayers *hw_layers) {
- DRMMaster *master = nullptr;
- DRMMaster::GetInstance(&master);
-
- if (!master) {
- DLOGE("Failed to acquire DRM Master instance");
- return;
- }
-
HWLayersInfo &hw_layer_info = hw_layers->info;
uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size());
@@ -237,28 +229,41 @@
input_buffer = &hw_rotator_session->output_buffer;
}
- int fd = input_buffer->planes[0].fd;
- if (fd >= 0 && hashmap_[current_index_].find(fd) == hashmap_[current_index_].end()) {
- AllocatedBufferInfo buf_info {};
- DRMBuffer layout {};
- buf_info.fd = layout.fd = fd;
- buf_info.aligned_width = layout.width = input_buffer->width;
- buf_info.aligned_height = layout.height = input_buffer->height;
- buf_info.format = input_buffer->format;
- GetDRMFormat(buf_info.format, &layout.drm_format, &layout.drm_format_modifier);
- buffer_allocator_->GetBufferLayout(buf_info, layout.stride, layout.offset,
- &layout.num_planes);
- uint32_t fb_id = 0;
- int ret = master->CreateFbId(layout, &fb_id);
- if (ret < 0) {
- DLOGE("CreateFbId failed. width %d, height %d, format: %s, stride %u, error %d",
- layout.width, layout.height, GetFormatString(buf_info.format), layout.stride[0],
- errno);
- } else {
- hashmap_[current_index_][fd] = fb_id;
- }
+ MapBufferToFbId(input_buffer);
+ }
+}
+
+void HWDeviceDRM::Registry::MapBufferToFbId(LayerBuffer* buffer) {
+ int fd = buffer->planes[0].fd;
+ DRMMaster *master = nullptr;
+ DRMMaster::GetInstance(&master);
+
+ if (!master) {
+ DLOGE("Failed to acquire DRM Master instance");
+ return;
+ }
+
+ if (fd >= 0 && hashmap_[current_index_].find(fd) == hashmap_[current_index_].end()) {
+ AllocatedBufferInfo buf_info{};
+ DRMBuffer layout{};
+ buf_info.fd = layout.fd = fd;
+ buf_info.aligned_width = layout.width = buffer->width;
+ buf_info.aligned_height = layout.height = buffer->height;
+ buf_info.format = buffer->format;
+ GetDRMFormat(buf_info.format, &layout.drm_format, &layout.drm_format_modifier);
+ buffer_allocator_->GetBufferLayout(buf_info, layout.stride, layout.offset,
+ &layout.num_planes);
+ uint32_t fb_id = 0;
+ int ret = master->CreateFbId(layout, &fb_id);
+ if (ret < 0) {
+ DLOGE("CreateFbId failed. width %d, height %d, format: %s, stride %u, error %d",
+ layout.width, layout.height, GetFormatString(buf_info.format), layout.stride[0],
+ errno);
+ } else {
+ hashmap_[current_index_][fd] = fb_id;
}
}
+ return;
}
void HWDeviceDRM::Registry::UnregisterNext() {
@@ -300,6 +305,7 @@
: hw_info_intf_(hw_info_intf), buffer_sync_handler_(buffer_sync_handler),
registry_(buffer_allocator) {
device_type_ = kDevicePrimary;
+ disp_type_ = DRMDisplayType::PERIPHERAL;
device_name_ = "Peripheral Display";
hw_info_intf_ = hw_info_intf;
}
@@ -309,15 +315,13 @@
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::PERIPHERAL, &token_)) {
- DLOGE("RegisterDisplay failed");
+ drm_master->GetHandle(&dev_fd_);
+ DRMLibLoader::GetInstance()->FuncGetDRMManager()(dev_fd_, &drm_mgr_intf_);
+ if (drm_mgr_intf_->RegisterDisplay(disp_type_, &token_)) {
+ DLOGE("RegisterDisplay failed for display %d", disp_type_);
return kErrorResources;
}
-
drm_mgr_intf_->CreateAtomicReq(token_, &drm_atomic_intf_);
drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
InitializeConfigs();
@@ -325,17 +329,18 @@
drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
// Commit to setup pipeline with mode, which then tells us the topology etc
- 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;
+
+ if (!deferred_initialize_) {
+ if (drm_atomic_intf_->Commit(true /* synchronous */)) {
+ DRM_LOGI("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_);
}
-
- // 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();
@@ -445,6 +450,15 @@
hw_panel_info_.is_primary_panel = connector_info_.is_primary;
hw_panel_info_.is_pluggable = 0;
+ // no supprt for 90 rotation only flips or 180 supported
+ hw_panel_info_.panel_orientation.rotation = 0;
+ hw_panel_info_.panel_orientation.flip_horizontal =
+ (connector_info_.panel_orientation == DRMRotation::FLIP_H) ||
+ (connector_info_.panel_orientation == DRMRotation::ROT_180);
+ hw_panel_info_.panel_orientation.flip_vertical =
+ (connector_info_.panel_orientation == DRMRotation::FLIP_V) ||
+ (connector_info_.panel_orientation == DRMRotation::ROT_180);
+
GetHWDisplayPortAndMode();
GetHWPanelMaxBrightness();
@@ -796,7 +810,7 @@
int ret = drm_atomic_intf_->Commit(false /* synchronous */);
if (ret) {
- DLOGE("%s failed with error %d", __FUNCTION__, ret);
+ DLOGE("%s failed with error %d crtc %d", __FUNCTION__, ret, token_.crtc_id);
return kErrorHardware;
}
@@ -872,7 +886,6 @@
DisplayError HWDeviceDRM::GetPPFeaturesVersion(PPFeatureVersion *vers) {
struct DRMPPFeatureInfo info = {};
-
for (uint32_t i = 0; i < kMaxNumPPFeatures; i++) {
memset(&info, 0, sizeof(struct DRMPPFeatureInfo));
info.id = HWColorManagerDrm::ToDrmFeatureId(i);
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index 16954af..ad7a3e3 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -49,7 +49,7 @@
class HWDeviceDRM : public HWInterface {
public:
- explicit HWDeviceDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
+ HWDeviceDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
HWInfoInterface *hw_info_intf);
virtual ~HWDeviceDRM() {}
virtual DisplayError Init();
@@ -93,6 +93,7 @@
virtual DisplayError SetScaleLutConfig(HWScaleLutInfo *lut_info);
virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes);
virtual DisplayError GetMixerAttributes(HWMixerAttributes *mixer_attributes);
+ virtual void InitializeConfigs();
enum {
kHWEventVSync,
@@ -115,7 +116,6 @@
void ResetDisplayParams();
bool EnableHotPlugDetection(int enable);
void UpdateMixerAttributes();
- void InitializeConfigs();
void SetBlending(const LayerBlending &source, sde_drm::DRMBlendType *target);
void SetSrcConfig(const LayerBuffer &input_buffer, uint32_t *config);
void SetRect(const LayerRect &source, sde_drm::DRMRect *target);
@@ -132,6 +132,8 @@
void UnregisterNext();
// Call on display disconnect to release all gem handles and fb_ids
void Clear();
+ // Maps given fd to FB ID
+ void MapBufferToFbId(LayerBuffer* buffer);
// Finds an fb_id corresponding to an fd in current map
uint32_t GetFbId(int fd);
@@ -144,24 +146,30 @@
BufferAllocator *buffer_allocator_ = {};
};
- HWResourceInfo hw_resource_ = {};
- HWPanelInfo hw_panel_info_ = {};
+ protected:
+ const char *device_name_ = {};
+ bool deferred_initialize_ = false;
+ sde_drm::DRMDisplayType disp_type_ = {};
HWInfoInterface *hw_info_intf_ = {};
BufferSyncHandler *buffer_sync_handler_ = {};
+ int dev_fd_ = -1;
+ Registry registry_;
+ sde_drm::DRMDisplayToken token_ = {};
+ HWResourceInfo hw_resource_ = {};
+ HWPanelInfo hw_panel_info_ = {};
HWDeviceType device_type_ = {};
- const char *device_name_ = {};
- bool synchronous_commit_ = false;
- HWDisplayAttributes display_attributes_ = {};
- HWMixerAttributes mixer_attributes_ = {};
sde_drm::DRMManagerInterface *drm_mgr_intf_ = {};
sde_drm::DRMAtomicReqInterface *drm_atomic_intf_ = {};
- sde_drm::DRMDisplayToken token_ = {};
- drmModeModeInfo current_mode_ = {};
- bool default_mode_ = false;
sde_drm::DRMConnectorInfo connector_info_ = {};
+ drmModeModeInfo current_mode_ = {};
+ HWDisplayAttributes display_attributes_ = {};
+
+ private:
+ bool synchronous_commit_ = false;
+ HWMixerAttributes mixer_attributes_ = {};
+ bool default_mode_ = false;
std::string interface_str_ = "DSI";
HWScaleDRM *hw_scale_ = {};
- Registry registry_;
};
} // namespace sdm
diff --git a/sdm/libs/core/drm/hw_virtual_drm.cpp b/sdm/libs/core/drm/hw_virtual_drm.cpp
new file mode 100644
index 0000000..5fe1d86
--- /dev/null
+++ b/sdm/libs/core/drm/hw_virtual_drm.cpp
@@ -0,0 +1,188 @@
+/*
+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 <stdio.h>
+#include <ctype.h>
+#include <drm_logger.h>
+#include <utils/debug.h>
+#include "hw_device_drm.h"
+#include "hw_virtual_drm.h"
+#include "hw_info_drm.h"
+
+#define __CLASS__ "HWVirtualDRM"
+
+using sde_drm::DRMDisplayType;
+using sde_drm::DRMConnectorInfo;
+using sde_drm::DRMRect;
+using sde_drm::DRMOps;
+
+namespace sdm {
+
+HWVirtualDRM::HWVirtualDRM(BufferSyncHandler *buffer_sync_handler,
+ BufferAllocator *buffer_allocator,
+ HWInfoInterface *hw_info_intf)
+ : HWDeviceDRM(buffer_sync_handler, buffer_allocator, hw_info_intf) {
+ HWDeviceDRM::deferred_initialize_ = true;
+ HWDeviceDRM::device_name_ = "Virtual Display Device";
+ HWDeviceDRM::hw_info_intf_ = hw_info_intf;
+ HWDeviceDRM::disp_type_ = DRMDisplayType::VIRTUAL;
+}
+
+DisplayError HWVirtualDRM::Init() {
+ return kErrorNone;
+}
+
+DisplayError HWVirtualDRM::DeferredInit() {
+ if (HWDeviceDRM::Init() != kErrorNone)
+ return kErrorResources;
+
+ drm_mgr_intf_->SetScalerLUT(drm_lut_info_);
+ DLOGI_IF(kTagDriverConfig, "Setup CRTC %d, Connector %d for %s",
+ token_.crtc_id, token_.conn_id, device_name_);
+
+ return kErrorNone;
+}
+
+void HWVirtualDRM::ConfigureWbConnectorFbId(uint32_t fb_id) {
+ drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_OUTPUT_FB_ID, token_.conn_id, fb_id);
+ return;
+}
+
+void HWVirtualDRM::ConfigureWbConnectorDestRect() {
+ DRMRect dst = {};
+ dst.left = 0;
+ dst.bottom = height_;
+ dst.top = 0;
+ dst.right = width_;
+ drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_OUTPUT_RECT, token_.conn_id, dst);
+ return;
+}
+
+void HWVirtualDRM::InitializeConfigs() {
+ current_mode_.hdisplay = current_mode_.hsync_start = current_mode_.hsync_end \
+ = current_mode_.htotal = (uint16_t) width_;
+ current_mode_.vdisplay = current_mode_.vsync_start = current_mode_.vsync_end \
+ = current_mode_.vtotal = (uint16_t) height_;
+ // Not sure SF has a way to configure refresh rate. Hardcoding to 60 fps for now.
+ // TODO(user): Make this configurable.
+ current_mode_.vrefresh = 60;
+ current_mode_.clock = (current_mode_.htotal * current_mode_.vtotal \
+ * current_mode_.vrefresh) / 1000;
+ struct sde_drm_wb_cfg wb_cfg;
+ wb_cfg.connector_id = token_.conn_id;
+ wb_cfg.flags |= SDE_DRM_WB_CFG_FLAGS_CONNECTED;
+ wb_cfg.count_modes = 1;
+ wb_cfg.modes = (uint64_t)¤t_mode_;
+ #ifdef DRM_IOCTL_SDE_WB_CONFIG
+ int ret = drmIoctl(dev_fd_, DRM_IOCTL_SDE_WB_CONFIG, &wb_cfg);
+ #endif
+ if (ret) {
+ DLOGE("WB config failed\n");
+ } else {
+ drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
+ current_mode_ = connector_info_.modes[0];
+ DumpConfigs();
+ }
+}
+
+void HWVirtualDRM::DumpConfigs() {
+ for (uint32_t i = 0; i < (uint32_t)connector_info_.num_modes; 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",
+ connector_info_.modes[i].name, connector_info_.modes[i].vrefresh,
+ connector_info_.modes[i].hdisplay,
+ connector_info_.modes[i].hsync_start, connector_info_.modes[i].hsync_end,
+ connector_info_.modes[i].htotal, connector_info_.modes[i].vdisplay,
+ connector_info_.modes[i].vsync_start, connector_info_.modes[i].vsync_end,
+ connector_info_.modes[i].vtotal);
+ }
+}
+
+DisplayError HWVirtualDRM::Commit(HWLayers *hw_layers) {
+ LayerBuffer *output_buffer = hw_layers->info.stack->output_buffer;
+ DisplayError err = kErrorNone;
+
+ registry_.RegisterCurrent(hw_layers);
+ registry_.MapBufferToFbId(output_buffer);
+ uint32_t fb_id = registry_.GetFbId(output_buffer->planes[0].fd);
+
+ ConfigureWbConnectorFbId(fb_id);
+ ConfigureWbConnectorDestRect();
+
+ err = HWDeviceDRM::AtomicCommit(hw_layers);
+ registry_.UnregisterNext();
+ return(err);
+}
+
+DisplayError HWVirtualDRM::Validate(HWLayers *hw_layers) {
+ // TODO(user) : Add validate support
+ return kErrorNone;
+}
+
+
+DisplayError HWVirtualDRM::SetDisplayAttributes(const HWDisplayAttributes &display_attributes) {
+ if (display_attributes.x_pixels == 0 || display_attributes.y_pixels == 0) {
+ return kErrorParameters;
+ }
+
+ display_attributes_ = display_attributes;
+
+ if (display_attributes_.x_pixels > hw_resource_.max_mixer_width) {
+ display_attributes_.is_device_split = true;
+ }
+
+ width_ = display_attributes_.x_pixels;
+ height_ = display_attributes_.y_pixels;
+ DeferredInit();
+
+ return kErrorNone;
+}
+
+DisplayError HWVirtualDRM::GetPPFeaturesVersion(PPFeatureVersion *vers) {
+ return kErrorNone;
+}
+
+DisplayError HWVirtualDRM::SetScaleLutConfig(HWScaleLutInfo *lut_info) {
+ drm_lut_info_.cir_lut = lut_info->cir_lut;
+ drm_lut_info_.dir_lut = lut_info->dir_lut;
+ drm_lut_info_.sep_lut = lut_info->sep_lut;
+ drm_lut_info_.cir_lut_size = lut_info->cir_lut_size;
+ drm_lut_info_.dir_lut_size = lut_info->dir_lut_size;
+ drm_lut_info_.sep_lut_size = lut_info->sep_lut_size;
+
+ // Due to differed Init in WB case, we cannot set scaler config immediately as we
+ // won't have SDE DRM initialized at this point. Hence have to cache LUT info here
+ // and set it in ::DeferredInit
+
+ return kErrorNone;
+}
+
+} // namespace sdm
+
diff --git a/sdm/libs/core/drm/hw_virtual_drm.h b/sdm/libs/core/drm/hw_virtual_drm.h
new file mode 100644
index 0000000..b63519a
--- /dev/null
+++ b/sdm/libs/core/drm/hw_virtual_drm.h
@@ -0,0 +1,71 @@
+/*
+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_VIRTUAL_DRM_H__
+#define __HW_VIRTUAL_DRM_H__
+
+#include "hw_device_drm.h"
+#include <drm/msm_drm.h>
+#include <drm/sde_drm.h>
+
+namespace sdm {
+
+class HWVirtualDRM : public HWDeviceDRM {
+ public:
+ HWVirtualDRM(BufferSyncHandler *buffer_sync_handler,
+ BufferAllocator *buffer_allocator, HWInfoInterface *hw_info_intf);
+ virtual ~HWVirtualDRM() {}
+ virtual DisplayError SetVSyncState(bool enable) { return kErrorNotSupported; }
+ virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes) {
+ return kErrorNotSupported;
+ }
+ virtual DisplayError SetDisplayAttributes(const HWDisplayAttributes &display_attributes);
+
+ protected:
+ virtual DisplayError Init();
+ virtual DisplayError Validate(HWLayers *hw_layers);
+ virtual DisplayError DeferredInit();
+ virtual void InitializeConfigs();
+ virtual DisplayError Commit(HWLayers *hw_layers);
+ virtual DisplayError GetPPFeaturesVersion(PPFeatureVersion *vers);
+ virtual DisplayError SetScaleLutConfig(HWScaleLutInfo *lut_info);
+ void ConfigureWbConnectorFbId(uint32_t fb_id);
+ void ConfigureWbConnectorDestRect();
+ void DumpConfigs();
+
+ private:
+ uint32_t width_ = 0;
+ uint32_t height_ = 0;
+ sde_drm::DRMScalerLUTInfo drm_lut_info_ = {};
+};
+
+} // namespace sdm
+
+#endif // __HW_VIRTUAL_DRM_H__
+
diff --git a/sdm/libs/core/hw_interface.cpp b/sdm/libs/core/hw_interface.cpp
index b5c9fe9..a27c5f8 100644
--- a/sdm/libs/core/hw_interface.cpp
+++ b/sdm/libs/core/hw_interface.cpp
@@ -37,6 +37,7 @@
#include "fb/hw_virtual.h"
#ifdef COMPILE_DRM
#include "drm/hw_device_drm.h"
+#include "drm/hw_virtual_drm.h"
#endif
#define __CLASS__ "HWInterface"
@@ -69,9 +70,11 @@
break;
case kVirtual:
if (driver_type == DriverType::FB) {
- hw = new HWVirtual(buffer_sync_handler, hw_info_intf);
+ hw = new HWVirtual(buffer_sync_handler,hw_info_intf);
} else {
- return kErrorNotSupported;
+#ifdef COMPILE_DRM
+ hw = new HWVirtualDRM(buffer_sync_handler, buffer_allocator, hw_info_intf);
+#endif
}
break;
default:
diff --git a/sdm/libs/hwc/hwc_display.cpp b/sdm/libs/hwc/hwc_display.cpp
index 07ec2ce..2c5c885 100644
--- a/sdm/libs/hwc/hwc_display.cpp
+++ b/sdm/libs/hwc/hwc_display.cpp
@@ -58,15 +58,6 @@
namespace sdm {
-static void ApplyDeInterlaceAdjustment(Layer *layer) {
- // De-interlacing adjustment
- if (layer->input_buffer.flags.interlace) {
- float height = (layer->src_rect.bottom - layer->src_rect.top) / 2.0f;
- layer->src_rect.top = ROUND_UP_ALIGN_DOWN(layer->src_rect.top / 2.0f, 2);
- layer->src_rect.bottom = layer->src_rect.top + floorf(height);
- }
-}
-
void HWCColorMode::Init() {
int ret = PopulateColorModes();
if (ret != 0) {
@@ -575,7 +566,6 @@
}
}
SetRect(hwc_layer.sourceCropf, &layer->src_rect);
- ApplyDeInterlaceAdjustment(layer);
uint32_t num_visible_rects = UINT32(hwc_layer.visibleRegionScreen.numRects);
uint32_t num_dirty_rects = UINT32(hwc_layer.surfaceDamage.numRects);
diff --git a/sdm/libs/hwc/hwc_session.cpp b/sdm/libs/hwc/hwc_session.cpp
index 8a5bd81..98e14ee 100644
--- a/sdm/libs/hwc/hwc_session.cpp
+++ b/sdm/libs/hwc/hwc_session.cpp
@@ -289,7 +289,7 @@
}
if (hwc_session->need_invalidate_) {
- hwc_procs->invalidate(hwc_procs);
+ hwc_session->AsyncRefresh();
hwc_session->need_invalidate_ = false;
}
@@ -420,6 +420,8 @@
hwc_session->bw_mode_release_fd_ = dup(content_list->retireFenceFd);
}
+ locker_.Signal();
+
// This is only indicative of how many times SurfaceFlinger posts
// frames to the display.
CALC_FPS();
@@ -693,6 +695,14 @@
return 0;
}
+static void PostRefresh(hwc_procs_t const *hwc_procs) {
+ hwc_procs->invalidate(hwc_procs);
+}
+
+void HWCSession::AsyncRefresh() {
+ future_ = std::async(PostRefresh, hwc_procs_);
+}
+
android::status_t HWCSession::notifyCallback(uint32_t command, const android::Parcel *input_parcel,
android::Parcel *output_parcel) {
SEQUENCE_WAIT_SCOPE_LOCK(locker_);
@@ -705,7 +715,7 @@
break;
case qService::IQService::SCREEN_REFRESH:
- hwc_procs_->invalidate(hwc_procs_);
+ AsyncRefresh();
break;
case qService::IQService::SET_IDLE_TIMEOUT:
@@ -856,7 +866,7 @@
}
android::status_t HWCSession::ControlPartialUpdate(const android::Parcel *input_parcel,
- android::Parcel *out) {
+ android::Parcel *output_parcel) {
DisplayError error = kErrorNone;
int ret = 0;
uint32_t disp_id = UINT32(input_parcel->readInt32());
@@ -865,14 +875,14 @@
if (disp_id != HWC_DISPLAY_PRIMARY) {
DLOGW("CONTROL_PARTIAL_UPDATE is not applicable for display = %d", disp_id);
ret = -EINVAL;
- out->writeInt32(ret);
+ output_parcel->writeInt32(ret);
return ret;
}
if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
DLOGE("primary display object is not instantiated");
ret = -EINVAL;
- out->writeInt32(ret);
+ output_parcel->writeInt32(ret);
return ret;
}
@@ -881,31 +891,30 @@
if (error == kErrorNone) {
if (!pending) {
- out->writeInt32(ret);
+ output_parcel->writeInt32(ret);
return ret;
}
} else if (error == kErrorNotSupported) {
- out->writeInt32(ret);
+ output_parcel->writeInt32(ret);
return ret;
} else {
ret = -EINVAL;
- out->writeInt32(ret);
+ output_parcel->writeInt32(ret);
return ret;
}
- // Todo(user): Unlock it before sending events to client. It may cause deadlocks in future.
- hwc_procs_->invalidate(hwc_procs_);
+ AsyncRefresh();
// Wait until partial update control is complete
ret = locker_.WaitFinite(kPartialUpdateControlTimeoutMs);
- out->writeInt32(ret);
+ output_parcel->writeInt32(ret);
return ret;
}
android::status_t HWCSession::HandleSetActiveDisplayConfig(const android::Parcel *input_parcel,
- android::Parcel *output_parcel) {
+ android::Parcel *output_parcel) {
int config = input_parcel->readInt32();
int dpy = input_parcel->readInt32();
int error = android::BAD_VALUE;
@@ -917,7 +926,7 @@
if (hwc_display_[dpy]) {
error = hwc_display_[dpy]->SetActiveDisplayConfig(config);
if (error == 0) {
- hwc_procs_->invalidate(hwc_procs_);
+ AsyncRefresh();
}
}
@@ -1128,7 +1137,7 @@
HWBwModes mode = camera_status > 0 ? kBwCamera : kBwDefault;
// trigger invalidate to apply new bw caps.
- hwc_procs_->invalidate(hwc_procs_);
+ AsyncRefresh();
error = core_intf_->SetMaxBandwidthMode(mode);
if (error != kErrorNone) {
@@ -1325,7 +1334,7 @@
switch (pending_action.action) {
case kInvalidating:
- hwc_procs_->invalidate(hwc_procs_);
+ AsyncRefresh();
break;
case kEnterQDCMMode:
ret = color_mgr_->EnableQDCMMode(true, hwc_display_[HWC_DISPLAY_PRIMARY]);
@@ -1336,12 +1345,12 @@
case kApplySolidFill:
ret = color_mgr_->SetSolidFill(pending_action.params,
true, hwc_display_[HWC_DISPLAY_PRIMARY]);
- hwc_procs_->invalidate(hwc_procs_);
+ AsyncRefresh();
break;
case kDisableSolidFill:
ret = color_mgr_->SetSolidFill(pending_action.params,
false, hwc_display_[HWC_DISPLAY_PRIMARY]);
- hwc_procs_->invalidate(hwc_procs_);
+ AsyncRefresh();
break;
case kSetPanelBrightness:
brightness_value = reinterpret_cast<int32_t*>(resp_payload.payload);
@@ -1355,7 +1364,7 @@
case kEnableFrameCapture:
ret = color_mgr_->SetFrameCapture(pending_action.params,
true, hwc_display_[HWC_DISPLAY_PRIMARY]);
- hwc_procs_->invalidate(hwc_procs_);
+ AsyncRefresh();
break;
case kDisableFrameCapture:
ret = color_mgr_->SetFrameCapture(pending_action.params,
@@ -1364,7 +1373,7 @@
case kConfigureDetailedEnhancer:
ret = color_mgr_->SetDetailedEnhancer(pending_action.params,
hwc_display_[HWC_DISPLAY_PRIMARY]);
- hwc_procs_->invalidate(hwc_procs_);
+ AsyncRefresh();
break;
case kInvalidatingAndkSetPanelBrightness:
brightness_value = reinterpret_cast<int32_t*>(resp_payload.payload);
@@ -1374,7 +1383,7 @@
}
if (HWC_DISPLAY_PRIMARY == display_id)
ret = hwc_display_[HWC_DISPLAY_PRIMARY]->CachePanelBrightness(*brightness_value);
- hwc_procs_->invalidate(hwc_procs_);
+ AsyncRefresh();
break;
case kNoAction:
break;
@@ -1460,7 +1469,7 @@
if (panel_reset == 0) {
if (hwc_procs_) {
reset_panel_ = true;
- hwc_procs_->invalidate(hwc_procs_);
+ AsyncRefresh();
} else {
DLOGW("Ignore resetpanel - hwc_proc not registered");
}
diff --git a/sdm/libs/hwc/hwc_session.h b/sdm/libs/hwc/hwc_session.h
index 1cd3e33..ce21c46 100644
--- a/sdm/libs/hwc/hwc_session.h
+++ b/sdm/libs/hwc/hwc_session.h
@@ -28,6 +28,7 @@
#include <hardware/hwcomposer.h>
#include <core/core_interface.h>
#include <utils/locker.h>
+#include <future> // NOLINT
#include "hwc_display_primary.h"
#include "hwc_display_external.h"
@@ -88,6 +89,7 @@
int GetVsyncPeriod(int disp);
int CreateExternalDisplay(int disp, uint32_t primary_width, uint32_t primary_height,
bool use_primary_res);
+ void AsyncRefresh();
// QClient methods
virtual android::status_t notifyCallback(uint32_t command, const android::Parcel *input_parcel,
@@ -103,7 +105,8 @@
android::status_t ConfigureRefreshRate(const android::Parcel *input_parcel);
android::status_t QdcmCMDHandler(const android::Parcel *input_parcel,
android::Parcel *output_parcel);
- android::status_t ControlPartialUpdate(const android::Parcel *input_parcel, android::Parcel *out);
+ android::status_t ControlPartialUpdate(const android::Parcel *input_parcel,
+ android::Parcel *output_parcel);
android::status_t OnMinHdcpEncryptionLevelChange(const android::Parcel *input_parcel,
android::Parcel *output_parcel);
android::status_t SetPanelBrightness(const android::Parcel *input_parcel,
@@ -151,6 +154,7 @@
qService::QService *qservice_ = NULL;
bool is_hdmi_primary_ = false;
bool is_hdmi_yuv_ = false;
+ std::future<void> future_;
std::bitset<HWC_NUM_DISPLAY_TYPES> connected_displays_; // Bit mask of connected displays
HWCSocketHandler socket_handler_;
Locker uevent_locker_;
diff --git a/sdm/libs/hwc2/hwc_buffer_allocator.cpp b/sdm/libs/hwc2/hwc_buffer_allocator.cpp
index da40a34..3c8d460 100644
--- a/sdm/libs/hwc2/hwc_buffer_allocator.cpp
+++ b/sdm/libs/hwc2/hwc_buffer_allocator.cpp
@@ -114,10 +114,6 @@
alloc_buffer_info->fd = -1;
alloc_buffer_info->stride = 0;
alloc_buffer_info->size = 0;
- // Works around b/36355756
- if (hnd != nullptr) {
- delete hnd;
- }
buffer_info->private_data = NULL;
return err;
}
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index f48ed2d..4f623ce 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -54,26 +54,6 @@
namespace sdm {
-static void ApplyDeInterlaceAdjustment(HWCLayer *hwc_layer, Layer *sdm_layer) {
- // De-interlacing adjustment
- if (sdm_layer->input_buffer.flags.interlace) {
- // Adjust src_rect only if new source crop was set
- if (hwc_layer->GetGeometryChanges() & kSourceCrop) {
- float height = (sdm_layer->src_rect.bottom - sdm_layer->src_rect.top) / 2.0f;
- sdm_layer->src_rect.top = ROUND_UP_ALIGN_DOWN(sdm_layer->src_rect.top / 2.0f, 2);
- sdm_layer->src_rect.bottom = sdm_layer->src_rect.top + floorf(height);
- }
-
- // Handle deinterlacing for UBWC Interlaced format.
- if (IsUBWCFormat(sdm_layer->input_buffer.format)) {
- sdm_layer->input_buffer.height /= 2;
- sdm_layer->input_buffer.unaligned_height /= 2;
- // After adjustments layer needs to be treated as UBWC progressive. Reset interlace flag.
- sdm_layer->input_buffer.flags.interlace = 0;
- }
- }
-}
-
// This weight function is needed because the color primaries are not sorted by gamut size
static ColorPrimaries WidestPrimaries(ColorPrimaries p1, ColorPrimaries p2) {
int weight = 10;
@@ -417,6 +397,7 @@
HWCLayer *layer = *layer_set_.emplace(new HWCLayer(id_, buffer_allocator_));
layer_map_.emplace(std::make_pair(layer->GetId(), layer));
*out_layer_id = layer->GetId();
+ validated_ = false;
geometry_changes_ |= GeometryChanges::kAdded;
return HWC2::Error::None;
}
@@ -447,6 +428,7 @@
break;
}
}
+ validated_ = false;
geometry_changes_ |= GeometryChanges::kRemoved;
return HWC2::Error::None;
@@ -462,6 +444,9 @@
// Add one layer for fb target
// TODO(user): Add blit target layers
for (auto hwc_layer : layer_set_) {
+ // Reset layer data which SDM may change
+ hwc_layer->ResetPerFrameData();
+
Layer *layer = hwc_layer->GetSDMLayer();
layer->flags = {}; // Reset earlier flags
if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::Client) {
@@ -536,7 +521,6 @@
INT(layer->dst_rect.right), INT(layer->dst_rect.bottom)};
ApplyScanAdjustment(&scaled_display_frame);
hwc_layer->SetLayerDisplayFrame(scaled_display_frame);
- ApplyDeInterlaceAdjustment(hwc_layer, layer);
// SDM requires these details even for solid fill
if (layer->flags.solid_fill) {
LayerBuffer *layer_buffer = &layer->input_buffer;
@@ -604,6 +588,7 @@
DLOGE("[%" PRIu64 "] updateLayerZ failed to find layer", id_);
return HWC2::Error::BadLayer;
}
+ validated_ = false;
const auto layer = map_layer->second;
const auto z_range = layer_set_.equal_range(layer);
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index a375831..1b04c84 100644
--- a/sdm/libs/hwc2/hwc_display.h
+++ b/sdm/libs/hwc2/hwc_display.h
@@ -137,6 +137,18 @@
virtual int GetDisplayConfigCount(uint32_t *count);
virtual int GetDisplayAttributesForConfig(int config,
DisplayConfigVariableInfo *display_attributes);
+ template <typename... Args>
+ int32_t CallLayerFunction(hwc2_layer_t layer, HWC2::Error (HWCLayer::*member)(Args... ),
+ Args... args) {
+ auto status = HWC2::Error::BadLayer;
+ validated_ = false;
+ auto hwc_layer = GetHWCLayer(layer);
+ if (hwc_layer != nullptr) {
+ status = (hwc_layer->*member)(std::forward<Args>(args)...);
+ }
+
+ return INT32(status);
+ }
int SetPanelBrightness(int level);
int GetPanelBrightness(int *level);
diff --git a/sdm/libs/hwc2/hwc_layers.cpp b/sdm/libs/hwc2/hwc_layers.cpp
index 7fef9cf..7fcd56b 100644
--- a/sdm/libs/hwc2/hwc_layers.cpp
+++ b/sdm/libs/hwc2/hwc_layers.cpp
@@ -258,14 +258,21 @@
HWC2::Error HWCLayer::SetLayerDisplayFrame(hwc_rect_t frame) {
LayerRect dst_rect = {};
+
SetRect(frame, &dst_rect);
- if (layer_->dst_rect != dst_rect) {
+ if (dst_rect_ != dst_rect) {
geometry_changes_ |= kDisplayFrame;
- layer_->dst_rect = dst_rect;
+ dst_rect_ = dst_rect;
}
+
return HWC2::Error::None;
}
+void HWCLayer::ResetPerFrameData() {
+ layer_->dst_rect = dst_rect_;
+ layer_->transform = layer_transform_;
+}
+
HWC2::Error HWCLayer::SetLayerPlaneAlpha(float alpha) {
// Conversion of float alpha in range 0.0 to 1.0 similar to the HWC Adapter
uint8_t plane_alpha = static_cast<uint8_t>(std::round(255.0f * alpha));
@@ -322,10 +329,11 @@
break;
}
- if (layer_->transform != layer_transform) {
+ if (layer_transform_ != layer_transform) {
geometry_changes_ |= kTransform;
- layer_->transform = layer_transform;
+ layer_transform_ = layer_transform;
}
+
return HWC2::Error::None;
}
diff --git a/sdm/libs/hwc2/hwc_layers.h b/sdm/libs/hwc2/hwc_layers.h
index bc3d84d..82bf466 100644
--- a/sdm/libs/hwc2/hwc_layers.h
+++ b/sdm/libs/hwc2/hwc_layers.h
@@ -61,6 +61,7 @@
uint32_t GetZ() const { return z_; }
hwc2_layer_t GetId() const { return id_; }
Layer *GetSDMLayer() { return layer_; }
+ void ResetPerFrameData();
HWC2::Error SetLayerBlendMode(HWC2::BlendMode mode);
HWC2::Error SetLayerBuffer(buffer_handle_t buffer, int32_t acquire_fence);
@@ -96,6 +97,8 @@
int ion_fd_ = -1;
HWCBufferAllocator *buffer_allocator_ = NULL;
int32_t dataspace_ = HAL_DATASPACE_UNKNOWN;
+ LayerTransform layer_transform_ = {};
+ LayerRect dst_rect_ = {};
// Composition requested by client(SF)
HWC2::Composition client_requested_ = HWC2::Composition::Device;
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
index 87d41d7..7d31a3a 100644
--- a/sdm/libs/hwc2/hwc_session.h
+++ b/sdm/libs/hwc2/hwc_session.h
@@ -70,15 +70,11 @@
}
HWCSession *hwc_session = static_cast<HWCSession *>(device);
- auto status = HWC2::Error::BadDisplay;
+ int32_t status = INT32(HWC2::Error::BadDisplay);
if (hwc_session->hwc_display_[display]) {
- status = HWC2::Error::BadLayer;
- auto hwc_layer = hwc_session->hwc_display_[display]->GetHWCLayer(layer);
- if (hwc_layer != nullptr) {
- status = (hwc_layer->*member)(std::forward<Args>(args)...);
- }
+ status = hwc_session->hwc_display_[display]->CallLayerFunction(layer, member, args...);
}
- return INT32(status);
+ return status;
}
// HWC2 Functions that require a concrete implementation in hwc session