浏览代码

Merge pull request #169 from UnityTech/kgdev

performance improvements...
/main
GitHub 6 年前
当前提交
93b48256
共有 6 个文件被更改,包括 215 次插入122 次删除
  1. 61
      Runtime/ui/matrix.cs
  2. 72
      Runtime/ui/painting/canvas_clip.cs
  3. 156
      Runtime/ui/painting/path.cs
  4. 14
      Runtime/ui/painting/tessellation_generator.cs
  5. 23
      Runtime/ui/painting/ArrayRef.cs
  6. 11
      Runtime/ui/painting/ArrayRef.cs.meta

61
Runtime/ui/matrix.cs


return true;
}
else {
var points = new[] {
this.mapXY(src.left, src.top),
this.mapXY(src.right, src.top),
this.mapXY(src.right, src.bottom),
this.mapXY(src.left, src.bottom),
};
float x1, y1, x2, y2, x3, y3, x4, y4;
this.mapXY(src.left, src.top, out x1, out y1);
this.mapXY(src.right, src.top, out x2, out y2);
this.mapXY(src.right, src.bottom, out x3, out y3);
this.mapXY(src.left, src.bottom, out x4, out y4);
var minX = x1;
var minY = y1;
var maxX = x1;
var maxY = y1;
if (x2 < minX) {
minX = x2;
}
if (x2 > maxX) {
maxX = x2;
}
if (y2 < minY) {
minY = y2;
}
if (y2 > maxY) {
maxY = y2;
}
var minX = points[0].dx;
var minY = points[0].dy;
var maxX = points[0].dx;
var maxY = points[0].dy;
if (x3 < minX) {
minX = x3;
}
if (x3 > maxX) {
maxX = x3;
}
if (y3 < minY) {
minY = y3;
}
if (y3 > maxY) {
maxY = y3;
}
for (int i = 1; i < 4; ++i) {
minX = Mathf.Min(minX, points[i].dx);
minY = Mathf.Min(minY, points[i].dy);
maxX = Mathf.Max(maxX, points[i].dx);
maxY = Mathf.Max(maxY, points[i].dy);
if (x4 < minX) {
minX = x4;
}
if (x4 > maxX) {
maxX = x4;
}
if (y4 < minY) {
minY = y4;
}
if (y4 > maxY) {
maxY = y4;
}
dst = Rect.fromLTRB(minX, minY, maxX, maxY);

72
Runtime/ui/painting/canvas_clip.cs


return this._genId;
}
// bool _convexContains(float x, float y) {
// if (this.mesh.vertices.Count <= 2) {
// return false;
// }
//
// if (this.mesh.matrix != null) {
// if (this._invMat == null) {
// this._invMat = Matrix3.I();
// this.mesh.matrix.invert(this._invMat); // ignore if not invertible for now.
// }
//
// var offset = this._invMat.mapXY(x, y);
// x = offset.dx;
// y = offset.dy;
// }
//
// for (var i = 0; i < this.mesh.vertices.Count; i++) {
// var p0 = this.mesh.vertices[i];
// var p1 = this.mesh.vertices[i == this.mesh.vertices.Count - 1 ? 0 : i + 1];
//
// if (PathUtils.triarea2(p0.x, p0.y, p1.x, p1.y, x, y) < 0.0f) {
// return false;
// }
// }
//
// return true;
// }
bool _convexContains(Rect rect) {
if (this.mesh.vertices.Count <= 2) {
return false;
}
for (var i = 0; i < this.mesh.vertices.Count; i++) {
var p1 = this.mesh.vertices[i];
var p0 = this.mesh.vertices[i == this.mesh.vertices.Count - 1 ? 0 : i + 1];
var v = p1 - p0;
if (v.x == 0.0 && v.y == 0.0) {
continue;
}
float yL = v.y * (rect.left - p0.x);
float xT = v.x * (rect.top - p0.y);
float yR = v.y * (rect.right - p0.x);
float xB = v.x * (rect.bottom - p0.y);
if ((xT < yL) || (xT < yR) || (xB < yL) || (xB < yR)) {
return false;
}
}
return true;
}
public bool contains(Rect rect) {
if (this.isRect) {

// this seems to be inefficient. disable it for now.
// if (this.convex) {
// return this._convexContains(rect.left, rect.top) &&
// this._convexContains(rect.left, rect.bottom) &&
// this._convexContains(rect.right, rect.top) &&
// this._convexContains(rect.right, rect.bottom);
// }
if (this.convex) {
if (this.mesh.matrix != null && !this.mesh.matrix.isIdentity()) {
if (this._invMat == null) {
this._invMat = Matrix3.I();
this.mesh.matrix.invert(this._invMat); // ignore if not invertible for now.
}
rect = this._invMat.mapRect(rect);
}
return this._convexContains(rect);
}
return false;
}

156
Runtime/ui/painting/path.cs


return totalW != 0;
}
static int windingLine(float x0, float y0, float x1, float y1, float x, float y) {
if (y0 == y1) {
return 0;

readonly float _distTol;
readonly float _tessTol;
readonly List<PathPath> _paths = new List<PathPath>();
readonly List<PathPoint> _points = new List<PathPoint>();
readonly List<Vector3> _vertices = new List<Vector3>();
readonly ArrayRef<PathPath> _paths = new ArrayRef<PathPath>();
readonly ArrayRef<PathPoint> _points = new ArrayRef<PathPoint>();
List<Vector3> _vertices = null;
MeshMesh _fillMesh;
bool _fillConvex;

}
public void addPath() {
this._paths.Add(new PathPath {
first = this._points.Count,
this._paths.add(new PathPath {
first = this._points.length,
winding = PathWinding.counterClockwise
});
}

}
void _addPoint(PathPoint point) {
if (this._paths.Count == 0) {
if (this._paths.length == 0) {
ref var path = ref this._paths.refAt(this._paths.Count - 1);
ref var path = ref this._paths.array[this._paths.length - 1];
ref var pt = ref this._points.refAt(this._points.Count - 1);
ref var pt = ref this._points.array[this._points.length - 1];
if (PathUtils.ptEquals(pt.x, pt.y, point.x, point.y, this._distTol)) {
pt.flags |= point.flags;
return;

this._points.Add(point);
this._points.add(point);
path.count++;
}

PointFlags flags) {
float x1, y1;
if (this._points.Count == 0) {
if (this._points.length == 0) {
ref var pt = ref this._points.refAt(this._points.Count - 1);
ref var pt = ref this._points.array[this._points.length - 1];
x1 = pt.x;
y1 = pt.y;
}

}
public void closePath() {
if (this._paths.Count == 0) {
if (this._paths.length == 0) {
ref var path = ref this._paths.refAt(this._paths.Count - 1);
ref var path = ref this._paths.array[this._paths.length - 1];
if (this._paths.Count == 0) {
if (this._paths.length == 0) {
ref var path = ref this._paths.refAt(this._paths.Count - 1);
ref var path = ref this._paths.array[this._paths.length - 1];
var points = this._points.array();
var paths = this._paths.array();
for (var j = 0; j < paths.Length; j++) {
ref var path = ref paths[j];
var points = this._points;
var paths = this._paths;
for (var j = 0; j < paths.length; j++) {
ref var path = ref paths.array[j];
if (path.count <= 1) {
continue;
}

ref var p0 = ref points[ip0];
ref var p1 = ref points[ip1];
ref var p0 = ref points.array[ip0];
ref var p1 = ref points.array[ip1];
if (PathUtils.ptEquals(p0.x, p0.y, p1.x, p1.y, this._distTol)) {
path.count--;
path.closed = true;

if (path.winding == PathWinding.clockwise) {
PathUtils.polyReverse(this._points, path.first, path.count);
PathUtils.polyReverse(points.array, path.first, path.count);
}
}
}

var points = this._points.array();
var paths = this._paths.array();
for (var j = 0; j < paths.Length; j++) {
ref var path = ref paths[j];
var points = this._points;
var paths = this._paths;
for (var j = 0; j < paths.length; j++) {
ref var path = ref paths.array[j];
if (path.count <= 2) {
continue;
}

for (var i = 0; i < path.count; i++) {
ref var p0 = ref points[ip0];
ref var p1 = ref points[ip1];
ref var p0 = ref points.array[ip0];
ref var p1 = ref points.array[ip1];
p0.dx = p1.x - p0.x; // no need to normalize
p0.dy = p1.y - p0.y;
ip0 = ip1++;

ip0 = path.first + path.count - 1;
ip1 = path.first;
for (var i = 0; i < path.count; i++) {
ref var p0 = ref points[ip0];
ref var p1 = ref points[ip1];
ref var p0 = ref points.array[ip0];
ref var p1 = ref points.array[ip1];
float cross = p1.dx * p0.dy - p0.dx * p1.dy;
if (cross < 0.0f) {

}
}
this._vertices.Clear();
for (var i = 0; i < paths.Length; i++) {
ref var path = ref paths[i];
var cvertices = 0;
for (var i = 0; i < paths.length; i++) {
ref var path = ref paths.array[i];
if (path.count <= 2) {
continue;
}
cvertices += path.count;
}
this._vertices = new List<Vector3>(cvertices);
for (var i = 0; i < paths.length; i++) {
ref var path = ref paths.array[i];
if (path.count <= 2) {
continue;
}

ref var p = ref points[path.first + j];
ref var p = ref points.array[path.first + j];
this._vertices.Add(new Vector2(p.x, p.y));
}

this._expandFill();
var paths = this._paths.array();
var paths = this._paths;
for (var i = 0; i < paths.Length; i++) {
ref var path = ref paths[i];
for (var i = 0; i < paths.length; i++) {
ref var path = ref paths.array[i];
if (path.count <= 2) {
continue;
}

}
var indices = new List<int>(cindices);
for (var i = 0; i < paths.Length; i++) {
ref var path = ref paths[i];
for (var i = 0; i < paths.length; i++) {
ref var path = ref paths.array[i];
if (path.count <= 2) {
continue;
}

this._fillMesh = mesh;
this._fillConvex = false;
for (var i = 0; i < paths.Length; i++) {
ref var path = ref paths[i];
for (var i = 0; i < paths.length; i++) {
ref var path = ref paths.array[i];
if (path.count <= 2) {
continue;
}

void _calculateJoins(float w, StrokeJoin lineJoin, float miterLimit) {
float iw = w > 0.0f ? 1.0f / w : 0.0f;
var points = this._points.array();
var paths = this._paths.array();
for (var i = 0; i < paths.Length; i++) {
ref var path = ref paths[i];
var points = this._points;
var paths = this._paths;
for (var i = 0; i < paths.length; i++) {
ref var path = ref paths.array[i];
if (path.count <= 1) {
continue;
}

for (var j = 0; j < path.count; j++) {
ref var p0 = ref points[ip0];
ref var p1 = ref points[ip1];
ref var p0 = ref points.array[ip0];
ref var p1 = ref points.array[ip1];
p0.dx = p1.x - p0.x;
p0.dy = p1.y - p0.y;
p0.len = PathUtils.normalize(ref p0.dx, ref p0.dy);

ip0 = path.first + path.count - 1;
ip1 = path.first;
for (var j = 0; j < path.count; j++) {
ref var p0 = ref points[ip0];
ref var p1 = ref points[ip1];
ref var p0 = ref points.array[ip0];
ref var p1 = ref points.array[ip1];
float dlx0 = p0.dy;
float dly0 = -p0.dx;
float dlx1 = p1.dy;

ncap = PathUtils.curveDivs(w, Mathf.PI, this._tessTol);
}
this._vertices.Clear();
var points = this._points;
var paths = this._paths;
var points = this._points.array();
var paths = this._paths.array();
for (var i = 0; i < paths.Length; i++) {
ref var path = ref paths[i];
var cvertices = 0;
for (var i = 0; i < paths.length; i++) {
ref var path = ref paths.array[i];
if (path.count <= 1) {
continue;
}
cvertices += path.count * 2;
cvertices += 4;
}
this._vertices = new List<Vector3>(cvertices);
for (var i = 0; i < paths.length; i++) {
ref var path = ref paths.array[i];
if (path.count <= 1) {
continue;
}

e = path.count - 1;
}
ref var p0 = ref points[ip0];
ref var p1 = ref points[ip1];
ref var p0 = ref points.array[ip0];
ref var p1 = ref points.array[ip1];
if (!path.closed) {
if (lineCap == StrokeCap.butt) {

}
for (var j = s; j < e; j++) {
p0 = ref points[ip0];
p1 = ref points[ip1];
p0 = ref points.array[ip0];
p1 = ref points.array[ip1];
if ((p1.flags & (PointFlags.bevel | PointFlags.innerBevel)) != 0) {
if (lineJoin == StrokeJoin.round) {

}
if (!path.closed) {
p0 = ref points[ip0];
p1 = ref points[ip1];
p0 = ref points.array[ip0];
p1 = ref points.array[ip1];
if (lineCap == StrokeCap.butt) {
this._vertices.buttCapEnd(p1, p0.dx, p0.dy, w, 0.0f);
}

this._expandStroke(strokeWidth, lineCap, lineJoin, miterLimit);
var paths = this._paths.array();
var paths = this._paths;
for (var i = 0; i < paths.Length; i++) {
ref var path = ref paths[i];
for (var i = 0; i < paths.length; i++) {
ref var path = ref paths.array[i];
if (path.count <= 1) {
continue;
}

}
var indices = new List<int>(cindices);
for (var i = 0; i < paths.Length; i++) {
ref var path = ref paths[i];
for (var i = 0; i < paths.length; i++) {
ref var path = ref paths.array[i];
if (path.count <= 1) {
continue;
}

return area * 0.5f;
}
public static void polyReverse(List<PathPoint> pts, int s, int npts) {
public static void polyReverse(PathPoint[] pts, int s, int npts) {
int i = s, j = s + npts - 1;
while (i < j) {
var tmp = pts[i];

14
Runtime/ui/painting/tessellation_generator.cs


public int level;
}
static readonly Stack<_StackData> _stack = new Stack<_StackData>();
static List<Vector2> _tessellateBezier(
float x1, float y1, float x2, float y2,
float x3, float y3, float x4, float y4,

var points = new List<Vector2>();
var stack = new Stack<_StackData>();
stack.Push(new _StackData {
_stack.Clear();
_stack.Push(new _StackData {
while (stack.Count > 0) {
var stackData = stack.Pop();
while (_stack.Count > 0) {
var stackData = _stack.Pop();
x1 = stackData.x1;
y1 = stackData.y1;
x2 = stackData.x2;

float y1234 = (y123 + y234) * 0.5f;
if (level < 10) {
stack.Push(new _StackData {
_stack.Push(new _StackData {
stack.Push(new _StackData {
_stack.Push(new _StackData {
x1 = x1, y1 = y1, x2 = x12, y2 = y12, x3 = x123, y3 = y123, x4 = x1234, y4 = y1234,
level = level + 1,
});

23
Runtime/ui/painting/ArrayRef.cs


using System;
namespace Unity.UIWidgets.ui {
public class ArrayRef<T> {
public T[] array;
public int length;
public ArrayRef() {
this.array = Array.Empty<T>();
this.length = 0;
}
public void add(T item) {
if (this.length == this.array.Length) {
int newCapacity = this.array.Length == 0 ? 4 : this.array.Length * 2;
Array.Resize(ref this.array, newCapacity);
}
this.array[this.length++] = item;
}
}
}

11
Runtime/ui/painting/ArrayRef.cs.meta


fileFormatVersion: 2
guid: 58955e5dc127a42a2ab203e6d1839fd8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存