浏览代码

Merge pull request #74 from UnityTech/xwzhu

performanceOverlay reconstruction
/main
GitHub 6 年前
当前提交
b8f3d408
共有 12 个文件被更改,包括 162 次插入171 次删除
  1. 8
      Runtime/editor/editor_window.cs
  2. 2
      Runtime/editor/rasterizer.cs
  3. 29
      Runtime/flow/compositor_context.cs
  4. 2
      Runtime/flow/layer.cs
  5. 4
      Runtime/flow/layer_tree.cs
  6. 55
      Runtime/flow/performance_overlay_layer.cs
  7. 3
      Runtime/rendering/binding.cs
  8. 17
      Runtime/ui/window.cs
  9. 2
      Runtime/flow/instrumentation.cs.meta
  10. 113
      Runtime/flow/instrumentation.cs
  11. 98
      Runtime/service/performance_utils.cs
  12. 0
      /Runtime/flow/instrumentation.cs.meta

8
Runtime/editor/editor_window.cs


}
float? _lastUpdateTime;
protected override float getUnscaledDeltaTime() {
if (this._lastUpdateTime == null) {
this._lastUpdateTime = (float) EditorApplication.timeSinceStartup;

this._lastUpdateTime = (float) EditorApplication.timeSinceStartup;
return deltaTime;
}
}
}
#endif

}
public void Update() {
PerformanceUtils.instance.updateDeltaTime(this.getUnscaledDeltaTime());
this.updateDeltaTime(this.getUnscaledDeltaTime());
Timer.update();
bool hasFocus = this.hasFocus();

2
Runtime/editor/rasterizer.cs


var canvas = frame.getCanvas();
using (var compositorFrame = this._compositorContext.acquireFrame(canvas)) {
using (var compositorFrame = this._compositorContext.acquireFrame(canvas, true)) {
if (compositorFrame != null && compositorFrame.raster(layerTree, false)) {
frame.submit();
this._fireNextFrameCallbackIfPresent();

29
Runtime/flow/compositor_context.cs


public class ScopedFrame : IDisposable {
readonly CompositorContext _context;
readonly Canvas _canvas;
readonly bool _instrumentation_enabled;
public ScopedFrame(CompositorContext context, Canvas canvas) {
public ScopedFrame(CompositorContext context, Canvas canvas, bool instrumentation_enabled) {
this._context._beginFrame(this);
this._instrumentation_enabled = instrumentation_enabled;
this._context._beginFrame(this, this._instrumentation_enabled);
}
public CompositorContext context() {

}
public void Dispose() {
this._context._endFrame(this);
this._context._endFrame(this, this._instrumentation_enabled);
readonly Stopwatch _frameTime;
this._frameTime = new Stopwatch();
public ScopedFrame acquireFrame(Canvas canvas) {
return new ScopedFrame(this, canvas);
public ScopedFrame acquireFrame(Canvas canvas, bool instrumentation_enabled) {
return new ScopedFrame(this, canvas, instrumentation_enabled);
}
public void onGrContextCreated(Surface surface) {

return this._rasterCache;
}
void _beginFrame(ScopedFrame frame) {
public Stopwatch frameTime() {
return this._frameTime;
void _endFrame(ScopedFrame frame) {
void _beginFrame(ScopedFrame frame, bool enable_instrumentation) {
if (enable_instrumentation) {
this._frameTime.start();
}
}
void _endFrame(ScopedFrame frame, bool enable_instrumentation) {
if (enable_instrumentation) {
this._frameTime.stop();
}
}
}
}

2
Runtime/flow/layer.cs


public RasterCache rasterCache;
public float devicePixelRatio;
public Rect cullRect;
public Stopwatch frameTime;
public Stopwatch frameTime;
}
public abstract class Layer {

4
Runtime/flow/layer_tree.cs


}
static readonly Matrix3 _identityMatrix = Matrix3.I();
frameTime = frame.context().frameTime()
};
this._rootLayer.preroll(prerollContext, _identityMatrix);

var paintContext = new PaintContext {
canvas = frame.canvas(),
rasterCache = ignoreRasterCache ? null : frame.context().rasterCache(),
frameTime = frame.context().frameTime()
};
if (this._rootLayer.needsPainting) {

55
Runtime/flow/performance_overlay_layer.cs


using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.service;
using UnityEngine;
using Canvas = Unity.UIWidgets.ui.Canvas;
using Rect = Unity.UIWidgets.ui.Rect;
namespace Unity.UIWidgets.flow {
public class PerformanceOverlayLayer : Layer {

this._drawFPS(canvas, x, y);
if ((this._options & (int) PerformanceOverlayOption.drawFrameCost) == 1) {
this._drawFrameCost(canvas, x, y + fpsHeight, width, height - padding - fpsHeight);
context.frameTime.visualize(canvas,
Rect.fromLTWH(x, y + fpsHeight, width, height - padding - fpsHeight));
}
canvas.restore();

void _drawFPS(Canvas canvas, float x, float y) {
var pb = new ParagraphBuilder(new ParagraphStyle { });
pb.addText("FPS = " + PerformanceUtils.instance.getFPS());
pb.addText("FPS = " + Window.instance.getFPS());
}
void _drawFrameCost(Canvas canvas, float x, float y, float width, float height) {
Rect visualizationRect = Rect.fromLTWH(x, y, width, height);
Paint paint = new Paint {color = Colors.blue};
Paint paint2 = new Paint {color = Colors.red};
Paint paint3 = new Paint {color = Colors.green};
Paint paint4 = new Paint {color = Colors.white70};
float[] costFrames = PerformanceUtils.instance.getFrames();
int curFrame = PerformanceUtils.instance.getCurFrame();
float barWidth = Mathf.Max(1, width / costFrames.Length);
float perHeight = height / 32.0f;
canvas.drawRect(visualizationRect, paint4);
canvas.drawRect(Rect.fromLTWH(x, y + perHeight * 16.0f, width, 1), paint3);
float cur_x = x;
Path barPath = new Path();
for (var i = 0; i < costFrames.Length; i++) {
if (costFrames[i] != 0) {
float curHeight = Mathf.Min(perHeight * costFrames[i], height);
Rect barRect = Rect.fromLTWH(cur_x, y + height - curHeight, barWidth, curHeight);
barPath.addRect(barRect);
}
cur_x += barWidth;
}
canvas.drawPath(barPath, paint);
if (curFrame >= 0 && curFrame < costFrames.Length && costFrames[curFrame] != 0) {
float curHeight = Mathf.Min(perHeight * costFrames[curFrame], height);
Rect barRect = Rect.fromLTWH(x + barWidth * curFrame, y + height - curHeight, barWidth, curHeight);
canvas.drawRect(barRect, paint2);
var pb = new ParagraphBuilder(new ParagraphStyle { });
pb.addText("Frame Cost: " + costFrames[curFrame] + "ms");
var paragraph = pb.build();
paragraph.layout(new ParagraphConstraints(width: 300));
canvas.drawParagraph(paragraph, new Offset(x, y + height - 12));
}
}
}
}

3
Runtime/rendering/binding.cs


using Unity.UIWidgets.foundation;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.service;
using Unity.UIWidgets.ui;
namespace Unity.UIWidgets.rendering {

}
protected virtual void drawFrame() {
PerformanceUtils.instance.startProfile();
PerformanceUtils.instance.endProfile();
}
public override void hitTest(HitTestResult result, Offset position) {

17
Runtime/ui/window.cs


using System.Collections.Generic;
using Unity.UIWidgets.async;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.service;
namespace Unity.UIWidgets.ui {
public delegate void VoidCallback();

if (value == null) {
D.assert(_instance != null, "Window.instance is already cleared.");
_instance = null;
} else {
}
else {
D.assert(_instance == null, "Window.instance is already assigned.");
_instance = value;
}

public abstract Timer runInMain(Action callback);
public abstract IDisposable getScope();
float deltaTime;
public void updateDeltaTime(float unscaledDeltaTime) {
this.deltaTime += (unscaledDeltaTime - this.deltaTime) * 0.1f;
}
public float getFPS() {
return 1.0f / this.deltaTime;
}
}
}

2
Runtime/flow/instrumentation.cs.meta


fileFormatVersion: 2
guid: 819a2117a730b431bb069817e3ed8cd7
guid: 89eef64f138164ea0a407cf8e65f8186
MonoImporter:
externalObjects: {}
serializedVersion: 2

113
Runtime/flow/instrumentation.cs


using Unity.UIWidgets.material;
using Unity.UIWidgets.ui;
using UnityEditor;
using UnityEngine;
using Canvas = Unity.UIWidgets.ui.Canvas;
using Rect = Unity.UIWidgets.ui.Rect;
namespace Unity.UIWidgets.flow {
static class InstrumentationUtils {
public const int kMaxSamples = 120;
public static float now() {
#if UNITY_EDITOR
return (float) EditorApplication.timeSinceStartup;
#else
return Time.realtimeSinceStartup;
#endif
}
}
public class Stopwatch {
float _start;
float[] _laps;
int _currentSample;
bool _cacheDirty;
public Stopwatch() {
this._start = InstrumentationUtils.now();
this._currentSample = 0;
float delta = 0f;
this._laps = new float[InstrumentationUtils.kMaxSamples];
for (int i = 0; i < this._laps.Length; i++) {
this._laps[i] = delta;
}
this._cacheDirty = true;
}
public void start() {
this._start = InstrumentationUtils.now();
this._currentSample = (this._currentSample + 1) % InstrumentationUtils.kMaxSamples;
}
public void stop() {
this._laps[this._currentSample] = InstrumentationUtils.now() - this._start;
}
public void setLapTime(float delta) {
this._currentSample = (this._currentSample + 1) % InstrumentationUtils.kMaxSamples;
this._laps[this._currentSample] = delta;
}
public float lastLap() {
return this._laps[(this._currentSample - 1) % InstrumentationUtils.kMaxSamples];
}
public float maxDelta() {
float maxDelta = 0f;
for (int i = 0; i < this._laps.Length; i++) {
if (maxDelta < this._laps[i]) {
maxDelta = this._laps[i];
}
}
return maxDelta;
}
public void visualize(Canvas canvas, Rect rect) {
Paint paint = new Paint {color = Colors.blue};
Paint paint2 = new Paint {color = Colors.red};
Paint paint3 = new Paint {color = Colors.green};
Paint paint4 = new Paint {color = Colors.white70};
float[] costFrames = this._laps;
int curFrame = (this._currentSample - 1) % InstrumentationUtils.kMaxSamples;
float barWidth = Mathf.Max(1, rect.width / costFrames.Length);
float perHeight = rect.height / 32.0f;
canvas.drawRect(rect, paint4);
canvas.drawRect(Rect.fromLTWH(rect.left, rect.top + perHeight * 16.0f, rect.width, 1), paint3);
float cur_x = rect.left;
Path barPath = new Path();
for (var i = 0; i < costFrames.Length; i++) {
if (costFrames[i] != 0) {
float curHeight = Mathf.Min(perHeight * costFrames[i] * 1000, rect.height);
Rect barRect = Rect.fromLTWH(cur_x, rect.top + rect.height - curHeight, barWidth, curHeight);
barPath.addRect(barRect);
}
cur_x += barWidth;
}
canvas.drawPath(barPath, paint);
if (curFrame >= 0 && curFrame < costFrames.Length && costFrames[curFrame] != 0) {
float curHeight = Mathf.Min(perHeight * costFrames[curFrame] * 1000, rect.height);
Rect barRect = Rect.fromLTWH(rect.left + barWidth * curFrame, rect.top + rect.height - curHeight,
barWidth, curHeight);
canvas.drawRect(barRect, paint2);
var pb = new ParagraphBuilder(new ParagraphStyle { });
pb.addText("Current Frame Cost: " + costFrames[curFrame] * 1000 + "ms" + " ; Max(in last 120 frames): " + this.maxDelta() * 1000 + "ms");
var paragraph = pb.build();
paragraph.layout(new ParagraphConstraints(width: 800));
canvas.drawParagraph(paragraph, new Offset(rect.left, rect.top + rect.height - 12));
}
}
}
}

98
Runtime/service/performance_utils.cs


using System.Diagnostics;
using Unity.UIWidgets.foundation;
namespace Unity.UIWidgets.service {
public class PerformanceUtils {
public static PerformanceUtils instance {
get {
if (_instance != null) {
return _instance;
}
_instance = new PerformanceUtils();
_instance._setup();
return _instance;
}
}
static PerformanceUtils _instance;
const int FrameBufferSize = 200;
float[] _frames;
int _curFrameId;
Stopwatch _stopwatch;
float deltaTime = 0.0f;
bool _enabled;
void _setup() {
this._frames = new float[FrameBufferSize];
this._curFrameId = -1;
this._enabled = false;
}
void _ensureStopWatch() {
if (this._stopwatch == null) {
this._stopwatch = new Stopwatch();
}
}
public void updateDeltaTime(float unscaledDeltaTime) {
this.deltaTime += (unscaledDeltaTime - this.deltaTime) * 0.1f;
}
public float getFPS() {
return 1.0f / this.deltaTime;
}
public void startProfile() {
if (!this._enabled) {
return;
}
this._ensureStopWatch();
if (this._stopwatch.IsRunning) {
D.assert(false, "Try to start the stopwatch when it is already running");
return;
}
this._stopwatch.Start();
}
public void endProfile() {
if (!this._enabled || this._stopwatch == null) {
return;
}
if (!this._stopwatch.IsRunning) {
D.assert(false, "Try to record the stopwatch when it is already stopped");
}
this._stopwatch.Stop();
float frameCost = this._stopwatch.ElapsedMilliseconds;
this._stopwatch.Reset();
if (frameCost == 0) {
return;
}
this._curFrameId = (this._curFrameId + 1) % FrameBufferSize;
this._frames[this._curFrameId] = frameCost;
}
public float[] getFrames() {
if (!this._enabled) {
this._enabled = true;
}
return this._frames;
}
public int getCurFrame() {
return this._curFrameId;
}
}
}

/Runtime/service/performance_utils.cs.meta → /Runtime/flow/instrumentation.cs.meta

正在加载...
取消
保存