Merge "sdm: color-manager: Clear feature list when add new feature"
diff --git a/libgralloc1/gr_buf_mgr.cpp b/libgralloc1/gr_buf_mgr.cpp
index 743c1c2..7e0ba14 100644
--- a/libgralloc1/gr_buf_mgr.cpp
+++ b/libgralloc1/gr_buf_mgr.cpp
@@ -771,6 +771,17 @@
AllocateBuffer(descriptor, hnd, size);
} break;
+ case GRALLOC1_MODULE_PERFORM_GET_INTERLACE_FLAG: {
+ private_handle_t *hnd = va_arg(args, private_handle_t *);
+ int *flag = va_arg(args, int *);
+ if (private_handle_t::validate(hnd) != 0) {
+ return GRALLOC1_ERROR_BAD_HANDLE;
+ }
+ if (getMetaData(hnd, GET_PP_PARAM_INTERLACED, flag) != 0) {
+ *flag = 0;
+ }
+ } break;
+
default:
break;
}
diff --git a/libgralloc1/gr_utils.cpp b/libgralloc1/gr_utils.cpp
index aee8c0d..b3056e1 100644
--- a/libgralloc1/gr_utils.cpp
+++ b/libgralloc1/gr_utils.cpp
@@ -311,6 +311,28 @@
ycbcr->cstride = VENUS_UV_STRIDE(color_format, INT(width));
}
+void GetYuvUbwcInterlacedSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
+ int color_format, struct android_ycbcr *ycbcr) {
+ unsigned int uv_stride, uv_height, uv_size;
+ unsigned int alignment = 4096;
+ uint64_t field_base;
+
+ // UBWC interlaced has top-bottom field layout with each field as
+ // 4-plane NV12_UBWC with width = image_width & height = image_height / 2.
+ // Client passed ycbcr argument is ptr to struct android_ycbcr[2].
+ // Plane info to be filled for each field separately.
+ height = (height + 1) >> 1;
+ uv_stride = VENUS_UV_STRIDE(color_format, INT(width));
+ uv_height = VENUS_UV_SCANLINES(color_format, INT(height));
+ uv_size = ALIGN((uv_stride * uv_height), alignment);
+
+ field_base = base;
+ GetYuvUbwcSPPlaneInfo(field_base, width, height, COLOR_FMT_NV12_UBWC, &ycbcr[0]);
+
+ field_base = reinterpret_cast<uint64_t>(ycbcr[0].cb) + uv_size;
+ GetYuvUbwcSPPlaneInfo(field_base, width, height, COLOR_FMT_NV12_UBWC, &ycbcr[1]);
+}
+
void GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t bpp,
struct android_ycbcr *ycbcr) {
unsigned int ystride, cstride;
@@ -332,6 +354,7 @@
gralloc1_producer_usage_t prod_usage = hnd->GetProducerUsage();
gralloc1_consumer_usage_t cons_usage = hnd->GetConsumerUsage();
unsigned int ystride, cstride;
+ bool interlaced = false;
memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
@@ -354,6 +377,11 @@
GetAlignedWidthAndHeight(info, &width, &height);
}
+ // Check metadata for interlaced content.
+ if (metadata && (metadata->operation & PP_PARAM_INTERLACED)) {
+ interlaced = metadata->interlaced ? true : false;
+ }
+
// Get the chroma offsets from the handle width/height. We take advantage
// of the fact the width _is_ the stride
switch (format) {
@@ -371,7 +399,11 @@
break;
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
- GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr);
+ if (!interlaced) {
+ GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr);
+ } else {
+ GetYuvUbwcInterlacedSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr);
+ }
ycbcr->chroma_step = 2;
break;
diff --git a/libgralloc1/gr_utils.h b/libgralloc1/gr_utils.h
index aa66fd0..2a08539 100644
--- a/libgralloc1/gr_utils.h
+++ b/libgralloc1/gr_utils.h
@@ -83,6 +83,8 @@
struct android_ycbcr *ycbcr);
void GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, int color_format,
struct android_ycbcr *ycbcr);
+void GetYuvUbwcInterlacedSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
+ int color_format, struct android_ycbcr *ycbcr);
void GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height);
unsigned int GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp);
unsigned int GetUBwcSize(int width, int height, int format, unsigned int alignedw,
diff --git a/libgralloc1/gralloc_priv.h b/libgralloc1/gralloc_priv.h
index ba156b6..1839d2f 100644
--- a/libgralloc1/gralloc_priv.h
+++ b/libgralloc1/gralloc_priv.h
@@ -97,6 +97,7 @@
#define GRALLOC_MODULE_PERFORM_SET_SINGLE_BUFFER_MODE 13
#define GRALLOC1_MODULE_PERFORM_GET_BUFFER_SIZE_AND_DIMENSIONS 14
#define GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER 15
+#define GRALLOC1_MODULE_PERFORM_GET_INTERLACE_FLAG 16
// OEM specific HAL formats
#define HAL_PIXEL_FORMAT_RGBA_5551 6
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 1be973c..1028663 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();
@@ -569,18 +574,19 @@
DisplayError HWDeviceDRM::PowerOn() {
DTRACE_SCOPED();
-/*
drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::ON);
-*/
+ int ret = drm_atomic_intf_->Commit(false /* synchronous */);
+ if (ret) {
+ DLOGE("%s failed with error %d", __FUNCTION__, ret);
+ return kErrorHardware;
+ }
return kErrorNone;
}
DisplayError HWDeviceDRM::PowerOff() {
-/*
drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::OFF);
drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 0);
-*/
int ret = drm_atomic_intf_->Commit(false /* synchronous */);
if (ret) {
DLOGE("%s failed with error %d", __FUNCTION__, ret);
@@ -805,7 +811,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;
}
@@ -881,7 +887,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..a7bcabd 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"
@@ -71,7 +72,9 @@
if (driver_type == DriverType::FB) {
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: