mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2026-05-07 13:08:04 +02:00
drm: Track VIC for modes
Some modes are "standard", and have a VIC (Video Identification Code). Try to figure out if the modes available to us have an associated VIC, store it and print it. This is preparation for eventually enabling YUV420 support, which is only supported on a per-mode basis. Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
This commit is contained in:
parent
36e95611ec
commit
3b33d4fab7
2 changed files with 109 additions and 1 deletions
|
|
@ -293,6 +293,7 @@ struct drm_mode {
|
|||
struct weston_mode base;
|
||||
drmModeModeInfo mode_info;
|
||||
uint32_t blob_id;
|
||||
uint8_t vic;
|
||||
};
|
||||
|
||||
enum drm_fb_type {
|
||||
|
|
|
|||
|
|
@ -100,6 +100,27 @@ drm_to_weston_mode_aspect_ratio(uint32_t drm_mode_flags)
|
|||
}
|
||||
}
|
||||
|
||||
static enum di_cta_video_format_picture_aspect_ratio
|
||||
drm_to_cta_aspect_ratio(uint32_t drm_mode_flags, bool *valid)
|
||||
{
|
||||
*valid = true;
|
||||
|
||||
switch (drm_mode_flags & DRM_MODE_FLAG_PIC_AR_MASK) {
|
||||
case DRM_MODE_FLAG_PIC_AR_4_3:
|
||||
return DI_CTA_VIDEO_FORMAT_PICTURE_ASPECT_RATIO_4_3;
|
||||
case DRM_MODE_FLAG_PIC_AR_16_9:
|
||||
return DI_CTA_VIDEO_FORMAT_PICTURE_ASPECT_RATIO_16_9;
|
||||
case DRM_MODE_FLAG_PIC_AR_64_27:
|
||||
return DI_CTA_VIDEO_FORMAT_PICTURE_ASPECT_RATIO_64_27;
|
||||
case DRM_MODE_FLAG_PIC_AR_256_135:
|
||||
return DI_CTA_VIDEO_FORMAT_PICTURE_ASPECT_RATIO_256_135;
|
||||
case DRM_MODE_FLAG_PIC_AR_NONE:
|
||||
default:
|
||||
*valid = false;
|
||||
return DI_CTA_VIDEO_FORMAT_PICTURE_ASPECT_RATIO_4_3;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
aspect_ratio_to_string(enum weston_mode_aspect_ratio ratio)
|
||||
{
|
||||
|
|
@ -509,6 +530,85 @@ drm_refresh_rate_mHz(const drmModeModeInfo *info)
|
|||
return refresh;
|
||||
}
|
||||
|
||||
static bool
|
||||
drmmodeinfo_is_fmt(const drmModeModeInfo *info,
|
||||
const struct di_cta_video_format *fmt)
|
||||
{
|
||||
int vfront = info->vsync_start - info->vdisplay;
|
||||
int vsync = info->vsync_end - info->vsync_start;
|
||||
int vback = info->vtotal - info->vsync_end;
|
||||
int hfront = info->hsync_start - info->hdisplay;
|
||||
int hsync = info->hsync_end - info->hsync_start;
|
||||
int hback = info->htotal - info->hsync_end;
|
||||
uint32_t fmt_clock_khz = fmt->pixel_clock_hz / 1000;
|
||||
enum di_cta_video_format_sync_polarity hpol, vpol;
|
||||
bool interlaced = !!(info->flags & DRM_MODE_FLAG_INTERLACE);
|
||||
enum di_cta_video_format_picture_aspect_ratio info_ar;
|
||||
bool valid_ar;
|
||||
|
||||
if (info->flags & DRM_MODE_FLAG_PHSYNC)
|
||||
hpol = DI_CTA_VIDEO_FORMAT_SYNC_POSITIVE;
|
||||
else if (info->flags & DRM_MODE_FLAG_NHSYNC)
|
||||
hpol = DI_CTA_VIDEO_FORMAT_SYNC_NEGATIVE;
|
||||
else
|
||||
return false;
|
||||
|
||||
if (info->flags & DRM_MODE_FLAG_PVSYNC)
|
||||
vpol = DI_CTA_VIDEO_FORMAT_SYNC_POSITIVE;
|
||||
else if (info->flags & DRM_MODE_FLAG_NVSYNC)
|
||||
vpol = DI_CTA_VIDEO_FORMAT_SYNC_NEGATIVE;
|
||||
else
|
||||
return false;
|
||||
|
||||
info_ar = drm_to_cta_aspect_ratio(info->flags, &valid_ar);
|
||||
if (!valid_ar)
|
||||
return false;
|
||||
|
||||
/* The clock match is imprecise because it's already rounded off
|
||||
* in drmModeModeInfo.
|
||||
*/
|
||||
if (info->hdisplay != fmt->h_active ||
|
||||
info->vdisplay != fmt->v_active ||
|
||||
hfront != fmt->h_front ||
|
||||
vfront != fmt->v_front ||
|
||||
hsync != fmt->h_sync ||
|
||||
vsync != fmt->v_sync ||
|
||||
hback != fmt->h_back ||
|
||||
vback != fmt->v_back ||
|
||||
info->clock != fmt_clock_khz ||
|
||||
hpol != fmt->h_sync_polarity ||
|
||||
vpol != fmt->v_sync_polarity ||
|
||||
interlaced != fmt->interlaced ||
|
||||
info_ar != fmt->picture_aspect_ratio)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int
|
||||
match_cta_mode(const drmModeModeInfo *info)
|
||||
{
|
||||
const struct di_cta_video_format *fmt;
|
||||
uint8_t vic;
|
||||
|
||||
/* FIXME: Some day we'll probably get this from libdi high-
|
||||
* level api, but for now we kludge it here.
|
||||
*
|
||||
* The stop at 219 works around an off by one bug in some
|
||||
* releases of libdi, and needs to be 255 when we can
|
||||
* bump version to ensure the fix.
|
||||
*/
|
||||
for (vic = 0; vic < 220; vic++) {
|
||||
fmt = di_cta_video_format_from_vic(vic);
|
||||
if (!fmt)
|
||||
continue;
|
||||
assert(fmt->vic == vic);
|
||||
if (drmmodeinfo_is_fmt(info, fmt))
|
||||
return vic;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a mode to output's mode list
|
||||
*
|
||||
|
|
@ -536,6 +636,8 @@ drm_output_add_mode(struct drm_output *output, const drmModeModeInfo *info)
|
|||
mode->mode_info = *info;
|
||||
mode->blob_id = 0;
|
||||
|
||||
mode->vic = match_cta_mode(info);
|
||||
|
||||
if (info->type & DRM_MODE_TYPE_PREFERRED)
|
||||
mode->base.flags |= WL_OUTPUT_MODE_PREFERRED;
|
||||
|
||||
|
|
@ -583,7 +685,12 @@ drm_output_print_modes(struct drm_output *output)
|
|||
dm = to_drm_mode(m);
|
||||
|
||||
aspect_ratio = aspect_ratio_to_string(m->aspect_ratio);
|
||||
weston_log_continue(STAMP_SPACE "%s@%.1f%s%s%s, %.1f MHz\n",
|
||||
if (dm->vic)
|
||||
weston_log_continue(STAMP_SPACE "VIC %3d, ", dm->vic);
|
||||
else
|
||||
weston_log_continue(STAMP_SPACE " ");
|
||||
|
||||
weston_log_continue("%s@%.1f%s%s%s, %.1f MHz\n",
|
||||
dm->mode_info.name, m->refresh / 1000.0,
|
||||
aspect_ratio,
|
||||
m->flags & WL_OUTPUT_MODE_PREFERRED ?
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue