| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- using System;
- using Avalonia.Skia;
- using Ryujinx.Ava.Ui.Vulkan;
- using Ryujinx.Ava.Ui.Vulkan.Surfaces;
- using SkiaSharp;
- namespace Ryujinx.Ava.Ui.Backend.Vulkan
- {
- internal class VulkanRenderTarget : ISkiaGpuRenderTarget
- {
- public GRContext GrContext { get; set; }
- private readonly VulkanSurfaceRenderTarget _surface;
- private readonly IVulkanPlatformSurface _vulkanPlatformSurface;
- public VulkanRenderTarget(VulkanPlatformInterface vulkanPlatformInterface, IVulkanPlatformSurface vulkanPlatformSurface)
- {
- _surface = vulkanPlatformInterface.CreateRenderTarget(vulkanPlatformSurface);
- _vulkanPlatformSurface = vulkanPlatformSurface;
- }
- public void Dispose()
- {
- _surface.Dispose();
- }
- public ISkiaGpuRenderSession BeginRenderingSession()
- {
- var session = _surface.BeginDraw(_vulkanPlatformSurface.Scaling);
- bool success = false;
- try
- {
- var disp = session.Display;
- var api = session.Api;
- var size = session.Size;
- var scaling = session.Scaling;
- if (size.Width <= 0 || size.Height <= 0 || scaling < 0)
- {
- size = new Avalonia.PixelSize(1, 1);
- scaling = 1;
- }
- lock (GrContext)
- {
- GrContext.ResetContext();
- var imageInfo = new GRVkImageInfo()
- {
- CurrentQueueFamily = disp.QueueFamilyIndex,
- Format = _surface.ImageFormat,
- Image = _surface.Image.Handle,
- ImageLayout = (uint)_surface.Image.CurrentLayout,
- ImageTiling = (uint)_surface.Image.Tiling,
- ImageUsageFlags = _surface.UsageFlags,
- LevelCount = _surface.MipLevels,
- SampleCount = 1,
- Protected = false,
- Alloc = new GRVkAlloc()
- {
- Memory = _surface.Image.MemoryHandle,
- Flags = 0,
- Offset = 0,
- Size = _surface.MemorySize
- }
- };
- var renderTarget =
- new GRBackendRenderTarget((int)size.Width, (int)size.Height, 1,
- imageInfo);
- var surface = SKSurface.Create(GrContext, renderTarget,
- GRSurfaceOrigin.TopLeft,
- _surface.IsRgba ? SKColorType.Rgba8888 : SKColorType.Bgra8888, SKColorSpace.CreateSrgb());
- if (surface == null)
- {
- throw new InvalidOperationException(
- "Surface can't be created with the provided render target");
- }
- success = true;
- return new VulkanGpuSession(GrContext, renderTarget, surface, session);
- }
- }
- finally
- {
- if (!success)
- {
- session.Dispose();
- }
- }
- }
- public bool IsCorrupted { get; }
- internal class VulkanGpuSession : ISkiaGpuRenderSession
- {
- private readonly GRBackendRenderTarget _backendRenderTarget;
- private readonly VulkanSurfaceRenderingSession _vulkanSession;
- public VulkanGpuSession(GRContext grContext,
- GRBackendRenderTarget backendRenderTarget,
- SKSurface surface,
- VulkanSurfaceRenderingSession vulkanSession)
- {
- GrContext = grContext;
- _backendRenderTarget = backendRenderTarget;
- SkSurface = surface;
- _vulkanSession = vulkanSession;
- SurfaceOrigin = GRSurfaceOrigin.TopLeft;
- }
- public void Dispose()
- {
- lock (_vulkanSession.Display.Lock)
- {
- SkSurface.Canvas.Flush();
- SkSurface.Dispose();
- _backendRenderTarget.Dispose();
- GrContext.Flush();
- _vulkanSession.Dispose();
- }
- }
- public GRContext GrContext { get; }
- public SKSurface SkSurface { get; }
- public double ScaleFactor => _vulkanSession.Scaling;
- public GRSurfaceOrigin SurfaceOrigin { get; }
- }
- }
- }
|