diff --git a/src/tests/servers/app/Jamfile b/src/tests/servers/app/Jamfile index a5d83f9c80..262fc2a46d 100644 --- a/src/tests/servers/app/Jamfile +++ b/src/tests/servers/app/Jamfile @@ -160,6 +160,7 @@ HaikuInstall install-test-apps : $(HAIKU_APP_TEST_DIR) : haiku_app_server SubInclude HAIKU_TOP src tests servers app archived_view ; SubInclude HAIKU_TOP src tests servers app async_drawing ; SubInclude HAIKU_TOP src tests servers app avoid_focus ; +SubInclude HAIKU_TOP src tests servers app benchmark ; SubInclude HAIKU_TOP src tests servers app bitmap_bounds ; SubInclude HAIKU_TOP src tests servers app bitmap_drawing ; SubInclude HAIKU_TOP src tests servers app code_to_name ; diff --git a/src/tests/servers/app/benchmark/Benchmark.cpp b/src/tests/servers/app/benchmark/Benchmark.cpp new file mode 100644 index 0000000000..d8acab3ff3 --- /dev/null +++ b/src/tests/servers/app/benchmark/Benchmark.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2008 Stephan Aßmus + * All rights reserved. Distributed under the terms of the MIT license. + */ +#include + +#include +#include + +#include "TestWindow.h" + +// tests +#include "StringTest.h" + +class Benchmark : public BApplication { +public: + Benchmark() + : BApplication("application/x-vnd.haiku-benchmark") + , fTest(new StringTest) + , fTestWindow(NULL) + { + } + + ~Benchmark() + { + delete fTest; + } + + virtual void ReadyToRun() + { + uint32 width = 500; + uint32 height = 500; + BScreen screen; + BRect frame = screen.Frame(); + frame.left = (frame.left + frame.right - width) / 2; + frame.top = (frame.top + frame.bottom - width) / 2; + frame.right = frame.left + width - 1; + frame.bottom = frame.top + height - 1; + + fTestWindow = new TestWindow(frame, fTest, B_OP_OVER, + BMessenger(this)); + } + + virtual bool QuitRequested() + { + if (fTestWindow != NULL) + fTestWindow->SetAllowedToQuit(true); + return BApplication::QuitRequested(); + } + + virtual void MessageReceived(BMessage* message) + { + switch (message->what) { + case MSG_TEST_CANCELED: + printf("Test canceled early.\n"); + // fall through + case MSG_TEST_FINISHED: + fTest->PrintResults(); + PostMessage(B_QUIT_REQUESTED); + break; + default: + BApplication::MessageReceived(message); + break; + } + } + +private: + Test* fTest; + TestWindow* fTestWindow; +}; + + +// main +int +main(int argc, char** argv) +{ + Benchmark app; + app.Run(); + return 0; +} diff --git a/src/tests/servers/app/benchmark/Jamfile b/src/tests/servers/app/benchmark/Jamfile new file mode 100644 index 0000000000..c612cc5ff5 --- /dev/null +++ b/src/tests/servers/app/benchmark/Jamfile @@ -0,0 +1,21 @@ +SubDir HAIKU_TOP src tests servers app benchmark ; + +SetSubDirSupportedPlatformsBeOSCompatible ; +AddSubDirSupportedPlatforms libbe_test ; + +UseHeaders [ FDirName os app ] ; +UseHeaders [ FDirName os interface ] ; + +Application Benchmark : + Benchmark.cpp + StringTest.cpp + Test.cpp + TestWindow.cpp + : be +; + +if ( $(TARGET_PLATFORM) = libbe_test ) { + HaikuInstall install-test-apps : $(HAIKU_APP_TEST_DIR) : Benchmark + : tests!apps ; +} + diff --git a/src/tests/servers/app/benchmark/StringTest.cpp b/src/tests/servers/app/benchmark/StringTest.cpp new file mode 100644 index 0000000000..309d3f683e --- /dev/null +++ b/src/tests/servers/app/benchmark/StringTest.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2008 Stephan Aßmus + * All rights reserved. Distributed under the terms of the MIT license. + */ +#include "StringTest.h" + +#include + +#include +#include + +#include "TestSupport.h" + + +StringTest::StringTest() + : Test() + , fTestDuration(0) + , fTestStart(-1) + , fGlyphsRendered(0) + , fGlyphsPerLine(500) + , fIterations(0) + , fMaxIterations(1500) + + , fStartHeight(11.0) + , fLineHeight(15.0) +{ +} + + +StringTest::~StringTest() +{ +} + + +void +StringTest::Prepare(BView* view) +{ + font_height fh; + view->GetFontHeight(&fh); + fLineHeight = ceilf(fh.ascent) + ceilf(fh.descent) + + ceilf(fh.leading); + fStartHeight = ceilf(fh.ascent) + ceilf(fh.descent); + fViewBounds = view->Bounds(); + + BString string; + string.Append('M', fGlyphsPerLine); + while (view->StringWidth(string.String()) < fViewBounds.Width() - 10) + string.Append('M', 1); + while (view->StringWidth(string.String()) > fViewBounds.Width() - 10) + string.Remove(string.Length() - 1, 1); + + fGlyphsPerLine = 60; //string.Length(); + fTestDuration = 0; + fGlyphsRendered = 0; + fIterations = 0; + fTestStart = system_time(); +} + +bool +StringTest::RunIteration(BView* view) +{ + BPoint textLocation; + textLocation.x = 5; + textLocation.y = random_number_between(fStartHeight, + fStartHeight + fLineHeight / 2); + + char buffer[fGlyphsPerLine + 1]; + buffer[fGlyphsPerLine] = 0; + + bigtime_t now = system_time(); + + while (true) { + // fill string with random chars + for (uint32 j = 0; j < fGlyphsPerLine; j++) + buffer[j] = 'a' + rand() % ('Z' - 'a'); + + view->DrawString(buffer, textLocation); + + fGlyphsRendered += fGlyphsPerLine; + + // offset text location + textLocation.y += fLineHeight; + if (textLocation.y > fViewBounds.bottom) + break; + } + + view->Sync(); + + fTestDuration += system_time() - now; + fIterations++; + + return fIterations < fMaxIterations; +} + + +void +StringTest::PrintResults() +{ + if (fTestDuration == 0) { + printf("Test was not run.\n"); + return; + } + bigtime_t timeLeak = system_time() - fTestStart - fTestDuration; + printf("Glyphs per DrawString() call: %ld\n", fGlyphsPerLine); + printf("Glyphs per second: %.3f\n", + fGlyphsRendered * 1000000.0 / fTestDuration); + printf("Average time between iterations: %.4f seconds.\n", + (float)timeLeak / fIterations / 1000000); +} + diff --git a/src/tests/servers/app/benchmark/StringTest.h b/src/tests/servers/app/benchmark/StringTest.h new file mode 100644 index 0000000000..062a7d5ada --- /dev/null +++ b/src/tests/servers/app/benchmark/StringTest.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2008 Stephan Aßmus + * All rights reserved. Distributed under the terms of the MIT license. + */ +#ifndef STRING_TEST_H +#define STRING_TEST_H + +#include + +#include "Test.h" + +class StringTest : public Test { +public: + StringTest(); + virtual ~StringTest(); + + virtual void Prepare(BView* view); + virtual bool RunIteration(BView* view); + virtual void PrintResults(); + +private: + bigtime_t fTestDuration; + bigtime_t fTestStart; + uint64 fGlyphsRendered; + uint32 fGlyphsPerLine; + uint32 fIterations; + uint32 fMaxIterations; + + float fStartHeight; + float fLineHeight; + BRect fViewBounds; +}; + +#endif // STRING_TEST_H diff --git a/src/tests/servers/app/benchmark/Test.cpp b/src/tests/servers/app/benchmark/Test.cpp new file mode 100644 index 0000000000..d64e405f2a --- /dev/null +++ b/src/tests/servers/app/benchmark/Test.cpp @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2008 Stephan Aßmus + * All rights reserved. Distributed under the terms of the MIT license. + */ +#include "Test.h" + + +Test::Test() +{ +} + + +Test::~Test() +{ +} diff --git a/src/tests/servers/app/benchmark/Test.h b/src/tests/servers/app/benchmark/Test.h new file mode 100644 index 0000000000..4e127f6e08 --- /dev/null +++ b/src/tests/servers/app/benchmark/Test.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2008 Stephan Aßmus + * All rights reserved. Distributed under the terms of the MIT license. + */ +#ifndef TEST_H +#define TEST_H + +class BView; + +class Test { +public: + Test(); + virtual ~Test(); + + virtual void Prepare(BView* view) = 0; + virtual bool RunIteration(BView* view) = 0; + virtual void PrintResults() = 0; +}; + +#endif // TEST_H diff --git a/src/tests/servers/app/benchmark/TestSupport.h b/src/tests/servers/app/benchmark/TestSupport.h new file mode 100644 index 0000000000..c66e0bc278 --- /dev/null +++ b/src/tests/servers/app/benchmark/TestSupport.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2008 Stephan Aßmus + * All rights reserved. Distributed under the terms of the MIT license. + */ +#ifndef TEST_SUPPORT_H +#define TEST_SUPPORT_H + +#include +#include + +// random_number_between +inline float +random_number_between(float v1, float v2) +{ + if (v1 < v2) + return v1 + fmod(rand() / 1000.0, (v2 - v1)); + else if (v2 < v1) + return v2 + fmod(rand() / 1000.0, (v1 - v2)); + return v1; +} + +#endif // TEST_SUPPORT_H diff --git a/src/tests/servers/app/benchmark/TestWindow.cpp b/src/tests/servers/app/benchmark/TestWindow.cpp new file mode 100644 index 0000000000..d9836739cf --- /dev/null +++ b/src/tests/servers/app/benchmark/TestWindow.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2008 Stephan Aßmus + * All rights reserved. Distributed under the terms of the MIT license. + */ +#include "TestWindow.h" + +#include "Test.h" + + +TestView::TestView(BRect frame, Test* test, drawing_mode mode, + const BMessenger& target) + : BView(frame, "test view", B_FOLLOW_ALL, B_WILL_DRAW) + , fTest(test) + , fTarget(target) +{ + SetDrawingMode(mode); + fTest->Prepare(this); +} + + +void +TestView::Draw(BRect updateRect) +{ + if (fTest->RunIteration(this)) { + Invalidate(); + return; + } + + fTarget.SendMessage(MSG_TEST_FINISHED); +} + + +TestWindow::TestWindow(BRect frame, Test* test, drawing_mode mode, + const BMessenger& target) + : BWindow(frame, "Test Window", B_TITLED_WINDOW_LOOK, + B_FLOATING_ALL_WINDOW_FEEL, B_NOT_ZOOMABLE | B_NOT_RESIZABLE) + , fTarget(target) + , fAllowedToQuit(false) +{ + TestView* view = new TestView(Bounds(), test, mode, target); + AddChild(view); + Show(); +} + + +bool +TestWindow::QuitRequested() +{ + if (fAllowedToQuit) + return true; + + fTarget.SendMessage(MSG_TEST_CANCELED); + return false; +} + + +void +TestWindow::SetAllowedToQuit(bool allowed) +{ + fAllowedToQuit = allowed; +} + diff --git a/src/tests/servers/app/benchmark/TestWindow.h b/src/tests/servers/app/benchmark/TestWindow.h new file mode 100644 index 0000000000..c4f76ef86e --- /dev/null +++ b/src/tests/servers/app/benchmark/TestWindow.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2008 Stephan Aßmus + * All rights reserved. Distributed under the terms of the MIT license. + */ +#ifndef TEST_WINDOW_H +#define TEST_WINDOW_H + +#include +#include +#include + + +enum { + MSG_TEST_FINISHED = 'tstf', + MSG_TEST_CANCELED = 'tstc' +}; + + +class Test; + +// TestView +class TestView : public BView { +public: + TestView(BRect frame, Test* test, + drawing_mode mode, + const BMessenger& target); + + virtual void Draw(BRect updateRect); + +private: + Test* fTest; + BMessenger fTarget; +}; + +// TestWindow +class TestWindow : public BWindow { +public: + TestWindow(BRect fame, Test* test, + drawing_mode mode, + const BMessenger& target); + + virtual bool QuitRequested(); + + void SetAllowedToQuit(bool allowed); +private: + BMessenger fTarget; + bool fAllowedToQuit; +}; + +#endif // TEST_WINDOW_H diff --git a/src/tests/servers/app/benchmark/run b/src/tests/servers/app/benchmark/run new file mode 100644 index 0000000000..151e4c50ae --- /dev/null +++ b/src/tests/servers/app/benchmark/run @@ -0,0 +1,17 @@ +#!/bin/sh + +../../../../../generated/tests/libbe_test/x86/apps/run_haiku_registrar || exit + +if test -f ../../../../../generated/tests/libbe_test/x86/apps/haiku_app_server; then + ../../../../../generated/tests/libbe_test/x86/apps/haiku_app_server & +else + echo "You need to \"TARGET_PLATFORM=libbe_test jam install-test-apps\" first." +fi + +sleep 1s + +if test -f ../../../../../generated/tests/libbe_test/x86/apps/Benchmark; then + ../../../../../generated/tests/libbe_test/x86/apps/Benchmark +else + echo "You need to \"TARGET_PLATFORM=libbe_test jam install-test-apps\" first." +fi