diff --git a/build/TrimmingEnable.props b/build/TrimmingEnable.props
index 1fa14cb022..34b3e232b6 100644
--- a/build/TrimmingEnable.props
+++ b/build/TrimmingEnable.props
@@ -19,4 +19,10 @@
$(WarningsAsErrors);IL3050;IL3051;IL3052;IL3053;IL3054;IL3055;IL3056
+
+ $(WarningsAsErrors);CA1420;CA1421
+
+
+
+
diff --git a/src/Android/Avalonia.Android/Avalonia.Android.csproj b/src/Android/Avalonia.Android/Avalonia.Android.csproj
index 170cc088fb..236422885a 100644
--- a/src/Android/Avalonia.Android/Avalonia.Android.csproj
+++ b/src/Android/Avalonia.Android/Avalonia.Android.csproj
@@ -4,6 +4,7 @@
$(AvsMinSupportedAndroidVersion)
true
Avalonia.Android.Internal
+ true
diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/AndroidFramebuffer.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/AndroidFramebuffer.cs
index 94e5f4bd01..20361b113b 100644
--- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/AndroidFramebuffer.cs
+++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/AndroidFramebuffer.cs
@@ -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,
diff --git a/src/Android/Avalonia.Android/Platform/Vulkan/VulkanSupport.cs b/src/Android/Avalonia.Android/Platform/Vulkan/VulkanSupport.cs
index 86f9f5938e..5d1b0e309a 100644
--- a/src/Android/Avalonia.Android/Platform/Vulkan/VulkanSupport.cs
+++ b/src/Android/Avalonia.Android/Platform/Vulkan/VulkanSupport.cs
@@ -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
diff --git a/src/Avalonia.Base/Avalonia.Base.csproj b/src/Avalonia.Base/Avalonia.Base.csproj
index 15f0665fd0..ce2d9ce9bc 100644
--- a/src/Avalonia.Base/Avalonia.Base.csproj
+++ b/src/Avalonia.Base/Avalonia.Base.csproj
@@ -5,7 +5,6 @@
True
true
$(BaseIntermediateOutputPath)\GeneratedFiles
- true
diff --git a/src/Avalonia.Base/Media/Imaging/PixelFormatTranscoder.cs b/src/Avalonia.Base/Media/Imaging/PixelFormatTranscoder.cs
index 6659197e1a..8cd0d5ca77 100644
--- a/src/Avalonia.Base/Media/Imaging/PixelFormatTranscoder.cs
+++ b/src/Avalonia.Base/Media/Imaging/PixelFormatTranscoder.cs
@@ -18,7 +18,7 @@ internal static unsafe class PixelFormatTranscoder
AlphaFormat destAlphaFormat)
{
var pixelCount = srcSize.Width * srcSize.Height;
- var bufferSize = pixelCount * Marshal.SizeOf();
+ var bufferSize = pixelCount * sizeof(Rgba8888Pixel);
using var blob = new UnmanagedBlob(bufferSize);
var pixels = new Span((void*)blob.Address, pixelCount);
diff --git a/src/Avalonia.Base/Platform/Internal/UnmanagedBlob.cs b/src/Avalonia.Base/Platform/Internal/UnmanagedBlob.cs
index 9a7582ca5f..eeba160a3c 100644
--- a/src/Avalonia.Base/Platform/Internal/UnmanagedBlob.cs
+++ b/src/Avalonia.Base/Platform/Internal/UnmanagedBlob.cs
@@ -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
}
}
}
diff --git a/src/Avalonia.FreeDesktop/Avalonia.FreeDesktop.csproj b/src/Avalonia.FreeDesktop/Avalonia.FreeDesktop.csproj
index 0cb0f04bc2..5dc19e593e 100644
--- a/src/Avalonia.FreeDesktop/Avalonia.FreeDesktop.csproj
+++ b/src/Avalonia.FreeDesktop/Avalonia.FreeDesktop.csproj
@@ -3,6 +3,7 @@
$(AvsCurrentTargetFramework);$(AvsLegacyTargetFrameworks);netstandard2.0
enable
+ true
diff --git a/src/Avalonia.OpenGL/Avalonia.OpenGL.csproj b/src/Avalonia.OpenGL/Avalonia.OpenGL.csproj
index e6a4e2724b..2c5734ed45 100644
--- a/src/Avalonia.OpenGL/Avalonia.OpenGL.csproj
+++ b/src/Avalonia.OpenGL/Avalonia.OpenGL.csproj
@@ -3,6 +3,7 @@
$(AvsCurrentTargetFramework);$(AvsLegacyTargetFrameworks);netstandard2.0
true
+ true
diff --git a/src/Avalonia.Vulkan/Avalonia.Vulkan.csproj b/src/Avalonia.Vulkan/Avalonia.Vulkan.csproj
index 59b8e62708..e270d64d70 100644
--- a/src/Avalonia.Vulkan/Avalonia.Vulkan.csproj
+++ b/src/Avalonia.Vulkan/Avalonia.Vulkan.csproj
@@ -3,6 +3,7 @@
$(AvsCurrentTargetFramework);$(AvsLegacyTargetFrameworks);netstandard2.0
true
+ true
diff --git a/src/Avalonia.X11/Avalonia.X11.csproj b/src/Avalonia.X11/Avalonia.X11.csproj
index 67a81ad154..b09bea889f 100644
--- a/src/Avalonia.X11/Avalonia.X11.csproj
+++ b/src/Avalonia.X11/Avalonia.X11.csproj
@@ -2,6 +2,7 @@
$(AvsCurrentTargetFramework);$(AvsLegacyTargetFrameworks);netstandard2.0
true
+ true
diff --git a/src/Browser/Avalonia.Browser/Rendering/BrowserWebGlRenderTarget.cs b/src/Browser/Avalonia.Browser/Rendering/BrowserWebGlRenderTarget.cs
index bbb713255b..db66c9a0ee 100644
--- a/src/Browser/Avalonia.Browser/Rendering/BrowserWebGlRenderTarget.cs
+++ b/src/Browser/Avalonia.Browser/Rendering/BrowserWebGlRenderTarget.cs
@@ -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;
-}
\ No newline at end of file
+}
diff --git a/src/Linux/Avalonia.LinuxFramebuffer/Avalonia.LinuxFramebuffer.csproj b/src/Linux/Avalonia.LinuxFramebuffer/Avalonia.LinuxFramebuffer.csproj
index f4a2948c48..444eb13875 100644
--- a/src/Linux/Avalonia.LinuxFramebuffer/Avalonia.LinuxFramebuffer.csproj
+++ b/src/Linux/Avalonia.LinuxFramebuffer/Avalonia.LinuxFramebuffer.csproj
@@ -2,6 +2,7 @@
$(AvsCurrentTargetFramework);$(AvsLegacyTargetFrameworks);netstandard2.0
true
+ true
diff --git a/src/Skia/Avalonia.Skia/Gpu/Metal/SkiaMetalApi.cs b/src/Skia/Avalonia.Skia/Gpu/Metal/SkiaMetalApi.cs
index 2085e065ee..d5e2352e13 100644
--- a/src/Skia/Avalonia.Skia/Gpu/Metal/SkiaMetalApi.cs
+++ b/src/Skia/Avalonia.Skia/Gpu/Metal/SkiaMetalApi.cs
@@ -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
diff --git a/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj b/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj
index b924ceebc3..c299bcba4e 100644
--- a/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj
+++ b/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj
@@ -2,6 +2,7 @@
$(AvsCurrentTargetFramework);$(AvsLegacyTargetFrameworks);netstandard2.0
true
+ true
true