From: José Fonseca Date: Sat, 25 May 2013 11:14:29 +0000 (+0100) Subject: tracecheck: Stop relying on retrace '-c' option. X-Git-Url: https://git.cworth.org/git?a=commitdiff_plain;h=cad91cbf99810d8a0b5c778375b424497025bcd9;p=apitrace tracecheck: Stop relying on retrace '-c' option. This option will soon be removed. Also share code with tracecheck. --- diff --git a/scripts/retracediff.py b/scripts/retracediff.py index 171622d..e59d00a 100755 --- a/scripts/retracediff.py +++ b/scripts/retracediff.py @@ -48,31 +48,60 @@ else: NULL = open('/dev/null', 'wt') -class Setup: +class RetraceRun: - def __init__(self, args, env=None): + def __init__(self, process): + self.process = process + + def nextSnapshot(self): + image, comment = read_pnm(self.process.stdout) + if image is None: + return None, None + + callNo = int(comment.strip()) + + return image, callNo + + def terminate(self): + try: + self.process.terminate() + except OSError: + # Avoid http://bugs.python.org/issue14252 + pass + + +class Retracer: + + def __init__(self, retraceExe, args, env=None): + self.retraceExe = retraceExe self.args = args self.env = env - def _retrace(self, args): + def _retrace(self, args, stdout=subprocess.PIPE): cmd = [ - options.retrace, + self.retraceExe, ] + args + self.args if self.env: for name, value in self.env.iteritems(): sys.stderr.write('%s=%s ' % (name, value)) sys.stderr.write(' '.join(cmd) + '\n') try: - return subprocess.Popen(cmd, env=self.env, stdout=subprocess.PIPE, stderr=NULL) + return subprocess.Popen(cmd, env=self.env, stdout=stdout, stderr=NULL) except OSError, ex: sys.stderr.write('error: failed to execute %s: %s\n' % (cmd[0], ex.strerror)) sys.exit(1) - def retrace(self): - return self._retrace([ + def retrace(self, args): + p = self._retrace([]) + p.wait() + return p.returncode + + def snapshot(self, call_nos): + process = self._retrace([ '-s', '-', - '-S', options.snapshot_frequency, + '-S', call_nos, ]) + return RetraceRun(process) def dump_state(self, call_no): '''Get the state dump at the specified call no.''' @@ -206,8 +235,8 @@ def main(): if options.src_driver: options.src_args.insert(0, '--driver=' + options.src_driver) - ref_setup = Setup(options.ref_args + args, ref_env) - src_setup = Setup(options.src_args + args, src_env) + refRetracer = Retracer(options.retrace, options.ref_args + args, ref_env) + srcRetracer = Retracer(options.retrace, options.src_args + args, src_env) if options.output: output = open(options.output, 'wt') @@ -220,27 +249,26 @@ def main(): last_bad = -1 last_good = 0 - ref_proc = ref_setup.retrace() + refRun = refRetracer.snapshot(options.snapshot_frequency) try: - src_proc = src_setup.retrace() + srcRun = srcRetracer.snapshot(options.snapshot_frequency) try: while True: # Get the reference image - ref_image, ref_comment = read_pnm(ref_proc.stdout) - if ref_image is None: + refImage, refCallNo = refRun.nextSnapshot() + if refImage is None: break # Get the source image - src_image, src_comment = read_pnm(src_proc.stdout) - if src_image is None: + srcImage, srcCallNo = srcRun.nextSnapshot() + if srcImage is None: break - assert ref_comment == src_comment - - call_no = int(ref_comment.strip()) + assert refCallNo == srcCallNo + callNo = refCallNo # Compare the two images - comparer = Comparer(ref_image, src_image) + comparer = Comparer(refImage, srcImage) precision = comparer.precision() mismatch = precision < options.threshold @@ -248,38 +276,30 @@ def main(): if mismatch: highligher.color(highligher.red) highligher.bold() - highligher.write('%u\t%f\n' % (call_no, precision)) + highligher.write('%u\t%f\n' % (callNo, precision)) if mismatch: highligher.normal() if mismatch: if options.diff_prefix: - prefix = os.path.join(options.diff_prefix, '%010u' % call_no) + prefix = os.path.join(options.diff_prefix, '%010u' % callNo) prefix_dir = os.path.dirname(prefix) if not os.path.isdir(prefix_dir): os.makedirs(prefix_dir) - ref_image.save(prefix + '.ref.png') - src_image.save(prefix + '.src.png') + refImage.save(prefix + '.ref.png') + srcImage.save(prefix + '.src.png') comparer.write_diff(prefix + '.diff.png') if last_bad < last_good: - src_setup.diff_state(last_good, call_no, output) - last_bad = call_no + srcRetracer.diff_state(last_good, callNo, output) + last_bad = callNo else: - last_good = call_no + last_good = callNo highligher.flush() finally: - try: - src_proc.terminate() - except OSError: - # Avoid http://bugs.python.org/issue14252 - pass + srcRun.terminate() finally: - try: - ref_proc.terminate() - except OSError: - # Avoid http://bugs.python.org/issue14252 - pass + refRun.terminate() if __name__ == '__main__': diff --git a/scripts/tracecheck.py b/scripts/tracecheck.py index d204fa6..3a2ec45 100755 --- a/scripts/tracecheck.py +++ b/scripts/tracecheck.py @@ -39,6 +39,9 @@ import subprocess import sys import traceback +import snapdiff +import retracediff + def good(): '''Tell git-bisect that this commit is good.''' @@ -142,9 +145,9 @@ def main(): # implementation is usable, and is the right one (i.e., we didn't fallback # to a different OpenGL implementation due to missing symbols). if platform.system() != 'Windows' and which('glxinfo'): - p = subprocess.Popen(['glxinfo'], stdout=subprocess.PIPE) - stdout, stderr = p.communicate() - if p.returncode: + glxinfo = subprocess.Popen(['glxinfo'], stdout=subprocess.PIPE) + stdout, stderr = glxinfo.communicate() + if glxinfo.returncode: skip() # Search for the GL_RENDERER string @@ -164,34 +167,45 @@ def main(): skip() # Run glretrace - command = [options.retrace] - if options.compare_prefix: - command += ['-c', options.compare_prefix] - else: - command += ['-b'] - command += args - sys.stdout.write(' '.join(command) + '\n') - sys.stdout.flush() - p = subprocess.Popen(command, stdout=subprocess.PIPE) - stdout, stderr = p.communicate() - if p.returncode: - if not options.compare_prefix: - bad() - else: - skip() + + retracer = retracediff.Retracer(options.retrace, args) if options.compare_prefix: - failed = False - precision_re = re.compile('^Snapshot (\S+) average precision of (\S+) bits$') - for line in stdout.split('\n'): - mo = precision_re.match(line) - if mo: - print line - call_no = int(mo.group(1)) - precision = float(mo.group(2)) - if precision < options.precision_threshold: - failed = True - if failed: + refImages = {} + callNos = [] + + images = snapdiff.find_images(options.compare_prefix) + images.sort() + for image in images: + imageName, ext = os.path.splitext(image) + try: + callNo = int(imageName) + except ValueError: + continue + refImages[callNo] = options.compare_prefix + image + callNos.append(callNo) + + run = retracer.snapshot(','.join(map(str, callNos))) + while True: + srcImage, callNo = run.nextSnapshot() + if srcImage is None: + break + + refImage = refImages[callNo] + + # Compare the two images + comparer = snapdiff.Comparer(refImage, srcImage) + precision = comparer.precision() + + mismatch = precision < options.precision_threshold + if mismatch: + bad() + run.process.wait() + if run.process.returncode: + skip() + else: + returncode = retracer.retrace('-b') + if returncode: bad() # TODO: allow more criterias here, such as, performance threshold