diff --git a/BizHawk.Client.Common/BizHawk.Client.Common.csproj b/BizHawk.Client.Common/BizHawk.Client.Common.csproj index a2ba22cb27..723997de06 100644 --- a/BizHawk.Client.Common/BizHawk.Client.Common.csproj +++ b/BizHawk.Client.Common/BizHawk.Client.Common.csproj @@ -50,6 +50,7 @@ + @@ -105,6 +106,9 @@ + + Code + @@ -194,6 +198,14 @@ {f51946ea-827f-4d82-b841-1f2f6d060312} BizHawk.Emulation.DiscSystem + + {5160CFB1-5389-47C1-B7F6-8A0DC97641EE} + BizHawk.Bizware.BizwareGL.OpenTK + + + {9F84A0B2-861E-4EF4-B89B-5E2A3F38A465} + BizHawk.Bizware.BizwareGL + diff --git a/BizHawk.Client.Common/GLManager.cs b/BizHawk.Client.Common/GLManager.cs new file mode 100644 index 0000000000..5401c7c665 --- /dev/null +++ b/BizHawk.Client.Common/GLManager.cs @@ -0,0 +1,90 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; + +using BizHawk.Common; +using BizHawk.Emulation.Common; + +using BizHawk.Bizware.BizwareGL; +using BizHawk.Bizware.BizwareGL.Drivers.OpenTK; + +namespace BizHawk.Client.Common +{ + /// + /// This class manages OpenGL contexts, in an effort to minimize context changes. + /// + public class GLManager + { + public GLManager() + { + int zzz = 9; + } + + public ContextRef CreateGLContext() + { + var ret = new ContextRef() + { + gl = new BizHawk.Bizware.BizwareGL.Drivers.OpenTK.IGL_TK() + }; + return ret; + } + + public ContextRef GetContextForGraphicsControl(GraphicsControl gc) + { + return new ContextRef() + { + gc = gc + }; + } + + /// + /// This might not be a GL implementation. If it isnt GL, then setting it as active context is just NOP + /// + public ContextRef GetContextForIGL(IGL gl) + { + return new ContextRef() + { + gl = gl + }; + } + + ContextRef ActiveContext; + + public void Invalidate() + { + ActiveContext = null; + } + + public void Activate(ContextRef cr) + { + if (cr == ActiveContext) + return; + ActiveContext = cr; + if (cr.gc != null) + { + //TODO - this is checking the current context inside to avoid an extra NOP context change. make this optional or remove it, since we're tracking it here + cr.gc.Begin(); + } + if (cr.gl != null) + { + if(cr.gl is BizHawk.Bizware.BizwareGL.Drivers.OpenTK.IGL_TK) + ((BizHawk.Bizware.BizwareGL.Drivers.OpenTK.IGL_TK)cr.gl).MakeDefaultCurrent(); + } + } + + 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 + } + + // ret.RequestGLContext = () => new BizHawk.Bizware.BizwareGL.Drivers.OpenTK.IGL_TK(); + //ret.ActivateGLContext = (gl) => ((BizHawk.Bizware.BizwareGL.Drivers.OpenTK.IGL_TK)gl).MakeDefaultCurrent(); + //ret.DeactivateGLContext = () => GlobalWin.DisplayManager.. + + public class ContextRef + { + public IGL gl; + public GraphicsControl gc; + } + } +} \ No newline at end of file diff --git a/BizHawk.Client.EmuHawk/DisplayManager/DisplayManager.cs b/BizHawk.Client.EmuHawk/DisplayManager/DisplayManager.cs index 1d362169a4..749d364c91 100644 --- a/BizHawk.Client.EmuHawk/DisplayManager/DisplayManager.cs +++ b/BizHawk.Client.EmuHawk/DisplayManager/DisplayManager.cs @@ -49,6 +49,7 @@ namespace BizHawk.Client.EmuHawk GL = GlobalWin.GL; this.presentationPanel = presentationPanel; GraphicsControl = this.presentationPanel.GraphicsControl; + CR_GraphicsControl = GlobalWin.GLManager.GetContextForGraphicsControl(GraphicsControl); //it's sort of important for these to be initialized to something nonzero currEmuWidth = currEmuHeight = 1; @@ -106,13 +107,14 @@ namespace BizHawk.Client.EmuHawk public bool NeedsToPaint { get; set; } //rendering resources: - IGL GL; + public IGL GL; StringRenderer TheOneFont; GuiRenderer Renderer; //layer resources PresentationPanel presentationPanel; //well, its the final layer's target, at least GraphicsControl GraphicsControl; //well, its the final layer's target, at least + GLManager.ContextRef CR_GraphicsControl; FilterManager.FilterProgram CurrentFilterProgram; /// @@ -350,6 +352,8 @@ namespace BizHawk.Client.EmuHawk FilterManager.FilterProgram UpdateSourceInternal(JobInfo job) { + GlobalWin.GLManager.Activate(CR_GraphicsControl); + IVideoProvider videoProvider = job.videoProvider; bool simulate = job.simulate; Size chain_outsize = job.chain_outsize; @@ -442,7 +446,7 @@ TESTEROO: //begin rendering on this context //should this have been done earlier? //do i need to check this on an intel video card to see if running excessively is a problem? (it used to be in the FinalTarget command below, shouldnt be a problem) - GraphicsControl.Begin(); + //GraphicsControl.Begin(); //run filter chain Texture2d texCurr = null; diff --git a/BizHawk.Client.EmuHawk/GlobalWin.cs b/BizHawk.Client.EmuHawk/GlobalWin.cs index 266a8525a9..d754397e8f 100644 --- a/BizHawk.Client.EmuHawk/GlobalWin.cs +++ b/BizHawk.Client.EmuHawk/GlobalWin.cs @@ -12,10 +12,12 @@ namespace BizHawk.Client.EmuHawk public static DirectSound DSound; #endif public static IGL GL; + public static GLManager.ContextRef CR_GL; public static Sound Sound; public static PresentationPanel PresentationPanel; public static OSDManager OSD = new OSDManager(); public static DisplayManager DisplayManager; + public static GLManager GLManager; //input state which has been destined for game controller inputs are coalesced here //public static ControllerInputCoalescer ControllerInputCoalescer = new ControllerInputCoalescer(); diff --git a/BizHawk.Client.EmuHawk/MainForm.cs b/BizHawk.Client.EmuHawk/MainForm.cs index 7cf00f798b..baf74d1786 100644 --- a/BizHawk.Client.EmuHawk/MainForm.cs +++ b/BizHawk.Client.EmuHawk/MainForm.cs @@ -57,6 +57,15 @@ namespace BizHawk.Client.EmuHawk // its.. weird. dont ask. } + CoreComm CreateCoreComm() + { + CoreComm ret = new CoreComm(ShowMessageCoreComm, NotifyCoreComm); + ret.RequestGLContext = () => GlobalWin.GLManager.CreateGLContext(); + ret.ActivateGLContext = (gl) => GlobalWin.GLManager.Activate((GLManager.ContextRef)gl); + ret.DeactivateGLContext = () => GlobalWin.GLManager.Deactivate(); + return ret; + } + public MainForm(string[] args) { GlobalWin.MainForm = this; @@ -160,7 +169,7 @@ namespace BizHawk.Client.EmuHawk Input.Initialize(); InitControls(); - Global.CoreComm = new CoreComm(ShowMessageCoreComm, NotifyCoreComm); + Global.CoreComm = CreateCoreComm(); CoreFileProvider.SyncCoreCommInputSignals(); Global.Emulator = new NullEmulator(Global.CoreComm); Global.ActiveController = Global.NullControls; @@ -2538,7 +2547,12 @@ namespace BizHawk.Client.EmuHawk coreskipaudio = Global.ClientControls["Turbo"] && _currAviWriter == null; - Global.Emulator.FrameAdvance(!_throttle.skipnextframe || _currAviWriter != null, !coreskipaudio); + { + bool render = !_throttle.skipnextframe || _currAviWriter != null; + bool renderSound = !coreskipaudio; + Global.Emulator.FrameAdvance(render, renderSound); + } + GlobalWin.DisplayManager.NeedsToPaint = true; Global.CheatList.Pulse(); @@ -2974,7 +2988,7 @@ namespace BizHawk.Client.EmuHawk // the new settings objects CommitCoreSettingsToConfig(); - var nextComm = new CoreComm(ShowMessageCoreComm, NotifyCoreComm); + var nextComm = CreateCoreComm(); CoreFileProvider.SyncCoreCommInputSignals(nextComm); var result = loader.LoadRom(path, nextComm); @@ -3147,7 +3161,7 @@ namespace BizHawk.Client.EmuHawk CommitCoreSettingsToConfig(); Global.Emulator.Dispose(); - Global.CoreComm = new CoreComm(ShowMessageCoreComm, NotifyCoreComm); + Global.CoreComm = CreateCoreComm(); CoreFileProvider.SyncCoreCommInputSignals(); Global.Emulator = new NullEmulator(Global.CoreComm); Global.ActiveController = Global.NullControls; @@ -3167,7 +3181,7 @@ namespace BizHawk.Client.EmuHawk if (GlobalWin.Tools.AskSave()) { CloseGame(clearSram); - Global.CoreComm = new CoreComm(ShowMessageCoreComm, NotifyCoreComm); + Global.CoreComm = CreateCoreComm(); CoreFileProvider.SyncCoreCommInputSignals(); Global.Emulator = new NullEmulator(Global.CoreComm); Global.Game = GameInfo.GetNullGame(); diff --git a/BizHawk.Client.EmuHawk/Program.cs b/BizHawk.Client.EmuHawk/Program.cs index ae0f14c1a5..df6cffa07d 100644 --- a/BizHawk.Client.EmuHawk/Program.cs +++ b/BizHawk.Client.EmuHawk/Program.cs @@ -80,6 +80,8 @@ namespace BizHawk.Client.EmuHawk //create IGL context. //at some point in the future, we may need to select from several drivers GlobalWin.GL = new BizHawk.Bizware.BizwareGL.Drivers.OpenTK.IGL_TK(); + GlobalWin.GLManager = new GLManager(); + GlobalWin.CR_GL = GlobalWin.GLManager.GetContextForIGL(GlobalWin.GL); try { diff --git a/BizHawk.Emulation.Common/Interfaces/CoreComms.cs b/BizHawk.Emulation.Common/Interfaces/CoreComms.cs index 26d3e0f71c..cb70c04d80 100644 --- a/BizHawk.Emulation.Common/Interfaces/CoreComms.cs +++ b/BizHawk.Emulation.Common/Interfaces/CoreComms.cs @@ -63,6 +63,10 @@ namespace BizHawk.Emulation.Common this.ShowMessage = ShowMessage; this.Notify = NotifyMessage; } + + public Func RequestGLContext; + public Action ActivateGLContext; + public Action DeactivateGLContext; //this shouldnt be necessary.. frontend should be changing context before it does anything.. but for now.. } public class TraceBuffer diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs index b9982600b4..7244319e83 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs @@ -61,14 +61,26 @@ namespace BizHawk.Emulation.Cores.Sega.Saturn this.SyncSettings = (SaturnSyncSettings)SyncSettings ?? new SaturnSyncSettings(); + if (this.SyncSettings.UseGL && glContext == null) + { + glContext = CoreComm.RequestGLContext(); + } + + ResetCounters(); + + CoreComm.ActivateGLContext(glContext); Init(bios); InputCallbackH = new LibYabause.InputCallback(() => CoreComm.InputCallback.Call()); LibYabause.libyabause_setinputcallback(InputCallbackH); CoreComm.UsesDriveLed = true; + + CoreComm.DeactivateGLContext(); } + static object glContext; + void Init(byte[] bios) { bool GL = SyncSettings.UseGL; @@ -99,7 +111,6 @@ namespace BizHawk.Emulation.Cores.Sega.Saturn else basetime = (int)((SyncSettings.RTCInitialTime - new DateTime(1970, 1, 1).ToLocalTime()).TotalSeconds); - if (!LibYabause.libyabause_init ( ref CDInt, @@ -186,6 +197,8 @@ namespace BizHawk.Emulation.Cores.Sega.Saturn { int w, h, nsamp; + CoreComm.ActivateGLContext(glContext); + LibYabause.Buttons1 p11 = (LibYabause.Buttons1)0xff; LibYabause.Buttons2 p12 = (LibYabause.Buttons2)0xff; LibYabause.Buttons1 p21 = (LibYabause.Buttons1)0xff; @@ -265,6 +278,8 @@ namespace BizHawk.Emulation.Cores.Sega.Saturn //Console.WriteLine(nsamp); //CheckStates(); + + CoreComm.DeactivateGLContext(); } public int Frame { get; private set; } @@ -515,6 +530,7 @@ namespace BizHawk.Emulation.Cores.Sega.Saturn { if (!Disposed) { + CoreComm.ActivateGLContext(glContext); if (SaveRamModified) DisposedSaveRam = ReadSaveRam(); LibYabause.libyabause_setvidbuff(IntPtr.Zero); @@ -523,6 +539,7 @@ namespace BizHawk.Emulation.Cores.Sega.Saturn VideoHandle.Free(); SoundHandle.Free(); Disposed = true; + CoreComm.DeactivateGLContext(); } } diff --git a/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/IGL_TK.cs b/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/IGL_TK.cs index 2fdb0c4f22..75eb97315e 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/IGL_TK.cs +++ b/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/IGL_TK.cs @@ -621,7 +621,7 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK } } - internal void MakeDefaultCurrent() + public void MakeDefaultCurrent() { MakeContextCurrent(this.GraphicsContext,OffscreenNativeWindow.WindowInfo); } diff --git a/output/dll/libyabause.dll b/output/dll/libyabause.dll index 2375ac83ac..3ddd703d32 100644 Binary files a/output/dll/libyabause.dll and b/output/dll/libyabause.dll differ diff --git a/yabause/src/libyabause/libyabause.vcxproj b/yabause/src/libyabause/libyabause.vcxproj index 8862e819e6..f1804474c2 100644 --- a/yabause/src/libyabause/libyabause.vcxproj +++ b/yabause/src/libyabause/libyabause.vcxproj @@ -51,6 +51,7 @@ Disabled WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBYABAUSE_EXPORTS;HAVE_C99_VARIADIC_MACROS;VERSION="LIB";C68K_NO_JUMP_TABLE;HAVE_LIBGL;%(PreprocessorDefinitions) 4244;4996;4018;4146 + true Windows @@ -71,6 +72,7 @@ true WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBYABAUSE_EXPORTS;HAVE_C99_VARIADIC_MACROS;VERSION="LIB";C68K_NO_JUMP_TABLE;HAVE_LIBGL;%(PreprocessorDefinitions) 4244;4996;4018;4146 + true Windows diff --git a/yabause/src/libyabause/yui.cpp b/yabause/src/libyabause/yui.cpp index cdc1e163c1..ee235f8c58 100644 --- a/yabause/src/libyabause/yui.cpp +++ b/yabause/src/libyabause/yui.cpp @@ -1,3 +1,6 @@ +//bizhawk +#define HEADLESS + #define WIN32_LEAN_AND_MEAN #include #include @@ -519,8 +522,17 @@ extern "C" __declspec(dllexport) int libyabause_init ) { usinggl = usegl; - if (usegl && (!StartGLContext() || !LoadExtensions())) - return 0; + + if (usegl) + { + //headless cores should not create GL contexts, but use the one from the invoking frontend + #ifndef HEADLESS + if(!StartGLContext()) + return 0; + #endif + if(!LoadExtensions()) + return 0; + } FECD.DeInit = _CD->DeInit; FECD.GetStatus = _CD->GetStatus;