VulkanSupport.cs 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Runtime.InteropServices;
  4. using Avalonia.Platform;
  5. using Avalonia.Vulkan;
  6. namespace Avalonia.Android.Platform.Vulkan
  7. {
  8. internal partial class VulkanSupport
  9. {
  10. [LibraryImport("libvulkan.so", StringMarshalling = StringMarshalling.Utf8)]
  11. private static partial IntPtr vkGetInstanceProcAddr(IntPtr instance, string name);
  12. public static VulkanPlatformGraphics? TryInitialize(VulkanOptions options) =>
  13. VulkanPlatformGraphics.TryCreate(options ?? new(), new VulkanPlatformSpecificOptions
  14. {
  15. RequiredInstanceExtensions = { "VK_KHR_android_surface" },
  16. GetProcAddressDelegate = vkGetInstanceProcAddr,
  17. PlatformFeatures = new Dictionary<Type, object>
  18. {
  19. [typeof(IVulkanKhrSurfacePlatformSurfaceFactory)] = new VulkanSurfaceFactory()
  20. }
  21. });
  22. internal class VulkanSurfaceFactory : IVulkanKhrSurfacePlatformSurfaceFactory
  23. {
  24. public bool CanRenderToSurface(IVulkanPlatformGraphicsContext context, object surface) =>
  25. surface is INativePlatformHandleSurface handle;
  26. public IVulkanKhrSurfacePlatformSurface CreateSurface(IVulkanPlatformGraphicsContext context, object handle) =>
  27. new AndroidVulkanSurface((INativePlatformHandleSurface)handle);
  28. }
  29. class AndroidVulkanSurface : IVulkanKhrSurfacePlatformSurface
  30. {
  31. private INativePlatformHandleSurface _handle;
  32. public AndroidVulkanSurface(INativePlatformHandleSurface handle)
  33. {
  34. _handle = handle;
  35. }
  36. public double Scaling => _handle.Scaling;
  37. public PixelSize Size => _handle.Size;
  38. public ulong CreateSurface(IVulkanPlatformGraphicsContext context) =>
  39. CreateAndroidSurface(_handle.Handle, context.Instance);
  40. public void Dispose()
  41. {
  42. // No-op
  43. }
  44. }
  45. private static ulong CreateAndroidSurface(nint handle, IVulkanInstance instance)
  46. {
  47. var vulkanAndroid = new AndroidVulkanInterface(instance);
  48. var createInfo = new VkAndroidSurfaceCreateInfoKHR()
  49. {
  50. sType = VkAndroidSurfaceCreateInfoKHR.VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR,
  51. window = handle
  52. };
  53. VulkanException.ThrowOnError("vkCreateAndroidSurfaceKHR",
  54. vulkanAndroid.vkCreateAndroidSurfaceKHR(instance.Handle, ref createInfo, IntPtr.Zero, out var surface));
  55. return surface;
  56. }
  57. }
  58. }