committed by
GitHub
19 changed files with 2745 additions and 0 deletions
@ -0,0 +1,11 @@ |
|||||
|
{ |
||||
|
"profiles": { |
||||
|
"ControlCatalog.NetCore": { |
||||
|
"commandName": "Project" |
||||
|
}, |
||||
|
"Dxgi": { |
||||
|
"commandName": "Project", |
||||
|
"commandLineArgs": "--dxgi" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Globalization; |
||||
|
using System.Text; |
||||
|
using Avalonia.Data.Converters; |
||||
|
|
||||
|
namespace ControlCatalog.Converter |
||||
|
{ |
||||
|
public class DegToRadConverter : IValueConverter |
||||
|
{ |
||||
|
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) |
||||
|
{ |
||||
|
if (value is double rad) |
||||
|
{ |
||||
|
return rad * 180.0d / Math.PI; |
||||
|
} |
||||
|
return 0.0d; |
||||
|
} |
||||
|
|
||||
|
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) |
||||
|
{ |
||||
|
if (value is double deg) |
||||
|
{ |
||||
|
return deg / 180.0d * Math.PI; |
||||
|
} |
||||
|
return 0.0d; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,107 @@ |
|||||
|
<UserControl xmlns="https://github.com/avaloniaui" |
||||
|
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:local="using:ControlCatalog.Pages" |
||||
|
xmlns:converters="using:ControlCatalog.Converter" |
||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" |
||||
|
x:Class="ControlCatalog.Pages.CustomDrawing"> |
||||
|
|
||||
|
<UserControl.Resources> |
||||
|
<converters:DegToRadConverter x:Key="DegToRadConverter"/> |
||||
|
</UserControl.Resources> |
||||
|
|
||||
|
<Grid> |
||||
|
<Grid.ColumnDefinitions> |
||||
|
<ColumnDefinition/> |
||||
|
<ColumnDefinition/> |
||||
|
<ColumnDefinition/> |
||||
|
</Grid.ColumnDefinitions> |
||||
|
<Grid.RowDefinitions> |
||||
|
<RowDefinition Height="Auto"/> |
||||
|
<RowDefinition/> |
||||
|
</Grid.RowDefinitions> |
||||
|
|
||||
|
<StackPanel Orientation="Vertical"> |
||||
|
<TextBlock Text="Translation" HorizontalAlignment="Center"/> |
||||
|
<Grid ColumnDefinitions="*,*" |
||||
|
RowDefinitions="Auto,Auto" |
||||
|
> |
||||
|
<TextBlock Text="Horizontal"/> |
||||
|
<TextBlock Text="Vertical" Grid.Column="1"/> |
||||
|
<TextBox IsEnabled="False" |
||||
|
Text="{Binding ElementName=CustomDrawingControl, |
||||
|
Path=ViewportCenterX, |
||||
|
Mode=OneWay, |
||||
|
StringFormat=\{0:g4\}}" |
||||
|
Grid.Row="1" |
||||
|
/> |
||||
|
<TextBox IsEnabled="False" |
||||
|
Text="{Binding ElementName=CustomDrawingControl, |
||||
|
Path=ViewportCenterY, |
||||
|
Mode=OneWay, |
||||
|
StringFormat=\{0:g4\}}" |
||||
|
Grid.Row="1" Grid.Column="1" |
||||
|
/> |
||||
|
</Grid> |
||||
|
</StackPanel> |
||||
|
|
||||
|
<StackPanel Orientation="Vertical" Grid.Column="1" |
||||
|
> |
||||
|
<TextBlock Text="Rotation" HorizontalAlignment="Center"/> |
||||
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" |
||||
|
> |
||||
|
<Button Content="➖" Width="40" Height="40" |
||||
|
VerticalContentAlignment="Center" |
||||
|
VerticalAlignment="Center" |
||||
|
Click="RotateMinus" |
||||
|
/> |
||||
|
<TextBox IsEnabled="False" |
||||
|
Text="{Binding ElementName=CustomDrawingControl, |
||||
|
Path=Rotation, |
||||
|
Converter={StaticResource DegToRadConverter}, |
||||
|
Mode=OneWay, |
||||
|
StringFormat=\{0:g4\}}" |
||||
|
Grid.Row="1" Grid.Column="1" |
||||
|
/> |
||||
|
<Button Content="➕" Width="40" Height="40" |
||||
|
VerticalContentAlignment="Center" |
||||
|
VerticalAlignment="Center" |
||||
|
Click="RotatePlus" |
||||
|
/> |
||||
|
</StackPanel> |
||||
|
</StackPanel> |
||||
|
|
||||
|
<StackPanel Orientation="Vertical" Grid.Column="2" |
||||
|
> |
||||
|
<TextBlock Text="Scale" HorizontalAlignment="Center"/> |
||||
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" |
||||
|
> |
||||
|
<Button Content="➖" Width="40" Height="40" |
||||
|
VerticalContentAlignment="Center" |
||||
|
VerticalAlignment="Center" |
||||
|
Click="ZoomOut" |
||||
|
/> |
||||
|
<TextBox IsEnabled="False" |
||||
|
Text="{Binding ElementName=CustomDrawingControl, |
||||
|
Path=Scale, |
||||
|
Mode=OneWay, |
||||
|
StringFormat=\{0:g4\}}" |
||||
|
Grid.Row="1" Grid.Column="1" |
||||
|
/> |
||||
|
<Button Content="➕" Width="40" Height="40" |
||||
|
VerticalContentAlignment="Center" |
||||
|
VerticalAlignment="Center" |
||||
|
Click="ZoomIn" |
||||
|
/> |
||||
|
</StackPanel> |
||||
|
</StackPanel> |
||||
|
|
||||
|
<Grid Grid.Row="1" Grid.ColumnSpan="3" ClipToBounds="True"> |
||||
|
<local:CustomDrawingExampleControl |
||||
|
x:Name="CustomDrawingControl" |
||||
|
/> |
||||
|
</Grid> |
||||
|
</Grid> |
||||
|
|
||||
|
</UserControl> |
||||
@ -0,0 +1,67 @@ |
|||||
|
using System; |
||||
|
using Avalonia.Controls; |
||||
|
using Avalonia.Interactivity; |
||||
|
using Avalonia.Markup.Xaml; |
||||
|
|
||||
|
namespace ControlCatalog.Pages |
||||
|
{ |
||||
|
public partial class CustomDrawing : UserControl |
||||
|
{ |
||||
|
public CustomDrawing() |
||||
|
{ |
||||
|
InitializeComponent(); |
||||
|
} |
||||
|
|
||||
|
private CustomDrawingExampleControl? _customControl; |
||||
|
public CustomDrawingExampleControl CustomDrawingControl |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
if (_customControl is not null) |
||||
|
return _customControl; |
||||
|
throw new System.Exception("Control did not get initialized"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void InitializeComponent() |
||||
|
{ |
||||
|
AvaloniaXamlLoader.Load(this); |
||||
|
var cntrl = this.FindControl<CustomDrawingExampleControl>("CustomDrawingControl"); |
||||
|
if (cntrl != null) |
||||
|
{ |
||||
|
_customControl = cntrl; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
// be sad about it
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void RotateMinus (object? sender, RoutedEventArgs e) |
||||
|
{ |
||||
|
if (_customControl is null) return; |
||||
|
_customControl.Rotation -= Math.PI / 20.0d; |
||||
|
} |
||||
|
|
||||
|
private void RotatePlus(object? sender, RoutedEventArgs e) |
||||
|
{ |
||||
|
if (_customControl is null) |
||||
|
return; |
||||
|
_customControl.Rotation += Math.PI / 20.0d; |
||||
|
} |
||||
|
|
||||
|
private void ZoomIn(object? sender, RoutedEventArgs e) |
||||
|
{ |
||||
|
if (_customControl is null) |
||||
|
return; |
||||
|
_customControl.Scale *= 1.2d; |
||||
|
} |
||||
|
|
||||
|
private void ZoomOut(object? sender, RoutedEventArgs e) |
||||
|
{ |
||||
|
if (_customControl is null) |
||||
|
return; |
||||
|
_customControl.Scale /= 1.2d; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,215 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Globalization; |
||||
|
using System.Text; |
||||
|
using Avalonia; |
||||
|
using Avalonia.Controls; |
||||
|
using Avalonia.Media; |
||||
|
using Avalonia.Input; |
||||
|
using Avalonia.Threading; |
||||
|
using Avalonia.Controls.Shapes; |
||||
|
|
||||
|
namespace ControlCatalog.Pages |
||||
|
{ |
||||
|
public class CustomDrawingExampleControl : Control |
||||
|
{ |
||||
|
private Point _cursorPoint; |
||||
|
|
||||
|
|
||||
|
public StyledProperty<double> ScaleProperty = AvaloniaProperty.Register<CustomDrawingExampleControl, double>(nameof(Scale), 1.0d); |
||||
|
public double Scale { get => GetValue(ScaleProperty); set => SetValue(ScaleProperty, value); } |
||||
|
|
||||
|
public StyledProperty<double> RotationProperty = AvaloniaProperty.Register<CustomDrawingExampleControl, double>(nameof(Rotation)); |
||||
|
/// <summary>
|
||||
|
/// Rotation, measured in Radians!
|
||||
|
/// </summary>
|
||||
|
public double Rotation |
||||
|
{ |
||||
|
get => GetValue(RotationProperty); |
||||
|
set |
||||
|
{ |
||||
|
double valueToUse = value % (Math.PI * 2); |
||||
|
SetValue(RotationProperty, valueToUse); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public StyledProperty<double> ViewportCenterYProperty = AvaloniaProperty.Register<CustomDrawingExampleControl, double>(nameof(ViewportCenterY), 0.0d); |
||||
|
public double ViewportCenterY { get => GetValue(ViewportCenterYProperty); set => SetValue(ViewportCenterYProperty, value); } |
||||
|
|
||||
|
public StyledProperty<double> ViewportCenterXProperty = AvaloniaProperty.Register<CustomDrawingExampleControl, double>(nameof(ViewportCenterX), 0.0d); |
||||
|
public double ViewportCenterX { get => GetValue(ViewportCenterXProperty); set => SetValue(ViewportCenterXProperty, value); } |
||||
|
|
||||
|
private IPen _pen; |
||||
|
|
||||
|
private System.Diagnostics.Stopwatch _timeKeeper = System.Diagnostics.Stopwatch.StartNew(); |
||||
|
|
||||
|
private bool _isPointerCaptured = false; |
||||
|
|
||||
|
public CustomDrawingExampleControl() |
||||
|
{ |
||||
|
_pen = new Pen(new SolidColorBrush(Colors.Black), lineCap: PenLineCap.Round); |
||||
|
|
||||
|
var _arc = new ArcSegment() |
||||
|
{ |
||||
|
IsLargeArc = false, |
||||
|
Point = new Point(0, 0), |
||||
|
RotationAngle = 0, |
||||
|
Size = new Size(25, 25), |
||||
|
SweepDirection = SweepDirection.Clockwise, |
||||
|
|
||||
|
}; |
||||
|
StreamGeometry sg = new StreamGeometry(); |
||||
|
var cntx = sg.Open(); |
||||
|
cntx.BeginFigure(new Point(-25.0d, -10.0d), false); |
||||
|
cntx.ArcTo(new Point(25.0d, -10.0d), new Size(10.0d, 10.0d), 0.0d, false, SweepDirection.Clockwise); |
||||
|
cntx.EndFigure(true); |
||||
|
_smileGeometry = sg.Clone(); |
||||
|
} |
||||
|
|
||||
|
private Geometry _smileGeometry; |
||||
|
|
||||
|
protected override void OnPointerMoved(PointerEventArgs e) |
||||
|
{ |
||||
|
base.OnPointerMoved(e); |
||||
|
|
||||
|
Point previousPoint = _cursorPoint; |
||||
|
|
||||
|
_cursorPoint = e.GetPosition(this); |
||||
|
|
||||
|
if (_isPointerCaptured) |
||||
|
{ |
||||
|
Point oldWorldPoint = UIPointToWorldPoint(previousPoint, ViewportCenterX, ViewportCenterY, Scale, Rotation); |
||||
|
Point newWorldPoint = UIPointToWorldPoint(_cursorPoint, ViewportCenterX, ViewportCenterY, Scale, Rotation); |
||||
|
|
||||
|
Vector diff = newWorldPoint - oldWorldPoint; |
||||
|
|
||||
|
ViewportCenterX -= diff.X; |
||||
|
ViewportCenterY -= diff.Y; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected override void OnPointerPressed(PointerPressedEventArgs e) |
||||
|
{ |
||||
|
e.Handled = true; |
||||
|
e.Pointer.Capture(this); |
||||
|
_isPointerCaptured = true; |
||||
|
base.OnPointerPressed(e); |
||||
|
} |
||||
|
|
||||
|
protected override void OnPointerWheelChanged(PointerWheelEventArgs e) |
||||
|
{ |
||||
|
base.OnPointerWheelChanged(e); |
||||
|
var oldScale = Scale; |
||||
|
Scale *= (1.0d + e.Delta.Y / 12.0d); |
||||
|
|
||||
|
Point oldWorldPoint = UIPointToWorldPoint(_cursorPoint, ViewportCenterX, ViewportCenterY, oldScale, Rotation); |
||||
|
Point newWorldPoint = UIPointToWorldPoint(_cursorPoint, ViewportCenterX, ViewportCenterY, Scale, Rotation); |
||||
|
|
||||
|
Vector diff = newWorldPoint - oldWorldPoint; |
||||
|
|
||||
|
ViewportCenterX -= diff.X; |
||||
|
ViewportCenterY -= diff.Y; |
||||
|
} |
||||
|
|
||||
|
protected override void OnPointerReleased(PointerReleasedEventArgs e) |
||||
|
{ |
||||
|
e.Pointer.Capture(null); |
||||
|
_isPointerCaptured = false; |
||||
|
base.OnPointerReleased(e); |
||||
|
} |
||||
|
|
||||
|
public override void Render(DrawingContext context) |
||||
|
{ |
||||
|
var localBounds = new Rect(new Size(this.Bounds.Width, this.Bounds.Height)); |
||||
|
var clip = context.PushClip(this.Bounds); |
||||
|
context.DrawRectangle(Brushes.White, _pen, localBounds, 1.0d); |
||||
|
|
||||
|
var halfMax = Math.Max(this.Bounds.Width / 2.0d, this.Bounds.Height / 2.0d) * Math.Sqrt(2.0d); |
||||
|
var halfMin = Math.Min(this.Bounds.Width / 2.0d, this.Bounds.Height / 2.0d) / 1.3d; |
||||
|
var halfWidth = this.Bounds.Width / 2.0d; |
||||
|
var halfHeight = this.Bounds.Height / 2.0d; |
||||
|
|
||||
|
// 0,0 refers to the top-left of the control now. It is not prime time to draw gui stuff because it'll be under the world
|
||||
|
|
||||
|
var translateModifier = context.PushPreTransform(Avalonia.Matrix.CreateTranslation(new Avalonia.Vector(halfWidth, halfHeight))); |
||||
|
|
||||
|
// now 0,0 refers to the ViewportCenter(X,Y).
|
||||
|
var rotationMatrix = Avalonia.Matrix.CreateRotation(Rotation); |
||||
|
var rotationModifier = context.PushPreTransform(rotationMatrix); |
||||
|
|
||||
|
// everything is rotated but not scaled
|
||||
|
|
||||
|
var scaleModifier = context.PushPreTransform(Avalonia.Matrix.CreateScale(Scale, -Scale)); |
||||
|
|
||||
|
var mapPositionModifier = context.PushPreTransform(Matrix.CreateTranslation(new Vector(-ViewportCenterX, -ViewportCenterY))); |
||||
|
|
||||
|
// now everything is rotated and scaled, and at the right position, now we're drawing strictly in world coordinates
|
||||
|
|
||||
|
context.DrawEllipse(Brushes.White, _pen, new Point(0.0d, 0.0d), 50.0d, 50.0d); |
||||
|
context.DrawLine(_pen, new Point(-25.0d, -5.0d), new Point(-25.0d, 15.0d)); |
||||
|
context.DrawLine(_pen, new Point(25.0d, -5.0d), new Point(25.0d, 15.0d)); |
||||
|
context.DrawGeometry(null, _pen, _smileGeometry); |
||||
|
|
||||
|
Point cursorInWorldPoint = UIPointToWorldPoint(_cursorPoint, ViewportCenterX, ViewportCenterY, Scale, Rotation); |
||||
|
context.DrawEllipse(Brushes.Gray, _pen, cursorInWorldPoint, 20.0d, 20.0d); |
||||
|
|
||||
|
|
||||
|
for (int i = 0; i < 10; i++) |
||||
|
{ |
||||
|
double orbitRadius = i * 100 + 200; |
||||
|
var orbitInput = ((_timeKeeper.Elapsed.TotalMilliseconds + 987654d) / orbitRadius) / 10.0d; |
||||
|
if (i % 3 == 0) |
||||
|
orbitInput *= -1; |
||||
|
Point orbitPosition = new Point(Math.Sin(orbitInput) * orbitRadius, Math.Cos(orbitInput) * orbitRadius); |
||||
|
context.DrawEllipse(Brushes.Gray, _pen, orbitPosition, 20.0d, 20.0d); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// end drawing the world
|
||||
|
|
||||
|
mapPositionModifier.Dispose(); |
||||
|
|
||||
|
scaleModifier.Dispose(); |
||||
|
|
||||
|
rotationModifier.Dispose(); |
||||
|
translateModifier.Dispose(); |
||||
|
|
||||
|
// this is prime time to draw gui stuff
|
||||
|
|
||||
|
context.DrawLine(_pen, _cursorPoint + new Vector(-20, 0), _cursorPoint + new Vector(20, 0)); |
||||
|
context.DrawLine(_pen, _cursorPoint + new Vector(0, -20), _cursorPoint + new Vector(0, 20)); |
||||
|
|
||||
|
clip.Dispose(); |
||||
|
|
||||
|
// oh and draw again when you can, no rush, right?
|
||||
|
Dispatcher.UIThread.Post(InvalidateVisual, DispatcherPriority.Background); |
||||
|
} |
||||
|
|
||||
|
private Point UIPointToWorldPoint(Point inPoint, double viewportCenterX, double viewportCenterY, double scale, double rotation) |
||||
|
{ |
||||
|
Point workingPoint = new Point(inPoint.X, -inPoint.Y); |
||||
|
workingPoint += new Vector(-this.Bounds.Width / 2.0d, this.Bounds.Height / 2.0d); |
||||
|
workingPoint /= scale; |
||||
|
|
||||
|
workingPoint = Matrix.CreateRotation(rotation).Transform(workingPoint); |
||||
|
|
||||
|
workingPoint += new Vector(viewportCenterX, viewportCenterY); |
||||
|
|
||||
|
return workingPoint; |
||||
|
} |
||||
|
|
||||
|
private Point WorldPointToUIPoint(Point inPoint, double viewportCenterX, double viewportCenterY, double scale, double rotation) |
||||
|
{ |
||||
|
Point workingPoint = new Point(inPoint.X, inPoint.Y); |
||||
|
|
||||
|
workingPoint -= new Vector(viewportCenterX, viewportCenterY); |
||||
|
// undo rotation
|
||||
|
workingPoint = Matrix.CreateRotation(-rotation).Transform(workingPoint); |
||||
|
workingPoint *= scale; |
||||
|
workingPoint -= new Vector(-this.Bounds.Width / 2.0d, this.Bounds.Height / 2.0d); |
||||
|
workingPoint = new Point(workingPoint.X, -workingPoint.Y); |
||||
|
|
||||
|
return workingPoint; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,139 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Avalonia.Win32.DxgiSwapchain |
||||
|
{ |
||||
|
internal enum D3D_FEATURE_LEVEL |
||||
|
{ |
||||
|
D3D_FEATURE_LEVEL_1_0_CORE = 0x1000, |
||||
|
|
||||
|
D3D_FEATURE_LEVEL_9_1 = 0x9100, |
||||
|
|
||||
|
D3D_FEATURE_LEVEL_9_2 = 0x9200, |
||||
|
|
||||
|
D3D_FEATURE_LEVEL_9_3 = 0x9300, |
||||
|
|
||||
|
D3D_FEATURE_LEVEL_10_0 = 0xa000, |
||||
|
|
||||
|
D3D_FEATURE_LEVEL_10_1 = 0xa100, |
||||
|
|
||||
|
D3D_FEATURE_LEVEL_11_0 = 0xb000, |
||||
|
|
||||
|
D3D_FEATURE_LEVEL_11_1 = 0xb100, |
||||
|
|
||||
|
D3D_FEATURE_LEVEL_12_0 = 0xc000, |
||||
|
|
||||
|
D3D_FEATURE_LEVEL_12_1 = 0xc100, |
||||
|
|
||||
|
D3D_FEATURE_LEVEL_12_2 = 0xc200, |
||||
|
} |
||||
|
|
||||
|
internal enum D3D11_RESOURCE_DIMENSION |
||||
|
{ |
||||
|
D3D11_USAGE_DEFAULT = 0, |
||||
|
|
||||
|
D3D11_USAGE_IMMUTABLE = 1, |
||||
|
|
||||
|
D3D11_USAGE_DYNAMIC = 2, |
||||
|
|
||||
|
D3D11_USAGE_STAGING = 3, |
||||
|
} |
||||
|
|
||||
|
internal enum D3D11_USAGE |
||||
|
{ |
||||
|
D3D11_USAGE_DEFAULT = 0, |
||||
|
|
||||
|
D3D11_USAGE_IMMUTABLE = 1, |
||||
|
|
||||
|
D3D11_USAGE_DYNAMIC = 2, |
||||
|
|
||||
|
D3D11_USAGE_STAGING = 3, |
||||
|
} |
||||
|
internal enum DXGI_SWAP_EFFECT |
||||
|
{ |
||||
|
DXGI_SWAP_EFFECT_DISCARD = 0, |
||||
|
|
||||
|
DXGI_SWAP_EFFECT_SEQUENTIAL = 1, |
||||
|
|
||||
|
DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL = 3, |
||||
|
|
||||
|
DXGI_SWAP_EFFECT_FLIP_DISCARD = 4, |
||||
|
} |
||||
|
|
||||
|
[Flags] |
||||
|
internal enum DXGI_SWAP_CHAIN_FLAG |
||||
|
{ |
||||
|
DXGI_SWAP_CHAIN_FLAG_NONPREROTATED = 1, |
||||
|
|
||||
|
DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH = 2, |
||||
|
|
||||
|
DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE = 4, |
||||
|
|
||||
|
DXGI_SWAP_CHAIN_FLAG_RESTRICTED_CONTENT = 8, |
||||
|
|
||||
|
DXGI_SWAP_CHAIN_FLAG_RESTRICT_SHARED_RESOURCE_DRIVER = 16, |
||||
|
|
||||
|
DXGI_SWAP_CHAIN_FLAG_DISPLAY_ONLY = 32, |
||||
|
|
||||
|
DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT = 64, |
||||
|
|
||||
|
DXGI_SWAP_CHAIN_FLAG_FOREGROUND_LAYER = 128, |
||||
|
|
||||
|
DXGI_SWAP_CHAIN_FLAG_FULLSCREEN_VIDEO = 256, |
||||
|
|
||||
|
DXGI_SWAP_CHAIN_FLAG_YUV_VIDEO = 512, |
||||
|
|
||||
|
DXGI_SWAP_CHAIN_FLAG_HW_PROTECTED = 1024, |
||||
|
|
||||
|
DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING = 2048, |
||||
|
|
||||
|
DXGI_SWAP_CHAIN_FLAG_RESTRICTED_TO_ALL_HOLOGRAPHIC_DISPLAYS = 4096, |
||||
|
} |
||||
|
|
||||
|
internal enum DXGI_SCALING |
||||
|
{ |
||||
|
DXGI_SCALING_STRETCH = 0, |
||||
|
|
||||
|
DXGI_SCALING_NONE = 1, |
||||
|
|
||||
|
DXGI_SCALING_ASPECT_RATIO_STRETCH = 2, |
||||
|
} |
||||
|
|
||||
|
internal enum DXGI_RESIDENCY |
||||
|
{ |
||||
|
DXGI_RESIDENCY_FULLY_RESIDENT = 1, |
||||
|
|
||||
|
DXGI_RESIDENCY_RESIDENT_IN_SHARED_MEMORY = 2, |
||||
|
|
||||
|
DXGI_RESIDENCY_EVICTED_TO_DISK = 3, |
||||
|
} |
||||
|
|
||||
|
internal enum DXGI_MODE_ROTATION |
||||
|
{ |
||||
|
DXGI_MODE_ROTATION_UNSPECIFIED = 0, |
||||
|
|
||||
|
DXGI_MODE_ROTATION_IDENTITY = 1, |
||||
|
|
||||
|
DXGI_MODE_ROTATION_ROTATE90 = 2, |
||||
|
|
||||
|
DXGI_MODE_ROTATION_ROTATE180 = 3, |
||||
|
|
||||
|
DXGI_MODE_ROTATION_ROTATE270 = 4, |
||||
|
} |
||||
|
|
||||
|
internal enum DXGI_ALPHA_MODE |
||||
|
{ |
||||
|
DXGI_ALPHA_MODE_UNSPECIFIED = 0, |
||||
|
|
||||
|
DXGI_ALPHA_MODE_PREMULTIPLIED = 1, |
||||
|
|
||||
|
DXGI_ALPHA_MODE_STRAIGHT = 2, |
||||
|
|
||||
|
DXGI_ALPHA_MODE_IGNORE = 3, |
||||
|
|
||||
|
DXGI_ALPHA_MODE_FORCE_DWORD = (unchecked((int)0xffffffff)), |
||||
|
} |
||||
|
} |
||||
File diff suppressed because it is too large
@ -0,0 +1,29 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Runtime.InteropServices; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Avalonia.Win32.DxgiSwapchain |
||||
|
{ |
||||
|
internal unsafe class DirectXUnmanagedMethods |
||||
|
{ |
||||
|
// these return HRESULTs expecting Marshall to throw Win32 exceptions on failures
|
||||
|
[DllImport("dxgi", ExactSpelling = true, PreserveSig = false)] |
||||
|
internal static extern void CreateDXGIFactory(ref Guid riid, out void* ppFactory); |
||||
|
|
||||
|
// these return HRESULTs expecting Marshall to throw Win32 exceptions on failures
|
||||
|
[DllImport("dxgi", ExactSpelling = true, PreserveSig = false)] |
||||
|
internal static extern void CreateDXGIFactory1(ref Guid riid, out void* ppFactory); |
||||
|
|
||||
|
[DllImport("user32", ExactSpelling = true)] |
||||
|
internal static extern bool GetMonitorInfoW(HANDLE hMonitor, IntPtr lpmi); |
||||
|
|
||||
|
[DllImport("user32", ExactSpelling = true)] |
||||
|
internal static extern bool EnumDisplaySettingsW(ushort* lpszDeviceName, uint iModeNum, DEVMODEW* lpDevMode); |
||||
|
|
||||
|
[DllImport("user32", ExactSpelling = true, SetLastError = true)] |
||||
|
internal static extern bool GetClientRect(IntPtr hWnd, Interop.UnmanagedMethods.RECT* lpRect); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,202 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.ComponentModel; |
||||
|
using System.Diagnostics; |
||||
|
using System.Linq; |
||||
|
using System.Runtime.InteropServices; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
using Avalonia.Logging; |
||||
|
using Avalonia.OpenGL.Angle; |
||||
|
using Avalonia.OpenGL.Egl; |
||||
|
using Avalonia.Rendering; |
||||
|
using static Avalonia.Win32.Interop.UnmanagedMethods; |
||||
|
using static Avalonia.Win32.DxgiSwapchain.DirectXUnmanagedMethods; |
||||
|
using MicroCom.Runtime; |
||||
|
|
||||
|
namespace Avalonia.Win32.DxgiSwapchain |
||||
|
{ |
||||
|
#pragma warning disable CA1416 // This should only be reachable on Windows
|
||||
|
#nullable enable |
||||
|
public unsafe class DxgiConnection : IRenderTimer |
||||
|
{ |
||||
|
public const uint ENUM_CURRENT_SETTINGS = unchecked((uint)(-1)); |
||||
|
|
||||
|
public bool RunsInBackground => true; |
||||
|
|
||||
|
public event Action<TimeSpan>? Tick; |
||||
|
|
||||
|
private AngleWin32EglDisplay _angle; |
||||
|
private EglPlatformOpenGlInterface _gl; |
||||
|
private object _syncLock; |
||||
|
|
||||
|
private IDXGIOutput? _output = null; |
||||
|
|
||||
|
private Stopwatch? _stopwatch = null; |
||||
|
|
||||
|
public DxgiConnection(EglPlatformOpenGlInterface gl, object syncLock) |
||||
|
{ |
||||
|
|
||||
|
_syncLock = syncLock; |
||||
|
_angle = (AngleWin32EglDisplay)gl.Display; |
||||
|
_gl = gl; |
||||
|
} |
||||
|
|
||||
|
public EglPlatformOpenGlInterface Egl => _gl; |
||||
|
|
||||
|
public static void TryCreateAndRegister(EglPlatformOpenGlInterface angle) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
TryCreateAndRegisterCore(angle); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
Logger.TryGet(LogEventLevel.Error, nameof(DxgiSwapchain)) |
||||
|
?.Log(null, "Unable to establish Dxgi: {0}", ex); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private unsafe void RunLoop() |
||||
|
{ |
||||
|
_stopwatch = System.Diagnostics.Stopwatch.StartNew(); |
||||
|
try |
||||
|
{ |
||||
|
GetBestOutputToVWaitOn(); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
Logger.TryGet(LogEventLevel.Error, nameof(DxgiSwapchain)) |
||||
|
?.Log(this, $"Failed to wait for vblank, Exception: {ex.Message}, HRESULT = {ex.HResult}"); |
||||
|
} |
||||
|
|
||||
|
while (true) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
lock (_syncLock) |
||||
|
{ |
||||
|
if (_output is not null) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
_output.WaitForVBlank(); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
Logger.TryGet(LogEventLevel.Error, nameof(DxgiSwapchain)) |
||||
|
?.Log(this, $"Failed to wait for vblank, Exception: {ex.Message}, HRESULT = {ex.HResult}"); |
||||
|
_output.Dispose(); |
||||
|
_output = null; |
||||
|
GetBestOutputToVWaitOn(); |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
// well since that obviously didn't work, then let's use the lowest-common-denominator instead
|
||||
|
// for reference, this has never happened on my machine,
|
||||
|
// but theoretically someone could have a weirder setup out there
|
||||
|
DwmFlush(); |
||||
|
} |
||||
|
Tick?.Invoke(_stopwatch.Elapsed); |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
Logger.TryGet(LogEventLevel.Error, nameof(DxgiSwapchain)) |
||||
|
?.Log(this, $"Failed to wait for vblank, Exception: {ex.Message}, HRESULT = {ex.HResult}"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Note: Defining best as display with highest refresh rate on
|
||||
|
private void GetBestOutputToVWaitOn() |
||||
|
{ |
||||
|
double highestRefreshRate = 0.0d; |
||||
|
|
||||
|
// IDXGIFactory Guid: [Guid("7B7166EC-21C7-44AE-B21A-C9AE321AE369")]
|
||||
|
Guid factoryGuid = MicroComRuntime.GetGuidFor(typeof(IDXGIFactory)); |
||||
|
CreateDXGIFactory(ref factoryGuid, out var factPointer); |
||||
|
|
||||
|
using var fact = MicroComRuntime.CreateProxyFor<IDXGIFactory>(factPointer, true); |
||||
|
|
||||
|
void* adapterPointer = null; |
||||
|
|
||||
|
ushort adapterIndex = 0; |
||||
|
|
||||
|
// this looks odd, but that's just how one enumerates adapters in DXGI
|
||||
|
while (fact.EnumAdapters(adapterIndex, &adapterPointer) == 0) |
||||
|
{ |
||||
|
using var adapter = MicroComRuntime.CreateProxyFor<IDXGIAdapter>(adapterPointer, true); |
||||
|
void* outputPointer = null; |
||||
|
ushort outputIndex = 0; |
||||
|
while (adapter.EnumOutputs(outputIndex, &outputPointer) == 0) |
||||
|
{ |
||||
|
using var output = MicroComRuntime.CreateProxyFor<IDXGIOutput>(outputPointer, true); |
||||
|
DXGI_OUTPUT_DESC outputDesc = output.Desc; |
||||
|
|
||||
|
|
||||
|
// this handle need not closing, by the way.
|
||||
|
HANDLE monitorH = outputDesc.Monitor; |
||||
|
MONITORINFOEXW monInfo = default; |
||||
|
// by setting cbSize we tell Windows to fully populate the extended info
|
||||
|
|
||||
|
monInfo.Base.cbSize = sizeof(MONITORINFOEXW); |
||||
|
GetMonitorInfoW(monitorH, (IntPtr)(&monInfo)); |
||||
|
|
||||
|
DEVMODEW devMode = default; |
||||
|
EnumDisplaySettingsW(outputDesc.DeviceName, ENUM_CURRENT_SETTINGS, &devMode); |
||||
|
|
||||
|
if (highestRefreshRate < devMode.dmDisplayFrequency) |
||||
|
{ |
||||
|
// ooh I like this output!
|
||||
|
if (_output is not null) |
||||
|
{ |
||||
|
_output.Dispose(); |
||||
|
_output = null; |
||||
|
} |
||||
|
_output = MicroComRuntime.CloneReference(output); |
||||
|
highestRefreshRate = devMode.dmDisplayFrequency; |
||||
|
} |
||||
|
// and then increment index to move onto the next monitor
|
||||
|
outputIndex++; |
||||
|
} |
||||
|
// and then increment index to move onto the next display adapater
|
||||
|
adapterIndex++; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// Used the windows composition as a blueprint for this startup/creation
|
||||
|
static private bool TryCreateAndRegisterCore(EglPlatformOpenGlInterface gl) |
||||
|
{ |
||||
|
var tcs = new TaskCompletionSource<bool>(); |
||||
|
var pumpLock = new object(); |
||||
|
var thread = new System.Threading.Thread(() => |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
DxgiConnection connection; |
||||
|
|
||||
|
connection = new DxgiConnection(gl, pumpLock); |
||||
|
|
||||
|
AvaloniaLocator.CurrentMutable.BindToSelf(connection); |
||||
|
AvaloniaLocator.CurrentMutable.Bind<IRenderTimer>().ToConstant(connection); |
||||
|
tcs.SetResult(true); |
||||
|
connection.RunLoop(); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
tcs.SetException(ex); |
||||
|
} |
||||
|
}); |
||||
|
thread.IsBackground = true; |
||||
|
thread.SetApartmentState(System.Threading.ApartmentState.STA); |
||||
|
thread.Start(); |
||||
|
// block until
|
||||
|
return tcs.Task.Result; |
||||
|
} |
||||
|
} |
||||
|
#nullable restore |
||||
|
#pragma warning restore CA1416 // Validate platform compatibility
|
||||
|
} |
||||
@ -0,0 +1,184 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.ComponentModel; |
||||
|
using System.Linq; |
||||
|
using System.Runtime.InteropServices; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
using Avalonia.OpenGL.Angle; |
||||
|
using Avalonia.OpenGL.Egl; |
||||
|
using Avalonia.OpenGL.Surfaces; |
||||
|
using MicroCom.Runtime; |
||||
|
using static Avalonia.OpenGL.Egl.EglGlPlatformSurfaceBase; |
||||
|
using static Avalonia.Win32.Interop.UnmanagedMethods; |
||||
|
|
||||
|
namespace Avalonia.Win32.DxgiSwapchain |
||||
|
{ |
||||
|
#pragma warning disable CA1416 // Validate platform compatibility, if you enter this not on windows you have messed up badly
|
||||
|
#nullable enable |
||||
|
public unsafe class DxgiRenderTarget : EglPlatformSurfaceRenderTargetBase |
||||
|
{ |
||||
|
// DXGI_FORMAT_B8G8R8A8_UNORM is target texture format as per ANGLE documentation
|
||||
|
|
||||
|
public const uint DXGI_USAGE_RENDER_TARGET_OUTPUT = 0x00000020U; |
||||
|
|
||||
|
private IEglWindowGlPlatformSurfaceInfo _window; |
||||
|
private EglPlatformOpenGlInterface _egl; |
||||
|
private DxgiConnection _connection; |
||||
|
private IDXGIDevice? _dxgiDevice = null; |
||||
|
private IDXGIFactory2? _dxgiFactory = null; |
||||
|
private IDXGISwapChain1? _swapChain = null; |
||||
|
private IUnknown? _renderTexture = null; |
||||
|
|
||||
|
private Interop.UnmanagedMethods.RECT _clientRect = default; |
||||
|
|
||||
|
private uint _flagsUsed; |
||||
|
|
||||
|
private Guid ID3D11Texture2DGuid = Guid.Parse("6F15AAF2-D208-4E89-9AB4-489535D34F9C"); |
||||
|
|
||||
|
public DxgiRenderTarget(IEglWindowGlPlatformSurfaceInfo window, EglPlatformOpenGlInterface egl, DxgiConnection connection) : base(egl) |
||||
|
{ |
||||
|
_window = window; |
||||
|
_egl = egl; |
||||
|
_connection = connection; |
||||
|
|
||||
|
// the D3D device is expected to at least be an ID3D11Device
|
||||
|
// but how do I wrap an IntPtr as a managed IUnknown now? Like this.
|
||||
|
IUnknown pdevice = MicroComRuntime.CreateProxyFor<IUnknown>(((AngleWin32EglDisplay)_egl.Display).GetDirect3DDevice(), false); |
||||
|
|
||||
|
_dxgiDevice = pdevice.QueryInterface<IDXGIDevice>(); |
||||
|
|
||||
|
// only needing the adapter pointer to ask it for the IDXGI Factory
|
||||
|
using (var adapterPointer = _dxgiDevice.Adapter) |
||||
|
{ |
||||
|
Guid factoryGuid = MicroComRuntime.GetGuidFor(typeof(IDXGIFactory2)); |
||||
|
_dxgiFactory = MicroComRuntime.CreateProxyFor<IDXGIFactory2>(adapterPointer.GetParent(&factoryGuid), true); |
||||
|
} |
||||
|
|
||||
|
DXGI_SWAP_CHAIN_DESC1 dxgiSwapChainDesc = new DXGI_SWAP_CHAIN_DESC1(); |
||||
|
|
||||
|
// standard swap chain really.
|
||||
|
dxgiSwapChainDesc.Format = DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM; |
||||
|
dxgiSwapChainDesc.SampleDesc.Count = 1U; |
||||
|
dxgiSwapChainDesc.SampleDesc.Quality = 0U; |
||||
|
dxgiSwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; |
||||
|
dxgiSwapChainDesc.AlphaMode = DXGI_ALPHA_MODE.DXGI_ALPHA_MODE_IGNORE; |
||||
|
dxgiSwapChainDesc.Width = (uint)_window.Size.Width; |
||||
|
dxgiSwapChainDesc.Height = (uint)_window.Size.Height; |
||||
|
dxgiSwapChainDesc.BufferCount = 2U; |
||||
|
dxgiSwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT.DXGI_SWAP_EFFECT_FLIP_DISCARD; |
||||
|
|
||||
|
// okay I know this looks bad, but we're hitting our render-calls by awaiting via dxgi
|
||||
|
// this is done in the DxgiConnection itself
|
||||
|
_flagsUsed = dxgiSwapChainDesc.Flags = (uint)(DXGI_SWAP_CHAIN_FLAG.DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING); |
||||
|
|
||||
|
_swapChain = _dxgiFactory.CreateSwapChainForHwnd |
||||
|
( |
||||
|
_dxgiDevice, |
||||
|
window.Handle, |
||||
|
&dxgiSwapChainDesc, |
||||
|
null, |
||||
|
null |
||||
|
); |
||||
|
|
||||
|
Interop.UnmanagedMethods.RECT pClientRect; |
||||
|
GetClientRect(_window.Handle, out pClientRect); |
||||
|
_clientRect = pClientRect; |
||||
|
} |
||||
|
|
||||
|
public override IGlPlatformSurfaceRenderingSession BeginDraw() |
||||
|
{ |
||||
|
if (_swapChain is null) |
||||
|
{ |
||||
|
throw new InvalidOperationException("No chain to draw on"); |
||||
|
} |
||||
|
|
||||
|
var contextLock = _egl.PrimaryContext.EnsureCurrent(); |
||||
|
EglSurface? surface = null; |
||||
|
IDisposable? transaction = null; |
||||
|
var success = false; |
||||
|
try |
||||
|
{ |
||||
|
Interop.UnmanagedMethods.RECT pClientRect; |
||||
|
GetClientRect(_window.Handle, out pClientRect); |
||||
|
if (!RectsEqual(pClientRect, _clientRect)) |
||||
|
{ |
||||
|
// we gotta resize
|
||||
|
_clientRect = pClientRect; |
||||
|
|
||||
|
if (_renderTexture is not null) |
||||
|
{ |
||||
|
_renderTexture.Dispose(); |
||||
|
_renderTexture = null; |
||||
|
} |
||||
|
|
||||
|
_swapChain.ResizeBuffers(2, |
||||
|
(ushort)(pClientRect.right - pClientRect.left), |
||||
|
(ushort)(pClientRect.bottom - pClientRect.top), |
||||
|
DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM, |
||||
|
(ushort)_flagsUsed |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
var size = _window.Size; |
||||
|
|
||||
|
// Get swapchain texture here
|
||||
|
var texture = _renderTexture; |
||||
|
if (texture is null) |
||||
|
{ |
||||
|
Guid textureGuid = ID3D11Texture2DGuid; |
||||
|
texture = MicroComRuntime.CreateProxyFor<IUnknown>(_swapChain.GetBuffer(0, &textureGuid), true); |
||||
|
} |
||||
|
_renderTexture = texture; |
||||
|
|
||||
|
// I also have to get the pointer to this texture directly
|
||||
|
surface = ((AngleWin32EglDisplay)_egl.Display).WrapDirect3D11Texture(_egl, MicroComRuntime.GetNativeIntPtr(_renderTexture), |
||||
|
0, 0, size.Width, size.Height); |
||||
|
|
||||
|
var res = base.BeginDraw(surface, _window, () => |
||||
|
{ |
||||
|
_swapChain.Present((ushort)0U, (ushort)0U); |
||||
|
surface?.Dispose(); |
||||
|
transaction?.Dispose(); |
||||
|
contextLock?.Dispose(); |
||||
|
}, true); |
||||
|
success = true; |
||||
|
return res; |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
if (!success) |
||||
|
{ |
||||
|
surface?.Dispose(); |
||||
|
if (_renderTexture is not null) |
||||
|
{ |
||||
|
_renderTexture.Dispose(); |
||||
|
_renderTexture = null; |
||||
|
} |
||||
|
transaction?.Dispose(); |
||||
|
contextLock.Dispose(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public override void Dispose() |
||||
|
{ |
||||
|
base.Dispose(); |
||||
|
_dxgiDevice?.Dispose(); |
||||
|
_dxgiFactory?.Dispose(); |
||||
|
_swapChain?.Dispose(); |
||||
|
_renderTexture?.Dispose(); |
||||
|
} |
||||
|
|
||||
|
internal static bool RectsEqual(in RECT l, in RECT r) |
||||
|
{ |
||||
|
return (l.left == r.left) |
||||
|
&& (l.top == r.top) |
||||
|
&& (l.right == r.right) |
||||
|
&& (l.bottom == r.bottom); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
#pragma warning restore CA1416 // Validate platform compatibility
|
||||
|
#nullable restore |
||||
|
} |
||||
@ -0,0 +1,32 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
using Avalonia.OpenGL.Egl; |
||||
|
using Avalonia.OpenGL.Surfaces; |
||||
|
|
||||
|
namespace Avalonia.Win32.DxgiSwapchain |
||||
|
{ |
||||
|
public class DxgiSwapchainWindow : EglGlPlatformSurfaceBase |
||||
|
{ |
||||
|
private DxgiConnection _connection; |
||||
|
private EglPlatformOpenGlInterface _egl; |
||||
|
private IEglWindowGlPlatformSurfaceInfo _window; |
||||
|
|
||||
|
public DxgiSwapchainWindow(DxgiConnection connection, IEglWindowGlPlatformSurfaceInfo window) |
||||
|
{ |
||||
|
_connection = connection; |
||||
|
_window = window; |
||||
|
_egl = connection.Egl; |
||||
|
} |
||||
|
|
||||
|
public override IGlPlatformSurfaceRenderTarget CreateGlRenderTarget() |
||||
|
{ |
||||
|
using (_egl.PrimaryContext.EnsureCurrent()) |
||||
|
{ |
||||
|
return new DxgiRenderTarget(_window, _egl, _connection); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,305 @@ |
|||||
|
@clr-namespace Avalonia.Win32.DxgiSwapchain |
||||
|
@clr-access internal |
||||
|
@clr-map FLOAT float |
||||
|
@clr-map HSTRING IntPtr |
||||
|
@clr-map Vector2 System.Numerics.Vector2 |
||||
|
@clr-map Vector3 System.Numerics.Vector3 |
||||
|
@clr-map Quaternion System.Numerics.Quaternion |
||||
|
@clr-map Matrix4x4 System.Numerics.Matrix4x4 |
||||
|
@clr-map RECT Avalonia.Win32.Interop.UnmanagedMethods.RECT |
||||
|
@clr-map SIZE Avalonia.Win32.Interop.UnmanagedMethods.SIZE |
||||
|
@clr-map POINT Avalonia.Win32.Interop.UnmanagedMethods.POINT |
||||
|
@clr-map HWND IntPtr |
||||
|
@clr-map BOOL int |
||||
|
@clr-map DWORD int |
||||
|
@clr-map boolean int |
||||
|
@clr-map BYTE byte |
||||
|
@clr-map INT16 short |
||||
|
@clr-map INT32 int |
||||
|
@clr-map INT64 long |
||||
|
@clr-map UINT ushort |
||||
|
@clr-map UINT16 ushort |
||||
|
@clr-map ULONG uint |
||||
|
@clr-map UINT32 uint |
||||
|
@clr-map UINT64 ulong |
||||
|
@clr-map DOUBLE double |
||||
|
@clr-map GUID System.Guid |
||||
|
@clr-map REFGUID System.Guid* |
||||
|
@clr-map REFIID System.Guid* |
||||
|
@clr-map WCHAR System.Char |
||||
|
@clr-map HMODULE void* |
||||
|
@clr-map DXGI_USAGE uint |
||||
|
@clr-map LARGE_INTEGER ulong |
||||
|
@clr-map INT int |
||||
|
@clr-map DXGI_SHARED_RESOURCE void* |
||||
|
@clr-map LUID ulong |
||||
|
@clr-map LPSTR ushort* |
||||
|
|
||||
|
|
||||
|
enum DXGI_FORMAT |
||||
|
{ |
||||
|
DXGI_FORMAT_UNKNOWN = 0, |
||||
|
DXGI_FORMAT_R32G32B32A32_TYPELESS = 1, |
||||
|
DXGI_FORMAT_R32G32B32A32_FLOAT = 2, |
||||
|
DXGI_FORMAT_R32G32B32A32_UINT = 3, |
||||
|
DXGI_FORMAT_R32G32B32A32_SINT = 4, |
||||
|
DXGI_FORMAT_R32G32B32_TYPELESS = 5, |
||||
|
DXGI_FORMAT_R32G32B32_FLOAT = 6, |
||||
|
DXGI_FORMAT_R32G32B32_UINT = 7, |
||||
|
DXGI_FORMAT_R32G32B32_SINT = 8, |
||||
|
DXGI_FORMAT_R16G16B16A16_TYPELESS = 9, |
||||
|
DXGI_FORMAT_R16G16B16A16_FLOAT = 10, |
||||
|
DXGI_FORMAT_R16G16B16A16_UNORM = 11, |
||||
|
DXGI_FORMAT_R16G16B16A16_UINT = 12, |
||||
|
DXGI_FORMAT_R16G16B16A16_SNORM = 13, |
||||
|
DXGI_FORMAT_R16G16B16A16_SINT = 14, |
||||
|
DXGI_FORMAT_R32G32_TYPELESS = 15, |
||||
|
DXGI_FORMAT_R32G32_FLOAT = 16, |
||||
|
DXGI_FORMAT_R32G32_UINT = 17, |
||||
|
DXGI_FORMAT_R32G32_SINT = 18, |
||||
|
DXGI_FORMAT_R32G8X24_TYPELESS = 19, |
||||
|
DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20, |
||||
|
DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21, |
||||
|
DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22, |
||||
|
DXGI_FORMAT_R10G10B10A2_TYPELESS = 23, |
||||
|
DXGI_FORMAT_R10G10B10A2_UNORM = 24, |
||||
|
DXGI_FORMAT_R10G10B10A2_UINT = 25, |
||||
|
DXGI_FORMAT_R11G11B10_FLOAT = 26, |
||||
|
DXGI_FORMAT_R8G8B8A8_TYPELESS = 27, |
||||
|
DXGI_FORMAT_R8G8B8A8_UNORM = 28, |
||||
|
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29, |
||||
|
DXGI_FORMAT_R8G8B8A8_UINT = 30, |
||||
|
DXGI_FORMAT_R8G8B8A8_SNORM = 31, |
||||
|
DXGI_FORMAT_R8G8B8A8_SINT = 32, |
||||
|
DXGI_FORMAT_R16G16_TYPELESS = 33, |
||||
|
DXGI_FORMAT_R16G16_FLOAT = 34, |
||||
|
DXGI_FORMAT_R16G16_UNORM = 35, |
||||
|
DXGI_FORMAT_R16G16_UINT = 36, |
||||
|
DXGI_FORMAT_R16G16_SNORM = 37, |
||||
|
DXGI_FORMAT_R16G16_SINT = 38, |
||||
|
DXGI_FORMAT_R32_TYPELESS = 39, |
||||
|
DXGI_FORMAT_D32_FLOAT = 40, |
||||
|
DXGI_FORMAT_R32_FLOAT = 41, |
||||
|
DXGI_FORMAT_R32_UINT = 42, |
||||
|
DXGI_FORMAT_R32_SINT = 43, |
||||
|
DXGI_FORMAT_R24G8_TYPELESS = 44, |
||||
|
DXGI_FORMAT_D24_UNORM_S8_UINT = 45, |
||||
|
DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46, |
||||
|
DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47, |
||||
|
DXGI_FORMAT_R8G8_TYPELESS = 48, |
||||
|
DXGI_FORMAT_R8G8_UNORM = 49, |
||||
|
DXGI_FORMAT_R8G8_UINT = 50, |
||||
|
DXGI_FORMAT_R8G8_SNORM = 51, |
||||
|
DXGI_FORMAT_R8G8_SINT = 52, |
||||
|
DXGI_FORMAT_R16_TYPELESS = 53, |
||||
|
DXGI_FORMAT_R16_FLOAT = 54, |
||||
|
DXGI_FORMAT_D16_UNORM = 55, |
||||
|
DXGI_FORMAT_R16_UNORM = 56, |
||||
|
DXGI_FORMAT_R16_UINT = 57, |
||||
|
DXGI_FORMAT_R16_SNORM = 58, |
||||
|
DXGI_FORMAT_R16_SINT = 59, |
||||
|
DXGI_FORMAT_R8_TYPELESS = 60, |
||||
|
DXGI_FORMAT_R8_UNORM = 61, |
||||
|
DXGI_FORMAT_R8_UINT = 62, |
||||
|
DXGI_FORMAT_R8_SNORM = 63, |
||||
|
DXGI_FORMAT_R8_SINT = 64, |
||||
|
DXGI_FORMAT_A8_UNORM = 65, |
||||
|
DXGI_FORMAT_R1_UNORM = 66, |
||||
|
DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67, |
||||
|
DXGI_FORMAT_R8G8_B8G8_UNORM = 68, |
||||
|
DXGI_FORMAT_G8R8_G8B8_UNORM = 69, |
||||
|
DXGI_FORMAT_BC1_TYPELESS = 70, |
||||
|
DXGI_FORMAT_BC1_UNORM = 71, |
||||
|
DXGI_FORMAT_BC1_UNORM_SRGB = 72, |
||||
|
DXGI_FORMAT_BC2_TYPELESS = 73, |
||||
|
DXGI_FORMAT_BC2_UNORM = 74, |
||||
|
DXGI_FORMAT_BC2_UNORM_SRGB = 75, |
||||
|
DXGI_FORMAT_BC3_TYPELESS = 76, |
||||
|
DXGI_FORMAT_BC3_UNORM = 77, |
||||
|
DXGI_FORMAT_BC3_UNORM_SRGB = 78, |
||||
|
DXGI_FORMAT_BC4_TYPELESS = 79, |
||||
|
DXGI_FORMAT_BC4_UNORM = 80, |
||||
|
DXGI_FORMAT_BC4_SNORM = 81, |
||||
|
DXGI_FORMAT_BC5_TYPELESS = 82, |
||||
|
DXGI_FORMAT_BC5_UNORM = 83, |
||||
|
DXGI_FORMAT_BC5_SNORM = 84, |
||||
|
DXGI_FORMAT_B5G6R5_UNORM = 85, |
||||
|
DXGI_FORMAT_B5G5R5A1_UNORM = 86, |
||||
|
DXGI_FORMAT_B8G8R8A8_UNORM = 87, |
||||
|
DXGI_FORMAT_B8G8R8X8_UNORM = 88, |
||||
|
DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89, |
||||
|
DXGI_FORMAT_B8G8R8A8_TYPELESS = 90, |
||||
|
DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91, |
||||
|
DXGI_FORMAT_B8G8R8X8_TYPELESS = 92, |
||||
|
DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93, |
||||
|
DXGI_FORMAT_BC6H_TYPELESS = 94, |
||||
|
DXGI_FORMAT_BC6H_UF16 = 95, |
||||
|
DXGI_FORMAT_BC6H_SF16 = 96, |
||||
|
DXGI_FORMAT_BC7_TYPELESS = 97, |
||||
|
DXGI_FORMAT_BC7_UNORM = 98, |
||||
|
DXGI_FORMAT_BC7_UNORM_SRGB = 99, |
||||
|
DXGI_FORMAT_AYUV = 100, |
||||
|
DXGI_FORMAT_Y410 = 101, |
||||
|
DXGI_FORMAT_Y416 = 102, |
||||
|
DXGI_FORMAT_NV12 = 103, |
||||
|
DXGI_FORMAT_P010 = 104, |
||||
|
DXGI_FORMAT_P016 = 105, |
||||
|
DXGI_FORMAT_420_OPAQUE = 106, |
||||
|
DXGI_FORMAT_YUY2 = 107, |
||||
|
DXGI_FORMAT_Y210 = 108, |
||||
|
DXGI_FORMAT_Y216 = 109, |
||||
|
DXGI_FORMAT_NV11 = 110, |
||||
|
DXGI_FORMAT_AI44 = 111, |
||||
|
DXGI_FORMAT_IA44 = 112, |
||||
|
DXGI_FORMAT_P8 = 113, |
||||
|
DXGI_FORMAT_A8P8 = 114, |
||||
|
DXGI_FORMAT_B4G4R4A4_UNORM = 115, |
||||
|
DXGI_FORMAT_P208 = 130, |
||||
|
DXGI_FORMAT_V208 = 131, |
||||
|
DXGI_FORMAT_V408 = 132, |
||||
|
DXGI_FORMAT_FORCE_UINT = -1 |
||||
|
} |
||||
|
|
||||
|
enum DXGI_MODE_SCANLINE_ORDER |
||||
|
{ |
||||
|
DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED = 0, |
||||
|
DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE = 1, |
||||
|
DXGI_MODE_SCANLINE_ORDER_UPPER_FIELD_FIRST = 2, |
||||
|
DXGI_MODE_SCANLINE_ORDER_LOWER_FIELD_FIRST = 3 |
||||
|
} |
||||
|
|
||||
|
enum DXGI_MODE_SCALING |
||||
|
{ |
||||
|
DXGI_MODE_SCALING_UNSPECIFIED = 0, |
||||
|
DXGI_MODE_SCALING_CENTERED = 1, |
||||
|
DXGI_MODE_SCALING_STRETCHED = 2 |
||||
|
} |
||||
|
|
||||
|
[uuid(aec22fb8-76f3-4639-9be0-28eb43a67a2e)] |
||||
|
interface IDXGIObject : IUnknown |
||||
|
{ |
||||
|
HRESULT SetPrivateData([in] REFGUID Name, [in] UINT DataSize, [in] void** pData); |
||||
|
HRESULT SetPrivateDataInterface([in] REFGUID Name, [in] IUnknown* pUnknown); |
||||
|
HRESULT GetPrivateData([in] REFGUID Name, [in, out] UINT* pDataSize, [out] void** pData); |
||||
|
HRESULT GetParent([in] REFIID riid, [out, retval] void** ppParent); |
||||
|
} |
||||
|
|
||||
|
[uuid(7b7166ec-21c7-44ae-b21a-c9ae321ae369)] |
||||
|
interface IDXGIFactory : IDXGIObject |
||||
|
{ |
||||
|
INT32 EnumAdapters([in] UINT Adapter, [out] void* ppAdapter); |
||||
|
HRESULT MakeWindowAssociation(HWND WindowHandle, UINT Flags); |
||||
|
HRESULT GetWindowAssociation([out, annotation("_Out_")] HWND* pWindowHandle); |
||||
|
HRESULT CreateSwapChain([in, annotation("_In_")] IUnknown* pDevice, [in, annotation("_In_")] DXGI_SWAP_CHAIN_DESC* pDesc, [out, annotation("_COM_Outptr_")] IDXGISwapChain** ppSwapChain); |
||||
|
HRESULT CreateSoftwareAdapter([in] HMODULE Module, [out, annotation("_COM_Outptr_")] IDXGIAdapter** ppAdapter); |
||||
|
} |
||||
|
|
||||
|
[uuid(3d3e0379-f9de-4d58-bb6c-18d62992f1a6)] |
||||
|
interface IDXGIDeviceSubObject : IDXGIObject |
||||
|
{ |
||||
|
HRESULT GetDevice([in, annotation("_In_")] REFIID riid, [out, retval, annotation("_COM_Outptr_")] void** ppDevice); |
||||
|
} |
||||
|
|
||||
|
[uuid(2411e7e1-12ac-4ccf-bd14-9798e8534dc0)] |
||||
|
interface IDXGIAdapter : IDXGIObject |
||||
|
{ |
||||
|
INT32 EnumOutputs([in] UINT Output, [in, out] void* ppOutput); |
||||
|
HRESULT GetDesc([out, annotation("_Out_")] DXGI_ADAPTER_DESC* pDesc); |
||||
|
HRESULT CheckInterfaceSupport([in, annotation("_In_")] REFGUID InterfaceName,[out, annotation("_Out_")] LARGE_INTEGER* pUMDVersion); |
||||
|
}; |
||||
|
|
||||
|
[uuid(310d36a0-d2e7-4c0a-aa04-6a9d23b8886a)] |
||||
|
interface IDXGISwapChain : IDXGIDeviceSubObject |
||||
|
{ |
||||
|
HRESULT Present([in] UINT SyncInterval, [in] UINT Flags); |
||||
|
HRESULT GetBuffer([in] UINT Buffer, [in, annotation("_In_")] REFIID riid, [in, out, annotation("_COM_Outptr_")] void** ppSurface); |
||||
|
HRESULT SetFullscreenState([in] BOOL Fullscreen, [in, annotation("_In_opt_")] IDXGIOutput* pTarget); |
||||
|
HRESULT GetFullscreenState([out, annotation("_Out_opt_")] BOOL* pFullscreen, [out, annotation("_COM_Outptr_opt_result_maybenull_")] IDXGIOutput** ppTarget); |
||||
|
HRESULT GetDesc([out] DXGI_SWAP_CHAIN_DESC* pDesc); |
||||
|
HRESULT ResizeBuffers([in] UINT BufferCount, [in] UINT Width, [in] UINT Height, [in] DXGI_FORMAT NewFormat, [in] UINT SwapChainFlags); |
||||
|
HRESULT ResizeTarget([in, annotation("_In_")] DXGI_MODE_DESC* pNewTargetParameters); |
||||
|
HRESULT GetContainingOutput([out, annotation("_COM_Outptr_")] IDXGIOutput** ppOutput); |
||||
|
HRESULT GetFrameStatistics([out, annotation("_Out_")] DXGI_FRAME_STATISTICS* pStats); |
||||
|
HRESULT GetLastPresentCount([out, annotation("_Out_")] UINT* pLastPresentCount); |
||||
|
} |
||||
|
|
||||
|
[uuid(54ec77fa-1377-44e6-8c32-88fd5f44c84c)] |
||||
|
interface IDXGIDevice : IDXGIObject |
||||
|
{ |
||||
|
HRESULT GetAdapter([out] IDXGIAdapter** pAdapter); |
||||
|
HRESULT CreateSurface([in, annotation("_In_")] DXGI_SURFACE_DESC* pDesc, [in] UINT NumSurfaces, [in] DXGI_USAGE Usage, [in, annotation("_In_opt_")] DXGI_SHARED_RESOURCE* pSharedResource, [out] IDXGISurface** ppSurface); |
||||
|
HRESULT QueryResourceResidency([in] IUnknown* ppResources, [out] DXGI_RESIDENCY* pResidencyStatus, [in] UINT NumResources); |
||||
|
HRESULT SetGPUThreadPriority([in] INT Priority); |
||||
|
HRESULT GetGPUThreadPriority([out, retval] INT* pPriority); |
||||
|
} |
||||
|
|
||||
|
[uuid(ae02eedb-c735-4690-8d52-5a8dc20213aa)] |
||||
|
interface IDXGIOutput : IDXGIObject |
||||
|
{ |
||||
|
HRESULT GetDesc([out] DXGI_OUTPUT_DESC* pDesc); |
||||
|
HRESULT GetDisplayModeList([in] DXGI_FORMAT EnumFormat, [in] UINT Flags, [in, out] UINT* pNumModes, [out] DXGI_MODE_DESC* pDesc); |
||||
|
HRESULT FindClosestMatchingMode([in, annotation("_In_")] DXGI_MODE_DESC* pModeToMatch, [out] DXGI_MODE_DESC* pClosestMatch, [in] IUnknown* pConcernedDevice); |
||||
|
HRESULT WaitForVBlank(); |
||||
|
HRESULT TakeOwnership([in, annotation("_In_")] IUnknown* pDevice, BOOL Exclusive); |
||||
|
void ReleaseOwnership(); |
||||
|
HRESULT GetGammaControlCapabilities([out, annotation("_Out_")] DXGI_GAMMA_CONTROL_CAPABILITIES* pGammaCaps); |
||||
|
HRESULT SetGammaControl([in, annotation("_In_")] DXGI_GAMMA_CONTROL* pArray); |
||||
|
HRESULT GetGammaControl([out, annotation("_Out_")] DXGI_GAMMA_CONTROL* pArray); |
||||
|
HRESULT SetDisplaySurface([in, annotation("_In_")] IDXGISurface* pScanoutSurface); |
||||
|
HRESULT GetDisplaySurfaceData([in, annotation("_In_")] IDXGISurface* pDestination); |
||||
|
HRESULT GetFrameStatistics([out, annotation("_Out_")] DXGI_FRAME_STATISTICS* pStats); |
||||
|
} |
||||
|
|
||||
|
[uuid(cafcb56c-6ac3-4889-bf47-9e23bbd260ec)] |
||||
|
interface IDXGISurface : IDXGIDeviceSubObject |
||||
|
{ |
||||
|
HRESULT GetDesc([out, annotation("_Out_")] DXGI_SURFACE_DESC* pDesc); |
||||
|
HRESULT Map([out, annotation("_Out_")] DXGI_MAPPED_RECT* pLockedRect, [in] UINT MapFlags); |
||||
|
HRESULT Unmap(); |
||||
|
} |
||||
|
|
||||
|
[uuid(770aae78-f26f-4dba-a829-253c83d1b387)] |
||||
|
interface IDXGIFactory1 : IDXGIFactory |
||||
|
{ |
||||
|
HRESULT EnumAdapters1([in] UINT Adapter, [out, annotation("_COM_Outptr_")] IDXGIAdapter1** ppAdapter); |
||||
|
BOOL IsCurrent(); |
||||
|
} |
||||
|
|
||||
|
[uuid(29038f61-3839-4626-91fd-086879011a05)] |
||||
|
interface IDXGIAdapter1 : IDXGIAdapter |
||||
|
{ |
||||
|
HRESULT GetDesc1([out, annotation("_Out_")] DXGI_ADAPTER_DESC1* pDesc); |
||||
|
} |
||||
|
|
||||
|
[uuid(50c83a1c-e072-4c48-87b0-3630fa36a6d0)] |
||||
|
interface IDXGIFactory2 : IDXGIFactory1 |
||||
|
{ |
||||
|
BOOL IsWindowedStereoEnabled(); |
||||
|
HRESULT CreateSwapChainForHwnd([in, annotation("_In_")] IUnknown* pDevice, [in, annotation("_In_")] HWND hWnd, [in, annotation("_In_")] DXGI_SWAP_CHAIN_DESC1* pDesc, [in, annotation("_In_opt_")] DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc, [in, annotation("_In_opt_")] IDXGIOutput* pRestrictToOutput, [out, annotation("_COM_Outptr_")] IDXGISwapChain1** ppSwapChain); |
||||
|
HRESULT CreateSwapChainForCoreWindow([in, annotation("_In_")] IUnknown* pDevice, [in, annotation("_In_")] IUnknown* pWindow, [in, annotation("_In_")] DXGI_SWAP_CHAIN_DESC1* pDesc, [in, annotation("_In_opt_")] IDXGIOutput* pRestrictToOutput, [out, annotation("_COM_Outptr_")] IDXGISwapChain1** ppSwapChain); |
||||
|
HRESULT GetSharedResourceAdapterLuid([annotation("_In_")] HANDLE hResource, [annotation("_Out_")] LUID* pLuid); |
||||
|
HRESULT RegisterStereoStatusWindow([in, annotation("_In_")] HWND WindowHandle, [in, annotation("_In_")] UINT wMsg, [out, annotation("_Out_")] DWORD* pdwCookie); |
||||
|
HRESULT RegisterStereoStatusEvent([in, annotation("_In_")] HANDLE hEvent, [out, annotation("_Out_")] DWORD* pdwCookie); |
||||
|
void UnregisterStereoStatus([in, annotation("_In_")] DWORD dwCookie); |
||||
|
HRESULT RegisterOcclusionStatusWindow([in, annotation("_In_")] HWND WindowHandle, [in, annotation("_In_")] UINT wMsg, [out, annotation("_Out_")] DWORD* pdwCookie); |
||||
|
HRESULT RegisterOcclusionStatusEvent([in, annotation("_In_")] HANDLE hEvent, [out, annotation("_Out_")] DWORD* pdwCookie); |
||||
|
void UnregisterOcclusionStatus([in, annotation("_In_")] DWORD dwCookie); |
||||
|
HRESULT CreateSwapChainForComposition([in, annotation("_In_")] IUnknown* pDevice, [in, annotation("_In_")] DXGI_SWAP_CHAIN_DESC1* pDesc, [in, annotation("_In_opt_")] IDXGIOutput* pRestrictToOutput, [out, annotation("_COM_Outptr_")] IDXGISwapChain1** ppSwapChain); |
||||
|
} |
||||
|
|
||||
|
[uuid(790a45f7-0d42-4876-983a-0a55cfe6f4aa)] |
||||
|
interface IDXGISwapChain1 : IDXGISwapChain |
||||
|
{ |
||||
|
HRESULT GetDesc1([out, annotation("_Out_")] DXGI_SWAP_CHAIN_DESC1* pDesc); |
||||
|
HRESULT GetFullscreenDesc([out, annotation("_Out_")] DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pDesc); |
||||
|
HRESULT GetHwnd([out, annotation("_Out_")] HWND* pHwnd); |
||||
|
HRESULT GetCoreWindow([in, annotation("_In_")] REFIID refiid, [out, annotation("_COM_Outptr_")] void** ppUnk); |
||||
|
HRESULT Present1([in] UINT SyncInterval, [in] UINT PresentFlags, [in, annotation("_In_")] DXGI_PRESENT_PARAMETERS* pPresentParameters); |
||||
|
BOOL IsTemporaryMonoSupported(); |
||||
|
HRESULT GetRestrictToOutput([out, annotation("_Out_")] IDXGIOutput** ppRestrictToOutput); |
||||
|
HRESULT SetBackgroundColor([in, annotation("_In_")] DXGI_RGBA* pColor); |
||||
|
HRESULT GetBackgroundColor([out, annotation("_Out_")] DXGI_RGBA* pColor); |
||||
|
HRESULT SetRotation([in, annotation("_In_")] DXGI_MODE_ROTATION Rotation); |
||||
|
HRESULT GetRotation([out, annotation("_Out_")] DXGI_MODE_ROTATION* pRotation); |
||||
|
} |
||||
|
|
||||
Loading…
Reference in new issue