Flutter Engine
The Flutter Engine
Functions | Variables
pdf-comparison Namespace Reference

Functions

def test_exe (cmd)
 
def print_cmd (cmd, o)
 
def check_call (cmd, **kwargs)
 
def check_output (cmd, **kwargs)
 
def remove (*paths)
 
def timeout (deadline, cmd)
 
def is_same (path1, path2)
 
def getfilesoftype (directory, ending)
 
def get_common_paths (dirs, ext)
 
def printable_path (d)
 
def spawn (cmd)
 
def sysopen (arg)
 
def shard (fn, arglist)
 
def shardsum (fn, arglist)
 
def checkout_worktree (checkoutable)
 
def build_skia (directory, executable)
 
def build_and_run_dm (directory, data_dir)
 
def rasterize (path)
 
def main (control_commitish)
 

Variables

 EXTRA_GN_ARGS = os.environ.get('PDF_COMPARISON_GN_ARGS', '')
 
string REFERENCE_BACKEND = 'gl' if 'PDF_COMPARISON_NOGPU' not in os.environ else '8888'
 
 DPI = float(os.environ.get('PDF_COMPARISON_DPI', 72))
 
string PDF_CONFIG = 'pdf' if 'PDF_COMPARISON_300DPI' not in os.environ else 'pdf300'
 
list BAD_TESTS
 
string NINJA = 'ninja'
 
string PDFIUM_TEST = 'pdfium_test'
 
 NUM_THREADS = int(os.environ.get('PDF_COMPARISON_THREADS', 40))
 
list SOURCES = ['gm']
 
string HTML_HEAD
 
string HTML_TAIL
 
tuple USAGE
 

Function Documentation

◆ build_and_run_dm()

def pdf-comparison.build_and_run_dm (   directory,
  data_dir 
)

Definition at line 227 of file pdf-comparison.py.

227def build_and_run_dm(directory, data_dir):
228 dm = build_skia(directory, 'dm')
229 for source in SOURCES:
230 os.makedirs(os.path.join(data_dir, PDF_CONFIG, source))
231 dm_args = [dm, '--src'] + SOURCES + ['--config', PDF_CONFIG, '-w', data_dir]
232 if BAD_TESTS:
233 dm_args += ['-m'] + ['~^%s$' % x for x in BAD_TESTS]
234 check_call(dm_args, cwd=directory)
235 return dm
236
def check_call(cmd, **kwargs)
def build_and_run_dm(directory, data_dir)
def build_skia(directory, executable)

◆ build_skia()

def pdf-comparison.build_skia (   directory,
  executable 
)

Definition at line 213 of file pdf-comparison.py.

213def build_skia(directory, executable):
214 args = ('--args=is_debug=false'
215 ' extra_cflags=["-DSK_PDF_LESS_COMPRESSION",'
216 ' "-DSK_PDF_BASE85_BINARY"] ')
217 if test_exe('ccache'):
218 args += ' cc_wrapper="ccache"'
219 args += EXTRA_GN_ARGS
220 build_dir = directory + '/out/pdftest'
221 check_call([sys.executable, 'bin/sync'], cwd=directory)
222 check_call([directory + '/bin/gn', 'gen', 'out/pdftest', args],
223 cwd=directory)
224 check_call([NINJA, executable], cwd=build_dir)
225 return os.path.join(build_dir, executable)
226
def test_exe(cmd)

◆ check_call()

def pdf-comparison.check_call (   cmd,
**  kwargs 
)

Definition at line 72 of file pdf-comparison.py.

72def check_call(cmd, **kwargs):
73 print_cmd(cmd, sys.stdout)
74 return subprocess.check_call(cmd, **kwargs)
75
def print_cmd(cmd, o)

◆ check_output()

def pdf-comparison.check_output (   cmd,
**  kwargs 
)

Definition at line 76 of file pdf-comparison.py.

76def check_output(cmd, **kwargs):
77 print_cmd(cmd, sys.stdout)
78 return subprocess.check_output(cmd, **kwargs)
79
def check_output(cmd, **kwargs)

◆ checkout_worktree()

def pdf-comparison.checkout_worktree (   checkoutable)

Definition at line 201 of file pdf-comparison.py.

201def checkout_worktree(checkoutable):
202 directory = os.path.join(tempfile.gettempdir(), 'skpdf_control_tree')
203 commit = check_output(['git', 'rev-parse', checkoutable]).strip()
204 if os.path.isdir(directory):
205 try:
206 check_call(['git', 'checkout', commit], cwd=directory)
207 return directory
208 except subprocess.CalledProcessError:
209 shutil.rmtree(directory)
210 check_call(['git', 'worktree', 'add', '-f', directory, commit])
211 return directory
212
def checkout_worktree(checkoutable)

◆ get_common_paths()

def pdf-comparison.get_common_paths (   dirs,
  ext 
)

Definition at line 114 of file pdf-comparison.py.

114def get_common_paths(dirs, ext):
115 return sorted(list(
116 set.intersection(*(set(getfilesoftype(d, ext)) for d in dirs))))
117
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not set
Definition: switches.h:76
def getfilesoftype(directory, ending)
def get_common_paths(dirs, ext)

◆ getfilesoftype()

def pdf-comparison.getfilesoftype (   directory,
  ending 
)

Definition at line 107 of file pdf-comparison.py.

107def getfilesoftype(directory, ending):
108 for dirpath, _, filenames in os.walk(directory):
109 rp = os.path.normpath(os.path.relpath(dirpath, directory))
110 for f in filenames:
111 if f.endswith(ending):
112 yield os.path.join(rp, f)
113

◆ is_same()

def pdf-comparison.is_same (   path1,
  path2 
)

Definition at line 94 of file pdf-comparison.py.

94def is_same(path1, path2):
95 if not os.path.isfile(path1) or not os.path.isfile(path2):
96 return os.path.isfile(path1) == os.path.isfile(path2)
97 with open(path1, 'rb') as f1:
98 with open(path2, 'rb') as f2:
99 while True:
100 c1, c2 = f1.read(4096), f2.read(4096)
101 if c1 != c2:
102 return False
103 if not c1:
104 return True
105
106
def is_same(path1, path2)

◆ main()

def pdf-comparison.main (   control_commitish)

Definition at line 245 of file pdf-comparison.py.

245def main(control_commitish):
246 assert os.pardir == '..' and '/' in [os.sep, os.altsep]
247 assert test_exe(NINJA)
248 assert test_exe(PDFIUM_TEST)
249 os.chdir(os.path.dirname(__file__) + '/../..')
250 control_worktree = checkout_worktree(control_commitish)
251 tmpdir = tempfile.mkdtemp(prefix='skpdf_')
252 exp = tmpdir + '/experim'
253 con = tmpdir + '/control'
254 build_and_run_dm(os.curdir, exp)
255 dm = build_and_run_dm(control_worktree, con)
256 image_diff_metric = build_skia(control_worktree, 'image_diff_metric')
257
258 out = sys.stdout
259 common_paths = get_common_paths([con, exp], '.pdf')
260 out.write('\nNumber of PDFs: %d\n\n' % len(common_paths))
261 def compare_identical(path):
262 cpath, epath = (os.path.join(x, path) for x in (con, exp))
263 if is_same(cpath, epath):
264 remove(cpath, epath)
265 return True
266 return False
267 identical_count = shardsum(compare_identical, common_paths)
268 out.write('Number of identical PDFs: %d\n\n' % identical_count)
269
270 differing_paths = get_common_paths([con, exp], '.pdf')
271 if not differing_paths:
272 out.write('All PDFs are the same!\n')
273 sys.exit(0)
274 out.write('Number of differing PDFs: %d\n' % len(differing_paths))
275 for p in differing_paths:
276 out.write(' %s\n' % printable_path(tmpdir + '/*/' + p))
277 out.write('\n')
278 shard(rasterize,
279 [os.path.join(x, p) for p in differing_paths for x in [con, exp]])
280
281 common_pngs = get_common_paths([con, exp], '.pdf.0.png')
282 identical_count = shardsum(compare_identical, common_pngs)
283 out.write('Number of PDFs that rasterize the same: %d\n\n'
284 % identical_count)
285
286 differing_pngs = get_common_paths([con, exp], '.pdf.0.png')
287 if not differing_pngs:
288 out.write('All PDFs rasterize the same!\n')
289 sys.exit(0)
290 out.write('Number of PDFs that rasterize differently: %d\n'
291 % len(differing_pngs))
292 for p in differing_pngs:
293 out.write(' %s\n' % printable_path(tmpdir + '/*/' + p))
294 out.write('\n')
295
296 scores = dict()
297 def compare_differing_pngs(path):
298 cpath, epath = (os.path.join(x, path) for x in (con, exp))
299 s = float(subprocess.check_output([image_diff_metric, cpath, epath]))
300 indicator = '.' if s < 0.001 else ':' if s < 0.01 else '!'
301 sys.stdout.write(indicator)
302 sys.stdout.flush()
303 scores[path] = s
304 shard(compare_differing_pngs, differing_pngs)
305 paths = sorted(scores.iterkeys(), key=lambda p: -scores[p])
306 out.write('\n\n')
307 for p in paths:
308 pdfpath = printable_path(tmpdir + '/*/' + p.replace('.0.png', ''))
309 out.write(' %6.4f %s\n' % (scores[p], pdfpath))
310 out.write('\n')
311
312 errors = []
313 rc = re.compile('^' + PDF_CONFIG + r'/([^/]*)/([^/]*)\.pdf\.0\.png$')
314 for p in paths:
315 m = rc.match(p)
316 assert(m)
317 source, name = m.groups()
318 errors.append((source, name, scores[p]))
319
320 for source in SOURCES:
321 os.makedirs(os.path.join(con, REFERENCE_BACKEND, source))
322 dm_args = [dm, '--src'] + SOURCES + [
323 '--config', REFERENCE_BACKEND, '-w', con, '-m'] + [
324 '^%s$' % name for _, name, _ in errors]
325 check_call(dm_args, cwd=control_worktree)
326
327 report = tmpdir + '/report.html'
328 with open(report, 'w') as o:
329 o.write(HTML_HEAD)
330 o.write('c="%s/";\n' % os.path.relpath(con, tmpdir))
331 o.write('e="%s/";\n' % os.path.relpath(exp, tmpdir))
332 o.write('z=[\n')
333 for source, name, score in errors:
334 gt = REFERENCE_BACKEND + '/' + source + '/' + name + '.png'
335 p = '%s/%s/%s.pdf.0.png' % (PDF_CONFIG, source, name)
336 desc = '%s | %s | %g' % (source, name, score)
337 o.write('["%s","%s","%s"],\n' % (p, gt, desc))
338 o.write(HTML_TAIL)
339 out.write(printable_path(report) + '\n')
340 sysopen(report)
341
def remove(*paths)
def shard(fn, arglist)
def shardsum(fn, arglist)
def main(control_commitish)

◆ print_cmd()

def pdf-comparison.print_cmd (   cmd,
  o 
)

Definition at line 61 of file pdf-comparison.py.

61def print_cmd(cmd, o):
62 m = re.compile('[^A-Za-z0-9_./-]')
63 o.write('+ ')
64 for c in cmd:
65 if m.search(c) is not None:
66 o.write(repr(c) + ' ')
67 else:
68 o.write(c + ' ')
69 o.write('\n')
70 o.flush()
71

◆ printable_path()

def pdf-comparison.printable_path (   d)

Definition at line 118 of file pdf-comparison.py.

118def printable_path(d):
119 if 'TMPDIR' in os.environ:
120 return d.replace(os.path.normpath(os.environ['TMPDIR']) + '/', '$TMPDIR/')
121 return d
122

◆ rasterize()

def pdf-comparison.rasterize (   path)

Definition at line 237 of file pdf-comparison.py.

237def rasterize(path):
238 ret = timeout(30, [PDFIUM_TEST, '--png', '--scale=%g' % (DPI / 72.0), path])
239 if ret != 0:
240 sys.stdout.write(
241 '\nTIMEOUT OR ERROR [%d] "%s"\n' % (ret, printable_path(path)))
242 return
243 assert os.path.isfile(path + '.0.png')
244
def rasterize(path)
def timeout(deadline, cmd)

◆ remove()

def pdf-comparison.remove ( paths)

Definition at line 80 of file pdf-comparison.py.

80def remove(*paths):
81 for path in paths:
82 os.remove(path)
83

◆ shard()

def pdf-comparison.shard (   fn,
  arglist 
)

Definition at line 181 of file pdf-comparison.py.

181def shard(fn, arglist):
182 jobs = [[arg for j, arg in enumerate(arglist) if j % NUM_THREADS == i]
183 for i in range(NUM_THREADS)]
184 results = []
185 def do_shard(*args):
186 for arg in args:
187 results.append(fn(arg))
188 thread_list = []
189 for job in jobs:
190 t = threading.Thread(target=do_shard, args=job)
191 t.start()
192 thread_list += [t]
193 for t in thread_list:
194 t.join()
195 return results
196

◆ shardsum()

def pdf-comparison.shardsum (   fn,
  arglist 
)

Definition at line 197 of file pdf-comparison.py.

197def shardsum(fn, arglist):
198 'return the number of True results returned by fn(arg) for arg in arglist.'
199 return sum(1 for result in shard(fn, arglist) if result)
200

◆ spawn()

def pdf-comparison.spawn (   cmd)

Definition at line 123 of file pdf-comparison.py.

123def spawn(cmd):
124 with open(os.devnull, 'w') as o:
125 subprocess.Popen(cmd, stdout=o, stderr=o)
126

◆ sysopen()

def pdf-comparison.sysopen (   arg)

Definition at line 127 of file pdf-comparison.py.

127def sysopen(arg):
128 plat = sys.platform
129 if plat.startswith('darwin'):
130 spawn(["open", arg])
131 elif plat.startswith('win'):
132 # pylint: disable=no-member
133 os.startfile(arg)
134 else:
135 spawn(["xdg-open", arg])
136

◆ test_exe()

def pdf-comparison.test_exe (   cmd)

Definition at line 53 of file pdf-comparison.py.

53def test_exe(cmd):
54 with open(os.devnull, 'w') as o:
55 try:
56 subprocess.call([cmd], stdout=o, stderr=o)
57 except OSError:
58 return False
59 return True
60

◆ timeout()

def pdf-comparison.timeout (   deadline,
  cmd 
)

Definition at line 84 of file pdf-comparison.py.

84def timeout(deadline, cmd):
85 #print_cmd(cmd, sys.stdout)
86 with open(os.devnull, 'w') as o:
87 proc = subprocess.Popen(cmd, stdout=o, stderr=subprocess.STDOUT)
88 timer = threading.Timer(deadline, proc.terminate)
89 timer.start()
90 proc.wait()
91 timer.cancel()
92 return proc.returncode
93

Variable Documentation

◆ BAD_TESTS

list pdf-comparison.BAD_TESTS
Initial value:
1= [
2 'image-cacherator-from-picture',
3 'image-cacherator-from-raster',
4 'mixershader',
5 'shadermaskfilter_image',
6 'tilemode_decal',
7]

Definition at line 37 of file pdf-comparison.py.

◆ DPI

pdf-comparison.DPI = float(os.environ.get('PDF_COMPARISON_DPI', 72))

Definition at line 33 of file pdf-comparison.py.

◆ EXTRA_GN_ARGS

pdf-comparison.EXTRA_GN_ARGS = os.environ.get('PDF_COMPARISON_GN_ARGS', '')

Definition at line 29 of file pdf-comparison.py.

◆ HTML_HEAD

string pdf-comparison.HTML_HEAD

Definition at line 137 of file pdf-comparison.py.

◆ HTML_TAIL

string pdf-comparison.HTML_TAIL
Initial value:
1= '''];
2for(i=0;i<z.length;i++){
3r(c+z[i][0],e+z[i][0],z[i][2],c+z[i][1]);}},false);
4</script></head><body><table id="t">
5<tr><th>BEFORE-AFTER DIFF</th>
6<th>BEFORE</th><th>AFTER</th>
7<th>REFERENCE</th></tr>
8</table></body></html>'''

Definition at line 172 of file pdf-comparison.py.

◆ NINJA

string pdf-comparison.NINJA = 'ninja'

Definition at line 45 of file pdf-comparison.py.

◆ NUM_THREADS

pdf-comparison.NUM_THREADS = int(os.environ.get('PDF_COMPARISON_THREADS', 40))

Definition at line 49 of file pdf-comparison.py.

◆ PDF_CONFIG

string pdf-comparison.PDF_CONFIG = 'pdf' if 'PDF_COMPARISON_300DPI' not in os.environ else 'pdf300'

Definition at line 35 of file pdf-comparison.py.

◆ PDFIUM_TEST

string pdf-comparison.PDFIUM_TEST = 'pdfium_test'

Definition at line 47 of file pdf-comparison.py.

◆ REFERENCE_BACKEND

string pdf-comparison.REFERENCE_BACKEND = 'gl' if 'PDF_COMPARISON_NOGPU' not in os.environ else '8888'

Definition at line 31 of file pdf-comparison.py.

◆ SOURCES

list pdf-comparison.SOURCES = ['gm']

Definition at line 51 of file pdf-comparison.py.

◆ USAGE

tuple pdf-comparison.USAGE
Initial value:
1= ('\nusage:\n {0} COMMIT_OR_BRANCH_TO_COMPARE_TO\n\n'
2 'e.g.:\n {0} HEAD\nor\n {0} HEAD~1\n\n')

Definition at line 344 of file pdf-comparison.py.