provide drm_output_new_mode interface to create new mode from outsite instead of only from edid or configure.
Signed-off-by: Quanxian Wang <quanxian.w...@intel.com> --- src/compositor-drm.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 154e15e..f988692 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -1390,6 +1390,96 @@ drm_output_add_mode(struct drm_output *output, drmModeModeInfo *info) } static int +drm_output_compare_timing(struct weston_mode *mode, + uint32_t clock, + int hdisplay, + int hsync_start, + int hsync_end, + int htotal, + int vdisplay, + int vsync_start, + int vsync_end, + int vtotal, + int vscan, + uint32_t flags) +{ + struct drm_mode *drmmode = (struct drm_mode *)mode; + drmModeModeInfo *modeinfo = &drmmode->mode_info; + + return (modeinfo->clock == clock && + modeinfo->hdisplay == hdisplay && + modeinfo->hsync_start == hsync_start && + modeinfo->hsync_end == hsync_end && + modeinfo->htotal == htotal && + modeinfo->vdisplay == vdisplay && + modeinfo->vsync_start == vsync_start && + modeinfo->vsync_end == vsync_end && + modeinfo->vtotal == vtotal && + modeinfo->vscan == vscan && + modeinfo->flags == flags); +} + +static struct weston_mode * +drm_output_new_timing(struct weston_output *output, + uint32_t clock, + int hdisplay, + int hsync_start, + int hsync_end, + int htotal, + int vdisplay, + int vsync_start, + int vsync_end, + int vtotal, + int vscan, + uint32_t flags) +{ + drmModeModeInfo *modeinfo; + struct drm_mode *mode = NULL; + uint64_t refresh; + + modeinfo = zalloc(sizeof(*modeinfo)); + if (modeinfo == NULL) + return NULL; + + modeinfo->type = DRM_MODE_TYPE_USERDEF; + modeinfo->hskew = 0; + modeinfo->hdisplay = hdisplay; + modeinfo->hsync_start = hsync_start; + modeinfo->hsync_end = hsync_end; + modeinfo->htotal = htotal; + modeinfo->vdisplay = vdisplay; + modeinfo->vsync_start = vsync_start; + modeinfo->vsync_end = vsync_end; + modeinfo->vtotal = vtotal; + modeinfo->vscan = vscan; + modeinfo->flags = flags; + modeinfo->clock = clock; + + /* Calculate higher precision (mHz) refresh rate */ + refresh = (clock * 1000000LL / htotal + + vtotal / 2) / vtotal; + + if (flags & DRM_MODE_FLAG_INTERLACE) + refresh *= 2; + if (flags & DRM_MODE_FLAG_DBLSCAN) + refresh /= 2; + if (vscan > 1) + refresh /= vscan; + + /* For new timing, there is no set for vrefresh. + * But in choose_mode, it will check with refresh value. + * So set vrefresh value to be refresh. + */ + modeinfo->vrefresh = refresh; + + mode = drm_output_add_mode((struct drm_output *)output, modeinfo); + if (mode) + return &mode->base; + else + return NULL; +} + +static int drm_subpixel_to_wayland(int drm_value) { switch (drm_value) { @@ -2046,6 +2136,8 @@ create_output_for_connector(struct drm_compositor *ec, output->base.assign_planes = drm_assign_planes; output->base.set_dpms = drm_set_dpms; output->base.switch_mode = drm_output_switch_mode; + output->base.new_timing = drm_output_new_timing; + output->base.compare_timing = drm_output_compare_timing; output->base.gamma_size = output->original_crtc->gamma_size; output->base.set_gamma = drm_output_set_gamma; -- 1.8.1.2 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel