Example #1
0
    def createEventSection(self, event):
        func = self.library.functions[event.name]

        if func.isRenderCall:
            title = "Render call %s (#%d)" % (event.name, event.seq)
        elif func.isFrameMarker:
            title = "Frame swap %s (#%d)" % (event.name, event.seq)
        else:
            title = "Event %s (#%d)" % (event.name, event.seq)

        section = Report.Section(title)

        # Add a framebuffer snapshot if we have one
        colorBuffer = player.Instrumentation.getBufferFileName(event)
        if func.isRenderCall and colorBuffer:
            section.create(Report.Image,
                           colorBuffer,
                           elementClass="screenshot")

        # Describe the event
        section.create(Report.Paragraph,
                       self.getEventDescription(event),
                       elementClass="code")

        # Insert sensor measurements
        statsTable = section.create(Report.Table, ["Sensor", "Value"])

        for name in sorted(event.sensorData.keys()):
            if name in self.trace.sensors and name in event.sensorData and event.sensorData[
                    name]:
                statsTable.addRow(self.trace.sensors[name].description,
                                  event.sensorData[name])

        return section
Example #2
0
    def createFrameSection(self, frame):
        frameSection = Report.Section("Frame #%d" % (frame.number + 1))
        frameSection.create(Report.LinkTarget, "frame%d" % (frame.number + 1))

        # Add a framebuffer snapshot if we have one
        colorBuffer = player.Instrumentation.getBufferFileName(frame.swapEvent)
        if colorBuffer:
            frameSection.create(Report.Image,
                                colorBuffer,
                                elementClass="screenshot")

        table = frameSection.create(Report.Table, ["Property", "Value"])
        table.addRow("API calls", len(frame.events))
        table.addRow("Render calls", len(frame.renderEvents))
        table.addRow("FPS", "%.02f" % (1.0 / frame.duration))

        # Add some frame-level graphs
        frameSection.add(
            self.createEventPlot("Event distribution",
                                 frame.events,
                                 sliceStart=frame.startTime,
                                 sliceLength=frame.duration,
                                 id=frame.number + 1))
        frameSection.add(
            self.createEventFrequencyPlot("Operation distribution",
                                          frame.events,
                                          id=frame.number + 1))

        return frameSection
Example #3
0
    def createEventFrequencyPlot(self, title, events, id=0):
        # Count the number of each event
        eventFrequency = Collections.DefaultDict(lambda: 0)
        for event in events:
            eventFrequency[event.name] += 1

        items = eventFrequency.items()
        items.sort(key=lambda f: -f[1])

        funcNames = [f[0] for f in items]
        funcFreq = [f[1] for f in items]

        # Create a bar charts and add a text describing the event to each bar
        pylab.figure()
        pylab.yticks([])
        pylab.ylim(len(funcNames), 0)
        rects = pylab.barh(range(len(funcNames)),
                           funcFreq,
                           color=self.primaryColor)

        for name, rect in zip(funcNames, rects):
            pylab.text(rect.get_x() + rect.get_width(),
                       rect.get_y() + rect.get_height(),
                       "  " + name,
                       fontsize=8)

        fn = os.path.join(self.path,
                          title.lower().replace(" ", "_") + "%03d.png" % id)
        pylab.savefig(fn)
        pylab.close()

        section = Report.Section(title)
        section.create(Report.Image, fn)
        return section
Example #4
0
    def createChecklistSection(self, title, checklistItems):
        checklistSection = Report.Section(title)
        checklistItems = Checklist.compileChecklist(self.project, self.trace,
                                                    checklistItems)

        for item in checklistItems:
            title = "%s [%s]" % (item.name, item.verdict and "PASS" or "FAIL")
            itemSection = checklistSection.create(Report.Section, title)
            itemSection.create(Report.Paragraph,
                               item.verdict and "PASS" or "FAIL",
                               elementClass=item.verdict and "checkpass"
                               or "checkfail")
            itemSection.create(Report.Paragraph, item.description)
            commentList = itemSection.create(Report.UnorderedList)

            # List unique comments only
            comments = sorted(item.comments, key=lambda c: c[1])
            lastComment = None
            repeatedEvents = []

            for event, comment in comments + [(None, None)]:
                if comment != lastComment:
                    if lastComment and repeatedEvents:
                        if len(repeatedEvents) < 100:
                            commentList.addItem(
                                "Previous comment repeated for %s." %
                                ", ".join([
                                    "%s (%d)" % (e.name, e.seq)
                                    for e in repeatedEvents
                                ]))
                        else:
                            commentList.addItem(
                                "Previous comment repeated for %d events." %
                                len(repeatedEvents))
                    if comment:
                        if event:
                            commentList.addItem(
                                "%s (%d): %s" %
                                (self.getEventDescription(event), event.seq,
                                 comment))
                        else:
                            commentList.addItem(comment)
                        lastComment = comment
                        repeatedEvents = []
                elif event:
                    repeatedEvents.append(event)
        return checklistSection
Example #5
0
    def createPlot(self, title, xAxis, yAxis, id=0, style="line"):
        # See if there's anything to plot
        for value in yAxis:
            if value:
                break
        else:
            return

        pylab.clf()
        Charting.slicePlot(xAxis, yAxis, color=self.primaryColor, style=style)
        fn = os.path.join(self.path,
                          title.lower().replace(" ", "_") + "%03d.png" % id)
        pylab.savefig(fn)
        pylab.close()

        section = Report.Section(title)
        section.create(Report.Image, fn)
        return section
Example #6
0
    def createEventPlot(self,
                        title,
                        events,
                        sliceStart=0.0,
                        sliceLength=10.0,
                        id=0):
        # See if there's anything to plot
        if not len(events) >= 2:
            return

        segmentDuration = (events[-1].time - events[0].time) / 1e6

        if segmentDuration < sliceLength:
            sliceLength = events[0].time / 1e6 + segmentDuration

        segmentStart = sliceStart
        slices = int(segmentDuration / sliceLength) + 2

        pylab.figure(figsize=(8, slices * 1))
        pylab.subplot(slices, 1, 1)
        pylab.xlim(sliceStart, sliceStart + sliceLength)
        pylab.yticks([])

        legends = {}
        for event in events:
            time = event.time / 1e6
            duration = event.duration / 1e6

            if time + duration > sliceStart + sliceLength:
                pylab.subplot(slices, 1,
                              int((time - segmentStart) / sliceLength) + 1)
                pylab.xticks(size=7)
                pylab.yticks([])
                sliceStart += sliceLength
                pylab.xlim(sliceStart, sliceStart + sliceLength)

            func = self.library.functions[event.name]
            if func.isFrameMarker:
                color = self.highlightColor
                label = "frameswap"
            elif func.isRenderCall:
                color = self.primaryColor
                label = "render"
            else:
                continue
            legends[label] = pylab.axvspan(time,
                                           time +
                                           max(sliceLength / 100.0, duration),
                                           facecolor=color,
                                           linewidth=.1,
                                           label=label)

        # Describe the chart elements
        l1 = []
        l2 = []
        if "render" in legends:
            l1.append(legends["render"])
            l2.append("Render call")
        if "frameswap" in legends:
            l1.append(legends["frameswap"])
            l2.append("Frame swap")

        pylab.legend(l1, l2)
        fn = os.path.join(self.path,
                          title.lower().replace(" ", "_") + "%03d.png" % id)

        pylab.savefig(fn)
        pylab.close()

        section = Report.Section(title)
        section.create(Report.Image, fn)
        return section