from base_driver import *
-class RefTraceParser(tracematch.RefTraceParser):
-
- def __init__(self, fileName):
- tracematch.RefTraceParser.__init__(self, open(fileName, 'rt'))
- self.fileName = fileName
- self.images = []
- self.states = []
- self.pragmaNo = 0
-
- def handlePragma(self, line):
- if self.calls:
- lastCall = self.calls[-1]
- if lastCall.callNo is None:
- paramName = 'pragma%u' % self.pragmaNo
- lastCall.callNo = tracematch.WildcardMatcher(paramName)
- else:
- paramName = lastCall.callNo.name
- else:
- paramName = 0
- self.pragmaNo += 1
-
- pragma, rest = line.split(None, 1)
- if pragma == '#image':
- imageFileName = self.getAbsPath(rest)
- self.images.append((paramName, imageFileName))
- elif pragma == '#state':
- stateFileName = self.getAbsPath(rest)
- self.states.append((paramName, stateFileName))
- else:
- assert False
-
- def getAbsPath(self, path):
- '''Get the absolute from a path relative to the reference filename'''
- return os.path.abspath(os.path.join(os.path.dirname(self.fileName), path))
-
-
class SrcTraceParser(tracematch.SrcTraceParser):
def __init__(self, stream):
self.swapbuffers += 1
-class TraceChecker:
-
- def __init__(self, srcStream, refFileName):
- self.srcStream = srcStream
- self.refFileName = refFileName
- self.doubleBuffer = False
- self.callNo = 0
- self.images = []
- self.states = []
-
- def check(self):
- srcParser = SrcTraceParser(self.srcStream)
- srcTrace = srcParser.parse()
- self.doubleBuffer = srcParser.swapbuffers > 0
-
- if self.refFileName:
- refParser = RefTraceParser(self.refFileName)
- refTrace = refParser.parse()
-
- try:
- mo = refTrace.match(srcTrace)
- except tracematch.TraceMismatch, ex:
- self.fail(str(ex))
-
- for paramName, imageFileName in refParser.images:
- if isinstance(paramName, int):
- callNo = paramName
- else:
- callNo = mo.params[paramName]
- self.images.append((callNo, imageFileName))
- for paramName, stateFileName in refParser.states:
- if isinstance(paramName, int):
- callNo = paramName
- else:
- callNo = mo.params[paramName]
- self.states.append((callNo, stateFileName))
-
-
class AppDriver(Driver):
cmd = None
if not self.cmd:
return
+ sys.stderr.write('Run application...\n')
+
p = popen(self.cmd, cwd=self.cwd)
p.wait()
if p.returncode != 0:
skip('application returned code %i' % p.returncode)
+ sys.stdout.flush()
+ sys.stderr.write('\n')
+
api_trace_map = {
'gl': 'gl',
'egl_gl': 'egl',
'd3d11_1': 'd3d11',
}
- api_retrace_map = {
- 'gl': 'glretrace',
- 'egl_gl': 'eglretrace',
- 'egl_gles1': 'eglretrace',
- 'egl_gles2': 'eglretrace',
- #'d3d8': 'd3dretrace',
- 'd3d9': 'd3dretrace',
- 'd3d10': 'd3dretrace',
- 'd3d10_1': 'd3dretrace',
- 'd3d11': 'd3dretrace',
- 'd3d11_1': 'd3dretrace',
+ api_replay_map = {
+ 'gl': 'glreplay',
+ 'egl_gl': 'eglreplay',
+ 'egl_gles1': 'eglreplay',
+ 'egl_gles2': 'eglreplay',
+ 'd3d8': 'd3dreplay',
+ 'd3d9': 'd3dreplay',
+ 'd3d10': 'd3dreplay',
+ 'd3d10_1': 'd3dreplay',
+ 'd3d11': 'd3dreplay',
+ 'd3d11_1': 'd3dreplay',
}
def traceApp(self):
if not self.cmd:
return
+ sys.stderr.write('Capturing trace...\n')
+
if self.trace_file is None:
if self.ref_dump is not None:
name = self.ref_dump
cmd = [
options.apitrace, 'trace',
- '--api', self.api_trace_map[self.api],
- '--output', self.trace_file,
+ '-v',
+ '-a', self.api_trace_map[self.api],
+ '-o', self.trace_file,
'--'
] + cmd
if self.max_frames is not None:
if not os.path.exists(self.trace_file):
fail('no trace file generated\n')
+
+ sys.stdout.flush()
+ sys.stderr.write('\n')
def checkTrace(self):
- cmd = [options.apitrace, 'dump', '--color=never', self.trace_file]
- p = popen(cmd, stdout=subprocess.PIPE)
+ sys.stderr.write('Comparing trace %s against %s...\n' % (self.trace_file, self.ref_dump))
+
+ cmd = [options.apitrace, 'dump', '--verbose', '--color=never', self.trace_file]
+ p = popen(cmd, stdout=subprocess.PIPE, universal_newlines=True)
+
+ srcParser = SrcTraceParser(p.stdout)
+ srcTrace = srcParser.parse()
+ self.doubleBuffer = srcParser.swapbuffers > 0
+
+ images = []
+ states = []
+
+ if self.ref_dump:
+ refParser = tracematch.RefTraceParser(self.ref_dump)
+ refTrace = refParser.parse()
- checker = TraceChecker(p.stdout, self.ref_dump)
- checker.check()
+ try:
+ mo = refTrace.match(srcTrace)
+ except tracematch.TraceMismatch, ex:
+ fail(str(ex))
+
+ dirName, baseName = os.path.split(os.path.abspath(self.ref_dump))
+ prefix, _ = os.path.splitext(baseName)
+ prefix += '.'
+ fileNames = os.listdir(dirName)
+ for fileName in fileNames:
+ if fileName.startswith(prefix) and fileName != self.ref_dump:
+ rest = fileName[len(prefix):]
+ paramName, ext = os.path.splitext(rest)
+ if ext in ('.json', '.png'):
+ if paramName.isdigit():
+ callNo = int(paramName)
+ else:
+ try:
+ callNo = mo.params[paramName]
+ except KeyError:
+ fail('could not find parameter %s for %s' % (paramName, fileName))
+ filePath = os.path.join(dirName, fileName)
+ if ext == '.png':
+ images.append((callNo, filePath))
+ if ext == '.json':
+ states.append((callNo, filePath))
p.wait()
if p.returncode != 0:
fail('`apitrace dump` returned code %i' % p.returncode)
- self.doubleBuffer = checker.doubleBuffer
+ sys.stdout.flush()
+ sys.stderr.write('\n')
- if self.api not in self.api_retrace_map:
+ if self.api not in self.api_replay_map:
return
- for callNo, refImageFileName in checker.images:
+ for callNo, refImageFileName in images:
self.checkImage(callNo, refImageFileName)
- for callNo, refStateFileName in checker.states:
+ for callNo, refStateFileName in states:
self.checkState(callNo, refStateFileName)
def checkImage(self, callNo, refImageFileName):
+ sys.stderr.write('Comparing snapshot from call %u against %s...\n' % (callNo, refImageFileName))
try:
from PIL import Image
except ImportError:
+ sys.stderr.write('warning: PIL not found, skipping image comparison\n');
return
srcImage = self.getImage(callNo)
comparer.write_diff(diffImageFileName)
fail('snapshot from call %u does not match %s' % (callNo, refImageFileName))
+ sys.stdout.flush()
+ sys.stderr.write('\n')
+
def checkState(self, callNo, refStateFileName):
+ sys.stderr.write('Comparing state dump from call %u against %s...\n' % (callNo, refStateFileName))
+
srcState = self.getState(callNo)
refState = self.getRefState(refStateFileName)
differ.visit(refState, srcState)
fail('state from call %u does not match %s' % (callNo, refStateFileName))
+ sys.stdout.flush()
+ sys.stderr.write('\n')
+
def getRefState(self, refStateFileName):
stream = open(refStateFileName, 'rt')
from jsondiff import load
s = json.dumps(state, sort_keys=True, indent=2)
open(filename, 'wt').write(s)
- def retrace(self):
- if self.api not in self.api_retrace_map:
+ def replay(self):
+ if self.api not in self.api_replay_map:
return
- p = self._retrace()
+ sys.stderr.write('Retracing %s...\n' % (self.trace_file,))
+
+ p = self._replay()
p.wait()
if p.returncode != 0:
- fail('retrace failed with code %i' % (p.returncode))
+ fail('replay failed with code %i' % (p.returncode))
+
+ sys.stdout.flush()
+ sys.stderr.write('\n')
def getImage(self, callNo):
from PIL import Image
state = self.getState(callNo)
if self.doubleBuffer:
- attachments = ['GL_BACK', 'GL_BACK_LEFT', 'GL_BACK_RIGHT', 'GL_COLOR_ATTACHMENT0']
+ attachments = ['GL_BACK', 'GL_BACK_LEFT', 'GL_BACK_RIGHT', 'GL_COLOR_ATTACHMENT0', 'RENDER_TARGET_0']
else:
- attachments = ['GL_FRONT', 'GL_FRONT_LEFT', 'GL_FRONT_RIGHT', 'GL_COLOR_ATTACHMENT0']
+ attachments = ['GL_FRONT', 'GL_FRONT_LEFT', 'GL_FRONT_RIGHT', 'GL_COLOR_ATTACHMENT0', 'RENDER_TARGET_0']
imageObj = self.getFramebufferAttachment(state, attachments)
data = imageObj['__data__']
stream = StringIO(base64.b64decode(data))
im = Image.open(stream)
- im.save('test.png')
return im
def getFramebufferAttachment(self, state, attachments):
else:
return state
- p = self._retrace(['-D', str(callNo)])
+ p = self._replay(['-D', str(callNo)])
state = json.load(p.stdout, strict=False)
p.wait()
if p.returncode != 0:
- fail('retrace returned code %i' % (p.returncode))
+ fail('replay returned code %i' % (p.returncode))
self.adjustSrcState(state)
except KeyError:
pass
- def _retrace(self, args = None, stdout=subprocess.PIPE):
- retrace = self.api_retrace_map[self.api]
- #cmd = [get_build_program(retrace)]
- cmd = [options.apitrace, 'retrace']
+ def _replay(self, args = None, stdout=subprocess.PIPE):
+ replay = self.api_replay_map[self.api]
+ #cmd = [get_build_program(replay)]
+ cmd = [options.apitrace, 'replay']
if self.doubleBuffer:
cmd += ['-db']
else:
self.runApp()
self.traceApp()
self.checkTrace()
- self.retrace()
+ self.replay()
pass_()