Skip to content

Commit 40ce1a2

Browse files
committed
Separate files
1 parent 0e760e6 commit 40ce1a2

30 files changed

+1280
-1290
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/// <summary>
2+
/// Contains properties pertaining to a display being connected or disconnected.
3+
/// </summary>
4+
/// <param name="Surface">The surface for which display(s) were connected.</param>
5+
/// <remarks>
6+
/// Old display objects are not guaranteed to be valid or relevant after this event is raised.
7+
/// </remarks>
8+
// Currently this event does not include the displays that were connected or disconnected. This is primarily because
9+
// there's no clean way to expose such "diffs" from an API perspective (as disconnected IDisplay objects are likely to
10+
// be invalid), and also why would we need to? If a use case arises and this can be implemented in a sound way, let's
11+
// evaluate that then.
12+
public readonly record struct DisplayAvailabilityChangeEvent(Surface Surface);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/// <summary>
2+
/// Contains properties pertaining to a surface changing to a different display.
3+
/// </summary>
4+
/// <param name="Surface">The surface changing to a different display.</param>
5+
/// <param name="Display">The display the surface has changed to.</param>
6+
/// <remarks>
7+
/// It is expected that this event shall be raised for each logically substantial change to the display parameters and
8+
/// this can be defined by each individual platform. For instance, if the underlying platform does not give the
9+
/// application access to any displays other than the one it's currently being displayed on, then it is expected that
10+
/// this event shall be raised if the display changed even if this is represented by the same object. Old display
11+
/// objects are not guaranteed to be valid or relevant after this event is raised.
12+
/// </remarks>
13+
public readonly record struct DisplayChangeEvent(Surface Surface, IDisplay Display);
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using Silk.NET.Maths;
2+
3+
/// <summary>
4+
/// Contains properties pertaining to a change in the location and/or size of a display.
5+
/// </summary>
6+
/// <param name="Surface">The surface owning the display.</param>
7+
/// <param name="Display">The display for which the location and/or size changed.</param>
8+
/// <param name="OldBounds">The previous value of <see cref="IDisplay.Bounds" />.</param>
9+
/// <param name="NewBounds">The new value of <see cref="IDisplay.Bounds" />.</param>
10+
/// <param name="OldWorkArea">The previous value of <see cref="IDisplay.WorkArea" />.</param>
11+
/// <param name="NewWorkArea">The new value of <see cref="IDisplay.WorkArea" />.</param>
12+
public readonly record struct DisplayCoordinatesEvent(
13+
Surface Surface,
14+
IDisplay Display,
15+
Rectangle<float> OldBounds,
16+
Rectangle<float> NewBounds,
17+
Rectangle<float> OldWorkArea,
18+
Rectangle<float> NewWorkArea
19+
);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/// <summary>
2+
/// Contains properties pertaining to a change in the available video modes for a display.
3+
/// </summary>
4+
/// <param name="Surface">The surface owning the display.</param>
5+
/// <param name="Display">The display for which the video mode availability changed.</param>
6+
// I don't think we need to have a diff here either, why would old video modes be relevant?
7+
public readonly record struct DisplayVideoModeAvailabilityChangeEvent(
8+
Surface Surface,
9+
IDisplay Display
10+
);
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
using Silk.NET.Maths;
2+
3+
/// <summary>
4+
/// Represents a display on which a surface can be rendered.
5+
/// </summary>
6+
/// <remarks>
7+
/// These objects may be shared with child windows created using <see cref="ISurfaceChildren" /> and vice versa i.e.
8+
/// this object can be shared between all surfaces that share a common ancestor (the "root surface"). Beyond that, these
9+
/// objects are not guaranteed to be valid across surfaces. This allows one event handler to enact changes on multiple
10+
/// surfaces.
11+
/// </remarks>
12+
public interface IDisplay
13+
{
14+
/// <summary>
15+
/// Gets the position and resolution of the monitor in screen space.
16+
/// </summary>
17+
Rectangle<float> Bounds { get; }
18+
19+
/// <summary>
20+
/// Gets the area within <see cref="Bounds" /> where surfaces are <i>intended</i> to be drawn.
21+
/// </summary>
22+
/// <remarks>
23+
/// This typically is the area left once you account for things like the menu bar and taskbar.
24+
/// </remarks>
25+
Rectangle<float> WorkArea { get; }
26+
27+
/// <summary>
28+
/// Gets a list of video modes known to be available when this display is <see cref="ISurfaceDisplay.Current" />.
29+
/// It may be the case that a list of video modes can't be determined until that's the case.
30+
/// </summary>
31+
IReadOnlyList<VideoMode>? KnownVideoModes { get; }
32+
33+
/// <summary>
34+
/// Gets a value indicating whether the user has designated this display their primary display.
35+
/// </summary>
36+
bool IsPrimary { get; }
37+
38+
/// <summary>
39+
/// Gets a colloquial name for the display. This may change, but hopefully not to something the end user won't recognise.
40+
/// </summary>
41+
string Name { get; }
42+
43+
/// <summary>
44+
/// An event raised when <see cref="Bounds" /> and/or <see cref="WorkArea" /> changes.
45+
/// </summary>
46+
event Action<DisplayCoordinatesEvent>? CoordinatesChanged;
47+
48+
/// <summary>
49+
/// An event raised when <see cref="KnownVideoModes" /> changes.
50+
/// </summary>
51+
event Action<DisplayVideoModeAvailabilityChangeEvent>? KnownVideoModesChanged;
52+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using System.Runtime.Versioning;
2+
3+
/// <summary>
4+
/// Represents an application running within a surface.
5+
/// </summary>
6+
public interface ISurfaceApplication
7+
{
8+
/// <summary>
9+
/// An optional window class.
10+
/// </summary>
11+
static virtual string? WindowClass => null;
12+
13+
/// <summary>
14+
/// Called upon initialization of the application.
15+
/// </summary>
16+
static abstract void Initialize<TSurface>(TSurface surface)
17+
where TSurface : Surface;
18+
19+
/// <summary>
20+
/// Runs an application using the reference implementation of Silk.NET.Windowing.
21+
/// </summary>
22+
/// <typeparam name="T">The application.</typeparam>
23+
[UnsupportedOSPlatform("android")]
24+
public static sealed void Run<T>()
25+
where T : ISurfaceApplication => throw new NotImplementedException();
26+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/// <summary>
2+
/// Provides the ability to spawn children surfaces.
3+
/// </summary>
4+
public interface ISurfaceChildren
5+
{
6+
/// <summary>
7+
/// Spawns an application to run within a new child surface. This call shall not block.
8+
/// </summary>
9+
/// <typeparam name="T">The application to run within the child surface.</typeparam>
10+
void Spawn<T>()
11+
where T : ISurfaceApplication;
12+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/// <summary>
2+
/// Provides the ability to configure displays on which the surface can render.
3+
/// </summary>
4+
public interface ISurfaceDisplay
5+
{
6+
/// <summary>
7+
/// Gets or sets display on which the surface is currently rendering. If setting, <c>value</c> must be contained in
8+
/// <see cref="Available" />.
9+
/// </summary>
10+
IDisplay Current { get; set; }
11+
12+
/// <summary>
13+
/// Gets a list of other displays that this surface can be moved to. If the surface cannot be programmatically moved
14+
/// to another display, it is expected that this shall return a single element list containing
15+
/// <see cref="Current" />.
16+
/// </summary>
17+
IReadOnlyList<IDisplay> Available { get; }
18+
19+
/// <summary>
20+
/// Gets or sets the video mode with which the surface is being rendered to the display. If setting, <c>value</c>
21+
/// must be contained in <see cref="AvailableVideoModes" />.
22+
/// </summary>
23+
VideoMode VideoMode { get; set; }
24+
25+
/// <summary>
26+
/// Gets a list of video modes with which the surface can be rendered. If the surface cannot programmatically change
27+
/// its video mode, it is expected that this shall return a single element list containing <see cref="VideoMode" />.
28+
/// </summary>
29+
IReadOnlyList<VideoMode> AvailableVideoModes { get; }
30+
31+
/// <summary>
32+
/// An event raised when <see cref="Current" /> changes.
33+
/// </summary>
34+
event Action<DisplayChangeEvent>? CurrentDisplayChanged;
35+
36+
/// <summary>
37+
/// An event raised when <see cref="Available" /> changes.
38+
/// </summary>
39+
event Action<DisplayAvailabilityChangeEvent>? AvailableChanged;
40+
41+
/// <summary>
42+
/// An event raised when <see cref="AvailableVideoModes" /> changes.
43+
/// </summary>
44+
event Action<DisplayVideoModeAvailabilityChangeEvent>? AvailableVideoModesChanged;
45+
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
using Silk.NET.Maths;
2+
3+
/// <summary>
4+
/// The OpenGL component of a <see cref="Surface" />. The <see cref="IGLContext" /> methods can only be executed once
5+
/// <see cref="ISurfaceApplication.Initialize{TSurface}" /> has executed.
6+
/// </summary>
7+
/// <remarks>
8+
/// These objects may be shared with child windows created using <see cref="ISurfaceChildren" /> and vice versa i.e.
9+
/// this object can be shared between all surfaces that share a common ancestor (the "root surface"). Beyond that, these
10+
/// objects are not guaranteed to be valid across surfaces. This allows one event handler to enact changes on multiple
11+
/// surfaces. This is important for <see cref="SharedContext" /> purposes.
12+
/// </remarks>
13+
public interface ISurfaceOpenGL : IGLContext
14+
{
15+
/// <summary>
16+
/// Gets or sets a value indicating whether OpenGL support is enabled for this surface. Setting
17+
/// <see cref="Profile" /> to a value other than <see cref="OpenGLContextProfile.None" /> will automatically set
18+
/// this property to <c>true</c>, and likewise toggling the value assigned to this property will change the value of
19+
/// <see cref="Profile" />.
20+
/// </summary>
21+
/// <remarks>
22+
/// This can only be set during the <see cref="ISurfaceApplication.Initialize{TSurface}" /> method.
23+
/// </remarks>
24+
// Included for consistency with Vulkan.
25+
bool IsEnabled
26+
{
27+
get => Profile != OpenGLContextProfile.None;
28+
set =>
29+
Profile = value
30+
? Profile == OpenGLContextProfile.None
31+
? OpenGLContextProfile.Default
32+
: Profile
33+
: OpenGLContextProfile.None;
34+
}
35+
36+
/// <summary>
37+
/// Preferred depth buffer bits of the window's framebuffer.
38+
/// </summary>
39+
/// <remarks>
40+
/// Pass <c>null</c> or <c>-1</c> to use the system default.
41+
/// This can only be set during the <see cref="ISurfaceApplication.Initialize{TSurface}" /> method.
42+
/// Setting this property will automatically set <see cref="Profile" /> to
43+
/// <see cref="OpenGLContextProfile.Default" /> if it is currently <see cref="OpenGLContextProfile.None" />.
44+
/// </remarks>
45+
int? PreferredDepthBufferBits { get; set; }
46+
47+
/// <summary>
48+
/// Preferred stencil buffer bits of the window's framebuffer.
49+
/// </summary>
50+
/// <remarks>
51+
/// Pass <c>null</c> or <c>-1</c> to use the system default.
52+
/// </remarks>
53+
int? PreferredStencilBufferBits { get; set; }
54+
55+
/// <summary>
56+
/// Preferred red, green, blue, and alpha bits of the window's framebuffer.
57+
/// </summary>
58+
/// <remarks>
59+
/// Pass <c>null</c> or <c>-1</c> for any of the channels to use the system default.
60+
/// </remarks>
61+
Vector4D<int>? PreferredBitDepth { get; set; }
62+
63+
/// <summary>
64+
/// Preferred number of samples for multi-sample anti-aliasing.
65+
/// </summary>
66+
/// <remarks>
67+
/// This can only be set during the <see cref="ISurfaceApplication.Initialize{TSurface}" /> method.
68+
/// </remarks>
69+
int? PreferredSampleCount { get; set; }
70+
71+
/// <summary>
72+
/// The API version to use.
73+
/// </summary>
74+
/// <remarks>
75+
/// This can only be set during the <see cref="ISurfaceApplication.Initialize{TSurface}" /> method.
76+
/// </remarks>
77+
Version32? Version { get; set; }
78+
79+
/// <summary>
80+
/// Flags used to create the OpenGL context.
81+
/// </summary>
82+
/// <remarks>
83+
/// This can only be set during the <see cref="ISurfaceApplication.Initialize{TSurface}" /> method.
84+
/// </remarks>
85+
OpenGLContextFlags Flags { get; set; }
86+
87+
/// <summary>
88+
/// The profile the OpenGL context should use. If <see cref="OpenGLContextProfile.None" /> is used, the OpenGL
89+
/// component is effectively disabled, allowing for other graphics APIs/components to be used. If any of the other
90+
/// properties on this class are set while this property is <see cref="OpenGLContextProfile.None" />, this property
91+
/// shall automatically be populated with the value <see cref="OpenGLContextProfile.Default" />.
92+
/// </summary>
93+
/// <remarks>
94+
/// This can only be set during the <see cref="ISurfaceApplication.Initialize{TSurface}" /> method. If the value is
95+
/// <see cref="OpenGLContextProfile.Default" />, this shall be replaced with the actual value upon exit from
96+
/// <see cref="ISurfaceApplication.Initialize{TSurface}" />.
97+
/// </remarks>
98+
OpenGLContextProfile Profile { get; set; }
99+
100+
/// <summary>
101+
/// Gets a value indicating whether the current configuration is supported (e.g. version number). If
102+
/// <see cref="Profile" /> is not <see cref="OpenGLContextProfile.None" /> and this property is <c>true</c>, the
103+
/// OpenGL context shall be created and accessible upon exit from
104+
/// <see cref="ISurfaceApplication.Initialize{TSurface}" />.
105+
/// </summary>
106+
bool IsSupported { get; }
107+
108+
/// <summary>
109+
/// Gets or sets a value indicating whether the platform should automatically <see cref="IGLContext.SwapBuffers" />
110+
/// after <see cref="Surface.Render" />. Defaults to <c>true</c>.
111+
/// </summary>
112+
/// <remarks>
113+
/// This can be set at any point throughout the surface's execution.
114+
/// </remarks>
115+
bool ShouldSwapAutomatically { get; set; }
116+
117+
/// <summary>
118+
/// Gets or sets the context with which this context should share resources.
119+
/// </summary>
120+
/// <remarks>
121+
/// This can only be set during the <see cref="ISurfaceApplication.Initialize{TSurface}" /> method.
122+
/// </remarks>
123+
IGLContext? SharedContext { get; set; }
124+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/// <summary>
2+
/// Provides information pertaining to the surface's graphical scaling.
3+
/// </summary>
4+
/// <remarks>
5+
/// <see cref="ContentScale" /> is typically used to scale UI elements to the correct size for the end user.
6+
/// <see cref="PixelDensity" /> on the other hand is used to scale the entire application to cover the entire client
7+
/// area in cases where the window client size is smaller than the actual drawable size (i.e. it is high density).
8+
/// If scaling content for legibility and scaling the application's rendering as a whole are not needed to be separated,
9+
/// it is recommended to use <see cref="DrawScale" />. Implementations shall always request a high density surface if
10+
/// given the choice, to account for the platforms where applications may not be able to opt-out of high density.
11+
/// </remarks>
12+
public interface ISurfaceScale
13+
{
14+
/// <summary>
15+
/// Gets the factor with which the application should scale its content to make the content more legible for the
16+
/// user. This has no influence on <see cref="Surface.DrawableSize" />.
17+
/// </summary>
18+
/// <seealso cref="DrawScale" />
19+
float ContentScale { get; }
20+
21+
/// <summary>
22+
/// Gets the suggested amplification factor when drawing in terms of <see cref="Surface.DrawableSize" />. This
23+
/// represents the scale from the pixel resolution to the desired content size, and is typically the multiplication
24+
/// of <see cref="PixelDensity" /> and <see cref="ContentScale" />.
25+
/// </summary>
26+
/// <remarks>
27+
/// For example, if <see cref="PixelDensity" /> is <c>2.0</c> (i.e. there are 2 pixels per screen coordinate)
28+
/// <i>and</i> the window manager requests that applications scale their content up by <c>2.0</c> to meet the user's
29+
/// settings as per <see cref="ContentScale" />, this would be <c>4.0</c>. This is because we're scaling once to
30+
/// account for the fact that the application has twice the amount of pixels available to it for the given window
31+
/// size, and then scaling again so that what we are drawing appears zoomed in as per the user's request. Note that
32+
/// it is rarely the case that an operating system employs both dense pixels <i>and</i> content scale. macOS for
33+
/// instance, instead of setting <see cref="ContentScale" />, opts to scale the resolution in the cases where the
34+
/// user wants magnified visuals instead of having the applications scale their content; whereas Windows sets
35+
/// <see cref="ContentScale" /> and instead always keeps <see cref="PixelDensity" /> as <c>1.0</c>. This is down
36+
/// to philosophical differences between the window coordinate systems on platforms as to whether they prefer to
37+
/// deal in physical device pixels or physical content sizes.
38+
/// </remarks>
39+
float DrawScale { get; }
40+
41+
/// <summary>
42+
/// Gets the ratio of pixels rendered to window size. This shall be equivalent to
43+
/// <see cref="Surface.DrawableSize" /> divided by <see cref="ISurfaceWindow.ClientSize" />.
44+
/// </summary>
45+
/// <seealso cref="DrawScale" />
46+
float PixelDensity { get; }
47+
}

0 commit comments

Comments
 (0)