committed by
GitHub
9 changed files with 172 additions and 70 deletions
@ -1,47 +0,0 @@ |
|||
using Android.App; |
|||
using Android.OS; |
|||
|
|||
namespace Avalonia.Android |
|||
{ |
|||
internal class ActivityTracker : Java.Lang.Object, global::Android.App.Application.IActivityLifecycleCallbacks |
|||
{ |
|||
public static Activity Current { get; private set; } |
|||
public void OnActivityCreated(Activity activity, Bundle savedInstanceState) |
|||
{ |
|||
Current = activity; |
|||
} |
|||
|
|||
public void OnActivityDestroyed(Activity activity) |
|||
{ |
|||
if (Current == activity) |
|||
Current = null; |
|||
} |
|||
|
|||
public void OnActivityPaused(Activity activity) |
|||
{ |
|||
if (Current == activity) |
|||
Current = null; |
|||
} |
|||
|
|||
public void OnActivityResumed(Activity activity) |
|||
{ |
|||
Current = activity; |
|||
} |
|||
|
|||
public void OnActivitySaveInstanceState(Activity activity, Bundle outState) |
|||
{ |
|||
Current = activity; |
|||
} |
|||
|
|||
public void OnActivityStarted(Activity activity) |
|||
{ |
|||
Current = activity; |
|||
} |
|||
|
|||
public void OnActivityStopped(Activity activity) |
|||
{ |
|||
if (Current == activity) |
|||
Current = null; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,101 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Reactive.Disposables; |
|||
using System.Threading.Tasks; |
|||
|
|||
using Android.OS; |
|||
using Android.Views; |
|||
|
|||
using Avalonia.Rendering; |
|||
|
|||
using Java.Lang; |
|||
|
|||
namespace Avalonia.Android |
|||
{ |
|||
internal sealed class ChoreographerTimer : Java.Lang.Object, IRenderTimer, Choreographer.IFrameCallback |
|||
{ |
|||
private readonly object _lock = new object(); |
|||
|
|||
private readonly Thread _thread; |
|||
private readonly TaskCompletionSource<Choreographer> _choreographer = new TaskCompletionSource<Choreographer>(); |
|||
|
|||
private readonly ISet<AvaloniaView> _views = new HashSet<AvaloniaView>(); |
|||
|
|||
private Action<TimeSpan> _tick; |
|||
private int _count; |
|||
|
|||
public ChoreographerTimer() |
|||
{ |
|||
_thread = new Thread(Loop); |
|||
_thread.Start(); |
|||
} |
|||
|
|||
public event Action<TimeSpan> Tick |
|||
{ |
|||
add |
|||
{ |
|||
lock (_lock) |
|||
{ |
|||
_tick += value; |
|||
_count++; |
|||
|
|||
if (_count == 1) |
|||
{ |
|||
_choreographer.Task.Result.PostFrameCallback(this); |
|||
} |
|||
} |
|||
} |
|||
remove |
|||
{ |
|||
lock (_lock) |
|||
{ |
|||
_tick -= value; |
|||
_count--; |
|||
} |
|||
} |
|||
} |
|||
|
|||
internal IDisposable SubscribeView(AvaloniaView view) |
|||
{ |
|||
lock (_lock) |
|||
{ |
|||
_views.Add(view); |
|||
|
|||
if (_views.Count == 1) |
|||
{ |
|||
_choreographer.Task.Result.PostFrameCallback(this); |
|||
} |
|||
} |
|||
|
|||
return Disposable.Create( |
|||
() => |
|||
{ |
|||
lock (_lock) |
|||
{ |
|||
_views.Remove(view); |
|||
} |
|||
} |
|||
); |
|||
} |
|||
|
|||
private void Loop() |
|||
{ |
|||
Looper.Prepare(); |
|||
_choreographer.SetResult(Choreographer.Instance); |
|||
Looper.Loop(); |
|||
} |
|||
|
|||
public void DoFrame(long frameTimeNanos) |
|||
{ |
|||
_tick?.Invoke(TimeSpan.FromTicks(frameTimeNanos / 100)); |
|||
|
|||
lock (_lock) |
|||
{ |
|||
if (_count > 0 && _views.Count > 0) |
|||
{ |
|||
Choreographer.Instance.PostFrameCallback(this); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,12 +1,21 @@ |
|||
using System; |
|||
using Avalonia.Input; |
|||
using Avalonia.Platform; |
|||
|
|||
namespace Avalonia.Android |
|||
{ |
|||
internal class CursorFactory : IStandardCursorFactory |
|||
internal class CursorFactory : ICursorFactory |
|||
{ |
|||
public IPlatformHandle GetCursor(StandardCursorType cursorType) |
|||
=> new PlatformHandle(IntPtr.Zero, "ZeroCursor"); |
|||
public ICursorImpl CreateCursor(IBitmapImpl cursor, PixelPoint hotSpot) => CursorImpl.ZeroCursor; |
|||
|
|||
public ICursorImpl GetCursor(StandardCursorType cursorType) => CursorImpl.ZeroCursor; |
|||
|
|||
private sealed class CursorImpl : ICursorImpl |
|||
{ |
|||
public static CursorImpl ZeroCursor { get; } = new CursorImpl(); |
|||
|
|||
private CursorImpl() { } |
|||
|
|||
public void Dispose() { } |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -1,23 +1,30 @@ |
|||
using Avalonia.OpenGL.Egl; |
|||
using System; |
|||
|
|||
using Avalonia.OpenGL.Egl; |
|||
using Avalonia.OpenGL.Surfaces; |
|||
|
|||
namespace Avalonia.Android.OpenGL |
|||
{ |
|||
internal sealed class GlRenderTarget : EglPlatformSurfaceRenderTargetBase |
|||
internal sealed class GlRenderTarget : EglPlatformSurfaceRenderTargetBase, IGlPlatformSurfaceRenderTargetWithCorruptionInfo |
|||
{ |
|||
private readonly EglGlPlatformSurfaceBase.IEglWindowGlPlatformSurfaceInfo _info; |
|||
private readonly EglSurface _surface; |
|||
private readonly IntPtr _handle; |
|||
|
|||
public GlRenderTarget( |
|||
EglPlatformOpenGlInterface egl, |
|||
EglGlPlatformSurfaceBase.IEglWindowGlPlatformSurfaceInfo info, |
|||
EglSurface surface) |
|||
EglSurface surface, |
|||
IntPtr handle) |
|||
: base(egl) |
|||
{ |
|||
_info = info; |
|||
_surface = surface; |
|||
_handle = handle; |
|||
} |
|||
|
|||
public bool IsCorrupted => _handle != _info.Handle; |
|||
|
|||
public override IGlPlatformSurfaceRenderingSession BeginDraw() => BeginDraw(_surface, _info); |
|||
} |
|||
} |
|||
|
|||
Loading…
Reference in new issue