1 #!/usr/bin/env python 2 3 # Copyright 2014 Google Inc. 4 # 5 # Use of this source code is governed by a BSD-style license that can be 6 # found in the LICENSE file. 7 8 """Script to test out suitableForGpuRasterization (via gpuveto)""" 9 10 import argparse 11 import glob 12 import os 13 import re 14 import subprocess 15 import sys 16 17 # Set the PYTHONPATH to include the tools directory. 18 sys.path.append( 19 os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir)) 20 import find_run_binary 21 22 def list_files(dir_or_file): 23 """Returns a list of all the files from the provided argument 24 25 @param dir_or_file: either a directory or skp file 26 27 @returns a list containing the files in the directory or a single file 28 """ 29 files = [] 30 for globbedpath in glob.iglob(dir_or_file): # useful on win32 31 if os.path.isdir(globbedpath): 32 for filename in os.listdir(globbedpath): 33 newpath = os.path.join(globbedpath, filename) 34 if os.path.isfile(newpath): 35 files.append(newpath) 36 elif os.path.isfile(globbedpath): 37 files.append(globbedpath) 38 return files 39 40 41 def execute_program(args): 42 """Executes a process and waits for it to complete. 43 44 @param args: is passed into subprocess.Popen(). 45 46 @returns a tuple of the process output (returncode, output) 47 """ 48 proc = subprocess.Popen(args, stdout=subprocess.PIPE, 49 stderr=subprocess.STDOUT) 50 output, _ = proc.communicate() 51 errcode = proc.returncode 52 return (errcode, output) 53 54 55 class GpuVeto(object): 56 57 def __init__(self): 58 self.bench_pictures = find_run_binary.find_path_to_program( 59 'bench_pictures') 60 sys.stdout.write('Running: %s\n' % (self.bench_pictures)) 61 self.gpuveto = find_run_binary.find_path_to_program('gpuveto') 62 assert os.path.isfile(self.bench_pictures) 63 assert os.path.isfile(self.gpuveto) 64 self.indeterminate = 0 65 self.truePositives = 0 66 self.falsePositives = 0 67 self.trueNegatives = 0 68 self.falseNegatives = 0 69 70 def process_skps(self, dir_or_file): 71 for skp in enumerate(dir_or_file): 72 self.process_skp(skp[1]) 73 74 sys.stdout.write('TP %d FP %d TN %d FN %d IND %d\n' % (self.truePositives, 75 self.falsePositives, 76 self.trueNegatives, 77 self.falseNegatives, 78 self.indeterminate)) 79 80 81 def process_skp(self, skp_file): 82 assert os.path.isfile(skp_file) 83 #print skp_file 84 85 # run gpuveto on the skp 86 args = [self.gpuveto, '-r', skp_file] 87 returncode, output = execute_program(args) 88 if (returncode != 0): 89 return 90 91 if ('unsuitable' in output): 92 suitable = False 93 else: 94 assert 'suitable' in output 95 suitable = True 96 97 # run raster config 98 args = [self.bench_pictures, '-r', skp_file, 99 '--repeat', '20', 100 '--timers', 'w', 101 '--config', '8888'] 102 returncode, output = execute_program(args) 103 if (returncode != 0): 104 return 105 106 matches = re.findall('[\d]+\.[\d]+', output) 107 if len(matches) != 1: 108 return 109 110 rasterTime = float(matches[0]) 111 112 # run gpu config 113 args2 = [self.bench_pictures, '-r', skp_file, 114 '--repeat', '20', 115 '--timers', 'w', 116 '--config', 'gpu'] 117 returncode, output = execute_program(args2) 118 if (returncode != 0): 119 return 120 121 matches = re.findall('[\d]+\.[\d]+', output) 122 if len(matches) != 1: 123 return 124 125 gpuTime = float(matches[0]) 126 127 # happens if page is too big it will not render 128 if 0 == gpuTime: 129 return 130 131 tolerance = 0.05 132 tol_range = tolerance * gpuTime 133 134 135 if rasterTime > gpuTime - tol_range and rasterTime < gpuTime + tol_range: 136 result = "NONE" 137 self.indeterminate += 1 138 elif suitable: 139 if gpuTime < rasterTime: 140 self.truePositives += 1 141 result = "TP" 142 else: 143 self.falsePositives += 1 144 result = "FP" 145 else: 146 if gpuTime < rasterTime: 147 self.falseNegatives += 1 148 result = "FN" 149 else: 150 self.trueNegatives += 1 151 result = "TN" 152 153 154 sys.stdout.write('%s: gpuveto: %d raster %.2f gpu: %.2f Result: %s\n' % ( 155 skp_file, suitable, rasterTime, gpuTime, result)) 156 157 def main(main_argv): 158 parser = argparse.ArgumentParser() 159 parser.add_argument('--skp_path', 160 help='Path to the SKP(s). Can either be a directory ' \ 161 'containing SKPs or a single SKP.', 162 required=True) 163 164 args = parser.parse_args() 165 GpuVeto().process_skps(list_files(args.skp_path)) 166 167 if __name__ == '__main__': 168 sys.exit(main(sys.argv[1])) 169