def calculateTraceStatistics(self, traceName): """ Calculate some derived OpenGL ES statistics based on instrumentation measurements. The following features are calculated from the trace: @param traceName: Name of trace to process. """ if not traceName in self.analyzer.traces: self.analyzer.fail("Trace not found: %s" % traceName) trace = self.analyzer.traces[traceName] GlesTraceOperations.calculateStatistics(self.analyzer.project, trace) self.analyzer.reportInfo("Statistics calculated.")
def simplifyTrace(self, traceName, traceNameOut = None): """ Remove redundant GLES commands from a trace. @param traceName: Name of trace to simplify @param traceNameOut: Result name, or the original trace name by default """ if not traceName in self.analyzer.traces: self.analyzer.fail("Trace not found: %s" % traceName) if not traceNameOut: traceNameOut = traceName trace = self.analyzer.traces[traceName] newTrace = GlesTraceOperations.simplify(self.analyzer.project, trace) self.analyzer.traces[traceNameOut] = newTrace self.analyzer.reportInfo("%d events from trace %s simplified into %d events of trace %s." % (len(trace.events), traceName, len(newTrace.events), traceNameOut))
def generateReport(project, trace, traceFileName, path, format): if traceFileName: title = "OpenGL ES performance report for %s" % os.path.basename(traceFileName) else: title = "OpenGL ES performance report" Log.notice(title) g = ReportGenerator.ReportGenerator(project, trace, title, path, format) # Calculate GLES specific stats GlesTraceOperations.calculateStatistics(project, trace) # Calculate general stats g.calculateStatistics() # Add some general information first section = g.report.create(Report.Section, "General statistics") table = g.createGeneralStatisticsTable() auxiliaryTable = g.createAuxiliaryStatisticsTable() histogramTable = g.createCallHistogramTable() if traceFileName: table.addRow("File name", traceFileName) section.add(table) section.add(auxiliaryTable) section.add(histogramTable) # Add a section about the used render targets addRenderTargetSection(g) # Add an overall timeline of all events g.report.add(g.createEventPlot("Event distribution", trace.events)) # Add a graph about the event type distribution g.report.add(g.createEventFrequencyPlot("Operation distribution", trace.events)) # Add overview section overviewSection = g.report.create(Report.Section, "Overview") # Frame thumbnails thumbnailSection = overviewSection.create(Report.Section, "Selected frames") thumbnails = g.createEventThumbnails([f.swapEvent for f in g.interestingFrames]) for frame, thumbnail in zip(g.interestingFrames, thumbnails): thumbnailSection.create(Report.Link, "#frame%d" % (frame.number + 1), thumbnail) # Textures textureLoaders = GlesTraceOperations.getTextureLoaders(project, trace) if textureLoaders: textureSection = overviewSection.create(Report.Section, "Loaded textures") task = Task.startTask("load-textures", "Loading textures", len(textureLoaders)) for event, func in textureLoaders: task.step() image = func().convert("RGBA") fn = os.path.join(path, "texture%03d.png" % event.seq) image.save(fn) textureSection.create(Report.Image, fn) # FPS data = [1.0 / f.duration for f in g.frames] plot = g.createPlot("Frames per second", range(len(g.frames)), data) overviewSection.add(plot) # Render calls data = [len(f.events) for f in g.frames] plot = g.createPlot("Number of API calls per frame", range(len(g.frames)), data) overviewSection.add(plot) # Overdraw data = [f.swapEvent.sensorData.get("draw_ratio", 0) for f in g.frames] plot = g.createPlot("Draw ratio", range(len(g.frames)), data) overviewSection.add(plot) # Fragment count data = [f.swapEvent.sensorData.get("rasterizer_pixels", 0) for f in g.frames] plot = g.createPlot("Rasterized fragments per frame", range(len(g.frames)), data) overviewSection.add(plot) # Texture reads data = [f.swapEvent.sensorData.get("rasterizer_texel_fetches", 0) for f in g.frames] plot = g.createPlot("Texel fetches per frame", range(len(g.frames)), data) overviewSection.add(plot) # Texture uploads data = [f.swapEvent.sensorData.get("texel_uploads", 0) for f in g.frames] plot = g.createPlot("Texel uploads per frame", range(len(g.frames)), data) overviewSection.add(plot) # Now go over each interesting frame task = Task.startTask("frame-report", "Generating report", len(g.interestingFrames)) frameDetailSection = g.report.create(Report.Section, "Detailed frame statistics") for frame in g.interestingFrames: task.step() frameSection = g.createFrameSection(frame) # Add some custom plots plot = g.createSensorPlot(frame, "rasterizer_pixels") frameSection.add(plot) plot = g.createSensorPlot(frame, "rasterizer_texel_fetches") frameSection.add(plot) plot = g.createSensorPlot(frame, "texel_uploads") frameSection.add(plot) # Now go over the individual render calls + the swap event for event in frame.renderEvents + [frame.swapEvent]: eventSection = g.createEventSection(event) frameSection.add(eventSection) frameDetailSection.add(frameSection) # Add the checklist result g.report.add(g.createChecklistSection("Performance Checklist", GlesChecklist.checklistItems)) # Finalize the report task.finish() g.generate()
def postProcessInstrumentationData(self, trace): GlesTraceOperations.calculateStatistics(self.analyzer.project, trace)