forked from Mirror/Ryujinx
c8f9292bab
* drop split devices, rebase * add fallback to opengl if vulkan is not available * addressed review * ensure present image references are incremented and decremented when necessary * allow changing vsync for vulkan * fix screenshot on avalonia vulkan * save favorite when toggled * improve sync between popups * use separate devices for each new window * fix crash when closing window * addressed review * don't create the main window with immediate mode * change skia vk delegate to method * update vulkan throwonerror * addressed review
96 lines
No EOL
2.4 KiB
C#
96 lines
No EOL
2.4 KiB
C#
using Avalonia;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Data;
|
|
using Avalonia.Media;
|
|
using Avalonia.Rendering.SceneGraph;
|
|
using Ryujinx.Common.Configuration;
|
|
using SPB.Windowing;
|
|
using System;
|
|
|
|
namespace Ryujinx.Ava.Ui.Controls
|
|
{
|
|
internal abstract class RendererControl : Control
|
|
{
|
|
protected object Image { get; set; }
|
|
|
|
public event EventHandler<EventArgs> RendererInitialized;
|
|
public event EventHandler<Size> SizeChanged;
|
|
|
|
protected Size RenderSize { get; private set; }
|
|
public bool IsStarted { get; private set; }
|
|
|
|
public GraphicsDebugLevel DebugLevel { get; }
|
|
|
|
private bool _isInitialized;
|
|
|
|
protected ICustomDrawOperation DrawOperation { get; private set; }
|
|
|
|
public RendererControl(GraphicsDebugLevel graphicsDebugLevel)
|
|
{
|
|
DebugLevel = graphicsDebugLevel;
|
|
IObservable<Rect> resizeObservable = this.GetObservable(BoundsProperty);
|
|
|
|
resizeObservable.Subscribe(Resized);
|
|
|
|
Focusable = true;
|
|
}
|
|
|
|
protected void Resized(Rect rect)
|
|
{
|
|
SizeChanged?.Invoke(this, rect.Size);
|
|
|
|
if (!rect.IsEmpty)
|
|
{
|
|
RenderSize = rect.Size * VisualRoot.RenderScaling;
|
|
DrawOperation = CreateDrawOperation();
|
|
}
|
|
}
|
|
|
|
protected abstract ICustomDrawOperation CreateDrawOperation();
|
|
protected abstract void CreateWindow();
|
|
|
|
public override void Render(DrawingContext context)
|
|
{
|
|
if (!_isInitialized)
|
|
{
|
|
CreateWindow();
|
|
|
|
OnRendererInitialized();
|
|
_isInitialized = true;
|
|
}
|
|
|
|
if (!IsStarted || Image == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (DrawOperation != null)
|
|
{
|
|
context.Custom(DrawOperation);
|
|
}
|
|
|
|
base.Render(context);
|
|
}
|
|
|
|
protected void OnRendererInitialized()
|
|
{
|
|
RendererInitialized?.Invoke(this, EventArgs.Empty);
|
|
}
|
|
|
|
internal abstract void Present(object image);
|
|
|
|
internal void Start()
|
|
{
|
|
IsStarted = true;
|
|
}
|
|
|
|
internal void Stop()
|
|
{
|
|
IsStarted = false;
|
|
}
|
|
|
|
public abstract void DestroyBackgroundContext();
|
|
internal abstract void MakeCurrent();
|
|
internal abstract void MakeCurrent(SwappableNativeWindowBase window);
|
|
}
|
|
} |