浏览代码

add raster cache.

/main
kg 6 年前
当前提交
c6ad4737
共有 25 个文件被更改,包括 602 次插入177 次删除
  1. 4
      Assets/UIWidgets/Tests/CanvasAndLayers.cs
  2. 28
      Assets/UIWidgets/editor/editor_window.cs
  3. 1
      Assets/UIWidgets/flow/layer.cs
  4. 16
      Assets/UIWidgets/flow/layer_builder.cs
  5. 44
      Assets/UIWidgets/flow/picture_layer.cs
  6. 2
      Assets/UIWidgets/flow/transform_layer.cs
  7. 2
      Assets/UIWidgets/painting/decoration_image.cs
  8. 39
      Assets/UIWidgets/painting/matrix_utils.cs
  9. 2
      Assets/UIWidgets/painting/text_painter.cs
  10. 4
      Assets/UIWidgets/rendering/box.cs
  11. 2
      Assets/UIWidgets/rendering/object.cs
  12. 4
      Assets/UIWidgets/rendering/proxy_box.cs
  13. 6
      Assets/UIWidgets/rendering/viewport.cs
  14. 2
      Assets/UIWidgets/ui/compositing.cs
  15. 7
      Assets/UIWidgets/ui/geometry.cs
  16. 53
      Assets/UIWidgets/ui/painting/canvas.cs
  17. 166
      Assets/UIWidgets/ui/painting/canvas_impl.cs
  18. 9
      Assets/UIWidgets/ui/painting/draw_cmd.cs
  19. 21
      Assets/UIWidgets/ui/painting/image.cs
  20. 10
      Assets/UIWidgets/ui/painting/picture.cs
  21. 7
      Assets/UIWidgets/ui/txt/paragraph.cs
  22. 112
      Assets/UIWidgets/flow/matrix_decomposition.cs
  23. 3
      Assets/UIWidgets/flow/matrix_decomposition.cs.meta
  24. 232
      Assets/UIWidgets/flow/raster_cache.cs
  25. 3
      Assets/UIWidgets/flow/raster_cache.cs.meta

4
Assets/UIWidgets/Tests/CanvasAndLayers.cs


};
canvas.drawImageRect(
_stream.completer._currentImgae.image,
paint,
_stream.completer._currentImgae.image
paint
);
}

28
Assets/UIWidgets/editor/editor_window.cs


this._lastPosition.height * EditorGUIUtility.pixelsPerPoint);
Window.instance = this;
instance = this;
Window.instance = null;
instance = null;
this._rasterCache = new RasterCache();
}
public readonly EditorWindow editorWindow;

readonly RasterCache _rasterCache;
Rect _lastPosition;
readonly DateTime _epoch = new DateTime(Stopwatch.GetTimestamp());
readonly MicrotaskQueue _microtaskQueue = new MicrotaskQueue();

public void OnGUI() {
Window.instance = this;
instance = this;
WidgetsBinding.instance = this._binding;
try {

Window.instance = null;
instance = null;
WidgetsBinding.instance = null;
}
}

}
}
if (_textInput != null)
{
if (_textInput != null) {
_textInput.OnGUI();
}
}

public override void render(Scene scene) {
var layer = scene.takeLayer();
var prerollContext = new PrerollContext();
var prerollContext = new PrerollContext {
rasterCache = this._rasterCache
};
var paintContext = new PaintContext {canvas = new CanvasImpl()};
var paintContext = new PaintContext {
canvas = new CanvasImpl()
};
this._rasterCache.sweepAfterFrame();
}
public override void scheduleMicrotask(Action callback) {

}
}
public override TextInput textInput
{
public override TextInput textInput {
get { return _textInput; }
}
}

1
Assets/UIWidgets/flow/layer.cs


namespace UIWidgets.flow {
public class PrerollContext {
public RasterCache rasterCache;
}
public class PaintContext {

16
Assets/UIWidgets/flow/layer_builder.cs


using System.Collections.Generic;
using UIWidgets.foundation;
using UIWidgets.painting;
using UIWidgets.ui;
using Matrix4x4 = UnityEngine.Matrix4x4;

}
public void pushTransform(Matrix4x4 matrix) {
Rect cullRect = MatrixUtils.transformRect(matrix.inverse, this._cullRects.Peek());
D.assert(matrix.determinant != 0.0);
Rect cullRect = Rect.largest;
if (!matrix.isPerspective()) {
cullRect = matrix.inverse.transformRect(this._cullRects.Peek());
}
var layer = new TransformLayer();
layer.transform = matrix;

this.pushLayer(layer, cullRect);
}
var layer = new ClipRRectLayer();
layer.clipRRect = clipRRect;

this.pushLayer(layer, this._cullRects.Peek());
}
public void addPicture(Offset offset, Picture picture) {
public void addPicture(Offset offset, Picture picture, bool isComplex, bool willChange) {
if (this._currentLayer == null) {
return;
}

var layer = new PictureLayer();
layer.offset = offset;
layer.picture = picture;
layer.isComplex = isComplex;
layer.willChange = willChange;
this._currentLayer.add(layer);
}
}

44
Assets/UIWidgets/flow/picture_layer.cs


set { this._picture = value; }
}
private bool _isComplex = false;
public bool isComplex {
set { this._isComplex = value; }
}
private bool _willChange = false;
public bool willChange {
set { this._willChange = value; }
}
private RasterCacheResult _rasterCacheResult;
if (context.rasterCache != null) {
Matrix4x4 ctm = matrix;
ctm = Matrix4x4.Translate(this._offset.toVector()) * ctm;
ctm.m03 = Mathf.Round(ctm.m03);
ctm.m13 = Mathf.Round(ctm.m13);
this._rasterCacheResult = context.rasterCache.getPrerolledImage(
this._picture, ref ctm, this._isComplex, this._willChange);
} else {
this._rasterCacheResult = null;
}
var bounds = this._picture.paintBounds.shift(this._offset);
this.paintBounds = bounds;
}

if (this._offset == Offset.zero) {
canvas.drawPicture(this._picture);
return;
}
canvas.concat(Matrix4x4.Translate(this._offset.toVector()));
var matrix = canvas.getMatrix();
matrix.m03 = Mathf.Round(matrix.m03);
matrix.m13 = Mathf.Round(matrix.m13);
canvas.setMatrix(matrix);
canvas.concat(Matrix4x4.Translate(new Vector2((float) this._offset.dx, (float) this._offset.dy)));
canvas.drawPicture(this._picture);
if (this._rasterCacheResult != null) {
this._rasterCacheResult.draw(canvas);
} else {
canvas.drawPicture(this._picture);
}
}
finally {
canvas.restore();

2
Assets/UIWidgets/flow/transform_layer.cs


Rect childPaintBounds = Rect.zero;
this.prerollChildren(context, childMatrix, ref childPaintBounds);
childPaintBounds = MatrixUtils.transformRect(this._tranform, childPaintBounds);
childPaintBounds = this._tranform.transformRect(childPaintBounds);
this.paintBounds = childPaintBounds;
}

2
Assets/UIWidgets/painting/decoration_image.cs


fittedSizes.source, Offset.zero & inputSize
);
foreach (Rect tileRect in _generateImageTileRects(rect, destinationRect, repeat)) {
canvas.drawImageRect(sourceRect, tileRect, paint, image);
canvas.drawImageRect(image, tileRect, sourceRect, paint);
}
}
else {

39
Assets/UIWidgets/painting/matrix_utils.cs


namespace UIWidgets.painting {
public static class MatrixUtils {
public static Offset transformPoint(Matrix4x4 transform, Offset point) {
public static Offset transformPoint(this Matrix4x4 transform, Offset point) {
public static Rect transformRect(Matrix4x4 transform, Offset[] points, out bool isRect) {
public static Rect transformRect(this Matrix4x4 transform, Offset[] points, out bool isRect) {
var topLeft = MatrixUtils.transformPoint(transform, points[0]);
var topRight = MatrixUtils.transformPoint(transform, points[1]);
var bottomLeft = MatrixUtils.transformPoint(transform, points[2]);
var bottomRight = MatrixUtils.transformPoint(transform, points[3]);
var topLeft = transform.transformPoint(points[0]);
var topRight = transform.transformPoint(points[1]);
var bottomLeft = transform.transformPoint(points[2]);
var bottomRight = transform.transformPoint(points[3]);
isRect = topLeft.dy == topRight.dy
&& topRight.dx == bottomRight.dx

return Rect.fromLTRB(left, top, right, bottom);
}
public static Rect transformRect(Matrix4x4 transform, Rect rect, out bool isRect) {
return MatrixUtils.transformRect(transform,
public static Rect transformRect(this Matrix4x4 transform, Rect rect, out bool isRect) {
return transform.transformRect(
public static Rect transformRect(Matrix4x4 transform, Offset[] points) {
public static Rect transformRect(this Matrix4x4 transform, Offset[] points) {
return MatrixUtils.transformRect(transform, points, out isRect);
return transform.transformRect(points, out isRect);
public static Rect transformRect(Matrix4x4 transform, Rect rect) {
public static Rect transformRect(this Matrix4x4 transform, Rect rect) {
return MatrixUtils.transformRect(transform, rect, out isRect);
return transform.transformRect(rect, out isRect);
public static Rect inverseTransformRect(Matrix4x4 transform, Rect rect) {
public static Rect inverseTransformRect(this Matrix4x4 transform, Rect rect) {
D.assert(rect != null);
D.assert(transform.determinant != 0.0);

transform = transform.inverse;
return MatrixUtils.transformRect(transform, rect);
var inverse = transform.inverse;
return inverse.transformRect(rect);
public static Offset getAsTranslation(ref Matrix4x4 transform) {
public static Offset getAsTranslation(this Matrix4x4 transform) {
if (transform.m00 == 1.0 &&
transform.m10 == 0.0 &&
transform.m20 == 0.0 &&

transform.m33 == 1.0) {
return new Offset(transform.m03, transform.m13);
}
}
public static bool isPerspective(this Matrix4x4 transform) {
return transform[3, 0] != 0 || transform[3, 1] != 0 || transform[3, 2] != 0 || transform[3, 3] != 1;
}
}
}

2
Assets/UIWidgets/painting/text_painter.cs


public void paint(Canvas canvas, Offset offset)
{
Debug.Assert(!_needsLayout);
_paragraph.paint(canvas, offset.dx, offset.dy);
_paragraph.paint(canvas, offset);
}
public Offset getOffsetForCaret(TextPosition position, Rect caretPrototype)

4
Assets/UIWidgets/rendering/box.cs


}
transform = transform.inverse;
return MatrixUtils.transformPoint(transform, point);
return transform.transformPoint(point);
return MatrixUtils.transformPoint(this.getTransformTo(ancestor), point);
return this.getTransformTo(ancestor).transformPoint(point);
}
public override Rect paintBounds {

2
Assets/UIWidgets/rendering/object.cs


new TransformLayer(effectiveTransform),
painter,
offset,
childPaintBounds: MatrixUtils.inverseTransformRect(effectiveTransform, this.estimatedBounds)
childPaintBounds: effectiveTransform.inverseTransformRect(this.estimatedBounds)
);
} else {
this.canvas.save();

4
Assets/UIWidgets/rendering/proxy_box.cs


return false;
}
position = MatrixUtils.transformPoint(transform.inverse, position);
position = transform.inverse.transformPoint(position);
}
return base.hitTestChildren(result, position: position);

if (this.child != null) {
var transform = this._effectiveTransform;
Offset childOffset = MatrixUtils.getAsTranslation(ref transform);
Offset childOffset = transform.getAsTranslation();
if (childOffset == null) {
context.pushTransform(this.needsCompositing, offset, transform, base.paint);
} else {

6
Assets/UIWidgets/rendering/viewport.cs


RenderSliver pivotParent = (RenderSliver) pivot.parent;
transform = targetBox.getTransformTo(pivot);
Rect bounds = MatrixUtils.transformRect(transform, rect);
Rect bounds = transform.transformRect(rect);
double offset = 0.0;

transform = target.getTransformTo(this);
this.applyPaintTransform(child, ref transform);
Rect targetRect = MatrixUtils.transformRect(transform, rect);
Rect targetRect = transform.transformRect(rect);
switch (this.axisDirection) {
case AxisDirection.down:

targetOffset = trailingEdgeOffset;
} else {
var transform = descendant.getTransformTo(viewport.parent);
return MatrixUtils.transformRect(transform, rect ?? descendant.paintBounds);
return transform.transformRect(rect ?? descendant.paintBounds);
}
D.assert(targetOffset != null);

2
Assets/UIWidgets/ui/compositing.cs


public void addPicture(Offset offset, Picture picture,
bool isComplexHint = false, bool willChangeHint = false) {
this._layerBuilder.addPicture(offset, picture);
this._layerBuilder.addPicture(offset, picture, isComplexHint, willChangeHint);
}
public Scene build() {

7
Assets/UIWidgets/ui/geometry.cs


return true;
}
public double shortestSide {
get { return Math.Min(Math.Abs(this.width), Math.Abs(this.height)); }
}

public bool contains(Rect rect) {
return this.contains(rect.topLeft) && this.contains(rect.bottomRight);
}
public Rect roundOut() {
return Rect.fromLTRB(
Math.Floor(this.left), Math.Floor(this.top),
Math.Ceiling(this.right), Math.Ceiling(this.bottom));
}
public static Rect lerp(Rect a, Rect b, double t) {

53
Assets/UIWidgets/ui/painting/canvas.cs


using UIWidgets.painting;
using System;
using UIWidgets.foundation;
using UIWidgets.painting;
void drawPloygon4(Offset[] points, Paint paint);
void drawPloygon4(Offset[] points, Paint paint = null);
void drawRect(Rect rect, BorderWidth borderWidth, BorderRadius borderRadius, Paint paint);
void drawRect(Rect rect, BorderWidth borderWidth = null, BorderRadius borderRadius = null, Paint paint = null);
void drawRectShadow(Rect rect, Paint paint);
void drawRectShadow(Rect rect, Paint paint = null);
void drawImageRect(Rect src, Rect dst, Paint paint, Image image);
void drawImageRect(Image image, Rect dest, Rect src = null, Paint paint = null);
void drawLine(Offset from, Offset to, Paint paint);
void drawLine(Offset from, Offset to, Paint paint = null);
void setMatrix(Matrix4x4 matrix);
Matrix4x4 getMatrix();
void saveLayer(Rect rect, Paint paint);
void saveLayer(Rect rect, Paint paint = null);
void restore();

void clipRRect(RRect rrect, bool doAntiAlias = true);
void drawTextBlob(TextBlob textBlob, double x, double y);
void drawTextBlob(TextBlob textBlob, Offset offset);
}
public class RecorderCanvas : Canvas {

readonly PictureRecorder _recorder;
int _saveCount = 1;
public void drawPloygon4(Offset[] points, Paint paint) {

});
}
public void drawImageRect(Rect src, Rect dst, Paint paint, Image image) {
public void drawImageRect(Image image, Rect dest, Rect src, Paint paint) {
paint = paint,
dest = dest,
dst = dst,
paint = paint,
public void drawLine(Offset from, Offset to, Paint paint)
{
this._recorder.addDrawCmd(new DrawLine
{
public void drawLine(Offset from, Offset to, Paint paint) {
this._recorder.addDrawCmd(new DrawLine {
from = from,
to = to,
paint = paint,

this._recorder.addDrawCmd(new DrawConcat {
transform = transform,
});
}
public void setMatrix(Matrix4x4 matrix) {
this._recorder.addDrawCmd(new DrawSetMatrix {
matrix = matrix,
});
}
public Matrix4x4 getMatrix() {
throw new Exception("not available in recorder");
}
public void save() {

});
}
public void drawTextBlob(TextBlob textBlob, double x, double y) {
this._recorder.addDrawCmd(new DrawTextBlob() {
public void drawTextBlob(TextBlob textBlob, Offset offset) {
this._recorder.addDrawCmd(new DrawTextBlob {
x = x,
y = y,
offset = offset
});
}
}

166
Assets/UIWidgets/ui/painting/canvas_impl.cs


using System;
using System.Collections.Generic;
using UIWidgets.foundation;
using UIWidgets.painting;
using UIWidgets.ui.painting.txt;
using UIWidgets.ui.txt;

throw new Exception("UIWidgets/2D Handles Lines not found");
}
CanvasImpl.linesMat = new Material(shader);
CanvasImpl.linesMat.hideFlags = HideFlags.HideAndDontSave;
linesMat = new Material(shader);
linesMat.hideFlags = HideFlags.HideAndDontSave;
shader = Shader.Find("UIWidgets/GUIRoundedRect");
if (shader == null) {

CanvasImpl.guiRoundedRectMat = new Material(shader);
CanvasImpl.guiRoundedRectMat.hideFlags = HideFlags.HideAndDontSave;
guiRoundedRectMat = new Material(shader);
guiRoundedRectMat.hideFlags = HideFlags.HideAndDontSave;
shader = Shader.Find("UIWidgets/GUITextureClip");
if (shader == null) {

CanvasImpl.guiTextureClipMat = new Material(shader);
CanvasImpl.guiTextureClipMat.hideFlags = HideFlags.HideAndDontSave;
guiTextureClipMat = new Material(shader);
guiTextureClipMat.hideFlags = HideFlags.HideAndDontSave;
shader = Shader.Find("UIWidgets/ShadowRect");
if (shader == null) {

CanvasImpl.shadowRectMat = new Material(shader);
CanvasImpl.shadowRectMat.hideFlags = HideFlags.HideAndDontSave;
shadowRectMat = new Material(shader);
shadowRectMat.hideFlags = HideFlags.HideAndDontSave;
}
private static readonly Material linesMat;

verts[i] = points[i].toVector();
}
this.prepareGL(CanvasImpl.linesMat);
CanvasImpl.linesMat.SetPass(0);
this.prepareGL(linesMat);
linesMat.SetPass(0);
GL.Begin(GL.TRIANGLES);
GL.Color(color.toColor());

}
public void drawRect(Rect rect, BorderWidth borderWidth, BorderRadius borderRadius, Paint paint) {
this.prepareGL(CanvasImpl.guiRoundedRectMat);
this.prepareGL(guiRoundedRectMat);
CanvasImpl.guiRoundedRectMat.SetFloatArray("UIWidgets_BorderWidth",
guiRoundedRectMat.SetFloatArray("UIWidgets_BorderWidth",
CanvasImpl.guiRoundedRectMat.SetFloatArray("UIWidgets_CornerRadius",
guiRoundedRectMat.SetFloatArray("UIWidgets_CornerRadius",
paint.color.toColor(), CanvasImpl.guiRoundedRectMat);
paint.color.toColor(), guiRoundedRectMat);
this.prepareGL(CanvasImpl.shadowRectMat);
this.prepareGL(shadowRectMat);
CanvasImpl.shadowRectMat.SetFloat("UIWidgets_sigma", (float) paint.blurSigma);
shadowRectMat.SetFloat("UIWidgets_sigma", (float) paint.blurSigma);
paint.color.toColor(), CanvasImpl.shadowRectMat);
paint.color.toColor(), shadowRectMat);
}
public void drawPicture(Picture picture) {

if (drawCmd is DrawPloygon4) {
var drawPloygon4 = (DrawPloygon4) drawCmd;
this.drawPloygon4(drawPloygon4.points, drawPloygon4.paint);
}
else if (drawCmd is DrawRect) {
} else if (drawCmd is DrawRect) {
} else if (drawCmd is DrawLine)
{
} else if (drawCmd is DrawLine) {
}
else if (drawCmd is DrawRectShadow) {
} else if (drawCmd is DrawRectShadow) {
}
else if (drawCmd is DrawPicture) {
} else if (drawCmd is DrawPicture) {
}
else if (drawCmd is DrawConcat) {
this.concat(((DrawConcat) drawCmd).transform);
}
else if (drawCmd is DrawSave) {
} else if (drawCmd is DrawConcat) {
var drawConcat = (DrawConcat) drawCmd;
this.concat(drawConcat.transform);
} else if (drawCmd is DrawSetMatrix) {
var drawSetMatrix = (DrawSetMatrix) drawCmd;
this.setMatrix(drawSetMatrix.matrix);
} else if (drawCmd is DrawSave) {
}
else if (drawCmd is DrawSaveLayer) {
} else if (drawCmd is DrawSaveLayer) {
}
else if (drawCmd is DrawRestore) {
} else if (drawCmd is DrawRestore) {
saveCount--;
if (saveCount < 0) {
throw new Exception("unmatched save/restore in picture");

}
else if (drawCmd is DrawClipRect) {
} else if (drawCmd is DrawClipRect) {
}
else if (drawCmd is DrawClipRRect) {
} else if (drawCmd is DrawClipRRect) {
this.drawTextBlob(drawTextBlob.textBlob, drawTextBlob.x, drawTextBlob.y);
this.drawTextBlob(drawTextBlob.textBlob, drawTextBlob.offset);
var drawImageProperties = (DrawImageRect) drawCmd;
this.drawImageRect(drawImageProperties.src, drawImageProperties.dst, drawImageProperties.paint, drawImageProperties.image);
}
else {
var drawImageRect = (DrawImageRect) drawCmd;
this.drawImageRect(drawImageRect.image, drawImageRect.dest, drawImageRect.src, drawImageRect.paint);
} else {
throw new Exception("unknown drawCmd: " + drawCmd);
}
}

this.restore();
}
public void drawImageRect(Rect src, Rect dst, Paint paint, Image image) {
if (image != null && image.texture != null) {
public void drawImageRect(Image image, Rect dest, Rect src = null, Paint paint = null) {
D.assert(image != null);
D.assert(dest != null);
if (image.texture != null) {
var srcRect = new UnityEngine.Rect(
(float) (src.left / textureWidth),
(float) ((textureHeight - src.bottom) / textureHeight),
(float) (src.width / textureWidth),
(float) (src.height / textureHeight)
);
Graphics.DrawTexture(dst.toRect(), image.texture, srcRect, 0, 0 ,0 ,0);
var srcRect = src == null
? new UnityEngine.Rect(0, 0, 1, 1)
: new UnityEngine.Rect(
(float) (src.left / textureWidth),
(float) ((textureHeight - src.bottom) / textureHeight),
(float) (src.width / textureWidth),
(float) (src.height / textureHeight)
);
this.prepareGL(guiTextureClipMat);
Graphics.DrawTexture(dest.toRect(), image.texture,
srcRect, 0, 0, 0, 0,
paint != null && paint.color != null ? paint.color.toColor() : UnityEngine.Color.white,
guiTextureClipMat);
public void drawLine(Offset from, Offset to, Paint paint)
{
public void drawLine(Offset from, Offset to, Paint paint) {
if (color.alpha > 0 && distance > 0)
{
if (color.alpha > 0 && distance > 0) {
this.prepareGL(CanvasImpl.linesMat);
CanvasImpl.linesMat.SetPass(0);
var points = new[]
{
this.prepareGL(linesMat);
linesMat.SetPass(0);
var points = new[] {
(from + diff).toVector(),
(from - diff).toVector(),
(to - diff).toVector(),

GL.Color(color.toColor());
for (int i = 0; i < points.Length; ++i)
{
for (int i = 0; i < points.Length; ++i) {
GL.End();
}
}

}
public void setMatrix(Matrix4x4 matrix) {
this._transform = matrix;
}
public Matrix4x4 getMatrix() {
return this._transform;
}
public void save() {
var state = new CanvasRec {
transform = this._transform,

public void saveLayer(Rect bounds, Paint paint) {
this.save();
var textureWidth = (int) Math.Round(bounds.width * EditorGUIUtility.pixelsPerPoint);
var textureHeight = (int) Math.Round(bounds.height * EditorGUIUtility.pixelsPerPoint);
bounds = bounds.roundOut();
var textureWidth = (int) Math.Ceiling(bounds.width * EditorGUIUtility.pixelsPerPoint);
var textureHeight = (int) Math.Ceiling(bounds.height * EditorGUIUtility.pixelsPerPoint);
var texture = RenderTexture.GetTemporary(
textureWidth, textureHeight, 32,

GL.PopMatrix();
this.prepareGL(CanvasImpl.guiTextureClipMat);
this.prepareGL(guiTextureClipMat);
layerRec.paint.color.toColor(), CanvasImpl.guiTextureClipMat);
layerRec.paint.color.toColor(), guiTextureClipMat);
RenderTexture.ReleaseTemporary(layerRec.texture);
layerRec.texture = null;

this.pushClipRRect(rect, this._transform);
}
public void drawTextBlob(TextBlob textBlob, double x, double y)
{
var mesh = MeshGenrator.generateMesh(textBlob, x, y);
public void drawTextBlob(TextBlob textBlob, Offset offset) {
var mesh = MeshGenrator.generateMesh(textBlob, offset.dx, offset.dy);
if (Camera.current != null) // draw mesh will use camera matrix, set to identity before draw mesh
if (Camera.current != null) // draw mesh will use camera matrix, set to identity before draw mesh
{
cameraMat = Camera.current.worldToCameraMatrix;
Camera.current.worldToCameraMatrix = Matrix4x4.identity;

if (Camera.current != null)
{
if (Camera.current != null) {
Camera.current.worldToCameraMatrix = cameraMat;
Camera.current.ResetWorldToCameraMatrix();
}

(float) rect.width,
(float) rect.height));
mat.SetVector("UIWidgets_GUIClipRectRadius", new Vector4(0, 0, 0, 0));
}
else {
} else {
var rrect = this._clipRec.rrect;
var rect = rrect.outerRect;
mat.SetVector("UIWidgets_GUIClipRect", new Vector4(

(float) rrect.brRadius,
(float) rrect.blRadius));
}
}
else {
} else {
mat.SetMatrix("UIWidgets_GUIClipMatrix", Matrix4x4.identity);
var rect = Rect.largest;
mat.SetVector("UIWidgets_GUIClipRect", new Vector4(

9
Assets/UIWidgets/ui/painting/draw_cmd.cs


public Paint paint;
public Image image;
public Rect src;
public Rect dst;
public Rect dest;
}
public class DrawSetMatrix : DrawCmd {
public Matrix4x4 matrix;
}
public class DrawSave : DrawCmd {

public class DrawTextBlob : DrawCmd
{
public TextBlob textBlob;
public double x;
public double y;
public Offset offset;
}
public class DrawLine : DrawCmd

21
Assets/UIWidgets/ui/painting/image.cs


using UnityEngine;
namespace UIWidgets.ui
{
public class Image
{
public Image(byte[] raw) {
rawData = raw;
namespace UIWidgets.ui {
public class Image {
public Image(byte[] raw = null, Texture2D texture = null) {
this.rawData = raw ?? new byte[0];
this._texture = texture;
get {
return texture != null ? texture.height : 0;
}
get { return texture != null ? texture.height : 0; }
get {
return texture != null ? texture.width : 0;
}
get { return texture != null ? texture.width : 0; }
}
public Texture2D texture {

return _texture;
}
}
private Texture2D _texture;
}

10
Assets/UIWidgets/ui/painting/picture.cs


} else if (drawCmd is DrawTextBlob)
{
var drawTextBlob = (DrawTextBlob) drawCmd;
var bounds = drawTextBlob.textBlob.boundsInText.shift(new Offset(drawTextBlob.x, drawTextBlob.y));
var bounds = drawTextBlob.textBlob.boundsInText.shift(drawTextBlob.offset);
this.addPaintBounds(drawImageRect.src);
this.addPaintBounds(drawImageRect.dest);
} else {
throw new Exception("unknown drawCmd: " + drawCmd);
}

throw new Exception("already a clipRec, considering using saveLayer.");
}
this._clipRect = MatrixUtils.transformRect(this._transform, rect);
this._clipRect = this._transform.transformRect(rect);
}
private void addPaintBounds(Rect paintBounds) {

paintBounds = MatrixUtils.transformRect(this._transform, paintBounds);
paintBounds = this._transform.transformRect(paintBounds);
if (this._clipRect != null) {
paintBounds = paintBounds.intersect(this._clipRect);
}

}
private void addPaintBounds(Offset[] points) {
var paintBounds = MatrixUtils.transformRect(this._transform, points);
var paintBounds = this._transform.transformRect(points);
if (this._clipRect != null) {
paintBounds = paintBounds.intersect(this._clipRect);
}

7
Assets/UIWidgets/ui/txt/paragraph.cs


get { return _didExceedMaxLines; }
}
public void paint(Canvas canvas, double x, double y)
public void paint(Canvas canvas, Offset offset)
var baseOffset = new Offset(x, y);
canvas.drawTextBlob(paintRecord.text, x, y);
paintDecorations(canvas, paintRecord, baseOffset);
canvas.drawTextBlob(paintRecord.text, offset);
paintDecorations(canvas, paintRecord, offset);
}
}

112
Assets/UIWidgets/flow/matrix_decomposition.cs


using UnityEngine;
namespace UIWidgets.flow {
public class MatrixDecomposition {
public MatrixDecomposition(Matrix4x4 matrix) {
if (matrix[3, 3] == 0) {
return;
}
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
matrix[j, i] /= matrix[3, 3];
}
}
Matrix4x4 perpectiveMatrix = matrix;
for (int i = 0; i < 3; i++) {
perpectiveMatrix[3, i] = 0;
}
perpectiveMatrix[3, 3] = 1;
if (perpectiveMatrix.determinant == 0) {
return;
}
if (matrix[3, 0] != 0 || matrix[3, 1] != 0 || matrix[3, 2] != 0) {
Vector4 rightHandSide = new Vector4(matrix[3, 0], matrix[3, 1], matrix[3, 2], matrix[3, 3]);
this.perspective = perpectiveMatrix.inverse.transpose * rightHandSide;
matrix[3, 0] = 0;
matrix[3, 1] = 0;
matrix[3, 2] = 0;
matrix[3, 3] = 1;
}
this.translation = new Vector3(matrix[0, 3], matrix[1, 3], matrix[2, 3]);
matrix[0, 3] = 0;
matrix[1, 3] = 0;
matrix[2, 3] = 0;
Vector3[] row = new Vector3[3];
for (int i = 0; i < 3; i++) {
row[i] = matrix.GetRow(i);
}
this.scale.x = row[0].magnitude;
row[0] = row[0].normalized;
this.shear.x = Vector3.Dot(row[0], row[1]);
row[1] += row[0] * -this.shear.x;
this.scale.y = row[1].magnitude;
row[1] = row[1].normalized;
this.shear.x /= this.scale.y;
this.shear.y = Vector3.Dot(row[0], row[2]);
row[2] += row[0] * -this.shear.y;
this.shear.z = Vector3.Dot(row[1], row[2]);
row[2] += row[1] * -this.shear.z;
this.scale.z = row[2].magnitude;
row[2] = row[2].normalized;
this.shear.y /= this.scale.z;
this.shear.z /= this.scale.z;
if (Vector3.Dot(row[0], Vector3.Cross(row[1], row[2])) < 0) {
this.scale.x *= -1;
this.scale.y *= -1;
this.scale.z *= -1;
for (int i = 0; i < 3; i++) {
row[i].x *= -1;
row[i].y *= -1;
row[i].z *= -1;
}
}
this.rotation = new Vector4(
0.5f * Mathf.Sqrt(Mathf.Max(1.0f + row[0].x - row[1].y - row[2].z, 0.0f)),
0.5f * Mathf.Sqrt(Mathf.Max(1.0f - row[0].x + row[1].y - row[2].z, 0.0f)),
0.5f * Mathf.Sqrt(Mathf.Max(1.0f - row[0].x - row[1].y + row[2].z, 0.0f)),
0.5f * Mathf.Sqrt(Mathf.Max(1.0f + row[0].x + row[1].y + row[2].z, 0.0f)));
if (row[2].y > row[1].z) {
this.rotation.x = -this.rotation.x;
}
if (row[0].z > row[2].x) {
this.rotation.y = -this.rotation.y;
}
if (row[1].x > row[0].y) {
this.rotation.z = -this.rotation.z;
}
this.valid = true;
}
public readonly bool valid;
public readonly Vector3 translation;
public readonly Vector3 scale;
public readonly Vector3 shear;
public readonly Vector4 perspective;
public readonly Vector4 rotation;
}
}

3
Assets/UIWidgets/flow/matrix_decomposition.cs.meta


fileFormatVersion: 2
guid: 215bc2db9a324b0d8a2980dade2db267
timeCreated: 1538271597

232
Assets/UIWidgets/flow/raster_cache.cs


using System;
using System.Collections.Generic;
using UIWidgets.foundation;
using UIWidgets.painting;
using UIWidgets.ui;
using UnityEditor;
using UnityEngine;
using Canvas = UIWidgets.ui.Canvas;
using Rect = UIWidgets.ui.Rect;
namespace UIWidgets.flow {
public class RasterCacheResult {
public RasterCacheResult(Image image, Rect bounds) {
D.assert(image != null);
D.assert(bounds != null);
this.image = image;
this.bounds = bounds;
}
public readonly Image image;
public readonly Rect bounds;
public void draw(Canvas canvas) {
var bounds = canvas.getMatrix().transformRect(this.bounds).roundOut();
D.assert(() => {
var textureWidth = (int) Math.Ceiling(
bounds.width * EditorGUIUtility.pixelsPerPoint); // todo: use window.pixelsPerPoint;
var textureHeight = (int) Math.Ceiling(
bounds.height * EditorGUIUtility.pixelsPerPoint);
D.assert(this.image.width == textureWidth);
D.assert(this.image.height == textureHeight);
return true;
});
canvas.save();
try {
canvas.setMatrix(Matrix4x4.identity);
canvas.drawImageRect(this.image, bounds);
}
finally {
canvas.restore();
}
}
}
class _RasterCacheKey : IEquatable<_RasterCacheKey> {
internal _RasterCacheKey(Picture picture, ref Matrix4x4 matrix) {
D.assert(picture != null);
this.picture = picture;
this.matrix = matrix;
this.matrix.m03 = this.matrix.m03 - (int) this.matrix.m03; // x
this.matrix.m13 = this.matrix.m13 - (int) this.matrix.m13; // y
D.assert(this.matrix.m03 == 0);
D.assert(this.matrix.m13 == 0);
}
public readonly Picture picture;
public readonly Matrix4x4 matrix;
public bool Equals(_RasterCacheKey other) {
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return this.picture.Equals(other.picture) && this.matrix.Equals(other.matrix);
}
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((_RasterCacheKey) obj);
}
public override int GetHashCode() {
unchecked {
return (this.picture.GetHashCode() * 397) ^ this.matrix.GetHashCode();
}
}
public static bool operator ==(_RasterCacheKey left, _RasterCacheKey right) {
return Equals(left, right);
}
public static bool operator !=(_RasterCacheKey left, _RasterCacheKey right) {
return !Equals(left, right);
}
}
class _RasterCacheEntry {
public bool usedThisFrame = false;
public int accessCount = 0;
public RasterCacheResult image;
}
public class RasterCache {
public RasterCache(int threshold = 3) {
this.threshold = threshold;
this._cache = new Dictionary<_RasterCacheKey, _RasterCacheEntry>();
}
public readonly int threshold;
readonly Dictionary<_RasterCacheKey, _RasterCacheEntry> _cache;
public RasterCacheResult getPrerolledImage(
Picture picture, ref Matrix4x4 transform, bool isComplex, bool willChange) {
if (this.threshold == 0) {
return null;
}
if (!_isPictureWorthRasterizing(picture, isComplex, willChange)) {
return null;
}
if (transform.m33 == 0 || transform.determinant == 0) {
return null;
}
_RasterCacheKey cacheKey = new _RasterCacheKey(picture, ref transform);
var entry = this._cache.putIfAbsent(cacheKey, () => new _RasterCacheEntry());
entry.accessCount = (entry.accessCount + 1).clamp(0, this.threshold);
entry.usedThisFrame = true;
if (entry.accessCount < this.threshold) {
return null;
}
if (entry.image == null) {
entry.image = this._rasterizePicture(picture, ref transform);
}
return entry.image;
}
static bool _isPictureWorthRasterizing(Picture picture,
bool isComplex, bool willChange) {
if (willChange) {
return false;
}
if (!_canRasterizePicture(picture)) {
return false;
}
if (isComplex) {
return true;
}
return picture.drawCmds.Count > 10;
}
static bool _canRasterizePicture(Picture picture) {
if (picture == null) {
return false;
}
var bounds = picture.paintBounds;
if (bounds.isEmpty) {
return false;
}
if (!bounds.isFinite) {
return false;
}
return true;
}
RasterCacheResult _rasterizePicture(Picture picture, ref Matrix4x4 transform) {
var bounds = transform.transformRect(picture.paintBounds).roundOut();
var textureWidth = (int) Math.Ceiling(
bounds.width * EditorGUIUtility.pixelsPerPoint); // todo: use window.pixelsPerPoint;
var textureHeight = (int) Math.Ceiling(
bounds.height * EditorGUIUtility.pixelsPerPoint);
var texture = RenderTexture.GetTemporary(
textureWidth, textureHeight, 32,
RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB);
var oldTexture = RenderTexture.active;
RenderTexture.active = texture;
GL.PushMatrix();
GL.LoadPixelMatrix((float) bounds.left, (float) bounds.right, (float) bounds.bottom, (float) bounds.top);
GL.Clear(true, true, new UnityEngine.Color(0, 0, 0, 0));
try {
var canvas = new CanvasImpl();
canvas.concat(transform);
canvas.drawPicture(picture);
Texture2D tex = new Texture2D(textureWidth, textureHeight, TextureFormat.ARGB32, false);
tex.ReadPixels(new UnityEngine.Rect(0, 0, textureWidth, textureHeight), 0, 0, false);
tex.Apply();
return new RasterCacheResult(new Image(texture: tex), picture.paintBounds);
}
finally {
GL.PopMatrix();
RenderTexture.active = oldTexture;
RenderTexture.ReleaseTemporary(texture);
}
}
public void sweepAfterFrame() {
var dead = new List<KeyValuePair<_RasterCacheKey, _RasterCacheEntry>>();
foreach (var entry in this._cache) {
if (!entry.Value.usedThisFrame) {
dead.Add(entry);
} else {
entry.Value.usedThisFrame = false;
}
}
foreach (var entry in dead) {
this._cache.Remove(entry.Key);
}
}
public void clear() {
this._cache.Clear();
}
}
}

3
Assets/UIWidgets/flow/raster_cache.cs.meta


fileFormatVersion: 2
guid: b65b634b39ec47fe9ae136d615b198c0
timeCreated: 1538204893
正在加载...
取消
保存