1
0
Fork 0

rockchip: drmhwc: Fix issue of set HDMI overscan [tbc]

- Add DrmConnector::unique_name()
- Porting CheckOverscan() of drmhwc2
- Get overscan value from persist.vendor.overscan.<unique_name()>
- introduce DrmConnector::update_overscan()
- Set overscan only when display changed

Signed-off-by: hmz007 <hmz007@gmail.com>
master
hmz007 3 years ago
parent 116aa590ab
commit 30030c3779

@ -520,7 +520,14 @@ LOCAL_CPPFLAGS += -DUSE_DRM_GENERIC_IMPORTER \
-DRK_RGA_SCALE_AND_ROTATE=$(RK_RGA_SCALE_AND_ROTATE) \ -DRK_RGA_SCALE_AND_ROTATE=$(RK_RGA_SCALE_AND_ROTATE) \
-DRGA_VER=$(RGA_VER) -DRK_PER_MODE=$(RK_PER_MODE) -DRK_ROTATE_VIDEO_MODE=$(RK_ROTATE_VIDEO_MODE) \ -DRGA_VER=$(RGA_VER) -DRK_PER_MODE=$(RK_PER_MODE) -DRK_ROTATE_VIDEO_MODE=$(RK_ROTATE_VIDEO_MODE) \
-DRK_CTS_WORKROUND=$(RK_CTS_WORKROUND) -DRK_CTS_WORKROUND=$(RK_CTS_WORKROUND)
LOCAL_HAVE_GIT = $(shell test -d $(LOCAL_PATH)/.git && echo true)
ifeq ($(LOCAL_HAVE_GIT),true)
MAJOR_VERSION := "RK_GRAPHICS_VER=commit-id:$(shell cd $(LOCAL_PATH) && git log -1 --oneline | awk '{print $$1}')" MAJOR_VERSION := "RK_GRAPHICS_VER=commit-id:$(shell cd $(LOCAL_PATH) && git log -1 --oneline | awk '{print $$1}')"
else
MAJOR_VERSION := "RK_GRAPHICS_VER=commit-id:63fcb48"
endif
LOCAL_CPPFLAGS += -DRK_GRAPHICS_VER=\"$(MAJOR_VERSION)\" LOCAL_CPPFLAGS += -DRK_GRAPHICS_VER=\"$(MAJOR_VERSION)\"
endif endif

@ -127,6 +127,13 @@ int DrmConnector::Init() {
ALOGW("Could not get hdmi_output_depth property\n"); ALOGW("Could not get hdmi_output_depth property\n");
} }
ret = drm_->GetConnectorProperty(*this, "CONNECTOR_ID", &connector_id_property_);
if (ret) {
ALOGW("Could not get CONNECTOR_ID property\n");
}
snprintf(unique_name_, 30, "%s-%d", drm_->connector_type_str(type_), connector_id());
bSupportSt2084_ = drm_->is_hdr_panel_support_st2084(this); bSupportSt2084_ = drm_->is_hdr_panel_support_st2084(this);
bSupportHLG_ = drm_->is_hdr_panel_support_HLG(this); bSupportHLG_ = drm_->is_hdr_panel_support_HLG(this);
@ -146,6 +153,12 @@ uint32_t DrmConnector::type_id() const {
return type_id_; return type_id_;
} }
uint32_t DrmConnector::connector_id() const {
uint64_t id = 0;
connector_id_property_.value(&id);
return (uint32_t) id;
}
int DrmConnector::priority() const{ int DrmConnector::priority() const{
return priority_; return priority_;
} }
@ -170,7 +183,7 @@ bool DrmConnector::built_in() const {
type_ == DRM_MODE_CONNECTOR_DSI || type_ == DRM_MODE_CONNECTOR_DSI ||
type_ == DRM_MODE_CONNECTOR_VIRTUAL || type_ == DRM_MODE_CONNECTOR_VIRTUAL ||
type_ == DRM_MODE_CONNECTOR_TV || type_ == DRM_MODE_CONNECTOR_TV ||
type_ == DRM_MODE_CONNECTOR_DPI; type_ == DRM_MODE_CONNECTOR_DPI;
} }
const DrmMode &DrmConnector::best_mode() const { const DrmMode &DrmConnector::best_mode() const {
@ -291,6 +304,43 @@ void DrmConnector::set_current_mode(const DrmMode &mode) {
current_mode_ = mode; current_mode_ = mode;
} }
static inline void check_margin(int &margin) {
if (margin < 80)
margin = 80;
else if (margin > 100)
margin = 100;
}
void DrmConnector::update_overscan(drmModeAtomicReqPtr pset, DrmCrtc *crtc) {
std::string prop = "persist.vendor.overscan.";
prop += unique_name();
char overscan[PROPERTY_VALUE_MAX] = {0};
int ret = property_get(prop.c_str(), overscan, "");
if (!ret)
return;
int left, right, top, bottom;
ret = sscanf(overscan, "overscan %d,%d,%d,%d", &left, &top, &right, &bottom);
if (ret != 4)
return;
check_margin(left);
check_margin(right);
check_margin(top);
check_margin(bottom);
uint32_t obj_id = crtc->id();
ALOGD_IF(log_level(DBG_DEBUG), "crtc-%d: set %s", obj_id, overscan);
ret = drmModeAtomicAddProperty(pset, obj_id, crtc->left_margin_property().id(), left) < 0 ||
drmModeAtomicAddProperty(pset, obj_id, crtc->right_margin_property().id(), right) < 0 ||
drmModeAtomicAddProperty(pset, obj_id, crtc->top_margin_property().id(), top) < 0 ||
drmModeAtomicAddProperty(pset, obj_id, crtc->bottom_margin_property().id(), bottom) < 0;
if (ret) {
ALOGE("Failed to add tv.margins %d,%d,%d,%d, ret = %d", left, right, top, bottom, ret);
}
}
const DrmProperty &DrmConnector::dpms_property() const { const DrmProperty &DrmConnector::dpms_property() const {
return dpms_property_; return dpms_property_;
} }

@ -61,6 +61,8 @@ class DrmConnector {
uint32_t id() const; uint32_t id() const;
uint32_t type_id() const; uint32_t type_id() const;
uint32_t connector_id() const;
const char* unique_name() const { return unique_name_; }
int display() const; int display() const;
void set_display(int display); void set_display(int display);
@ -84,6 +86,7 @@ class DrmConnector {
void set_best_mode(const DrmMode &mode); void set_best_mode(const DrmMode &mode);
void set_active_mode(const DrmMode &mode); void set_active_mode(const DrmMode &mode);
void set_current_mode(const DrmMode &mode); void set_current_mode(const DrmMode &mode);
void update_overscan(drmModeAtomicReqPtr pset, DrmCrtc *crtc);
void SetDpmsMode(uint32_t dpms_mode); void SetDpmsMode(uint32_t dpms_mode);
const DrmProperty &dpms_property() const; const DrmProperty &dpms_property() const;
@ -128,6 +131,7 @@ class DrmConnector {
uint32_t id_; uint32_t id_;
uint32_t type_id_; uint32_t type_id_;
char unique_name_[30] = {0};
DrmEncoder *encoder_; DrmEncoder *encoder_;
int display_; int display_;
@ -156,6 +160,7 @@ class DrmConnector {
DrmProperty hdmi_output_colorimetry_; DrmProperty hdmi_output_colorimetry_;
DrmProperty hdmi_output_format_; DrmProperty hdmi_output_format_;
DrmProperty hdmi_output_depth_; DrmProperty hdmi_output_depth_;
DrmProperty connector_id_property_;
std::vector<DrmEncoder *> possible_encoders_; std::vector<DrmEncoder *> possible_encoders_;
uint32_t possible_displays_; uint32_t possible_displays_;

@ -410,6 +410,7 @@ int DrmDisplayCompositor::Init(DrmResources *drm, int display) {
pthread_cond_init(&composite_queue_cond_, NULL); pthread_cond_init(&composite_queue_cond_, NULL);
forceOverscan_ = property_get_bool("vendor.hwc.force_overscan", false);
vop_bw_fd_ = open(VOP_BW_PATH, O_WRONLY); vop_bw_fd_ = open(VOP_BW_PATH, O_WRONLY);
if(vop_bw_fd_ < 0) if(vop_bw_fd_ < 0)
@ -1069,6 +1070,48 @@ static const char *RotatingToString(uint64_t rotating) {
} }
} }
int DrmDisplayCompositor::CheckOverscan(drmModeAtomicReqPtr pset, DrmCrtc *crtc, int display,
bool reset, const char *UniqueName)
{
int ret = 0;
int left_margin = 100, right_margin= 100, top_margin = 100, bottom_margin = 100;
if (!reset) {
char overscan_value[PROPERTY_VALUE_MAX] = {0};
char overscan_pro[PROPERTY_VALUE_MAX] = {0};
snprintf(overscan_pro, PROPERTY_VALUE_MAX, "persist.vendor.overscan.%s", UniqueName);
ret = property_get(overscan_pro, overscan_value, "");
if (!ret) {
return 0;
}
sscanf(overscan_value, "overscan %d,%d,%d,%d", &left_margin, &top_margin,
&right_margin, &bottom_margin);
ALOGD_IF(log_level(DBG_VERBOSE), "display=%d, %s", display, overscan_value);
if (left_margin < OVERSCAN_MIN_VALUE) left_margin = OVERSCAN_MIN_VALUE;
if (top_margin < OVERSCAN_MIN_VALUE) top_margin = OVERSCAN_MIN_VALUE;
if (right_margin < OVERSCAN_MIN_VALUE) right_margin = OVERSCAN_MIN_VALUE;
if (bottom_margin < OVERSCAN_MIN_VALUE) bottom_margin = OVERSCAN_MIN_VALUE;
if (left_margin > OVERSCAN_MAX_VALUE) left_margin = OVERSCAN_MAX_VALUE;
if (top_margin > OVERSCAN_MAX_VALUE) top_margin = OVERSCAN_MAX_VALUE;
if (right_margin > OVERSCAN_MAX_VALUE) right_margin = OVERSCAN_MAX_VALUE;
if (bottom_margin > OVERSCAN_MAX_VALUE) bottom_margin = OVERSCAN_MAX_VALUE;
}
uint32_t crtc_id = crtc->id();
ret = drmModeAtomicAddProperty(pset, crtc_id, crtc->left_margin_property().id(), left_margin) < 0 ||
drmModeAtomicAddProperty(pset, crtc_id, crtc->right_margin_property().id(), right_margin) < 0 ||
drmModeAtomicAddProperty(pset, crtc_id, crtc->top_margin_property().id(), top_margin) < 0 ||
drmModeAtomicAddProperty(pset, crtc_id, crtc->bottom_margin_property().id(), bottom_margin) < 0;
if (ret) {
ALOGE("Failed to add overscan to pset");
}
return ret;
}
int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp, int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp,
bool test_only) { bool test_only) {
ATRACE_CALL(); ATRACE_CALL();
@ -1094,67 +1137,22 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp,
return -ENOMEM; return -ENOMEM;
} }
if (crtc->can_overscan()) { if (forceOverscan_ && crtc->can_overscan()) {
char overscan[PROPERTY_VALUE_MAX];
int left_margin = 100, right_margin= 100, top_margin = 100, bottom_margin = 100;
DrmConnector *conn = drm_->GetConnectorFromType(display_); DrmConnector *conn = drm_->GetConnectorFromType(display_);
if(conn == NULL) if (!conn) {
{
ALOGE("%s: line=%d display %d connector is NULL", __FUNCTION__, __LINE__, display_); ALOGE("%s: line=%d display %d connector is NULL", __FUNCTION__, __LINE__, display_);
drmModeAtomicFree(pset);
return -ENODEV; return -ENODEV;
} }
DrmMode mode = conn->current_mode();
if(display_comp->mode_3d() != NON_3D || (mode.interlaced() > 0))
{
left_margin = 100;
top_margin = 100;
right_margin = 100;
bottom_margin = 100;
}
else
{
if (display_ == HWC_DISPLAY_PRIMARY){
if(hwc_have_baseparameter()){
property_get("persist." PROPERTY_TYPE ".overscan.main", overscan, "use_baseparameter");
if(!strcmp(overscan,"use_baseparameter"))
hwc_get_baseparameter_config(overscan,display_,BP_OVERSCAN,0);
}else{
property_get("persist." PROPERTY_TYPE ".overscan.main", overscan, "overscan 100,100,100,100");
}
}else{
if(hwc_have_baseparameter()){
property_get("persist." PROPERTY_TYPE ".overscan.aux", overscan, "use_baseparameter");
if(!strcmp(overscan,"use_baseparameter"))
hwc_get_baseparameter_config(overscan,display_,BP_OVERSCAN,0);
}else{
property_get("persist." PROPERTY_TYPE ".overscan.aux", overscan, "overscan 100,100,100,100");
}
}
sscanf(overscan, "overscan %d,%d,%d,%d", &left_margin, &top_margin,
&right_margin, &bottom_margin);
ALOGD_IF(log_level(DBG_VERBOSE),"vop post scale overscan(%d,%d,%d,%d)",
left_margin,top_margin,right_margin,bottom_margin);
}
if (left_margin < OVERSCAN_MIN_VALUE) left_margin = OVERSCAN_MIN_VALUE; if (!conn->built_in()) {
if (top_margin < OVERSCAN_MIN_VALUE) top_margin = OVERSCAN_MIN_VALUE; DrmMode mode = conn->current_mode();
if (right_margin < OVERSCAN_MIN_VALUE) right_margin = OVERSCAN_MIN_VALUE; bool reset = display_comp->mode_3d() != NON_3D || (mode.interlaced() > 0);
if (bottom_margin < OVERSCAN_MIN_VALUE) bottom_margin = OVERSCAN_MIN_VALUE; int ret = CheckOverscan(pset, crtc, display_, reset, conn->unique_name());
if (ret) {
if (left_margin > OVERSCAN_MAX_VALUE) left_margin = OVERSCAN_MAX_VALUE; drmModeAtomicFree(pset);
if (top_margin > OVERSCAN_MAX_VALUE) top_margin = OVERSCAN_MAX_VALUE; return ret;
if (right_margin > OVERSCAN_MAX_VALUE) right_margin = OVERSCAN_MAX_VALUE; }
if (bottom_margin > OVERSCAN_MAX_VALUE) bottom_margin = OVERSCAN_MAX_VALUE;
ret = drmModeAtomicAddProperty(pset, crtc->id(), crtc->left_margin_property().id(), left_margin) < 0 ||
drmModeAtomicAddProperty(pset, crtc->id(), crtc->right_margin_property().id(), right_margin) < 0 ||
drmModeAtomicAddProperty(pset, crtc->id(), crtc->top_margin_property().id(), top_margin) < 0 ||
drmModeAtomicAddProperty(pset, crtc->id(), crtc->bottom_margin_property().id(), bottom_margin) < 0;
if (ret) {
ALOGE("Failed to add overscan to pset");
drmModeAtomicFree(pset);
return ret;
} }
} }

@ -185,6 +185,8 @@ class DrmDisplayCompositor {
void freeRgaBuffers(); void freeRgaBuffers();
#endif #endif
int PrepareFrame(DrmDisplayComposition *display_comp); int PrepareFrame(DrmDisplayComposition *display_comp);
int CheckOverscan(drmModeAtomicReqPtr pset, DrmCrtc *crtc, int display,
bool reset, const char *UniqueName);
int CommitFrame(DrmDisplayComposition *display_comp, bool test_only); int CommitFrame(DrmDisplayComposition *display_comp, bool test_only);
int SquashFrame(DrmDisplayComposition *src, DrmDisplayComposition *dst); int SquashFrame(DrmDisplayComposition *src, DrmDisplayComposition *dst);
int ApplyDpms(DrmDisplayComposition *display_comp); int ApplyDpms(DrmDisplayComposition *display_comp);
@ -196,6 +198,7 @@ class DrmDisplayCompositor {
std::tuple<int, uint32_t> CreateModeBlob(const DrmMode &mode); std::tuple<int, uint32_t> CreateModeBlob(const DrmMode &mode);
std::map<uint32_t, std::string> overscan_;
DrmResources *drm_; DrmResources *drm_;
int display_; int display_;
@ -216,6 +219,7 @@ class DrmDisplayCompositor {
* clearDisplay_ to notify FrameWorker to clear compositions. * clearDisplay_ to notify FrameWorker to clear compositions.
*/ */
bool clearDisplay_; bool clearDisplay_;
bool forceOverscan_;
mutable pthread_mutex_t mode_lock_; mutable pthread_mutex_t mode_lock_;
ModeState mode_; ModeState mode_;

@ -1003,7 +1003,11 @@ int DrmResources::UpdateDisplayRoute(void)
DRM_ATOMIC_ADD_PROP(conn->id(), conn->crtc_id_property().id(), crtc->id()); DRM_ATOMIC_ADD_PROP(conn->id(), conn->crtc_id_property().id(), crtc->id());
DRM_ATOMIC_ADD_PROP(crtc->id(), crtc->mode_property().id(), blob_id[i]); DRM_ATOMIC_ADD_PROP(crtc->id(), crtc->mode_property().id(), blob_id[i]);
DRM_ATOMIC_ADD_PROP(crtc->id(), crtc->active_property().id(), 1); DRM_ATOMIC_ADD_PROP(crtc->id(), crtc->active_property().id(), 1);
if (!conn->built_in() && crtc->can_overscan())
conn->update_overscan(pset, crtc);
} }
/* /*
* Disable unused connector * Disable unused connector
*/ */

Loading…
Cancel
Save