mirror of
https://github.com/brl/mutter.git
synced 2024-11-26 10:00:45 -05:00
aa05b66a01
This adds a performance tracking framework that can run a set of tests over specified git revisions. The ruby script for generating the reports comes from similar performance tracking in GEGL. The framework permits evaluating new tests against older version of clutter. The tests themselves go through a few hoops for disabling framerate limiting in both mesa and clutter. When running make check the tests will be run and lines of the form: @ test-state: 40.51 fps will be left in the output, a script can scrape these lines out of a build log on a buildbot to in other ways track performance.
180 lines
4.4 KiB
Ruby
Executable File
180 lines
4.4 KiB
Ruby
Executable File
#!/usr/bin/env ruby
|
|
#
|
|
# ruby program to generate a performance report in PDF/png over git revisions, based on work
|
|
# originally done for gegl by pippin@gimp.org, the original program is in the public domain.
|
|
|
|
require 'cairo'
|
|
|
|
def cairo_surface(w,h)
|
|
surface = Cairo::PDFSurface.new("report.pdf", w,h)
|
|
cr = Cairo::Context.new(surface)
|
|
yield(cr)
|
|
end
|
|
|
|
class Database
|
|
|
|
def initialize()
|
|
@vals = Hash.new
|
|
@runs = Array.new
|
|
@colors = [
|
|
[0,1,0, 0.8],
|
|
[0,1,1, 0.8],
|
|
[1,0,0, 0.8],
|
|
[1,0,1, 0.8],
|
|
[1,1,0, 0.8],
|
|
#[0.5,0.5,0.5,0.8],
|
|
# gray doesnt have sufficient contrast against background
|
|
[0.5,0.5,1, 0.8],
|
|
[0.5,1,0.5, 0.8],
|
|
[0.5,1,1, 0.8],
|
|
[1,0.5,0.5, 0.8],
|
|
[1,0.5,1, 0.8],
|
|
[1,1,0.5, 0.8],
|
|
[1,1,1, 0.8],
|
|
]
|
|
@width = 1800
|
|
@height = 500
|
|
|
|
@marginlx = 10
|
|
@marginrx = 180
|
|
@rgap = 40
|
|
@marginy = 10
|
|
end
|
|
def val_max(key)
|
|
max=0
|
|
@runs.each { |run|
|
|
val = @vals[key][run]
|
|
if val and val > max
|
|
max = val
|
|
end
|
|
}
|
|
max
|
|
end
|
|
def val_min(key)
|
|
min=9999990
|
|
@runs.each { |run|
|
|
val = @vals[key][run]
|
|
min = val if val and val < min
|
|
}
|
|
#min
|
|
0 # this shows the relative noise in measurements better
|
|
end
|
|
def add_run(run)
|
|
@runs = @runs + [run]
|
|
end
|
|
def add_entry(run, name, val)
|
|
if !@vals[name]
|
|
@vals[name]=Hash.new
|
|
end
|
|
# check if there is an existing value,
|
|
# and perhaps have different behaviors
|
|
# associated with
|
|
@vals[name][run] = val.to_f
|
|
end
|
|
|
|
def drawbg cr
|
|
cr.set_source_rgba(0.2, 0.2, 0.2, 1)
|
|
cr.paint
|
|
|
|
i=0
|
|
@runs.each { |run|
|
|
if i % 2 == 1
|
|
cr.move_to 1.0 * i / @runs.length * (@width - @marginlx-@marginrx) + @marginlx, 0 * (@height - @marginy*2) + @marginy
|
|
cr.line_to 1.0 * i / @runs.length * (@width - @marginlx-@marginrx) + @marginlx, 1.0 * (@height - @marginy*2) + @marginy
|
|
cr.rel_line_to(1.0 / @runs.length * (@width - @marginlx-@marginrx), 0)
|
|
cr.rel_line_to(0, -(@height - @marginy*2))
|
|
|
|
cr.set_source_rgba([0.25,0.25,0.25,1])
|
|
cr.fill
|
|
end
|
|
i+=1
|
|
}
|
|
end
|
|
|
|
def drawtext cr
|
|
i = 0
|
|
@runs.each { |run|
|
|
y = i * 10 + 20
|
|
while y > @height - @marginy
|
|
y = y - @height + @marginy + 10
|
|
end
|
|
cr.move_to 1.0 * i / @runs.length * (@width - @marginlx-@marginrx) + @marginlx, y
|
|
|
|
cr.set_source_rgba(0.6,0.6,0.6,1)
|
|
cr.show_text(run[0..6])
|
|
i+=1
|
|
}
|
|
end
|
|
|
|
def draw_limits cr, key
|
|
cr.move_to @width - @marginrx + @rgap, 20
|
|
cr.set_source_rgba(1.0, 1.0, 1.0, 1.0)
|
|
cr.show_text(" #{val_max(key)} ")
|
|
cr.move_to @width - @marginrx + @rgap, @height - @marginy
|
|
cr.show_text(" #{val_min(key)} ")
|
|
end
|
|
|
|
def draw_val cr, key, valno
|
|
min = val_min(key)
|
|
max = val_max(key)
|
|
|
|
cr.set_source_rgba(@colors[valno])
|
|
cr.move_to(@width - @marginrx + @rgap, valno * 14 + @marginy + 20)
|
|
cr.show_text(key)
|
|
|
|
cr.line_width = 2
|
|
cr.new_path
|
|
|
|
i = 0
|
|
@runs.each { |run|
|
|
val = @vals[key][run]
|
|
if val
|
|
cr.line_to 1.0 * (i+0.5) / @runs.length * (@width - @marginlx-@marginrx) + @marginlx,
|
|
(1.0 - ((val-min) * 1.0 / (max - min))) * (@height - @marginy*2) + @marginy
|
|
end
|
|
i = i + 1
|
|
}
|
|
cr.stroke
|
|
end
|
|
|
|
def create_report
|
|
cairo_surface(@width, @height) { |cr|
|
|
drawbg cr
|
|
valno = 0
|
|
@vals.each { |key, value|
|
|
draw_val cr, key, valno
|
|
valno += 1
|
|
}
|
|
drawtext cr
|
|
cr.target.write_to_png("report.png")
|
|
|
|
valno = 0
|
|
@vals.each { |key, value|
|
|
cr.show_page
|
|
drawbg cr
|
|
draw_val cr, key, valno
|
|
drawtext cr
|
|
draw_limits cr, key
|
|
valno += 1
|
|
}
|
|
}
|
|
end
|
|
end
|
|
|
|
generator = Database.new
|
|
|
|
items = File.open('jobs').each { |rev|
|
|
rev.strip!
|
|
generator.add_run(rev)
|
|
filename = "reports/" + rev;
|
|
if File.exist?(filename)
|
|
File.open(filename).each { |line|
|
|
if line =~ /^@ (.*):(.*)/
|
|
generator.add_entry(rev, $1, $2)
|
|
end
|
|
}
|
|
end
|
|
}
|
|
|
|
generator.create_report
|