VulkanSkiaExternalObjectsFeature.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. using System;
  2. using System.Collections.Generic;
  3. using Avalonia.Platform;
  4. using Avalonia.Rendering.Composition;
  5. using Avalonia.Vulkan;
  6. using SkiaSharp;
  7. namespace Avalonia.Skia.Vulkan;
  8. internal class VulkanSkiaExternalObjectsFeature : IExternalObjectsRenderInterfaceContextFeature
  9. {
  10. private readonly VulkanSkiaGpu _gpu;
  11. private readonly IVulkanPlatformGraphicsContext _context;
  12. private readonly IVulkanContextExternalObjectsFeature _feature;
  13. public VulkanSkiaExternalObjectsFeature(VulkanSkiaGpu gpu,
  14. IVulkanPlatformGraphicsContext context, IVulkanContextExternalObjectsFeature feature)
  15. {
  16. _gpu = gpu;
  17. _context = context;
  18. _feature = feature;
  19. }
  20. public IPlatformRenderInterfaceImportedImage ImportImage(IPlatformHandle handle,
  21. PlatformGraphicsExternalImageProperties properties) =>
  22. new Image(_gpu, _feature.ImportImage(handle, properties), properties);
  23. public IPlatformRenderInterfaceImportedSemaphore ImportSemaphore(IPlatformHandle handle) => new Semaphore(_feature.ImportSemaphore(handle));
  24. class Semaphore : IPlatformRenderInterfaceImportedSemaphore
  25. {
  26. private IVulkanExternalSemaphore? _inner;
  27. public Semaphore(IVulkanExternalSemaphore inner)
  28. {
  29. _inner = inner;
  30. }
  31. public void Dispose()
  32. {
  33. _inner?.Dispose();
  34. _inner = null;
  35. }
  36. public IVulkanExternalSemaphore Inner =>
  37. _inner ?? throw new ObjectDisposedException(nameof(IVulkanExternalSemaphore));
  38. }
  39. class Image : IPlatformRenderInterfaceImportedImage
  40. {
  41. private readonly VulkanSkiaGpu _gpu;
  42. private IVulkanExternalImage? _inner;
  43. private readonly PlatformGraphicsExternalImageProperties _properties;
  44. public Image(VulkanSkiaGpu gpu, IVulkanExternalImage inner, PlatformGraphicsExternalImageProperties properties)
  45. {
  46. _gpu = gpu;
  47. _inner = inner;
  48. _properties = properties;
  49. }
  50. public void Dispose()
  51. {
  52. _inner?.Dispose();
  53. _inner = null;
  54. }
  55. public IBitmapImpl SnapshotWithKeyedMutex(uint acquireIndex, uint releaseIndex) => throw new NotSupportedException();
  56. public IBitmapImpl SnapshotWithSemaphores(IPlatformRenderInterfaceImportedSemaphore waitForSemaphore,
  57. IPlatformRenderInterfaceImportedSemaphore signalSemaphore)
  58. {
  59. var info = _inner!.Info;
  60. _gpu.GrContext.ResetContext();
  61. ((Semaphore)waitForSemaphore).Inner.SubmitWaitSemaphore();
  62. var imageInfo = new GRVkImageInfo
  63. {
  64. CurrentQueueFamily = _gpu.Vulkan.Device.GraphicsQueueFamilyIndex,
  65. Format = info.Format,
  66. Image = (ulong)info.Handle,
  67. ImageLayout = info.Layout,
  68. ImageTiling = info.Tiling,
  69. ImageUsageFlags = info.UsageFlags,
  70. LevelCount = info.LevelCount,
  71. SampleCount = info.SampleCount,
  72. Protected = info.IsProtected,
  73. Alloc = new GRVkAlloc
  74. {
  75. Memory = (ulong)info.MemoryHandle,
  76. Size = info.MemorySize
  77. }
  78. };
  79. using var renderTarget = new GRBackendRenderTarget(_properties.Width, _properties.Height, 1, imageInfo);
  80. using var surface = SKSurface.Create(_gpu.GrContext, renderTarget,
  81. _properties.TopLeftOrigin ? GRSurfaceOrigin.TopLeft : GRSurfaceOrigin.BottomLeft,
  82. _properties.Format == PlatformGraphicsExternalImageFormat.R8G8B8A8UNorm
  83. ? SKColorType.Rgba8888
  84. : SKColorType.Bgra8888, SKColorSpace.CreateSrgb());
  85. var image = surface.Snapshot();
  86. _gpu.GrContext.Flush();
  87. //surface.Canvas.Flush();
  88. ((Semaphore)signalSemaphore).Inner.SubmitSignalSemaphore();
  89. return new ImmutableBitmap(image);
  90. }
  91. public IBitmapImpl SnapshotWithAutomaticSync() => throw new NotSupportedException();
  92. }
  93. public IPlatformRenderInterfaceImportedImage ImportImage(ICompositionImportableSharedGpuContextImage image) => throw new System.NotSupportedException();
  94. public CompositionGpuImportedImageSynchronizationCapabilities
  95. GetSynchronizationCapabilities(string imageHandleType) => _feature.GetSynchronizationCapabilities(imageHandleType);
  96. public byte[]? DeviceUuid => _feature.DeviceUuid;
  97. public byte[]? DeviceLuid => _feature.DeviceLuid;
  98. public IReadOnlyList<string> SupportedImageHandleTypes => _feature.SupportedImageHandleTypes;
  99. public IReadOnlyList<string> SupportedSemaphoreTypes => _feature.SupportedSemaphoreTypes;
  100. }