[NUI] Remove useless DisposeQueue adding at TextField
[platform/core/csapi/tizenfx.git] / test / Tizen.NUI.PerformanceTest / PerformanceTest.cs
1 /*
2  * Copyright (c) 2022 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 using System;
19 using Tizen.NUI;
20 using Tizen.NUI.BaseComponents;
21 using Tizen.NUI.Constants;
22
23
24 class PerformanceTestExample : NUIApplication
25 {
26     const uint ROWS_COUNT = 32;
27     const uint COLUMNS_COUNT = 32;
28     const uint TOTAL_COLUMNS_COUNT = 80;
29     const uint DURATION_PER_COLUMNS = 50; // miliseconds
30     const float VIEW_MARGIN_RATE = 0.1f;
31     enum ViewTestType{
32         TEST_TYPE_COLOR = 0,            ///< Test with simple color
33         TEST_TYPE_IMAGE,                ///< Test with simple image
34         TEST_TYPE_TEXT,                 ///< Test with simple text label
35         TEST_TYPE_ROUNDED_COLOR,        ///< Test with rounded color
36         TEST_TYPE_BORDER_COLOR,         ///< Test with borderline color
37         TEST_TYPE_ROUNDED_BORDER_COLOR, ///< Test with rounded borderline color
38         TEST_TYPE_BLUR_COLOR,           ///< Test with blur color
39         TEST_TYPE_ROUNDED_BLUR_COLOR,   ///< Test with blur color
40         TEST_TYPE_MAX,
41     };
42
43     static string TestTypeString(ViewTestType type)
44     {
45         switch(type)
46         {
47             case ViewTestType.TEST_TYPE_COLOR:               return "COLOR";
48             case ViewTestType.TEST_TYPE_IMAGE:               return "IMAGE";
49             case ViewTestType.TEST_TYPE_TEXT:                return "TEXT";
50             case ViewTestType.TEST_TYPE_ROUNDED_COLOR:       return "ROUNDED COLOR";
51             case ViewTestType.TEST_TYPE_BORDER_COLOR:        return "BORDER COLOR";
52             case ViewTestType.TEST_TYPE_ROUNDED_BORDER_COLOR:return "ROUNDED BORDER COLOR";
53             case ViewTestType.TEST_TYPE_BLUR_COLOR:          return "BLUR COLOR";
54             case ViewTestType.TEST_TYPE_ROUNDED_BLUR_COLOR:  return "ROUNDED BLUR COLOR";
55             default:                                         return "UNKNOWN";
56         }
57     }
58
59     static string IMAGE_DIR = Tizen.Applications.Application.Current.DirectoryInfo.Resource + "image/";
60     readonly static string[] IMAGE_PATH = {
61     IMAGE_DIR + "gallery-medium-1.jpg",
62     IMAGE_DIR + "gallery-medium-2.jpg",
63     IMAGE_DIR + "gallery-medium-3.jpg",
64     IMAGE_DIR + "gallery-medium-4.jpg",
65     IMAGE_DIR + "gallery-medium-5.jpg",
66     IMAGE_DIR + "gallery-medium-6.jpg",
67     IMAGE_DIR + "gallery-medium-7.jpg",
68     IMAGE_DIR + "gallery-medium-8.jpg",
69     IMAGE_DIR + "gallery-medium-9.jpg",
70     IMAGE_DIR + "gallery-medium-10.jpg",
71     IMAGE_DIR + "gallery-medium-11.jpg",
72     IMAGE_DIR + "gallery-medium-12.jpg",
73     IMAGE_DIR + "gallery-medium-13.jpg",
74     IMAGE_DIR + "gallery-medium-14.jpg",
75     IMAGE_DIR + "gallery-medium-15.jpg",
76     IMAGE_DIR + "gallery-medium-16.jpg",
77     IMAGE_DIR + "gallery-medium-17.jpg",
78     IMAGE_DIR + "gallery-medium-18.jpg",
79     IMAGE_DIR + "gallery-medium-19.jpg",
80     IMAGE_DIR + "gallery-medium-20.jpg",
81     IMAGE_DIR + "gallery-medium-21.jpg",
82     IMAGE_DIR + "gallery-medium-22.jpg",
83     IMAGE_DIR + "gallery-medium-23.jpg",
84     IMAGE_DIR + "gallery-medium-24.jpg",
85     IMAGE_DIR + "gallery-medium-25.jpg",
86     IMAGE_DIR + "gallery-medium-26.jpg",
87     IMAGE_DIR + "gallery-medium-27.jpg",
88     IMAGE_DIR + "gallery-medium-28.jpg",
89     IMAGE_DIR + "gallery-medium-29.jpg",
90     IMAGE_DIR + "gallery-medium-30.jpg",
91     IMAGE_DIR + "gallery-medium-31.jpg",
92     IMAGE_DIR + "gallery-medium-32.jpg",
93     IMAGE_DIR + "gallery-medium-33.jpg",
94     IMAGE_DIR + "gallery-medium-34.jpg",
95     IMAGE_DIR + "gallery-medium-35.jpg",
96     IMAGE_DIR + "gallery-medium-36.jpg",
97     IMAGE_DIR + "gallery-medium-37.jpg",
98     IMAGE_DIR + "gallery-medium-38.jpg",
99     IMAGE_DIR + "gallery-medium-39.jpg",
100     IMAGE_DIR + "gallery-medium-40.jpg",
101     IMAGE_DIR + "gallery-medium-41.jpg",
102     IMAGE_DIR + "gallery-medium-42.jpg",
103     IMAGE_DIR + "gallery-medium-43.jpg",
104     IMAGE_DIR + "gallery-medium-44.jpg",
105     IMAGE_DIR + "gallery-medium-45.jpg",
106     IMAGE_DIR + "gallery-medium-46.jpg",
107     IMAGE_DIR + "gallery-medium-47.jpg",
108     IMAGE_DIR + "gallery-medium-48.jpg",
109     IMAGE_DIR + "gallery-medium-49.jpg",
110     IMAGE_DIR + "gallery-medium-50.jpg",
111     IMAGE_DIR + "gallery-medium-51.jpg",
112     IMAGE_DIR + "gallery-medium-52.jpg",
113     IMAGE_DIR + "gallery-medium-53.jpg",
114     };
115
116     class Statistic
117     {
118         const double trimRate = 0.34;
119         global::System.Collections.Generic.List<double> v;
120         int vcnt;
121         double vsum;
122         public Statistic()
123         {
124             clear();
125         }
126         public void clear()
127         {
128             v = new global::System.Collections.Generic.List<double>();
129             vcnt = 0;
130             vsum = 0.0;
131         }
132         public void add(double x)
133         {
134             v.Add(x);
135             vcnt++;
136             vsum += x;
137         }
138         public double getAverage()
139         {
140             if(vcnt == 0)return 0.0;
141             return vsum / vcnt;
142         }
143         public double getTrimedAverage()
144         {
145             if(vcnt == 0)return 0.0;
146             v.Sort();
147             double trimVsum = 0;
148             int removedCnt = (int)(vcnt * trimRate * 0.5);
149             int trimVcnt = vcnt - removedCnt * 2;
150             if(trimVcnt == 0)
151             {
152                 trimVcnt += 2;
153                 removedCnt--;
154             }
155             for(int i = removedCnt; i < vcnt - removedCnt; i++)
156             {
157                 trimVsum += v[i];
158             }
159
160             return trimVsum / trimVcnt;
161         }
162     };
163     Statistic mCreationStatistic;
164     Window mWindow;
165     Vector2 mWindowSize;
166     Vector2 mSize;
167     ViewTestType mTestType = ViewTestType.TEST_TYPE_COLOR;
168
169     // To keep reference count.
170     global::System.Collections.Generic.LinkedList<View> mViewList;
171     global::System.Collections.Generic.LinkedList<Timer> mTimerList;
172     global::System.Collections.Generic.LinkedList<Animation> mAnimationList;
173
174     uint mColumnsCount = ROWS_COUNT;
175     uint mRowsCount = COLUMNS_COUNT;
176     uint mTotalColumnsCount = TOTAL_COLUMNS_COUNT;
177     uint mDurationPerColumns = DURATION_PER_COLUMNS; // miliseconds
178
179     uint tickCount;
180     uint deleteCount;
181
182     DateTime appStartTime;
183     DateTime appEndTime;
184     protected void CreateScene()
185     {
186         appStartTime = DateTime.Now;
187
188         mViewList  = new global::System.Collections.Generic.LinkedList<View>();
189         mTimerList = new global::System.Collections.Generic.LinkedList<Timer>();
190         mAnimationList = new global::System.Collections.Generic.LinkedList<Animation>();
191
192         mWindow = Window.Instance;
193         mWindow.BackgroundColor = Color.White;
194         mWindowSize = mWindow.WindowSize;
195
196         mSize = new Vector2(mWindowSize.X / mColumnsCount, mWindowSize.Y / mRowsCount);
197
198         Timer timer = new Timer(mDurationPerColumns);
199         timer.Tick += OnTick;
200         mTimerList.AddLast(timer);
201
202         tickCount = 0;
203         deleteCount = 0;
204
205         mCreationStatistic = new Statistic();
206
207         timer.Start();
208
209         mWindow.KeyEvent += OnKeyEvent;
210     }
211     bool OnTick(object o, EventArgs e)
212     {
213         tickCount++;
214         if(tickCount < mTotalColumnsCount * (int)ViewTestType.TEST_TYPE_MAX)
215         {
216             // Start next phase.
217             Timer timer = new Timer(mDurationPerColumns);
218             timer.Tick += OnTick;
219             mTimerList.AddLast(timer);
220
221             timer.Start();
222         }
223         DateTime startTime;
224         DateTime endTime;
225
226         startTime = DateTime.Now;
227
228         View columnView = new View()
229         {
230             BackgroundColor = Color.Blue,
231             Size = new Size(mSize.X, mWindowSize.Y),
232             Position = new Position(mWindowSize.X, 0.0f),
233         };
234
235         for(int i = 0; i < mRowsCount; ++i)
236         {
237             View bgView;
238             switch(mTestType)
239             {
240                 case ViewTestType.TEST_TYPE_COLOR:
241                 default:
242                 {
243                     bgView = CreateColor();
244                     break;
245                 }
246                 case ViewTestType.TEST_TYPE_IMAGE:
247                 {
248                     bgView = CreateImage();
249                     break;
250                 }
251                 case ViewTestType.TEST_TYPE_TEXT:
252                 {
253                     bgView = CreateTextLabel();
254                     break;
255                 }
256                 case ViewTestType.TEST_TYPE_ROUNDED_COLOR:
257                 {
258                     bgView = CreateRoundedColor();
259                     break;
260                 }
261                 case ViewTestType.TEST_TYPE_BORDER_COLOR:
262                 {
263                     bgView = CreateBorderColor(Math.Min(mSize.X, mSize.Y) * VIEW_MARGIN_RATE);
264                     break;
265                 }
266                 case ViewTestType.TEST_TYPE_ROUNDED_BORDER_COLOR:
267                 {
268                     bgView = CreateRoundedBorderColor(Math.Min(mSize.X, mSize.Y) * VIEW_MARGIN_RATE);
269                     break;
270                 }
271                 case ViewTestType.TEST_TYPE_BLUR_COLOR:
272                 {
273                     bgView = CreateBlurColor(Math.Min(mSize.X, mSize.Y) * VIEW_MARGIN_RATE * 0.5f);
274                     break;
275                 }
276                 case ViewTestType.TEST_TYPE_ROUNDED_BLUR_COLOR:
277                 {
278                     bgView = CreateRoundedBlurColor(Math.Min(mSize.X, mSize.Y) * VIEW_MARGIN_RATE * 0.5f);
279                     break;
280                 }
281             }
282             bgView.Size = new Size(mSize.X * (1.0f - VIEW_MARGIN_RATE), mSize.Y * (1.0f - VIEW_MARGIN_RATE));
283             bgView.Position = new Position(mSize.X * VIEW_MARGIN_RATE * 0.5f, (mSize.Y * VIEW_MARGIN_RATE * 0.5f) + (mSize.Y * (float)i));
284             columnView.Add(bgView);
285         }
286
287         mWindow.Add(columnView);
288         mViewList.AddLast(columnView);
289
290         // Add move animation
291         Animation animation = new Animation((int)(mDurationPerColumns * (mColumnsCount + 1)));
292         animation.AnimateTo(columnView, "PositionX", -mSize.X);
293         animation.Finished += OnAnimationFinished;
294         animation.Play();
295
296         mAnimationList.AddLast(animation);
297
298         endTime = DateTime.Now;
299
300         mCreationStatistic.add((endTime - startTime).TotalMilliseconds);
301
302         if(tickCount % mTotalColumnsCount == 0)
303         {
304             Tizen.Log.Error("NUI.PerfNew", $"Average of creation {mRowsCount} NUI({TestTypeString(mTestType)}) : {mCreationStatistic.getTrimedAverage()} ms\n");
305             mCreationStatistic.clear();
306             mTestType = (ViewTestType)(((int)(mTestType) + 1) % (int)(ViewTestType.TEST_TYPE_MAX));
307         }
308
309         return false;
310     }
311
312     void OnKeyEvent(object source, Window.KeyEventArgs e)
313     {
314         if (e.Key.State == Key.StateType.Down)
315         {
316             FullGC();
317             //Streamline.AnnotateChannelEnd(0);
318
319             switch( e.Key.KeyPressedName )
320             {
321                 case "Escape":
322                 case "Back":
323                 {
324                     Deactivate();
325                     Exit();
326                 }
327                 break;
328             }
329         }
330     }
331
332     void OnAnimationFinished(object o, EventArgs e)
333     {
334         // We can assume that front of mViewLIst must be deleted.
335         mViewList.First.Value.Unparent();
336         mViewList.First.Value.Dispose();
337         mViewList.RemoveFirst();
338
339         // Dereference timer safety
340         mTimerList.First.Value.Dispose();
341         mTimerList.RemoveFirst();
342
343         // Dereference animation safety
344         mAnimationList.RemoveFirst();
345
346         deleteCount++;
347
348         Animation me = o as Animation;
349         me.Dispose();
350
351         // If all views are deleted, quit this application. byebye~
352         if(deleteCount == mTotalColumnsCount * (int)ViewTestType.TEST_TYPE_MAX)
353         {
354             appEndTime = DateTime.Now;
355             Tizen.Log.Error("NUI.PerfNew", $"Duration of all app running time : {((appEndTime - appStartTime)).TotalMilliseconds} ms\n");
356             Deactivate();
357             FullGC();
358             Exit();
359         }
360     }
361
362     private View CreateColor()
363     {
364         View bgView = new View(){
365             BackgroundColor = Color.Yellow,
366         };
367         return bgView;
368     }
369     private int gImageCount = 0;
370     private View CreateImage()
371     {
372         ImageView bgView = new ImageView(){
373             BackgroundColor = Color.Yellow,
374             ResourceUrl = IMAGE_PATH[(gImageCount++) % (IMAGE_PATH.Length)],
375         };
376         return bgView;
377     }
378     private View CreateTextLabel()
379     {
380         TextLabel bgView = new TextLabel(){
381             Text = "Hello, World!",
382         };
383         return bgView;
384     }
385     private View CreateRoundedColor()
386     {
387         View bgView = new View(){
388             BackgroundColor = Color.Yellow,
389             CornerRadius = 0.5f,
390             CornerRadiusPolicy = VisualTransformPolicyType.Relative,
391         };
392         return bgView;
393     }
394
395     private View CreateBorderColor(float requiredBorderlineWidth)
396     {
397         View bgView = new View(){
398             BackgroundColor = Color.Yellow,
399             BorderlineColor = Color.Red,
400             BorderlineWidth = requiredBorderlineWidth,
401         };
402         return bgView;
403     }
404     private View CreateRoundedBorderColor(float requiredBorderlineWidth)
405     {
406         View bgView = new View(){
407             BackgroundColor = Color.Yellow,
408             CornerRadius = 0.5f,
409             CornerRadiusPolicy = VisualTransformPolicyType.Relative,
410             BorderlineColor = Color.Red,
411             BorderlineWidth = requiredBorderlineWidth,
412         };
413         return bgView;
414     }
415     private View CreateBlurColor(float requiredBlurRadius)
416     {
417         View bgView = new View();
418
419         using(PropertyMap map = new PropertyMap())
420         {
421             map.Insert((int)Visual.Property.Type, new PropertyValue((int)Visual.Type.Color));
422             map.Insert((int)ColorVisualProperty.MixColor, new PropertyValue(Color.Yellow));
423             map.Insert((int)ColorVisualProperty.BlurRadius, new PropertyValue(requiredBlurRadius));
424
425             bgView.Background = map;
426         }
427
428         return bgView;
429     }
430     private View CreateRoundedBlurColor(float requiredBlurRadius)
431     {
432         View bgView = new View();
433
434         using(PropertyMap map = new PropertyMap())
435         {
436             map.Insert((int)Visual.Property.Type, new PropertyValue((int)Visual.Type.Color));
437             map.Insert((int)ColorVisualProperty.MixColor, new PropertyValue(Color.Yellow));
438             map.Insert((int)ColorVisualProperty.BlurRadius, new PropertyValue(requiredBlurRadius));
439             map.Insert((int)Visual.Property.CornerRadius, new PropertyValue(0.5f));
440             map.Insert((int)Visual.Property.CornerRadiusPolicy, new PropertyValue((int)VisualTransformPolicyType.Relative));
441
442             bgView.Background = map;
443         }
444
445         return bgView;
446     }
447
448     public void Activate()
449     {
450         CreateScene();
451     }
452     public void FullGC(){
453         global::System.GC.Collect();
454         global::System.GC.WaitForPendingFinalizers();
455         global::System.GC.Collect();
456     }
457
458     public void Deactivate()
459     {
460         DestroyScene();
461     }
462     private void DestroyScene()
463     {
464     }
465
466     protected override void OnCreate()
467     {
468         // Up call to the Base class first
469         base.OnCreate();
470         Activate();
471     }
472
473     /// <summary>
474     /// The main entry point for the application.
475     /// </summary>
476     [STAThread] // Forces app to use one thread to access NUI
477     static void Main(string[] args)
478     {
479         PerformanceTestExample example = new PerformanceTestExample();
480         example.Run(args);
481     }
482 }