From 96e089be76b0a9dc70721e0f9592e13eb07ee5a8 Mon Sep 17 00:00:00 2001 From: Ricardo Quesada Date: Wed, 26 Nov 2014 16:55:39 -0800 Subject: [PATCH] Sprite Performance Test automation works OK --- cocos/base/CCConsole.cpp | 2 +- cocos/base/CCDirector.cpp | 3 +- .../PerformanceTest/PerformanceSpriteTest.cpp | 313 ++++++++---------- .../PerformanceTest/PerformanceSpriteTest.h | 71 ++-- 4 files changed, 179 insertions(+), 210 deletions(-) diff --git a/cocos/base/CCConsole.cpp b/cocos/base/CCConsole.cpp index 782446ad8f..673cefc62b 100644 --- a/cocos/base/CCConsole.cpp +++ b/cocos/base/CCConsole.cpp @@ -224,7 +224,7 @@ static void _log(const char *format, va_list args) fflush(stdout); #else // Linux, Mac, iOS, etc - fprintf(stdout, "cocos2d: %s", buf); + fprintf(stdout, "%s", buf); fflush(stdout); #endif diff --git a/cocos/base/CCDirector.cpp b/cocos/base/CCDirector.cpp index 6672681e22..b4f31e5146 100644 --- a/cocos/base/CCDirector.cpp +++ b/cocos/base/CCDirector.cpp @@ -1086,13 +1086,14 @@ void Director::showStats() float dt = _deltaTime * FPS_FILTER + (1-FPS_FILTER) * prevDeltaTime; prevDeltaTime = dt; + _frameRate = 1/dt; // Probably we don't need this anymore since // the framerate is using a low-pass filter // to make the FPS stable if (_accumDt > CC_DIRECTOR_STATS_INTERVAL) { - sprintf(buffer, "%.1f / %.3f", 1/dt, _secondsPerFrame); + sprintf(buffer, "%.1f / %.3f", _frameRate, _secondsPerFrame); _FPSLabel->setString(buffer); _accumDt = 0; } diff --git a/tests/cpp-tests/Classes/PerformanceTest/PerformanceSpriteTest.cpp b/tests/cpp-tests/Classes/PerformanceTest/PerformanceSpriteTest.cpp index 71a67e35ed..67e15332ae 100644 --- a/tests/cpp-tests/Classes/PerformanceTest/PerformanceSpriteTest.cpp +++ b/tests/cpp-tests/Classes/PerformanceTest/PerformanceSpriteTest.cpp @@ -55,7 +55,7 @@ void SubTest::initWithSubTest(int subtest, Node* p) { srand(0); - subtestNumber = subtest; + _subtestNumber = subtest; _parentNode = nullptr; /* * Tests: @@ -73,6 +73,8 @@ void SubTest::initWithSubTest(int subtest, Node* p) *10: 64 (32-bit) sprites of 32 x 32 each that belong to on texture atlas *11: 64 (32-bit) PNG Batch Node of 32 x 32 each *12: 64 (16-bit) PNG Batch Node of 32 x 32 each + * + *13: (16-bit) PNG sprites. 33% from test4, 33% from test8, 33% from test12 */ // purge textures @@ -81,7 +83,7 @@ void SubTest::initWithSubTest(int subtest, Node* p) mgr->removeTextureForKey("Images/grossini_dance_atlas.png"); mgr->removeTextureForKey("Images/spritesheet1.png"); - switch ( subtestNumber) + switch ( _subtestNumber) { /// case 1: @@ -147,7 +149,7 @@ Sprite* SubTest::createSpriteWithTag(int tag) TextureCache *cache = Director::getInstance()->getTextureCache(); Sprite* sprite = nullptr; - switch (subtestNumber) + switch (_subtestNumber) { /// case 1: @@ -327,25 +329,25 @@ void SpriteMenuLayer::showCurrentTest() switch (_curCase) { case 0: - scene = new (std::nothrow) SpritePerformTest1; + scene = new (std::nothrow) SpritePerformTestA; break; case 1: - scene = new (std::nothrow) SpritePerformTest2; + scene = new (std::nothrow) SpritePerformTestB; break; case 2: - scene = new (std::nothrow) SpritePerformTest3; + scene = new (std::nothrow) SpritePerformTestC; break; case 3: - scene = new (std::nothrow) SpritePerformTest4; + scene = new (std::nothrow) SpritePerformTestD; break; case 4: - scene = new (std::nothrow) SpritePerformTest5; + scene = new (std::nothrow) SpritePerformTestE; break; case 5: - scene = new (std::nothrow) SpritePerformTest6; + scene = new (std::nothrow) SpritePerformTestF; break; case 6: - scene = new (std::nothrow) SpritePerformTest7; + scene = new (std::nothrow) SpritePerformTestG; break; } @@ -364,21 +366,25 @@ void SpriteMenuLayer::showCurrentTest() // //////////////////////////////////////////////////////// +// 500 sprites, 1500 sprites, etc... bool SpriteMainScene::_s_autoTest = false; -int SpriteMainScene::_s_nSpriteCurCase = 0; +int SpriteMainScene::_s_nSpriteCurCase = 0; +int SpriteMainScene::_s_spritesQuatityIndex = 0; +int SpriteMainScene::_s_spritesQuanityArray[] = {500, 1000, 3000, 0}; +std::vector SpriteMainScene::_s_saved_fps = {}; void SpriteMainScene::initWithSubTest(int asubtest, int nNodes) { //srandom(0); - subtestNumber = asubtest; + _subtestNumber = asubtest; _subTest = new (std::nothrow) SubTest; _subTest->initWithSubTest(asubtest, this); auto s = Director::getInstance()->getWinSize(); - lastRenderedCount = 0; - quantityNodes = 0; + _lastRenderedCount = 0; + _quantityNodes = 0; MenuItemFont::setFontSize(65); auto decrease = MenuItemFont::create(" - ", CC_CALLBACK_1(SpriteMainScene::onDecrease, this)); @@ -464,7 +470,7 @@ void SpriteMainScene::initWithSubTest(int asubtest, int nNodes) l->setPosition( Vec2(VisibleRect::center().x, VisibleRect::top().y - 60) ); } - while(quantityNodes < nNodes) + while(_quantityNodes < nNodes) onIncrease(this); } @@ -496,34 +502,34 @@ void SpriteMainScene::testNCallback(Ref* sender) return; } - subtestNumber = static_cast(sender)->getTag(); + _subtestNumber = static_cast(sender)->getTag(); auto menu = static_cast( getChildByTag(kTagMenuLayer) ); menu->restartCallback(sender); } void SpriteMainScene::updateNodes() { - if( quantityNodes != lastRenderedCount ) + if( _quantityNodes != _lastRenderedCount ) { auto infoLabel = (Label *) getChildByTag(kTagInfoLayer); char str[16] = {0}; - sprintf(str, "%u nodes", quantityNodes); + sprintf(str, "%u nodes", _quantityNodes); infoLabel->setString(str); - lastRenderedCount = quantityNodes; + _lastRenderedCount = _quantityNodes; } } void SpriteMainScene::onIncrease(Ref* sender) { - if( quantityNodes >= kMaxNodes) + if( _quantityNodes >= kMaxNodes) return; for( int i=0;i< kNodesIncrease;i++) { - auto sprite = _subTest->createSpriteWithTag(quantityNodes); + auto sprite = _subTest->createSpriteWithTag(_quantityNodes); doTest(sprite); - quantityNodes++; + _quantityNodes++; } updateNodes(); @@ -532,13 +538,13 @@ void SpriteMainScene::onIncrease(Ref* sender) void SpriteMainScene::onDecrease(Ref* sender) { - if( quantityNodes <= 0 ) + if( _quantityNodes <= 0 ) return; for( int i=0;i < kNodesIncrease;i++) { - quantityNodes--; - _subTest->removeByTag(quantityNodes); + _quantityNodes--; + _subTest->removeByTag(_quantityNodes); } updateNodes(); @@ -546,42 +552,39 @@ void SpriteMainScene::onDecrease(Ref* sender) void SpriteMainScene::dumpProfilerFPS() { - if (_vecFPS.empty()) - { - log("Error: the FPS vector is empty"); - return; - } - - auto iter = _vecFPS.begin(); - float minFPS = *iter; - float maxFPS = *iter; - float totalFPS = 0.0f; - float averagerFPS = 0.0f; - for (auto fps : _vecFPS) - { - CCLOG("fps is :%f\n",fps); - minFPS = std::min(minFPS, fps); - maxFPS = std::max(maxFPS, fps); - totalFPS += fps; - } - - averagerFPS = totalFPS / _vecFPS.size(); - log("Cur test: %d, cur sub item :%d,cur sprite nums:%d, the min FPS value is %.1f,the max FPS value is %.1f,the averager FPS is %.1f", SpriteMainScene::_s_nSpriteCurCase, subtestNumber, quantityNodes, minFPS, maxFPS, averagerFPS); - + log("COPY & PASTE into Cocos2d-x Performance Test spreadsheet"); + log("https://docs.google.com/spreadsheets/d/1XolpgYfoWszA2rxnVRCAVS7ILAGiV049o5mpL29cwLs/edit#gid=1561044615"); + log(""); + int index = 0; + int sprites = 0; + while((sprites = _s_spritesQuanityArray[index++])) { + log("Number of sprites: %d", sprites); + for(int i=0; i < MAX_SPRITE_TEST_CASE; i++) + { + char buffer[512]; + for(int j=0; j < MAX_SUB_TEST_NUMS; j++) + { + float fps = _s_saved_fps[j + i*MAX_SUB_TEST_NUMS]; + char fps_str[64]; + sprintf(fps_str, "\t%.1f", fps); + strcat(buffer, fps_str); + } + log("%c%s", i + 'A', buffer); + buffer[0] = 0; + } + }; +} + +void SpriteMainScene::saveFPS() +{ + float fps = Director::getInstance()->getFrameRate(); + _s_saved_fps.push_back(fps); } void SpriteMainScene::updateAutoTest(float dt) { - if (SpriteMainScene::_s_autoTest) - { - _executeTimes += 1; - _vecFPS.push_back(Director::getInstance()->getFrameRate()); - if ( _executeTimes >= SpriteMainScene::MAX_AUTO_TEST_TIMES ) - { - dumpProfilerFPS(); - nextAutoTest(); - } - } + saveFPS(); + nextAutoTest(); } void SpriteMainScene::onEnter() @@ -590,14 +593,11 @@ void SpriteMainScene::onEnter() if ( SpriteMainScene::_s_autoTest ) { - _vecFPS.clear(); - _executeTimes = 0; - auto director = Director::getInstance(); auto sched = director->getScheduler(); - - sched->schedule(CC_SCHEDULE_SELECTOR(SpriteMainScene::updateAutoTest), this, 0.2f, false); - + + // schedule it only once. Call me after 3 seconds + sched->schedule(CC_SCHEDULE_SELECTOR(SpriteMainScene::updateAutoTest), this, SECONDS_PER_TESTS, 0, 0, false); } } @@ -607,14 +607,13 @@ void SpriteMainScene::onExit() { auto director = Director::getInstance(); auto sched = director->getScheduler(); - sched->unschedule(CC_SCHEDULE_SELECTOR(SpriteMainScene::updateAutoTest), this ); } Scene::onExit(); } -void SpriteMainScene::autoShowSpriteTests(int curCase, int subTest,int nodes) +void SpriteMainScene::autoShowSpriteTests(int curCase, int subTest, int nodes) { SpriteMainScene* scene = nullptr; @@ -622,30 +621,31 @@ void SpriteMainScene::autoShowSpriteTests(int curCase, int subTest,int nodes) switch (curCase) { case 0: - scene = new (std::nothrow) SpritePerformTest1; + scene = new (std::nothrow) SpritePerformTestA; break; case 1: - scene = new (std::nothrow) SpritePerformTest2; + scene = new (std::nothrow) SpritePerformTestB; break; case 2: - scene = new (std::nothrow) SpritePerformTest3; + scene = new (std::nothrow) SpritePerformTestC; break; case 3: - scene = new (std::nothrow) SpritePerformTest4; + scene = new (std::nothrow) SpritePerformTestD; break; case 4: - scene = new (std::nothrow) SpritePerformTest5; + scene = new (std::nothrow) SpritePerformTestE; break; case 5: - scene = new (std::nothrow) SpritePerformTest6; + scene = new (std::nothrow) SpritePerformTestF; break; case 6: - scene = new (std::nothrow) SpritePerformTest7; + scene = new (std::nothrow) SpritePerformTestG; + break; + default: + CCASSERT(false, "Invalid scene value"); break; } - - SpriteMainScene::_s_nSpriteCurCase = curCase; - + if (scene) { scene->initWithSubTest(subTest, nodes); @@ -656,15 +656,14 @@ void SpriteMainScene::autoShowSpriteTests(int curCase, int subTest,int nodes) void SpriteMainScene::beginAutoTest() { - if (0 != SpriteMainScene::_s_nSpriteCurCase) - { - SpriteMainScene::_s_nSpriteCurCase = 0; - } - - auto scene = new (std::nothrow) SpritePerformTest1; - scene->initWithSubTest(1, 500); - Director::getInstance()->replaceScene(scene); - scene->release(); + _s_spritesQuatityIndex = 0; + _s_nSpriteCurCase = 0; + _s_saved_fps.clear(); + + _subtestNumber = 0; + _quantityNodes = _s_spritesQuanityArray[_s_spritesQuatityIndex]; + + nextAutoTest(); } void SpriteMainScene::endAutoTest() @@ -679,25 +678,32 @@ void SpriteMainScene::endAutoTest() void SpriteMainScene::nextAutoTest() { - if ( SpriteMainScene::_s_nSpriteCurCase < SpriteMainScene::MAX_SPRITE_TEST_CASE ) + if (SpriteMainScene::_s_nSpriteCurCase < SpriteMainScene::MAX_SPRITE_TEST_CASE) { - if ( subtestNumber < SpriteMainScene::MAX_SUB_TEST_NUMS ) + if (_subtestNumber < SpriteMainScene::MAX_SUB_TEST_NUMS) { - subtestNumber += 1; - autoShowSpriteTests(SpriteMainScene::_s_nSpriteCurCase, subtestNumber, quantityNodes); + // Increase Sub Main Test (1, 2, 3, 4, ...) + _subtestNumber += 1; + autoShowSpriteTests(_s_nSpriteCurCase, _subtestNumber, _quantityNodes); } - else if ( subtestNumber == SpriteMainScene::MAX_SUB_TEST_NUMS ) + else if (_subtestNumber == SpriteMainScene::MAX_SUB_TEST_NUMS) { - if (quantityNodes == SpriteMainScene::AUTO_TEST_NODE_NUM1) + if (SpriteMainScene::_s_nSpriteCurCase + 1 < SpriteMainScene::MAX_SPRITE_TEST_CASE) { - autoShowSpriteTests(SpriteMainScene::_s_nSpriteCurCase, 1, SpriteMainScene::AUTO_TEST_NODE_NUM2); + // Increase Main Test (A, B, C, ...) + _subtestNumber = 1; + _s_nSpriteCurCase++; + autoShowSpriteTests(_s_nSpriteCurCase, _subtestNumber, _quantityNodes); } else { - if (SpriteMainScene::_s_nSpriteCurCase + 1 < SpriteMainScene::MAX_SPRITE_TEST_CASE) - { - SpriteMainScene::_s_nSpriteCurCase += 1; - autoShowSpriteTests(SpriteMainScene::_s_nSpriteCurCase, 1, SpriteMainScene::AUTO_TEST_NODE_NUM1); + // Increase quanity of sprites, or finish + int sprites = _s_spritesQuanityArray[++_s_spritesQuatityIndex]; + if (sprites != 0) { + _quantityNodes = sprites; + _subtestNumber = 1; + _s_nSpriteCurCase = 0; + autoShowSpriteTests(_s_nSpriteCurCase, _subtestNumber, _quantityNodes); } else { @@ -725,25 +731,25 @@ void SpriteMainScene::finishAutoTest() } } - log("Sprite performance test is finish "); + log("Sprite performance test is finished"); + + dumpProfilerFPS(); } void SpriteMainScene::onAutoTest(Ref* sender) { SpriteMainScene::_s_autoTest = !SpriteMainScene::_s_autoTest; MenuItemFont* menuItem = dynamic_cast(sender); - if (nullptr != menuItem) + + if (SpriteMainScene::_s_autoTest) { - if (SpriteMainScene::_s_autoTest) - { - menuItem->setString("Auto Test On"); - beginAutoTest(); - } - else - { - menuItem->setString("Auto Test Off"); - endAutoTest(); - } + menuItem->setString("Auto Test On"); + beginAutoTest(); + } + else + { + menuItem->setString("Auto Test Off"); + endAutoTest(); } } @@ -827,161 +833,126 @@ void performanceScale(Sprite* sprite) //////////////////////////////////////////////////////// // -// SpritePerformTest1 +// SpritePerformTestA // //////////////////////////////////////////////////////// -std::string SpritePerformTest1::title() const +std::string SpritePerformTestA::title() const { char str[32] = {0}; - sprintf(str, "A (%d) position", subtestNumber); + sprintf(str, "A (%d) position", _subtestNumber); std::string strRet = str; return strRet; } -std::string SpritePerformTest1::subtitle() const -{ - return "test 1"; -} - -void SpritePerformTest1::doTest(Sprite* sprite) +void SpritePerformTestA::doTest(Sprite* sprite) { performancePosition(sprite); } //////////////////////////////////////////////////////// // -// SpritePerformTest2 +// SpritePerformTestB // //////////////////////////////////////////////////////// -std::string SpritePerformTest2::title() const +std::string SpritePerformTestB::title() const { char str[32] = {0}; - sprintf(str, "B (%d) scale", subtestNumber); + sprintf(str, "B (%d) scale", _subtestNumber); std::string strRet = str; return strRet; } -std::string SpritePerformTest2::subtitle() const -{ - return "test 2"; -} - -void SpritePerformTest2::doTest(Sprite* sprite) +void SpritePerformTestB::doTest(Sprite* sprite) { performanceScale(sprite); } //////////////////////////////////////////////////////// // -// SpritePerformTest3 +// SpritePerformTestC // //////////////////////////////////////////////////////// -std::string SpritePerformTest3::title() const +std::string SpritePerformTestC::title() const { char str[32] = {0}; - sprintf(str, "C (%d) scale + rot", subtestNumber); + sprintf(str, "C (%d) scale + rot", _subtestNumber); std::string strRet = str; return strRet; } -std::string SpritePerformTest3::subtitle() const -{ - return "test 3"; -} - -void SpritePerformTest3::doTest(Sprite* sprite) +void SpritePerformTestC::doTest(Sprite* sprite) { performanceRotationScale(sprite); } //////////////////////////////////////////////////////// // -// SpritePerformTest4 +// SpritePerformTestD // //////////////////////////////////////////////////////// -std::string SpritePerformTest4::title() const +std::string SpritePerformTestD::title() const { char str[32] = {0}; - sprintf(str, "D (%d) 100%% out", subtestNumber); + sprintf(str, "D (%d) 100%% out", _subtestNumber); std::string strRet = str; return strRet; } -std::string SpritePerformTest4::subtitle() const -{ - return "test 4"; -} - -void SpritePerformTest4::doTest(Sprite* sprite) +void SpritePerformTestD::doTest(Sprite* sprite) { performanceOut100(sprite); } //////////////////////////////////////////////////////// // -// SpritePerformTest5 +// SpritePerformTestE // //////////////////////////////////////////////////////// -std::string SpritePerformTest5::title() const +std::string SpritePerformTestE::title() const { char str[32] = {0}; - sprintf(str, "E (%d) 80%% out", subtestNumber); + sprintf(str, "E (%d) 80%% out", _subtestNumber); std::string strRet = str; return strRet; } -std::string SpritePerformTest5::subtitle() const -{ - return "test 5"; -} - -void SpritePerformTest5::doTest(Sprite* sprite) +void SpritePerformTestE::doTest(Sprite* sprite) { performanceout20(sprite); } //////////////////////////////////////////////////////// // -// SpritePerformTest6 +// SpritePerformTestF // //////////////////////////////////////////////////////// -std::string SpritePerformTest6::title() const +std::string SpritePerformTestF::title() const { char str[32] = {0}; - sprintf(str, "F (%d) actions", subtestNumber); + sprintf(str, "F (%d) actions", _subtestNumber); std::string strRet = str; return strRet; } -std::string SpritePerformTest6::subtitle() const -{ - return "test 6"; -} - -void SpritePerformTest6::doTest(Sprite* sprite) +void SpritePerformTestF::doTest(Sprite* sprite) { performanceActions(sprite); } //////////////////////////////////////////////////////// // -// SpritePerformTest7 +// SpritePerformTestG // //////////////////////////////////////////////////////// -std::string SpritePerformTest7::title() const +std::string SpritePerformTestG::title() const { char str[32] = {0}; - sprintf(str, "G (%d) actions 80%% out", subtestNumber); + sprintf(str, "G (%d) actions 80%% out", _subtestNumber); std::string strRet = str; return strRet; } -std::string SpritePerformTest7::subtitle() const -{ - return "test 7"; -} - -void SpritePerformTest7::doTest(Sprite* sprite) +void SpritePerformTestG::doTest(Sprite* sprite) { performanceActions20(sprite); } @@ -989,7 +960,7 @@ void SpritePerformTest7::doTest(Sprite* sprite) void runSpriteTest() { SpriteMainScene::_s_autoTest = false; - auto scene = new (std::nothrow) SpritePerformTest1; + auto scene = new (std::nothrow) SpritePerformTestA; scene->initWithSubTest(1, 50); Director::getInstance()->replaceScene(scene); scene->release(); diff --git a/tests/cpp-tests/Classes/PerformanceTest/PerformanceSpriteTest.h b/tests/cpp-tests/Classes/PerformanceTest/PerformanceSpriteTest.h index 1ac62dc8f5..75fcb9c95c 100644 --- a/tests/cpp-tests/Classes/PerformanceTest/PerformanceSpriteTest.h +++ b/tests/cpp-tests/Classes/PerformanceTest/PerformanceSpriteTest.h @@ -28,8 +28,11 @@ #ifndef __PERFORMANCE_SPRITE_TEST_H__ #define __PERFORMANCE_SPRITE_TEST_H__ +#include + #include "PerformanceTest.h" + class SubTest { public: @@ -39,7 +42,7 @@ public: void initWithSubTest(int nSubTest, Node* parent); protected: - int subtestNumber; + int _subtestNumber; Node *_parentNode; }; @@ -73,93 +76,87 @@ public: virtual void doTest(Sprite* sprite) = 0; - int getSubTestNum() { return subtestNumber; } - int getNodesNum() { return quantityNodes; } + int getSubTestNum() { return _subtestNumber; } + int getNodesNum() { return _quantityNodes; } virtual void onEnter() override; virtual void onExit() override; - void updateAutoTest(float dt); - void onAutoTest(Ref* sender); + void updateAutoTest(float dt); + void onAutoTest(Ref* sender); + // auto tests static bool _s_autoTest; - static int _s_nSpriteCurCase; + static int _s_nSpriteCurCase; + static int _s_spritesQuatityIndex; + static int _s_spritesQuanityArray[]; + static std::vector _s_saved_fps; protected: - void dumpProfilerFPS(); - void beginAutoTest(); - void endAutoTest(); - void nextAutoTest(); - void finishAutoTest(); - void autoShowSpriteTests(int curCase, int subTest,int nodes); + void dumpProfilerFPS(); + void saveFPS(); + void beginAutoTest(); + void endAutoTest(); + void nextAutoTest(); + void finishAutoTest(); + void autoShowSpriteTests(int curCase, int subTest,int nodes); - int lastRenderedCount; - int quantityNodes; - SubTest *_subTest; - int subtestNumber; - std::vector _vecFPS; - int _executeTimes; + int _lastRenderedCount; + int _quantityNodes; + SubTest* _subTest; + int _subtestNumber; - static const int MAX_AUTO_TEST_TIMES = 25; - static const int MAX_SPRITE_TEST_CASE = 7; - static const int MAX_SUB_TEST_NUMS = 13; - static const int AUTO_TEST_NODE_NUM1 = 500; - static const int AUTO_TEST_NODE_NUM2 = 1500; + constexpr static const float SECONDS_PER_TESTS = 3.0f; + static const int MAX_SPRITE_TEST_CASE = 7; + static const int MAX_SUB_TEST_NUMS = 13; }; -class SpritePerformTest1 : public SpriteMainScene +class SpritePerformTestA : public SpriteMainScene { public: virtual void doTest(Sprite* sprite) override; virtual std::string title() const override; - virtual std::string subtitle() const override; }; -class SpritePerformTest2 : public SpriteMainScene +class SpritePerformTestB : public SpriteMainScene { public: virtual void doTest(Sprite* sprite) override; virtual std::string title() const override; - virtual std::string subtitle() const override; }; -class SpritePerformTest3 : public SpriteMainScene +class SpritePerformTestC : public SpriteMainScene { public: virtual void doTest(Sprite* sprite) override; virtual std::string title() const override; - virtual std::string subtitle() const override; }; -class SpritePerformTest4 : public SpriteMainScene +class SpritePerformTestD : public SpriteMainScene { public: virtual void doTest(Sprite* sprite) override; virtual std::string title() const override; - virtual std::string subtitle() const override; }; -class SpritePerformTest5 : public SpriteMainScene +class SpritePerformTestE : public SpriteMainScene { public: virtual void doTest(Sprite* sprite) override; virtual std::string title() const override; - virtual std::string subtitle() const override; }; -class SpritePerformTest6 : public SpriteMainScene +class SpritePerformTestF : public SpriteMainScene { public: virtual void doTest(Sprite* sprite) override; virtual std::string title() const override; - virtual std::string subtitle() const override; }; -class SpritePerformTest7 : public SpriteMainScene +class SpritePerformTestG : public SpriteMainScene { public: virtual void doTest(Sprite* sprite) override; virtual std::string title() const override; - virtual std::string subtitle() const override; }; void runSpriteTest();