flutter/examples/game/test_performance.dart
Adam Barth 4467a268ce Move theme into material.dart
Also, introduce Colors and Typography to hold the material colors and the
typography declarations. Previously we expected clients of these libraries to
import them into a namespace, but that doesn't play nice with re-exporting them
from material.dart.
2015-09-18 09:57:21 -07:00

309 lines
8.5 KiB
Dart

import 'dart:sky' as sky;
import 'dart:math' as math;
import 'package:sky/material.dart';
import 'package:sky/rendering.dart';
import 'package:sky/services.dart';
import 'package:sky/widgets.dart';
import 'package:skysprites/skysprites.dart';
AssetBundle _initBundle() {
if (rootBundle != null)
return rootBundle;
return new NetworkAssetBundle(Uri.base);
}
final AssetBundle _bundle = _initBundle();
ImageMap _images;
SpriteSheet _spriteSheet;
TestApp _app;
main() async {
_images = new ImageMap(_bundle);
await _images.load([
'assets/sprites.png'
]);
String json = await _bundle.loadString('assets/sprites.json');
_spriteSheet = new SpriteSheet(_images['assets/sprites.png'], json);
_app = new TestApp();
runApp(_app);
}
class TestApp extends App {
Widget build() {
ThemeData theme = new ThemeData(
brightness: ThemeBrightness.light,
primarySwatch: Colors.purple
);
return new Theme(
data: theme,
child: new Title(
title: 'Test Sprite Performance',
child: new SpriteWidget(new TestPerformance())
)
);
}
}
class TestPerformance extends NodeWithSize {
final int numFramesPerTest = 100;
final int numTests = 5;
TestPerformance() : super(new Size(1024.0, 1024.0)) {
}
int test = 0;
int frame = 0;
int testStartTime;
void update(double dt) {
if (frame % numFramesPerTest == 0) {
if (test > 0 && test <= numTests) {
// End last test
int currentTime = new DateTime.now().millisecondsSinceEpoch;
int totalTestTime = currentTime - testStartTime;
double millisPerFrame =
totalTestTime.toDouble() / numFramesPerTest.toDouble();
print(" - RESULT fps: ${(1.0 / (millisPerFrame / 1000)).toStringAsFixed(1)} millis/frame: ${millisPerFrame.round()}");
// Clear test
removeAllChildren();
}
if (test < numTests) {
// Start new test
PerformanceTest perfTest = createTest(test);
addChild(perfTest);
print("TEST ${test + 1}/$numTests STARTING: ${perfTest.name}");
testStartTime = new DateTime.now().millisecondsSinceEpoch;
}
test++;
}
frame++;
}
PerformanceTest createTest(int n) {
if (test == 0) {
// Test atlas performance
return new TestPerformanceAtlas();
} else if (test == 1) {
// Test atlas performance
return new TestPerformanceAtlas2();
} else if (test == 2) {
// Test sprite performance
return new TestPerformanceSprites();
} else if (test == 3) {
// Test sprite performance
return new TestPerformanceSprites2();
} else if (test == 4) {
// Test particle performance
return new TestPerformanceParticles();
}
return null;
}
}
abstract class PerformanceTest extends Node {
String get name;
}
class TestPerformanceParticles extends PerformanceTest {
String get name => "64 particle systems";
final grid = 8;
TestPerformanceParticles() {
for (int x = 0; x < grid; x++) {
for (int y = 0; y < grid; y++) {
ParticleSystem particles = new ParticleSystem(
_spriteSheet["explosion_particle.png"],
rotateToMovement: true,
startRotation:90.0,
startRotationVar: 0.0,
endRotation: 90.0,
startSize: 0.3,
startSizeVar: 0.1,
endSize: 0.3,
endSizeVar: 0.1,
emissionRate:100.0,
greenVar: 127,
redVar: 127
);
particles.position = new Point(x * 1024.0 / (grid - 1), y * 1024.0 / (grid - 1));
addChild(particles);
}
}
}
}
class TestPerformanceSprites extends PerformanceTest {
String get name => "1001 sprites (24% offscreen)";
final int grid = 100;
TestPerformanceSprites() {
for (int x = 0; x < grid; x++) {
for (int y = 0; y < grid; y++) {
Sprite sprt = new Sprite(_spriteSheet["asteroid_big_1.png"]);
sprt.scale = 1.0;
sprt.position = new Point(x * 1024.0 / (grid - 1), y * 1024.0 / (grid - 1));
addChild(sprt);
//sprt.actions.run(new ActionRepeatForever(new ActionTween((a) => sprt.rotation = a, 0.0, 360.0, 1.0)));
}
}
Sprite sprt = new Sprite(_spriteSheet["asteroid_big_1.png"]);
sprt.position = new Point(512.0, 512.0);
addChild(sprt);
}
void update(double dt) {
for (Sprite sprt in children) {
sprt.rotation += 1;
}
}
}
class TestPerformanceSprites2 extends PerformanceTest {
String get name => "1001 sprites (24% offscreen never added)";
final int grid = 100;
TestPerformanceSprites2() {
for (int x = 12; x < grid - 12; x++) {
for (int y = 0; y < grid; y++) {
Sprite sprt = new Sprite(_spriteSheet["asteroid_big_1.png"]);
sprt.scale = 1.0;
sprt.position = new Point(x * 1024.0 / (grid - 1), y * 1024.0 / (grid - 1));
addChild(sprt);
//sprt.actions.run(new ActionRepeatForever(new ActionTween((a) => sprt.rotation = a, 0.0, 360.0, 1.0)));
}
}
Sprite sprt = new Sprite(_spriteSheet["asteroid_big_1.png"]);
sprt.position = new Point(512.0, 512.0);
addChild(sprt);
}
void update(double dt) {
for (Sprite sprt in children) {
sprt.rotation += 1;
}
}
}
class TestPerformanceAtlas extends PerformanceTest {
String get name => "1001 rects drawAtlas (24% offscreen)";
final int grid = 100;
double rotation = 0.0;
List<Rect> rects = [];
Paint cachedPaint = new Paint()
..filterQuality = sky.FilterQuality.low
..isAntiAlias = false;
TestPerformanceAtlas() {
for (int x = 0; x < grid; x++) {
for (int y = 0; y < grid; y++) {
rects.add(_spriteSheet["asteroid_big_1.png"].frame);
}
}
rects.add(_spriteSheet["asteroid_big_1.png"].frame);
}
void paint(PaintingCanvas canvas) {
// Setup transforms
List<sky.RSTransform> transforms = [];
for (int x = 0; x < grid; x++) {
for (int y = 0; y < grid; y++) {
double xPos = x * 1024.0 / (grid - 1);
double yPos = y * 1024.0 / (grid - 1);
transforms.add(createTransform(xPos, yPos, rects[0].size.width / 2.0, rects[0].size.height / 2.0, rotation, 1.0));
}
}
transforms.add(createTransform(512.0, 512.0, rects[0].size.width / 2.0, rects[0].size.height / 2.0, rotation, 1.0));
// Draw atlas
Rect cullRect = spriteBox.visibleArea;
canvas.drawAtlas(_spriteSheet.image, transforms, rects, null, null, cullRect, cachedPaint);
}
void update(double dt) {
rotation += 1.0;
}
sky.RSTransform createTransform(double x, double y, double ax, double ay, double rot, double scale) {
double scos = math.cos(convertDegrees2Radians(rot)) * scale;
double ssin = math.sin(convertDegrees2Radians(rot)) * scale;
double tx = x + -scos * ax + ssin * ay;
double ty = y + -ssin * ax - scos * ay;
return new sky.RSTransform(scos, ssin, tx, ty);
}
}
class TestPerformanceAtlas2 extends PerformanceTest {
String get name => "1001 rects drawAtlas (24% offscreen never added)";
final int grid = 100;
double rotation = 0.0;
List<Rect> rects = [];
Paint cachedPaint = new Paint()
..filterQuality = sky.FilterQuality.low
..isAntiAlias = false;
TestPerformanceAtlas2() {
for (int x = 12; x < grid - 12; x++) {
for (int y = 0; y < grid; y++) {
rects.add(_spriteSheet["asteroid_big_1.png"].frame);
}
}
rects.add(_spriteSheet["asteroid_big_1.png"].frame);
}
void paint(PaintingCanvas canvas) {
// Setup transforms
List<sky.RSTransform> transforms = [];
for (int x = 12; x < grid - 12; x++) {
for (int y = 0; y < grid; y++) {
double xPos = x * 1024.0 / (grid - 1);
double yPos = y * 1024.0 / (grid - 1);
transforms.add(createTransform(xPos, yPos, rects[0].size.width / 2.0, rects[0].size.height / 2.0, rotation, 1.0));
}
}
transforms.add(createTransform(512.0, 512.0, rects[0].size.width / 2.0, rects[0].size.height / 2.0, rotation, 1.0));
// Draw atlas
Rect cullRect = spriteBox.visibleArea;
canvas.drawAtlas(_spriteSheet.image, transforms, rects, null, null, cullRect, cachedPaint);
}
void update(double dt) {
rotation += 1.0;
}
sky.RSTransform createTransform(double x, double y, double ax, double ay, double rot, double scale) {
double scos = math.cos(convertDegrees2Radians(rot)) * scale;
double ssin = math.sin(convertDegrees2Radians(rot)) * scale;
double tx = x + -scos * ax + ssin * ay;
double ty = y + -ssin * ax - scos * ay;
return new sky.RSTransform(scos, ssin, tx, ty);
}
}