committed by
GitHub
5 changed files with 113 additions and 1 deletions
@ -0,0 +1,25 @@ |
|||||
|
using System; |
||||
|
using Avalonia.SourceGenerator; |
||||
|
using Avalonia.Vulkan; |
||||
|
|
||||
|
namespace Avalonia.Android.Platform.Vulkan; |
||||
|
partial class AndroidVulkanInterface |
||||
|
{ |
||||
|
public AndroidVulkanInterface(IVulkanInstance instance) |
||||
|
{ |
||||
|
Initialize(name => instance.GetInstanceProcAddress(instance.Handle, name)); |
||||
|
} |
||||
|
|
||||
|
[GetProcAddress("vkCreateAndroidSurfaceKHR")] |
||||
|
public partial int vkCreateAndroidSurfaceKHR(IntPtr instance, ref VkAndroidSurfaceCreateInfoKHR pCreateInfo, |
||||
|
IntPtr pAllocator, out ulong pSurface); |
||||
|
} |
||||
|
|
||||
|
struct VkAndroidSurfaceCreateInfoKHR |
||||
|
{ |
||||
|
public const uint VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR = 1000008000; |
||||
|
public uint sType; |
||||
|
public IntPtr pNext; |
||||
|
public uint flags; |
||||
|
public IntPtr window; |
||||
|
} |
||||
@ -0,0 +1,68 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Runtime.InteropServices; |
||||
|
using Avalonia.Platform; |
||||
|
using Avalonia.Vulkan; |
||||
|
|
||||
|
namespace Avalonia.Android.Platform.Vulkan |
||||
|
{ |
||||
|
internal class VulkanSupport |
||||
|
{ |
||||
|
[DllImport("libvulkan.so")] |
||||
|
private static extern IntPtr vkGetInstanceProcAddr(IntPtr instance, string name); |
||||
|
|
||||
|
public static VulkanPlatformGraphics? TryInitialize(VulkanOptions options) => |
||||
|
VulkanPlatformGraphics.TryCreate(options ?? new(), new VulkanPlatformSpecificOptions |
||||
|
{ |
||||
|
RequiredInstanceExtensions = { "VK_KHR_android_surface" }, |
||||
|
GetProcAddressDelegate = vkGetInstanceProcAddr, |
||||
|
PlatformFeatures = new Dictionary<Type, object> |
||||
|
{ |
||||
|
[typeof(IVulkanKhrSurfacePlatformSurfaceFactory)] = new VulkanSurfaceFactory() |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
internal class VulkanSurfaceFactory : IVulkanKhrSurfacePlatformSurfaceFactory |
||||
|
{ |
||||
|
public bool CanRenderToSurface(IVulkanPlatformGraphicsContext context, object surface) => |
||||
|
surface is INativePlatformHandleSurface handle; |
||||
|
|
||||
|
public IVulkanKhrSurfacePlatformSurface CreateSurface(IVulkanPlatformGraphicsContext context, object handle) => |
||||
|
new AndroidVulkanSurface((INativePlatformHandleSurface)handle); |
||||
|
} |
||||
|
|
||||
|
class AndroidVulkanSurface : IVulkanKhrSurfacePlatformSurface |
||||
|
{ |
||||
|
private INativePlatformHandleSurface _handle; |
||||
|
|
||||
|
public AndroidVulkanSurface(INativePlatformHandleSurface handle) |
||||
|
{ |
||||
|
_handle = handle; |
||||
|
} |
||||
|
|
||||
|
public double Scaling => _handle.Scaling; |
||||
|
public PixelSize Size => _handle.Size; |
||||
|
public ulong CreateSurface(IVulkanPlatformGraphicsContext context) => |
||||
|
CreateAndroidSurface(_handle.Handle, context.Instance); |
||||
|
|
||||
|
public void Dispose() |
||||
|
{ |
||||
|
// No-op
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private static ulong CreateAndroidSurface(nint handle, IVulkanInstance instance) |
||||
|
{ |
||||
|
var vulkanAndroid = new AndroidVulkanInterface(instance); |
||||
|
var createInfo = new VkAndroidSurfaceCreateInfoKHR() |
||||
|
{ |
||||
|
|
||||
|
sType = VkAndroidSurfaceCreateInfoKHR.VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR, |
||||
|
window = handle |
||||
|
}; |
||||
|
VulkanException.ThrowOnError("vkCreateAndroidSurfaceKHR", |
||||
|
vulkanAndroid.vkCreateAndroidSurfaceKHR(instance.Handle, ref createInfo, IntPtr.Zero, out var surface)); |
||||
|
return surface; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue