Browse Source

android - use existing window handle in android frame buffer

android_native_window_crash
Emmanuel Hansen 11 months ago
parent
commit
096ff1f210
  1. 10
      src/Android/Avalonia.Android/Platform/SkiaPlatform/AndroidFramebuffer.cs
  2. 2
      src/Android/Avalonia.Android/Platform/SkiaPlatform/FramebufferManager.cs
  3. 10
      src/Android/Avalonia.Android/Platform/SkiaPlatform/InvalidationAwareSurfaceView.cs

10
src/Android/Avalonia.Android/Platform/SkiaPlatform/AndroidFramebuffer.cs

@ -3,6 +3,7 @@ using System.Runtime.InteropServices;
using System.Runtime.Versioning; using System.Runtime.Versioning;
using Android.Runtime; using Android.Runtime;
using Android.Views; using Android.Views;
using Avalonia.Logging;
using Avalonia.Platform; using Avalonia.Platform;
namespace Avalonia.Android.Platform.SkiaPlatform namespace Avalonia.Android.Platform.SkiaPlatform
@ -11,14 +12,16 @@ namespace Avalonia.Android.Platform.SkiaPlatform
{ {
private IntPtr _window; private IntPtr _window;
public AndroidFramebuffer(Surface surface, double scaling) public AndroidFramebuffer(InvalidationAwareSurfaceView surface, double scaling)
{ {
if(surface == null) if(surface == null)
throw new ArgumentNullException(nameof(surface)); throw new ArgumentNullException(nameof(surface));
_window = ANativeWindow_fromSurface(JNIEnv.Handle, surface.Handle); _window = (surface as IPlatformHandle).Handle;
if (_window == IntPtr.Zero) if (_window == IntPtr.Zero)
throw new Exception("Unable to obtain ANativeWindow"); throw new Exception("Unable to obtain ANativeWindow");
ANativeWindow_Buffer buffer; ANativeWindow_Buffer buffer;
Logger.TryGet(LogEventLevel.Verbose, LogArea.AndroidPlatform)?
.Log(_window, "Creating AndroidFrameBuffer");
var rc = new ARect() var rc = new ARect()
{ {
right = ANativeWindow_getWidth(_window), right = ANativeWindow_getWidth(_window),
@ -39,7 +42,8 @@ namespace Avalonia.Android.Platform.SkiaPlatform
public void Dispose() public void Dispose()
{ {
ANativeWindow_unlockAndPost(_window); ANativeWindow_unlockAndPost(_window);
ANativeWindow_release(_window); Logger.TryGet(LogEventLevel.Verbose, LogArea.AndroidPlatform)?
.Log(_window, "Releasing AndroidFrameBuffer");
_window = IntPtr.Zero; _window = IntPtr.Zero;
Address = IntPtr.Zero; Address = IntPtr.Zero;
} }

2
src/Android/Avalonia.Android/Platform/SkiaPlatform/FramebufferManager.cs

@ -14,7 +14,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
} }
public ILockedFramebuffer Lock() => new AndroidFramebuffer( public ILockedFramebuffer Lock() => new AndroidFramebuffer(
_topLevel.InternalView.Holder?.Surface ?? throw new InvalidOperationException("TopLevel.InternalView.Holder.Surface was not expected to be null."), _topLevel.InternalView ?? throw new InvalidOperationException("TopLevel.InternalView was not expected to be null."),
_topLevel.RenderScaling); _topLevel.RenderScaling);
public IFramebufferRenderTarget CreateFramebufferRenderTarget() => new FuncFramebufferRenderTarget(Lock); public IFramebufferRenderTarget CreateFramebufferRenderTarget() => new FuncFramebufferRenderTarget(Lock);

10
src/Android/Avalonia.Android/Platform/SkiaPlatform/InvalidationAwareSurfaceView.cs

@ -42,26 +42,26 @@ namespace Avalonia.Android
public virtual void SurfaceChanged(ISurfaceHolder holder, Format format, int width, int height) public virtual void SurfaceChanged(ISurfaceHolder holder, Format format, int width, int height)
{ {
CacheSurfaceProperties(holder);
Logger.TryGet(LogEventLevel.Verbose, LogArea.AndroidPlatform)? Logger.TryGet(LogEventLevel.Verbose, LogArea.AndroidPlatform)?
.Log(this, "InvalidationAwareSurfaceView Changed"); .Log(this, $"InvalidationAwareSurfaceView Changed. Format:{format} Size:{width} x {height}");
CacheSurfaceProperties(holder);
} }
public void SurfaceCreated(ISurfaceHolder holder) public void SurfaceCreated(ISurfaceHolder holder)
{ {
CacheSurfaceProperties(holder);
Logger.TryGet(LogEventLevel.Verbose, LogArea.AndroidPlatform)? Logger.TryGet(LogEventLevel.Verbose, LogArea.AndroidPlatform)?
.Log(this, "InvalidationAwareSurfaceView Created"); .Log(this, "InvalidationAwareSurfaceView Created");
CacheSurfaceProperties(holder);
SurfaceWindowCreated?.Invoke(this, EventArgs.Empty); SurfaceWindowCreated?.Invoke(this, EventArgs.Empty);
} }
public void SurfaceDestroyed(ISurfaceHolder holder) public void SurfaceDestroyed(ISurfaceHolder holder)
{ {
Logger.TryGet(LogEventLevel.Verbose, LogArea.AndroidPlatform)?
.Log(this, "InvalidationAwareSurfaceView Destroyed");
ReleaseNativeWindowHandle(); ReleaseNativeWindowHandle();
_size = new PixelSize(1, 1); _size = new PixelSize(1, 1);
_scaling = 1; _scaling = 1;
Logger.TryGet(LogEventLevel.Verbose, LogArea.AndroidPlatform)?
.Log(this, "InvalidationAwareSurfaceView Destroyed");
} }
public virtual void SurfaceRedrawNeeded(ISurfaceHolder holder) public virtual void SurfaceRedrawNeeded(ISurfaceHolder holder)

Loading…
Cancel
Save