2 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 using Tizen.NUI.BaseComponents;
21 using Tizen.NUI.Constants;
24 class PerformanceTestExample : NUIApplication
26 const uint ROWS_COUNT = 40;
27 const uint COLUMNS_COUNT = 40;
28 const uint TOTAL_COLUMNS_COUNT = 80;
29 const uint DURATION_PER_COLUMNS = 50; // miliseconds
30 // Increase animation time cause OnTick time can be delayed.
31 const uint DURATION_OF_ANIMATION = (DURATION_PER_COLUMNS*(COLUMNS_COUNT * 4 / 3)); // miliseconds.
34 const float VIEW_MARGIN_RATE = 0.2f;
36 TEST_TYPE_COLOR = 0, ///< Test with simple color
37 TEST_TYPE_IMAGE, ///< Test with simple image
38 TEST_TYPE_TEXT, ///< Test with simple text label
39 TEST_TYPE_ROUNDED_COLOR, ///< Test with rounded color
40 TEST_TYPE_BORDER_COLOR, ///< Test with borderline color
41 TEST_TYPE_ROUNDED_BORDER_COLOR, ///< Test with rounded borderline color
42 TEST_TYPE_BLUR_COLOR, ///< Test with blur color
43 TEST_TYPE_ROUNDED_BLUR_COLOR, ///< Test with blur color
47 static string TestTypeString(ViewTestType type)
51 case ViewTestType.TEST_TYPE_COLOR: return "COLOR";
52 case ViewTestType.TEST_TYPE_IMAGE: return "IMAGE";
53 case ViewTestType.TEST_TYPE_TEXT: return "TEXT";
54 case ViewTestType.TEST_TYPE_ROUNDED_COLOR: return "ROUNDED COLOR";
55 case ViewTestType.TEST_TYPE_BORDER_COLOR: return "BORDER COLOR";
56 case ViewTestType.TEST_TYPE_ROUNDED_BORDER_COLOR:return "ROUNDED BORDER COLOR";
57 case ViewTestType.TEST_TYPE_BLUR_COLOR: return "BLUR COLOR";
58 case ViewTestType.TEST_TYPE_ROUNDED_BLUR_COLOR: return "ROUNDED BLUR COLOR";
59 default: return "UNKNOWN";
63 static string IMAGE_DIR = Tizen.Applications.Application.Current.DirectoryInfo.Resource + "image/";
64 readonly static string[] IMAGE_PATH = {
65 IMAGE_DIR + "gallery-small-1.jpg",
70 const double trimRate = 0.34;
71 global::System.Collections.Generic.List<double> v;
80 v = new global::System.Collections.Generic.List<double>();
84 public void add(double x)
90 public double getAverage()
92 if(vcnt == 0)return 0.0;
95 public double getTrimedAverage()
97 if(vcnt == 0)return 0.0;
100 int removedCnt = (int)(vcnt * trimRate * 0.5); // floor
101 int trimVcnt = vcnt - removedCnt * 2;
107 for(int i = removedCnt; i < vcnt - removedCnt; i++)
112 return trimVsum / trimVcnt;
115 Statistic mCreationStatistic;
119 ViewTestType mTestType = ViewTestType.TEST_TYPE_COLOR;
121 // To keep reference count.
122 global::System.Collections.Generic.LinkedList<View> mCreatingControlList;
123 global::System.Collections.Generic.LinkedList<View> mRemovingControlList;
124 global::System.Collections.Generic.LinkedList<Timer> mTimerList;
125 global::System.Collections.Generic.LinkedList<Animation> mCreatingAnimationList;
126 global::System.Collections.Generic.LinkedList<Animation> mRemovingAnimationList;
128 uint mColumnsCount = ROWS_COUNT;
129 uint mRowsCount = COLUMNS_COUNT;
130 uint mTotalColumnsCount = TOTAL_COLUMNS_COUNT;
131 uint mDurationPerColumns = DURATION_PER_COLUMNS; // miliseconds
135 uint mCreateCount = 0u;
136 uint mDeleteCount = 0u;
137 uint mImageCount = 0u;
139 DateTime appStartTime;
141 protected void CreateScene()
143 appStartTime = DateTime.Now;
145 mCreatingControlList = new global::System.Collections.Generic.LinkedList<View>();
146 mRemovingControlList = new global::System.Collections.Generic.LinkedList<View>();
147 mTimerList = new global::System.Collections.Generic.LinkedList<Timer>();
148 mCreatingAnimationList = new global::System.Collections.Generic.LinkedList<Animation>();
149 mRemovingAnimationList = new global::System.Collections.Generic.LinkedList<Animation>();
151 mWindow = Window.Instance;
152 mWindow.BackgroundColor = Color.White;
153 mWindowSize = mWindow.WindowSize;
155 mSize = new Vector2(mWindowSize.X / mColumnsCount, mWindowSize.Y / mRowsCount);
157 Timer timer = new Timer(mDurationPerColumns);
158 timer.Tick += OnTick;
159 mTimerList.AddLast(timer);
164 mCreationStatistic = new Statistic();
168 mWindow.KeyEvent += OnKeyEvent;
170 bool OnTick(object o, EventArgs e)
173 if(mCreateCount < mColumnsCount)
176 Timer timer = new Timer(mDurationPerColumns);
177 timer.Tick += OnTick;
178 mTimerList.AddLast(timer);
184 void CreateColumnView()
189 startTime = DateTime.Now;
191 View columnView = new View()
193 BackgroundColor = Color.Blue,
194 Size = new Size(mSize.X, mWindowSize.Y),
195 Position = new Position(mSize.X * (mCreateCount % mColumnsCount), -mWindowSize.Y),
197 ParentOrigin = Position.ParentOriginTopLeft,
198 PivotPoint = Position.PivotPointTopLeft,
199 PositionUsesPivotPoint = true,
202 for(int i = 0; i < mRowsCount; ++i)
207 case ViewTestType.TEST_TYPE_COLOR:
210 bgView = CreateColor();
213 case ViewTestType.TEST_TYPE_IMAGE:
215 bgView = CreateImage();
218 case ViewTestType.TEST_TYPE_TEXT:
220 bgView = CreateTextLabel();
223 case ViewTestType.TEST_TYPE_ROUNDED_COLOR:
225 bgView = CreateRoundedColor();
228 case ViewTestType.TEST_TYPE_BORDER_COLOR:
230 bgView = CreateBorderColor(Math.Min(mSize.X, mSize.Y) * VIEW_MARGIN_RATE);
233 case ViewTestType.TEST_TYPE_ROUNDED_BORDER_COLOR:
235 bgView = CreateRoundedBorderColor(Math.Min(mSize.X, mSize.Y) * VIEW_MARGIN_RATE);
238 case ViewTestType.TEST_TYPE_BLUR_COLOR:
240 bgView = CreateBlurColor(Math.Min(mSize.X, mSize.Y) * VIEW_MARGIN_RATE * 0.5f);
243 case ViewTestType.TEST_TYPE_ROUNDED_BLUR_COLOR:
245 bgView = CreateRoundedBlurColor(Math.Min(mSize.X, mSize.Y) * VIEW_MARGIN_RATE * 0.5f);
249 bgView.Size = new Size(mSize.X * (1.0f - VIEW_MARGIN_RATE), mSize.Y * (1.0f - VIEW_MARGIN_RATE));
250 bgView.Position = new Position(mSize.X * VIEW_MARGIN_RATE * 0.5f, (mSize.Y * VIEW_MARGIN_RATE * 0.5f) + (mSize.Y * (float)i));
251 columnView.Add(bgView);
254 mWindow.Add(columnView);
255 mCreatingControlList.AddLast(columnView);
257 // Add appearing animation
258 Animation appearingAnimation = new Animation((int)(DURATION_OF_ANIMATION));
259 appearingAnimation.AnimateTo(columnView, "PositionY", 0.0f);
260 appearingAnimation.Finished += OnAppearAnimationFinished;
261 appearingAnimation.Play();
263 mCreatingAnimationList.AddLast(appearingAnimation);
265 endTime = DateTime.Now;
267 mCreationStatistic.add((endTime - startTime).TotalMilliseconds);
271 if(mCreateCount % mTotalColumnsCount == 0)
273 Tizen.Log.Error("NUI.PerfNew", $"Average of creation {mRowsCount} NUI({TestTypeString(mTestType)}) : {mCreationStatistic.getTrimedAverage()} ms\n");
274 mCreationStatistic.clear();
275 mTestType = (ViewTestType)(((int)(mTestType) + 1) % (int)(ViewTestType.TEST_TYPE_MAX));
279 void OnKeyEvent(object source, Window.KeyEventArgs e)
281 if (e.Key.State == Key.StateType.Down)
284 //Streamline.AnnotateChannelEnd(0);
286 switch( e.Key.KeyPressedName )
299 void OnAppearAnimationFinished(object o, EventArgs e)
301 // We can assume that front of mControlList must be disappearing.
302 var currentControl = mCreatingControlList.First.Value;
303 mCreatingControlList.RemoveFirst();
305 // Dereference timer safety
306 if(mTimerList.Count > 0)
308 mTimerList.First.Value.Dispose();
309 mTimerList.RemoveFirst();
312 // Dereference animation safety
313 mCreatingAnimationList.RemoveFirst();
315 mRemovingControlList.AddLast(currentControl);
317 if(mCreateCount < mTotalColumnsCount * (int)(ViewTestType.TEST_TYPE_MAX))
322 // Add disappearing animation
323 Animation disappearingAnimation = new Animation((int)(DURATION_OF_ANIMATION));
324 disappearingAnimation.AnimateTo(currentControl, "PositionY", (float)mWindowSize.Y);
325 disappearingAnimation.Finished += OnDisappearAnimationFinished;
326 disappearingAnimation.Play();
328 mRemovingAnimationList.AddLast(disappearingAnimation);
330 void OnDisappearAnimationFinished(object o, EventArgs e)
332 // We can assume that front of mControlList must be disappearing.
333 var currentControl = mRemovingControlList.First.Value;
334 mRemovingControlList.RemoveFirst();
336 // We can assume that front of mViewLIst must be deleted.
337 currentControl.Unparent();
338 currentControl.DisposeRecursively();
340 // Dereference animation safety
341 mRemovingAnimationList.RemoveFirst();
345 // If all views are deleted, quit this application. byebye~
346 if(mDeleteCount == mTotalColumnsCount * (int)ViewTestType.TEST_TYPE_MAX)
348 appEndTime = DateTime.Now;
349 Tizen.Log.Error("NUI.PerfNew", $"Duration of all app running time : {((appEndTime - appStartTime)).TotalMilliseconds} ms\n");
356 private View CreateColor()
358 View bgView = new View(){
359 BackgroundColor = Color.Yellow,
361 ParentOrigin = Position.ParentOriginTopLeft,
362 PivotPoint = Position.PivotPointTopLeft,
363 PositionUsesPivotPoint = true,
367 private View CreateImage()
369 ImageView bgView = new ImageView(){
370 BackgroundColor = Color.Yellow,
371 ResourceUrl = IMAGE_PATH[(mImageCount++) % (IMAGE_PATH.Length)],
373 ParentOrigin = Position.ParentOriginTopLeft,
374 PivotPoint = Position.PivotPointTopLeft,
375 PositionUsesPivotPoint = true,
379 private View CreateTextLabel()
381 TextLabel bgView = new TextLabel(){
382 Text = "Hello, World!",
384 ParentOrigin = Position.ParentOriginTopLeft,
385 PivotPoint = Position.PivotPointTopLeft,
386 PositionUsesPivotPoint = true,
390 private View CreateRoundedColor()
392 View bgView = new View(){
393 BackgroundColor = Color.Yellow,
395 CornerRadiusPolicy = VisualTransformPolicyType.Relative,
397 ParentOrigin = Position.ParentOriginTopLeft,
398 PivotPoint = Position.PivotPointTopLeft,
399 PositionUsesPivotPoint = true,
404 private View CreateBorderColor(float requiredBorderlineWidth)
406 View bgView = new View(){
407 BackgroundColor = Color.Yellow,
408 BorderlineColor = Color.Red,
409 BorderlineWidth = requiredBorderlineWidth,
411 ParentOrigin = Position.ParentOriginTopLeft,
412 PivotPoint = Position.PivotPointTopLeft,
413 PositionUsesPivotPoint = true,
417 private View CreateRoundedBorderColor(float requiredBorderlineWidth)
419 View bgView = new View(){
420 BackgroundColor = Color.Yellow,
422 CornerRadiusPolicy = VisualTransformPolicyType.Relative,
423 BorderlineColor = Color.Red,
424 BorderlineWidth = requiredBorderlineWidth,
426 ParentOrigin = Position.ParentOriginTopLeft,
427 PivotPoint = Position.PivotPointTopLeft,
428 PositionUsesPivotPoint = true,
432 private View CreateBlurColor(float requiredBlurRadius)
434 View bgView = new View()
436 ParentOrigin = Position.ParentOriginTopLeft,
437 PivotPoint = Position.PivotPointTopLeft,
438 PositionUsesPivotPoint = true,
441 using(PropertyMap map = new PropertyMap())
443 map.Insert((int)Visual.Property.Type, new PropertyValue((int)Visual.Type.Color));
444 map.Insert((int)ColorVisualProperty.MixColor, new PropertyValue(Color.Yellow));
445 map.Insert((int)ColorVisualProperty.BlurRadius, new PropertyValue(requiredBlurRadius));
447 bgView.Background = map;
452 private View CreateRoundedBlurColor(float requiredBlurRadius)
454 View bgView = new View()
456 ParentOrigin = Position.ParentOriginTopLeft,
457 PivotPoint = Position.PivotPointTopLeft,
458 PositionUsesPivotPoint = true,
461 using(PropertyMap map = new PropertyMap())
463 map.Insert((int)Visual.Property.Type, new PropertyValue((int)Visual.Type.Color));
464 map.Insert((int)ColorVisualProperty.MixColor, new PropertyValue(Color.Yellow));
465 map.Insert((int)ColorVisualProperty.BlurRadius, new PropertyValue(requiredBlurRadius));
466 map.Insert((int)Visual.Property.CornerRadius, new PropertyValue(0.5f));
467 map.Insert((int)Visual.Property.CornerRadiusPolicy, new PropertyValue((int)VisualTransformPolicyType.Relative));
469 bgView.Background = map;
475 public void Activate()
479 public void FullGC(){
480 global::System.GC.Collect();
481 global::System.GC.WaitForPendingFinalizers();
482 global::System.GC.Collect();
485 public void Deactivate()
489 private void DestroyScene()
493 protected override void OnCreate()
495 // Up call to the Base class first
501 /// The main entry point for the application.
503 [STAThread] // Forces app to use one thread to access NUI
504 static void Main(string[] args)
506 PerformanceTestExample example = new PerformanceTestExample();