您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
231 行
6.9 KiB
231 行
6.9 KiB
using System;
|
|
using Unity.UIWidgets.foundation;
|
|
using Unity.UIWidgets.ui;
|
|
using UnityEngine;
|
|
using Canvas = Unity.UIWidgets.ui.Canvas;
|
|
using Rect = UnityEngine.Rect;
|
|
|
|
namespace Unity.UIWidgets.editor {
|
|
public delegate bool SubmitCallback(SurfaceFrame surfaceFrame, Canvas canvas);
|
|
|
|
public class SurfaceFrame : IDisposable {
|
|
bool _submitted;
|
|
|
|
readonly GrSurface _surface;
|
|
|
|
readonly SubmitCallback _submitCallback;
|
|
|
|
public SurfaceFrame(GrSurface surface, SubmitCallback submitCallback) {
|
|
this._surface = surface;
|
|
this._submitCallback = submitCallback;
|
|
}
|
|
|
|
public void Dispose() {
|
|
if (this._submitCallback != null && !this._submitted) {
|
|
this._submitCallback(this, null);
|
|
}
|
|
}
|
|
|
|
public Canvas getCanvas() {
|
|
return this._surface != null ? this._surface.getCanvas() : null;
|
|
}
|
|
|
|
public bool submit() {
|
|
if (this._submitted) {
|
|
return false;
|
|
}
|
|
|
|
this._submitted = this._performSubmit();
|
|
|
|
return this._submitted;
|
|
}
|
|
|
|
bool _performSubmit() {
|
|
if (this._submitCallback == null) {
|
|
return false;
|
|
}
|
|
|
|
if (this._submitCallback(this, this.getCanvas())) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public interface Surface : IDisposable {
|
|
SurfaceFrame acquireFrame(Size size, float devicePixelRatio, int antiAliasing);
|
|
|
|
MeshPool getMeshPool();
|
|
}
|
|
|
|
public class WindowSurfaceImpl : Surface {
|
|
static Material _guiTextureMat;
|
|
static Material _uiDefaultMat;
|
|
|
|
public delegate void DrawToTargetFunc(Rect screenRect, Texture texture, Material mat);
|
|
|
|
internal static Material _getGUITextureMat() {
|
|
if (_guiTextureMat) {
|
|
return _guiTextureMat;
|
|
}
|
|
|
|
var guiTextureShader = Shader.Find("UIWidgets/GUITexture");
|
|
if (guiTextureShader == null) {
|
|
throw new Exception("UIWidgets/GUITexture not found");
|
|
}
|
|
|
|
_guiTextureMat = new Material(guiTextureShader);
|
|
_guiTextureMat.hideFlags = HideFlags.HideAndDontSave;
|
|
return _guiTextureMat;
|
|
}
|
|
|
|
internal static Material _getUIDefaultMat() {
|
|
if (_uiDefaultMat) {
|
|
return _uiDefaultMat;
|
|
}
|
|
|
|
var uiDefaultShader = Shader.Find("UIWidgets/UIDefault");
|
|
if (uiDefaultShader == null) {
|
|
throw new Exception("UIWidgets/UIDefault not found");
|
|
}
|
|
|
|
_uiDefaultMat = new Material(uiDefaultShader);
|
|
_uiDefaultMat.hideFlags = HideFlags.HideAndDontSave;
|
|
return _uiDefaultMat;
|
|
}
|
|
|
|
|
|
GrSurface _surface;
|
|
readonly DrawToTargetFunc _drawToTargetFunc;
|
|
MeshPool _meshPool = new MeshPool();
|
|
|
|
public WindowSurfaceImpl(DrawToTargetFunc drawToTargetFunc = null) {
|
|
this._drawToTargetFunc = drawToTargetFunc;
|
|
}
|
|
|
|
public SurfaceFrame acquireFrame(Size size, float devicePixelRatio, int antiAliasing) {
|
|
this._createOrUpdateRenderTexture(size, devicePixelRatio, antiAliasing);
|
|
|
|
return new SurfaceFrame(this._surface,
|
|
(frame, canvas) => this._presentSurface(canvas));
|
|
}
|
|
|
|
public MeshPool getMeshPool() {
|
|
return this._meshPool;
|
|
}
|
|
|
|
public void Dispose() {
|
|
if (this._surface != null) {
|
|
this._surface.Dispose();
|
|
this._surface = null;
|
|
}
|
|
|
|
if (this._meshPool != null) {
|
|
this._meshPool.Dispose();
|
|
this._meshPool = null;
|
|
}
|
|
}
|
|
|
|
protected bool _presentSurface(Canvas canvas) {
|
|
if (canvas == null) {
|
|
return false;
|
|
}
|
|
|
|
this._surface.getCanvas().flush();
|
|
this._surface.getCanvas().reset();
|
|
|
|
var screenRect = new Rect(0, 0,
|
|
this._surface.size.width / this._surface.devicePixelRatio,
|
|
this._surface.size.height / this._surface.devicePixelRatio);
|
|
|
|
if (this._drawToTargetFunc == null) {
|
|
Graphics.DrawTexture(screenRect, this._surface.getRenderTexture(),
|
|
_getGUITextureMat());
|
|
}
|
|
else {
|
|
this._drawToTargetFunc(screenRect, this._surface.getRenderTexture(),
|
|
_getUIDefaultMat());
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void _createOrUpdateRenderTexture(Size size, float devicePixelRatio, int antiAliasing) {
|
|
if (this._surface != null
|
|
&& this._surface.size == size
|
|
&& this._surface.devicePixelRatio == devicePixelRatio
|
|
&& this._surface.antiAliasing == antiAliasing
|
|
&& this._surface.getRenderTexture() != null) {
|
|
return;
|
|
}
|
|
|
|
if (this._surface != null) {
|
|
this._surface.Dispose();
|
|
this._surface = null;
|
|
}
|
|
|
|
this._surface = new GrSurface(size, devicePixelRatio, antiAliasing, this._meshPool);
|
|
}
|
|
}
|
|
|
|
public class GrSurface : IDisposable {
|
|
public readonly Size size;
|
|
|
|
public readonly float devicePixelRatio;
|
|
|
|
public readonly int antiAliasing;
|
|
|
|
readonly MeshPool _meshPool;
|
|
|
|
RenderTexture _renderTexture;
|
|
|
|
CommandBufferCanvas _canvas;
|
|
|
|
public RenderTexture getRenderTexture() {
|
|
return this._renderTexture;
|
|
}
|
|
|
|
public Canvas getCanvas() {
|
|
if (this._canvas == null) {
|
|
this._canvas = new CommandBufferCanvas(
|
|
this._renderTexture, this.devicePixelRatio, this._meshPool);
|
|
}
|
|
|
|
return this._canvas;
|
|
}
|
|
|
|
public GrSurface(Size size, float devicePixelRatio, int antiAliasing, MeshPool meshPool) {
|
|
this.size = size;
|
|
this.devicePixelRatio = devicePixelRatio;
|
|
this.antiAliasing = antiAliasing;
|
|
|
|
var desc = new RenderTextureDescriptor(
|
|
(int) this.size.width, (int) this.size.height,
|
|
RenderTextureFormat.Default, 24) {
|
|
useMipMap = false,
|
|
autoGenerateMips = false,
|
|
};
|
|
|
|
if (antiAliasing != 0) {
|
|
desc.msaaSamples = antiAliasing;
|
|
}
|
|
|
|
this._renderTexture = new RenderTexture(desc);
|
|
this._renderTexture.hideFlags = HideFlags.HideAndDontSave;
|
|
|
|
this._meshPool = meshPool;
|
|
}
|
|
|
|
public void Dispose() {
|
|
if (this._renderTexture) {
|
|
this._renderTexture = ObjectUtils.SafeDestroy(this._renderTexture);
|
|
}
|
|
|
|
if (this._canvas != null) {
|
|
this._canvas.reset();
|
|
this._canvas = null;
|
|
}
|
|
}
|
|
}
|
|
}
|