committed by
GitHub
46 changed files with 481 additions and 366 deletions
@ -0,0 +1,6 @@ |
|||||
|
// Copyright (c) The Avalonia Project. All rights reserved.
|
||||
|
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
||||
|
|
||||
|
using Avalonia.Metadata; |
||||
|
|
||||
|
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Layout")] |
||||
@ -0,0 +1,23 @@ |
|||||
|
using System; |
||||
|
using System.Reactive.Disposables; |
||||
|
using Avalonia.Native.Interop; |
||||
|
using Avalonia.Rendering; |
||||
|
|
||||
|
namespace Avalonia.Native |
||||
|
{ |
||||
|
public class AvaloniaNativeDeferredRendererLock : IDeferredRendererLock |
||||
|
{ |
||||
|
private readonly IAvnWindowBase _window; |
||||
|
|
||||
|
public AvaloniaNativeDeferredRendererLock(IAvnWindowBase window) |
||||
|
{ |
||||
|
_window = window; |
||||
|
} |
||||
|
public IDisposable TryLock() |
||||
|
{ |
||||
|
if (_window.TryLock()) |
||||
|
return Disposable.Create(() => _window.Unlock()); |
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,108 +0,0 @@ |
|||||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|
||||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|
||||
|
|
||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using Avalonia.Native.Interop; |
|
||||
using Avalonia.Rendering; |
|
||||
using Avalonia.VisualTree; |
|
||||
|
|
||||
namespace Avalonia.Native |
|
||||
{ |
|
||||
public class DeferredRendererProxy : IRenderer, IRenderLoopTask, IRenderLoop |
|
||||
{ |
|
||||
public DeferredRendererProxy(IRenderRoot root, IAvnWindowBase window) |
|
||||
{ |
|
||||
if (window != null) |
|
||||
{ |
|
||||
_useLock = true; |
|
||||
window.AddRef(); |
|
||||
_window = new IAvnWindowBase(window.NativePointer); |
|
||||
} |
|
||||
_renderer = new DeferredRenderer(root, this); |
|
||||
_rendererTask = (IRenderLoopTask)_renderer; |
|
||||
} |
|
||||
|
|
||||
void IRenderLoop.Add(IRenderLoopTask i) |
|
||||
{ |
|
||||
AvaloniaLocator.Current.GetService<IRenderLoop>().Add(this); |
|
||||
} |
|
||||
|
|
||||
void IRenderLoop.Remove(IRenderLoopTask i) |
|
||||
{ |
|
||||
AvaloniaLocator.Current.GetService<IRenderLoop>().Remove(this); |
|
||||
} |
|
||||
|
|
||||
private DeferredRenderer _renderer; |
|
||||
private IRenderLoopTask _rendererTask; |
|
||||
private IAvnWindowBase _window; |
|
||||
private bool _useLock; |
|
||||
|
|
||||
public bool DrawFps{ |
|
||||
get => _renderer.DrawFps; |
|
||||
set => _renderer.DrawFps = value; |
|
||||
} |
|
||||
public bool DrawDirtyRects |
|
||||
{ |
|
||||
get => _renderer.DrawDirtyRects; |
|
||||
set => _renderer.DrawDirtyRects = value; |
|
||||
} |
|
||||
|
|
||||
public bool NeedsUpdate => _rendererTask.NeedsUpdate; |
|
||||
|
|
||||
public void AddDirty(IVisual visual) => _renderer.AddDirty(visual); |
|
||||
|
|
||||
public void Dispose() |
|
||||
{ |
|
||||
_renderer.Dispose(); |
|
||||
_window?.Dispose(); |
|
||||
_window = null; |
|
||||
} |
|
||||
public IEnumerable<IVisual> HitTest(Point p, IVisual root, Func<IVisual, bool> filter) |
|
||||
{ |
|
||||
return _renderer.HitTest(p, root, filter); |
|
||||
} |
|
||||
|
|
||||
public void Paint(Rect rect) |
|
||||
{ |
|
||||
if (NeedsUpdate) |
|
||||
{ |
|
||||
Update(TimeSpan.FromMilliseconds(Environment.TickCount)); |
|
||||
} |
|
||||
|
|
||||
Render(); |
|
||||
} |
|
||||
|
|
||||
public void Resized(Size size) => _renderer.Resized(size); |
|
||||
|
|
||||
public void Start() => _renderer.Start(); |
|
||||
|
|
||||
public void Stop() => _renderer.Stop(); |
|
||||
|
|
||||
public void Update(TimeSpan time) |
|
||||
{ |
|
||||
_rendererTask.Update(time); |
|
||||
} |
|
||||
|
|
||||
public void Render() |
|
||||
{ |
|
||||
if(_useLock) |
|
||||
{ |
|
||||
_rendererTask.Render(); |
|
||||
return; |
|
||||
} |
|
||||
if (_window == null) |
|
||||
return; |
|
||||
if (!_window.TryLock()) |
|
||||
return; |
|
||||
try |
|
||||
{ |
|
||||
_rendererTask.Render(); |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
_window.Unlock(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,44 @@ |
|||||
|
using System; |
||||
|
using System.Reactive.Disposables; |
||||
|
using System.Threading; |
||||
|
|
||||
|
namespace Avalonia.OpenGL |
||||
|
{ |
||||
|
public class EglContext : IGlContext |
||||
|
{ |
||||
|
private readonly EglDisplay _disp; |
||||
|
private readonly EglInterface _egl; |
||||
|
private readonly object _lock = new object(); |
||||
|
|
||||
|
public EglContext(EglDisplay display, EglInterface egl, IntPtr ctx, IntPtr offscreenSurface) |
||||
|
{ |
||||
|
_disp = display; |
||||
|
_egl = egl; |
||||
|
Context = ctx; |
||||
|
OffscreenSurface = offscreenSurface; |
||||
|
} |
||||
|
|
||||
|
public IntPtr Context { get; } |
||||
|
public IntPtr OffscreenSurface { get; } |
||||
|
public IGlDisplay Display => _disp; |
||||
|
|
||||
|
public IDisposable Lock() |
||||
|
{ |
||||
|
Monitor.Enter(_lock); |
||||
|
return Disposable.Create(() => Monitor.Exit(_lock)); |
||||
|
} |
||||
|
|
||||
|
public void MakeCurrent() |
||||
|
{ |
||||
|
if (!_egl.MakeCurrent(_disp.Handle, IntPtr.Zero, IntPtr.Zero, Context)) |
||||
|
throw new OpenGlException("eglMakeCurrent failed"); |
||||
|
} |
||||
|
|
||||
|
public void MakeCurrent(EglSurface surface) |
||||
|
{ |
||||
|
var surf = ((EglSurface)surface)?.DangerousGetHandle() ?? OffscreenSurface; |
||||
|
if (!_egl.MakeCurrent(_disp.Handle, surf, surf, Context)) |
||||
|
throw new OpenGlException("eglMakeCurrent failed"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,28 @@ |
|||||
|
using System; |
||||
|
using System.Runtime.InteropServices; |
||||
|
|
||||
|
namespace Avalonia.OpenGL |
||||
|
{ |
||||
|
public class EglSurface : SafeHandle |
||||
|
{ |
||||
|
private readonly EglDisplay _display; |
||||
|
private readonly EglInterface _egl; |
||||
|
|
||||
|
public EglSurface(EglDisplay display, EglInterface egl, IntPtr surface) : base(surface, true) |
||||
|
{ |
||||
|
_display = display; |
||||
|
_egl = egl; |
||||
|
} |
||||
|
|
||||
|
protected override bool ReleaseHandle() |
||||
|
{ |
||||
|
_egl.DestroySurface(_display.Handle, handle); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
public override bool IsInvalid => handle == IntPtr.Zero; |
||||
|
|
||||
|
public IGlDisplay Display => _display; |
||||
|
public void SwapBuffers() => _egl.SwapBuffers(_display.Handle, handle); |
||||
|
} |
||||
|
} |
||||
@ -1,10 +0,0 @@ |
|||||
using System; |
|
||||
|
|
||||
namespace Avalonia.OpenGL |
|
||||
{ |
|
||||
public interface IGlSurface : IDisposable |
|
||||
{ |
|
||||
IGlDisplay Display { get; } |
|
||||
void SwapBuffers(); |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,9 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Avalonia.Rendering |
||||
|
{ |
||||
|
public interface IDeferredRendererLock |
||||
|
{ |
||||
|
IDisposable TryLock(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
using System; |
||||
|
using System.Reactive.Disposables; |
||||
|
using System.Threading; |
||||
|
|
||||
|
namespace Avalonia.Rendering |
||||
|
{ |
||||
|
public class ManagedDeferredRendererLock : IDeferredRendererLock |
||||
|
{ |
||||
|
private readonly object _lock = new object(); |
||||
|
public IDisposable TryLock() |
||||
|
{ |
||||
|
if (Monitor.TryEnter(_lock)) |
||||
|
return Disposable.Create(() => Monitor.Exit(_lock)); |
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
using System; |
||||
|
using Avalonia.Input; |
||||
|
using Avalonia.Platform; |
||||
|
|
||||
|
namespace Avalonia.Controls.UnitTests |
||||
|
{ |
||||
|
public class CursorFactoryMock : IStandardCursorFactory |
||||
|
{ |
||||
|
public IPlatformHandle GetCursor(StandardCursorType cursorType) |
||||
|
{ |
||||
|
return new PlatformHandle(IntPtr.Zero, cursorType.ToString()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue