mirror of
https://github.com/SK-la/osu-framework.git
synced 2026-03-13 11:20:31 +00:00
Rename to graphics surface and invert data path
This commit is contained in:
@@ -38,7 +38,7 @@ namespace osu.Framework.Android
|
||||
base.SetupConfig(defaultOverrides);
|
||||
}
|
||||
|
||||
protected override IWindow CreateWindow() => new AndroidGameWindow(gameView);
|
||||
protected override IWindow CreateWindow(GraphicsSurfaceType preferredSurface) => new AndroidGameWindow(gameView);
|
||||
|
||||
public override bool CanExit => false;
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace osu.Framework.iOS
|
||||
true);
|
||||
}
|
||||
|
||||
protected override IWindow CreateWindow() => new IOSGameWindow(gameView);
|
||||
protected override IWindow CreateWindow(GraphicsSurfaceType preferredSurface) => new IOSGameWindow(gameView);
|
||||
|
||||
protected override void SetupConfig(IDictionary<FrameworkSetting, object> defaultOverrides)
|
||||
{
|
||||
|
||||
@@ -23,14 +23,12 @@ namespace osu.Framework.Graphics.OpenGL
|
||||
{
|
||||
internal class GLRenderer : Renderer
|
||||
{
|
||||
public override GraphicsBackend BackendType => GraphicsBackend.OpenGL;
|
||||
|
||||
private IOpenGLWindowGraphics openGLGraphics = null!;
|
||||
private IOpenGLGraphicsSurface openGLSurface = null!;
|
||||
|
||||
public override bool VerticalSync
|
||||
{
|
||||
get => openGLGraphics.VerticalSync;
|
||||
set => openGLGraphics.VerticalSync = value;
|
||||
get => openGLSurface.VerticalSync;
|
||||
set => openGLSurface.VerticalSync = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -49,10 +47,13 @@ namespace osu.Framework.Graphics.OpenGL
|
||||
|
||||
private bool? lastBlendingEnabledState;
|
||||
|
||||
protected override void Initialise(IWindowGraphics graphics)
|
||||
protected override void Initialise(IGraphicsSurface graphicsSurface)
|
||||
{
|
||||
openGLGraphics = graphics as IOpenGLWindowGraphics ?? throw new ArgumentException($"Window must implement {nameof(IOpenGLWindowGraphics)}.");
|
||||
openGLGraphics.MakeCurrent(openGLGraphics.WindowContext);
|
||||
if (graphicsSurface.Type != GraphicsSurfaceType.OpenGL)
|
||||
throw new InvalidOperationException($"{nameof(GLRenderer)} only supports OpenGL graphics surfaces.");
|
||||
|
||||
openGLSurface = (IOpenGLGraphicsSurface)graphicsSurface;
|
||||
openGLSurface.MakeCurrent(openGLSurface.WindowContext);
|
||||
|
||||
string version = GL.GetString(StringName.Version);
|
||||
IsEmbedded = version.Contains("OpenGL ES"); // As defined by https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glGetString.xml
|
||||
@@ -70,7 +71,7 @@ namespace osu.Framework.Graphics.OpenGL
|
||||
GL Vendor: {GL.GetString(StringName.Vendor)}
|
||||
GL Extensions: {GL.GetString(StringName.Extensions)}");
|
||||
|
||||
openGLGraphics.ClearCurrent();
|
||||
openGLSurface.ClearCurrent();
|
||||
}
|
||||
|
||||
protected internal override void BeginFrame(Vector2 windowSize)
|
||||
@@ -83,9 +84,9 @@ namespace osu.Framework.Graphics.OpenGL
|
||||
base.BeginFrame(windowSize);
|
||||
}
|
||||
|
||||
protected internal override void MakeCurrent() => openGLGraphics.MakeCurrent(openGLGraphics.WindowContext);
|
||||
protected internal override void ClearCurrent() => openGLGraphics.ClearCurrent();
|
||||
protected internal override void SwapBuffers() => openGLGraphics.SwapBuffers();
|
||||
protected internal override void MakeCurrent() => openGLSurface.MakeCurrent(openGLSurface.WindowContext);
|
||||
protected internal override void ClearCurrent() => openGLSurface.ClearCurrent();
|
||||
protected internal override void SwapBuffers() => openGLSurface.SwapBuffers();
|
||||
protected internal override void WaitUntilIdle() => GL.Finish();
|
||||
|
||||
public bool BindBuffer(BufferTarget target, int buffer)
|
||||
@@ -180,7 +181,8 @@ namespace osu.Framework.Graphics.OpenGL
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void SetFrameBufferImplementation(IFrameBuffer? frameBuffer) => GL.BindFramebuffer(FramebufferTarget.Framebuffer, ((GLFrameBuffer?)frameBuffer)?.FrameBuffer ?? BackbufferFramebuffer);
|
||||
protected override void SetFrameBufferImplementation(IFrameBuffer? frameBuffer) =>
|
||||
GL.BindFramebuffer(FramebufferTarget.Framebuffer, ((GLFrameBuffer?)frameBuffer)?.FrameBuffer ?? BackbufferFramebuffer);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a frame buffer.
|
||||
@@ -366,7 +368,8 @@ namespace osu.Framework.Graphics.OpenGL
|
||||
return new GLFrameBuffer(this, glFormats, glFilteringMode);
|
||||
}
|
||||
|
||||
protected override INativeTexture CreateNativeTexture(int width, int height, bool manualMipmaps = false, TextureFilteringMode filteringMode = TextureFilteringMode.Linear, Rgba32 initialisationColour = default)
|
||||
protected override INativeTexture CreateNativeTexture(int width, int height, bool manualMipmaps = false, TextureFilteringMode filteringMode = TextureFilteringMode.Linear,
|
||||
Rgba32 initialisationColour = default)
|
||||
{
|
||||
All glFilteringMode;
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ namespace osu.Framework.Graphics.Rendering.Dummy
|
||||
public ref readonly MaskingInfo CurrentMaskingInfo => ref maskingInfo;
|
||||
private readonly MaskingInfo maskingInfo;
|
||||
|
||||
public GraphicsBackend BackendType => default;
|
||||
public bool VerticalSync { get; set; } = true;
|
||||
public RectangleI Viewport => RectangleI.Empty;
|
||||
public RectangleF Ortho => RectangleF.Empty;
|
||||
@@ -49,7 +48,7 @@ namespace osu.Framework.Graphics.Rendering.Dummy
|
||||
WhitePixel = new Texture(new DummyNativeTexture(this), WrapMode.None, WrapMode.None);
|
||||
}
|
||||
|
||||
void IRenderer.Initialise(IWindowGraphics graphics)
|
||||
void IRenderer.Initialise(IGraphicsSurface graphicsSurface)
|
||||
{
|
||||
IsInitialised = true;
|
||||
}
|
||||
|
||||
@@ -42,11 +42,6 @@ namespace osu.Framework.Graphics.Rendering
|
||||
/// </summary>
|
||||
public const int MAX_QUADS = ushort.MaxValue / INDICES_PER_QUAD;
|
||||
|
||||
/// <summary>
|
||||
/// The type of the graphics backend represented by this renderer.
|
||||
/// </summary>
|
||||
GraphicsBackend BackendType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables vertical sync.
|
||||
/// </summary>
|
||||
@@ -142,7 +137,7 @@ namespace osu.Framework.Graphics.Rendering
|
||||
/// <summary>
|
||||
/// Performs a once-off initialisation of this <see cref="IRenderer"/>.
|
||||
/// </summary>
|
||||
protected internal void Initialise(IWindowGraphics graphics);
|
||||
protected internal void Initialise(IGraphicsSurface graphicsSurface);
|
||||
|
||||
/// <summary>
|
||||
/// Resets any states to prepare for drawing a new frame.
|
||||
|
||||
@@ -33,8 +33,6 @@ namespace osu.Framework.Graphics.Rendering
|
||||
/// </summary>
|
||||
private const int vbo_free_check_interval = 300;
|
||||
|
||||
public virtual GraphicsBackend BackendType => GraphicsBackend.OpenGL;
|
||||
|
||||
public abstract bool VerticalSync { get; set; }
|
||||
|
||||
public int MaxTextureSize { get; protected set; } = 4096; // default value is to allow roughly normal flow in cases we don't have graphics context, like headless CI.
|
||||
@@ -133,9 +131,20 @@ namespace osu.Framework.Graphics.Rendering
|
||||
new TextureAtlas(this, TextureAtlas.WHITE_PIXEL_SIZE + TextureAtlas.PADDING, TextureAtlas.WHITE_PIXEL_SIZE + TextureAtlas.PADDING, true).WhitePixel);
|
||||
}
|
||||
|
||||
void IRenderer.Initialise(IWindowGraphics graphics)
|
||||
void IRenderer.Initialise(IGraphicsSurface graphicsSurface)
|
||||
{
|
||||
Initialise(graphics);
|
||||
switch (graphicsSurface.Type)
|
||||
{
|
||||
case GraphicsSurfaceType.OpenGL:
|
||||
Trace.Assert(graphicsSurface is IOpenGLGraphicsSurface, $"Window must implement {nameof(IOpenGLGraphicsSurface)}.");
|
||||
break;
|
||||
|
||||
case GraphicsSurfaceType.Metal:
|
||||
Trace.Assert(graphicsSurface is IMetalGraphicsSurface, $"Window graphics API must implement {nameof(IMetalGraphicsSurface)}.");
|
||||
break;
|
||||
}
|
||||
|
||||
Initialise(graphicsSurface);
|
||||
|
||||
defaultQuadBatch = CreateQuadBatch<TexturedVertex2D>(100, 1000);
|
||||
resetScheduler.AddDelayed(disposalQueue.CheckPendingDisposals, 0, true);
|
||||
@@ -280,7 +289,7 @@ namespace osu.Framework.Graphics.Rendering
|
||||
/// <summary>
|
||||
/// Performs a once-off initialisation of this <see cref="Renderer"/>.
|
||||
/// </summary>
|
||||
protected abstract void Initialise(IWindowGraphics graphics);
|
||||
protected abstract void Initialise(IGraphicsSurface graphicsSurface);
|
||||
|
||||
/// <summary>
|
||||
/// Swaps the back buffer with the front buffer to display the new frame.
|
||||
|
||||
@@ -15,36 +15,12 @@ using osuTK.Graphics;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using Veldrid;
|
||||
using Veldrid.OpenGL;
|
||||
using GraphicsBackend = osu.Framework.Platform.GraphicsBackend;
|
||||
using PixelFormat = Veldrid.PixelFormat;
|
||||
|
||||
namespace osu.Framework.Graphics.Veldrid
|
||||
{
|
||||
internal class VeldridRenderer : Renderer
|
||||
{
|
||||
private IWindowGraphics graphics = null!;
|
||||
|
||||
public override GraphicsBackend BackendType
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (RuntimeInfo.OS)
|
||||
{
|
||||
case RuntimeInfo.Platform.Windows:
|
||||
return GraphicsBackend.Direct3D11;
|
||||
|
||||
case RuntimeInfo.Platform.macOS:
|
||||
case RuntimeInfo.Platform.iOS:
|
||||
return GraphicsBackend.Metal;
|
||||
|
||||
default:
|
||||
case RuntimeInfo.Platform.Linux:
|
||||
case RuntimeInfo.Platform.Android:
|
||||
return GraphicsBackend.Vulkan;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool VerticalSync
|
||||
{
|
||||
get => Device.SyncToVerticalBlank;
|
||||
@@ -57,6 +33,8 @@ namespace osu.Framework.Graphics.Veldrid
|
||||
|
||||
public CommandList Commands { get; private set; } = null!;
|
||||
|
||||
private IGraphicsSurface graphicsSurface = null!;
|
||||
|
||||
private GraphicsPipelineDescription pipeline = new GraphicsPipelineDescription
|
||||
{
|
||||
RasterizerState = RasterizerStateDescription.CullNone,
|
||||
@@ -64,15 +42,13 @@ namespace osu.Framework.Graphics.Veldrid
|
||||
ShaderSet = { VertexLayouts = new VertexLayoutDescription[1] }
|
||||
};
|
||||
|
||||
protected override void Initialise(IWindowGraphics graphics)
|
||||
protected override void Initialise(IGraphicsSurface graphicsSurface)
|
||||
{
|
||||
// Veldrid must either be initialised on the main/"input" thread, or in a separate thread away from the draw thread at least.
|
||||
// Otherwise the window may not render anything on some platforms (macOS at least).
|
||||
Debug.Assert(!ThreadSafety.IsDrawThread, "Veldrid cannot be initialised on the draw thread.");
|
||||
|
||||
this.graphics = graphics;
|
||||
|
||||
var size = graphics.GetDrawableSize();
|
||||
this.graphicsSurface = graphicsSurface;
|
||||
|
||||
var options = new GraphicsDeviceOptions
|
||||
{
|
||||
@@ -86,6 +62,8 @@ namespace osu.Framework.Graphics.Veldrid
|
||||
ResourceBindingModel = ResourceBindingModel.Improved,
|
||||
};
|
||||
|
||||
var size = graphicsSurface.GetDrawableSize();
|
||||
|
||||
var swapchain = new SwapchainDescription
|
||||
{
|
||||
Width = (uint)size.Width,
|
||||
@@ -100,11 +78,11 @@ namespace osu.Framework.Graphics.Veldrid
|
||||
switch (RuntimeInfo.OS)
|
||||
{
|
||||
case RuntimeInfo.Platform.Windows:
|
||||
swapchain.Source = SwapchainSource.CreateWin32(graphics.WindowHandle, IntPtr.Zero);
|
||||
swapchain.Source = SwapchainSource.CreateWin32(graphicsSurface.WindowHandle, IntPtr.Zero);
|
||||
break;
|
||||
|
||||
case RuntimeInfo.Platform.macOS:
|
||||
var metalGraphics = graphics as IMetalWindowGraphics ?? throw new InvalidOperationException($"Window graphics API must implement {nameof(IMetalWindowGraphics)}.");
|
||||
var metalGraphics = (IMetalGraphicsSurface)graphicsSurface;
|
||||
swapchain.Source = SwapchainSource.CreateNSView(metalGraphics.CreateMetalView());
|
||||
break;
|
||||
|
||||
@@ -114,10 +92,10 @@ namespace osu.Framework.Graphics.Veldrid
|
||||
break;
|
||||
}
|
||||
|
||||
switch (BackendType)
|
||||
switch (graphicsSurface.Type)
|
||||
{
|
||||
case GraphicsBackend.OpenGL:
|
||||
var openGLGraphics = graphics as IOpenGLWindowGraphics ?? throw new InvalidOperationException($"Window graphics API must implement {nameof(IOpenGLWindowGraphics)}");
|
||||
case GraphicsSurfaceType.OpenGL:
|
||||
var openGLGraphics = (IOpenGLGraphicsSurface)graphicsSurface;
|
||||
|
||||
Device = GraphicsDevice.CreateOpenGL(options, new OpenGLPlatformInfo(
|
||||
openGLContextHandle: openGLGraphics.WindowContext,
|
||||
@@ -132,17 +110,17 @@ namespace osu.Framework.Graphics.Veldrid
|
||||
Device.LogOpenGL(out maxTextureSize);
|
||||
break;
|
||||
|
||||
case GraphicsBackend.Vulkan:
|
||||
case GraphicsSurfaceType.Vulkan:
|
||||
Device = GraphicsDevice.CreateVulkan(options, swapchain);
|
||||
Device.LogVulkan(out maxTextureSize);
|
||||
break;
|
||||
|
||||
case GraphicsBackend.Direct3D11:
|
||||
case GraphicsSurfaceType.Direct3D11:
|
||||
Device = GraphicsDevice.CreateD3D11(options, swapchain);
|
||||
Device.LogD3D11(out maxTextureSize);
|
||||
break;
|
||||
|
||||
case GraphicsBackend.Metal:
|
||||
case GraphicsSurfaceType.Metal:
|
||||
Device = GraphicsDevice.CreateMetal(options, swapchain);
|
||||
Device.LogMetal(out maxTextureSize);
|
||||
break;
|
||||
@@ -183,18 +161,18 @@ namespace osu.Framework.Graphics.Veldrid
|
||||
|
||||
protected internal override void MakeCurrent()
|
||||
{
|
||||
if (BackendType == GraphicsBackend.OpenGL)
|
||||
if (graphicsSurface.Type == GraphicsSurfaceType.OpenGL)
|
||||
{
|
||||
var openGLGraphics = (IOpenGLWindowGraphics)graphics;
|
||||
var openGLGraphics = (IOpenGLGraphicsSurface)graphicsSurface;
|
||||
openGLGraphics.MakeCurrent(openGLGraphics.WindowContext);
|
||||
}
|
||||
}
|
||||
|
||||
protected internal override void ClearCurrent()
|
||||
{
|
||||
if (BackendType == GraphicsBackend.OpenGL)
|
||||
if (graphicsSurface.Type == GraphicsSurfaceType.OpenGL)
|
||||
{
|
||||
var openGLGraphics = (IOpenGLWindowGraphics)graphics;
|
||||
var openGLGraphics = (IOpenGLGraphicsSurface)graphicsSurface;
|
||||
openGLGraphics.ClearCurrent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ namespace osu.Framework.Platform
|
||||
/// <summary>
|
||||
/// Creates the game window for the host. Should be implemented per-platform if required.
|
||||
/// </summary>
|
||||
protected virtual IWindow CreateWindow(GraphicsBackend backend) => null;
|
||||
protected virtual IWindow CreateWindow(GraphicsSurfaceType preferredSurface) => null;
|
||||
|
||||
[CanBeNull]
|
||||
public virtual Clipboard GetClipboard() => null;
|
||||
@@ -530,7 +530,7 @@ namespace osu.Framework.Platform
|
||||
{
|
||||
Renderer.SwapBuffers();
|
||||
|
||||
if (Renderer.BackendType == GraphicsBackend.OpenGL && Renderer.VerticalSync)
|
||||
if (Window.GraphicsSurface.Type == GraphicsSurfaceType.OpenGL && Renderer.VerticalSync)
|
||||
// without waiting (i.e. glFinish), vsync is basically unplayable due to the extra latency introduced.
|
||||
// we will likely want to give the user control over this in the future as an advanced setting.
|
||||
Renderer.WaitUntilIdle();
|
||||
@@ -699,7 +699,7 @@ namespace osu.Framework.Platform
|
||||
|
||||
SetupForRun();
|
||||
|
||||
Window = CreateWindow(Renderer.BackendType);
|
||||
Window = CreateWindow(GraphicsSurfaceType.OpenGL);
|
||||
|
||||
populateInputHandlers();
|
||||
|
||||
@@ -714,7 +714,7 @@ namespace osu.Framework.Platform
|
||||
Window.Create();
|
||||
Window.Title = $@"osu!framework (running ""{Name}"")";
|
||||
|
||||
Renderer.Initialise(Window.Graphics);
|
||||
Renderer.Initialise(Window);
|
||||
|
||||
currentDisplayMode = Window.CurrentDisplayMode.GetBoundCopy();
|
||||
currentDisplayMode.BindValueChanged(_ => updateFrameSyncMode());
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.ComponentModel;
|
||||
using osu.Framework.Graphics.Rendering;
|
||||
|
||||
namespace osu.Framework.Platform
|
||||
{
|
||||
/// <summary>
|
||||
/// The graphics backend represented by the <see cref="IRenderer"/>.
|
||||
/// </summary>
|
||||
public enum GraphicsBackend
|
||||
{
|
||||
[Description("OpenGL")]
|
||||
OpenGL,
|
||||
|
||||
[Description("Metal")]
|
||||
Metal,
|
||||
|
||||
[Description("Vulkan")]
|
||||
Vulkan,
|
||||
|
||||
[Description("Direct3D 11")]
|
||||
Direct3D11,
|
||||
}
|
||||
}
|
||||
37
osu.Framework/Platform/GraphicsSurfaceType.cs
Normal file
37
osu.Framework/Platform/GraphicsSurfaceType.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace osu.Framework.Platform
|
||||
{
|
||||
/// <summary>
|
||||
/// The graphics surface of an <see cref="IWindow"/>.
|
||||
/// </summary>
|
||||
public enum GraphicsSurfaceType
|
||||
{
|
||||
/// <summary>
|
||||
/// An OpenGL graphics surface. The window must implement <see cref="IOpenGLGraphicsSurface"/>.
|
||||
/// </summary>
|
||||
[Description("OpenGL")]
|
||||
OpenGL,
|
||||
|
||||
/// <summary>
|
||||
/// A Metal graphics surface. The window must implement <see cref="IMetalGraphicsSurface"/>.
|
||||
/// </summary>
|
||||
[Description("Metal")]
|
||||
Metal,
|
||||
|
||||
/// <summary>
|
||||
/// A Vulkan graphics surface.
|
||||
/// </summary>
|
||||
[Description("Vulkan")]
|
||||
Vulkan,
|
||||
|
||||
/// <summary>
|
||||
/// A Direct3D11 graphics surface.
|
||||
/// </summary>
|
||||
[Description("Direct3D 11")]
|
||||
Direct3D11,
|
||||
}
|
||||
}
|
||||
@@ -7,9 +7,9 @@ using System.Drawing;
|
||||
namespace osu.Framework.Platform
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the graphics API provided by an <see cref="IWindow"/>.
|
||||
/// Represents the graphics API surface provided by an <see cref="IWindow"/>.
|
||||
/// </summary>
|
||||
public interface IWindowGraphics
|
||||
public interface IGraphicsSurface
|
||||
{
|
||||
/// <summary>
|
||||
/// A pointer representing a handle to this window, provided by the operating system.
|
||||
@@ -23,9 +23,9 @@ namespace osu.Framework.Platform
|
||||
IntPtr DisplayHandle { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The type of the graphics backend represented by this renderer.
|
||||
/// The type of surface.
|
||||
/// </summary>
|
||||
GraphicsBackend BackendType { get; }
|
||||
GraphicsSurfaceType Type { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Performs an initialisation of the graphics backend after <see cref="IWindow"/> has been created.
|
||||
@@ -8,7 +8,7 @@ namespace osu.Framework.Platform
|
||||
/// <summary>
|
||||
/// Represents Metal-specific graphics API provided by an <see cref="IWindow"/>.
|
||||
/// </summary>
|
||||
public interface IMetalWindowGraphics
|
||||
public interface IMetalGraphicsSurface
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an NSView backed with a Metal layer.
|
||||
@@ -8,7 +8,7 @@ namespace osu.Framework.Platform
|
||||
/// <summary>
|
||||
/// Represents OpenGL-specific graphics API provided by an <see cref="IWindow"/>.
|
||||
/// </summary>
|
||||
public interface IOpenGLWindowGraphics
|
||||
public interface IOpenGLGraphicsSurface
|
||||
{
|
||||
/// <summary>
|
||||
/// Enables or disables vertical sync.
|
||||
@@ -21,7 +21,7 @@ namespace osu.Framework.Platform
|
||||
/// <summary>
|
||||
/// The graphics API for this window.
|
||||
/// </summary>
|
||||
internal IWindowGraphics Graphics { get; }
|
||||
internal IGraphicsSurface GraphicsSurface { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Cycles through the available <see cref="WindowMode"/>s as determined by <see cref="SupportedWindowModes"/>.
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace osu.Framework.Platform.Linux
|
||||
base.SetupForRun();
|
||||
}
|
||||
|
||||
protected override IWindow CreateWindow(GraphicsBackend backend) => new SDL2DesktopWindow(backend);
|
||||
protected override IWindow CreateWindow(GraphicsSurfaceType preferredSurface) => new SDL2DesktopWindow(preferredSurface);
|
||||
|
||||
public override IEnumerable<string> UserStoragePaths
|
||||
{
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace osu.Framework.Platform.MacOS
|
||||
{
|
||||
}
|
||||
|
||||
protected override IWindow CreateWindow(GraphicsBackend backend) => new MacOSWindow(backend);
|
||||
protected override IWindow CreateWindow(GraphicsSurfaceType preferredSurface) => new MacOSWindow(preferredSurface);
|
||||
|
||||
public override IEnumerable<string> UserStoragePaths
|
||||
{
|
||||
@@ -50,7 +50,7 @@ namespace osu.Framework.Platform.MacOS
|
||||
base.Swap();
|
||||
|
||||
// It has been reported that this helps performance on macOS (https://github.com/ppy/osu/issues/7447)
|
||||
if (Renderer.BackendType == GraphicsBackend.OpenGL && !Renderer.VerticalSync)
|
||||
if (Window.GraphicsSurface.Type == GraphicsSurfaceType.OpenGL && !Renderer.VerticalSync)
|
||||
Renderer.WaitUntilIdle();
|
||||
}
|
||||
|
||||
|
||||
@@ -24,8 +24,8 @@ namespace osu.Framework.Platform.MacOS
|
||||
private IntPtr originalScrollWheel;
|
||||
private ScrollWheelDelegate scrollWheelHandler;
|
||||
|
||||
public MacOSWindow(GraphicsBackend backend)
|
||||
: base(backend)
|
||||
public MacOSWindow(GraphicsSurfaceType surfaceType)
|
||||
: base(surfaceType)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -12,11 +12,11 @@ using osuTK.Platform;
|
||||
|
||||
namespace osu.Framework.Platform
|
||||
{
|
||||
public class OsuTKWindowGraphics : IWindowGraphics, IOpenGLWindowGraphics
|
||||
public class OsuTKGraphicsSurface : IGraphicsSurface, IOpenGLGraphicsSurface
|
||||
{
|
||||
private readonly IGameWindow window;
|
||||
|
||||
public GraphicsBackend BackendType => GraphicsBackend.OpenGL;
|
||||
public GraphicsSurfaceType Type => GraphicsSurfaceType.OpenGL;
|
||||
|
||||
public IntPtr WindowHandle => window.WindowInfo.Handle;
|
||||
public IntPtr DisplayHandle => throw new NotSupportedException($@"{nameof(DisplayHandle)} is not supported.");
|
||||
@@ -29,7 +29,7 @@ namespace osu.Framework.Platform
|
||||
internal Version GLSLVersion;
|
||||
internal bool IsEmbedded;
|
||||
|
||||
public OsuTKWindowGraphics(IGameWindow window)
|
||||
public OsuTKGraphicsSurface(IGameWindow window)
|
||||
{
|
||||
this.window = window;
|
||||
}
|
||||
@@ -24,9 +24,8 @@ namespace osu.Framework.Platform
|
||||
{
|
||||
public abstract class OsuTKWindow : IWindow, IGameWindow
|
||||
{
|
||||
private readonly IWindowGraphics graphics;
|
||||
|
||||
IWindowGraphics IWindow.Graphics => graphics;
|
||||
private readonly IGraphicsSurface graphicsSurface;
|
||||
IGraphicsSurface IWindow.GraphicsSurface => graphicsSurface;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IGraphicsContext"/> associated with this <see cref="OsuTKWindow"/>.
|
||||
@@ -142,8 +141,8 @@ namespace osu.Framework.Platform
|
||||
|
||||
UpdateFrame += (_, _) => UpdateFrameScheduler.Update();
|
||||
|
||||
graphics = new OsuTKWindowGraphics(this);
|
||||
graphics.Initialise();
|
||||
graphicsSurface = new OsuTKGraphicsSurface(this);
|
||||
graphicsSurface.Initialise();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -903,18 +903,18 @@ namespace osu.Framework.Platform.SDL2
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static SDL.SDL_WindowFlags ToFlags(this GraphicsBackend backend)
|
||||
public static SDL.SDL_WindowFlags ToFlags(this GraphicsSurfaceType surfaceType)
|
||||
{
|
||||
switch (backend)
|
||||
switch (surfaceType)
|
||||
{
|
||||
case GraphicsBackend.OpenGL:
|
||||
case GraphicsSurfaceType.OpenGL:
|
||||
return SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL;
|
||||
|
||||
case GraphicsBackend.Vulkan when !RuntimeInfo.IsApple:
|
||||
case GraphicsSurfaceType.Vulkan when !RuntimeInfo.IsApple:
|
||||
return SDL.SDL_WindowFlags.SDL_WINDOW_VULKAN;
|
||||
|
||||
case GraphicsBackend.Metal:
|
||||
case GraphicsBackend.Vulkan when RuntimeInfo.IsApple:
|
||||
case GraphicsSurfaceType.Metal:
|
||||
case GraphicsSurfaceType.Vulkan when RuntimeInfo.IsApple:
|
||||
return SDL.SDL_WindowFlags.SDL_WINDOW_METAL;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ using SDL2;
|
||||
|
||||
namespace osu.Framework.Platform.SDL2
|
||||
{
|
||||
public class SDL2WindowGraphics : IWindowGraphics, IOpenGLWindowGraphics, IMetalWindowGraphics
|
||||
public class SDL2GraphicsSurface : IGraphicsSurface, IOpenGLGraphicsSurface, IMetalGraphicsSurface
|
||||
{
|
||||
private readonly SDL2DesktopWindow window;
|
||||
|
||||
@@ -22,21 +22,32 @@ namespace osu.Framework.Platform.SDL2
|
||||
public IntPtr WindowHandle => window.WindowHandle;
|
||||
public IntPtr DisplayHandle => window.DisplayHandle;
|
||||
|
||||
public GraphicsBackend BackendType { get; }
|
||||
public GraphicsSurfaceType Type { get; }
|
||||
|
||||
public SDL2WindowGraphics(SDL2DesktopWindow window, GraphicsBackend backend)
|
||||
public SDL2GraphicsSurface(SDL2DesktopWindow window, GraphicsSurfaceType surfaceType)
|
||||
{
|
||||
this.window = window;
|
||||
Type = surfaceType;
|
||||
|
||||
BackendType = backend;
|
||||
switch (surfaceType)
|
||||
{
|
||||
case GraphicsSurfaceType.OpenGL:
|
||||
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_STENCIL_SIZE, 8);
|
||||
break;
|
||||
|
||||
if (backend == GraphicsBackend.OpenGL)
|
||||
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_STENCIL_SIZE, 8);
|
||||
case GraphicsSurfaceType.Vulkan:
|
||||
case GraphicsSurfaceType.Metal:
|
||||
case GraphicsSurfaceType.Direct3D11:
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentException($"Unexpected graphics surface: {Type}.", nameof(surfaceType));
|
||||
}
|
||||
}
|
||||
|
||||
public void Initialise()
|
||||
{
|
||||
if (BackendType == GraphicsBackend.OpenGL)
|
||||
if (Type == GraphicsSurfaceType.OpenGL)
|
||||
initialiseOpenGL();
|
||||
}
|
||||
|
||||
@@ -44,27 +55,25 @@ namespace osu.Framework.Platform.SDL2
|
||||
{
|
||||
int width, height;
|
||||
|
||||
switch (BackendType)
|
||||
switch (Type)
|
||||
{
|
||||
case GraphicsBackend.OpenGL:
|
||||
case GraphicsSurfaceType.OpenGL:
|
||||
default:
|
||||
SDL.SDL_GL_GetDrawableSize(window.SDLWindowHandle, out width, out height);
|
||||
break;
|
||||
|
||||
case GraphicsBackend.Vulkan:
|
||||
case GraphicsSurfaceType.Vulkan:
|
||||
SDL.SDL_Vulkan_GetDrawableSize(window.SDLWindowHandle, out width, out height);
|
||||
break;
|
||||
|
||||
case GraphicsBackend.Metal:
|
||||
case GraphicsSurfaceType.Metal:
|
||||
SDL.SDL_Metal_GetDrawableSize(window.SDLWindowHandle, out width, out height);
|
||||
break;
|
||||
|
||||
case GraphicsBackend.Direct3D11:
|
||||
case GraphicsSurfaceType.Direct3D11:
|
||||
// todo: SDL has no "drawable size" method for D3D11, return window size for now.
|
||||
SDL.SDL_GetWindowSize(window.SDLWindowHandle, out width, out height);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InvalidOperationException($"Unexpected graphics backend: {BackendType}.");
|
||||
}
|
||||
|
||||
return new Size(width, height);
|
||||
@@ -140,27 +149,27 @@ namespace osu.Framework.Platform.SDL2
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool IOpenGLWindowGraphics.VerticalSync
|
||||
bool IOpenGLGraphicsSurface.VerticalSync
|
||||
{
|
||||
get => SDL.SDL_GL_GetSwapInterval() != 0;
|
||||
set => SDL.SDL_GL_SetSwapInterval(value ? 1 : 0);
|
||||
}
|
||||
|
||||
IntPtr IOpenGLWindowGraphics.WindowContext => context;
|
||||
IntPtr IOpenGLWindowGraphics.CurrentContext => SDL.SDL_GL_GetCurrentContext();
|
||||
IntPtr IOpenGLGraphicsSurface.WindowContext => context;
|
||||
IntPtr IOpenGLGraphicsSurface.CurrentContext => SDL.SDL_GL_GetCurrentContext();
|
||||
|
||||
void IOpenGLWindowGraphics.SwapBuffers() => SDL.SDL_GL_SwapWindow(window.SDLWindowHandle);
|
||||
void IOpenGLWindowGraphics.CreateContext() => SDL.SDL_GL_CreateContext(window.SDLWindowHandle);
|
||||
void IOpenGLWindowGraphics.DeleteContext(IntPtr context) => SDL.SDL_GL_DeleteContext(context);
|
||||
void IOpenGLWindowGraphics.MakeCurrent(IntPtr context) => SDL.SDL_GL_MakeCurrent(window.SDLWindowHandle, context);
|
||||
void IOpenGLWindowGraphics.ClearCurrent() => SDL.SDL_GL_MakeCurrent(window.SDLWindowHandle, IntPtr.Zero);
|
||||
IntPtr IOpenGLWindowGraphics.GetProcAddress(string symbol) => getProcAddress(symbol);
|
||||
void IOpenGLGraphicsSurface.SwapBuffers() => SDL.SDL_GL_SwapWindow(window.SDLWindowHandle);
|
||||
void IOpenGLGraphicsSurface.CreateContext() => SDL.SDL_GL_CreateContext(window.SDLWindowHandle);
|
||||
void IOpenGLGraphicsSurface.DeleteContext(IntPtr context) => SDL.SDL_GL_DeleteContext(context);
|
||||
void IOpenGLGraphicsSurface.MakeCurrent(IntPtr context) => SDL.SDL_GL_MakeCurrent(window.SDLWindowHandle, context);
|
||||
void IOpenGLGraphicsSurface.ClearCurrent() => SDL.SDL_GL_MakeCurrent(window.SDLWindowHandle, IntPtr.Zero);
|
||||
IntPtr IOpenGLGraphicsSurface.GetProcAddress(string symbol) => getProcAddress(symbol);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Metal-specific implementation
|
||||
|
||||
IntPtr IMetalWindowGraphics.CreateMetalView() => SDL.SDL_Metal_CreateView(window.SDLWindowHandle);
|
||||
IntPtr IMetalGraphicsSurface.CreateMetalView() => SDL.SDL_Metal_CreateView(window.SDLWindowHandle);
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -28,9 +28,8 @@ namespace osu.Framework.Platform
|
||||
{
|
||||
internal IntPtr SDLWindowHandle { get; private set; } = IntPtr.Zero;
|
||||
|
||||
private readonly SDL2WindowGraphics graphics;
|
||||
|
||||
IWindowGraphics IWindow.Graphics => graphics;
|
||||
private readonly SDL2GraphicsSurface graphicsSurface;
|
||||
IGraphicsSurface IWindow.GraphicsSurface => graphicsSurface;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if window has been created.
|
||||
@@ -160,7 +159,7 @@ namespace osu.Framework.Platform
|
||||
[UsedImplicitly]
|
||||
private SDL.SDL_EventFilter? eventFilterDelegate;
|
||||
|
||||
public SDL2DesktopWindow(GraphicsBackend backend)
|
||||
public SDL2DesktopWindow(GraphicsSurfaceType surfaceType)
|
||||
{
|
||||
if (SDL.SDL_Init(SDL.SDL_INIT_VIDEO | SDL.SDL_INIT_GAMECONTROLLER) < 0)
|
||||
{
|
||||
@@ -176,8 +175,7 @@ namespace osu.Framework.Platform
|
||||
Logger.Log($@"SDL {category.ReadableName()} log [{priority.ReadableName()}]: {message}");
|
||||
}, IntPtr.Zero);
|
||||
|
||||
graphics = CreateGraphics(backend);
|
||||
|
||||
graphicsSurface = new SDL2GraphicsSurface(this, surfaceType);
|
||||
SupportedWindowModes = new BindableList<WindowMode>(DefaultSupportedWindowModes);
|
||||
|
||||
CursorStateBindable.ValueChanged += evt =>
|
||||
@@ -202,7 +200,7 @@ namespace osu.Framework.Platform
|
||||
SDL.SDL_WindowFlags.SDL_WINDOW_HIDDEN; // shown after first swap to avoid white flash on startup (windows)
|
||||
|
||||
flags |= WindowState.ToFlags();
|
||||
flags |= graphics.BackendType.ToFlags();
|
||||
flags |= graphicsSurface.Type.ToFlags();
|
||||
|
||||
SDL.SDL_SetHint(SDL.SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, "1");
|
||||
SDL.SDL_SetHint(SDL.SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "1");
|
||||
@@ -219,7 +217,7 @@ namespace osu.Framework.Platform
|
||||
|
||||
Exists = true;
|
||||
|
||||
graphics.Initialise();
|
||||
graphicsSurface.Initialise();
|
||||
|
||||
initialiseWindowingAfterCreation();
|
||||
}
|
||||
@@ -446,8 +444,6 @@ namespace osu.Framework.Platform
|
||||
|
||||
#endregion
|
||||
|
||||
protected virtual SDL2WindowGraphics CreateGraphics(GraphicsBackend backend) => new SDL2WindowGraphics(this, backend);
|
||||
|
||||
public void SetIconFromStream(Stream stream)
|
||||
{
|
||||
using (var ms = new MemoryStream())
|
||||
|
||||
@@ -24,11 +24,11 @@ namespace osu.Framework.Platform.Windows
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
protected override void Initialise(IWindowGraphics graphics)
|
||||
protected override void Initialise(IGraphicsSurface graphicsSurface)
|
||||
{
|
||||
base.Initialise(graphics);
|
||||
base.Initialise(graphicsSurface);
|
||||
|
||||
WindowsWindow window = (WindowsWindow)host.Window;
|
||||
WindowsWindow windowsWindow = (WindowsWindow)host.Window;
|
||||
|
||||
bool isIntel = GL.GetString(StringName.Vendor).Trim() == "Intel";
|
||||
|
||||
@@ -40,9 +40,9 @@ namespace osu.Framework.Platform.Windows
|
||||
else
|
||||
{
|
||||
// For all other vendors, support depends on the system setup - e.g. NVIDIA Optimus doesn't support exclusive fullscreen with OpenGL.
|
||||
window.IsActive.BindValueChanged(_ => detectFullscreenCapability(window));
|
||||
window.WindowStateChanged += _ => detectFullscreenCapability(window);
|
||||
detectFullscreenCapability(window);
|
||||
windowsWindow.IsActive.BindValueChanged(_ => detectFullscreenCapability(windowsWindow));
|
||||
windowsWindow.WindowStateChanged += _ => detectFullscreenCapability(windowsWindow);
|
||||
detectFullscreenCapability(windowsWindow);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace osu.Framework.Platform.Windows
|
||||
timePeriod = new TimePeriod(1);
|
||||
}
|
||||
|
||||
protected override IWindow CreateWindow(GraphicsBackend backend) => new WindowsWindow(backend);
|
||||
protected override IWindow CreateWindow(GraphicsSurfaceType preferredSurface) => new WindowsWindow(preferredSurface);
|
||||
|
||||
public override IEnumerable<KeyBinding> PlatformKeyBindings => base.PlatformKeyBindings.Concat(new[]
|
||||
{
|
||||
|
||||
@@ -30,8 +30,8 @@ namespace osu.Framework.Platform.Windows
|
||||
|
||||
private const int wm_killfocus = 8;
|
||||
|
||||
public WindowsWindow(GraphicsBackend backend)
|
||||
: base(backend)
|
||||
public WindowsWindow(GraphicsSurfaceType surfaceType)
|
||||
: base(surfaceType)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user