Skip to content

Commit

Permalink
chore: get important changes from unoplatform#18216
Browse files Browse the repository at this point in the history
  • Loading branch information
ramezgerges committed Oct 7, 2024
1 parent 9817a07 commit fbe830a
Show file tree
Hide file tree
Showing 10 changed files with 60 additions and 38 deletions.
4 changes: 2 additions & 2 deletions doc/articles/controls/GLCanvasElement.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ uid: Uno.Controls.GLCanvasElement
## Uno.WinUI.Graphics3D.GLCanvasElement

> [!IMPORTANT]
> This functionality is only available on WinUI and Skia Desktop (`netX.0-desktop`) targets that are running with Desktop OpenGL (not GLES) hardware acceleration. This is also not available on MacOS.
> This functionality is only available on WinUI, Android and Skia Desktop (`netX.0-desktop`) and targets that are running on platforms with support for hardware acceleration. On Windows and Linux, this means having (desktop) OpenGL support. On Mac OS X, this means having Vulkan support (to be used by ANGLE). This is also not available on MacOS.
`GLCanvasElement` is a `Grid` for drawing 3D graphics with OpenGL. This class comes as a part of the `Uno.WinUI.Graphics3D` package.

Expand All @@ -31,7 +31,7 @@ The `OnDestroy` method is the complement of `Init` and is used to clean up any a

The `RenderOverride` is the main render-loop function. When adding your drawing logic in `RenderOverride`, you can assume that the OpenGL viewport rectangle is already set and its dimensions are equal to the `resolution` parameter provided to the `GLCanvasElement` constructor.

To learn more about using Silk.NET as a C# binding for OpenGL, see the examples in the Silk.NET repository [here](https://github.com/dotnet/Silk.NET/tree/main/examples/CSharp). Note that the windowing and inputs APIs in Silk.NET are not relevant to `GLCanvasElement`, since we only use Silk.NET as an OpenGL binding library, not a windowing library.
To learn more about using [Silk.NET](https://www.nuget.org/packages/Silk.NET.OpenGL/) as a C# binding for OpenGL, see the examples in the Silk.NET repository [here](https://github.com/dotnet/Silk.NET/tree/main/examples/CSharp). Note that the windowing and inputs APIs in Silk.NET are not relevant to `GLCanvasElement`, since we only use Silk.NET as an OpenGL binding library, not a windowing library.

Additionally, `GLCanvasElement` has an `Invalidate` method that requests a redrawing of the `GLCanvasElement`, calling `RenderOverride` in the process. Note that `RenderOverride` will only be called once per `Invalidate` call and the output will be saved to be used in future frames. To update the output, you must call `Invalidate`. If you need to continuously update the output (e.g. in an animation), you can add an `Invalidate` call inside `RenderOverride`.

Expand Down
12 changes: 6 additions & 6 deletions src/AddIns/Uno.WinUI.Graphics3DGL/GLCanvasElement.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
using System;
using System.Diagnostics;
using Silk.NET.OpenGL;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Media.Imaging;
using Silk.NET.OpenGL;
using Window = Microsoft.UI.Xaml.Window;

#if WINAPPSDK
using System.Runtime.InteropServices;
Expand Down Expand Up @@ -174,7 +174,7 @@ private unsafe void OnLoaded(object sender, RoutedEventArgs routedEventArgs)

private void OnUnloaded(object sender, RoutedEventArgs routedEventArgs)
{
Debug.Assert(_gl is not null); // because OnLoaded creates _gl
global::System.Diagnostics.Debug.Assert(_gl is not null); // because OnLoaded creates _gl

#if WINAPPSDK
Marshal.FreeHGlobal(_pixels);
Expand Down Expand Up @@ -215,7 +215,7 @@ private unsafe void Render()
return;
}

Debug.Assert(_gl is not null); // because _gl exists if loaded
global::System.Diagnostics.Debug.Assert(_gl is not null); // because _gl exists if loaded

using var _ = new GLStateDisposable(this);

Expand Down Expand Up @@ -253,15 +253,15 @@ public GLStateDisposable(GLCanvasElement glCanvasElement)
{
_glCanvasElement = glCanvasElement;
var gl = _glCanvasElement._gl;
Debug.Assert(gl is not null);
global::System.Diagnostics.Debug.Assert(gl is not null);

_contextDisposable = _glCanvasElement._nativeOpenGlWrapper.MakeCurrent();
}

public void Dispose()
{
var gl = _glCanvasElement._gl;
Debug.Assert(gl is not null);
global::System.Diagnostics.Debug.Assert(gl is not null);

_contextDisposable.Dispose();
}
Expand Down
30 changes: 20 additions & 10 deletions src/AddIns/Uno.WinUI.Graphics3DGL/Uno.WinUI.Graphics3DGL.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>$(NetSkiaPreviousAndCurrent)</TargetFrameworks>
<TargetFrameworks Condition="$(BuildGraphics3DGLForWindows) != ''">$(NetUWPOrWinUI)</TargetFrameworks>
<TargetFrameworks>$(NetPrevious)</TargetFrameworks>
<TargetFrameworks Condition="'$(BuildGraphics3DGLForWindows)' != ''">$(NetUWPOrWinUI)</TargetFrameworks>

<RootNamespace>Uno.WinUI.Graphics3DGL</RootNamespace>
<GeneratePackageOnBuild Condition="'$(Configuration)'=='Release'">true</GeneratePackageOnBuild>
Expand All @@ -18,8 +18,25 @@
<PackageReference Include="Uno.Core.Extensions.Logging.Singleton" Version="4.0.1" />
</ItemGroup>

<ItemGroup Condition="!$(TargetFramework.Contains('windows10'))">
<ProjectReference Include="..\..\Uno.UI\Uno.UI.Reference.csproj" PrivateAssets="all" />
</ItemGroup>

<Choose>
<When Condition="$(TargetFramework) == $(NetUWPOrWinUI)">
<!-- Android -->
<When Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)'))=='android'">
<PropertyGroup>
<DefineConstants>$(DefineConstants);ANDROID</DefineConstants>
</PropertyGroup>
</When>
<!-- Skia Desktop -->
<When Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)'))==''">
<PropertyGroup>
<DefineConstants>$(DefineConstants);CROSSRUNTIME</DefineConstants>
</PropertyGroup>
</When>
<!-- WinUI -->
<When Condition="$(TargetFramework.Contains('windows10'))">
<PropertyGroup>
<RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers>

Expand All @@ -39,13 +56,6 @@
<Compile Include="..\..\Uno.UI\Graphics\INativeOpenGLWrapper.cs" />
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<ProjectReference Include="..\..\Uno.Foundation\Uno.Foundation.Skia.csproj" />
<ProjectReference Include="..\..\Uno.UI\Uno.UI.Skia.csproj" />
<ProjectReference Include="..\..\Uno.UWP\Uno.Skia.csproj" />
</ItemGroup>
</Otherwise>
</Choose>

<ItemGroup>
Expand Down
9 changes: 4 additions & 5 deletions src/SamplesApp/SamplesApp.Skia/SamplesApp.Skia.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\AddIns\Uno.WinUI.Graphics3DGL\Uno.WinUI.Graphics3DGL.csproj" />
<ProjectReference Include="..\..\AddIns\Uno.WinUI.Graphics2DSK\Uno.WinUI.Graphics2DSK.csproj" />
<ProjectReference Include="..\..\AddIns\Uno.UI.Lottie\Uno.UI.Lottie.Skia.csproj" />
<ProjectReference Include="..\..\AddIns\Uno.UI.MSAL\Uno.UI.MSAL.Skia.csproj" />
<ProjectReference Include="..\..\AddIns\Uno.UI.Svg\Uno.UI.Svg.Skia.csproj" />
Expand All @@ -26,16 +28,13 @@
<ProjectReference Include="..\..\Uno.UI.RemoteControl\Uno.UI.RemoteControl.Skia.csproj" />
<ProjectReference Include="..\..\Uno.UI.RuntimeTests\Uno.UI.RuntimeTests.Skia.csproj" />
<ProjectReference Include="..\..\Uno.UI\Uno.UI.Skia.csproj" />
<ProjectReference Include="..\..\Uno.UI.Composition\Uno.UI.Composition.Skia.csproj" />
<ProjectReference Include="..\..\Uno.UI.Dispatching\Uno.UI.Dispatching.Skia.csproj" />
<ProjectReference Include="..\..\Uno.UI.Toolkit\Uno.UI.Toolkit.Skia.csproj" />
<ProjectReference Include="..\..\Uno.UWP\Uno.Skia.csproj" />
<ProjectReference Include="..\..\Uno.UI.Adapter.Microsoft.Extensions.Logging\Uno.UI.Adapter.Microsoft.Extensions.Logging.csproj" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\AddIns\Uno.WinUI.Graphics3DGL\Uno.WinUI.Graphics3DGL.csproj" />
<ProjectReference Include="..\..\AddIns\Uno.WinUI.Graphics2DSK\Uno.WinUI.Graphics2DSK.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Uno.BenchmarkDotNet" Version="0.11.7-develop" />
<PackageReference Include="Uno.BenchmarkDotNet.Annotations" Version="0.11.7-develop" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace UITests.Shared.Windows_UI_Composition
{
#if WINAPPSDK
public class RotatingCubeGlCanvasElement() : GLCanvasElement(1200, 800, () => SamplesApp.App.MainWindow)
#elif __SKIA__
#else
public class RotatingCubeGlCanvasElement() : GLCanvasElement(1200, 800, null)
#endif
{
Expand Down Expand Up @@ -67,9 +67,8 @@ public class RotatingCubeGlCanvasElement() : GLCanvasElement(1200, 800, null)
0, 4, 5,
};

private readonly string _vertexShaderSource = "#version 330" + Environment.NewLine +
private readonly string _vertexShaderSource =
"""

layout(location = 0) in vec3 pos;
layout(location = 1) in vec3 vertex_color;

Expand All @@ -83,9 +82,8 @@ void main() {
}
""";

private readonly string FragmentShaderSource = "#version 330" + Environment.NewLine +
private readonly string FragmentShaderSource =
"""

in vec3 color;

out vec4 frag_color;
Expand All @@ -104,7 +102,11 @@ protected override void Init(GL Gl)
_vao.VertexAttributePointer(0, 3, VertexAttribPointerType.Float, 6, 0);
_vao.VertexAttributePointer(1, 3, VertexAttribPointerType.Float, 6, 3);

_shader = new Shader(Gl, _vertexShaderSource, FragmentShaderSource);
var slVersion = Gl.GetStringS(StringName.ShadingLanguageVersion);
var versionDef = slVersion.Contains("OpenGL ES", StringComparison.InvariantCultureIgnoreCase)
? "#version 300 es"
: "#version 330";
_shader = new Shader(Gl, versionDef + Environment.NewLine + _vertexShaderSource, versionDef + Environment.NewLine + FragmentShaderSource);
}

protected override void OnDestroy(GL Gl)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ namespace UITests.Shared.Windows_UI_Composition
{
// https://learnopengl.com/Getting-started/Hello-Triangle
public class SimpleTriangleGlCanvasElement()
#if __SKIA__
: GLCanvasElement(1200, 800, null)
#elif WINAPPSDK
#if WINAPPSDK
: GLCanvasElement(1200, 800, () => SamplesApp.App.MainWindow)
#else
: GLCanvasElement(1200, 800, null)
#endif
{
private uint _vao;
Expand All @@ -37,10 +37,13 @@ unsafe protected override void Init(GL gl)
gl.VertexAttribPointer(0, 3, GLEnum.Float, false, 3 * sizeof(float), (void*)0);
gl.EnableVertexAttribArray(0);

// string.Empty is added so that the version line is not interpreted as a preprocessor command
var slVersion = gl.GetStringS(StringName.ShadingLanguageVersion);
var versionDef = slVersion.Contains("OpenGL ES", StringComparison.InvariantCultureIgnoreCase)
? "#version 300 es"
: "#version 330";
var vertexCode =
$$"""
{{string.Empty}}#version 330
{{versionDef}}

layout (location = 0) in vec3 aPosition;
out vec4 vertexColor;
Expand All @@ -52,10 +55,9 @@ void main()
}
""";

// string.Empty is added so that the version line is not interpreted as a preprocessor command
var fragmentCode =
$$"""
{{string.Empty}}#version 330
{{versionDef}}

out vec4 out_color;
in vec4 vertexColor;
Expand Down
1 change: 1 addition & 0 deletions src/Uno.Foundation/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,5 @@
[assembly: InternalsVisibleTo("Uno.UI.Runtime.WebAssembly")]
[assembly: InternalsVisibleTo("Uno.UI.Composition")]
[assembly: InternalsVisibleTo("Uno.UI.Dispatching")]
[assembly: InternalsVisibleTo("Uno.WinUI.Graphics3DGL")]
[assembly: System.Reflection.AssemblyMetadata("IsTrimmable", "True")]
1 change: 1 addition & 0 deletions src/Uno.UI-Skia-only.slnf
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"Uno.UI.Toolkit\\Uno.UI.Toolkit.Skia.csproj",
"Uno.UI.XamlHost.Skia.Wpf\\Uno.UI.XamlHost.Skia.Wpf.csproj",
"Uno.UI.XamlHost\\Uno.UI.XamlHost.Skia.csproj",
"Uno.UI\\Uno.UI.Reference.csproj",
"Uno.UI\\Uno.UI.Skia.csproj",
"Uno.UWPSyncGenerator.Reference\\Uno.UWPSyncGenerator.Reference.csproj",
"Uno.UWPSyncGenerator\\Uno.UWPSyncGenerator.csproj",
Expand Down
9 changes: 8 additions & 1 deletion src/Uno.UI/Graphics/INativeOpenGLWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,14 @@ internal interface INativeOpenGLWrapper
/// </summary>
public void CreateContext(UIElement element);

/// <remarks>This should be cast to a Silk.NET.GL</remarks>
/// <remarks>
/// This should be cast to a Silk.NET.OpenGL.GL (even on devices with GLES, not Desktop GL).
/// The Silk.NET.OpenGL.GL API surface is a almost a complete superset of the Silk.NET.OpenGLES.GL API
/// surface (with the exception of BlendBarrier and PrimitiveBoundingBox which are OpenGL ES 3.2-only APIs).
/// So, we always expose an OpenGL.GL object even on GLES devices, with the caveat that the user is only
/// allowed to make calls that are available on this GL (or GLES) version (just like OpenGL 4-only APIs
/// aren't allowed on OpenGL 3 implementations).
/// </remarks>
public object CreateGLSilkNETHandle();

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Uno.UI/XamlMerge.targets
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</ItemGroup>

<PropertyGroup>
<XamlMergeOutputFile>$(MSBuildProjectDirectory)\UI\Xaml\Style\mergedstyles.xaml</XamlMergeOutputFile>
<XamlMergeOutputFile>$(MSBuildProjectDirectory)\obj\$(MSBuildProjectName)\$(Configuration)\$(TargetFramework)\mergedstyles.xaml</XamlMergeOutputFile>
</PropertyGroup>

<ItemGroup>
Expand Down

0 comments on commit fbe830a

Please sign in to comment.