1*61046927SAndroid Build Coastguard Worker#!/usr/bin/env python3 2*61046927SAndroid Build Coastguard Worker 3*61046927SAndroid Build Coastguard Workerimport re 4*61046927SAndroid Build Coastguard Workerimport sys 5*61046927SAndroid Build Coastguard Workerimport gzip 6*61046927SAndroid Build Coastguard Workerimport io 7*61046927SAndroid Build Coastguard Worker 8*61046927SAndroid Build Coastguard Worker# Captures per-frame state, including all the renderpasses, and 9*61046927SAndroid Build Coastguard Worker# time spent in blits and compute jobs: 10*61046927SAndroid Build Coastguard Workerclass Frame: 11*61046927SAndroid Build Coastguard Worker def __init__(self): 12*61046927SAndroid Build Coastguard Worker self.frame_nr = None 13*61046927SAndroid Build Coastguard Worker self.renderpasses = [] 14*61046927SAndroid Build Coastguard Worker # Times in ns: 15*61046927SAndroid Build Coastguard Worker self.times_sysmem = [] 16*61046927SAndroid Build Coastguard Worker self.times_gmem = [] 17*61046927SAndroid Build Coastguard Worker self.times_compute = [] 18*61046927SAndroid Build Coastguard Worker self.times_blit = [] 19*61046927SAndroid Build Coastguard Worker 20*61046927SAndroid Build Coastguard Worker def print(self): 21*61046927SAndroid Build Coastguard Worker print("FRAME[{}]: {} blits ({:,} ns), {} SYSMEM ({:,} ns), {} GMEM ({:,} ns), {} COMPUTE ({:,} ns)".format( 22*61046927SAndroid Build Coastguard Worker self.frame_nr, 23*61046927SAndroid Build Coastguard Worker len(self.times_blit), sum(self.times_blit), 24*61046927SAndroid Build Coastguard Worker len(self.times_sysmem), sum(self.times_sysmem), 25*61046927SAndroid Build Coastguard Worker len(self.times_gmem), sum(self.times_gmem), 26*61046927SAndroid Build Coastguard Worker len(self.times_compute), sum(self.times_compute) 27*61046927SAndroid Build Coastguard Worker )) 28*61046927SAndroid Build Coastguard Worker 29*61046927SAndroid Build Coastguard Worker i = 0 30*61046927SAndroid Build Coastguard Worker prologue_time = 0 31*61046927SAndroid Build Coastguard Worker binning_time = 0 32*61046927SAndroid Build Coastguard Worker restore_clear_time = 0 33*61046927SAndroid Build Coastguard Worker draw_time = 0 34*61046927SAndroid Build Coastguard Worker resolve_time = 0 35*61046927SAndroid Build Coastguard Worker elapsed_time = 0 36*61046927SAndroid Build Coastguard Worker total_time = sum(self.times_blit) + sum(self.times_sysmem) + sum(self.times_gmem) + sum(self.times_compute) 37*61046927SAndroid Build Coastguard Worker 38*61046927SAndroid Build Coastguard Worker for renderpass in self.renderpasses: 39*61046927SAndroid Build Coastguard Worker renderpass.print(i) 40*61046927SAndroid Build Coastguard Worker prologue_time += renderpass.prologue_time 41*61046927SAndroid Build Coastguard Worker binning_time += renderpass.binning_time 42*61046927SAndroid Build Coastguard Worker restore_clear_time += renderpass.restore_clear_time 43*61046927SAndroid Build Coastguard Worker draw_time += renderpass.draw_time 44*61046927SAndroid Build Coastguard Worker resolve_time += renderpass.resolve_time 45*61046927SAndroid Build Coastguard Worker elapsed_time += renderpass.elapsed_time 46*61046927SAndroid Build Coastguard Worker i += 1 47*61046927SAndroid Build Coastguard Worker 48*61046927SAndroid Build Coastguard Worker print(" TOTAL: prologue: {:,} ns ({}%), binning: {:,} ns ({}%), restore/clear: {:,} ns ({}%), draw: {:,} ns ({}%), resolve: {:,} ns ({}%), blit: {:,} ns ({}%), compute: {:,} ns ({}%), GMEM: {:,} ns ({}%), sysmem: {:,} ns ({}%), total: {:,} ns\n".format( 49*61046927SAndroid Build Coastguard Worker prologue_time, 100.0 * prologue_time / total_time, 50*61046927SAndroid Build Coastguard Worker binning_time, 100.0 * binning_time / total_time, 51*61046927SAndroid Build Coastguard Worker restore_clear_time, 100.0 * restore_clear_time / total_time, 52*61046927SAndroid Build Coastguard Worker draw_time, 100.0 * draw_time / total_time, 53*61046927SAndroid Build Coastguard Worker resolve_time, 100.0 * resolve_time / total_time, 54*61046927SAndroid Build Coastguard Worker sum(self.times_blit), 100.0 * sum(self.times_blit) / total_time, 55*61046927SAndroid Build Coastguard Worker sum(self.times_compute), 100.0 * sum(self.times_compute) / total_time, 56*61046927SAndroid Build Coastguard Worker sum(self.times_gmem), 100.0 * sum(self.times_gmem) / total_time, 57*61046927SAndroid Build Coastguard Worker sum(self.times_sysmem), 100.0 * sum(self.times_sysmem) / total_time, 58*61046927SAndroid Build Coastguard Worker total_time 59*61046927SAndroid Build Coastguard Worker )) 60*61046927SAndroid Build Coastguard Worker 61*61046927SAndroid Build Coastguard Workerclass FramebufferState: 62*61046927SAndroid Build Coastguard Worker def __init__(self, width, height, layers, samples, nr_cbufs): 63*61046927SAndroid Build Coastguard Worker self.width = width 64*61046927SAndroid Build Coastguard Worker self.height = height 65*61046927SAndroid Build Coastguard Worker self.layers = layers 66*61046927SAndroid Build Coastguard Worker self.samples = samples 67*61046927SAndroid Build Coastguard Worker self.nr_cbufs = nr_cbufs 68*61046927SAndroid Build Coastguard Worker self.surfaces = [] # per MRT + zsbuf 69*61046927SAndroid Build Coastguard Worker 70*61046927SAndroid Build Coastguard Worker def get_formats(self): 71*61046927SAndroid Build Coastguard Worker formats = [] 72*61046927SAndroid Build Coastguard Worker for surface in self.surfaces: 73*61046927SAndroid Build Coastguard Worker formats.append(surface.format) 74*61046927SAndroid Build Coastguard Worker return formats 75*61046927SAndroid Build Coastguard Worker 76*61046927SAndroid Build Coastguard Workerclass SurfaceState: 77*61046927SAndroid Build Coastguard Worker def __init__(self, width, height, samples, format): 78*61046927SAndroid Build Coastguard Worker self.width = width 79*61046927SAndroid Build Coastguard Worker self.height = height 80*61046927SAndroid Build Coastguard Worker self.samples = samples 81*61046927SAndroid Build Coastguard Worker self.format = format 82*61046927SAndroid Build Coastguard Worker 83*61046927SAndroid Build Coastguard Workerclass BinningState: 84*61046927SAndroid Build Coastguard Worker def __init__(self, nbins_x, nbins_y, bin_w, bin_h): 85*61046927SAndroid Build Coastguard Worker self.nbins_x = nbins_x 86*61046927SAndroid Build Coastguard Worker self.nbins_y = nbins_y 87*61046927SAndroid Build Coastguard Worker self.bin_w = bin_w 88*61046927SAndroid Build Coastguard Worker self.bin_h = bin_h 89*61046927SAndroid Build Coastguard Worker 90*61046927SAndroid Build Coastguard Worker# Captures per-renderpass state, which can be either a binning or 91*61046927SAndroid Build Coastguard Worker# sysmem pass. Blits and compute jobs are not tracked separately 92*61046927SAndroid Build Coastguard Worker# but have their time their times accounted for in the Frame state 93*61046927SAndroid Build Coastguard Workerclass RenderPass: 94*61046927SAndroid Build Coastguard Worker def __init__(self, cleared, gmem_reason, num_draws): 95*61046927SAndroid Build Coastguard Worker self.cleared = cleared 96*61046927SAndroid Build Coastguard Worker self.gmem_reason = gmem_reason 97*61046927SAndroid Build Coastguard Worker self.num_draws = num_draws 98*61046927SAndroid Build Coastguard Worker 99*61046927SAndroid Build Coastguard Worker # The rest of the parameters aren't known until we see a later trace: 100*61046927SAndroid Build Coastguard Worker self.binning_state = None # None for sysmem passes, else BinningState 101*61046927SAndroid Build Coastguard Worker self.fb = None 102*61046927SAndroid Build Coastguard Worker self.fast_cleared = None 103*61046927SAndroid Build Coastguard Worker 104*61046927SAndroid Build Coastguard Worker self.elapsed_time = 0 105*61046927SAndroid Build Coastguard Worker self.state_restore_time = 0 106*61046927SAndroid Build Coastguard Worker self.prologue_time = 0 107*61046927SAndroid Build Coastguard Worker self.draw_time = 0 108*61046927SAndroid Build Coastguard Worker self.restore_clear_time = 0 109*61046927SAndroid Build Coastguard Worker 110*61046927SAndroid Build Coastguard Worker # Specific to GMEM passes: 111*61046927SAndroid Build Coastguard Worker self.binning_time = 0 112*61046927SAndroid Build Coastguard Worker self.vsc_overflow_test_time = 0 113*61046927SAndroid Build Coastguard Worker self.resolve_time = 0 114*61046927SAndroid Build Coastguard Worker 115*61046927SAndroid Build Coastguard Worker def print_gmem_pass(self, nr): 116*61046927SAndroid Build Coastguard Worker print(" GMEM[{}]: {}x{} ({}x{} tiles), {} draws, prologue: {:,} ns, binning: {:,} ns, restore/clear: {:,} ns, draw: {:,} ns, resolve: {:,} ns, total: {:,} ns, rt/zs: {}".format( 117*61046927SAndroid Build Coastguard Worker nr, self.fb.width, self.fb.height, 118*61046927SAndroid Build Coastguard Worker self.binning_state.nbins_x, self.binning_state.nbins_y, 119*61046927SAndroid Build Coastguard Worker self.num_draws, self.prologue_time, self.binning_time, 120*61046927SAndroid Build Coastguard Worker self.restore_clear_time, self.draw_time, self.resolve_time, 121*61046927SAndroid Build Coastguard Worker self.elapsed_time, 122*61046927SAndroid Build Coastguard Worker ", ".join(self.fb.get_formats()) 123*61046927SAndroid Build Coastguard Worker )) 124*61046927SAndroid Build Coastguard Worker 125*61046927SAndroid Build Coastguard Worker def print_sysmem_pass(self, nr): 126*61046927SAndroid Build Coastguard Worker print(" SYSMEM[{}]: {}x{}, {} draws, prologue: {:,} ns, clear: {:,} ns, draw: {:,} ns, total: {:,} ns, rt/zs: {}".format( 127*61046927SAndroid Build Coastguard Worker nr, self.fb.width, self.fb.height, 128*61046927SAndroid Build Coastguard Worker self.num_draws, self.prologue_time, 129*61046927SAndroid Build Coastguard Worker self.restore_clear_time, self.draw_time, 130*61046927SAndroid Build Coastguard Worker self.elapsed_time, 131*61046927SAndroid Build Coastguard Worker ", ".join(self.fb.get_formats()) 132*61046927SAndroid Build Coastguard Worker )) 133*61046927SAndroid Build Coastguard Worker 134*61046927SAndroid Build Coastguard Worker def print(self, nr): 135*61046927SAndroid Build Coastguard Worker if self.binning_state: 136*61046927SAndroid Build Coastguard Worker self.print_gmem_pass(nr) 137*61046927SAndroid Build Coastguard Worker else: 138*61046927SAndroid Build Coastguard Worker self.print_sysmem_pass(nr) 139*61046927SAndroid Build Coastguard Worker 140*61046927SAndroid Build Coastguard Workerdef main(): 141*61046927SAndroid Build Coastguard Worker filename = sys.argv[1] 142*61046927SAndroid Build Coastguard Worker if filename.endswith(".gz"): 143*61046927SAndroid Build Coastguard Worker file = gzip.open(filename, "r") 144*61046927SAndroid Build Coastguard Worker file = io.TextIOWrapper(file) 145*61046927SAndroid Build Coastguard Worker else: 146*61046927SAndroid Build Coastguard Worker file = open(filename, "r") 147*61046927SAndroid Build Coastguard Worker lines = file.read().split('\n') 148*61046927SAndroid Build Coastguard Worker 149*61046927SAndroid Build Coastguard Worker flush_batch_match = re.compile(r": flush_batch: (\S+): cleared=(\S+), gmem_reason=(\S+), num_draws=(\S+)") 150*61046927SAndroid Build Coastguard Worker framebuffer_match = re.compile(r": framebuffer: (\S+)x(\S+)x(\S+)@(\S+), nr_cbufs: (\S+)") 151*61046927SAndroid Build Coastguard Worker surface_match = re.compile(r": surface: (\S+)x(\S+)@(\S+), fmt=(\S+)") 152*61046927SAndroid Build Coastguard Worker 153*61046927SAndroid Build Coastguard Worker # draw/renderpass passes: 154*61046927SAndroid Build Coastguard Worker gmem_match = re.compile(r": render_gmem: (\S+)x(\S+) bins of (\S+)x(\S+)") 155*61046927SAndroid Build Coastguard Worker sysmem_match = re.compile(r": render_sysmem") 156*61046927SAndroid Build Coastguard Worker state_restore_match = re.compile(r"\+(\S+): end_state_restore") 157*61046927SAndroid Build Coastguard Worker prologue_match = re.compile(r"\+(\S+): end_prologue") 158*61046927SAndroid Build Coastguard Worker binning_ib_match = re.compile(r"\+(\S+): end_binning_ib") 159*61046927SAndroid Build Coastguard Worker vsc_overflow_match = re.compile(r"\+(\S+): end_vsc_overflow_test") 160*61046927SAndroid Build Coastguard Worker draw_ib_match = re.compile(r"\+(\S+): end_draw_ib") 161*61046927SAndroid Build Coastguard Worker resolve_match = re.compile(r"\+(\S+): end_resolve") 162*61046927SAndroid Build Coastguard Worker 163*61046927SAndroid Build Coastguard Worker start_clear_restore_match = re.compile(r"start_clear_restore: fast_cleared: (\S+)") 164*61046927SAndroid Build Coastguard Worker end_clear_restore_match = re.compile(r"\+(\S+): end_clear_restore") 165*61046927SAndroid Build Coastguard Worker 166*61046927SAndroid Build Coastguard Worker # Non-draw passes: 167*61046927SAndroid Build Coastguard Worker compute_match = re.compile(r": start_compute") 168*61046927SAndroid Build Coastguard Worker blit_match = re.compile(r": start_blit") 169*61046927SAndroid Build Coastguard Worker 170*61046927SAndroid Build Coastguard Worker # End of pass/frame markers: 171*61046927SAndroid Build Coastguard Worker elapsed_match = re.compile(r"ELAPSED: (\S+) ns") 172*61046927SAndroid Build Coastguard Worker eof_match = re.compile(r"END OF FRAME (\S+)") 173*61046927SAndroid Build Coastguard Worker 174*61046927SAndroid Build Coastguard Worker frame = Frame() # current frame state 175*61046927SAndroid Build Coastguard Worker renderpass = None # current renderpass state 176*61046927SAndroid Build Coastguard Worker times = None 177*61046927SAndroid Build Coastguard Worker 178*61046927SAndroid Build Coastguard Worker # Helper to set the appropriate times table for the current pass, 179*61046927SAndroid Build Coastguard Worker # which is expected to only happen once for a given render pass 180*61046927SAndroid Build Coastguard Worker def set_times(t): 181*61046927SAndroid Build Coastguard Worker nonlocal times 182*61046927SAndroid Build Coastguard Worker if times is not None: 183*61046927SAndroid Build Coastguard Worker print("expected times to not be set yet") 184*61046927SAndroid Build Coastguard Worker times = t 185*61046927SAndroid Build Coastguard Worker 186*61046927SAndroid Build Coastguard Worker for line in lines: 187*61046927SAndroid Build Coastguard Worker # Note, we only expect the flush_batch trace for !nondraw: 188*61046927SAndroid Build Coastguard Worker match = re.search(flush_batch_match, line) 189*61046927SAndroid Build Coastguard Worker if match is not None: 190*61046927SAndroid Build Coastguard Worker assert(renderpass is None) 191*61046927SAndroid Build Coastguard Worker renderpass = RenderPass(cleared=match.group(2), 192*61046927SAndroid Build Coastguard Worker gmem_reason=match.group(3), 193*61046927SAndroid Build Coastguard Worker num_draws=match.group(4)) 194*61046927SAndroid Build Coastguard Worker frame.renderpasses.append(renderpass) 195*61046927SAndroid Build Coastguard Worker continue 196*61046927SAndroid Build Coastguard Worker 197*61046927SAndroid Build Coastguard Worker match = re.search(framebuffer_match, line) 198*61046927SAndroid Build Coastguard Worker if match is not None: 199*61046927SAndroid Build Coastguard Worker assert(renderpass.fb is None) 200*61046927SAndroid Build Coastguard Worker renderpass.fb = FramebufferState(width=match.group(1), 201*61046927SAndroid Build Coastguard Worker height=match.group(2), 202*61046927SAndroid Build Coastguard Worker layers=match.group(3), 203*61046927SAndroid Build Coastguard Worker samples=match.group(4), 204*61046927SAndroid Build Coastguard Worker nr_cbufs=match.group(5)) 205*61046927SAndroid Build Coastguard Worker continue 206*61046927SAndroid Build Coastguard Worker 207*61046927SAndroid Build Coastguard Worker match = re.search(surface_match, line) 208*61046927SAndroid Build Coastguard Worker if match is not None: 209*61046927SAndroid Build Coastguard Worker surface = SurfaceState(width=match.group(1), 210*61046927SAndroid Build Coastguard Worker height=match.group(2), 211*61046927SAndroid Build Coastguard Worker samples=match.group(3), 212*61046927SAndroid Build Coastguard Worker format=match.group(4)) 213*61046927SAndroid Build Coastguard Worker renderpass.fb.surfaces.append(surface) 214*61046927SAndroid Build Coastguard Worker continue 215*61046927SAndroid Build Coastguard Worker 216*61046927SAndroid Build Coastguard Worker match = re.search(gmem_match, line) 217*61046927SAndroid Build Coastguard Worker if match is not None: 218*61046927SAndroid Build Coastguard Worker assert(renderpass.binning_state is None) 219*61046927SAndroid Build Coastguard Worker renderpass.binning_state = BinningState(nbins_x=match.group(1), 220*61046927SAndroid Build Coastguard Worker nbins_y=match.group(2), 221*61046927SAndroid Build Coastguard Worker bin_w=match.group(3), 222*61046927SAndroid Build Coastguard Worker bin_h=match.group(4)) 223*61046927SAndroid Build Coastguard Worker set_times(frame.times_gmem) 224*61046927SAndroid Build Coastguard Worker continue 225*61046927SAndroid Build Coastguard Worker 226*61046927SAndroid Build Coastguard Worker match = re.search(sysmem_match, line) 227*61046927SAndroid Build Coastguard Worker if match is not None: 228*61046927SAndroid Build Coastguard Worker assert(renderpass.binning_state is None) 229*61046927SAndroid Build Coastguard Worker set_times(frame.times_sysmem) 230*61046927SAndroid Build Coastguard Worker continue 231*61046927SAndroid Build Coastguard Worker 232*61046927SAndroid Build Coastguard Worker match = re.search(state_restore_match, line) 233*61046927SAndroid Build Coastguard Worker if match is not None: 234*61046927SAndroid Build Coastguard Worker renderpass.state_restore_time += int(match.group(1)) 235*61046927SAndroid Build Coastguard Worker continue 236*61046927SAndroid Build Coastguard Worker 237*61046927SAndroid Build Coastguard Worker match = re.search(prologue_match, line) 238*61046927SAndroid Build Coastguard Worker if match is not None: 239*61046927SAndroid Build Coastguard Worker renderpass.prologue_time += int(match.group(1)) 240*61046927SAndroid Build Coastguard Worker continue 241*61046927SAndroid Build Coastguard Worker 242*61046927SAndroid Build Coastguard Worker match = re.search(binning_ib_match, line) 243*61046927SAndroid Build Coastguard Worker if match is not None: 244*61046927SAndroid Build Coastguard Worker assert(renderpass.binning_state is not None) 245*61046927SAndroid Build Coastguard Worker renderpass.binning_time += int(match.group(1)) 246*61046927SAndroid Build Coastguard Worker continue 247*61046927SAndroid Build Coastguard Worker 248*61046927SAndroid Build Coastguard Worker match = re.search(vsc_overflow_match, line) 249*61046927SAndroid Build Coastguard Worker if match is not None: 250*61046927SAndroid Build Coastguard Worker assert(renderpass.binning_state is not None) 251*61046927SAndroid Build Coastguard Worker renderpass.vsc_overflow_test_time += int(match.group(1)) 252*61046927SAndroid Build Coastguard Worker continue 253*61046927SAndroid Build Coastguard Worker 254*61046927SAndroid Build Coastguard Worker match = re.search(draw_ib_match, line) 255*61046927SAndroid Build Coastguard Worker if match is not None: 256*61046927SAndroid Build Coastguard Worker renderpass.draw_time += int(match.group(1)) 257*61046927SAndroid Build Coastguard Worker continue 258*61046927SAndroid Build Coastguard Worker 259*61046927SAndroid Build Coastguard Worker match = re.search(resolve_match, line) 260*61046927SAndroid Build Coastguard Worker if match is not None: 261*61046927SAndroid Build Coastguard Worker assert(renderpass.binning_state is not None) 262*61046927SAndroid Build Coastguard Worker renderpass.resolve_time += int(match.group(1)) 263*61046927SAndroid Build Coastguard Worker continue 264*61046927SAndroid Build Coastguard Worker 265*61046927SAndroid Build Coastguard Worker match = re.search(start_clear_restore_match, line) 266*61046927SAndroid Build Coastguard Worker if match is not None: 267*61046927SAndroid Build Coastguard Worker renderpass.fast_cleared = match.group(1) 268*61046927SAndroid Build Coastguard Worker continue 269*61046927SAndroid Build Coastguard Worker 270*61046927SAndroid Build Coastguard Worker match = re.search(end_clear_restore_match, line) 271*61046927SAndroid Build Coastguard Worker if match is not None: 272*61046927SAndroid Build Coastguard Worker renderpass.restore_clear_time += int(match.group(1)) 273*61046927SAndroid Build Coastguard Worker continue 274*61046927SAndroid Build Coastguard Worker 275*61046927SAndroid Build Coastguard Worker match = re.search(compute_match, line) 276*61046927SAndroid Build Coastguard Worker if match is not None: 277*61046927SAndroid Build Coastguard Worker set_times(frame.times_compute) 278*61046927SAndroid Build Coastguard Worker continue 279*61046927SAndroid Build Coastguard Worker 280*61046927SAndroid Build Coastguard Worker match = re.search(blit_match, line) 281*61046927SAndroid Build Coastguard Worker if match is not None: 282*61046927SAndroid Build Coastguard Worker set_times(frame.times_blit) 283*61046927SAndroid Build Coastguard Worker continue 284*61046927SAndroid Build Coastguard Worker 285*61046927SAndroid Build Coastguard Worker match = re.search(eof_match, line) 286*61046927SAndroid Build Coastguard Worker if match is not None: 287*61046927SAndroid Build Coastguard Worker frame.frame_nr = int(match.group(1)) 288*61046927SAndroid Build Coastguard Worker frame.print() 289*61046927SAndroid Build Coastguard Worker frame = Frame() 290*61046927SAndroid Build Coastguard Worker times = None 291*61046927SAndroid Build Coastguard Worker renderpass = None 292*61046927SAndroid Build Coastguard Worker continue 293*61046927SAndroid Build Coastguard Worker 294*61046927SAndroid Build Coastguard Worker match = re.search(elapsed_match, line) 295*61046927SAndroid Build Coastguard Worker if match is not None: 296*61046927SAndroid Build Coastguard Worker time = int(match.group(1)) 297*61046927SAndroid Build Coastguard Worker #print("ELAPSED: " + str(time) + " ns") 298*61046927SAndroid Build Coastguard Worker if renderpass is not None: 299*61046927SAndroid Build Coastguard Worker renderpass.elapsed_time = time 300*61046927SAndroid Build Coastguard Worker times.append(time) 301*61046927SAndroid Build Coastguard Worker times = None 302*61046927SAndroid Build Coastguard Worker renderpass = None 303*61046927SAndroid Build Coastguard Worker continue 304*61046927SAndroid Build Coastguard Worker 305*61046927SAndroid Build Coastguard Worker 306*61046927SAndroid Build Coastguard Workerif __name__ == "__main__": 307*61046927SAndroid Build Coastguard Worker main() 308*61046927SAndroid Build Coastguard Worker 309