tests: Add performance tracking framework
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.
This commit is contained in:
parent
fa1350b8f3
commit
aa05b66a01
@ -32,4 +32,7 @@ gcov:
|
|||||||
test-report full-report:
|
test-report full-report:
|
||||||
$(MAKE) -C tests/conform $(@)
|
$(MAKE) -C tests/conform $(@)
|
||||||
|
|
||||||
.PHONY: gcov test-report full-report
|
perf-report:
|
||||||
|
$(MAKE) -C tests/performance $(@)
|
||||||
|
|
||||||
|
.PHONY: gcov test-report full-report perf-report
|
||||||
|
@ -949,6 +949,7 @@ AC_CONFIG_FILES([
|
|||||||
tests/interactive/Makefile
|
tests/interactive/Makefile
|
||||||
tests/interactive/wrapper.sh
|
tests/interactive/wrapper.sh
|
||||||
tests/micro-bench/Makefile
|
tests/micro-bench/Makefile
|
||||||
|
tests/performance/Makefile
|
||||||
|
|
||||||
doc/Makefile
|
doc/Makefile
|
||||||
doc/reference/Makefile
|
doc/reference/Makefile
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
SUBDIRS = accessibility data interactive micro-bench
|
SUBDIRS = accessibility data interactive micro-bench performance
|
||||||
|
|
||||||
if BUILD_TESTS
|
if BUILD_TESTS
|
||||||
SUBDIRS += conform
|
SUBDIRS += conform
|
||||||
endif
|
endif
|
||||||
|
|
||||||
DIST_SUBDIRS = accessibility data conform interactive micro-bench
|
DIST_SUBDIRS = accessibility data conform interactive micro-bench performance
|
||||||
|
|
||||||
EXTRA_DIST = README
|
EXTRA_DIST = README
|
||||||
|
|
||||||
|
18
tests/README
18
tests/README
@ -4,15 +4,15 @@ The conform/ tests should be non-interactive unit-tests that verify a single
|
|||||||
feature is behaving as documented. See conform/ADDING_NEW_TESTS for more
|
feature is behaving as documented. See conform/ADDING_NEW_TESTS for more
|
||||||
details.
|
details.
|
||||||
|
|
||||||
The micro-bench/ tests should be focused perfomance test, ideally testing a
|
The performance/ tests are performance tests, both focused tests testing single
|
||||||
single metric. Please never forget that these tests are synthetec and if you
|
metrics and larger tests. These tests are used to report one or more
|
||||||
are using them then you understand what metric is being tested. They probably
|
performance markers for the build of Clutter. Each performance marker is picked
|
||||||
don't reflect any real world application loads and the intention is that you
|
up from the standard output of running the tests from strings having the form
|
||||||
use these tests once you have already determined the crux of your problem and
|
"\n@ marker-name: 42.23" where 'marker-name' and '42.23' are the key/value pairs
|
||||||
need focused feedback that your changes are indeed improving matters. There is
|
of a single metric. Each test can provide multiple key/value pairs. Note that
|
||||||
no exit status requirements for these tests, but they should give clear
|
if framerate is the feedback metric the test should forcibly enable FPS
|
||||||
feedback as to their performance. If the framerate is the feedback metric, then
|
debugging itself. The file test-common.h contains utility function helping to
|
||||||
the test should forcibly enable FPS debugging.
|
do fps reporting.
|
||||||
|
|
||||||
The interactive/ tests are any tests whose status can not be determined without
|
The interactive/ tests are any tests whose status can not be determined without
|
||||||
a user looking at some visual output, or providing some manual input etc. This
|
a user looking at some visual output, or providing some manual input etc. This
|
||||||
|
66
tests/performance/Makefile-retrospect
Normal file
66
tests/performance/Makefile-retrospect
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# A makefile based framework for testing performance commits in retrospect,
|
||||||
|
# based on work done by pippin@gimp.org done for GEGL, original code placed in the public domain.
|
||||||
|
|
||||||
|
SELF = Makefile-retrospect
|
||||||
|
|
||||||
|
MAKE_FLAGS = -j3 -k
|
||||||
|
CC = "ccache gcc" # if you do not have ccache replace with just gcc
|
||||||
|
|
||||||
|
PROJECT_PATH = ../../
|
||||||
|
|
||||||
|
# mute makes echoing of commands
|
||||||
|
.SILENT:
|
||||||
|
|
||||||
|
# replace sequential with random to build a random subset
|
||||||
|
all: reset sequential
|
||||||
|
#all: reset random
|
||||||
|
|
||||||
|
retry:
|
||||||
|
rm -rf reports/`cat jobs | tail -n1`*
|
||||||
|
make -f $(SELF)
|
||||||
|
|
||||||
|
prepare:
|
||||||
|
# uncomment these to make sure cpu is in high performance mode
|
||||||
|
#sudo sh -c 'echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor || true'
|
||||||
|
#sudo sh -c 'echo performance > /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor || true'
|
||||||
|
|
||||||
|
reset:
|
||||||
|
rm -rf jobs jobs
|
||||||
|
# remove checkout dir to have a full reset on each invokation
|
||||||
|
rm -rf checkout
|
||||||
|
# create clone
|
||||||
|
git clone -s $(PROJECT_PATH) checkout
|
||||||
|
mkdir reports > /dev/null 2>&1 || true
|
||||||
|
make -f $(SELF) jobs
|
||||||
|
make -f $(SELF) prepare
|
||||||
|
|
||||||
|
jobs: joblist
|
||||||
|
./makejobs.rb joblist > jobs
|
||||||
|
|
||||||
|
sequential:
|
||||||
|
for a in `cat jobs`;do make -f $(SELF) reports/$$a;done
|
||||||
|
|
||||||
|
random:
|
||||||
|
for a in `cat jobs|sort`;do make -f $(SELF) reports/$$a;done
|
||||||
|
|
||||||
|
reports/%:
|
||||||
|
# check out revision
|
||||||
|
(cd checkout; git checkout `echo $@|sed s:reports/::`)
|
||||||
|
# write header for report
|
||||||
|
git log -1 `echo $@|sed s:reports/::` > $@ || true
|
||||||
|
# clean previous build
|
||||||
|
rm -rf install; mkdir install
|
||||||
|
# build revision
|
||||||
|
(cd checkout; if [ ! -f Makefile ]; then CC=$(CC) ./autogen.sh --disable-introspection --prefix=`pwd`/../install; fi ; \
|
||||||
|
make $(MAKE_FLAGS) ; make -k install ) > $@.log 2>&1 || true
|
||||||
|
# testing
|
||||||
|
make -f Makefile-tests clean;\
|
||||||
|
make -f Makefile-tests; sync;\
|
||||||
|
make -f Makefile-tests check >> $@ || true
|
||||||
|
# update report.pdf / report.png
|
||||||
|
./create-report.rb
|
||||||
|
echo
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf reports jobs report.pdf report.png checkout install
|
||||||
|
make -f Makefile-tests clean
|
15
tests/performance/Makefile-tests
Normal file
15
tests/performance/Makefile-tests
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
CFILES = $(wildcard *.c)
|
||||||
|
bins = $(subst ,,$(CFILES:.c=))
|
||||||
|
|
||||||
|
all: $(bins)
|
||||||
|
|
||||||
|
%: %.c
|
||||||
|
PKG_CONFIG_PATH=install/lib/pkgconfig:$(PKG_CONFIG_PATH) $(CC) -DTESTS_DATA_DIR=\"../data/\" `pkg-config clutter-1.0 --cflags --libs` -Wall -O2 -o $@ $<
|
||||||
|
|
||||||
|
check: $(bins)
|
||||||
|
for a in $(bins); do \
|
||||||
|
LD_LIBRARY_PATH=install/lib:$(LD_LIBRARY_PATH) ./$$a;\
|
||||||
|
done
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(bins)
|
42
tests/performance/Makefile.am
Normal file
42
tests/performance/Makefile.am
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
include $(top_srcdir)/build/autotools/Makefile.am.silent
|
||||||
|
|
||||||
|
noinst_PROGRAMS = \
|
||||||
|
test-picking \
|
||||||
|
test-text-perf \
|
||||||
|
test-state \
|
||||||
|
test-state-interactive \
|
||||||
|
test-state-hidden \
|
||||||
|
test-state-mini \
|
||||||
|
test-state-pick
|
||||||
|
|
||||||
|
INCLUDES = \
|
||||||
|
-I$(top_srcdir)/ \
|
||||||
|
-I$(top_srcdir)/clutter \
|
||||||
|
-I$(top_srcdir)/clutter/cogl \
|
||||||
|
-I$(top_builddir)/clutter \
|
||||||
|
-I$(top_builddir)/clutter/cogl
|
||||||
|
LDADD = $(top_builddir)/clutter/libclutter-@CLUTTER_SONAME_INFIX@-@CLUTTER_API_VERSION@.la
|
||||||
|
AM_CFLAGS = \
|
||||||
|
$(CLUTTER_CFLAGS) \
|
||||||
|
$(MAINTAINER_CFLAGS) \
|
||||||
|
-DG_DISABLE_SINGLE_INCLUDES \
|
||||||
|
-DTESTS_DATA_DIR=\""$(top_srcdir)/tests/data/"\"
|
||||||
|
|
||||||
|
perf-report: check
|
||||||
|
|
||||||
|
check:
|
||||||
|
for a in $(noinst_PROGRAMS);do ./$$a;done;true
|
||||||
|
|
||||||
|
AM_LDFLAGS = $(CLUTTER_LIBS)
|
||||||
|
|
||||||
|
test_picking_SOURCES = test-picking.c
|
||||||
|
test_text_perf_SOURCES = test-text-perf.c
|
||||||
|
test_state_SOURCES = test-state.c
|
||||||
|
test_state_hidden_SOURCES = test-state-hidden.c
|
||||||
|
test_state_pick_SOURCES = test-state-pick.c
|
||||||
|
test_state_interactive_SOURCES = test-state-interactive.c
|
||||||
|
test_state_mini_SOURCES = test-state-mini.c
|
||||||
|
|
||||||
|
EXTRA_DIST = Makefile-retrospect Makefile-tests create-report.rb test-common.h
|
||||||
|
|
||||||
|
-include $(top_srcdir)/build/autotools/Makefile.am.gitignore
|
179
tests/performance/create-report.rb
Executable file
179
tests/performance/create-report.rb
Executable file
@ -0,0 +1,179 @@
|
|||||||
|
#!/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
|
27
tests/performance/joblist
Normal file
27
tests/performance/joblist
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# This file lists the commits that we want to do retrospective testing
|
||||||
|
# of, aborting the retrospective testing and adjusting this file will
|
||||||
|
# add the commit range to be tested without having to redo the initial one
|
||||||
|
# thus allowing a sparse distributed range to first be tested, with
|
||||||
|
# detailed ranges added in later.
|
||||||
|
|
||||||
|
master~500..master % 32 # every 32th commit, to provide context
|
||||||
|
|
||||||
|
# various spans of commits around which "interesting things happen"
|
||||||
|
|
||||||
|
#eeac7~1..985a4
|
||||||
|
#6c6e93d~1..3142b15
|
||||||
|
#0486c56..88b026
|
||||||
|
#732eecf..8cfb158
|
||||||
|
#b499696..b77d9a6
|
||||||
|
#ba09e9c..7bdbbe6
|
||||||
|
#b424bd7..c1878
|
||||||
|
#bc58de4..d03c3a6
|
||||||
|
#5640a6..a29623e
|
||||||
|
#6fd2663..6ec9c32
|
||||||
|
# 012e4ab..1a8d577 #
|
||||||
|
#120d759~4..2235e70
|
||||||
|
|
||||||
|
# ef8be9e25ebe77fc63055191cc48af53d731c108 - actor: Use paint volumes to always queue clipped redraws
|
||||||
|
|
||||||
|
# 5d16000 going up, and 3b78949 going down,. was a case of clipped redraws being broken
|
||||||
|
|
24
tests/performance/makejobs.rb
Executable file
24
tests/performance/makejobs.rb
Executable file
@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
# this ruby script generates a chronologically sorted
|
||||||
|
|
||||||
|
res = ""
|
||||||
|
input = File.read(ARGV[0])
|
||||||
|
input = input.gsub(/#.*/, "")
|
||||||
|
input.split("\n").each {|a|
|
||||||
|
if a =~ /([^ ]*)\.\.([^ ]*) %(.*)/
|
||||||
|
res += `git log #{$1}..#{$2} | grep '^commit' | sed 's/commit //' | sed -n '0~#{$3}p'`
|
||||||
|
elsif a =~ /([^ ]*)\.\.([^ ]*)/
|
||||||
|
res += `git log #{$1}..#{$2} | grep '^commit' | sed 's/commit //'`
|
||||||
|
else
|
||||||
|
res += `echo #{a}`
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
all = `git log | grep '^commit' | sed 's/commit//' `
|
||||||
|
all.split("\n").reverse.each {|a|
|
||||||
|
if res.match(a.strip) != nil
|
||||||
|
puts "#{a.strip}"
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
130
tests/performance/test-common.h
Normal file
130
tests/performance/test-common.h
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <glib.h>
|
||||||
|
#include <clutter/clutter.h>
|
||||||
|
|
||||||
|
static GTimer *testtimer = NULL;
|
||||||
|
static gint testframes = 0;
|
||||||
|
static float testmaxtime = 1.0;
|
||||||
|
|
||||||
|
/* initialize environment to be suitable for fps testing */
|
||||||
|
void clutter_perf_fps_init (void)
|
||||||
|
{
|
||||||
|
/* Force not syncing to vblank, we want free-running maximum FPS */
|
||||||
|
g_setenv ("vblank_mode", "0", FALSE);
|
||||||
|
g_setenv ("CLUTTER_VBLANK", "none", FALSE);
|
||||||
|
|
||||||
|
/* also overrride internal default FPS */
|
||||||
|
g_setenv ("CLUTTER_DEFAULT_FPS", "1000", FALSE);
|
||||||
|
|
||||||
|
if (g_getenv ("CLUTTER_PERFORMANCE_TEST_DURATION"))
|
||||||
|
testmaxtime = atof(g_getenv("CLUTTER_PERFORMANCE_TEST_DURATION"));
|
||||||
|
else
|
||||||
|
testmaxtime = 10.0;
|
||||||
|
|
||||||
|
g_random_set_seed (12345678);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void perf_stage_paint_cb (ClutterStage *stage, gpointer *data);
|
||||||
|
static gboolean perf_fake_mouse_cb (gpointer stage);
|
||||||
|
|
||||||
|
void clutter_perf_fps_start (ClutterStage *stage)
|
||||||
|
{
|
||||||
|
g_signal_connect (stage, "paint", G_CALLBACK (perf_stage_paint_cb), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clutter_perf_fake_mouse (ClutterStage *stage)
|
||||||
|
{
|
||||||
|
g_timeout_add (1000/60, perf_fake_mouse_cb, stage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clutter_perf_fps_report (const gchar *id)
|
||||||
|
{
|
||||||
|
g_print ("\n@ %s: %.2f fps \n",
|
||||||
|
id, testframes / g_timer_elapsed (testtimer, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void perf_stage_paint_cb (ClutterStage *stage, gpointer *data)
|
||||||
|
{
|
||||||
|
if (!testtimer)
|
||||||
|
testtimer = g_timer_new ();
|
||||||
|
testframes ++;
|
||||||
|
if (g_timer_elapsed (testtimer, NULL) > testmaxtime)
|
||||||
|
{
|
||||||
|
clutter_main_quit ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wrap (gfloat *value, gfloat min, gfloat max)
|
||||||
|
{
|
||||||
|
if (*value > max)
|
||||||
|
*value = min;
|
||||||
|
else if (*value < min)
|
||||||
|
*value = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean perf_fake_mouse_cb (gpointer stage)
|
||||||
|
{
|
||||||
|
ClutterEvent *event = clutter_event_new (CLUTTER_MOTION);
|
||||||
|
static ClutterInputDevice *device = NULL;
|
||||||
|
int i;
|
||||||
|
static float x = 0.0;
|
||||||
|
static float y = 0.0;
|
||||||
|
static float xd = 0.0;
|
||||||
|
static float yd = 0.0;
|
||||||
|
static gboolean inited = FALSE;
|
||||||
|
|
||||||
|
gfloat w, h;
|
||||||
|
|
||||||
|
if (!inited) /* XXX:
|
||||||
|
force clutter to do handle our motion events,
|
||||||
|
by forcibly updating the input device's state
|
||||||
|
this shoudl be possible to do in a better
|
||||||
|
manner in the future, a versioning check
|
||||||
|
will have to be added when this is possible
|
||||||
|
without a hack... and the means to do the
|
||||||
|
hack is deprecated
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
ClutterEvent *event2 = clutter_event_new (CLUTTER_ENTER);
|
||||||
|
device = clutter_device_manager_get_core_device (clutter_device_manager_get_default (), CLUTTER_POINTER_DEVICE);
|
||||||
|
|
||||||
|
event2->crossing.stage = stage;
|
||||||
|
event2->crossing.source = stage;
|
||||||
|
event2->crossing.x = 10;
|
||||||
|
event2->crossing.y = 10;
|
||||||
|
event2->crossing.device = device;
|
||||||
|
event2->crossing.related = NULL;
|
||||||
|
|
||||||
|
clutter_input_device_update_from_event (device, event2, TRUE);
|
||||||
|
|
||||||
|
clutter_event_put (event2);
|
||||||
|
clutter_event_free (event2);
|
||||||
|
inited = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_actor_get_size (stage, &w, &h);
|
||||||
|
event->motion.stage = stage;
|
||||||
|
event->motion.device = device;
|
||||||
|
|
||||||
|
/* called about every 60fps, and do 10 picks per stage */
|
||||||
|
for (i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
event->motion.x = x;
|
||||||
|
event->motion.y = y;
|
||||||
|
|
||||||
|
clutter_event_put (event);
|
||||||
|
|
||||||
|
x += xd;
|
||||||
|
y += yd;
|
||||||
|
xd += g_random_double_range (-0.1, 0.1);
|
||||||
|
yd += g_random_double_range (-0.1, 0.1);
|
||||||
|
|
||||||
|
wrap (&x, 0, w);
|
||||||
|
wrap (&y, 0, h);
|
||||||
|
|
||||||
|
xd = CLAMP(xd, -1.3, 1.3);
|
||||||
|
yd = CLAMP(yd, -1.3, 1.3);
|
||||||
|
}
|
||||||
|
clutter_event_free (event);
|
||||||
|
return TRUE;
|
||||||
|
}
|
133
tests/performance/test-picking.c
Normal file
133
tests/performance/test-picking.c
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <clutter/clutter.h>
|
||||||
|
#include "test-common.h"
|
||||||
|
|
||||||
|
#define N_ACTORS 100
|
||||||
|
#define N_EVENTS 5
|
||||||
|
|
||||||
|
static gint n_actors = N_ACTORS;
|
||||||
|
static gint n_events = N_EVENTS;
|
||||||
|
|
||||||
|
static GOptionEntry entries[] = {
|
||||||
|
{
|
||||||
|
"num-actors", 'a',
|
||||||
|
0,
|
||||||
|
G_OPTION_ARG_INT, &n_actors,
|
||||||
|
"Number of actors", "ACTORS"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"num-events", 'e',
|
||||||
|
0,
|
||||||
|
G_OPTION_ARG_INT, &n_events,
|
||||||
|
"Number of events", "EVENTS"
|
||||||
|
},
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
motion_event_cb (ClutterActor *actor, ClutterEvent *event, gpointer user_data)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_events (ClutterActor *stage)
|
||||||
|
{
|
||||||
|
glong i;
|
||||||
|
static gdouble angle = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < n_events; i++)
|
||||||
|
{
|
||||||
|
angle += (2.0 * M_PI) / (gdouble)n_actors;
|
||||||
|
while (angle > M_PI * 2.0)
|
||||||
|
angle -= M_PI * 2.0;
|
||||||
|
|
||||||
|
/* If we synthesized events, they would be motion compressed;
|
||||||
|
* calling get_actor_at_position() doesn't have that problem
|
||||||
|
*/
|
||||||
|
clutter_stage_get_actor_at_pos (CLUTTER_STAGE (stage),
|
||||||
|
CLUTTER_PICK_REACTIVE,
|
||||||
|
256.0 + 206.0 * cos (angle),
|
||||||
|
256.0 + 206.0 * sin (angle));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean queue_redraw (gpointer data)
|
||||||
|
{
|
||||||
|
ClutterActor *stage = CLUTTER_ACTOR (data);
|
||||||
|
clutter_actor_queue_redraw (stage);
|
||||||
|
do_events (stage);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
glong i;
|
||||||
|
gdouble angle;
|
||||||
|
const ClutterColor black = { 0x00, 0x00, 0x00, 0xff };
|
||||||
|
ClutterColor color = { 0x00, 0x00, 0x00, 0xff };
|
||||||
|
ClutterActor *stage, *rect;
|
||||||
|
|
||||||
|
clutter_perf_fps_init ();
|
||||||
|
|
||||||
|
if (CLUTTER_INIT_SUCCESS !=
|
||||||
|
clutter_init_with_args (&argc, &argv,
|
||||||
|
NULL,
|
||||||
|
entries,
|
||||||
|
NULL,
|
||||||
|
NULL))
|
||||||
|
{
|
||||||
|
g_warning ("Failed to initialize clutter");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
stage = clutter_stage_get_default ();
|
||||||
|
clutter_actor_set_size (stage, 512, 512);
|
||||||
|
clutter_stage_set_color (CLUTTER_STAGE (stage), &black);
|
||||||
|
|
||||||
|
printf ("Picking performance test with "
|
||||||
|
"%d actors and %d events per frame\n",
|
||||||
|
n_actors,
|
||||||
|
n_events);
|
||||||
|
|
||||||
|
for (i = n_actors - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
angle = ((2.0 * M_PI) / (gdouble) n_actors) * i;
|
||||||
|
|
||||||
|
color.red = (1.0 - ABS ((MAX (0, MIN (n_actors/2.0 + 0, i))) /
|
||||||
|
(gdouble)(n_actors/4.0) - 1.0)) * 255.0;
|
||||||
|
color.green = (1.0 - ABS ((MAX (0, MIN (n_actors/2.0 + 0,
|
||||||
|
fmod (i + (n_actors/3.0)*2, n_actors)))) /
|
||||||
|
(gdouble)(n_actors/4) - 1.0)) * 255.0;
|
||||||
|
color.blue = (1.0 - ABS ((MAX (0, MIN (n_actors/2.0 + 0,
|
||||||
|
fmod ((i + (n_actors/3.0)), n_actors)))) /
|
||||||
|
(gdouble)(n_actors/4.0) - 1.0)) * 255.0;
|
||||||
|
|
||||||
|
rect = clutter_rectangle_new_with_color (&color);
|
||||||
|
clutter_actor_set_size (rect, 100, 100);
|
||||||
|
clutter_actor_set_anchor_point_from_gravity (rect,
|
||||||
|
CLUTTER_GRAVITY_CENTER);
|
||||||
|
clutter_actor_set_position (rect,
|
||||||
|
256 + 206 * cos (angle),
|
||||||
|
256 + 206 * sin (angle));
|
||||||
|
clutter_actor_set_reactive (rect, TRUE);
|
||||||
|
g_signal_connect (rect, "motion-event",
|
||||||
|
G_CALLBACK (motion_event_cb), NULL);
|
||||||
|
|
||||||
|
clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_actor_show (stage);
|
||||||
|
|
||||||
|
clutter_perf_fps_start (CLUTTER_STAGE (stage));
|
||||||
|
g_idle_add (queue_redraw, (gpointer)stage);
|
||||||
|
clutter_main ();
|
||||||
|
clutter_perf_fps_report ("test-picking");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
149
tests/performance/test-state-hidden.c
Normal file
149
tests/performance/test-state-hidden.c
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <gmodule.h>
|
||||||
|
#include <clutter/clutter.h>
|
||||||
|
#include "test-common.h"
|
||||||
|
|
||||||
|
#define STAGE_WIDTH 160
|
||||||
|
#define STAGE_HEIGHT 120
|
||||||
|
|
||||||
|
#define ACTOR_WIDTH 8
|
||||||
|
#define ACTOR_HEIGHT 8
|
||||||
|
|
||||||
|
#define COLS (STAGE_WIDTH/ACTOR_WIDTH)
|
||||||
|
#define ROWS (STAGE_HEIGHT/ACTOR_HEIGHT)
|
||||||
|
#define TOTAL (ROWS*COLS)
|
||||||
|
|
||||||
|
|
||||||
|
static void completed (ClutterState *state,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
if (g_str_equal (clutter_state_get_state (state), "right"))
|
||||||
|
{
|
||||||
|
/* skip straight to left state when reaching right */
|
||||||
|
clutter_state_warp_to_state (state, "left");
|
||||||
|
}
|
||||||
|
else if (g_str_equal (clutter_state_get_state (state), "active"))
|
||||||
|
clutter_state_set_state (state, "right");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clutter_state_set_state (state, "active");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ClutterActor *new_rect (gint r,
|
||||||
|
gint g,
|
||||||
|
gint b,
|
||||||
|
gint a)
|
||||||
|
{
|
||||||
|
ClutterColor *color = clutter_color_new (r, g, b, a);
|
||||||
|
ClutterActor *group = clutter_group_new ();
|
||||||
|
ClutterActor *rectangle = clutter_rectangle_new_with_color (color);
|
||||||
|
|
||||||
|
gchar *file = g_build_filename (TESTS_DATA_DIR, "redhand.png", NULL);
|
||||||
|
|
||||||
|
g_free (file);
|
||||||
|
clutter_actor_set_size (rectangle, ACTOR_WIDTH,ACTOR_HEIGHT);
|
||||||
|
clutter_color_free (color);
|
||||||
|
clutter_container_add (CLUTTER_CONTAINER (group), rectangle, NULL);
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
gint
|
||||||
|
main (gint argc,
|
||||||
|
gchar **argv)
|
||||||
|
{
|
||||||
|
ClutterColor black={0,0,0,0xff};
|
||||||
|
ClutterActor *stage;
|
||||||
|
ClutterActor *group;
|
||||||
|
ClutterState *layout_state;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
clutter_perf_fps_init ();
|
||||||
|
if (CLUTTER_INIT_SUCCESS != clutter_init (&argc, &argv))
|
||||||
|
g_error ("Failed to initialize Clutter");
|
||||||
|
|
||||||
|
stage = clutter_stage_get_default ();
|
||||||
|
group = clutter_group_new ();
|
||||||
|
layout_state = clutter_state_new ();
|
||||||
|
clutter_stage_set_color (CLUTTER_STAGE (stage), &black);
|
||||||
|
clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT);
|
||||||
|
|
||||||
|
for (i=0; i<TOTAL; i++)
|
||||||
|
{
|
||||||
|
ClutterActor *actor;
|
||||||
|
ClutterState *a_state;
|
||||||
|
|
||||||
|
int row = i/COLS;
|
||||||
|
int col = i%COLS;
|
||||||
|
|
||||||
|
actor = new_rect (255 * ( 1.0*col/COLS), 50,
|
||||||
|
255 * ( 1.0*row/ROWS), 255);
|
||||||
|
clutter_container_add_actor (CLUTTER_CONTAINER (group), actor);
|
||||||
|
clutter_actor_set_position (actor, 320.0, 240.0);
|
||||||
|
clutter_actor_set_reactive (actor, TRUE);
|
||||||
|
|
||||||
|
|
||||||
|
clutter_state_set (layout_state, NULL, "active",
|
||||||
|
actor, "delayed::x", CLUTTER_LINEAR,
|
||||||
|
ACTOR_WIDTH * 1.0 * ((TOTAL-1-i) % COLS),
|
||||||
|
((row*1.0/ROWS))/2, (1.0-(row*1.0/ROWS))/2,
|
||||||
|
actor, "delayed::y", CLUTTER_LINEAR,
|
||||||
|
ACTOR_HEIGHT * 1.0 * ((TOTAL-1-i) / COLS),
|
||||||
|
((row*1.0/ROWS))/2, 0.0,
|
||||||
|
actor, "rotation-angle-x", CLUTTER_LINEAR, 0.0,
|
||||||
|
actor, "rotation-angle-y", CLUTTER_LINEAR, 0.0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
clutter_state_set (layout_state, NULL, "right",
|
||||||
|
actor, "delayed::x", CLUTTER_LINEAR, STAGE_WIDTH * 1.0,
|
||||||
|
((row*1.0/ROWS))/2,
|
||||||
|
(1.0-(row*1.0/ROWS))/2,
|
||||||
|
actor, "delayed::y", CLUTTER_LINEAR, STAGE_HEIGHT * 1.0,
|
||||||
|
((row*1.0/ROWS))/2,
|
||||||
|
0.0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
clutter_state_set (layout_state, NULL, "left",
|
||||||
|
actor, "rotation-angle-x", CLUTTER_LINEAR, 45.0,
|
||||||
|
actor, "rotation-angle-y", CLUTTER_LINEAR, 5.0,
|
||||||
|
actor, "x", CLUTTER_LINEAR, 0-64.0,
|
||||||
|
actor, "y", CLUTTER_LINEAR, 0-64.0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
a_state = clutter_state_new ();
|
||||||
|
g_object_set_data_full (G_OBJECT (actor), "hover-state-machine",
|
||||||
|
a_state, g_object_unref);
|
||||||
|
|
||||||
|
clutter_state_set (a_state, NULL, "normal",
|
||||||
|
actor, "opacity", CLUTTER_LINEAR, 0x77,
|
||||||
|
actor, "rotation-angle-z", CLUTTER_LINEAR, 0.0,
|
||||||
|
NULL);
|
||||||
|
clutter_state_set (a_state, NULL, "hover",
|
||||||
|
actor, "opacity", CLUTTER_LINEAR, 0xff,
|
||||||
|
actor, "rotation-angle-z", CLUTTER_LINEAR, 10.0,
|
||||||
|
NULL);
|
||||||
|
clutter_actor_set_opacity (actor, 0x77);
|
||||||
|
|
||||||
|
clutter_state_set_duration (a_state, NULL, NULL, 500);
|
||||||
|
}
|
||||||
|
clutter_container_add_actor (CLUTTER_CONTAINER (stage), group);
|
||||||
|
clutter_actor_set_opacity (group, 0);
|
||||||
|
|
||||||
|
clutter_state_set_duration (layout_state, NULL, NULL, 1000);
|
||||||
|
clutter_state_set_duration (layout_state, "active", "left", 1400);
|
||||||
|
|
||||||
|
g_signal_connect (layout_state, "completed", G_CALLBACK (completed), NULL);
|
||||||
|
|
||||||
|
clutter_actor_show (stage);
|
||||||
|
|
||||||
|
clutter_state_warp_to_state (layout_state, "left");
|
||||||
|
clutter_state_set_state (layout_state, "active");
|
||||||
|
|
||||||
|
clutter_perf_fps_start (CLUTTER_STAGE (stage));
|
||||||
|
clutter_main ();
|
||||||
|
clutter_perf_fps_report ("test-state-hidden");
|
||||||
|
g_object_unref (layout_state);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
194
tests/performance/test-state-interactive.c
Normal file
194
tests/performance/test-state-interactive.c
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <gmodule.h>
|
||||||
|
#include <clutter/clutter.h>
|
||||||
|
#include "test-common.h"
|
||||||
|
|
||||||
|
#define STAGE_WIDTH 800
|
||||||
|
#define STAGE_HEIGHT 600
|
||||||
|
|
||||||
|
#define ACTOR_WIDTH 64
|
||||||
|
#define ACTOR_HEIGHT 64
|
||||||
|
|
||||||
|
#define COLS (STAGE_WIDTH/ACTOR_WIDTH)
|
||||||
|
#define ROWS (STAGE_HEIGHT/ACTOR_HEIGHT)
|
||||||
|
#define TOTAL (ROWS*COLS)
|
||||||
|
|
||||||
|
|
||||||
|
static gboolean press_event (ClutterActor *actor,
|
||||||
|
ClutterEvent *event,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
ClutterState *state = CLUTTER_STATE (user_data);
|
||||||
|
clutter_state_set_state (state, "right");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean release_event (ClutterActor *actor,
|
||||||
|
ClutterEvent *event,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
ClutterState *state = CLUTTER_STATE (user_data);
|
||||||
|
clutter_state_set_state (state, "active");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean enter_event (ClutterActor *actor,
|
||||||
|
ClutterEvent *event,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
ClutterState *state = CLUTTER_STATE (user_data);
|
||||||
|
clutter_state_set_state (state, "hover");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean leave_event (ClutterActor *actor,
|
||||||
|
ClutterEvent *event,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
ClutterState *state = CLUTTER_STATE (user_data);
|
||||||
|
clutter_state_set_state (state, "normal");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void completed (ClutterState *state,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
g_print ("Completed transitioning to state: %s\n",
|
||||||
|
clutter_state_get_state (state));
|
||||||
|
|
||||||
|
if (g_str_equal (clutter_state_get_state (state), "right"))
|
||||||
|
{
|
||||||
|
/* skip straight to left state when reaching right */
|
||||||
|
clutter_state_warp_to_state (state, "left");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ClutterActor *new_rect (gint r,
|
||||||
|
gint g,
|
||||||
|
gint b,
|
||||||
|
gint a)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
ClutterColor *color = clutter_color_new (r, g, b, a);
|
||||||
|
ClutterActor *group = clutter_group_new ();
|
||||||
|
ClutterActor *rectangle = clutter_rectangle_new_with_color (color);
|
||||||
|
ClutterActor *hand = NULL;
|
||||||
|
|
||||||
|
gchar *file = g_build_filename (TESTS_DATA_DIR, "redhand.png", NULL);
|
||||||
|
|
||||||
|
hand = clutter_texture_new_from_file (file, &error);
|
||||||
|
if (rectangle == NULL)
|
||||||
|
g_error ("image load failed: %s", error->message);
|
||||||
|
g_free (file);
|
||||||
|
clutter_actor_set_size (hand, ACTOR_WIDTH,ACTOR_HEIGHT);
|
||||||
|
|
||||||
|
clutter_actor_set_size (rectangle, ACTOR_WIDTH,ACTOR_HEIGHT);
|
||||||
|
clutter_color_free (color);
|
||||||
|
clutter_container_add (CLUTTER_CONTAINER (group), rectangle, hand, NULL);
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
gint
|
||||||
|
main (gint argc,
|
||||||
|
gchar **argv)
|
||||||
|
{
|
||||||
|
ClutterColor black={0,0,0,0xff};
|
||||||
|
ClutterActor *stage;
|
||||||
|
ClutterState *layout_state;
|
||||||
|
gint i;
|
||||||
|
clutter_perf_fps_init ();
|
||||||
|
if (CLUTTER_INIT_SUCCESS != clutter_init (&argc, &argv))
|
||||||
|
g_error ("Failed to initialize Clutter");
|
||||||
|
|
||||||
|
stage = clutter_stage_get_default ();
|
||||||
|
layout_state = clutter_state_new ();
|
||||||
|
clutter_stage_set_color (CLUTTER_STAGE (stage), &black);
|
||||||
|
clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT);
|
||||||
|
|
||||||
|
g_signal_connect (stage, "button-press-event",
|
||||||
|
G_CALLBACK (press_event), layout_state);
|
||||||
|
g_signal_connect (stage, "button-release-event",
|
||||||
|
G_CALLBACK (release_event), layout_state);
|
||||||
|
|
||||||
|
for (i=0; i<TOTAL; i++)
|
||||||
|
{
|
||||||
|
ClutterActor *actor;
|
||||||
|
ClutterState *a_state;
|
||||||
|
|
||||||
|
int row = i/COLS;
|
||||||
|
int col = i%COLS;
|
||||||
|
|
||||||
|
actor = new_rect (255 * ( 1.0*col/COLS), 50,
|
||||||
|
255 * ( 1.0*row/ROWS), 255);
|
||||||
|
clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor);
|
||||||
|
clutter_actor_set_position (actor, 320.0, 240.0);
|
||||||
|
clutter_actor_set_reactive (actor, TRUE);
|
||||||
|
|
||||||
|
|
||||||
|
clutter_state_set (layout_state, NULL, "active",
|
||||||
|
actor, "delayed::x", CLUTTER_LINEAR,
|
||||||
|
ACTOR_WIDTH * 1.0 * ((TOTAL-1-i) % COLS),
|
||||||
|
((row*1.0/ROWS))/2, (1.0-(row*1.0/ROWS))/2,
|
||||||
|
actor, "delayed::y", CLUTTER_LINEAR,
|
||||||
|
ACTOR_HEIGHT * 1.0 * ((TOTAL-1-i) / COLS),
|
||||||
|
((row*1.0/ROWS))/2, 0.0,
|
||||||
|
actor, "rotation-angle-x", CLUTTER_LINEAR, 0.0,
|
||||||
|
actor, "rotation-angle-y", CLUTTER_LINEAR, 0.0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
clutter_state_set (layout_state, NULL, "right",
|
||||||
|
actor, "delayed::x", CLUTTER_LINEAR, STAGE_WIDTH * 1.0,
|
||||||
|
((row*1.0/ROWS))/2,
|
||||||
|
(1.0-(row*1.0/ROWS))/2,
|
||||||
|
actor, "delayed::y", CLUTTER_LINEAR, STAGE_HEIGHT * 1.0,
|
||||||
|
((row*1.0/ROWS))/2,
|
||||||
|
0.0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
clutter_state_set (layout_state, NULL, "left",
|
||||||
|
actor, "rotation-angle-x", CLUTTER_LINEAR, 45.0,
|
||||||
|
actor, "rotation-angle-y", CLUTTER_LINEAR, 5.0,
|
||||||
|
actor, "x", CLUTTER_LINEAR, 0-64.0,
|
||||||
|
actor, "y", CLUTTER_LINEAR, 0-64.0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
a_state = clutter_state_new ();
|
||||||
|
g_object_set_data_full (G_OBJECT (actor), "hover-state-machine",
|
||||||
|
a_state, g_object_unref);
|
||||||
|
g_signal_connect (actor, "enter-event",
|
||||||
|
G_CALLBACK (enter_event), a_state);
|
||||||
|
g_signal_connect (actor, "leave-event",
|
||||||
|
G_CALLBACK (leave_event), a_state);
|
||||||
|
|
||||||
|
clutter_state_set (a_state, NULL, "normal",
|
||||||
|
actor, "opacity", CLUTTER_LINEAR, 0x77,
|
||||||
|
actor, "rotation-angle-z", CLUTTER_LINEAR, 0.0,
|
||||||
|
NULL);
|
||||||
|
clutter_state_set (a_state, NULL, "hover",
|
||||||
|
actor, "opacity", CLUTTER_LINEAR, 0xff,
|
||||||
|
actor, "rotation-angle-z", CLUTTER_LINEAR, 10.0,
|
||||||
|
NULL);
|
||||||
|
clutter_actor_set_opacity (actor, 0x77);
|
||||||
|
|
||||||
|
clutter_state_set_duration (a_state, NULL, NULL, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_state_set_duration (layout_state, NULL, NULL, 1000);
|
||||||
|
clutter_state_set_duration (layout_state, "active", "left", 1400);
|
||||||
|
|
||||||
|
g_signal_connect (layout_state, "completed", G_CALLBACK (completed), NULL);
|
||||||
|
|
||||||
|
clutter_actor_show (stage);
|
||||||
|
|
||||||
|
clutter_state_warp_to_state (layout_state, "left");
|
||||||
|
clutter_state_set_state (layout_state, "active");
|
||||||
|
|
||||||
|
clutter_perf_fake_mouse (CLUTTER_STAGE (stage));
|
||||||
|
clutter_perf_fps_start (CLUTTER_STAGE (stage));
|
||||||
|
clutter_main ();
|
||||||
|
clutter_perf_fps_report ("test-state-interactive");
|
||||||
|
g_object_unref (layout_state);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
152
tests/performance/test-state-mini.c
Normal file
152
tests/performance/test-state-mini.c
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <gmodule.h>
|
||||||
|
#include <clutter/clutter.h>
|
||||||
|
#include "test-common.h"
|
||||||
|
|
||||||
|
#define STAGE_WIDTH 160
|
||||||
|
#define STAGE_HEIGHT 120
|
||||||
|
|
||||||
|
#define ACTOR_WIDTH 8
|
||||||
|
#define ACTOR_HEIGHT 8
|
||||||
|
|
||||||
|
#define COLS (STAGE_WIDTH/ACTOR_WIDTH)
|
||||||
|
#define ROWS (STAGE_HEIGHT/ACTOR_HEIGHT)
|
||||||
|
#define TOTAL (ROWS*COLS)
|
||||||
|
|
||||||
|
|
||||||
|
static void completed (ClutterState *state,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
if (g_str_equal (clutter_state_get_state (state), "right"))
|
||||||
|
{
|
||||||
|
/* skip straight to left state when reaching right */
|
||||||
|
clutter_state_warp_to_state (state, "left");
|
||||||
|
}
|
||||||
|
else if (g_str_equal (clutter_state_get_state (state), "active"))
|
||||||
|
clutter_state_set_state (state, "right");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clutter_state_set_state (state, "active");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ClutterActor *new_rect (gint r,
|
||||||
|
gint g,
|
||||||
|
gint b,
|
||||||
|
gint a)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
ClutterColor *color = clutter_color_new (r, g, b, a);
|
||||||
|
ClutterActor *group = clutter_group_new ();
|
||||||
|
ClutterActor *rectangle = clutter_rectangle_new_with_color (color);
|
||||||
|
ClutterActor *hand = NULL;
|
||||||
|
|
||||||
|
gchar *file = g_build_filename (TESTS_DATA_DIR, "redhand.png", NULL);
|
||||||
|
|
||||||
|
hand = clutter_texture_new_from_file (file, &error);
|
||||||
|
if (rectangle == NULL)
|
||||||
|
g_error ("image load failed: %s", error->message);
|
||||||
|
g_free (file);
|
||||||
|
clutter_actor_set_size (hand, ACTOR_WIDTH,ACTOR_HEIGHT);
|
||||||
|
|
||||||
|
clutter_actor_set_size (rectangle, ACTOR_WIDTH,ACTOR_HEIGHT);
|
||||||
|
clutter_color_free (color);
|
||||||
|
clutter_container_add (CLUTTER_CONTAINER (group), rectangle, hand, NULL);
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
gint
|
||||||
|
main (gint argc,
|
||||||
|
gchar **argv)
|
||||||
|
{
|
||||||
|
ClutterColor black={0,0,0,0xff};
|
||||||
|
ClutterActor *stage;
|
||||||
|
ClutterState *layout_state;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
clutter_perf_fps_init ();
|
||||||
|
if (CLUTTER_INIT_SUCCESS != clutter_init (&argc, &argv))
|
||||||
|
g_error ("Failed to initialize Clutter");
|
||||||
|
|
||||||
|
stage = clutter_stage_get_default ();
|
||||||
|
layout_state = clutter_state_new ();
|
||||||
|
clutter_stage_set_color (CLUTTER_STAGE (stage), &black);
|
||||||
|
clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT);
|
||||||
|
|
||||||
|
for (i=0; i<TOTAL; i++)
|
||||||
|
{
|
||||||
|
ClutterActor *actor;
|
||||||
|
ClutterState *a_state;
|
||||||
|
|
||||||
|
int row = i/COLS;
|
||||||
|
int col = i%COLS;
|
||||||
|
|
||||||
|
actor = new_rect (255 * ( 1.0*col/COLS), 50,
|
||||||
|
255 * ( 1.0*row/ROWS), 255);
|
||||||
|
clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor);
|
||||||
|
clutter_actor_set_position (actor, 320.0, 240.0);
|
||||||
|
clutter_actor_set_reactive (actor, TRUE);
|
||||||
|
|
||||||
|
|
||||||
|
clutter_state_set (layout_state, NULL, "active",
|
||||||
|
actor, "delayed::x", CLUTTER_LINEAR,
|
||||||
|
ACTOR_WIDTH * 1.0 * ((TOTAL-1-i) % COLS),
|
||||||
|
((row*1.0/ROWS))/2, (1.0-(row*1.0/ROWS))/2,
|
||||||
|
actor, "delayed::y", CLUTTER_LINEAR,
|
||||||
|
ACTOR_HEIGHT * 1.0 * ((TOTAL-1-i) / COLS),
|
||||||
|
((row*1.0/ROWS))/2, 0.0,
|
||||||
|
actor, "rotation-angle-x", CLUTTER_LINEAR, 0.0,
|
||||||
|
actor, "rotation-angle-y", CLUTTER_LINEAR, 0.0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
clutter_state_set (layout_state, NULL, "right",
|
||||||
|
actor, "delayed::x", CLUTTER_LINEAR, STAGE_WIDTH * 1.0,
|
||||||
|
((row*1.0/ROWS))/2,
|
||||||
|
(1.0-(row*1.0/ROWS))/2,
|
||||||
|
actor, "delayed::y", CLUTTER_LINEAR, STAGE_HEIGHT * 1.0,
|
||||||
|
((row*1.0/ROWS))/2,
|
||||||
|
0.0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
clutter_state_set (layout_state, NULL, "left",
|
||||||
|
actor, "rotation-angle-x", CLUTTER_LINEAR, 45.0,
|
||||||
|
actor, "rotation-angle-y", CLUTTER_LINEAR, 5.0,
|
||||||
|
actor, "x", CLUTTER_LINEAR, 0-64.0,
|
||||||
|
actor, "y", CLUTTER_LINEAR, 0-64.0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
a_state = clutter_state_new ();
|
||||||
|
g_object_set_data_full (G_OBJECT (actor), "hover-state-machine",
|
||||||
|
a_state, g_object_unref);
|
||||||
|
|
||||||
|
clutter_state_set (a_state, NULL, "normal",
|
||||||
|
actor, "opacity", CLUTTER_LINEAR, 0x77,
|
||||||
|
actor, "rotation-angle-z", CLUTTER_LINEAR, 0.0,
|
||||||
|
NULL);
|
||||||
|
clutter_state_set (a_state, NULL, "hover",
|
||||||
|
actor, "opacity", CLUTTER_LINEAR, 0xff,
|
||||||
|
actor, "rotation-angle-z", CLUTTER_LINEAR, 10.0,
|
||||||
|
NULL);
|
||||||
|
clutter_actor_set_opacity (actor, 0x77);
|
||||||
|
|
||||||
|
clutter_state_set_duration (a_state, NULL, NULL, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_state_set_duration (layout_state, NULL, NULL, 1000);
|
||||||
|
clutter_state_set_duration (layout_state, "active", "left", 1400);
|
||||||
|
|
||||||
|
g_signal_connect (layout_state, "completed", G_CALLBACK (completed), NULL);
|
||||||
|
|
||||||
|
clutter_actor_show (stage);
|
||||||
|
|
||||||
|
clutter_state_warp_to_state (layout_state, "left");
|
||||||
|
clutter_state_set_state (layout_state, "active");
|
||||||
|
|
||||||
|
clutter_perf_fps_start (CLUTTER_STAGE (stage));
|
||||||
|
clutter_main ();
|
||||||
|
clutter_perf_fps_report ("test-state-mini");
|
||||||
|
g_object_unref (layout_state);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
158
tests/performance/test-state-pick.c
Normal file
158
tests/performance/test-state-pick.c
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <gmodule.h>
|
||||||
|
#include <clutter/clutter.h>
|
||||||
|
#include "test-common.h"
|
||||||
|
|
||||||
|
static gint times = 16;
|
||||||
|
|
||||||
|
#define STAGE_WIDTH 800
|
||||||
|
#define STAGE_HEIGHT 600
|
||||||
|
|
||||||
|
#define ACTOR_WIDTH 64
|
||||||
|
#define ACTOR_HEIGHT 64
|
||||||
|
|
||||||
|
#define COLS (STAGE_WIDTH/ACTOR_WIDTH)
|
||||||
|
#define ROWS (STAGE_HEIGHT/ACTOR_HEIGHT)
|
||||||
|
#define TOTAL (ROWS*COLS)
|
||||||
|
|
||||||
|
|
||||||
|
static void completed (ClutterState *state,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
if (g_str_equal (clutter_state_get_state (state), "right"))
|
||||||
|
{
|
||||||
|
/* skip straight to left state when reaching right */
|
||||||
|
clutter_state_warp_to_state (state, "left");
|
||||||
|
}
|
||||||
|
else if (g_str_equal (clutter_state_get_state (state), "active"))
|
||||||
|
clutter_state_set_state (state, "right");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clutter_state_set_state (state, "active");
|
||||||
|
}
|
||||||
|
times --;
|
||||||
|
if (times <=0)
|
||||||
|
clutter_main_quit ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static ClutterActor *new_rect (gint r,
|
||||||
|
gint g,
|
||||||
|
gint b,
|
||||||
|
gint a)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
ClutterColor *color = clutter_color_new (r, g, b, a);
|
||||||
|
ClutterActor *group = clutter_group_new ();
|
||||||
|
ClutterActor *rectangle = clutter_rectangle_new_with_color (color);
|
||||||
|
ClutterActor *hand = NULL;
|
||||||
|
|
||||||
|
gchar *file = g_build_filename (TESTS_DATA_DIR, "redhand.png", NULL);
|
||||||
|
|
||||||
|
hand = clutter_texture_new_from_file (file, &error);
|
||||||
|
if (rectangle == NULL)
|
||||||
|
g_error ("image load failed: %s", error->message);
|
||||||
|
g_free (file);
|
||||||
|
clutter_actor_set_size (hand, ACTOR_WIDTH,ACTOR_HEIGHT);
|
||||||
|
|
||||||
|
clutter_actor_set_size (rectangle, ACTOR_WIDTH,ACTOR_HEIGHT);
|
||||||
|
clutter_color_free (color);
|
||||||
|
clutter_container_add (CLUTTER_CONTAINER (group), rectangle, hand, NULL);
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
gint
|
||||||
|
main (gint argc,
|
||||||
|
gchar **argv)
|
||||||
|
{
|
||||||
|
ClutterColor black={0,0,0,0xff};
|
||||||
|
ClutterActor *stage;
|
||||||
|
ClutterState *layout_state;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
clutter_perf_fps_init ();
|
||||||
|
if (CLUTTER_INIT_SUCCESS != clutter_init (&argc, &argv))
|
||||||
|
g_error ("Failed to initialize Clutter");
|
||||||
|
|
||||||
|
stage = clutter_stage_get_default ();
|
||||||
|
layout_state = clutter_state_new ();
|
||||||
|
clutter_stage_set_color (CLUTTER_STAGE (stage), &black);
|
||||||
|
clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT);
|
||||||
|
|
||||||
|
for (i=0; i<TOTAL; i++)
|
||||||
|
{
|
||||||
|
ClutterActor *actor;
|
||||||
|
ClutterState *a_state;
|
||||||
|
|
||||||
|
int row = i/COLS;
|
||||||
|
int col = i%COLS;
|
||||||
|
|
||||||
|
actor = new_rect (255 * ( 1.0*col/COLS), 50,
|
||||||
|
255 * ( 1.0*row/ROWS), 255);
|
||||||
|
clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor);
|
||||||
|
clutter_actor_set_position (actor, 320.0, 240.0);
|
||||||
|
clutter_actor_set_reactive (actor, TRUE);
|
||||||
|
|
||||||
|
|
||||||
|
clutter_state_set (layout_state, NULL, "active",
|
||||||
|
actor, "delayed::x", CLUTTER_LINEAR,
|
||||||
|
ACTOR_WIDTH * 1.0 * ((TOTAL-1-i) % COLS),
|
||||||
|
((row*1.0/ROWS))/2, (1.0-(row*1.0/ROWS))/2,
|
||||||
|
actor, "delayed::y", CLUTTER_LINEAR,
|
||||||
|
ACTOR_HEIGHT * 1.0 * ((TOTAL-1-i) / COLS),
|
||||||
|
((row*1.0/ROWS))/2, 0.0,
|
||||||
|
actor, "rotation-angle-x", CLUTTER_LINEAR, 0.0,
|
||||||
|
actor, "rotation-angle-y", CLUTTER_LINEAR, 0.0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
clutter_state_set (layout_state, NULL, "right",
|
||||||
|
actor, "delayed::x", CLUTTER_LINEAR, STAGE_WIDTH * 1.0,
|
||||||
|
((row*1.0/ROWS))/2,
|
||||||
|
(1.0-(row*1.0/ROWS))/2,
|
||||||
|
actor, "delayed::y", CLUTTER_LINEAR, STAGE_HEIGHT * 1.0,
|
||||||
|
((row*1.0/ROWS))/2,
|
||||||
|
0.0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
clutter_state_set (layout_state, NULL, "left",
|
||||||
|
actor, "rotation-angle-x", CLUTTER_LINEAR, 45.0,
|
||||||
|
actor, "rotation-angle-y", CLUTTER_LINEAR, 5.0,
|
||||||
|
actor, "x", CLUTTER_LINEAR, 0-64.0,
|
||||||
|
actor, "y", CLUTTER_LINEAR, 0-64.0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
a_state = clutter_state_new ();
|
||||||
|
g_object_set_data_full (G_OBJECT (actor), "hover-state-machine",
|
||||||
|
a_state, g_object_unref);
|
||||||
|
|
||||||
|
clutter_state_set (a_state, NULL, "normal",
|
||||||
|
actor, "opacity", CLUTTER_LINEAR, 0x77,
|
||||||
|
actor, "rotation-angle-z", CLUTTER_LINEAR, 0.0,
|
||||||
|
NULL);
|
||||||
|
clutter_state_set (a_state, NULL, "hover",
|
||||||
|
actor, "opacity", CLUTTER_LINEAR, 0xff,
|
||||||
|
actor, "rotation-angle-z", CLUTTER_LINEAR, 10.0,
|
||||||
|
NULL);
|
||||||
|
clutter_actor_set_opacity (actor, 0x77);
|
||||||
|
|
||||||
|
clutter_state_set_duration (a_state, NULL, NULL, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_state_set_duration (layout_state, NULL, NULL, 1000);
|
||||||
|
clutter_state_set_duration (layout_state, "active", "left", 1400);
|
||||||
|
|
||||||
|
g_signal_connect (layout_state, "completed", G_CALLBACK (completed), NULL);
|
||||||
|
|
||||||
|
clutter_actor_show (stage);
|
||||||
|
|
||||||
|
clutter_state_warp_to_state (layout_state, "left");
|
||||||
|
clutter_state_set_state (layout_state, "active");
|
||||||
|
|
||||||
|
clutter_perf_fake_mouse (CLUTTER_STAGE (stage));
|
||||||
|
clutter_perf_fps_start (CLUTTER_STAGE (stage));
|
||||||
|
clutter_main ();
|
||||||
|
clutter_perf_fps_report ("test-state-pick");
|
||||||
|
g_object_unref (layout_state);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
157
tests/performance/test-state.c
Normal file
157
tests/performance/test-state.c
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <gmodule.h>
|
||||||
|
#include <clutter/clutter.h>
|
||||||
|
#include "test-common.h"
|
||||||
|
|
||||||
|
static gint times = 16;
|
||||||
|
|
||||||
|
#define STAGE_WIDTH 800
|
||||||
|
#define STAGE_HEIGHT 600
|
||||||
|
|
||||||
|
#define ACTOR_WIDTH 64
|
||||||
|
#define ACTOR_HEIGHT 64
|
||||||
|
|
||||||
|
#define COLS (STAGE_WIDTH/ACTOR_WIDTH)
|
||||||
|
#define ROWS (STAGE_HEIGHT/ACTOR_HEIGHT)
|
||||||
|
#define TOTAL (ROWS*COLS)
|
||||||
|
|
||||||
|
|
||||||
|
static void completed (ClutterState *state,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
if (g_str_equal (clutter_state_get_state (state), "right"))
|
||||||
|
{
|
||||||
|
/* skip straight to left state when reaching right */
|
||||||
|
clutter_state_warp_to_state (state, "left");
|
||||||
|
}
|
||||||
|
else if (g_str_equal (clutter_state_get_state (state), "active"))
|
||||||
|
clutter_state_set_state (state, "right");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clutter_state_set_state (state, "active");
|
||||||
|
}
|
||||||
|
times --;
|
||||||
|
if (times <=0)
|
||||||
|
clutter_main_quit ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static ClutterActor *new_rect (gint r,
|
||||||
|
gint g,
|
||||||
|
gint b,
|
||||||
|
gint a)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
ClutterColor *color = clutter_color_new (r, g, b, a);
|
||||||
|
ClutterActor *group = clutter_group_new ();
|
||||||
|
ClutterActor *rectangle = clutter_rectangle_new_with_color (color);
|
||||||
|
ClutterActor *hand = NULL;
|
||||||
|
|
||||||
|
gchar *file = g_build_filename (TESTS_DATA_DIR, "redhand.png", NULL);
|
||||||
|
|
||||||
|
hand = clutter_texture_new_from_file (file, &error);
|
||||||
|
if (rectangle == NULL)
|
||||||
|
g_error ("image load failed: %s", error->message);
|
||||||
|
g_free (file);
|
||||||
|
clutter_actor_set_size (hand, ACTOR_WIDTH,ACTOR_HEIGHT);
|
||||||
|
|
||||||
|
clutter_actor_set_size (rectangle, ACTOR_WIDTH,ACTOR_HEIGHT);
|
||||||
|
clutter_color_free (color);
|
||||||
|
clutter_container_add (CLUTTER_CONTAINER (group), rectangle, hand, NULL);
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
gint
|
||||||
|
main (gint argc,
|
||||||
|
gchar **argv)
|
||||||
|
{
|
||||||
|
ClutterColor black={0,0,0,0xff};
|
||||||
|
ClutterActor *stage;
|
||||||
|
ClutterState *layout_state;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
clutter_perf_fps_init ();
|
||||||
|
if (CLUTTER_INIT_SUCCESS != clutter_init (&argc, &argv))
|
||||||
|
g_error ("Failed to initialize Clutter");
|
||||||
|
|
||||||
|
stage = clutter_stage_get_default ();
|
||||||
|
layout_state = clutter_state_new ();
|
||||||
|
clutter_stage_set_color (CLUTTER_STAGE (stage), &black);
|
||||||
|
clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT);
|
||||||
|
|
||||||
|
for (i=0; i<TOTAL; i++)
|
||||||
|
{
|
||||||
|
ClutterActor *actor;
|
||||||
|
ClutterState *a_state;
|
||||||
|
|
||||||
|
int row = i/COLS;
|
||||||
|
int col = i%COLS;
|
||||||
|
|
||||||
|
actor = new_rect (255 * ( 1.0*col/COLS), 50,
|
||||||
|
255 * ( 1.0*row/ROWS), 255);
|
||||||
|
clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor);
|
||||||
|
clutter_actor_set_position (actor, 320.0, 240.0);
|
||||||
|
clutter_actor_set_reactive (actor, TRUE);
|
||||||
|
|
||||||
|
|
||||||
|
clutter_state_set (layout_state, NULL, "active",
|
||||||
|
actor, "delayed::x", CLUTTER_LINEAR,
|
||||||
|
ACTOR_WIDTH * 1.0 * ((TOTAL-1-i) % COLS),
|
||||||
|
((row*1.0/ROWS))/2, (1.0-(row*1.0/ROWS))/2,
|
||||||
|
actor, "delayed::y", CLUTTER_LINEAR,
|
||||||
|
ACTOR_HEIGHT * 1.0 * ((TOTAL-1-i) / COLS),
|
||||||
|
((row*1.0/ROWS))/2, 0.0,
|
||||||
|
actor, "rotation-angle-x", CLUTTER_LINEAR, 0.0,
|
||||||
|
actor, "rotation-angle-y", CLUTTER_LINEAR, 0.0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
clutter_state_set (layout_state, NULL, "right",
|
||||||
|
actor, "delayed::x", CLUTTER_LINEAR, STAGE_WIDTH * 1.0,
|
||||||
|
((row*1.0/ROWS))/2,
|
||||||
|
(1.0-(row*1.0/ROWS))/2,
|
||||||
|
actor, "delayed::y", CLUTTER_LINEAR, STAGE_HEIGHT * 1.0,
|
||||||
|
((row*1.0/ROWS))/2,
|
||||||
|
0.0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
clutter_state_set (layout_state, NULL, "left",
|
||||||
|
actor, "rotation-angle-x", CLUTTER_LINEAR, 45.0,
|
||||||
|
actor, "rotation-angle-y", CLUTTER_LINEAR, 5.0,
|
||||||
|
actor, "x", CLUTTER_LINEAR, 0-64.0,
|
||||||
|
actor, "y", CLUTTER_LINEAR, 0-64.0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
a_state = clutter_state_new ();
|
||||||
|
g_object_set_data_full (G_OBJECT (actor), "hover-state-machine",
|
||||||
|
a_state, g_object_unref);
|
||||||
|
|
||||||
|
clutter_state_set (a_state, NULL, "normal",
|
||||||
|
actor, "opacity", CLUTTER_LINEAR, 0x77,
|
||||||
|
actor, "rotation-angle-z", CLUTTER_LINEAR, 0.0,
|
||||||
|
NULL);
|
||||||
|
clutter_state_set (a_state, NULL, "hover",
|
||||||
|
actor, "opacity", CLUTTER_LINEAR, 0xff,
|
||||||
|
actor, "rotation-angle-z", CLUTTER_LINEAR, 10.0,
|
||||||
|
NULL);
|
||||||
|
clutter_actor_set_opacity (actor, 0x77);
|
||||||
|
|
||||||
|
clutter_state_set_duration (a_state, NULL, NULL, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_state_set_duration (layout_state, NULL, NULL, 1000);
|
||||||
|
clutter_state_set_duration (layout_state, "active", "left", 1400);
|
||||||
|
|
||||||
|
g_signal_connect (layout_state, "completed", G_CALLBACK (completed), NULL);
|
||||||
|
|
||||||
|
clutter_actor_show (stage);
|
||||||
|
|
||||||
|
clutter_state_warp_to_state (layout_state, "left");
|
||||||
|
clutter_state_set_state (layout_state, "active");
|
||||||
|
|
||||||
|
clutter_perf_fps_start (CLUTTER_STAGE (stage));
|
||||||
|
clutter_main ();
|
||||||
|
clutter_perf_fps_report ("test-state");
|
||||||
|
g_object_unref (layout_state);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
164
tests/performance/test-text-perf.c
Normal file
164
tests/performance/test-text-perf.c
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
#include <clutter/clutter.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "test-common.h"
|
||||||
|
|
||||||
|
#define STAGE_WIDTH 800
|
||||||
|
#define STAGE_HEIGHT 600
|
||||||
|
|
||||||
|
static int font_size;
|
||||||
|
static int n_chars;
|
||||||
|
static int rows, cols;
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
queue_redraw (gpointer stage)
|
||||||
|
{
|
||||||
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gunichar
|
||||||
|
get_character (int ch)
|
||||||
|
{
|
||||||
|
int total_letters = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
static const struct
|
||||||
|
{
|
||||||
|
gunichar first_letter;
|
||||||
|
int n_letters;
|
||||||
|
}
|
||||||
|
ranges[] =
|
||||||
|
{
|
||||||
|
{ 'a', 26 }, /* lower case letters */
|
||||||
|
{ 'A', 26 }, /* upper case letters */
|
||||||
|
{ '0', 10 }, /* digits */
|
||||||
|
{ 0x410, 0x40 }, /* cyrillic alphabet */
|
||||||
|
{ 0x3b1, 18 } /* greek alphabet */
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (ranges); i++)
|
||||||
|
total_letters += ranges[i].n_letters;
|
||||||
|
|
||||||
|
ch %= total_letters;
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (ranges) - 1; i++)
|
||||||
|
if (ch < ranges[i].n_letters)
|
||||||
|
return ch + ranges[i].first_letter;
|
||||||
|
else
|
||||||
|
ch -= ranges[i].n_letters;
|
||||||
|
|
||||||
|
return ch + ranges[i].first_letter;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ClutterActor *
|
||||||
|
create_label (void)
|
||||||
|
{
|
||||||
|
ClutterColor label_color = { 0xff, 0xff, 0xff, 0xff };
|
||||||
|
ClutterActor *label;
|
||||||
|
char *font_name;
|
||||||
|
GString *str;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
font_name = g_strdup_printf ("Monospace %dpx", font_size);
|
||||||
|
|
||||||
|
str = g_string_new (NULL);
|
||||||
|
for (i = 0; i < n_chars; i++)
|
||||||
|
g_string_append_unichar (str, get_character (i));
|
||||||
|
|
||||||
|
label = clutter_text_new_with_text (font_name, str->str);
|
||||||
|
clutter_text_set_color (CLUTTER_TEXT (label), &label_color);
|
||||||
|
|
||||||
|
g_free (font_name);
|
||||||
|
g_string_free (str, TRUE);
|
||||||
|
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
ClutterActor *stage;
|
||||||
|
ClutterColor stage_color = { 0x00, 0x00, 0x00, 0xff };
|
||||||
|
ClutterActor *label;
|
||||||
|
int w, h;
|
||||||
|
int row, col;
|
||||||
|
float scale = 1.0f;
|
||||||
|
|
||||||
|
clutter_perf_fps_init ();
|
||||||
|
|
||||||
|
if (CLUTTER_INIT_SUCCESS != clutter_init (&argc, &argv))
|
||||||
|
g_error ("Failed to initialize Clutter");
|
||||||
|
|
||||||
|
if (argc != 3)
|
||||||
|
{
|
||||||
|
//g_printerr ("Usage test-text-perf FONT_SIZE N_CHARS\n");
|
||||||
|
//exit (1);
|
||||||
|
font_size = 30;
|
||||||
|
n_chars = 400;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
font_size = atoi (argv[1]);
|
||||||
|
n_chars = atoi (argv[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_print ("Monospace %dpx, string length = %d\n", font_size, n_chars);
|
||||||
|
|
||||||
|
stage = clutter_stage_get_default ();
|
||||||
|
clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT);
|
||||||
|
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
|
||||||
|
|
||||||
|
label = create_label ();
|
||||||
|
w = clutter_actor_get_width (label);
|
||||||
|
h = clutter_actor_get_height (label);
|
||||||
|
|
||||||
|
/* If the label is too big to fit on the stage then scale it so that
|
||||||
|
it will fit */
|
||||||
|
if (w > STAGE_WIDTH || h > STAGE_HEIGHT)
|
||||||
|
{
|
||||||
|
float x_scale = STAGE_WIDTH / (float) w;
|
||||||
|
float y_scale = STAGE_HEIGHT / (float) h;
|
||||||
|
|
||||||
|
if (x_scale < y_scale)
|
||||||
|
{
|
||||||
|
scale = x_scale;
|
||||||
|
cols = 1;
|
||||||
|
rows = STAGE_HEIGHT / (h * scale);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scale = y_scale;
|
||||||
|
cols = STAGE_WIDTH / (w * scale);
|
||||||
|
rows = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_print ("Text scaled by %f to fit on the stage\n", scale);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cols = STAGE_WIDTH / w;
|
||||||
|
rows = STAGE_HEIGHT / h;
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_actor_destroy (label);
|
||||||
|
|
||||||
|
for (row=0; row<rows; row++)
|
||||||
|
for (col=0; col<cols; col++)
|
||||||
|
{
|
||||||
|
label = create_label();
|
||||||
|
clutter_actor_set_scale (label, scale, scale);
|
||||||
|
clutter_actor_set_position (label, w * col * scale, h * row * scale);
|
||||||
|
clutter_container_add_actor (CLUTTER_CONTAINER (stage), label);
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_actor_show_all (stage);
|
||||||
|
|
||||||
|
clutter_perf_fps_start (CLUTTER_STAGE (stage));
|
||||||
|
g_idle_add (queue_redraw, stage);
|
||||||
|
clutter_main ();
|
||||||
|
clutter_perf_fps_report ("test-text-perf");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user