]> git.alsa-project.org Git - alsa.git/commitdiff
hda-analyzer: fix graph creation
authorJaroslav Kysela <perex@t61.perex-int.cz>
Tue, 6 Jul 2010 12:09:19 +0000 (14:09 +0200)
committerJaroslav Kysela <perex@perex.cz>
Tue, 6 Jul 2010 12:09:19 +0000 (14:09 +0200)
- tests with Lenovo T61 showed more poblems when the connection graph
  is rendered

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
hda-analyzer/hda_codec.py
hda-analyzer/hda_graph.py

index bdf008dd90102fcacdedc4d724a30fe82a68849f..8ff9267a2a2bfaee73b200cf770cce644202f3c3 100644 (file)
@@ -1233,7 +1233,7 @@ class HDACodec:
         res += 1
     return res
 
-  def graph(self, dump=False):
+  def graph(self, dump=False, prefer_x=None, prefer_y=None):
   
     def mfind(nid):
       for y in range(len(res)):
@@ -1252,7 +1252,7 @@ class HDACodec:
             x = 1
             y += 1
           if y >= len(res) - 1:
-            raise ValueError, "cannot place nid to graph matrix"
+            return False
           if res[y][x+1] is None and \
              res[y][x-1] is None and \
              res[y+1][x] is None and \
@@ -1297,15 +1297,19 @@ class HDACodec:
           return doplace(nid, y+1, 1)
         if x+1 < len(res[0]):
           return doplace(nid, 1, x+1)
-        raise ValueError, "cannot place nid to graph matrix"
-      return False
+        return False
+      return None
   
+    error = 0
     res = []
     unplaced = []
     # determine all termination widgets
     terms = {'AUD_IN':[], 'AUD_OUT':[], 'PIN_IN':[], 'PIN_OUT':[]}
+    mixes = 0
     for nid in self.nodes:
       node = self.nodes[nid]
+      if node.wtype_id == 'AUD_MIX':
+        mixes += 1
       if node.wtype_id in ['AUD_IN', 'AUD_OUT', 'PIN']:
         id = node.wtype_id
         if id == 'PIN':
@@ -1316,10 +1320,21 @@ class HDACodec:
     for id in terms:
       terms[id].sort()
     # build the matrix
-    x = max(len(terms['AUD_IN']), len(terms['AUD_OUT'])) + 2
-    y = max(len(terms['PIN_IN']), len(terms['PIN_OUT'])) + 2
-    if x == 2 and y == 2:
+    if prefer_x:
+      x = prefer_x
+    else:
+      x = max(len(terms['AUD_IN']), len(terms['AUD_OUT'])) + 2
+    if prefer_y:
+      y = prefer_y
+    else:
+      y = max(len(terms['PIN_IN']), len(terms['PIN_OUT'])) + 2
+    if x <= 2 and y <= 2:
       return None
+    while (x - 2) * (y - 2) < mixes * 9:
+      if x <= y:
+        x += 1
+      else:
+        y += 1
     for a in range(y):
       res.append([None]*x)
     if 'PIN_IN' in terms:
@@ -1343,7 +1358,7 @@ class HDACodec:
       res.insert(-2, [None]*x)
     # assign unplaced nids - check connections
     unplaced.sort()
-    while unplaced:
+    while unplaced and not error:
       change = len(unplaced)
       for idx in range(len(res)):
         for idx1 in range(len(res[idx])):
@@ -1354,8 +1369,15 @@ class HDACodec:
           if not node or not node.connections:
             continue
           for conn in node.connections:
-            if conn in unplaced and doplace(conn, idx, idx1):
-              unplaced.remove(conn)
+            if conn in unplaced:
+              pl = doplace(conn, idx, idx1)
+              if pl is True:
+                unplaced.remove(conn)
+              elif pl is None:
+                error += 1
+                break
+      if error:
+        break
       for nid in unplaced:
         node = self.nodes[nid]
         if not node.connections:
@@ -1363,9 +1385,17 @@ class HDACodec:
         for conn in node.connections:
           placed = False
           y, x = mfind(nid)
-          if doplace(nid, y, x):
+          if not y or not x:
+            continue
+          pl = doplace(nid, y, x)
+          if pl is True:
             unplaced.remove(nid)
             break
+          elif pl is None:
+            error += 1
+            break
+        if error:
+          break
       if len(unplaced) == change:
         break
     y = len(res)
@@ -1378,6 +1408,8 @@ class HDACodec:
       if x >= len(res[0]):
         y += 1
         x = 0
+    if error:
+      return self.graph(dump=dump, prefer_x=x+2, prefer_y=y+2)
     # do extra check
     check = []
     for y in range(len(res)):
index 1ac6987d298e4a2155e53d9489ddaccc51353b01..7700f29f8a2a9c8f4b0002ef24197f5f956d3724 100755 (executable)
@@ -128,6 +128,7 @@ class Route:
     self.src = src_node
     self.dst = dst_node
     self.lines = []
+    self.wronglines = []
     self.analyze_routes(routes, nodes)
     src_node.dst_routes.append(self)
     dst_node.src_routes.append(self)
@@ -170,6 +171,13 @@ class Route:
       cr.line_to(line[2], line[3])
       cr.stroke()
 
+    for line in self.wronglines:
+      cr.set_line_width(1.5)
+      cr.set_source_rgb(1, 0, 0)
+      cr.move_to(line[0], line[1])
+      cr.line_to(line[2], line[3])
+      cr.stroke()
+
   def select_line(self, routes, nodes, possible):
 
     def check_dot(posx, posy, line):
@@ -278,11 +286,19 @@ class Route:
       if tryit == 2:
         r = range(-height-extra+5, -height-5, 5)
         r.reverse()
+      x1 = x + 5 + fixup
+      x2 = sel[0] - fixup
+      if x1 > x2:
+        sub = width/2
+        x1 = x + sub + fixup
+        sub -= 5
+      else:
+        sub = 0
       for i in range(tryit*extra, (tryit+1)*extra-5-1, 5):
-        possible.append([x+5+fixup, sel[1]+i, sel[0]-fixup, sel[1]+i])
+        possible.append([x1, sel[1]+i, x2, sel[1]+i])
       sel1 = self.select_line(routes, nodes, possible)
       if sel1:
-        sel1[0] -= fixup
+        sel1[0] -= fixup + sub
         sel1[2] += fixup
         possible = []
         for j in range(0, width/2-10, 5):
@@ -296,7 +312,7 @@ class Route:
           tryit = -1
           break
     if tryit >= 0:
-      self.lines.append([x+5, y, sel[0], sel[1], 1])
+      self.wronglines.append([x+5, y, sel[0], sel[1]])
       print "[1] displaced route 0x%x->0x%x %s %s" % (self.src.node.nid, self.dst.node.nid, repr(self.lines[-1]), repr(sel))
       res = False
 
@@ -309,11 +325,19 @@ class Route:
       if tryit == 2:
         r = range(-height-extra+5, -height-5, 5)
         r.reverse()
+      sub = width/2
+      x1 = x + sub + fixup
+      x2 = sel[2] - fixup
+      if x1 < x2:
+        x1 = x + 5 + fixup
+        sub = 0
+      else:
+        sub -= 5
       for i in r:
-        possible.append([x+(width/2-1)+fixup, sel[3]+i, sel[2]-fixup, sel[3]+i])
+        possible.append([x1, sel[3]+i, x2, sel[3]+i])
       sel1 = self.select_line(routes, nodes, possible)
       if sel1:
-        sel1[0] -= fixup + (width/2-1) - 5
+        sel1[0] -= fixup + sub
         sel1[2] += fixup
         possible = []
         for j in range(0, width/2-10, 5):
@@ -327,7 +351,7 @@ class Route:
           tryit = -1
           break
     if tryit >= 0:
-      self.lines.append([x+5, y, sel[2], sel[3], 1])
+      self.wronglines.append([x+5, y, sel[2], sel[3]])
       print "[2] displaced route 0x%x->0x%x %s %s" % (self.src.node.nid, self.dst.node.nid, repr(self.lines[-1]), repr(sel))
       res = False
       
@@ -455,6 +479,8 @@ class CodecGraphLayout(gtk.Layout):
       if not route.finish(self.routes, self.nodes):
         res = False
         break
+    if not res:
+      return
     # final step - optimize drawings
     while 1:
       size = self.compressx(sx)
@@ -585,20 +611,23 @@ class CodecGraphLayout(gtk.Layout):
   def mouse_move(self, widget, event):
     oldpopup = self.popup
     self.popup = None
-    for route in self.routes:
-      route.highlight = False
+    redraw = False
     found = False
+    for route in self.routes:
+      if route.highlight:
+        redraw = True
+        route.highlight = False
     for node in self.nodes:
       if node.mouse_move(event.x, event.y, self):
-        self.queue_draw()
-        found = True
+        found = redraw = True
         break
     if not found:
       for route in self.routes:
         if route.mouse_move(event.x, event.y, self):
-          self.queue_draw()
-          found = True
+          found = redraw = True
           break
+    if redraw:
+      self.queue_draw()
     if self.popup:
       if oldpopup != self.popup:
         self.show_popup(event)