-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Win32+Angle: reuse the first created D3D11 display
- Loading branch information
Showing
6 changed files
with
196 additions
and
148 deletions.
There are no files selected for viewing
143 changes: 0 additions & 143 deletions
143
src/Windows/Avalonia.Win32/OpenGl/Angle/AngleWin32PlatformGraphics.cs
This file was deleted.
Oops, something went wrong.
48 changes: 48 additions & 0 deletions
48
src/Windows/Avalonia.Win32/OpenGl/Angle/AngleWin32PlatformGraphicsFactory.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
using System; | ||
using System.Linq; | ||
using Avalonia.Logging; | ||
using Avalonia.OpenGL.Angle; | ||
using Avalonia.Platform; | ||
|
||
namespace Avalonia.Win32.OpenGl.Angle; | ||
|
||
internal static class AngleWin32PlatformGraphicsFactory | ||
{ | ||
public static IPlatformGraphics? TryCreate(AngleOptions? options) | ||
{ | ||
Win32AngleEglInterface egl; | ||
try | ||
{ | ||
egl = new(); | ||
} | ||
catch (Exception e) | ||
{ | ||
Logger.TryGet(LogEventLevel.Error, "OpenGL") | ||
?.Log(null, "Unable to load ANGLE: {0}", e); | ||
return null; | ||
} | ||
|
||
var allowedPlatformApis = options?.AllowedPlatformApis ?? new[] { AngleOptions.PlatformApi.DirectX11 }; | ||
|
||
foreach (var api in allowedPlatformApis.Distinct()) | ||
{ | ||
switch (api) | ||
{ | ||
case AngleOptions.PlatformApi.DirectX11 | ||
when D3D11AngleWin32PlatformGraphics.TryCreate(egl) is { } platformGraphics: | ||
return platformGraphics; | ||
|
||
case AngleOptions.PlatformApi.DirectX9 | ||
when D3D9AngleWin32PlatformGraphics.TryCreate(egl) is { } platformGraphics: | ||
return platformGraphics; | ||
|
||
default: | ||
Logger.TryGet(LogEventLevel.Error, "OpenGL") | ||
?.Log(null, "Unknown requested PlatformApi {0}", api); | ||
break; | ||
} | ||
} | ||
|
||
return null; | ||
} | ||
} |
91 changes: 91 additions & 0 deletions
91
src/Windows/Avalonia.Win32/OpenGl/Angle/D3D11AngleWin32PlatformGraphics.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Threading; | ||
using Avalonia.Logging; | ||
using Avalonia.OpenGL; | ||
using Avalonia.OpenGL.Angle; | ||
using Avalonia.OpenGL.Egl; | ||
using Avalonia.Platform; | ||
|
||
namespace Avalonia.Win32.OpenGl.Angle; | ||
|
||
internal sealed class D3D11AngleWin32PlatformGraphics : IPlatformGraphics, IPlatformGraphicsOpenGlContextFactory | ||
{ | ||
private readonly Win32AngleEglInterface _egl; | ||
private AngleWin32EglDisplay? _initialDisplay; | ||
|
||
public D3D11AngleWin32PlatformGraphics(Win32AngleEglInterface egl, AngleWin32EglDisplay? initialDisplay) | ||
{ | ||
_egl = egl; | ||
_initialDisplay = initialDisplay; | ||
} | ||
|
||
public bool UsesSharedContext | ||
=> false; | ||
|
||
public IPlatformGraphicsContext CreateContext() | ||
{ | ||
var display = Interlocked.Exchange(ref _initialDisplay, null); | ||
if (display is { IsLost: true }) | ||
display = null; | ||
|
||
display ??= AngleWin32EglDisplay.CreateD3D11Display(_egl); | ||
return CreateContextForDisplay(display); | ||
} | ||
|
||
private static EglContext CreateContextForDisplay(AngleWin32EglDisplay display) | ||
{ | ||
var success = false; | ||
try | ||
{ | ||
var context = display.CreateContext(new EglContextOptions | ||
{ | ||
DisposeCallback = display.Dispose, | ||
ExtraFeatures = new Dictionary<Type, Func<EglContext, object>> | ||
{ | ||
[typeof(IGlPlatformSurfaceRenderTargetFactory)] = _ => new AngleD3DTextureFeature(), | ||
[typeof(IGlContextExternalObjectsFeature)] = context => new AngleExternalObjectsFeature(context) | ||
} | ||
}); | ||
success = true; | ||
return context; | ||
} | ||
finally | ||
{ | ||
if (!success) | ||
display.Dispose(); | ||
} | ||
} | ||
|
||
public IGlContext CreateContext(IEnumerable<GlVersion>? versions) | ||
{ | ||
if (versions is not null && versions.All(v => v.Type != GlProfileType.OpenGLES || v.Major != 3)) | ||
throw new OpenGlException("Unable to create context with requested version"); | ||
|
||
return (IGlContext)CreateContext(); | ||
} | ||
|
||
IPlatformGraphicsContext IPlatformGraphics.GetSharedContext() | ||
=> throw new InvalidOperationException(); | ||
|
||
public static D3D11AngleWin32PlatformGraphics? TryCreate(Win32AngleEglInterface egl) | ||
{ | ||
AngleWin32EglDisplay? display = null; | ||
try | ||
{ | ||
display = AngleWin32EglDisplay.CreateD3D11Display(egl); | ||
using var ctx = display.CreateContext(new EglContextOptions()); | ||
ctx.MakeCurrent().Dispose(); | ||
} | ||
catch (Exception e) | ||
{ | ||
display?.Dispose(); | ||
Logger.TryGet(LogEventLevel.Error, "OpenGL") | ||
?.Log(null, "Unable to initialize ANGLE-based rendering with DirectX11 : {0}", e); | ||
return null; | ||
} | ||
|
||
return new D3D11AngleWin32PlatformGraphics(egl, display); | ||
} | ||
} |
53 changes: 53 additions & 0 deletions
53
src/Windows/Avalonia.Win32/OpenGl/Angle/D3D9AngleWin32PlatformGraphics.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
using System; | ||
using Avalonia.Logging; | ||
using Avalonia.OpenGL.Angle; | ||
using Avalonia.OpenGL.Egl; | ||
using Avalonia.Platform; | ||
|
||
namespace Avalonia.Win32.OpenGl.Angle; | ||
|
||
internal sealed class D3D9AngleWin32PlatformGraphics : IPlatformGraphics | ||
{ | ||
private readonly AngleWin32EglDisplay _sharedDisplay; | ||
private EglContext? _sharedContext; | ||
|
||
public D3D9AngleWin32PlatformGraphics(AngleWin32EglDisplay sharedDisplay) | ||
=> _sharedDisplay = sharedDisplay; | ||
|
||
public bool UsesSharedContext | ||
=> true; | ||
|
||
public IPlatformGraphicsContext GetSharedContext() | ||
{ | ||
if (_sharedContext is { IsLost: true }) | ||
{ | ||
_sharedContext.Dispose(); | ||
_sharedContext = null; | ||
} | ||
|
||
return _sharedContext ??= _sharedDisplay.CreateContext(new EglContextOptions()); | ||
} | ||
|
||
IPlatformGraphicsContext IPlatformGraphics.CreateContext() | ||
=> throw new InvalidOperationException(); | ||
|
||
public static D3D9AngleWin32PlatformGraphics? TryCreate(Win32AngleEglInterface egl) | ||
{ | ||
AngleWin32EglDisplay? sharedDisplay = null; | ||
try | ||
{ | ||
sharedDisplay = AngleWin32EglDisplay.CreateD3D9Display(egl); | ||
using var ctx = sharedDisplay.CreateContext(new EglContextOptions()); | ||
ctx.MakeCurrent().Dispose(); | ||
} | ||
catch (Exception e) | ||
{ | ||
sharedDisplay?.Dispose(); | ||
Logger.TryGet(LogEventLevel.Error, "OpenGL") | ||
?.Log(null, "Unable to initialize ANGLE-based rendering with DirectX9 : {0}", e); | ||
return null; | ||
} | ||
|
||
return new D3D9AngleWin32PlatformGraphics(sharedDisplay); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters