Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Angle WPF #1521

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
38 changes: 12 additions & 26 deletions samples/Gallery/WPF/SkiaSharpSample.sln
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.HarfBuzz", "..\..
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Views.Desktop.Common", "..\..\..\source\SkiaSharp.Views\SkiaSharp.Views.Desktop.Common\SkiaSharp.Views.Desktop.Common.csproj", "{D52BB2A5-9B68-4A89-B221-2A4EC7DA01F9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Views.WindowsForms", "..\..\..\source\SkiaSharp.Views\SkiaSharp.Views.WindowsForms\SkiaSharp.Views.WindowsForms.csproj", "{A1334727-7CC6-43AC-A617-EEFE2174F454}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -27,6 +25,18 @@ Global
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{74178C7C-19A0-45E6-8EFB-F4DB7EE37C6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{74178C7C-19A0-45E6-8EFB-F4DB7EE37C6F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{74178C7C-19A0-45E6-8EFB-F4DB7EE37C6F}.Debug|x64.ActiveCfg = Debug|x64
{74178C7C-19A0-45E6-8EFB-F4DB7EE37C6F}.Debug|x64.Build.0 = Debug|x64
{74178C7C-19A0-45E6-8EFB-F4DB7EE37C6F}.Debug|x86.ActiveCfg = Debug|x86
{74178C7C-19A0-45E6-8EFB-F4DB7EE37C6F}.Debug|x86.Build.0 = Debug|x86
{74178C7C-19A0-45E6-8EFB-F4DB7EE37C6F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{74178C7C-19A0-45E6-8EFB-F4DB7EE37C6F}.Release|Any CPU.Build.0 = Release|Any CPU
{74178C7C-19A0-45E6-8EFB-F4DB7EE37C6F}.Release|x64.ActiveCfg = Release|x64
{74178C7C-19A0-45E6-8EFB-F4DB7EE37C6F}.Release|x64.Build.0 = Release|x64
{74178C7C-19A0-45E6-8EFB-F4DB7EE37C6F}.Release|x86.ActiveCfg = Release|x86
{74178C7C-19A0-45E6-8EFB-F4DB7EE37C6F}.Release|x86.Build.0 = Release|x86
{EB1BBDCC-FB07-40D5-8B9E-0079E2C2F2DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EB1BBDCC-FB07-40D5-8B9E-0079E2C2F2DF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EB1BBDCC-FB07-40D5-8B9E-0079E2C2F2DF}.Debug|x64.ActiveCfg = Debug|Any CPU
Expand Down Expand Up @@ -63,18 +73,6 @@ Global
{2AE5D8C5-EAC6-4515-89F2-A4994B41C925}.Release|x64.Build.0 = Release|Any CPU
{2AE5D8C5-EAC6-4515-89F2-A4994B41C925}.Release|x86.ActiveCfg = Release|Any CPU
{2AE5D8C5-EAC6-4515-89F2-A4994B41C925}.Release|x86.Build.0 = Release|Any CPU
{74178C7C-19A0-45E6-8EFB-F4DB7EE37C6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{74178C7C-19A0-45E6-8EFB-F4DB7EE37C6F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{74178C7C-19A0-45E6-8EFB-F4DB7EE37C6F}.Debug|x64.ActiveCfg = Debug|x64
{74178C7C-19A0-45E6-8EFB-F4DB7EE37C6F}.Debug|x64.Build.0 = Debug|x64
{74178C7C-19A0-45E6-8EFB-F4DB7EE37C6F}.Debug|x86.ActiveCfg = Debug|x86
{74178C7C-19A0-45E6-8EFB-F4DB7EE37C6F}.Debug|x86.Build.0 = Debug|x86
{74178C7C-19A0-45E6-8EFB-F4DB7EE37C6F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{74178C7C-19A0-45E6-8EFB-F4DB7EE37C6F}.Release|Any CPU.Build.0 = Release|Any CPU
{74178C7C-19A0-45E6-8EFB-F4DB7EE37C6F}.Release|x64.ActiveCfg = Release|x64
{74178C7C-19A0-45E6-8EFB-F4DB7EE37C6F}.Release|x64.Build.0 = Release|x64
{74178C7C-19A0-45E6-8EFB-F4DB7EE37C6F}.Release|x86.ActiveCfg = Release|x86
{74178C7C-19A0-45E6-8EFB-F4DB7EE37C6F}.Release|x86.Build.0 = Release|x86
{156FADFB-602E-4658-A235-D4D24CD46F09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{156FADFB-602E-4658-A235-D4D24CD46F09}.Debug|Any CPU.Build.0 = Debug|Any CPU
{156FADFB-602E-4658-A235-D4D24CD46F09}.Debug|x64.ActiveCfg = Debug|Any CPU
Expand All @@ -99,18 +97,6 @@ Global
{D52BB2A5-9B68-4A89-B221-2A4EC7DA01F9}.Release|x64.Build.0 = Release|Any CPU
{D52BB2A5-9B68-4A89-B221-2A4EC7DA01F9}.Release|x86.ActiveCfg = Release|Any CPU
{D52BB2A5-9B68-4A89-B221-2A4EC7DA01F9}.Release|x86.Build.0 = Release|Any CPU
{A1334727-7CC6-43AC-A617-EEFE2174F454}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A1334727-7CC6-43AC-A617-EEFE2174F454}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A1334727-7CC6-43AC-A617-EEFE2174F454}.Debug|x64.ActiveCfg = Debug|Any CPU
{A1334727-7CC6-43AC-A617-EEFE2174F454}.Debug|x64.Build.0 = Debug|Any CPU
{A1334727-7CC6-43AC-A617-EEFE2174F454}.Debug|x86.ActiveCfg = Debug|Any CPU
{A1334727-7CC6-43AC-A617-EEFE2174F454}.Debug|x86.Build.0 = Debug|Any CPU
{A1334727-7CC6-43AC-A617-EEFE2174F454}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A1334727-7CC6-43AC-A617-EEFE2174F454}.Release|Any CPU.Build.0 = Release|Any CPU
{A1334727-7CC6-43AC-A617-EEFE2174F454}.Release|x64.ActiveCfg = Release|Any CPU
{A1334727-7CC6-43AC-A617-EEFE2174F454}.Release|x64.Build.0 = Release|Any CPU
{A1334727-7CC6-43AC-A617-EEFE2174F454}.Release|x86.ActiveCfg = Release|Any CPU
{A1334727-7CC6-43AC-A617-EEFE2174F454}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
13 changes: 2 additions & 11 deletions samples/Gallery/WPF/SkiaSharpSample/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="clr-namespace:SkiaSharp.Views.WPF;assembly=SkiaSharp.Views.WPF"
xmlns:local="clr-namespace:SkiaSharpSample"
xmlns:wpf="clr-namespace:SkiaSharp.Views.WPF;assembly=SkiaSharp.Views.WPF"
mc:Ignorable="d"
Title="SkiaSharp for WPF" Height="350" Width="525" Icon="icon.ico">
<DockPanel>
Expand All @@ -16,17 +15,9 @@
<MenuItem Header="Toggle Samples Slideshow" Click="OnToggleSlideshow" />
<Separator />
</MenuItem>
<MenuItem Header="_Tools">
<MenuItem Header="Configure Backend">
<MenuItem Header="Memory" Click="OnBackendChanged" Tag="Memory" />
<MenuItem Header="OpenGL" Click="OnBackendChanged" Tag="OpenGL" />
<MenuItem Header="Vulkan" Click="OnBackendChanged" Tag="Vulkan" />
</MenuItem>
</MenuItem>
</Menu>
<Grid>
<views:SKElement x:Name="canvas" PaintSurface="OnPaintCanvas" MouseLeftButtonUp="OnSampleClicked" />
<WindowsFormsHost x:Name="glhost" Initialized="OnGLControlHost" Visibility="Collapsed" />
<wpf:SKElement x:Name="canvas" PaintSurface="OnPaintCanvas" MouseLeftButtonUp="OnSampleClicked" />
</Grid>
</DockPanel>
</Window>
19 changes: 0 additions & 19 deletions samples/Gallery/WPF/SkiaSharpSample/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,9 @@ private void OnBackendChanged(object sender, RoutedEventArgs e)
switch (backend)
{
case SampleBackends.Memory:
glhost.Visibility = Visibility.Collapsed;
canvas.Visibility = Visibility.Visible;
break;
case SampleBackends.OpenGL:
glhost.Visibility = Visibility.Visible;
canvas.Visibility = Visibility.Collapsed;
break;
default:
Expand Down Expand Up @@ -148,22 +146,6 @@ private void OnToggleSlideshow(object sender, RoutedEventArgs e)
}
}

private void OnGLControlHost(object sender, EventArgs e)
{
var glControl = new SKGLControl();
glControl.PaintSurface += OnPaintGL;
glControl.Dock = System.Windows.Forms.DockStyle.Fill;
glControl.Click += OnSampleClicked;

var host = (WindowsFormsHost)sender;
host.Child = glControl;
}

private void OnPaintGL(object sender, SKPaintGLSurfaceEventArgs e)
{
OnPaintSurface(e.Surface.Canvas, e.BackendRenderTarget.Width, e.BackendRenderTarget.Height);
}

private void OnPaintCanvas(object sender, SKPaintSurfaceEventArgs e)
{
OnPaintSurface(e.Surface.Canvas, e.Info.Width, e.Info.Height);
Expand Down Expand Up @@ -202,7 +184,6 @@ private void SetSample(SampleBase newSample)
private void OnRefreshRequested(object sender, EventArgs e)
{
canvas.InvalidateVisual();
glhost.Child?.Invalidate();
}

private void OnPaintSurface(SKCanvas canvas, int width, int height)
Expand Down
6 changes: 1 addition & 5 deletions samples/Gallery/WPF/SkiaSharpSample/SkiaSharpSample.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
<Reference Include="WindowsFormsIntegration" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="OpenTK" Version="3.1.0" />
<PackageReference Include="OpenTK" Version="3.2.0" />
<PackageReference Include="OpenTK.GLControl" Version="3.1.0" />
<ProjectReference Include="..\..\..\..\binding\HarfBuzzSharp\HarfBuzzSharp.csproj">
<Project>{2ae5d8c5-eac6-4515-89f2-a4994b41c925}</Project>
Expand All @@ -115,10 +115,6 @@
<Project>{d52bb2a5-9b68-4a89-b221-2a4ec7da01f9}</Project>
<Name>SkiaSharp.Views.Desktop.Common</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\..\source\SkiaSharp.Views\SkiaSharp.Views.WindowsForms\SkiaSharp.Views.WindowsForms.csproj">
<Project>{a1334727-7cc6-43ac-a617-eefe2174f454}</Project>
<Name>SkiaSharp.Views.WindowsForms</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\..\source\SkiaSharp.Views\SkiaSharp.Views.WPF\SkiaSharp.Views.WPF.csproj">
<Project>{743cf830-d458-41a9-865a-f85126562015}</Project>
<Name>SkiaSharp.Views.WPF</Name>
Expand Down
9 changes: 9 additions & 0 deletions source/SkiaSharp.Views/SkiaSharp.Views.WPF/GLMode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace SkiaSharp.Views.WPF
{
public enum GLMode : byte
{
NotInitialized = 0,
Angle = 1,
CPU = 2,
}
}
96 changes: 96 additions & 0 deletions source/SkiaSharp.Views/SkiaSharp.Views.WPF/Interop/D3D9Interop.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
using System;
using SharpDX.Direct3D9;

namespace SkiaSharp.Views.WPF.Angle
{
internal class D3D9Interop
{
private bool disposed;
private Texture? texture;
private readonly Direct3DEx d3dEx;
private readonly DeviceEx deviceEx;

public D3D9Interop()
{
d3dEx = new Direct3DEx();
deviceEx = MakeDevice();
}

/// <summary>
/// Creates a new Direct3D9 Ex device, required for efficient
/// hardware-accelerated in Windows Vista and later.
/// </summary>
/// <returns></returns>
private DeviceEx MakeDevice() =>
new DeviceEx(d3dEx, 0,
DeviceType.Hardware,
IntPtr.Zero,
CreateFlags.HardwareVertexProcessing
| CreateFlags.Multithreaded
| CreateFlags.FpuPreserve,
new PresentParameters
{
Windowed = true,
SwapEffect = SwapEffect.Discard,
PresentationInterval = PresentInterval.Immediate,

// The device back buffer is not used.
BackBufferFormat = Format.Unknown,
BackBufferWidth = 1,
BackBufferHeight = 1,

// Use dummy window handle.
DeviceWindowHandle = IntPtr.Zero
});

/// <summary>
/// Creates a new Direct3D9 texture that uses the same memory as the
/// passed in DirectX11-texture.
/// </summary>
public Texture CreateNewSharedTexture(IntPtr sharedHandle, int width, int height)
{
if (disposed)
{
throw new ObjectDisposedException(GetType().FullName);
}
if (sharedHandle == IntPtr.Zero)
{
throw new ArgumentException(
"Unable to access resource. The texture needs to be created as a shared resource.", "render_target");
}

texture?.Dispose();
texture = new Texture(deviceEx,
width,
height,
1, Usage.RenderTarget, Format.A8R8G8B8,
Pool.Default, ref sharedHandle);
return texture;
}

~D3D9Interop()
{
Dispose(false);
}

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

private void Dispose(bool disposeManaged)
{
if (disposed)
return;

if (disposeManaged)
{
texture?.Dispose();
deviceEx?.Dispose();
d3dEx?.Dispose();
}
disposed = true;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using System;
using System.Windows.Forms;
using OpenTK.Graphics;
using OpenTK.Platform;
using OpenTK.Platform.Egl;

namespace SkiaSharp.Views.WPF.Angle
{
/// <summary>
/// GLES 2.0 and ANGLE context initialization over DirectX 9
/// </summary>
internal class D3DAngleInterop : IDisposable
{
private readonly Control control;
private readonly GraphicsContext context;
private readonly IAngleWindowInfo windowInfo;
private readonly D3D9Interop d3d9Interop;
private bool disposed;

public D3DAngleInterop()
{
d3d9Interop = new D3D9Interop();
control = new Control();

var basicWindowInfo = Utilities.CreateWindowsWindowInfo(control.Handle);
windowInfo = Utilities.CreateAngleWindowInfo(basicWindowInfo);

context = new GraphicsContext(
new GraphicsMode(32, 24), windowInfo, 2, 0,
GraphicsContextFlags.Embedded | GraphicsContextFlags.Offscreen | GraphicsContextFlags.AngleD3D9);
context.MakeCurrent(windowInfo);
context.LoadAll();
}

public IntPtr GetD3DSharedHandleForSurface(IntPtr eglSurface, int width, int height)
{
var ptr = windowInfo.QuerySurfacePointer(eglSurface);
var texture = d3d9Interop.CreateNewSharedTexture(ptr, width, height);
return texture.GetSurfaceLevel(0).NativePointer;
}

public void EnsureContext() => context.MakeCurrent(windowInfo);

public void MakeCurrent(IntPtr surface) => windowInfo.MakeCurrent(surface);

public IntPtr CreateOffscreenSurface(int width, int height) => windowInfo.CreateSurface(width, height);

public void DestroyOffscreenSurface(ref IntPtr surface) => windowInfo.DestroySurface(ref surface);

~D3DAngleInterop()
{
Dispose(false);
}

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

private void Dispose(bool disposeManaged)
{
if (disposed)
return;

if (disposeManaged)
{
context.Dispose();
d3d9Interop.Dispose();
}
disposed = true;
}
}
}
Loading