From d715ed3402bb1fd5caba3bc2c0b2f1d1a4fbfdab Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Tue, 6 Jul 2010 14:09:19 +0200 Subject: [PATCH] hda-analyzer: fix graph creation - tests with Lenovo T61 showed more poblems when the connection graph is rendered Signed-off-by: Jaroslav Kysela --- hda-analyzer/hda_codec.py | 54 +++++++++++++++++++++++++++++++-------- hda-analyzer/hda_graph.py | 53 +++++++++++++++++++++++++++++--------- 2 files changed, 84 insertions(+), 23 deletions(-) diff --git a/hda-analyzer/hda_codec.py b/hda-analyzer/hda_codec.py index bdf008d..8ff9267 100644 --- a/hda-analyzer/hda_codec.py +++ b/hda-analyzer/hda_codec.py @@ -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)): diff --git a/hda-analyzer/hda_graph.py b/hda-analyzer/hda_graph.py index 1ac6987..7700f29 100755 --- a/hda-analyzer/hda_graph.py +++ b/hda-analyzer/hda_graph.py @@ -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) -- 2.47.1