diff --git a/src/Avalonia.Diagnostics/ViewModels/ControlDetailsViewModel.cs b/src/Avalonia.Diagnostics/ViewModels/ControlDetailsViewModel.cs index 34cc32972c..0339d724f7 100644 --- a/src/Avalonia.Diagnostics/ViewModels/ControlDetailsViewModel.cs +++ b/src/Avalonia.Diagnostics/ViewModels/ControlDetailsViewModel.cs @@ -3,19 +3,19 @@ using System.Collections.Generic; using System.Linq; -using Avalonia.Controls; +using Avalonia.VisualTree; using ReactiveUI; namespace Avalonia.Diagnostics.ViewModels { internal class ControlDetailsViewModel : ReactiveObject { - public ControlDetailsViewModel(Control control) + public ControlDetailsViewModel(IVisual control) { - if (control != null) + if (control is AvaloniaObject avaloniaObject) { - Properties = AvaloniaPropertyRegistry.Instance.GetRegistered(control) - .Select(x => new PropertyDetails(control, x)) + Properties = AvaloniaPropertyRegistry.Instance.GetRegistered(avaloniaObject) + .Select(x => new PropertyDetails(avaloniaObject, x)) .OrderBy(x => x.IsAttached) .ThenBy(x => x.Name); } diff --git a/src/Avalonia.Diagnostics/ViewModels/TreeNode.cs b/src/Avalonia.Diagnostics/ViewModels/TreeNode.cs index f186304f7b..0b0b7a94fe 100644 --- a/src/Avalonia.Diagnostics/ViewModels/TreeNode.cs +++ b/src/Avalonia.Diagnostics/ViewModels/TreeNode.cs @@ -5,8 +5,8 @@ using System; using System.Collections.Specialized; using System.Reactive; using System.Reactive.Linq; -using Avalonia.Controls; using Avalonia.Styling; +using Avalonia.VisualTree; using ReactiveUI; namespace Avalonia.Diagnostics.ViewModels @@ -16,32 +16,35 @@ namespace Avalonia.Diagnostics.ViewModels private string _classes; private bool _isExpanded; - public TreeNode(Control control, TreeNode parent) + public TreeNode(IVisual visual, TreeNode parent) { - Control = control; Parent = parent; - Type = control.GetType().Name; + Type = visual.GetType().Name; + Visual = visual; - var classesChanged = Observable.FromEventPattern< - NotifyCollectionChangedEventHandler, - NotifyCollectionChangedEventArgs>( - x => control.Classes.CollectionChanged += x, - x => control.Classes.CollectionChanged -= x) - .TakeUntil(((IStyleable)control).StyleDetach); + if (visual is IStyleable styleable) + { + var classesChanged = Observable.FromEventPattern< + NotifyCollectionChangedEventHandler, + NotifyCollectionChangedEventArgs>( + x => styleable.Classes.CollectionChanged += x, + x => styleable.Classes.CollectionChanged -= x) + .TakeUntil(((IStyleable)styleable).StyleDetach); - classesChanged.Select(_ => Unit.Default) - .StartWith(Unit.Default) - .Subscribe(_ => - { - if (control.Classes.Count > 0) + classesChanged.Select(_ => Unit.Default) + .StartWith(Unit.Default) + .Subscribe(_ => { - Classes = "(" + string.Join(" ", control.Classes) + ")"; - } - else - { - Classes = string.Empty; - } - }); + if (styleable.Classes.Count > 0) + { + Classes = "(" + string.Join(" ", styleable.Classes) + ")"; + } + else + { + Classes = string.Empty; + } + }); + } } public IReadOnlyReactiveList Children @@ -56,7 +59,7 @@ namespace Avalonia.Diagnostics.ViewModels private set { this.RaiseAndSetIfChanged(ref _classes, value); } } - public Control Control + public IVisual Visual { get; } diff --git a/src/Avalonia.Diagnostics/ViewModels/TreePageViewModel.cs b/src/Avalonia.Diagnostics/ViewModels/TreePageViewModel.cs index 92be04a056..97bd971e74 100644 --- a/src/Avalonia.Diagnostics/ViewModels/TreePageViewModel.cs +++ b/src/Avalonia.Diagnostics/ViewModels/TreePageViewModel.cs @@ -18,7 +18,7 @@ namespace Avalonia.Diagnostics.ViewModels { Nodes = nodes; _details = this.WhenAnyValue(x => x.SelectedNode) - .Select(x => x != null ? new ControlDetailsViewModel(x.Control) : null) + .Select(x => x != null ? new ControlDetailsViewModel(x.Visual) : null) .ToProperty(this, x => x.Details); } @@ -79,7 +79,7 @@ namespace Avalonia.Diagnostics.ViewModels private TreeNode FindNode(TreeNode node, IControl control) { - if (node.Control == control) + if (node.Visual == control) { return node; } diff --git a/src/Avalonia.Diagnostics/ViewModels/VisualTreeNode.cs b/src/Avalonia.Diagnostics/ViewModels/VisualTreeNode.cs index d155572c14..f1b02a61c9 100644 --- a/src/Avalonia.Diagnostics/ViewModels/VisualTreeNode.cs +++ b/src/Avalonia.Diagnostics/ViewModels/VisualTreeNode.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using Avalonia.Controls; +using Avalonia.Styling; using Avalonia.VisualTree; using ReactiveUI; @@ -10,7 +11,7 @@ namespace Avalonia.Diagnostics.ViewModels internal class VisualTreeNode : TreeNode { public VisualTreeNode(IVisual visual, TreeNode parent) - : base((Control)visual, parent) + : base(visual, parent) { var host = visual as IVisualTreeHost; @@ -23,9 +24,9 @@ namespace Avalonia.Diagnostics.ViewModels Children = new ReactiveList(new[] { new VisualTreeNode(host.Root, this) }); } - if (Control != null) + if ((Visual is IStyleable styleable)) { - IsInTemplate = Control.TemplatedParent != null; + IsInTemplate = styleable.TemplatedParent != null; } } diff --git a/src/Avalonia.Diagnostics/Views/TreePage.xaml.cs b/src/Avalonia.Diagnostics/Views/TreePage.xaml.cs index 0a79aa90d7..7e4e5a8564 100644 --- a/src/Avalonia.Diagnostics/Views/TreePage.xaml.cs +++ b/src/Avalonia.Diagnostics/Views/TreePage.xaml.cs @@ -23,14 +23,14 @@ namespace Avalonia.Diagnostics.Views protected void AddAdorner(object sender, PointerEventArgs e) { var node = (TreeNode)((Control)sender).DataContext; - var layer = AdornerLayer.GetAdornerLayer(node.Control); + var layer = AdornerLayer.GetAdornerLayer(node.Visual); if (layer != null) { _adorner = new Rectangle { Fill = new SolidColorBrush(0x80a0c5e8), - [AdornerLayer.AdornedElementProperty] = node.Control, + [AdornerLayer.AdornedElementProperty] = node.Visual, }; layer.Children.Add(_adorner); diff --git a/src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj b/src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj index e71201b949..ab62f5ac75 100644 --- a/src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj +++ b/src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj @@ -73,7 +73,7 @@ - + diff --git a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs index 7ac527bb1e..469c29d626 100644 --- a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs +++ b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs @@ -31,49 +31,76 @@ namespace Avalonia.Direct2D1 { private static readonly Direct2D1Platform s_instance = new Direct2D1Platform(); - private static readonly SharpDX.Direct2D1.Factory s_d2D1Factory = -#if DEBUG - new SharpDX.Direct2D1.Factory1(SharpDX.Direct2D1.FactoryType.MultiThreaded, SharpDX.Direct2D1.DebugLevel.Error); -#else - new SharpDX.Direct2D1.Factory1(SharpDX.Direct2D1.FactoryType.MultiThreaded, SharpDX.Direct2D1.DebugLevel.None); -#endif - private static readonly SharpDX.DirectWrite.Factory s_dwfactory = new SharpDX.DirectWrite.Factory(); + private static SharpDX.Direct2D1.Factory s_d2D1Factory; - private static readonly SharpDX.WIC.ImagingFactory s_imagingFactory = new SharpDX.WIC.ImagingFactory(); + private static SharpDX.DirectWrite.Factory s_dwfactory; - private static readonly SharpDX.DXGI.Device s_dxgiDevice; + private static SharpDX.WIC.ImagingFactory s_imagingFactory; - private static readonly SharpDX.Direct2D1.Device s_d2D1Device; + private static SharpDX.DXGI.Device s_dxgiDevice; - static Direct2D1Platform() - { - var featureLevels = new[] - { - SharpDX.Direct3D.FeatureLevel.Level_11_1, - SharpDX.Direct3D.FeatureLevel.Level_11_0, - SharpDX.Direct3D.FeatureLevel.Level_10_1, - SharpDX.Direct3D.FeatureLevel.Level_10_0, - SharpDX.Direct3D.FeatureLevel.Level_9_3, - SharpDX.Direct3D.FeatureLevel.Level_9_2, - SharpDX.Direct3D.FeatureLevel.Level_9_1, - }; - - using (var d3dDevice = new SharpDX.Direct3D11.Device( - SharpDX.Direct3D.DriverType.Hardware, - SharpDX.Direct3D11.DeviceCreationFlags.BgraSupport | SharpDX.Direct3D11.DeviceCreationFlags.VideoSupport, - featureLevels)) - { - s_dxgiDevice = d3dDevice.QueryInterface(); - } + private static SharpDX.Direct2D1.Device s_d2D1Device; + + private static readonly object s_initLock = new object(); + private static bool s_initialized = false; - using (var factory1 = s_d2D1Factory.QueryInterface()) + internal static void InitializeDirect2D() + { + lock (s_initLock) { - s_d2D1Device = new SharpDX.Direct2D1.Device(factory1, s_dxgiDevice); + if (s_initialized) + return; +#if DEBUG + try + { + s_d2D1Factory = + + new SharpDX.Direct2D1.Factory1(SharpDX.Direct2D1.FactoryType.MultiThreaded, + SharpDX.Direct2D1.DebugLevel.Error); + } + catch + { + // + } +#endif + s_dwfactory = new SharpDX.DirectWrite.Factory(); + s_imagingFactory = new SharpDX.WIC.ImagingFactory(); + if (s_d2D1Factory == null) + s_d2D1Factory = new SharpDX.Direct2D1.Factory1(SharpDX.Direct2D1.FactoryType.MultiThreaded, + SharpDX.Direct2D1.DebugLevel.None); + + + var featureLevels = new[] + { + SharpDX.Direct3D.FeatureLevel.Level_11_1, + SharpDX.Direct3D.FeatureLevel.Level_11_0, + SharpDX.Direct3D.FeatureLevel.Level_10_1, + SharpDX.Direct3D.FeatureLevel.Level_10_0, + SharpDX.Direct3D.FeatureLevel.Level_9_3, + SharpDX.Direct3D.FeatureLevel.Level_9_2, + SharpDX.Direct3D.FeatureLevel.Level_9_1, + }; + + using (var d3dDevice = new SharpDX.Direct3D11.Device( + SharpDX.Direct3D.DriverType.Hardware, + SharpDX.Direct3D11.DeviceCreationFlags.BgraSupport | + SharpDX.Direct3D11.DeviceCreationFlags.VideoSupport, + featureLevels)) + { + s_dxgiDevice = d3dDevice.QueryInterface(); + } + + using (var factory1 = s_d2D1Factory.QueryInterface()) + { + s_d2D1Device = new SharpDX.Direct2D1.Device(factory1, s_dxgiDevice); + } + s_initialized = true; } } public static void Initialize() { + InitializeDirect2D(); AvaloniaLocator.CurrentMutable .Bind().ToConstant(s_instance) .BindToSelf(s_d2D1Factory) diff --git a/src/Windows/Avalonia.Direct2D1/Direct2DChecker.cs b/src/Windows/Avalonia.Direct2D1/Direct2DChecker.cs new file mode 100644 index 0000000000..e7e27493e5 --- /dev/null +++ b/src/Windows/Avalonia.Direct2D1/Direct2DChecker.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Avalonia.Platform; + +namespace Avalonia.Direct2D1 +{ + class Direct2DChecker : IModuleEnvironmentChecker + { + //Direct2D backend doesn't work on some machines anymore + public bool IsCompatible + { + get + { + try + { + Direct2D1Platform.InitializeDirect2D(); + return true; + } + catch + { + return false; + } + } + } + } +} diff --git a/src/Windows/Avalonia.Direct2D1/Properties/AssemblyInfo.cs b/src/Windows/Avalonia.Direct2D1/Properties/AssemblyInfo.cs index 63d9c5bfe3..c1c5b24048 100644 --- a/src/Windows/Avalonia.Direct2D1/Properties/AssemblyInfo.cs +++ b/src/Windows/Avalonia.Direct2D1/Properties/AssemblyInfo.cs @@ -7,5 +7,5 @@ using Avalonia.Direct2D1; [assembly: AssemblyTitle("Avalonia.Direct2D1")] [assembly: ExportRenderingSubsystem(OperatingSystemType.WinNT, 1, "Direct2D1", typeof(Direct2D1Platform), nameof(Direct2D1Platform.Initialize), - typeof(WindowsVersionChecker))] + typeof(Direct2DChecker))] diff --git a/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs b/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs index 26be2fc259..3c1024e73a 100644 --- a/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs +++ b/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs @@ -99,9 +99,9 @@ namespace Avalonia.Direct2D1 Quality = 0, }, Usage = Usage.RenderTargetOutput, - BufferCount = 2, - Scaling = Scaling.None, - SwapEffect = SwapEffect.FlipSequential, + BufferCount = 1, + Scaling = Scaling.Stretch, + SwapEffect = SwapEffect.Discard, Flags = 0, }; diff --git a/src/Windows/Avalonia.Direct2D1/WindowsVersionChecker.cs b/src/Windows/Avalonia.Direct2D1/WindowsVersionChecker.cs deleted file mode 100644 index 875167b71a..0000000000 --- a/src/Windows/Avalonia.Direct2D1/WindowsVersionChecker.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Avalonia.Platform; - -namespace Avalonia.Direct2D1 -{ - class WindowsVersionChecker : IModuleEnvironmentChecker - { - //Direct2D backend doesn't work with Win7 anymore - public bool IsCompatible => Environment.OSVersion.Version >= new Version(6, 2); - } -}