Skip to content
This repository was archived by the owner on Sep 7, 2022. It is now read-only.

Commit 33cad3c

Browse files
authored
Merge pull request #176 from Unity-Technologies/siyaoH/1.17/gc
incremental gc
2 parents 52fe7aa + b2887b9 commit 33cad3c

File tree

7 files changed

+87
-15
lines changed

7 files changed

+87
-15
lines changed

README-ZH.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -202,15 +202,17 @@ UIWidgets也支持Gif!
202202
#### 七、图片导入设置
203203
请将图片放入StreamingAssets下,而后用```Image.file```读取
204204

205-
#### 八、自动降低帧率
206-
目前在默认情况下,为了保证流畅度,项目在各个平台上均会以最高的刷新频率运行。不过您可以通过在代码中设置```SchedulerBinding.MEnableAutoAdjustFramerate = true```的方式来开启自动降帧的功能:该功能开启后,在UI内容不变的情况下我们将降低项目的刷新率来降低耗电。
205+
#### 八、移动设备优化
206+
目前在默认情况下,为了保证流畅度,项目在各个平台上均会以最高的刷新频率运行。不过您可以通过在代码中设置```UIWidgetsGlobalConfiguration.EnableAutoAdjustFramerate = true```的方式来开启自动降帧的功能:该功能开启后,在UI内容不变的情况下我们将降低项目的刷新率来降低耗电。
207+
208+
在移动设备上UI绘制的流畅度受到GC影响较大。项目默认会开启OnDemandGC来接管并优化整体GC效果。如果您不需要GC被UIWidgets控制,请在代码中设置```UIWidgetsGlobalConfiguration.EnableIncrementalGC = false```。
207209

208210

209211
## 调试UIWidgets应用程序
210212

211213
在编辑器菜单栏选择```UIWidgets->EnableDebug```
212214

213-
如果想在runtime选择是否debug,请修改文件```com.unity.uiwidgets/com.unity.uiwidgets/Runtime/foundation/debug.cs```中的```static bool debugEnableAtRuntimeInternal```
215+
如果想在runtime开启debug模式,请在项目代码中设置```UIWidgetsGlobalConfiguration.EnableDebugAtRuntime = true```。在默认情况下debug模式为关闭状态。
214216

215217
## 使用Window Scope保护外部调用
216218
如果您在调试时遇到 `AssertionError: Window.instance is null` 或者在调用 `Window.instance` 时得到空指针, 那么您需要

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -213,16 +213,16 @@ want to show the status bar in your App, you can disable```Start in fullscreen``
213213
#### Image Import Setting
214214
Please put images under StreamingAssets folder, a and loading it using ```Image.file```.
215215

216-
#### Automatic Framerate Adjustment
217-
You can enable this feature by setting ```SchedulerBinding.MEnableAutoAdjustFramerate = true``` in your project, which will automatically drop the frame rate of your App to 0 if the UI contents of UIWidgetsPanel is not changed for some time. This will help to prevent battery drain on mobile devices significantly.
216+
#### Performance Optimization on Mobile devices
217+
By setting ```UIWidgetsGlobalConfiguration.EnableAutoAdjustFramerate = true``` in your project, UIWidgets will drop the frame rate of your App to 0 if the UI contents of UIWidgetsPanel is not changed for some time. This will help to prevent battery drain on mobile devices significantly. Note that this feature is disabled by default.
218218

219-
Note that this feature is disabled by default though.
219+
Long time garbage collection may cause App to stuck frequently. In UIWidgets we enable incremental garbage collection to avoid it. However, you can disable this feature by setting ```UIWidgetsGlobalConfiguration.EnableIncrementalGC = false```.
220220

221221
## Debug UIWidgets Application
222222

223223
In Unity editor, you can switch debug/release mode by “UIWidgets->EnableDebug”.
224224

225-
If you want to change different mode in runtime, please modify the file “com.unity.uiwidgets/com.unity.uiwidgets/Runtime/foundation/debug.cs” by making “static bool debugEnableAtRuntimeInternal” to true or false. Note that the value is set to false by default.
225+
You can also enable debug mode in runtime by setting ```UIWidgetsGlobalConfiguration.EnableDebugAtRuntime = true``` in your project. Note that this value is set to false by default.
226226

227227
## Using Window Scope
228228
If you see the error `AssertionError: Window.instance is null` or null pointer error of `Window.instance`,
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace Unity.UIWidgets.engine {
2+
public static class UIWidgetsGlobalConfiguration {
3+
//disable auto adjust framerate by default
4+
public static bool EnableAutoAdjustFramerate = false;
5+
6+
//enable incremental gc by default
7+
public static bool EnableIncrementalGC = true;
8+
9+
//disable debug at runtime by default
10+
public static bool EnableDebugAtRuntime = false;
11+
}
12+
}

com.unity.uiwidgets/Runtime/engine/UIWidgetsGlobalConfiguration.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

com.unity.uiwidgets/Runtime/engine/UIWidgetsPanel.cs

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33
using System.Collections.Generic;
44
using Unity.UIWidgets.external.simplejson;
55
using Unity.UIWidgets.foundation;
6+
using Unity.UIWidgets.rendering;
67
using Unity.UIWidgets.ui;
78
using Unity.UIWidgets.widgets;
89
using UnityEngine;
910
using UnityEngine.EventSystems;
11+
using UnityEngine.Profiling;
12+
using UnityEngine.Scripting;
1013
using UnityEngine.UI;
1114
using RawImage = UnityEngine.UI.RawImage;
1215

@@ -146,17 +149,63 @@ void _handleViewMetricsChanged(string method, List<JSONNode> args) {
146149
Window.instance.onMetricsChanged?.Invoke();
147150
}
148151
}
149-
152+
150153
protected virtual void Update() {
151154
if (!_viewMetricsCallbackRegistered) {
152155
_viewMetricsCallbackRegistered = true;
153156
UIWidgetsMessageManager.instance?.AddChannelMessageDelegate("ViewportMetricsChanged",
154157
_handleViewMetricsChanged);
155158
}
159+
160+
#if !UNITY_EDITOR
161+
CollectGarbageOnDemand();
162+
#endif
156163

157164
Input_Update();
158165
}
159166

167+
#region OnDemandGC
168+
#if !UNITY_EDITOR
169+
// 8 MB
170+
const long kCollectAfterAllocating = 8 * 1024 * 1024;
171+
172+
long lastFrameMemory = 0;
173+
long nextCollectAt = 0;
174+
175+
void TryEnableOnDemandGC()
176+
{
177+
if (UIWidgetsGlobalConfiguration.EnableIncrementalGC)
178+
{
179+
GarbageCollector.GCMode = GarbageCollector.Mode.Disabled;
180+
Application.lowMemory += GC.Collect;
181+
}
182+
}
183+
184+
void CollectGarbageOnDemand()
185+
{
186+
if (!UIWidgetsGlobalConfiguration.EnableIncrementalGC)
187+
{
188+
return;
189+
}
190+
191+
var mem = Profiler.GetMonoUsedSizeLong();
192+
if (mem < lastFrameMemory)
193+
{
194+
// GC happened.
195+
nextCollectAt = mem + kCollectAfterAllocating;
196+
}
197+
else if (mem >= nextCollectAt)
198+
{
199+
// Trigger incremental GC
200+
GarbageCollector.CollectIncremental(1000);
201+
lastFrameMemory = mem + kCollectAfterAllocating;
202+
}
203+
204+
lastFrameMemory = mem;
205+
}
206+
#endif
207+
#endregion
208+
160209
#if !UNITY_EDITOR && UNITY_ANDROID
161210
bool AndroidInitialized = true;
162211

@@ -185,6 +234,11 @@ protected void OnEnable() {
185234
//the hook API cannot be automatically called on IOS, so we need try hook it here
186235
Hooks.tryHook();
187236
#endif
237+
238+
#if !UNITY_EDITOR
239+
TryEnableOnDemandGC();
240+
#endif
241+
188242
base.OnEnable();
189243

190244
D.assert(_wrapper == null);

com.unity.uiwidgets/Runtime/foundation/debug.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,6 @@ public static class D {
5252
public static bool debugCheckIntrinsicSizes = false;
5353

5454
public static bool debugPrintMouseHoverEvents = false;
55-
56-
static bool debugEnableAtRuntimeInternal = false;
5755

5856
public static HSVColor debugCurrentRepaintColor =
5957
HSVColor.fromAHSV(0.4f, 60.0f, 1.0f, 1.0f);
@@ -95,7 +93,7 @@ public static bool enableDebug {
9593
}
9694
}
9795
#else
98-
public static bool enableDebug => debugEnableAtRuntimeInternal;
96+
public static bool enableDebug => UIWidgetsGlobalConfiguration.EnableDebugAtRuntime;
9997
#endif
10098

10199
public static void _debugDrawDoubleRect(Canvas canvas, Rect outerRect, Rect innerRect, Color color) {

com.unity.uiwidgets/Runtime/scheduler/binding.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -440,9 +440,6 @@ public void ensureVisualUpdate() {
440440
static readonly TimeSpan _coolDownDelay = new TimeSpan(0, 0, 0, 0, 200);
441441
static Timer frameCoolDownTimer = null;
442442

443-
//disable auto adjust framerate by default
444-
public static bool MEnableAutoAdjustFramerate = false;
445-
446443
public void scheduleFrame() {
447444
if (hasScheduledFrame || !framesEnabled) {
448445
return;
@@ -460,11 +457,14 @@ public void scheduleFrame() {
460457
Window.instance.scheduleFrame();
461458
hasScheduledFrame = true;
462459

460+
#if !UNITY_EDITOR
463461
adjustFrameRate();
462+
#endif
464463
}
465464

465+
#if !UNITY_EDITOR
466466
void adjustFrameRate() {
467-
if (!MEnableAutoAdjustFramerate) {
467+
if (!UIWidgetsGlobalConfiguration.EnableAutoAdjustFramerate) {
468468
return;
469469
}
470470

@@ -488,6 +488,7 @@ void onFrameRateSpeedUp() {
488488
void onFrameRateCoolDown() {
489489
OnDemandRendering.renderFrameInterval = defaultMaxRenderFrameInterval;
490490
}
491+
#endif
491492

492493
public void scheduleForcedFrame() {
493494
if (!framesEnabled) {
@@ -510,7 +511,9 @@ public void scheduleForcedFrame() {
510511
Window.instance.scheduleFrame();
511512
hasScheduledFrame = true;
512513

514+
#if !UNITY_EDITOR
513515
adjustFrameRate();
516+
#endif
514517
}
515518

516519
public void scheduleWarmUpFrame() {

0 commit comments

Comments
 (0)