Replace PreferGLES settings flag with GLProfile enum.

This commit is contained in:
Paul Chote
2020-04-21 10:42:02 +01:00
committed by abcdefg30
parent 91c4179f05
commit 839be24053
6 changed files with 81 additions and 32 deletions

View File

@@ -23,7 +23,7 @@ namespace OpenRA
public interface IPlatform
{
IPlatformWindow CreateWindow(Size size, WindowMode windowMode, float scaleModifier, int batchSize, int videoDisplay);
IPlatformWindow CreateWindow(Size size, WindowMode windowMode, float scaleModifier, int batchSize, int videoDisplay, GLProfile profile);
ISoundEngine CreateSound(string device);
IFont CreateFont(byte[] data);
}
@@ -70,6 +70,10 @@ namespace OpenRA
void SetHardwareCursor(IHardwareCursor cursor);
void SetRelativeMouseMode(bool mode);
void SetScaleModifier(float scale);
GLProfile GLProfile { get; }
GLProfile[] SupportedGLProfiles { get; }
}
public interface IGraphicsContext : IDisposable

View File

@@ -75,7 +75,10 @@ namespace OpenRA
this.platform = platform;
var resolution = GetResolution(graphicSettings);
Window = platform.CreateWindow(new Size(resolution.Width, resolution.Height), graphicSettings.Mode, graphicSettings.UIScale, graphicSettings.BatchSize, graphicSettings.VideoDisplay);
Window = platform.CreateWindow(new Size(resolution.Width, resolution.Height),
graphicSettings.Mode, graphicSettings.UIScale, graphicSettings.BatchSize,
graphicSettings.VideoDisplay, graphicSettings.GLProfile);
Context = Window.Context;
TempBufferSize = graphicSettings.BatchSize;
@@ -310,6 +313,8 @@ namespace OpenRA
public Size NativeResolution { get { return Window.NativeWindowSize; } }
public float WindowScale { get { return Window.EffectiveWindowScale; } }
public float NativeWindowScale { get { return Window.NativeWindowScale; } }
public GLProfile GLProfile { get { return Window.GLProfile; } }
public GLProfile[] SupportedGLProfiles { get { return Window.SupportedGLProfiles; } }
public interface IBatchRenderer { void Flush(); }

View File

@@ -172,12 +172,14 @@ namespace OpenRA
[Desc("Disable operating-system provided cursor rendering.")]
public bool DisableHardwareCursors = false;
[Desc("Use OpenGL ES if both ES and regular OpenGL are available.")]
public bool PreferGLES = false;
[Desc("Display index to use in a multi-monitor fullscreen setup.")]
public int VideoDisplay = 0;
[Desc("Preferred OpenGL profile to use.",
"Modern: OpenGL Core Profile 3.2 or greater.",
"Embedded: OpenGL ES 3.0 or greater.")]
public GLProfile GLProfile = GLProfile.Modern;
public int BatchSize = 8192;
public int SheetSize = 2048;

View File

@@ -122,6 +122,7 @@ namespace OpenRA.Mods.Common.LoadScreens
}
// Saved settings may have been invalidated by a hardware change
Game.Settings.Graphics.GLProfile = Game.Renderer.GLProfile;
Game.Settings.Graphics.VideoDisplay = Game.Renderer.CurrentDisplay;
// If a ModContent section is defined then we need to make sure that the

View File

@@ -16,9 +16,9 @@ namespace OpenRA.Platforms.Default
{
public class DefaultPlatform : IPlatform
{
public IPlatformWindow CreateWindow(Size size, WindowMode windowMode, float scaleModifier, int batchSize, int videoDisplay)
public IPlatformWindow CreateWindow(Size size, WindowMode windowMode, float scaleModifier, int batchSize, int videoDisplay, GLProfile profile)
{
return new Sdl2PlatformWindow(size, windowMode, scaleModifier, batchSize, videoDisplay);
return new Sdl2PlatformWindow(size, windowMode, scaleModifier, batchSize, videoDisplay, profile);
}
public ISoundEngine CreateSound(string device)

View File

@@ -12,6 +12,7 @@
using System;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using OpenRA.Primitives;
using SDL2;
@@ -34,6 +35,8 @@ namespace OpenRA.Platforms.Default
float windowScale = 1f;
int2? lockedMousePosition;
float scaleModifier;
readonly GLProfile profile;
readonly GLProfile[] supportedProfiles;
internal IntPtr Window
{
@@ -107,12 +110,31 @@ namespace OpenRA.Platforms.Default
public bool HasInputFocus { get; internal set; }
public GLProfile GLProfile
{
get
{
lock (syncObject)
return profile;
}
}
public GLProfile[] SupportedGLProfiles
{
get
{
lock (syncObject)
return supportedProfiles;
}
}
public event Action<float, float, float, float> OnWindowScaleChanged = (oldNative, oldEffective, newNative, newEffective) => { };
[DllImport("user32.dll")]
static extern bool SetProcessDPIAware();
public Sdl2PlatformWindow(Size requestEffectiveWindowSize, WindowMode windowMode, float scaleModifier, int batchSize, int videoDisplay)
public Sdl2PlatformWindow(Size requestEffectiveWindowSize, WindowMode windowMode,
float scaleModifier, int batchSize, int videoDisplay, GLProfile requestProfile)
{
// Lock the Window/Surface properties until initialization is complete
lock (syncObject)
@@ -124,31 +146,24 @@ namespace OpenRA.Platforms.Default
SetProcessDPIAware();
SDL.SDL_Init(SDL.SDL_INIT_NOPARACHUTE | SDL.SDL_INIT_VIDEO);
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_DOUBLEBUFFER, 1);
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_RED_SIZE, 8);
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_GREEN_SIZE, 8);
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_BLUE_SIZE, 8);
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_ALPHA_SIZE, 0);
// Decide between OpenGL and OpenGL ES rendering
// Test whether we can use the preferred renderer and fall back to the other if that fails
// If neither works we will throw a graphics error later when trying to create the real window
bool useGLES;
if (Game.Settings.Graphics.PreferGLES)
useGLES = CanCreateGLWindow(3, 0, SDL.SDL_GLprofile.SDL_GL_CONTEXT_PROFILE_ES);
// Decide which OpenGL profile to use.
// We first need to query the available profiles on Windows/Linux.
// On macOS, known/consistent OpenGL support is provided by the OS.
if (Platform.CurrentPlatform == PlatformType.OSX)
supportedProfiles = new[] { GLProfile.Modern };
else
useGLES = !CanCreateGLWindow(3, 2, SDL.SDL_GLprofile.SDL_GL_CONTEXT_PROFILE_CORE);
supportedProfiles = new[] { GLProfile.Modern, GLProfile.Embedded }
.Where(CanCreateGLWindow)
.ToArray();
var glMajor = 3;
var glMinor = useGLES ? 0 : 2;
var glProfile = useGLES ? SDL.SDL_GLprofile.SDL_GL_CONTEXT_PROFILE_ES : SDL.SDL_GLprofile.SDL_GL_CONTEXT_PROFILE_CORE;
if (!supportedProfiles.Any())
throw new InvalidOperationException("No supported OpenGL profiles were found.");
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MAJOR_VERSION, glMajor);
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MINOR_VERSION, glMinor);
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_PROFILE_MASK, (int)glProfile);
Console.WriteLine("Using SDL 2 with OpenGL{0} renderer", useGLES ? " ES" : "");
profile = supportedProfiles.Contains(requestProfile) ? requestProfile : supportedProfiles.First();
SetSDLAttributes(profile);
Console.WriteLine("Using SDL 2 with OpenGL ({0}) renderer", profile);
if (videoDisplay < 0 || videoDisplay >= DisplayCount)
videoDisplay = 0;
@@ -451,12 +466,34 @@ namespace OpenRA.Platforms.Default
return input.SetClipboardText(text);
}
static bool CanCreateGLWindow(int major, int minor, SDL.SDL_GLprofile profile)
static void SetSDLAttributes(GLProfile profile)
{
SDL.SDL_GL_ResetAttributes();
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_DOUBLEBUFFER, 1);
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_RED_SIZE, 8);
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_GREEN_SIZE, 8);
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_BLUE_SIZE, 8);
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_ALPHA_SIZE, 0);
switch (profile)
{
case GLProfile.Modern:
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_PROFILE_MASK, (int)SDL.SDL_GLprofile.SDL_GL_CONTEXT_PROFILE_CORE);
break;
case GLProfile.Embedded:
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_PROFILE_MASK, (int)SDL.SDL_GLprofile.SDL_GL_CONTEXT_PROFILE_ES);
break;
}
}
static bool CanCreateGLWindow(GLProfile profile)
{
// Implementation inspired by TestIndividualGLVersion from Veldrid
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MAJOR_VERSION, major);
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MINOR_VERSION, minor);
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_PROFILE_MASK, (int)profile);
SetSDLAttributes(profile);
var flags = SDL.SDL_WindowFlags.SDL_WINDOW_HIDDEN | SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL;
var window = SDL.SDL_CreateWindow("", 0, 0, 1, 1, flags);