Browse Source

[MONOMAC] Pass frames back to UI thread instead of using lockFocusIfCanDraw

pull/1240/head
Nikita Tsukanov 9 years ago
parent
commit
a0c4ec9039
  1. 29
      src/OSX/Avalonia.MonoMac/EmulatedFramebuffer.cs
  2. 30
      src/OSX/Avalonia.MonoMac/TopLevelImpl.cs

29
src/OSX/Avalonia.MonoMac/EmulatedFramebuffer.cs

@ -11,7 +11,7 @@ namespace Avalonia.MonoMac
{ {
private readonly TopLevelImpl.TopLevelView _view; private readonly TopLevelImpl.TopLevelView _view;
private readonly CGSize _logicalSize; private readonly CGSize _logicalSize;
private bool _isDeferred; private readonly bool _isDeferred;
[DllImport("libc")] [DllImport("libc")]
static extern void memset(IntPtr p, int c, IntPtr size); static extern void memset(IntPtr p, int c, IntPtr size);
@ -32,34 +32,12 @@ namespace Avalonia.MonoMac
Address = Marshal.AllocHGlobal(size); Address = Marshal.AllocHGlobal(size);
memset(Address, 0, new IntPtr(size)); memset(Address, 0, new IntPtr(size));
} }
class CocoaDrawLock : IDisposable
{
private readonly NSView _view;
public void Dispose()
{
_view.NonUIUnlockFocus();
}
public CocoaDrawLock(NSView view)
{
_view = view;
}
}
CocoaDrawLock LockCocoaDrawing()
{
if (!_view.NonUILockFocusIfCanDraw())
return null;
return new CocoaDrawLock(_view);
}
public void Dispose() public void Dispose()
{ {
if (Address == IntPtr.Zero) if (Address == IntPtr.Zero)
return; return;
var nfo = (int) CGBitmapFlags.ByteOrder32Big | (int) CGImageAlphaInfo.PremultipliedLast; var nfo = (int) CGBitmapFlags.ByteOrder32Big | (int) CGImageAlphaInfo.PremultipliedLast;
IDisposable drawLock = LockCocoaDrawing();
CGImage image = null; CGImage image = null;
try try
{ {
@ -69,7 +47,7 @@ namespace Avalonia.MonoMac
image = bContext.ToImage(); image = bContext.ToImage();
lock (_view.SyncRoot) lock (_view.SyncRoot)
{ {
if (!_isDeferred || drawLock != null) if(!_isDeferred)
{ {
using (var nscontext = NSGraphicsContext.CurrentContext) using (var nscontext = NSGraphicsContext.CurrentContext)
using (var context = nscontext.GraphicsPort) using (var context = nscontext.GraphicsPort)
@ -95,7 +73,6 @@ namespace Avalonia.MonoMac
} }
Marshal.FreeHGlobal(Address); Marshal.FreeHGlobal(Address);
Address = IntPtr.Zero; Address = IntPtr.Zero;
drawLock?.Dispose();
} }

30
src/OSX/Avalonia.MonoMac/TopLevelImpl.cs

@ -7,7 +7,7 @@ using Avalonia.Controls.Platform.Surfaces;
using Avalonia.Rendering; using Avalonia.Rendering;
using Avalonia.Threading; using Avalonia.Threading;
using MonoMac.AppKit; using MonoMac.AppKit;
using MonoMac.CoreFoundation;
using MonoMac.CoreGraphics; using MonoMac.CoreGraphics;
using MonoMac.Foundation; using MonoMac.Foundation;
using MonoMac.ObjCRuntime; using MonoMac.ObjCRuntime;
@ -37,6 +37,7 @@ namespace Avalonia.MonoMac
private readonly IKeyboardDevice _keyboard; private readonly IKeyboardDevice _keyboard;
private NSTrackingArea _area; private NSTrackingArea _area;
private NSCursor _cursor; private NSCursor _cursor;
private bool _nonUiRedrawQueued;
public CGSize PixelSize { get; set; } public CGSize PixelSize { get; set; }
@ -55,7 +56,10 @@ namespace Avalonia.MonoMac
protected override void Dispose(bool disposing) protected override void Dispose(bool disposing)
{ {
if (disposing) if (disposing)
SetBackBufferImage(null); {
_backBuffer?.Dispose();
_backBuffer = null;
}
base.Dispose(disposing); base.Dispose(disposing);
} }
@ -69,6 +73,8 @@ namespace Avalonia.MonoMac
public override void DrawRect(CGRect dirtyRect) public override void DrawRect(CGRect dirtyRect)
{ {
lock (SyncRoot)
_nonUiRedrawQueued = false;
lock (SyncRoot) lock (SyncRoot)
{ {
if (_backBuffer != null) if (_backBuffer != null)
@ -93,6 +99,25 @@ namespace Avalonia.MonoMac
{ {
_backBuffer?.Dispose(); _backBuffer?.Dispose();
_backBuffer = image; _backBuffer = image;
if (image == null)
return;
if (_nonUiRedrawQueued)
return;
_nonUiRedrawQueued = true;
Dispatcher.UIThread.InvokeAsync(
() =>
{
lock (SyncRoot)
{
if (!_nonUiRedrawQueued)
return;
_nonUiRedrawQueued = false;
}
SetNeedsDisplayInRect(Frame);
Display();
}, DispatcherPriority.Render);
} }
} }
@ -138,6 +163,7 @@ namespace Avalonia.MonoMac
AddTrackingArea(_area); AddTrackingArea(_area);
UpdateCursor(); UpdateCursor();
_tl?.Resized?.Invoke(_tl.ClientSize); _tl?.Resized?.Invoke(_tl.ClientSize);
Dispatcher.UIThread.RunJobs(DispatcherPriority.Layout);
} }
InputModifiers GetModifiers(NSEventModifierMask mod) InputModifiers GetModifiers(NSEventModifierMask mod)

Loading…
Cancel
Save