Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/videomode Remove duplicate video modes.



details:   https://anonhg.NetBSD.org/src/rev/bc3971e17892
branches:  trunk
changeset: 763978:bc3971e17892
user:      jdc <jdc%NetBSD.org@localhost>
date:      Sat Apr 09 18:18:28 2011 +0000

description:
Remove duplicate video modes.

When parsing the established and the detailed timings, check to see if this
mode already exists in our mode list.  If the mode exists when parsing
established timings, then do nothing (we already have this exact mode).  If
the mode exists when parsing detailed timings, then replace our timings with
the timings from the monitor.

diffstat:

 sys/dev/videomode/edid.c |  68 ++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 54 insertions(+), 14 deletions(-)

diffs (123 lines):

diff -r 3736746ad2b8 -r bc3971e17892 sys/dev/videomode/edid.c
--- a/sys/dev/videomode/edid.c  Sat Apr 09 17:55:51 2011 +0000
+++ b/sys/dev/videomode/edid.c  Sat Apr 09 18:18:28 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: edid.c,v 1.8 2011/03/30 18:50:37 jdc Exp $ */
+/* $NetBSD: edid.c,v 1.9 2011/04/09 18:18:28 jdc Exp $ */
 
 /*-
  * Copyright (c) 2006 Itronix Inc.
@@ -32,7 +32,7 @@
  */ 
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: edid.c,v 1.8 2011/03/30 18:50:37 jdc Exp $");
+__KERNEL_RCSID(0, "$NetBSD: edid.c,v 1.9 2011/04/09 18:18:28 jdc Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -300,6 +300,26 @@
        return NULL;
 }
 
+static struct videomode *
+edid_search_mode(struct edid_info *edid, const struct videomode *mode)
+{
+       int     refresh, i;
+
+       refresh = DIVIDE(DIVIDE(mode->dot_clock * 1000,
+           mode->htotal), mode->vtotal);
+       for (i = 0; i < edid->edid_nmodes; i++) {
+               if (mode->hdisplay == edid->edid_modes[i].hdisplay &&
+                   mode->vdisplay == edid->edid_modes[i].vdisplay &&
+                   refresh == DIVIDE(DIVIDE(
+                   edid->edid_modes[i].dot_clock * 1000,
+                   edid->edid_modes[i].htotal),
+                   edid->edid_modes[i].vtotal)) {
+                       return &(edid->edid_modes[i]);
+               }
+       }
+       return NULL;
+}
+
 static int
 edid_std_timing(uint8_t *data, struct videomode *vmp)
 {
@@ -373,7 +393,7 @@
        vsyncwid = EDID_DET_TIMING_VSYNC_WIDTH(data);
        vsyncoff = EDID_DET_TIMING_VSYNC_OFFSET(data);
        
-       /* XXX: I'm not doing anything with the borders, should I? */
+       /* Borders are contained within the blank areas. */
 
        vmp->hdisplay = hactive;
        vmp->htotal = hactive + hblank;
@@ -406,16 +426,27 @@
 edid_block(struct edid_info *edid, uint8_t *data)
 {
        int                     i;
-       struct videomode        mode;
+       struct videomode        mode, *exist_mode;
 
        if (EDID_BLOCK_IS_DET_TIMING(data)) {
                if (edid_det_timing(data, &mode)) {
-                       edid->edid_modes[edid->edid_nmodes] = mode;
-                       if (edid->edid_preferred_mode == NULL) {
-                               edid->edid_preferred_mode =
-                                   &edid->edid_modes[edid->edid_nmodes];
+                       /* Does this mode already exist? */
+                       exist_mode = edid_search_mode(edid, &mode);
+                       if (exist_mode != NULL) {
+                               memcpy(exist_mode, &mode,
+                                   sizeof(struct videomode));
+                               if (edid->edid_preferred_mode == NULL) {
+                                       edid->edid_preferred_mode =
+                                           exist_mode;
+                               }
+                       } else {
+                               edid->edid_modes[edid->edid_nmodes] = mode;
+                               if (edid->edid_preferred_mode == NULL) {
+                                       edid->edid_preferred_mode =
+                                           &edid->edid_modes[edid->edid_nmodes];
+                               }
+                               edid->edid_nmodes++;    
                        }
-                       edid->edid_nmodes++;    
                }
                return;
        }
@@ -473,8 +504,13 @@
                data += EDID_DESC_STD_TIMING_START;
                for (i = 0; i < EDID_DESC_STD_TIMING_COUNT; i++) {
                        if (edid_std_timing(data, &mode)) {
-                               edid->edid_modes[edid->edid_nmodes] = mode;
-                               edid->edid_nmodes++;
+                               /* Does this mode already exist? */
+                               exist_mode = edid_search_mode(edid, &mode);
+                               if (exist_mode == NULL) {
+                                       edid->edid_modes[edid->edid_nmodes] =
+                                           mode;
+                                       edid->edid_nmodes++;
+                               }
                        }
                        data += 2;
                }
@@ -574,11 +610,15 @@
 
        /* do standard timing section */
        for (i = 0; i < EDID_STD_TIMING_COUNT; i++) {
-               struct videomode        mode;
+               struct videomode        mode, *exist_mode;
                if (edid_std_timing(data + EDID_OFFSET_STD_TIMING + i * 2,
                        &mode)) {
-                       edid->edid_modes[edid->edid_nmodes] = mode;
-                       edid->edid_nmodes++;
+                       /* Does this mode already exist? */
+                       exist_mode = edid_search_mode(edid, &mode);
+                       if (exist_mode == NULL) {
+                               edid->edid_modes[edid->edid_nmodes] = mode;
+                               edid->edid_nmodes++;
+                       }
                }
        }
 



Home | Main Index | Thread Index | Old Index