Browse Source

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

Nikita Tsukanov 8 years ago
parent
commit
a0c4ec9039

+ 3 - 26
src/OSX/Avalonia.MonoMac/EmulatedFramebuffer.cs

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

+ 28 - 2
src/OSX/Avalonia.MonoMac/TopLevelImpl.cs

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