summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorJosé Fonseca <jfonseca@vmware.com>2013-05-25 12:14:29 +0100
committerJosé Fonseca <jfonseca@vmware.com>2013-05-25 12:16:43 +0100
commitcad91cbf99810d8a0b5c778375b424497025bcd9 (patch)
tree9cb787025592b99fee13aabcb92b1bf1e96e6349 /scripts
parentcbac4128897a0346e66a6cacabf083789ef07f83 (diff)
tracecheck: Stop relying on retrace '-c' option.
This option will soon be removed. Also share code with tracecheck.
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/retracediff.py94
-rwxr-xr-xscripts/tracecheck.py72
2 files changed, 100 insertions, 66 deletions
diff --git a/scripts/retracediff.py b/scripts/retracediff.py
index 171622d0..e59d00a5 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 d204fa63..3a2ec452 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