24
24
****************************************************************************/
25
25
26
26
#include " NewRendererTest.h"
27
-
27
+ #include < chrono>
28
+ #include < sstream>
28
29
USING_NS_CC;
29
30
31
+ class DurationRecorder {
32
+ public:
33
+ void startTick (const std::string &key) {
34
+ _durations[key] = - now ();
35
+ }
36
+
37
+ int endTick (const std::string &key) {
38
+ auto n = now ();
39
+ auto itr = _durations.find (key);
40
+ if (_durations.find (key) == _durations.end ())
41
+ {
42
+ return -1 ;
43
+ }
44
+ else if (itr->second < 0 ) {
45
+ itr->second = n + itr->second ;
46
+ }
47
+ return itr->second ;
48
+ }
49
+
50
+ inline int64_t now () const {
51
+ return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now ().time_since_epoch ()).count ();
52
+ }
53
+
54
+ void reset () {
55
+ _durations.clear ();
56
+ }
57
+
58
+ private:
59
+ std::map<std::string, int64_t > _durations;
60
+ };
61
+
62
+
63
+
30
64
NewRendererTests::NewRendererTests ()
31
65
{
66
+
32
67
ADD_TEST_CASE (NewSpriteTest);
33
68
ADD_TEST_CASE (GroupCommandTest);
34
69
// ADD_TEST_CASE(NewClippingNodeTest); // When depth and stencil are used together, ...
@@ -41,6 +76,7 @@ NewRendererTests::NewRendererTests()
41
76
ADD_TEST_CASE (RendererBatchQuadTri);
42
77
ADD_TEST_CASE (RendererUniformBatch);
43
78
ADD_TEST_CASE (RendererUniformBatch2);
79
+ ADD_TEST_CASE (SpriteCreation);
44
80
ADD_TEST_CASE (NonBatchSprites);
45
81
};
46
82
@@ -382,6 +418,167 @@ std::string NewCullingTest::subtitle() const
382
418
return " Drag the layer to test the result of culling" ;
383
419
}
384
420
421
+ SpriteCreation::SpriteCreation ()
422
+ {
423
+
424
+ Size s = Director::getInstance ()->getWinSize ();
425
+ Node* parent = Node::create ();
426
+ parent->setPosition (s.width / 2 ,s.height / 2 );
427
+ addChild (parent);
428
+
429
+
430
+ #define KEY_CREATION " 11"
431
+ #define KEY_DESTROYATION " 22"
432
+
433
+ labelCreate = Label::createWithTTF (TTFConfig (" fonts/arial.ttf" ), " Sprite Creation: .." );
434
+ labelDestory= Label::createWithTTF (TTFConfig (" fonts/arial.ttf" ), " Destroy Sprites: .." );
435
+
436
+ MenuItemFont::setFontName (" fonts/arial.ttf" );
437
+ MenuItemFont::setFontSize (65 );
438
+ auto decrease = MenuItemFont::create (" - " , CC_CALLBACK_1 (SpriteCreation::delSpritesCallback, this ));
439
+ decrease->setColor (Color3B (0 , 200 , 20 ));
440
+ auto increase = MenuItemFont::create (" + " , CC_CALLBACK_1 (SpriteCreation::addSpritesCallback, this ));
441
+ increase->setColor (Color3B (0 , 200 , 20 ));
442
+
443
+ auto menu = Menu::create (decrease, increase, nullptr );
444
+ menu->alignItemsHorizontally ();
445
+ menu->setPosition (Vec2 (s.width / 2 , s.height - 105 ));
446
+ addChild (menu, 1 );
447
+
448
+ TTFConfig ttfCount (" fonts/Marker Felt.ttf" , 30 );
449
+ _labelSpriteNum = Label::createWithTTF (ttfCount, " Label" );
450
+ _labelSpriteNum->setColor (Color3B (0 , 200 , 20 ));
451
+ _labelSpriteNum->setPosition (Vec2 (s.width / 2 , s.height - 130 ));
452
+ addChild (_labelSpriteNum);
453
+
454
+ updateSpriteCountLabel (totalSprites);
455
+
456
+ labelCreate->setPosition (0 , -20 );
457
+ labelDestory->setPosition (0 , -50 );
458
+
459
+ parent->addChild (labelCreate);
460
+ parent->addChild (labelDestory);
461
+
462
+ doTest ();
463
+ }
464
+
465
+ void SpriteCreation::updateSpriteCountLabel (int x)
466
+ {
467
+ totalSprites = std::max (1 , x);
468
+ std::stringstream ss;
469
+ ss << totalSprites << " sprites" ;
470
+ _labelSpriteNum->setString (ss.str ());
471
+ }
472
+
473
+ void SpriteCreation::doTest ()
474
+ {
475
+
476
+ DurationRecorder perf;
477
+ std::vector<std::string> predefineTextures = {
478
+ " Images/concave.png" ,
479
+ " Images/atlastest.png" ,
480
+ " Images/grossini_dance_atlas-mono.png" ,
481
+ " Images/HelloWorld.png" ,
482
+ " Images/background1.png" ,
483
+ " Images/background2.png" ,
484
+ " Images/stone.png" ,
485
+ " Images/issue_17116.png" ,
486
+ " Images/sprite_polygon_crash.png" ,
487
+ " Images/bitmapFontTest3.png" ,
488
+ " Images/cocos-html5.png" ,
489
+ " Images/Fog.png" ,
490
+ " Images/poly_test_textures.png" ,
491
+ " Images/powered.png" ,
492
+ " Images/bug14017.png" ,
493
+ " Images/test-rgba1.png" ,
494
+ " Images/grossinis_heads.png" ,
495
+ " Images/cocos2dbanner.png"
496
+ };
497
+
498
+
499
+ std::vector<Sprite*> spriteCache;
500
+ spriteCache.reserve (totalSprites);
501
+
502
+ perf.startTick (KEY_CREATION);
503
+
504
+ for (int i=0 ; i< totalSprites; ++i)
505
+ {
506
+ auto * sprite = new Sprite ();
507
+ if (sprite == nullptr )
508
+ {
509
+ break ;
510
+ }
511
+ if (!sprite->initWithFile (predefineTextures[i % predefineTextures.size ()]))
512
+ {
513
+ delete sprite;
514
+ break ;
515
+ }
516
+ spriteCache.push_back (sprite);
517
+ }
518
+
519
+ auto creationDuration = perf.endTick (KEY_CREATION);
520
+ perf.startTick (KEY_DESTROYATION);
521
+
522
+ for (int i=0 ; i< totalSprites; ++i)
523
+ {
524
+ spriteCache[i]->release ();
525
+ }
526
+ auto destroyDuration = perf.endTick (KEY_DESTROYATION);
527
+ std::stringstream ss;
528
+ auto t1_ms = creationDuration * 1.0 / 1000000 ;
529
+ ss << " Create " << spriteCache.size () << " sprites takes " << t1_ms<< " ms, " << (int64_t )(spriteCache.size () * 1000 / t1_ms) << " sprites per second!" ;
530
+ labelCreate->setString (ss.str ());
531
+
532
+ if (t1_ms < 100 ) {
533
+ suggestDelta =(int ) (0.5 * totalSprites);
534
+ } else if (t1_ms < 1000 ) {
535
+ suggestDelta =(int ) (0.2 * totalSprites);
536
+ } else if (t1_ms) {
537
+ suggestDelta =(int ) (0.1 * totalSprites);
538
+ }
539
+
540
+ suggestDelta = suggestDelta < 1000 ? 1000 : suggestDelta - suggestDelta % 1000 ;
541
+
542
+ ss.str (" " );
543
+ auto t2_ms = destroyDuration * 1.0 / 1000000 ;
544
+ ss << " Destroy " << spriteCache.size () << " sprites takes " << t2_ms<< " ms, " << (int64_t )(spriteCache.size () * 1000 / t2_ms) << " sprites per second!" ;
545
+ labelDestory->setString (ss.str ());
546
+
547
+ spriteCache.clear ();
548
+ }
549
+
550
+ void SpriteCreation::addSpritesCallback (cocos2d::Ref *)
551
+ {
552
+ updateSpriteCountLabel (totalSprites + suggestDelta);
553
+ doTest ();
554
+ }
555
+
556
+ void SpriteCreation::delSpritesCallback (cocos2d::Ref *)
557
+ {
558
+ updateSpriteCountLabel (totalSprites - suggestDelta);
559
+ doTest ();
560
+ }
561
+
562
+ SpriteCreation::~SpriteCreation ()
563
+ {
564
+
565
+ }
566
+
567
+ std::string SpriteCreation::title () const
568
+ {
569
+ return " Sprite Creation" ;
570
+ }
571
+
572
+ std::string SpriteCreation::subtitle () const
573
+ {
574
+ #if defined(COCOS2D_DEBUG) && COCOS2D_DEBUG == 1
575
+ return " In debug mode" ;
576
+ #else
577
+ return " In release mode" ;
578
+ #endif
579
+ }
580
+
581
+
385
582
VBOFullTest::VBOFullTest ()
386
583
{
387
584
Size s = Director::getInstance ()->getWinSize ();
@@ -791,31 +988,88 @@ std::string RendererUniformBatch2::subtitle() const
791
988
NonBatchSprites::NonBatchSprites ()
792
989
{
793
990
Size s = Director::getInstance ()->getWinSize ();
794
- Node* parent = Node::create ();
795
- parent->setPosition (0 , 0 );
796
- addChild (parent);
991
+ _spritesAnchor = Node::create ();
992
+ _spritesAnchor->setPosition (0 , 0 );
993
+ addChild (_spritesAnchor);
994
+
995
+
996
+ _totalSprites = Label::createWithTTF (TTFConfig (" fonts/arial.ttf" ), " sprites" );
997
+ _totalSprites->setColor (Color3B::YELLOW);
998
+ _totalSprites->enableOutline (Color4B::RED, 2 );
999
+ _totalSprites->setPosition (s.width /2 , s.height /2 );
1000
+
1001
+ addChild (_totalSprites);
1002
+
1003
+ scheduleUpdate ();
1004
+ }
1005
+
1006
+ void NonBatchSprites::createSprite ()
1007
+ {
797
1008
798
- for (int i = 0 ; i < 2000 ; ++i)
1009
+ Size s = Director::getInstance ()->getWinSize ();
1010
+ Sprite* sprite = nullptr ;
1011
+ if (_spriteIndex % 2 == 0 )
799
1012
{
800
- Sprite* sprite = nullptr ;
801
- if (i % 2 == 0 )
802
- {
803
- sprite = Sprite::create (" Images/grossini_dance_05.png" );
804
- }
805
- else
806
- {
807
- sprite = Sprite::create (" Images/grossini_dance_01.png" );
808
- }
1013
+ sprite = Sprite::create (" Images/grossini_dance_05.png" );
1014
+ }
1015
+ else
1016
+ {
1017
+ sprite = Sprite::create (" Images/grossini_dance_01.png" );
1018
+ }
809
1019
810
- if (!sprite) break ;
1020
+ if (!sprite) return ;
1021
+ auto r = rand_0_1 () * 0.6 + 0.2 ;
1022
+ sprite->setScale (r, r);
1023
+ float x = ((float )std::rand ()) / RAND_MAX;
1024
+ float y = ((float )std::rand ()) / RAND_MAX;
1025
+ sprite->runAction (RepeatForever::create (RotateBy::create (1 , 45 )));
811
1026
812
- sprite->setScale (0 .1f , 0 .1f );
813
- float x = ((float )std::rand ()) / RAND_MAX;
814
- float y = ((float )std::rand ()) / RAND_MAX;
815
- sprite->runAction (RepeatForever::create (RotateBy::create (1 , 45 )));
816
-
817
- sprite->setPosition (Vec2 (x * s.width , y * s.height ));
818
- parent->addChild (sprite);
1027
+ sprite->setPosition (Vec2 (x * s.width , y * s.height ));
1028
+ _spritesAnchor->addChild (sprite);
1029
+
1030
+ _spriteIndex++;
1031
+ std::stringstream ss;
1032
+ ss << _spriteIndex << " sprites" ;
1033
+ _totalSprites->setString (ss.str ());
1034
+ }
1035
+
1036
+ void NonBatchSprites::update (float dt)
1037
+ {
1038
+
1039
+ if ( dt <= 1 .0f / 28 .0f && dt >= 1 .0f / 31 .0f )
1040
+ {
1041
+ _around30fps.hit ();
1042
+ }
1043
+ else
1044
+ {
1045
+ _around30fps.cancel ();
1046
+ }
1047
+
1048
+ _maDt = 0 .7f * _maDt + 0 .3f * dt;
1049
+ _rmaDt = 0 .5f * _rmaDt + 0 .5f * dt;
1050
+ if (_maDt <= DEST_DT_30FPS) {
1051
+ _contSlow.cancel ();
1052
+ _contFast.hit ();
1053
+ if (_contFast.ok ()){
1054
+ auto t2 = DEST_DT_30FPS - _rmaDt;
1055
+ auto delta = (int )(t2 / _rmaDt * _spriteIndex * 0.1 );
1056
+ delta =std::min (20 , std::max (1 , delta));
1057
+ for (int i =0 ;i< delta; i++) {
1058
+ createSprite ();
1059
+ }
1060
+ }
1061
+ }else {
1062
+ _contSlow.hit ();
1063
+ _contFast.cancel ();
1064
+ }
1065
+
1066
+ if (_contSlow.ok () || _around30fps.ok ())
1067
+ {
1068
+ unscheduleUpdate ();
1069
+ std::stringstream ss;
1070
+ ss << _spriteIndex << " sprites, DONE!" ;
1071
+ _totalSprites->setString (ss.str ());
1072
+ _totalSprites->setScale (1.2 );
819
1073
}
820
1074
}
821
1075
@@ -831,6 +1085,10 @@ std::string NonBatchSprites::title() const
831
1085
832
1086
std::string NonBatchSprites::subtitle () const
833
1087
{
834
- return " simulate lots of sprites" ;
1088
+ #if defined(COCOS2D_DEBUG) && COCOS2D_DEBUG == 1
1089
+ return " DEBUG: simulate lots of sprites, drop to 30 fps" ;
1090
+ #else
1091
+ return " RELEASE: simulate lots of sprites, drop to 30 fps" ;
1092
+ #endif
835
1093
}
836
1094
0 commit comments