Using a bitfield does not save storage space in this case, and also
stops pattern matching from working (switch() statement in C# or match
… with expressions in F#.)
joyGetDevCaps() is an extremely slow call that allocates memory.
WinMMJoystick is now caching its results for a significant speedup in
Joystick.GetCapabilities() and GetState().
The cache is updated whenever a joystick device is removed. WIP to
handle device added notifications.
This protects against a potential denial-of-service issue during mode
selection, where the platform backend will try to reduce AA level until
a supported mode is found.
When refreshing the AvailableDevices list, it is important to set the
original resolution on any DisplayDevices that were previously available
to allow the RestoreResolution() method to work correctly.
Most OpenGL versions work with single-byte ASCII strings exclusively.
OpenGL 4.2 adds UTF8 encoded comments to GLSL shaders. Unfortunately,
UTF16 (.Net) to UTF8 conversions will usually modify the length of the
resulting byte array.
This is not currently possible to implement inside OpenTK, since the
binding generator does not know which length parameter corresponds to a
string parameter.
For this reason, and to maintain compatibility with older OpenGL
versions, we perform a destructive UTF16-to-ASCII encoding, which
replaces unsupported characters by '?'. This allows multi-byte post-4.2.
GLSL shaders to work as expected.
If non-destructive round-tripping of strings is required, the user will
have to use the IntPtr overload for string parameters and perform the
UTF16-to-UTF8 encoding/decoding manually. This need is very unlikely to
arise in practice.
OpenTK will now detect when an UpdateFrame handler is consistently
taking too long to finish, and stop raising UpdateFrame events. This
gives ProcessEvents() a chance to execute and will protect the
application from hanging up.
The UpdateFrame event rate will now match TargetUpdatePeriod even if
vsync is enabled. Previously, it would be quantized to a multiple or
integer fraction of of the vsync rate.
Alc.GetString() could crash if the unmanaged code returned null due to
any kind of failure. This is now fixed and better documented.
Additionally, the array overload for Alc.GetString() will now correctly
forward the ‘device’ parameter to unmanaged code.
Multiple UpdateFrame events should be raised to match the desired
TargetUpdateFrequency, when TargetUpdateFrequency > 0. The loop would
incorrectly check for TargetRenderFrequency instead.
Affects issue #43
This patch adds more robust checks for WGL_ARB_pixel_format and
WGL_ARB_multisample before using the relevant extensions, and adds
checks whether Wgl.Arb.ChoosePixelFormat() returns a valid pixel format
before trying to use it (thanks to Repetier for catching this edge
case.)
Additionally, the ChoosePixelFormatPFD code-path now heavily penalizes
single-buffered modes when the user requests a double-buffered mode.
Affects issues #42 and #45
SDL will fail to construct an OpenGL 3.x/4.x context on Mac OS X,
unless ContextProfileFlags.CORE is specified.
Fixes issue #44
Upstream enhancement request at
https://bugzilla.libsdl.org/show_bug.cgi?id=2342
When running over remote desktop without hardware acceleration, there
are no GraphicsModes that support desktop composition. This patch adds
logic to avoid requesting composition-capable modes when running over
RDP.
Additionally, it changes the mode selection logic to consider modes that
support features partially (e.g. 16bpp color instead of 32bpp), albeit
with a heavy penalty over fully supported modes.
This patch adds a workaround for WM_STYLECHANGED messages that are not
delivered when running on Mono/Windows. If we detect Mono, then we call
HandleStyleChanged() directly in order to update the internal state of
our WinGLNative instance.
OpenTK now directly calculates the elapsed time between UpdateFrame
(RenderFrame) events and compares that directly to TargetUpdatePeriod
(TargetRenderPeriod). This significantly simplifies the implementation
and improves timing stability.
PlatformFactoryBase provides a common base interface for platform
backends. Platform backends should inherit from PlatformFactoryBase in
order to reduce code duplication.
LegacyJoystickDriver implements the legacy IJoystickDriver interface
(GameWindow.Joysticks) in terms of the new IJoystickDriver2 interface
(OpenTK.Input.Joystick).
This removes a large chunk of code from each platform backend, as they
no longer need to implement IJoystickDriver themselves. Additionally,
it adds support for device hot plugging which was previously missing.
This patch modifies GameWindow.Run() to use a single stopwatch instead
of two separate stopwatches for timing UpdateFrame and RenderFrame
events.
It improves timing accuracy for issue #20 (FrameEventArgs.Time
Inconsistencies)
DeviceAdded already checks that devices conform to the desired usage
pages. Checking again in DeviceRemoved is unnecessary - if a device
exists, then it has already passed muster.
JoystickAxis/Button.Last is used internally to allocate the correct
amount of storage for joystick axes and buttons. JoystickAxis.Axis10 is
required to support the maximum number of axes available on Mac OS X.
SDL2 uses a weird system of device ids and instance ids to report
joystick events, where the ADDED event uses a device id and the rest use
instance ids.
The SDL2 joystick driver is now fixed to correctly distinguish between
the two, which fixes hotplugging support for joystick devices.
SDL GameControllerAxis and GamePadAxes are not interchangeable. The
driver will now correctly interpret incoming SDL messages and update
the GamePadState for the relevant axis.
GamePadState.SetAxis() receives a GamePadAxes enumeration, which is a
bitmask of the axes we wish to set. SetAxis now correctly decodes the
bitmask to apply the values we are interested in.
When combining OpenTK with a third-party OpenGL toolkit, it is now
possible to implement a suitable GetAddress() and GetCurrentContext()
implementation in terms of the third-party toolkit. If no
implementation is specified, then OpenTK will try to guess the most
suitable implementation within its own platform backends.
If no custom implementation is defined, and if no suitable
implementation can be found, then OpenTK will throw a
PlatformNotSupportedException. If a suitable implementation is found or
defined, then OpenTK will attempt to load OpenGL entry points using
that implementation.
In this case third-party toolkit remains solely responsible for
managing its context via its MakeCurrent(), SwapBuffers(), etc
implementations.
DummyGLContext will now attempt to load OpenGL and OpenGL ES entry
points when a suitable OpenGL context is current on the calling thread.
This allows OpenTK to be used on contexts created through third-party
toolkits.
CreateGetAddress() constructs a GraphicsContext.GetAddressDelegate that
is suitable for the current platform. This can be used when combining
OpenTK with an OpenGL context created through a third-party toolkit.
The functions defined in libdl.dylib are useful in more places than
just AglContext. Moving them to their own class ensures we can access
these from wherever we might need them.
CGL appears to work with both AGL and NSOpenGL contexts, whereas AGL is
limited to AGL contexts. This allows us to be more flexible in terms of
implementation (i.e. we can use Cgl.GetCurrentContext to retrieve a
handle to a context created through SDL, which uses NSOpenGL
internally.)
When the user requests a GraphicsMode that is not directly supported
by the GPU/drivers, we should relax the requested parameters until
we find a supported mode. An exception should only be thrown when
there is no usable mode.
This makes the X11 backend match the behavior of Windows. The SDL/X11
backend works a little bit differently, in that it falls back to the
a default mode directly if the requested mode is not available. There
is nothing we can do about that.
The _NET_FRAME_EXTENTS atom is implemented differently by
different window managers, when window decorations are hidden
with Motif. Unity returns a 0 size, while Gnome 3 returns the
previous size.
This patch removes that ambiguity: when decorations are hidden,
border size becomes zero. This should work everywhere, unless
some window manager decides to troll us by decorating the window
when we explicitly request no decorations. Sigh...
Windows can now be resized programmatically, even when they have
WindowBorder.Fixed. All resizing logic is now consolidated in the
Bounds property, and ConfigureNotify messages are now handled
correctly depending on their source (StructureNotify or
SubStructureNotify.)
WinMM is optimized for general joystick use, not for the canonical
GamePad layout. Instead of exposing IGamePadDriver directly, it should
expose IJoystickDriver2 and use a mapping driver to get GamePad support.
Without this flag, OpenGL rendering does not work as expected.
Additionally, all WGL_ARB_pixel_format attributes are expected to be
specified in key-value pairs. Fixed double-buffering and stereoscoping
rendering attributes.
Fixed WGL_ARB_pixel_format attribute selection for doublebuffering,
stereoscopic rendering and hardware acceleration. Implemented
minimization strategy to select the optimal PixelFormatDescriptor in the
fallback path.
Instead of creating a list of all available formats and iterating
through that, we let the driver decide which is the best accelerated
format to use for the user parameters. If no such format exists, we fall
back to generic acceleration or software acceleration, in turn.
This affects issue #21
Starting with OpenGL 4.2, strings passed to GL.ShaderSource are allowed
to contain multi-byte characters in comments (issue #18). This patch
modifies the marshaling code to use UTF8.GetBytes in order to marshal
strings, instead of Marshal.StringToHGlobalAnsi().
Don't filter window messages passed to our window (see
http://blogs.msdn.com/b/oldnewthing/archive/2005/02/09/369804.aspx).
Additionally, return the correct values for all messages we are actually
handling and clean up unmanaged memory after we are done with the
window.
Instead of combining PeekMessage+GetMessage, we can simply call
PeekMessage(Remove) to achieve the same effect. This also allows us to
remove the IsIdle property, which is no longer used anywhere.
The temporary context is now retained until the actual context has been
constructed. If we don't do this, then WGL_ARB_create_context may fail
to work correctly on specific GPUs (e.g. Intel). This may affect issue
#19.
The correct way to query number of available pixel formats is to use
Wgl.Arb.GetPixelFormatAttrib(NumberPixelFormatsArb), not
Wgl.Arb.ChoosePixelFormats. This fixes an issue where Intel drivers
would fail to report any pixel formats in GetModesARB, even when
WGL_ARB_pixel_format is supported.
On many/most platforms, GraphicsContexts can only be released by the
thread where they are current. This means that the user must call
GraphicsContext.Dispose() or risk a resource leak.
Since we cannot release contexts on the finalizer thread, we should keep
strong references, instead of weak references, until the user explicitly
calls Dispose().
This patch fixes issues with SDL2 crashing when running the MonoGame
WindowsGL test suite.
Misbehaving clients that shall not be named here may call
GameWindow.Close() inside the GameWindow.Closing event. This causes
recursion in SDL2, crashing the application.
This patch adds a guard to protect against recursion when calling
GameWindow.Close().
Several projects are still using the last svn revision from the
sourceforge repository (r3127). These overloads provide an upgrade path
from r3127 to OpenTK 1.1.
The Mono 2.10 compiler fails when compiling extern methods that are not
marked as DllImport. We fix that by adding a method body that throws a
NotImplementedException instead.
Additionally, MonoDevelop 2.8 cannot open sln files with ToolsVersion 12.
The fix is to change ToolsVersion to 11.
Tools now go to the Binaries/Tools/[Debug|Release] directory. OpenTK
remains at BInaries/OpenTK/[Debug|Release].
Mono.Cecil and IKVM now reside under the Dependencies/managed/
directory.
Instead of modifying the name of an OpenGL symbol on the managed side,
before copying it to the unmanaged side, we perform the modification
directly on the unmanaged side. This reduces the total amount of
allocations in OpenTK by ~30% (673496 bytes in 10750 objects compared
to 930272 bytes in 15243 objects before this modification.)
It is now possible to indicate that an application is not DPI-aware. In
that case, OpenTK will let the operating system handle DPI scaling. This
results in worse visuals (pixel doubling) but allows non DPI-aware
applications to continue working.
We should be able to use static pinvokes on platforms that do not
provide or require extensions and calli instructions on platforms with
extension APIs. This dinstiction will be implemented as a parameter in
the rewriter.
WGL was autogenerated a few years ago but never touched after that.
Since we use a tiny fraction of all available methods, it makes sense to
remove the unused ones. This reduces dll size and improves startup
times.
The rewriter will patch the body of methods marked with [AutoGenerated].
Methods that are implemented manually (e.g. various math helper
overloads) should avoid this attribute.
On Windows, entry points for OpenGL 1.0 and 1.1 are not exposed by
wglGetProcAddress. We fall back to LoadLibrary+GetProcAddress when
wglProcAddress fails.
OpenTK normally uses reflection to load bindings, instead of generating
huge constructors. Although reflection is faster on first load (thanks
to reduced JIT overhead), it fails to work correctly with monolinker.
This branch explores the performance of a direct binding.
When we enter the modal resize loop on Windows with ClipCursor set, we
cause a feedback loop where every resize causes the cursor to move and
every move causes a new resize. To fix this, we need to ungrab the
cursor when we are enter the modal loop.
Implementations may reuse OpenGL context handles that have been
destroyed. If a context is finalized but not Disposed, then OpenTK may
keep a reference to the old context handle, causing a crash when the
same handle is returned for a new context. To fix that, new context
handles will now replace old handles in case of a clash.
SDL_DestroyWindow must be called on the main thread. If the window is
finalized, the finalizer will push a CLOSE event to the event loop
(thread-safe) and the window will be destroyed on the main thread.
Sdl2InputDriver.Dispose() would call SDL_DelEventWatch with a different
"user_data" parameter than SDL_AdEventWatch. This caused the EventFilter
to remain registered and subsequently crash when closing and reopening a
window.
GetBoolean, GetInteger6, GetFixedvOES and Delete* are now matched in
the convenience wrapper generator. Methods returning vectors of fixed
size (e.g. 4 ints) are no longer matched.
OpenTK.Toolkit will now initialize OpenTK.Configuration and
OpenTK.Platform.Factory explicitly. It can also receive an optional
ToolkitOptions parameter to influence the OpenTK.Platform implementation
that will be chosen. Finally, it explicitly implements IDisposable to
clean up after itself.
This significantly cleans up the startup sequence on all platforms:
- X11 is not detected on non-Linux platforms unless the user explicitly
requests it
- Supports selection of platform abstractions (SDL) vs native
implementations.
- Returns correct flags on Android and iOS.
This contains a semantic change: OpenTK.Configuration will not return
correct values until OpenTK.Toolkit.Init() has been called, either
directly or indirectly (e.g. by creating a window.)
OpenTK 1.0 and Xamarin Android/iOS do not use strongly-typed enums for
OpenGL ES. Generate overloads with the "All" enum in order to maintain
compatibility.
It is now possible to pass a non-realized GraphicsMode to the X11GLContext and X11GLNative constructors. A non-realized GraphicsMode is a GraphicsMode with a null Index (i.e. which has not passed through SelectGraphicsMode()).
According to the Linux OpenGL ABI, glXGetProcAddressARB must be statically exported by libGL. This does *not* hold true for glXGetProcAddress. We must used the ARB version instead.
Furthermore, glx entry points, unlike wgl, do not depend on any specific OpenGL context. This means we can load them in the constructor of the Glx class.
WinGraphicsMode no longer creates a temporary context in order to create
the list of available modes. Instead, it requires to be passed an
existing context in its constructor.
WinGLContext now creates one temporary context in its static constructor
and hands that to WinGraphicsMode.
WinFactory no longer supports the CreateGraphicsMode API. This API will
be removed in the future, because the link because contexts and modes
cannot be separated in the general case.