Begin with DisableRuntimeMarshalling support + fix macOS Metal AOT (#17116)
* Add attribute * Replace `SetLastError = true` with `Marshal.GetLastSystemError()` * Make Avalonia.Base and Avalonia.Skia compatible with DisableRuntimeMarshalling * First step in Android DisableRuntimeMarshalling support * Make Avalonia.Browser compatible * Set EnableRuntimeMarshalling=true on all projects we are not yet ready to support without runtime marshalling
This commit is contained in:
@@ -19,4 +19,10 @@
|
||||
<WarningsAsErrors Condition="'$(IsAotCompatible)' == 'true'">$(WarningsAsErrors);IL3050;IL3051;IL3052;IL3053;IL3054;IL3055;IL3056</WarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0')) AND '$(EnableRuntimeMarshalling)' != 'true'">
|
||||
<WarningsAsErrors>$(WarningsAsErrors);CA1420;CA1421</WarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0')) AND '$(EnableRuntimeMarshalling)' != 'true'">
|
||||
<AssemblyAttribute Include="System.Runtime.CompilerServices.DisableRuntimeMarshallingAttribute" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<SupportedOSPlatformVersion>$(AvsMinSupportedAndroidVersion)</SupportedOSPlatformVersion>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<AndroidResgenNamespace>Avalonia.Android.Internal</AndroidResgenNamespace>
|
||||
<EnableRuntimeMarshalling>true</EnableRuntimeMarshalling>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\packages\Avalonia\Avalonia.csproj" />
|
||||
|
||||
@@ -6,7 +6,7 @@ using Avalonia.Platform;
|
||||
|
||||
namespace Avalonia.Android.Platform.SkiaPlatform
|
||||
{
|
||||
class AndroidFramebuffer : ILockedFramebuffer
|
||||
unsafe class AndroidFramebuffer : ILockedFramebuffer
|
||||
{
|
||||
private IntPtr _window;
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
|
||||
bottom = ANativeWindow_getHeight(_window)
|
||||
};
|
||||
Size = new PixelSize(rc.right, rc.bottom);
|
||||
ANativeWindow_lock(_window, out buffer, ref rc);
|
||||
ANativeWindow_lock(_window, &buffer, &rc);
|
||||
|
||||
Format = buffer.format == AndroidPixelFormat.WINDOW_FORMAT_RGB_565
|
||||
? PixelFormat.Rgb565 : PixelFormat.Rgba8888;
|
||||
@@ -61,7 +61,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
|
||||
internal static extern void ANativeWindow_unlockAndPost(IntPtr window);
|
||||
|
||||
[DllImport("android")]
|
||||
internal static extern int ANativeWindow_lock(IntPtr window, out ANativeWindow_Buffer outBuffer, ref ARect inOutDirtyBounds);
|
||||
internal static extern int ANativeWindow_lock(IntPtr window, ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds);
|
||||
public enum AndroidPixelFormat
|
||||
{
|
||||
WINDOW_FORMAT_RGBA_8888 = 1,
|
||||
|
||||
@@ -6,10 +6,10 @@ using Avalonia.Vulkan;
|
||||
|
||||
namespace Avalonia.Android.Platform.Vulkan
|
||||
{
|
||||
internal class VulkanSupport
|
||||
internal partial class VulkanSupport
|
||||
{
|
||||
[DllImport("libvulkan.so")]
|
||||
private static extern IntPtr vkGetInstanceProcAddr(IntPtr instance, string name);
|
||||
[LibraryImport("libvulkan.so", StringMarshalling = StringMarshalling.Utf8)]
|
||||
private static partial IntPtr vkGetInstanceProcAddr(IntPtr instance, string name);
|
||||
|
||||
public static VulkanPlatformGraphics? TryInitialize(VulkanOptions options) =>
|
||||
VulkanPlatformGraphics.TryCreate(options ?? new(), new VulkanPlatformSpecificOptions
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
|
||||
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GeneratedFiles</CompilerGeneratedFilesOutputPath>
|
||||
<IsTrimmable>true</IsTrimmable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Assets\*.trie" />
|
||||
|
||||
@@ -18,7 +18,7 @@ internal static unsafe class PixelFormatTranscoder
|
||||
AlphaFormat destAlphaFormat)
|
||||
{
|
||||
var pixelCount = srcSize.Width * srcSize.Height;
|
||||
var bufferSize = pixelCount * Marshal.SizeOf<Rgba8888Pixel>();
|
||||
var bufferSize = pixelCount * sizeof(Rgba8888Pixel);
|
||||
using var blob = new UnmanagedBlob(bufferSize);
|
||||
|
||||
var pixels = new Span<Rgba8888Pixel>((void*)blob.Address, pixelCount);
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using Avalonia.Compatibility;
|
||||
|
||||
namespace Avalonia.Platform.Internal;
|
||||
|
||||
@@ -108,21 +109,15 @@ internal class UnmanagedBlob : IDisposable
|
||||
public int Size { get; private set; }
|
||||
public bool IsDisposed { get; private set; }
|
||||
|
||||
[DllImport("libc", SetLastError = true)]
|
||||
[DllImport("libc")]
|
||||
private static extern IntPtr mmap(IntPtr addr, IntPtr length, int prot, int flags, int fd, IntPtr offset);
|
||||
[DllImport("libc", SetLastError = true)]
|
||||
[DllImport("libc")]
|
||||
private static extern int munmap(IntPtr addr, IntPtr length);
|
||||
[DllImport("libc", SetLastError = true)]
|
||||
private static extern long sysconf(int name);
|
||||
|
||||
private bool? _useMmap;
|
||||
private bool UseMmap
|
||||
=> _useMmap ?? ((_useMmap = RuntimeInformation.IsOSPlatform(OSPlatform.Linux)).Value);
|
||||
|
||||
// Could be replaced with https://github.com/dotnet/runtime/issues/40892 when it will be available.
|
||||
private IntPtr Alloc(int size)
|
||||
{
|
||||
if (!UseMmap)
|
||||
if (!OperatingSystemEx.IsLinux())
|
||||
{
|
||||
return Marshal.AllocHGlobal(size);
|
||||
}
|
||||
@@ -131,8 +126,12 @@ internal class UnmanagedBlob : IDisposable
|
||||
var rv = mmap(IntPtr.Zero, new IntPtr(size), 3, 0x22, -1, IntPtr.Zero);
|
||||
if (rv.ToInt64() == -1 || (ulong)rv.ToInt64() == 0xffffffff)
|
||||
{
|
||||
var errno = Marshal.GetLastWin32Error();
|
||||
#if NET6_0_OR_GREATER
|
||||
var errno = Marshal.GetLastSystemError();
|
||||
throw new Exception("Unable to allocate memory: " + errno);
|
||||
#else
|
||||
throw new Exception("Unable to allocate memory");
|
||||
#endif
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
@@ -140,7 +139,7 @@ internal class UnmanagedBlob : IDisposable
|
||||
|
||||
private void Free(IntPtr ptr, int len)
|
||||
{
|
||||
if (!UseMmap)
|
||||
if (!OperatingSystemEx.IsLinux())
|
||||
{
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
}
|
||||
@@ -148,8 +147,12 @@ internal class UnmanagedBlob : IDisposable
|
||||
{
|
||||
if (munmap(ptr, new IntPtr(len)) == -1)
|
||||
{
|
||||
var errno = Marshal.GetLastWin32Error();
|
||||
#if NET6_0_OR_GREATER
|
||||
var errno = Marshal.GetLastSystemError();
|
||||
throw new Exception("Unable to free memory: " + errno);
|
||||
#else
|
||||
throw new Exception("Unable to free memory");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>$(AvsCurrentTargetFramework);$(AvsLegacyTargetFrameworks);netstandard2.0</TargetFrameworks>
|
||||
<Nullable>enable</Nullable>
|
||||
<EnableRuntimeMarshalling>true</EnableRuntimeMarshalling>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="../../build/TrimmingEnable.props" />
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>$(AvsCurrentTargetFramework);$(AvsLegacyTargetFrameworks);netstandard2.0</TargetFrameworks>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<EnableRuntimeMarshalling>true</EnableRuntimeMarshalling>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>$(AvsCurrentTargetFramework);$(AvsLegacyTargetFrameworks);netstandard2.0</TargetFrameworks>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<EnableRuntimeMarshalling>true</EnableRuntimeMarshalling>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>$(AvsCurrentTargetFramework);$(AvsLegacyTargetFrameworks);netstandard2.0</TargetFrameworks>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<EnableRuntimeMarshalling>true</EnableRuntimeMarshalling>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -96,8 +96,8 @@ partial class WebGlContext : IGlContext, Avalonia.Skia.IGlSkiaSpecificOptionsFea
|
||||
[JSImport("WebGlRenderTarget.makeContextCurrent", AvaloniaModule.MainModuleName)]
|
||||
private static partial bool MakeContextCurrent(int context);
|
||||
|
||||
[DllImport("libSkiaSharp", EntryPoint = "eglGetProcAddress")]
|
||||
private static extern IntPtr eglGetProcAddress(string name);
|
||||
[LibraryImport("libSkiaSharp", EntryPoint = "eglGetProcAddress", StringMarshalling = StringMarshalling.Utf8)]
|
||||
private static partial IntPtr eglGetProcAddress(string name);
|
||||
|
||||
private int _contextId;
|
||||
private readonly Thread _thread;
|
||||
@@ -177,4 +177,4 @@ partial class WebGlContext : IGlContext, Avalonia.Skia.IGlSkiaSpecificOptionsFea
|
||||
throw new NotSupportedException();
|
||||
|
||||
public bool UseNativeSkiaGrGlInterface => true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>$(AvsCurrentTargetFramework);$(AvsLegacyTargetFrameworks);netstandard2.0</TargetFrameworks>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<EnableRuntimeMarshalling>true</EnableRuntimeMarshalling>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\packages\Avalonia\Avalonia.csproj" />
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using Avalonia.Compatibility;
|
||||
using Avalonia.Platform.Interop;
|
||||
@@ -77,13 +78,18 @@ internal unsafe class SkiaMetalApi
|
||||
{
|
||||
options ??= new();
|
||||
var nativeOptions = _contextOptionsToNative.Invoke(options, null)!;
|
||||
var pOptions = Marshal.AllocHGlobal(Marshal.SizeOf(nativeOptions));
|
||||
Marshal.StructureToPtr(nativeOptions, pOptions, false);
|
||||
var context = _gr_direct_context_make_metal_with_options(device, queue, pOptions);
|
||||
Marshal.FreeHGlobal(pOptions);
|
||||
if (context == IntPtr.Zero)
|
||||
throw new InvalidOperationException("Unable to create GRContext from Metal device.");
|
||||
return (GRContext)_contextCtor.Invoke(new object[] { context, true });
|
||||
var gcHandle = GCHandle.Alloc(nativeOptions, GCHandleType.Pinned);
|
||||
try
|
||||
{
|
||||
var context = _gr_direct_context_make_metal_with_options(device, queue, gcHandle.AddrOfPinnedObject());
|
||||
if (context == IntPtr.Zero)
|
||||
throw new InvalidOperationException("Unable to create GRContext from Metal device.");
|
||||
return (GRContext)_contextCtor.Invoke(new object[] { context, true });
|
||||
}
|
||||
finally
|
||||
{
|
||||
gcHandle.Free();
|
||||
}
|
||||
}
|
||||
|
||||
internal struct GRMtlTextureInfoNative
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>$(AvsCurrentTargetFramework);$(AvsLegacyTargetFrameworks);netstandard2.0</TargetFrameworks>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<EnableRuntimeMarshalling>true</EnableRuntimeMarshalling>
|
||||
<!-- We still keep BinaryFormatter for WinForms compatibility. -->
|
||||
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
|
||||
</PropertyGroup>
|
||||
|
||||
Reference in New Issue
Block a user