diff --git a/src/BizHawk.Bizware.BizwareGL/IGL.cs b/src/BizHawk.Bizware.BizwareGL/IGL.cs
index 6b6f57d324..d6353bf10d 100644
--- a/src/BizHawk.Bizware.BizwareGL/IGL.cs
+++ b/src/BizHawk.Bizware.BizwareGL/IGL.cs
@@ -159,7 +159,7 @@ namespace BizHawk.Bizware.BizwareGL
///
/// In case you already have the texture ID (from an opengl emulator gpu core) you can get a Texture2d with it this way.
- /// Otherwise, if this isn't an OpenGL frontend implementation, I guess... try reading the texturedata out of it and making a new texture?
+ /// Otherwise, if this isn't an OpenGL frontend implementation, the core is expected to readback the texture for GetVideoBuffer()
///
Texture2d WrapGLTexture2d(IntPtr glTexId, int width, int height);
diff --git a/src/BizHawk.Bizware.BizwareGL/RenderTarget.cs b/src/BizHawk.Bizware.BizwareGL/RenderTarget.cs
index 999dd8e9bc..8285cbbfb3 100644
--- a/src/BizHawk.Bizware.BizwareGL/RenderTarget.cs
+++ b/src/BizHawk.Bizware.BizwareGL/RenderTarget.cs
@@ -9,7 +9,6 @@ namespace BizHawk.Bizware.BizwareGL
Owner = owner;
Opaque = opaque;
Texture2d = tex;
- tex.IsUpsideDown = true;
}
public override string ToString()
diff --git a/src/BizHawk.Bizware.Graphics/D3D9/IGL_D3D9.cs b/src/BizHawk.Bizware.Graphics/D3D9/IGL_D3D9.cs
index f1bbb4a735..782d8f8eea 100644
--- a/src/BizHawk.Bizware.Graphics/D3D9/IGL_D3D9.cs
+++ b/src/BizHawk.Bizware.Graphics/D3D9/IGL_D3D9.cs
@@ -683,8 +683,7 @@ namespace BizHawk.Bizware.Graphics
public Texture2d WrapGLTexture2d(IntPtr glTexId, int width, int height)
{
- // not needed 1st pass (except for GL cores)
- // TODO - need to rip the texture data. we had code for that somewhere...
+ // only used for OpenGL
return null;
}
diff --git a/src/BizHawk.Bizware.Graphics/OpenGL/IGL_OpenGL.cs b/src/BizHawk.Bizware.Graphics/OpenGL/IGL_OpenGL.cs
index fa23167641..8c771af9cd 100644
--- a/src/BizHawk.Bizware.Graphics/OpenGL/IGL_OpenGL.cs
+++ b/src/BizHawk.Bizware.Graphics/OpenGL/IGL_OpenGL.cs
@@ -37,10 +37,7 @@ namespace BizHawk.Bizware.Graphics
{
public EDispMethod DispMethodEnum => EDispMethod.OpenGL;
- private readonly SDL2OpenGLContext OffscreenContext;
- private SDL2OpenGLContext ActiveContext;
- private GL GL => ActiveContext.GL;
-
+ private readonly GL GL;
private readonly int _majorVersion, _minorVersion;
private readonly bool _forwardCompatible;
@@ -50,36 +47,20 @@ namespace BizHawk.Bizware.Graphics
public string API => "OPENGL";
- public int Version
- {
- get
- {
- // doesnt work on older than gl3 maybe
- // int major, minor;
- // // other overloads may not exist...
- // GL.GetInteger(GetPName.MajorVersion, out major);
- // GL.GetInteger(GetPName.MinorVersion, out minor);
-
- // supposedly the standard dictates that whatever junk is in the version string, some kind of version is at the beginning
- // can be either in major_number.minor_number or major_number.minor_number.release_number, with vendor specific info afterwards
- var versionString = GL.GetStringS(StringName.Version);
- var versionParts = versionString.Split('.');
- var major = int.Parse(versionParts[0]);
- var minor = int.Parse(versionParts[1][0].ToString());
- // getting a release number is too hard and not needed now
- return major * 100 + minor * 10;
- }
- }
-
public IGL_OpenGL(int majorVersion, int minorVersion, bool forwardCompatible)
{
- // create an offscreen context, so things can be done without a control
- ActiveContext = OffscreenContext = new(majorVersion, minorVersion, forwardCompatible);
-
_majorVersion = majorVersion;
_minorVersion = minorVersion;
_forwardCompatible = forwardCompatible;
+ // we need an active context in order to acquire these functions
+ // technically, they could be different between contexts
+ // but with the exact same requested version and config that is highly unlikely in practice
+ using (new SDL2OpenGLContext(majorVersion, minorVersion, forwardCompatible))
+ {
+ GL = GL.GetApi(SDL2OpenGLContext.GetGLProcAddress);
+ }
+
// misc initialization
CreateRenderStates();
}
@@ -94,7 +75,6 @@ namespace BizHawk.Bizware.Graphics
public void Dispose()
{
- OffscreenContext.Dispose();
}
public void Clear(BizClearBufferMask mask)
@@ -477,7 +457,7 @@ namespace BizHawk.Bizware.Graphics
public Texture2d WrapGLTexture2d(IntPtr glTexId, int width, int height)
{
- return new(this, glTexId.ToInt32(), width, height);
+ return new(this, (uint)glTexId.ToInt32(), width, height) { IsUpsideDown = true };
}
public unsafe void LoadTextureData(Texture2d tex, BitmapBuffer bmp)
@@ -505,7 +485,7 @@ namespace BizHawk.Bizware.Graphics
{
// create a texture for it
var texId = GenTexture();
- var tex = new Texture2d(this, texId, w, h);
+ var tex = new Texture2d(this, texId, w, h) { IsUpsideDown = true }; // TODO: The IsUpsideDown doesn't ever get used here it seems
GL.BindTexture(TextureTarget.Texture2D, texId);
GL.TexImage2D(TextureTarget.Texture2D, 0, InternalFormat.Rgba8, (uint)w, (uint)h, 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero.ToPointer());
@@ -839,26 +819,11 @@ namespace BizHawk.Bizware.Graphics
private VertexLayout sStatePendingVertexLayout;
private readonly HashSet sVertexAttribEnables = new();
- private void ContextChangeCallback(SDL2OpenGLContext context)
+ private void ContextChangeCallback()
{
- // null means the current context is being cleared
- // set it back to the offscreen context
- if (context is null)
- {
- OffscreenContext.MakeContextCurrent();
- context = OffscreenContext;
- }
-
sActiveTexture = -1;
sStatePendingVertexLayout = null;
sVertexAttribEnables.Clear();
- ActiveContext = context;
- }
-
- public void MakeOffscreenContextCurrent()
- {
- OffscreenContext.MakeContextCurrent();
- ContextChangeCallback(OffscreenContext);
}
}
}
diff --git a/src/BizHawk.Bizware.Graphics/OpenGL/OpenGLControl.cs b/src/BizHawk.Bizware.Graphics/OpenGL/OpenGLControl.cs
index f04cc6c325..0dd2efbbbf 100644
--- a/src/BizHawk.Bizware.Graphics/OpenGL/OpenGLControl.cs
+++ b/src/BizHawk.Bizware.Graphics/OpenGL/OpenGLControl.cs
@@ -11,7 +11,7 @@ namespace BizHawk.Bizware.Graphics
private readonly int _majorVersion;
private readonly int _minorVersion;
private readonly bool _forwardCompatible;
- private readonly Action _contextChangeCallback;
+ private readonly Action _contextChangeCallback;
public SDL2OpenGLContext Context { get; private set; }
@@ -21,7 +21,7 @@ namespace BizHawk.Bizware.Graphics
set => throw new NotImplementedException();
}
- public OpenGLControl(int majorVersion, int minorVersion, bool forwardCompatible, Action contextChangeCallback)
+ public OpenGLControl(int majorVersion, int minorVersion, bool forwardCompatible, Action contextChangeCallback)
{
_majorVersion = majorVersion;
_minorVersion = minorVersion;
@@ -59,8 +59,7 @@ namespace BizHawk.Bizware.Graphics
{
base.OnHandleCreated(e);
Context = new(Handle, _majorVersion, _minorVersion, _forwardCompatible);
-
- _contextChangeCallback(Context);
+ _contextChangeCallback();
}
protected override void OnHandleDestroyed(EventArgs e)
@@ -69,7 +68,7 @@ namespace BizHawk.Bizware.Graphics
if (Context.IsCurrent)
{
- _contextChangeCallback(null);
+ _contextChangeCallback();
}
Context.Dispose();
@@ -92,7 +91,7 @@ namespace BizHawk.Bizware.Graphics
if (!Context.IsCurrent)
{
Context.MakeContextCurrent();
- _contextChangeCallback(Context);
+ _contextChangeCallback();
}
}
}
@@ -110,7 +109,8 @@ namespace BizHawk.Bizware.Graphics
public void End()
{
- _contextChangeCallback(null);
+ SDL2OpenGLContext.MakeNoneCurrent();
+ _contextChangeCallback();
}
public void SwapBuffers()
diff --git a/src/BizHawk.Bizware.Graphics/OpenGL/SDL2OpenGLContext.cs b/src/BizHawk.Bizware.Graphics/OpenGL/SDL2OpenGLContext.cs
index 6b882c72df..7d03136eec 100644
--- a/src/BizHawk.Bizware.Graphics/OpenGL/SDL2OpenGLContext.cs
+++ b/src/BizHawk.Bizware.Graphics/OpenGL/SDL2OpenGLContext.cs
@@ -1,6 +1,5 @@
using System;
-
-using Silk.NET.OpenGL.Legacy;
+using System.Runtime.InteropServices;
using static SDL2.SDL;
@@ -9,7 +8,7 @@ namespace BizHawk.Bizware.Graphics
///
/// Wraps an SDL2 OpenGL context
///
- internal class SDL2OpenGLContext : IDisposable
+ public class SDL2OpenGLContext : IDisposable
{
static SDL2OpenGLContext()
{
@@ -41,11 +40,50 @@ namespace BizHawk.Bizware.Graphics
SDL_SetHint(SDL_HINT_VIDEO_FOREIGN_WINDOW_OPENGL, "1");
}
+ [UnmanagedFunctionPointer(CallingConvention.Winapi)]
+ private delegate IntPtr glGetStringDelegate(int name);
+
+ private static readonly Lazy _version = new(() =>
+ {
+ var prevWindow = SDL_GL_GetCurrentWindow();
+ var prevContext = SDL_GL_GetCurrentContext();
+
+ try
+ {
+ using (new SDL2OpenGLContext(2, 0, false))
+ {
+ var getStringFp = GetGLProcAddress("glGetString");
+ if (getStringFp == IntPtr.Zero) // uhhh?
+ {
+ return 0;
+ }
+
+ var getStringFunc = Marshal.GetDelegateForFunctionPointer(getStringFp);
+ const int GL_VERSION = 0x1F02;
+ var version = getStringFunc(GL_VERSION);
+ if (version == IntPtr.Zero)
+ {
+ return 0;
+ }
+
+ var versionString = Marshal.PtrToStringAnsi(version);
+ var versionParts = versionString!.Split('.');
+ var major = int.Parse(versionParts[0]);
+ var minor = int.Parse(versionParts[1][0].ToString());
+ return major * 100 + minor;
+ }
+ }
+ finally
+ {
+ SDL_GL_MakeCurrent(prevWindow, prevContext);
+ }
+ });
+
+ public static int Version => _version.Value;
+
private IntPtr _sdlWindow;
private IntPtr _glContext;
- public GL GL { get; private set; }
-
private void CreateContext(int majorVersion, int minorVersion, bool forwardCompatible)
{
if (SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_CONTEXT_MAJOR_VERSION, majorVersion) != 0)
@@ -80,10 +118,6 @@ namespace BizHawk.Bizware.Graphics
{
throw new($"Could not create GL Context! SDL Error: {SDL_GetError()}");
}
-
- // get GL functions
- // these are specific towards a context, and so these are owned by the context here
- GL = GL.GetApi(SDL_GL_GetProcAddress);
}
public SDL2OpenGLContext(IntPtr nativeWindowhandle, int majorVersion, int minorVersion, bool forwardCompatible)
@@ -146,6 +180,15 @@ namespace BizHawk.Bizware.Graphics
_ = SDL_GL_MakeCurrent(_sdlWindow, _glContext);
}
+ public static void MakeNoneCurrent()
+ {
+ // no-op if nothing is current
+ _ = SDL_GL_MakeCurrent(IntPtr.Zero, IntPtr.Zero);
+ }
+
+ public static IntPtr GetGLProcAddress(string proc)
+ => SDL_GL_GetProcAddress(proc);
+
public void SetVsync(bool state)
{
if (!IsCurrent)
diff --git a/src/BizHawk.Client.Common/DisplayManager/DisplayManagerBase.cs b/src/BizHawk.Client.Common/DisplayManager/DisplayManagerBase.cs
index 21a69d9f4a..9e9b9fd64f 100644
--- a/src/BizHawk.Client.Common/DisplayManager/DisplayManagerBase.cs
+++ b/src/BizHawk.Client.Common/DisplayManager/DisplayManagerBase.cs
@@ -196,7 +196,9 @@ namespace BizHawk.Client.Common
private RetroShaderChain _shaderChainUser;
- protected virtual void ActivateGLContext() => throw new NotImplementedException();
+ public virtual void ActivateOpenGLContext() => throw new NotImplementedException();
+
+ protected virtual void ActivateGraphicsControlContext() => throw new NotImplementedException();
protected virtual void SwapBuffersOfGraphicsControl() => throw new NotImplementedException();
@@ -771,12 +773,10 @@ namespace BizHawk.Client.Common
private FilterProgram UpdateSourceInternal(JobInfo job)
{
- //no drawing actually happens. it's important not to begin drawing on a control
- if (!job.Simulate/* && !job.Offscreen*/)
+ // no drawing actually happens
+ if (!job.Simulate)
{
- // i don't want to do this for offscreen jobs
- // but it seems that would be required in case this context isn't active
- ActivateGLContext();
+ ActivateGraphicsControlContext();
if (job.ChainOutsize.Width == 0 || job.ChainOutsize.Height == 0)
{
@@ -791,17 +791,14 @@ namespace BizHawk.Client.Common
}
var videoProvider = job.VideoProvider;
+ var glTextureProvider = videoProvider as IGLTextureProvider;
var simulate = job.Simulate;
var chainOutsize = job.ChainOutsize;
- //simulate = true;
-
- var videoBuffer = videoProvider.GetVideoBuffer();
var bufferWidth = videoProvider.BufferWidth;
var bufferHeight = videoProvider.BufferHeight;
var presenterTextureWidth = bufferWidth;
var presenterTextureHeight = bufferHeight;
- var isGlTextureId = videoBuffer.Length == 1;
var vw = videoProvider.VirtualWidth;
var vh = videoProvider.VirtualHeight;
@@ -854,23 +851,22 @@ namespace BizHawk.Client.Common
Texture2d videoTexture = null;
if (!simulate)
{
- if (isGlTextureId)
+ if (glTextureProvider != null && _gl.DispMethodEnum == EDispMethod.OpenGL)
{
// FYI: this is a million years from happening on n64, since it's all geriatric non-FBO code
- // is it workable for saturn?
- videoTexture = _gl.WrapGLTexture2d(new(videoBuffer[0]), bufferWidth, bufferHeight);
+ videoTexture = _gl.WrapGLTexture2d(new(glTextureProvider.GetGLTexture()), bufferWidth, bufferHeight);
}
else
{
// wrap the VideoProvider data in a BitmapBuffer (no point to refactoring that many IVideoProviders)
- bb = new(bufferWidth, bufferHeight, videoBuffer);
+ bb = new(bufferWidth, bufferHeight, videoProvider.GetVideoBuffer());
bb.DiscardAlpha();
//now, acquire the data sent from the videoProvider into a texture
videoTexture = _videoTextureFrugalizer.Get(bb);
// lets not use this. lets define BizwareGL to make clamp by default (TBD: check opengl)
- // GL.SetTextureWrapMode(videoTexture, true);
+ // _gl.SetTextureWrapMode(videoTexture, true);
}
}
@@ -897,7 +893,6 @@ namespace BizHawk.Client.Common
fPresent.TextureSize = new(presenterTextureWidth, presenterTextureHeight);
fPresent.BackgroundColor = videoProvider.BackgroundColor;
fPresent.GuiRenderer = _renderer;
- fPresent.Flip = isGlTextureId;
fPresent.Config_FixAspectRatio = GlobalConfig.DispFixAspectRatio;
fPresent.Config_FixScaleInteger = GlobalConfig.DispFixScaleInteger;
fPresent.Padding = (ClientExtraPadding.Left, ClientExtraPadding.Top, ClientExtraPadding.Right, ClientExtraPadding.Bottom);
@@ -932,7 +927,7 @@ namespace BizHawk.Client.Common
public void Blank()
{
- ActivateGLContext();
+ ActivateGraphicsControlContext();
_gl.BeginScene();
_gl.BindRenderTarget(null);
_gl.SetClearColor(Color.Black);
diff --git a/src/BizHawk.Client.Common/DisplayManager/Filters/Gui.cs b/src/BizHawk.Client.Common/DisplayManager/Filters/Gui.cs
index 95d4cae720..72badbcf27 100644
--- a/src/BizHawk.Client.Common/DisplayManager/Filters/Gui.cs
+++ b/src/BizHawk.Client.Common/DisplayManager/Filters/Gui.cs
@@ -435,7 +435,6 @@ namespace BizHawk.Client.Common.Filters
public int BackgroundColor;
public bool AutoPrescale;
public IGuiRenderer GuiRenderer;
- public bool Flip;
public IGL GL;
private bool nop;
private LetterboxingLogic LL;
@@ -491,7 +490,7 @@ namespace BizHawk.Client.Common.Filters
public override void SetInputFormat(string channel, SurfaceState state)
{
- bool need = state.SurfaceFormat.Size != OutputSize || FilterOption != eFilterOption.None || Flip;
+ bool need = state.SurfaceFormat.Size != OutputSize || FilterOption != eFilterOption.None;
if (!need)
{
@@ -575,14 +574,7 @@ namespace BizHawk.Client.Common.Filters
//this was handled earlier by another filter
}
- GuiRenderer.Modelview.Translate(LL.vx, LL.vy);
- if (Flip)
- {
- GuiRenderer.Modelview.Scale(1, -1);
- GuiRenderer.Modelview.Translate(0, -LL.vh);
- }
- GuiRenderer.Draw(InputTexture,0,0,LL.vw,LL.vh);
-
+ GuiRenderer.Draw(InputTexture, LL.vx, LL.vy, LL.vw, LL.vh);
GuiRenderer.End();
}
}
diff --git a/src/BizHawk.Client.EmuHawk/DisplayManager/DisplayManager.cs b/src/BizHawk.Client.EmuHawk/DisplayManager/DisplayManager.cs
index d2516549bd..3c65e9a219 100644
--- a/src/BizHawk.Client.EmuHawk/DisplayManager/DisplayManager.cs
+++ b/src/BizHawk.Client.EmuHawk/DisplayManager/DisplayManager.cs
@@ -20,8 +20,6 @@ namespace BizHawk.Client.EmuHawk
private readonly PresentationPanel _presentationPanel; // well, its the final layer's target, at least
- private readonly GLManager.ContextRef _crGraphicsControl;
-
private GraphicsControl _graphicsControl => _presentationPanel.GraphicsControl;
public DisplayManager(
@@ -36,14 +34,17 @@ namespace BizHawk.Client.EmuHawk
{
_presentationPanel = presentationPanel;
_getIsSecondaryThrottlingDisabled = getIsSecondaryThrottlingDisabled;
-
- // setup the GL context manager, needed for coping with multiple opengl cores vs opengl display method
- // but is it tho? --yoshi
- // turns out it was, calling Instance getter here initialises it, and the encapsulated Activate call is necessary too --yoshi
- _crGraphicsControl = GLManager.GetContextForGraphicsControl(_graphicsControl);
}
- protected override void ActivateGLContext() => GLManager.Instance.Activate(_crGraphicsControl);
+ public override void ActivateOpenGLContext()
+ {
+ if (_gl.DispMethodEnum == EDispMethod.OpenGL)
+ {
+ _graphicsControl.Begin();
+ }
+ }
+
+ protected override void ActivateGraphicsControlContext() => _graphicsControl.Begin();
protected override Size GetGraphicsControlSize() => _graphicsControl.Size;
diff --git a/src/BizHawk.Client.EmuHawk/GLManager.cs b/src/BizHawk.Client.EmuHawk/GLManager.cs
deleted file mode 100644
index 712b65b36d..0000000000
--- a/src/BizHawk.Client.EmuHawk/GLManager.cs
+++ /dev/null
@@ -1,91 +0,0 @@
-using System;
-using BizHawk.Bizware.BizwareGL;
-using BizHawk.Bizware.Graphics;
-
-namespace BizHawk.Client.EmuHawk
-{
- ///
- /// This singleton class manages OpenGL contexts, in an effort to minimize context changes.
- ///
- public class GLManager : IDisposable
- {
- private GLManager()
- {
- }
-
- public void Dispose()
- {
- }
-
- private static readonly Lazy _lazyInstance = new(() => new());
-
- public static GLManager Instance => _lazyInstance.Value;
-
- public void ReleaseGLContext(object o)
- {
- var cr = (ContextRef)o;
- cr.GL.Dispose();
- }
-
- public ContextRef CreateGLContext(int majorVersion, int minorVersion, bool forwardCompatible)
- {
- var gl = new IGL_OpenGL(majorVersion, minorVersion, forwardCompatible);
- return new() { GL = gl };
- }
-
- public static ContextRef GetContextForGraphicsControl(GraphicsControl gc)
- {
- return new()
- {
- Gc = gc,
- GL = gc.IGL
- };
- }
-
- private ContextRef _activeContext;
-
- public void Invalidate()
- {
- _activeContext = null;
- }
-
- public void Activate(ContextRef cr)
- {
- if (cr == _activeContext)
- {
- // D3D9 needs a begin signal to set the swap chain to the next backbuffer
- if (cr.GL.DispMethodEnum is EDispMethod.D3D9)
- {
- cr.Gc.Begin();
- }
-
- return;
- }
-
- _activeContext = cr;
-
- if (cr.Gc != null)
- {
- cr.Gc.Begin();
- }
- else
- {
- if (cr.GL is IGL_OpenGL gl)
- {
- gl.MakeOffscreenContextCurrent();
- }
- }
- }
-
- public void Deactivate()
- {
- //this is here for future use and tracking purposes.. however.. instead of relying on this, we should just make sure we always activate what we need before we use it
- }
-
- public class ContextRef
- {
- public IGL GL { get; set; }
- public GraphicsControl Gc { get; set; }
- }
- }
-}
\ No newline at end of file
diff --git a/src/BizHawk.Client.EmuHawk/GraphicsImplementations/OpenGLProvider.cs b/src/BizHawk.Client.EmuHawk/GraphicsImplementations/OpenGLProvider.cs
new file mode 100644
index 0000000000..8b1b5530c8
--- /dev/null
+++ b/src/BizHawk.Client.EmuHawk/GraphicsImplementations/OpenGLProvider.cs
@@ -0,0 +1,30 @@
+using System;
+
+using BizHawk.Bizware.Graphics;
+using BizHawk.Emulation.Common;
+
+namespace BizHawk.Client.EmuHawk
+{
+ ///
+ /// Provides a way for a core to use OpenGL
+ ///
+ public class OpenGLProvider : IOpenGLProvider
+ {
+ public int GLVersion => SDL2OpenGLContext.Version;
+
+ public object RequestGLContext(int major, int minor, bool forwardCompatible)
+ => new SDL2OpenGLContext(major, minor, forwardCompatible);
+
+ public void ReleaseGLContext(object context)
+ => ((SDL2OpenGLContext)context).Dispose();
+
+ public void ActivateGLContext(object context)
+ => ((SDL2OpenGLContext)context).MakeContextCurrent();
+
+ public void DeactivateGLContext()
+ => SDL2OpenGLContext.MakeNoneCurrent();
+
+ public IntPtr GetGLProcAddress(string proc)
+ => SDL2OpenGLContext.GetGLProcAddress(proc);
+ }
+}
diff --git a/src/BizHawk.Client.EmuHawk/MainForm.cs b/src/BizHawk.Client.EmuHawk/MainForm.cs
index d16067653a..c929c6c3fd 100644
--- a/src/BizHawk.Client.EmuHawk/MainForm.cs
+++ b/src/BizHawk.Client.EmuHawk/MainForm.cs
@@ -226,7 +226,8 @@ namespace BizHawk.Client.EmuHawk
message => this.ModalMessageBox(message, "Warning", EMsgBoxIcon.Warning),
AddOnScreenMessage,
cfp,
- prefs);
+ prefs,
+ new OpenGLProvider());
}
private void SetImages()
@@ -3837,6 +3838,7 @@ namespace BizHawk.Client.EmuHawk
//path = ioa_openrom.Path;
}
+ DisplayManager.ActivateOpenGLContext(); // required in case the core wants to created a shared OpenGL context
var result = loader.LoadRom(path, nextComm, ioaRetro?.CorePath, forcedCoreName: MovieSession.QueuedCoreName);
if (result) Game = loader.Game;
diff --git a/src/BizHawk.Client.EmuHawk/Program.cs b/src/BizHawk.Client.EmuHawk/Program.cs
index 9ac125af41..e12e756901 100644
--- a/src/BizHawk.Client.EmuHawk/Program.cs
+++ b/src/BizHawk.Client.EmuHawk/Program.cs
@@ -1,7 +1,6 @@
using System;
using System.Diagnostics;
using System.IO;
-using System.Linq;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
@@ -227,16 +226,14 @@ namespace BizHawk.Client.EmuHawk
return TryInitIGL(initialConfig.DispMethod = fallback.Method);
}
case EDispMethod.OpenGL:
- var glOpenGL = new IGL_OpenGL(2, 0, false);
- if (glOpenGL.Version < 200)
+ if (SDL2OpenGLContext.Version < 200)
{
// too old to use, GDI+ will be better
- glOpenGL.Dispose();
var fallback = ChooseFallback();
new ExceptionBox(new Exception($"Initialization of OpenGL Display Method failed; falling back to {fallback.Name}")).ShowDialog();
return TryInitIGL(initialConfig.DispMethod = fallback.Method);
}
- return CheckRenderer(glOpenGL);
+ return CheckRenderer(new IGL_OpenGL(2, 0, false));
default:
case EDispMethod.GdiPlus:
static GLControlWrapper_GdiPlus CreateGLControlWrapper(IGL_GdiPlus self) => new(self); // inlining as lambda causes crash, don't wanna know why --yoshi
diff --git a/src/BizHawk.Emulation.Common/CoreComms.cs b/src/BizHawk.Emulation.Common/CoreComms.cs
index 9c7410dd4b..d8572275e1 100644
--- a/src/BizHawk.Emulation.Common/CoreComms.cs
+++ b/src/BizHawk.Emulation.Common/CoreComms.cs
@@ -14,13 +14,15 @@ namespace BizHawk.Emulation.Common
Action showMessage,
Action notifyMessage,
ICoreFileProvider coreFileProvider,
- CorePreferencesFlags prefs
+ CorePreferencesFlags prefs,
+ IOpenGLProvider oglProvider
)
{
ShowMessage = showMessage;
Notify = notifyMessage;
CoreFileProvider = coreFileProvider;
CorePreferences = prefs;
+ OpenGLProvider = oglProvider;
}
public ICoreFileProvider CoreFileProvider { get; }
@@ -47,5 +49,10 @@ namespace BizHawk.Emulation.Common
/// Yeah, I put more stuff in corecomm. If you don't like it, change the settings/syncsettings stuff to support multiple "settings sets" to act like ini file sections kind of, so that we can hand a generic settings object to cores instead of strictly ones defined by the cores
///
public CorePreferencesFlags CorePreferences { get; }
+
+ ///
+ /// Interface to provide OpenGL resources to the core
+ ///
+ public IOpenGLProvider OpenGLProvider { get; }
}
}
diff --git a/src/BizHawk.Emulation.Common/Interfaces/IOpenGLProvider.cs b/src/BizHawk.Emulation.Common/Interfaces/IOpenGLProvider.cs
new file mode 100644
index 0000000000..cc530aa767
--- /dev/null
+++ b/src/BizHawk.Emulation.Common/Interfaces/IOpenGLProvider.cs
@@ -0,0 +1,44 @@
+using System;
+
+namespace BizHawk.Emulation.Common
+{
+ ///
+ /// Defines an interface for cores to obtain OpenGL contexts and functions
+ ///
+ public interface IOpenGLProvider
+ {
+ ///
+ /// OpenGL version, using major.minor.build format with decimal points ommitted (e.g. 1.2.3 turns into 123)
+ ///
+ public int GLVersion { get; }
+
+ ///
+ /// Requests an OpenGL context with specified major / minor / forwardCompatible
+ /// The requested OpenGL context will be shared with the current context
+ /// Note: creating a context implicitly makes that created context current
+ ///
+ public object RequestGLContext(int major, int minor, bool forwardCompatible);
+
+ ///
+ /// Frees this OpenGL context
+ ///
+ public void ReleaseGLContext(object context);
+
+ ///
+ /// Sets this OpenGL context to current
+ ///
+ public void ActivateGLContext(object context);
+
+ ///
+ /// Deactivates the current OpenGL context
+ /// No context will be current after this call
+ ///
+ public void DeactivateGLContext();
+
+ ///
+ /// Gets an OpenGL function pointer
+ /// The user must make a context active before using this
+ ///
+ public IntPtr GetGLProcAddress(string proc);
+ }
+}
diff --git a/src/BizHawk.Emulation.Common/Interfaces/Services/IGLTextureProvider.cs b/src/BizHawk.Emulation.Common/Interfaces/Services/IGLTextureProvider.cs
new file mode 100644
index 0000000000..dcf4248e78
--- /dev/null
+++ b/src/BizHawk.Emulation.Common/Interfaces/Services/IGLTextureProvider.cs
@@ -0,0 +1,15 @@
+namespace BizHawk.Emulation.Common
+{
+ ///
+ /// This service is an extension of IVideoProvider, providing the ability to pass an OpenGL texture to the client
+ /// If available and the client is using OpenGL for display, this texture will be used
+ /// If unavailable or the client is not using OpenGL for display, the client will fall back to the base
+ ///
+ public interface IGLTextureProvider : IVideoProvider, ISpecializedEmulatorService
+ {
+ ///
+ /// Returns an OpenGL texture of the current video content
+ ///
+ int GetGLTexture();
+ }
+}