fix context creation on nvidia, 1.0.4-pre4

This commit is contained in:
emmaus 2020-09-19 21:37:43 +00:00
parent 39bbaf3c6b
commit f04d3b0d46
11 changed files with 898 additions and 555 deletions

View file

@ -59,7 +59,6 @@ namespace OpenTK
private IGraphicsContext _graphicsContext;
private IWindowInfo _windowInfo;
private bool _initialized;
private int swapInterval = 0;
private bool _resize;
#endregion
@ -94,18 +93,6 @@ namespace OpenTK
/// <summary>The minor version of OpenGL to use.</summary>
public int GLVersionMinor { get; set; }
public int SwapInterval
{
get => swapInterval; set
{
swapInterval = value;
if (GraphicsContext != null)
{
GraphicsContext.SwapInterval = value;
}
}
}
public GraphicsContextFlags GraphicsContextFlags
{
get;
@ -131,6 +118,8 @@ namespace OpenTK
/// <summary>Constructs a new GLWidget</summary>
public GLWidget(GraphicsMode graphicsMode, int glVersionMajor, int glVersionMinor, GraphicsContextFlags graphicsContextFlags)
{
OpenTK.Toolkit.Init();
SingleBuffer = graphicsMode.Buffers == 1;
ColorBPP = graphicsMode.ColorFormat.BitsPerPixel;
AccumulatorBPP = graphicsMode.AccumulatorFormat.BitsPerPixel;
@ -142,13 +131,6 @@ namespace OpenTK
GLVersionMajor = glVersionMajor;
GLVersionMinor = glVersionMinor;
GraphicsContextFlags = graphicsContextFlags;
this.ConfigureEvent += GLWidget_ConfigureEvent;
}
private void GLWidget_ConfigureEvent(object o, ConfigureEventArgs args)
{
Resize = true;
}
~GLWidget()
@ -156,28 +138,13 @@ namespace OpenTK
Dispose(false);
}
public void MakeCurrent()
{
GraphicsContext.MakeCurrent(_windowInfo);
}
public void ClearCurrent()
{
GraphicsContext.MakeCurrent(null);
}
public void Swapbuffers()
{
GraphicsContext.SwapBuffers();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
try
{
MakeCurrent();
GraphicsContext.MakeCurrent(WindowInfo);
}
catch (Exception ex)
{
@ -205,7 +172,10 @@ namespace OpenTK
private static void OnGraphicsContextInitialized()
{
GraphicsContextInitialized?.Invoke(null, EventArgs.Empty);
if (GraphicsContextInitialized != null)
{
GraphicsContextInitialized(null, EventArgs.Empty);
}
}
// Called when the first GraphicsContext is being destroyed in the case of GraphicsContext.ShareContexts == True;
@ -213,7 +183,10 @@ namespace OpenTK
private static void OnGraphicsContextShuttingDown()
{
GraphicsContextShuttingDown?.Invoke(null, EventArgs.Empty);
if (GraphicsContextShuttingDown != null)
{
GraphicsContextShuttingDown(null, EventArgs.Empty);
}
}
// Called when this GLWidget has a valid GraphicsContext
@ -221,7 +194,21 @@ namespace OpenTK
protected virtual void OnInitialized()
{
Initialized?.Invoke(this, EventArgs.Empty);
if (Initialized != null)
{
Initialized(this, EventArgs.Empty);
}
}
public void MakeCurrent()
{
GraphicsContext.MakeCurrent(_windowInfo);
}
public bool Resize { get => _resize; set => _resize = value; }
public void ClearCurrent()
{
GraphicsContext.MakeCurrent(null);
}
// Called when this GLWidget needs to render a frame
@ -236,32 +223,9 @@ namespace OpenTK
RenderFrame?.Invoke(this, EventArgs.Empty);
}
// Called when this GLWidget is being Disposed
public event EventHandler ShuttingDown;
protected virtual void OnShuttingDown()
public void Swapbuffers()
{
if (ShuttingDown != null)
{
ShuttingDown(this, EventArgs.Empty);
}
}
#endregion
// Called when the widget needs to be (fully or partially) redrawn.
protected override bool OnDrawn(Cairo.Context cr)
{
if (!_initialized)
Initialize();
else if (!IsRenderHandler)
{
MakeCurrent();
OnRenderFrame();
ClearCurrent();
}
return true;
GraphicsContext.SwapBuffers();
}
public void Update()
@ -274,14 +238,49 @@ namespace OpenTK
_resize = false;
}
// Called when this GLWidget is being Disposed
public event EventHandler ShuttingDown;
protected virtual void OnShuttingDown()
{
if (ShuttingDown != null)
{
ShuttingDown(this, EventArgs.Empty);
}
}
#endregion
// Called when a widget is realized. (window handles and such are valid)
// protected override void OnRealized() { base.OnRealized(); }
// Called when the widget needs to be (fully or partially) redrawn.
protected override bool OnDrawn(Cairo.Context cr)
{
if (!_initialized)
Initialize();
else if (!IsRenderHandler)
GraphicsContext.MakeCurrent(WindowInfo);
return true;
}
// Called on Resize
protected override bool OnConfigureEvent(Gdk.EventConfigure evnt)
{
if (GraphicsContext != null)
{
GraphicsContext.Update(WindowInfo);
}
return true;
}
private void Initialize()
{
Toolkit.Init();
_initialized = true;
Gdk.GLContext.ClearCurrent();
// If this looks uninitialized... initialize.
if (ColorBPP == 0)
{
@ -323,7 +322,7 @@ namespace OpenTK
// GraphicsContext
GraphicsContext = new GraphicsContext(graphicsMode, WindowInfo, GLVersionMajor, GLVersionMinor, GraphicsContextFlags);
MakeCurrent();
GraphicsContext.MakeCurrent(WindowInfo);
if (OpenTK.Graphics.GraphicsContext.ShareContexts)
{
@ -342,15 +341,6 @@ namespace OpenTK
OnGraphicsContextInitialized();
}
GraphicsContext.SwapInterval = SwapInterval;
var swap = GraphicsContext.SwapInterval;
GTKBindingHelper.InitializeGlBindings();
ClearCurrent();
MakeCurrent();
OnInitialized();
}
@ -565,7 +555,6 @@ namespace OpenTK
public IGraphicsContext GraphicsContext { get => _graphicsContext; set => _graphicsContext = value; }
public IWindowInfo WindowInfo { get => _windowInfo; set => _windowInfo = value; }
public bool Resize { get => _resize; set => _resize = value; }
[DllImport(UnixLibX11Name, EntryPoint = "XGetVisualInfo")]
private static extern IntPtr XGetVisualInfoInternal(IntPtr display, IntPtr vinfo_mask, ref XVisualInfo template, out int nitems);

View file

@ -1,17 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Description>GLWigdet for GTKSharp, using Opentk.</Description>
<Version>1.0.4-pre1</Version>
<Version>1.0.4-pre4</Version>
<RepositoryUrl>https://github.com/Ryujinx/GLWidget</RepositoryUrl>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="GtkSharp" Version="3.22.25.56"/>
<PackageReference Include="OpenTK.Graphics" Version="4.0.0-pre9.6"/>
<PackageReference Include="OpenTK.Windowing.Common" Version="4.0.0-pre9.6"/>
<PackageReference Include="System.Drawing.Common" Version="4.7.0"/>
<PackageReference Include="MonoMac.NetStandard" Version="0.0.4"/>
<PackageReference Include="GtkSharp" Version="3.22.25.56" />
<PackageReference Include="OpenTK.Graphics" Version="4.0.0-pre9.6" />
<PackageReference Include="OpenTK.Windowing.Common" Version="4.0.0-pre9.6" />
<PackageReference Include="System.Drawing.Common" Version="4.7.0" />
<PackageReference Include="MonoMac.NetStandard" Version="0.0.4" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,51 @@
//
// The Open Toolkit Library License
//
// Copyright (c) 2006 - 2009 the Open Toolkit library.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
using System;
namespace OpenTK
{
/// <summary>
/// Defines bitwise combianations of GameWindow construction options.
/// </summary>
[Flags]
public enum GameWindowFlags
{
/// <summary>
/// Indicates default construction options.
/// </summary>
Default = 0,
/// <summary>
/// Indicates that the GameWindow should cover the whole screen.
/// </summary>
Fullscreen = 1,
/// <summary>
/// Indicates that the GameWindow should be a fixed window.
/// </summary>
FixedWindow = 2,
}
}

View file

@ -111,8 +111,26 @@ namespace OpenTK.Platform.Windows
internal static readonly int WindowInfoSize;
}
internal static class Functions
{
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern ushort RegisterClass(ref WindowClass window_class);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern ushort RegisterClassEx(ref ExtendedWindowClass window_class);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern short UnregisterClass([MarshalAs(UnmanagedType.LPTStr)] LPCTSTR className, IntPtr instance);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern short UnregisterClass(IntPtr className, IntPtr instance);
[DllImport("User32.dll", CharSet = CharSet.Unicode)]
public extern static IntPtr DefWindowProc(HWND hWnd, WindowMessage msg, IntPtr wParam, IntPtr lParam);
/// <summary>
///
/// </summary>
@ -134,6 +152,49 @@ namespace OpenTK.Platform.Windows
[DllImport("gdi32.dll")]
internal static extern int ChoosePixelFormat(IntPtr dc, ref PixelFormatDescriptor pfd);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern IntPtr CreateWindowEx(
ExtendedWindowStyle ExStyle,
[MarshalAs(UnmanagedType.LPTStr)] string className,
[MarshalAs(UnmanagedType.LPTStr)] string windowName,
WindowStyle Style,
int X, int Y,
int Width, int Height,
IntPtr HandleToParentWindow,
IntPtr Menu,
IntPtr Instance,
IntPtr Param);
/*
[DllImport("user32.dll", SetLastError = true)]
internal static extern int CreateWindowEx(
[In]ExtendedWindowStyle ExStyle,
[In]IntPtr ClassName,
[In]IntPtr WindowName,
[In]WindowStyle Style,
[In]int X, [In]int Y,
[In]int Width, [In]int Height,
[In]IntPtr HandleToParentWindow,
[In]IntPtr Menu,
[In]IntPtr Instance,
[In]IntPtr Param);
*/
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern IntPtr CreateWindowEx(
ExtendedWindowStyle ExStyle,
IntPtr ClassAtom,
IntPtr WindowName,
WindowStyle Style,
int X, int Y,
int Width, int Height,
IntPtr HandleToParentWindow,
IntPtr Menu,
IntPtr Instance,
IntPtr Param);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DestroyWindow(IntPtr windowHandle);
[DllImport("gdi32.dll")]
internal static extern int DescribePixelFormat(IntPtr deviceContext, int pixel, int pfdSize, ref PixelFormatDescriptor pixelFormat);
@ -214,6 +275,7 @@ namespace OpenTK.Platform.Windows
public delegate void TimerProc(HWND hwnd, WindowMessage uMsg, UINT_PTR idEvent, DWORD dwTime);
}
internal static class Constants
{
// Found in winuser.h
@ -655,6 +717,7 @@ namespace OpenTK.Platform.Windows
}
}
/// \internal
/// <summary>
/// Contains window information.

View file

@ -23,7 +23,7 @@ namespace OpenTK.Platform.Windows
private bool vsync_supported;
private bool vsync_tear_supported;
private bool focused;
private readonly WinGraphicsMode ModeSelector;
// We need to create a temp context in order to load
@ -96,6 +96,74 @@ namespace OpenTK.Platform.Windows
}
}
private IntPtr WindowProcedure(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
{
IntPtr? result = null;
switch (message)
{
case WindowMessage.ACTIVATE:
HandleActivate(handle, message, wParam, lParam);
break;
case WindowMessage.CREATE:
HandleCreate(handle, message, wParam, lParam);
break;
case WindowMessage.CLOSE:
HandleClose(handle, message, wParam, lParam);
return IntPtr.Zero;
case WindowMessage.DESTROY:
HandleDestroy(handle, message, wParam, lParam);
break;
}
if (result.HasValue)
{
return result.Value;
}
else
{
return Functions.DefWindowProc(handle, message, wParam, lParam);
}
}
private void HandleCreate(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
{
}
private void HandleClose(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
{
System.ComponentModel.CancelEventArgs e = new System.ComponentModel.CancelEventArgs();
}
private void HandleDestroy(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
{
}
private void HandleActivate(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
{
// See http://msdn.microsoft.com/en-us/library/ms646274(VS.85).aspx (WM_ACTIVATE notification):
// wParam: The low-order word specifies whether the window is being activated or deactivated.
bool new_focused_state = false;
if (IntPtr.Size == 4)
{
focused = (wParam.ToInt32() & 0xFFFF) != 0;
}
else
{
focused = (wParam.ToInt64() & 0xFFFF) != 0;
}
}
private readonly IntPtr ClassName = Marshal.StringToHGlobalAuto(Guid.NewGuid().ToString());
private readonly IntPtr Instance = GetModuleHandle(typeof(WinGLContext).Module.Name);
[DllImport("kernel32.dll")]
internal static extern IntPtr GetModuleHandle([MarshalAs(UnmanagedType.LPTStr)] string module_name);
public WinGLContext(GraphicsMode format, WinWindowInfo window, IGraphicsContext sharedContext,
int major, int minor, GraphicsContextFlags flags)
{
@ -114,13 +182,26 @@ namespace OpenTK.Platform.Windows
}
IntPtr current_context = Wgl.GetCurrentContext();
ExtendedWindowClass wc = new ExtendedWindowClass();
wc.Size = ExtendedWindowClass.SizeInBytes;
wc.Style = ClassStyle.OwnDC;
wc.Instance = Instance;
wc.WndProc = WindowProcedure;
wc.ClassName = ClassName;
ushort atom = Functions.RegisterClassEx(ref wc);
IntPtr window_name = Marshal.StringToHGlobalAuto("temp");
var temp_window = Functions.CreateWindowEx(ExtendedWindowStyle.WindowEdge | ExtendedWindowStyle.ApplicationWindow, ClassName, window_name, WindowStyle.OverlappedWindow | WindowStyle.ClipChildren, 0, 0, 10, 10, IntPtr.Zero, IntPtr.Zero,Instance, IntPtr.Zero);
var error = Marshal.GetLastWin32Error();
TemporaryContext temp_context = null;
try
{
if (current_context == IntPtr.Zero)
{
// Create temporary context to load WGL extensions
temp_context = new TemporaryContext(window.Handle);
temp_context = new TemporaryContext(temp_window);
current_context = Wgl.GetCurrentContext();
if (current_context != IntPtr.Zero && current_context == temp_context.Context.Handle)
{
@ -198,6 +279,13 @@ namespace OpenTK.Platform.Windows
temp_context.Dispose();
temp_context = null;
}
if (temp_window != null)
{
error = Marshal.GetLastWin32Error();
Functions.DestroyWindow(temp_window);
Functions.UnregisterClass(ClassName, Instance);
error = Marshal.GetLastWin32Error();
}
}
}
@ -396,9 +484,7 @@ namespace OpenTK.Platform.Windows
Debug.WriteLine(mode.Index.ToString());
var index = Functions.ChoosePixelFormat(window.DeviceContext, ref pfd);
if (!Functions.SetPixelFormat(window.DeviceContext, index, ref pfd))
if (!Functions.SetPixelFormat(window.DeviceContext, (int)mode.Index.Value, ref pfd))
{
throw new GraphicsContextException(String.Format(
"Requested GraphicsMode not available. SetPixelFormat error: {0}",

View file

@ -60,6 +60,7 @@ namespace OpenTK.Platform.Windows
ColorFormat accum, int buffers, bool stereo)
{
GraphicsMode mode = new GraphicsMode(color, depth, stencil, samples, accum, buffers, stereo);
GraphicsMode created_mode = ChoosePixelFormatARB(Device, mode);
// If ChoosePixelFormatARB failed, iterate through all acceleration types in turn (ICD, MCD, None)

View file

@ -0,0 +1,21 @@
namespace OpenTK
{
/// <summary>
/// Enumerates available window borders.
/// </summary>
public enum WindowBorder
{
/// <summary>
/// The window has a resizable border. A window with a resizable border can be resized by the user or programmatically.
/// </summary>
Resizable = 0,
/// <summary>
/// The window has a fixed border. A window with a fixed border can only be resized programmatically.
/// </summary>
Fixed,
/// <summary>
/// The window does not have a border. A window with a hidden border can only be resized programmatically.
/// </summary>
Hidden
}
}

View file

@ -0,0 +1,93 @@
//
// WindowIcon.cs
//
// Author:
// Stefanos A. <stapostol@gmail.com>
//
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
using System;
using System.Runtime.InteropServices;
namespace OpenTK
{
/// <summary>
/// Stores a window icon. A window icon is defined
/// as a 2-dimensional buffer of RGBA values.
/// </summary>
public class WindowIcon
{
/// \internal
/// <summary>
/// Initializes a new instance of the <see cref="OpenTK.WindowIcon"/> class.
/// </summary>
internal protected WindowIcon()
{
}
private WindowIcon(int width, int height)
{
if (width < 0 || width > 256 || height < 0 || height > 256)
{
throw new ArgumentOutOfRangeException();
}
this.Width = width;
this.Height = height;
}
internal WindowIcon(int width, int height, byte[] data)
: this(width, height)
{
if (data == null)
{
throw new ArgumentNullException();
}
if (data.Length < Width * Height * 4)
{
throw new ArgumentOutOfRangeException();
}
this.Data = data;
}
internal WindowIcon(int width, int height, IntPtr data)
: this(width, height)
{
if (data == IntPtr.Zero)
{
throw new ArgumentNullException();
}
// We assume that width and height are correctly set.
// If they are not, we will read garbage and probably
// crash.
this.Data = new byte[width * height * 4];
Marshal.Copy(data, this.Data, 0, this.Data.Length);
}
internal byte[] Data { get; }
internal int Width { get; }
internal int Height { get; }
}
}

View file

@ -0,0 +1,31 @@
/* Licensed under the MIT/X11 license.
* Copyright (c) 2006-2008 the OpenTK Team.
* This notice may not be removed from any source distribution.
* See license.txt for licensing details.
*/
namespace OpenTK
{
/// <summary>
/// Enumerates available window states.
/// </summary>
public enum WindowState
{
/// <summary>
/// The window is in its normal state.
/// </summary>
Normal = 0,
/// <summary>
/// The window is minimized to the taskbar (also known as 'iconified').
/// </summary>
Minimized,
/// <summary>
/// The window covers the whole working area, which includes the desktop but not the taskbar and/or panels.
/// </summary>
Maximized,
/// <summary>
/// The window covers the whole screen, including all taskbars and/or panels.
/// </summary>
Fullscreen
}
}

View file

@ -12,6 +12,7 @@ namespace GLWidgetTestGTK3
{
// GTKBindingHelper.InitXThreads();
// GTK
GTKBindingHelper.InitializeGlBindings();
Application.Init();
MainWindow win = MainWindow.Create();
win.Show();

View file

@ -94,7 +94,14 @@ namespace GLWidgetTestGTK3.World
GL.UniformMatrix4(projectionShaderVariableHandle, false, ref modelViewProjection);
// Draw the model
GL.DrawArrays(BeginMode.Triangles, 0, Mesh.GetVertexCount());
try
{
GL.DrawArrays(PrimitiveType.Triangles, 0, Mesh.GetVertexCount());
}
catch (Exception)
{
}
// Release the attribute arrays
GL.DisableVertexAttribArray(0);