浏览代码

noallocate -- use rendering-specified classes 2

/main
xingwei.zhu 5 年前
当前提交
19e54da2
共有 5 个文件被更改,包括 324 次插入10 次删除
  1. 16
      Runtime/ui/painting/canvas_impl.cs
  2. 30
      Runtime/ui/utils/basic_types/generic_list.cs
  3. 25
      Runtime/ui/utils/basic_types/no_alloc_item.cs
  4. 1
      Runtime/widgets/binding.cs
  5. 262
      Runtime/ui/utils/basic_types/tessellation_generator.cs

16
Runtime/ui/painting/canvas_impl.cs


break;
}
case DrawClipPath cmd: {
var uipath = uiPath.fromPath(cmd.path);
this._drawPath(uiPath.fromPath(cmd.path), cmd.paint);
var uipath = uiPath.fromPath(cmd.path);
this._drawPath(uipath, cmd.paint);
break;
}
case DrawImage cmd: {

this.draws.Add(new CmdLayer {layer = layer});
}
public override void dispose() {
public override void clear() {
base.dispose();
}
}

}
internal class CmdLayer {
internal class CmdLayer : PoolItem {
internal class CmdDraw {
internal class CmdDraw : PoolItem {
public uiMeshMesh mesh;
public TextBlobMesh textMesh;
public int pass;

public static readonly Matrix3 idMat3 = Matrix3.I();
public static readonly int texId = Shader.PropertyToID("_tex");
public static readonly int matId = Shader.PropertyToID("_mat");
public override void clear() {
}
}
internal class CmdScissor {

30
Runtime/ui/utils/basic_types/generic_list.cs


using System;
using System.Runtime.CompilerServices;
namespace Unity.UIWidgets.ui {

this.list = this.list ?? new List<T>(128);
}
public List<T> data => this.list;
public override void dispose() {
public void AddRange(IList<T> items) {
this.list.AddRange(items);
}
public void Clear() {
this.list.Clear();
}
public override void clear() {
base.dispose();
}
public int Count {
get { return this.list.Count; }
}
public void SetCapacity(int capacity) {
this.list.Capacity = Math.Max(capacity, this.list.Capacity);
}
public T this[int index] {
get {
return this.list[index];
}
set { this.list[index] = value; }
}
}
}

25
Runtime/ui/utils/basic_types/no_alloc_item.cs


if (this._size > this._watermark) {
this._watermark = this._size;
Debug.Log("Item watermark increases >>> " + this._itemKey + " = " + this._watermark);
//Debug.Log("Item watermark increases >>> " + this._itemKey + " = " + this._watermark);
}
}

debugInfo[typeof(T)].consume();
}
curItem.activate();
return (T)curItem;
}

poolDict[typeofT].Add(item);
if (_debugFlag) {

this.length = len;
}
public override void dispose() {
public override void clear() {
this.length = 0;
base.dispose();
}

//ensure that base class has a empty constructor
bool __activated_flag = false;
public void activate() {
this.__activated_flag = true;
}
public virtual void dispose() {
public virtual void clear() {
}
public void dispose() {
if (!this.__activated_flag) {
//Debug.Assert(false, "an item has been recycled more than once !");
return;
}
this.clear();
this.__activated_flag = false;
}
public void recycle() {

1
Runtime/widgets/binding.cs


this.addPersistentFrameCallback((duration) => {
TextBlobMesh.tickNextFrame();
TessellationGenerator.tickNextFrame();
uiTessellationGenerator.tickNextFrame();
});
}

262
Runtime/ui/utils/basic_types/tessellation_generator.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Unity.UIWidgets.ui {
class uiTessellationKey : PoolItem, IEquatable<uiTessellationKey> {
public float x2;
public float y2;
public float x3;
public float y3;
public float x4;
public float y4;
public float tessTol;
public static uiTessellationKey create(float x1, float y1, float x2, float y2, float x3, float y3, float x4,
float y4,
float tessTol) {
var newKey = ItemPoolManager.alloc<uiTessellationKey>();
newKey.x2 = x2 - x1;
newKey.y2 = y2 - y1;
newKey.x3 = x3 - x1;
newKey.y3 = y3 - y1;
newKey.x4 = x4 - x1;
newKey.y4 = y4 - y1;
newKey.tessTol = tessTol;
return newKey;
}
public uiTessellationKey() {
}
public bool Equals(uiTessellationKey other) {
if (ReferenceEquals(null, other)) {
return false;
}
if (ReferenceEquals(this, other)) {
return true;
}
return this.x2 == other.x2 && this.y2 == other.y2 && this.x3 == other.x3 &&
this.y3 == other.y3 && this.x4 == other.x4 && this.y4 == other.y4 &&
this.tessTol == other.tessTol;
}
public override bool Equals(object obj) {
if (ReferenceEquals(null, obj)) {
return false;
}
if (ReferenceEquals(this, obj)) {
return true;
}
if (obj.GetType() != this.GetType()) {
return false;
}
return this.Equals((uiTessellationKey) obj);
}
public override unsafe int GetHashCode() {
unchecked {
var hashCode = 0;
float x = this.x2;
hashCode ^= *(int*) &x;
x = this.y2;
hashCode = (hashCode * 13) ^ *(int*) &x;
x = this.x3;
hashCode = (hashCode * 13) ^ *(int*) &x;
x = this.y3;
hashCode = (hashCode * 13) ^ *(int*) &x;
x = this.x4;
hashCode = (hashCode * 13) ^ *(int*) &x;
x = this.y4;
hashCode = (hashCode * 13) ^ *(int*) &x;
x = this.tessTol;
hashCode = (hashCode * 13) ^ *(int*) &x;
return hashCode;
}
}
public static bool operator ==(uiTessellationKey left, uiTessellationKey right) {
return Equals(left, right);
}
public static bool operator !=(uiTessellationKey left, uiTessellationKey right) {
return !Equals(left, right);
}
public override string ToString() {
return $"uiTessellationKey(" +
$"x2: {this.x2}, " +
$"y2: {this.y2}, " +
$"x3: {this.x3}, " +
$"y3: {this.y3}, " +
$"x4: {this.x4}, " +
$"y4: {this.y4}, " +
$"tessTol: {this.tessTol})";
}
}
class uiTessellationInfo : PoolItem {
public uiTessellationKey key;
public uiList<Vector2> points;
long _timeToLive;
public static uiTessellationInfo create(uiTessellationKey key, uiList<Vector2> points, int timeToLive = 5) {
var newInfo = ItemPoolManager.alloc<uiTessellationInfo>();
newInfo.points = points;
newInfo.key = key;
newInfo.touch(timeToLive);
return newInfo;
}
public uiTessellationInfo() {
}
public override void clear() {
this.points.dispose();
}
public long timeToLive {
get { return this._timeToLive; }
}
public void touch(long timeTolive = 5) {
this._timeToLive = timeTolive + TextBlobMesh.frameCount;
}
}
static class uiTessellationGenerator {
static readonly Dictionary<uiTessellationKey, uiTessellationInfo> _tessellations =
new Dictionary<uiTessellationKey, uiTessellationInfo>();
static long _frameCount = 0;
public static long frameCount {
get { return _frameCount; }
}
public static int tessellationCount {
get { return _tessellations.Count; }
}
public static void tickNextFrame() {
_frameCount++;
var keysToRemove = _tessellations.Values.Where(info => info.timeToLive < _frameCount)
.Select(info => info.key).ToList();
foreach (var key in keysToRemove) {
key.dispose();
_tessellations[key].dispose();
_tessellations.Remove(key);
}
}
public static uiList<Vector2> tessellateBezier(float x1, float y1, float x2, float y2,
float x3, float y3, float x4, float y4, float tessTol) {
var key = uiTessellationKey.create(x1, y1, x2, y2, x3, y3, x4, y4, tessTol);
_tessellations.TryGetValue(key, out var uiTessellationInfo);
if (uiTessellationInfo != null) {
key.dispose();
uiTessellationInfo.touch();
return uiTessellationInfo.points;
}
var points = _tessellateBezier(x1, y1, x2, y2, x3, y3, x4, y4, tessTol);
_tessellations[key] = uiTessellationInfo.create(key, points);
return points;
}
struct _StackData {
public float x1;
public float y1;
public float x2;
public float y2;
public float x3;
public float y3;
public float x4;
public float y4;
public int level;
}
static readonly Stack<_StackData> _stack = new Stack<_StackData>();
static uiList<Vector2> _tessellateBezier(
float x1, float y1, float x2, float y2,
float x3, float y3, float x4, float y4,
float tessTol) {
x2 = x2 - x1;
y2 = y2 - y1;
x3 = x3 - x1;
y3 = y3 - y1;
x4 = x4 - x1;
y4 = y4 - y1;
var points = ItemPoolManager.alloc<uiList<Vector2>>();
_stack.Clear();
_stack.Push(new _StackData {
x1 = 0, y1 = 0, x2 = x2, y2 = y2, x3 = x3, y3 = y3, x4 = x4, y4 = y4, level = 0,
});
while (_stack.Count > 0) {
var stackData = _stack.Pop();
x1 = stackData.x1;
y1 = stackData.y1;
x2 = stackData.x2;
y2 = stackData.y2;
x3 = stackData.x3;
y3 = stackData.y3;
x4 = stackData.x4;
y4 = stackData.y4;
int level = stackData.level;
float dx = x4 - x1;
float dy = y4 - y1;
float d2 = Mathf.Abs((x2 - x4) * dy - (y2 - y4) * dx);
float d3 = Mathf.Abs((x3 - x4) * dy - (y3 - y4) * dx);
if ((d2 + d3) * (d2 + d3) <= tessTol * (dx * dx + dy * dy)) {
points.Add(new Vector2(x4, y4));
continue;
}
float x12 = (x1 + x2) * 0.5f;
float y12 = (y1 + y2) * 0.5f;
float x23 = (x2 + x3) * 0.5f;
float y23 = (y2 + y3) * 0.5f;
float x34 = (x3 + x4) * 0.5f;
float y34 = (y3 + y4) * 0.5f;
float x123 = (x12 + x23) * 0.5f;
float y123 = (y12 + y23) * 0.5f;
float x234 = (x23 + x34) * 0.5f;
float y234 = (y23 + y34) * 0.5f;
float x1234 = (x123 + x234) * 0.5f;
float y1234 = (y123 + y234) * 0.5f;
if (level < 10) {
_stack.Push(new _StackData {
x1 = x1234, y1 = y1234, x2 = x234, y2 = y234, x3 = x34, y3 = y34, x4 = x4, y4 = y4,
level = level + 1,
});
_stack.Push(new _StackData {
x1 = x1, y1 = y1, x2 = x12, y2 = y12, x3 = x123, y3 = y123, x4 = x1234, y4 = y1234,
level = level + 1,
});
}
}
return points;
}
}
}
正在加载...
取消
保存