From 9880d640581bd23ccdded8328ee69e2dd058c640 Mon Sep 17 00:00:00 2001 From: Jumar Macato Date: Sat, 29 Dec 2018 23:36:53 +0800 Subject: [PATCH 01/11] Bugfix for #2020: Snap last interpolated value to either start/end values of the animation when fillmode is active. --- src/Avalonia.Animation/AnimationInstance`1.cs | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/Avalonia.Animation/AnimationInstance`1.cs b/src/Avalonia.Animation/AnimationInstance`1.cs index bc7e106a2a..6f601a3e13 100644 --- a/src/Avalonia.Animation/AnimationInstance`1.cs +++ b/src/Avalonia.Animation/AnimationInstance`1.cs @@ -19,6 +19,7 @@ namespace Avalonia.Animation private ulong? _iterationCount; private ulong _currentIteration; private bool _gotFirstKFValue; + private bool _playbackReversed; private FillMode _fillMode; private PlaybackDirection _playbackDirection; private Animator _animator; @@ -160,9 +161,14 @@ namespace Avalonia.Animation _currentIteration = (ulong)(opsTime / iterationTime); - // Stop animation when the current iteration is beyond the iteration count. + // Stop animation when the current iteration is beyond the iteration count + // and snap the last iteration value to exact values. if ((_currentIteration + 1) > _iterationCount) + { + var easedTime = _easeFunc.Ease(_playbackReversed ? 0.0 : 1.0); + _lastInterpValue = _interpolator(easedTime, _neutralValue); DoComplete(); + } if (playbackTime <= iterDuration) { @@ -170,27 +176,26 @@ namespace Avalonia.Animation var normalizedTime = playbackTime / iterDuration; // Check if normalized time needs to be reversed according to PlaybackDirection - - bool playbackReversed; + switch (_playbackDirection) { case PlaybackDirection.Normal: - playbackReversed = false; + _playbackReversed = false; break; case PlaybackDirection.Reverse: - playbackReversed = true; + _playbackReversed = true; break; case PlaybackDirection.Alternate: - playbackReversed = (_currentIteration % 2 == 0) ? false : true; + _playbackReversed = (_currentIteration % 2 == 0) ? false : true; break; case PlaybackDirection.AlternateReverse: - playbackReversed = (_currentIteration % 2 == 0) ? true : false; + _playbackReversed = (_currentIteration % 2 == 0) ? true : false; break; default: throw new InvalidOperationException($"Animation direction value is unknown: {_playbackDirection}"); } - if (playbackReversed) + if (_playbackReversed) normalizedTime = 1 - normalizedTime; // Ease and interpolate From 02faa2e3acdbdce04af735ca1aad45e5eea7c48b Mon Sep 17 00:00:00 2001 From: mstr2 Date: Mon, 31 Dec 2018 05:37:57 +0100 Subject: [PATCH 02/11] Added the option to include the OpenGL error code description when constructing OpenGlException --- src/Avalonia.OpenGL/EglContext.cs | 6 ++-- src/Avalonia.OpenGL/EglDisplay.cs | 17 ++++++------ src/Avalonia.OpenGL/EglInterface.cs | 7 +++-- src/Avalonia.OpenGL/GlInterface.cs | 5 +++- src/Avalonia.OpenGL/OpenGlException.cs | 38 ++++++++++++++++++++++++++ 5 files changed, 58 insertions(+), 15 deletions(-) diff --git a/src/Avalonia.OpenGL/EglContext.cs b/src/Avalonia.OpenGL/EglContext.cs index 27b1abe411..17caf84179 100644 --- a/src/Avalonia.OpenGL/EglContext.cs +++ b/src/Avalonia.OpenGL/EglContext.cs @@ -31,14 +31,14 @@ namespace Avalonia.OpenGL public void MakeCurrent() { if (!_egl.MakeCurrent(_disp.Handle, IntPtr.Zero, IntPtr.Zero, Context)) - throw new OpenGlException("eglMakeCurrent failed"); + throw OpenGlException.GetFormattedException("eglMakeCurrent", _egl); } public void MakeCurrent(EglSurface surface) { - var surf = ((EglSurface)surface)?.DangerousGetHandle() ?? OffscreenSurface; + var surf = surface?.DangerousGetHandle() ?? OffscreenSurface; if (!_egl.MakeCurrent(_disp.Handle, surf, surf, Context)) - throw new OpenGlException("eglMakeCurrent failed"); + throw OpenGlException.GetFormattedException("eglMakeCurrent", _egl); } } } diff --git a/src/Avalonia.OpenGL/EglDisplay.cs b/src/Avalonia.OpenGL/EglDisplay.cs index 90a70adcb7..2a75e9458e 100644 --- a/src/Avalonia.OpenGL/EglDisplay.cs +++ b/src/Avalonia.OpenGL/EglDisplay.cs @@ -1,5 +1,4 @@ using System; -using System.ComponentModel; using System.Runtime.InteropServices; using Avalonia.Platform.Interop; using static Avalonia.OpenGL.EglConsts; @@ -34,11 +33,11 @@ namespace Avalonia.OpenGL if (_display == IntPtr.Zero) _display = _egl.GetDisplay(IntPtr.Zero); - if(_display == IntPtr.Zero) - throw new OpenGlException("eglGetDisplay failed"); - + if (_display == IntPtr.Zero) + throw OpenGlException.GetFormattedException("eglGetDisplay", _egl); + if (!_egl.Initialize(_display, out var major, out var minor)) - throw new OpenGlException("eglInitialize failed"); + throw OpenGlException.GetFormattedException("eglInitialize", _egl); foreach (var cfg in new[] { @@ -113,7 +112,7 @@ namespace Avalonia.OpenGL var shareCtx = (EglContext)share; var ctx = _egl.CreateContext(_display, _config, shareCtx?.Context ?? IntPtr.Zero, _contextAttributes); if (ctx == IntPtr.Zero) - throw new OpenGlException("eglCreateContext failed"); + throw OpenGlException.GetFormattedException("eglCreateContext", _egl); var surf = _egl.CreatePBufferSurface(_display, _config, new[] { EGL_WIDTH, 1, @@ -121,7 +120,7 @@ namespace Avalonia.OpenGL EGL_NONE }); if (surf == IntPtr.Zero) - throw new OpenGlException("eglCreatePbufferSurface failed"); + throw OpenGlException.GetFormattedException("eglCreatePBufferSurface", _egl); var rv = new EglContext(this, _egl, ctx, surf); rv.MakeCurrent(null); return rv; @@ -130,14 +129,14 @@ namespace Avalonia.OpenGL public void ClearContext() { if (!_egl.MakeCurrent(_display, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero)) - throw new OpenGlException("eglMakeCurrent failed"); + throw OpenGlException.GetFormattedException("eglMakeCurrent", _egl); } public EglSurface CreateWindowSurface(IntPtr window) { var s = _egl.CreateWindowSurface(_display, _config, window, new[] {EGL_NONE, EGL_NONE}); if (s == IntPtr.Zero) - throw new OpenGlException("eglCreateWindowSurface failed"); + throw OpenGlException.GetFormattedException("eglCreateWindowSurface", _egl); return new EglSurface(this, _egl, s); } diff --git a/src/Avalonia.OpenGL/EglInterface.cs b/src/Avalonia.OpenGL/EglInterface.cs index 535f66ee1f..c41a01340c 100644 --- a/src/Avalonia.OpenGL/EglInterface.cs +++ b/src/Avalonia.OpenGL/EglInterface.cs @@ -1,7 +1,6 @@ using System; using Avalonia.Platform; using Avalonia.Platform.Interop; -using static Avalonia.OpenGL.EglConsts; namespace Avalonia.OpenGL { @@ -32,8 +31,12 @@ namespace Avalonia.OpenGL var lib = dyn.LoadLibrary(library); return (s, o) => dyn.GetProcAddress(lib, s, o); } - + // ReSharper disable UnassignedGetOnlyAutoProperty + public delegate int EglGetError(); + [EntryPoint("eglGetError")] + public EglGetError GetError { get; } + public delegate IntPtr EglGetDisplay(IntPtr nativeDisplay); [EntryPoint("eglGetDisplay")] public EglGetDisplay GetDisplay { get; } diff --git a/src/Avalonia.OpenGL/GlInterface.cs b/src/Avalonia.OpenGL/GlInterface.cs index 60dc5381d4..f23e1c5829 100644 --- a/src/Avalonia.OpenGL/GlInterface.cs +++ b/src/Avalonia.OpenGL/GlInterface.cs @@ -19,7 +19,10 @@ namespace Avalonia.OpenGL public T GetProcAddress(string proc) => Marshal.GetDelegateForFunctionPointer(GetProcAddress(proc)); // ReSharper disable UnassignedGetOnlyAutoProperty - + public delegate int GlGetError(); + [EntryPoint("glGetError")] + public GlGetError GetError { get; } + public delegate void GlClearStencil(int s); [EntryPoint("glClearStencil")] public GlClearStencil ClearStencil { get; } diff --git a/src/Avalonia.OpenGL/OpenGlException.cs b/src/Avalonia.OpenGL/OpenGlException.cs index 7ba539a2b2..9d9940949b 100644 --- a/src/Avalonia.OpenGL/OpenGlException.cs +++ b/src/Avalonia.OpenGL/OpenGlException.cs @@ -1,12 +1,50 @@ using System; +using System.Reflection; namespace Avalonia.OpenGL { public class OpenGlException : Exception { + public int? ErrorCode { get; private set; } + public OpenGlException(string message) : base(message) { + } + + private OpenGlException(string message, int errorCode) : base(message) + { + ErrorCode = errorCode; + } + + public static OpenGlException GetFormattedException(string funcName, EglInterface egl) + { + return GetFormattedException(typeof(EglConsts).GetFields(), funcName, 0x3000, 0x301F, egl.GetError()); + } + + public static OpenGlException GetFormattedException(string funcName, GlInterface gl) + { + return GetFormattedException(typeof(GlConsts).GetFields(), funcName, 0x0500, 0x0505, gl.GetError()); + } + + private static OpenGlException GetFormattedException( + FieldInfo[] fields, string funcName, int minValue, int maxValue, int errorCode) + { + foreach (var field in fields) + { + int value = (int)field.GetValue(null); + if (value < minValue || value > maxValue) + { + continue; + } + + if (value == errorCode) + { + return new OpenGlException( + $"{funcName} failed with error {field.Name} (0x{errorCode.ToString("X")})", errorCode); + } + } + return new OpenGlException($"{funcName} failed with error 0x{errorCode.ToString("X")}", errorCode); } } } From 2ed745d493857a2df155db2a2ffcb9c4c4d45cb2 Mon Sep 17 00:00:00 2001 From: Jeffrey Ye Date: Tue, 8 Jan 2019 11:02:34 -0800 Subject: [PATCH 03/11] #2222 Get all fonts in the system --- src/Avalonia.Visuals/Media/FontFamily.cs | 7 +++++++ .../Platform/IPlatformRenderInterface.cs | 5 +++++ src/Skia/Avalonia.Skia/PlatformRenderInterface.cs | 2 ++ src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs | 13 +++++++++++++ .../Media/Direct2D1FontCollectionCache.cs | 2 +- .../MockPlatformRenderInterface.cs | 2 ++ 6 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/Avalonia.Visuals/Media/FontFamily.cs b/src/Avalonia.Visuals/Media/FontFamily.cs index 0ba25e6c0d..60d40e449e 100644 --- a/src/Avalonia.Visuals/Media/FontFamily.cs +++ b/src/Avalonia.Visuals/Media/FontFamily.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using Avalonia.Media.Fonts; +using Avalonia.Platform; namespace Avalonia.Media { @@ -51,6 +52,12 @@ namespace Avalonia.Media /// public static FontFamily Default => new FontFamily(String.Empty); + /// + /// Represents all font families in the system + /// + public static IEnumerable SystemFontFamilies => + AvaloniaLocator.Current.GetService().InstalledFontNames.Select(name => new FontFamily(name)); + /// /// Gets the primary family name of the font family. /// diff --git a/src/Avalonia.Visuals/Platform/IPlatformRenderInterface.cs b/src/Avalonia.Visuals/Platform/IPlatformRenderInterface.cs index aacdef0538..3a1f79e32a 100644 --- a/src/Avalonia.Visuals/Platform/IPlatformRenderInterface.cs +++ b/src/Avalonia.Visuals/Platform/IPlatformRenderInterface.cs @@ -13,6 +13,11 @@ namespace Avalonia.Platform /// public interface IPlatformRenderInterface { + /// + /// Get all installed fonts in the system + /// + IEnumerable InstalledFontNames { get; } + /// /// Creates a formatted text implementation. /// diff --git a/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs b/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs index 9b10d74c64..8080c27831 100644 --- a/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs +++ b/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs @@ -19,6 +19,8 @@ namespace Avalonia.Skia { private GRContext GrContext { get; } + public IEnumerable InstalledFontNames => SKFontManager.Default.FontFamilies; + public PlatformRenderInterface() { var gl = AvaloniaLocator.Current.GetService(); diff --git a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs index 3ec18dac5e..8412a65e23 100644 --- a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs +++ b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs @@ -41,6 +41,19 @@ namespace Avalonia.Direct2D1 public static SharpDX.DXGI.Device1 DxgiDevice { get; private set; } + public IEnumerable InstalledFontNames + { + get + { + var cache = Direct2D1FontCollectionCache.s_installedFontCollection; + var length = cache.FontFamilyCount; + for (int i = 0; i < length; i++) + { + var names = cache.GetFontFamily(i).FamilyNames; + yield return names.GetString(0); + } + } + } private static readonly object s_initLock = new object(); private static bool s_initialized = false; diff --git a/src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs b/src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs index d60aa15a5e..d93a59d384 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs @@ -7,7 +7,7 @@ namespace Avalonia.Direct2D1.Media internal static class Direct2D1FontCollectionCache { private static readonly ConcurrentDictionary s_cachedCollections; - private static readonly SharpDX.DirectWrite.FontCollection s_installedFontCollection; + internal static readonly SharpDX.DirectWrite.FontCollection s_installedFontCollection; static Direct2D1FontCollectionCache() { diff --git a/tests/Avalonia.UnitTests/MockPlatformRenderInterface.cs b/tests/Avalonia.UnitTests/MockPlatformRenderInterface.cs index f8ad7e63f2..b65c40cedd 100644 --- a/tests/Avalonia.UnitTests/MockPlatformRenderInterface.cs +++ b/tests/Avalonia.UnitTests/MockPlatformRenderInterface.cs @@ -9,6 +9,8 @@ namespace Avalonia.UnitTests { public class MockPlatformRenderInterface : IPlatformRenderInterface { + public IEnumerable InstalledFontNames => Mock.Of>(); + public IFormattedTextImpl CreateFormattedText( string text, Typeface typeface, From dad512ba80fe8b01730f97fbe9cc54374d6e8cec Mon Sep 17 00:00:00 2001 From: Jeffrey Ye Date: Tue, 8 Jan 2019 11:03:14 -0800 Subject: [PATCH 04/11] Font Dropdown in ControlCatalog --- samples/ControlCatalog/Pages/DropDownPage.xaml | 9 +++++++++ samples/ControlCatalog/Pages/DropDownPage.xaml.cs | 3 +++ 2 files changed, 12 insertions(+) diff --git a/samples/ControlCatalog/Pages/DropDownPage.xaml b/samples/ControlCatalog/Pages/DropDownPage.xaml index 864d2be49c..7673294e46 100644 --- a/samples/ControlCatalog/Pages/DropDownPage.xaml +++ b/samples/ControlCatalog/Pages/DropDownPage.xaml @@ -27,6 +27,15 @@ + + + + + + + + + diff --git a/samples/ControlCatalog/Pages/DropDownPage.xaml.cs b/samples/ControlCatalog/Pages/DropDownPage.xaml.cs index edab5f1ceb..397f9f21e1 100644 --- a/samples/ControlCatalog/Pages/DropDownPage.xaml.cs +++ b/samples/ControlCatalog/Pages/DropDownPage.xaml.cs @@ -13,6 +13,9 @@ namespace ControlCatalog.Pages private void InitializeComponent() { AvaloniaXamlLoader.Load(this); + var fontDropDown = this.Find("fontDropDown"); + fontDropDown.Items = Avalonia.Media.FontFamily.SystemFontFamilies; + fontDropDown.SelectedIndex = 0; } } } From 27edc74bf88fcb1ae63b616775bd340b1d1cccb9 Mon Sep 17 00:00:00 2001 From: Jeffrey Ye Date: Wed, 9 Jan 2019 08:12:19 -0800 Subject: [PATCH 05/11] more comments, and fix compilation error --- src/Avalonia.Visuals/Media/FontFamily.cs | 2 +- .../VisualTree/MockRenderInterface.cs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Avalonia.Visuals/Media/FontFamily.cs b/src/Avalonia.Visuals/Media/FontFamily.cs index 60d40e449e..5c152cd8a0 100644 --- a/src/Avalonia.Visuals/Media/FontFamily.cs +++ b/src/Avalonia.Visuals/Media/FontFamily.cs @@ -53,7 +53,7 @@ namespace Avalonia.Media public static FontFamily Default => new FontFamily(String.Empty); /// - /// Represents all font families in the system + /// Represents all font families in the system. This can be an expensive call depending on platform implementation. /// public static IEnumerable SystemFontFamilies => AvaloniaLocator.Current.GetService().InstalledFontNames.Select(name => new FontFamily(name)); diff --git a/tests/Avalonia.Visuals.UnitTests/VisualTree/MockRenderInterface.cs b/tests/Avalonia.Visuals.UnitTests/VisualTree/MockRenderInterface.cs index 92c12c6b9e..bd46e68fd8 100644 --- a/tests/Avalonia.Visuals.UnitTests/VisualTree/MockRenderInterface.cs +++ b/tests/Avalonia.Visuals.UnitTests/VisualTree/MockRenderInterface.cs @@ -8,6 +8,8 @@ namespace Avalonia.Visuals.UnitTests.VisualTree { class MockRenderInterface : IPlatformRenderInterface { + public IEnumerable InstalledFontNames => throw new NotImplementedException(); + public IFormattedTextImpl CreateFormattedText( string text, Typeface typeface, From 3a28179704ffe4f164c472a805f4d1accb42878b Mon Sep 17 00:00:00 2001 From: Jeffrey Ye Date: Wed, 9 Jan 2019 23:19:45 -0800 Subject: [PATCH 06/11] return new string[0] from mock interfaces --- tests/Avalonia.UnitTests/MockPlatformRenderInterface.cs | 2 +- .../VisualTree/MockRenderInterface.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Avalonia.UnitTests/MockPlatformRenderInterface.cs b/tests/Avalonia.UnitTests/MockPlatformRenderInterface.cs index b65c40cedd..0e2abb314d 100644 --- a/tests/Avalonia.UnitTests/MockPlatformRenderInterface.cs +++ b/tests/Avalonia.UnitTests/MockPlatformRenderInterface.cs @@ -9,7 +9,7 @@ namespace Avalonia.UnitTests { public class MockPlatformRenderInterface : IPlatformRenderInterface { - public IEnumerable InstalledFontNames => Mock.Of>(); + public IEnumerable InstalledFontNames => new string[0]; public IFormattedTextImpl CreateFormattedText( string text, diff --git a/tests/Avalonia.Visuals.UnitTests/VisualTree/MockRenderInterface.cs b/tests/Avalonia.Visuals.UnitTests/VisualTree/MockRenderInterface.cs index bd46e68fd8..fec0f0831a 100644 --- a/tests/Avalonia.Visuals.UnitTests/VisualTree/MockRenderInterface.cs +++ b/tests/Avalonia.Visuals.UnitTests/VisualTree/MockRenderInterface.cs @@ -8,7 +8,7 @@ namespace Avalonia.Visuals.UnitTests.VisualTree { class MockRenderInterface : IPlatformRenderInterface { - public IEnumerable InstalledFontNames => throw new NotImplementedException(); + public IEnumerable InstalledFontNames => new string[0]; public IFormattedTextImpl CreateFormattedText( string text, From 440985a2b3f4b0bcdf7dde10a461d65ae982c631 Mon Sep 17 00:00:00 2001 From: Jumar Macato Date: Thu, 10 Jan 2019 19:35:21 +0800 Subject: [PATCH 07/11] Add unit test for FillMode --- .../AnimationIterationTests.cs | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tests/Avalonia.Animation.UnitTests/AnimationIterationTests.cs b/tests/Avalonia.Animation.UnitTests/AnimationIterationTests.cs index d89b8469df..f7a8774689 100644 --- a/tests/Avalonia.Animation.UnitTests/AnimationIterationTests.cs +++ b/tests/Avalonia.Animation.UnitTests/AnimationIterationTests.cs @@ -8,6 +8,7 @@ using Avalonia.Styling; using Avalonia.UnitTests; using Avalonia.Data; using Xunit; +using Avalonia.Animation.Easings; namespace Avalonia.Animation.UnitTests { @@ -73,5 +74,58 @@ namespace Avalonia.Animation.UnitTests Assert.True(animationRun.Status == TaskStatus.RanToCompletion); Assert.Equal(border.Width, 100d); } + + [Fact] + public void Check_FillModes_Start_and_End_Values_if_Retained() + { + var keyframe1 = new KeyFrame() + { + Setters = + { + new Setter(Border.WidthProperty, 0d), + }, + Cue = new Cue(0.0d) + }; + + var keyframe2 = new KeyFrame() + { + Setters = + { + new Setter(Border.WidthProperty, 300d), + }, + Cue = new Cue(1.0d) + }; + + var animation = new Animation() + { + Duration = TimeSpan.FromSeconds(0.05d), + Delay = TimeSpan.FromSeconds(0.05d), + Easing = new SineEaseInOut(), + FillMode = FillMode.Both, + Children = + { + keyframe1, + keyframe2 + } + }; + + var border = new Border() + { + Height = 100d, + Width = 100d, + }; + + var clock = new TestClock(); + var animationRun = animation.RunAsync(border, clock); + + clock.Step(TimeSpan.FromSeconds(0d)); + Assert.Equal(border.Width, 0d); + + clock.Step(TimeSpan.FromSeconds(0.050d)); + Assert.Equal(border.Width, 0d); + + clock.Step(TimeSpan.FromSeconds(0.100d)); + Assert.Equal(border.Width, 300d); + } } } From 4c4e72ab862fd29889059918d038c9db5bf3ca9b Mon Sep 17 00:00:00 2001 From: mstr2 Date: Tue, 15 Jan 2019 18:24:21 +0100 Subject: [PATCH 08/11] Moved GL/EGL errors to separate enumeration --- src/Avalonia.OpenGL/EglErrors.cs | 21 ++++++++++++++++++ src/Avalonia.OpenGL/GlConsts.cs | 3 +++ src/Avalonia.OpenGL/GlErrors.cs | 15 +++++++++++++ src/Avalonia.OpenGL/OpenGlException.cs | 30 ++++++++++---------------- 4 files changed, 50 insertions(+), 19 deletions(-) create mode 100644 src/Avalonia.OpenGL/EglErrors.cs create mode 100644 src/Avalonia.OpenGL/GlErrors.cs diff --git a/src/Avalonia.OpenGL/EglErrors.cs b/src/Avalonia.OpenGL/EglErrors.cs new file mode 100644 index 0000000000..bfe46f2b69 --- /dev/null +++ b/src/Avalonia.OpenGL/EglErrors.cs @@ -0,0 +1,21 @@ +namespace Avalonia.OpenGL +{ + public enum EglErrors + { + EGL_SUCCESS = EglConsts.EGL_SUCCESS, + EGL_NOT_INITIALIZED = EglConsts.EGL_NOT_INITIALIZED, + EGL_BAD_ACCESS = EglConsts.EGL_BAD_ACCESS, + EGL_BAD_ALLOC = EglConsts.EGL_BAD_ALLOC, + EGL_BAD_ATTRIBUTE = EglConsts.EGL_BAD_ATTRIBUTE, + EGL_BAD_CONTEXT = EglConsts.EGL_BAD_CONTEXT, + EGL_BAD_CONFIG = EglConsts.EGL_BAD_CONFIG, + EGL_BAD_CURRENT_SURFACE = EglConsts.EGL_BAD_CURRENT_SURFACE, + EGL_BAD_DISPLAY = EglConsts.EGL_BAD_DISPLAY, + EGL_BAD_SURFACE = EglConsts.EGL_BAD_SURFACE, + EGL_BAD_MATCH = EglConsts.EGL_BAD_MATCH, + EGL_BAD_PARAMETER = EglConsts.EGL_BAD_PARAMETER, + EGL_BAD_NATIVE_PIXMAP = EglConsts.EGL_BAD_NATIVE_PIXMAP, + EGL_BAD_NATIVE_WINDOW = EglConsts.EGL_BAD_NATIVE_WINDOW, + EGL_CONTEXT_LOST = EglConsts.EGL_CONTEXT_LOST + } +} diff --git a/src/Avalonia.OpenGL/GlConsts.cs b/src/Avalonia.OpenGL/GlConsts.cs index 3084a6f958..275f351e3e 100644 --- a/src/Avalonia.OpenGL/GlConsts.cs +++ b/src/Avalonia.OpenGL/GlConsts.cs @@ -456,12 +456,15 @@ namespace Avalonia.OpenGL public const int GL_RENDERER = 0x1F01; public const int GL_VERSION = 0x1F02; public const int GL_EXTENSIONS = 0x1F03; + public const int GL_NO_ERROR = 0; public const int GL_INVALID_ENUM = 0x0500; public const int GL_INVALID_VALUE = 0x0501; public const int GL_INVALID_OPERATION = 0x0502; public const int GL_STACK_OVERFLOW = 0x0503; public const int GL_STACK_UNDERFLOW = 0x0504; public const int GL_OUT_OF_MEMORY = 0x0505; + public const int GL_INVALID_FRAMEBUFFER_OPERATION = 0x0506; + public const int GL_CONTEXT_LOST = 0x0507; public const int GL_CURRENT_BIT = 0x00000001; public const int GL_POINT_BIT = 0x00000002; public const int GL_LINE_BIT = 0x00000004; diff --git a/src/Avalonia.OpenGL/GlErrors.cs b/src/Avalonia.OpenGL/GlErrors.cs new file mode 100644 index 0000000000..ecc7d21c7a --- /dev/null +++ b/src/Avalonia.OpenGL/GlErrors.cs @@ -0,0 +1,15 @@ +namespace Avalonia.OpenGL +{ + public enum GlErrors + { + GL_NO_ERROR = GlConsts.GL_NO_ERROR, + GL_INVALID_ENUM = GlConsts.GL_INVALID_ENUM, + GL_INVALID_VALUE = GlConsts.GL_INVALID_VALUE, + GL_INVALID_OPERATION = GlConsts.GL_INVALID_OPERATION, + GL_INVALID_FRAMEBUFFER_OPERATION = GlConsts.GL_INVALID_FRAMEBUFFER_OPERATION, + GL_STACK_OVERFLOW = GlConsts.GL_STACK_OVERFLOW, + GL_STACK_UNDERFLOW = GlConsts.GL_STACK_UNDERFLOW, + GL_OUT_OF_MEMORY = GlConsts.GL_OUT_OF_MEMORY, + GL_CONTEXT_LOST = GlConsts.GL_CONTEXT_LOST + } +} diff --git a/src/Avalonia.OpenGL/OpenGlException.cs b/src/Avalonia.OpenGL/OpenGlException.cs index 9d9940949b..d3cd7d059e 100644 --- a/src/Avalonia.OpenGL/OpenGlException.cs +++ b/src/Avalonia.OpenGL/OpenGlException.cs @@ -1,5 +1,4 @@ using System; -using System.Reflection; namespace Avalonia.OpenGL { @@ -18,33 +17,26 @@ namespace Avalonia.OpenGL public static OpenGlException GetFormattedException(string funcName, EglInterface egl) { - return GetFormattedException(typeof(EglConsts).GetFields(), funcName, 0x3000, 0x301F, egl.GetError()); + return GetFormattedException(typeof(EglErrors), funcName, egl.GetError()); } public static OpenGlException GetFormattedException(string funcName, GlInterface gl) { - return GetFormattedException(typeof(GlConsts).GetFields(), funcName, 0x0500, 0x0505, gl.GetError()); + return GetFormattedException(typeof(GlErrors), funcName, gl.GetError()); } - private static OpenGlException GetFormattedException( - FieldInfo[] fields, string funcName, int minValue, int maxValue, int errorCode) + private static OpenGlException GetFormattedException(Type consts, string funcName, int errorCode) { - foreach (var field in fields) + try { - int value = (int)field.GetValue(null); - if (value < minValue || value > maxValue) - { - continue; - } - - if (value == errorCode) - { - return new OpenGlException( - $"{funcName} failed with error {field.Name} (0x{errorCode.ToString("X")})", errorCode); - } + string errorName = Enum.GetName(consts, errorCode); + return new OpenGlException( + $"{funcName} failed with error {errorName} (0x{errorCode.ToString("X")})", errorCode); + } + catch (ArgumentException) + { + return new OpenGlException($"{funcName} failed with error 0x{errorCode.ToString("X")}", errorCode); } - - return new OpenGlException($"{funcName} failed with error 0x{errorCode.ToString("X")}", errorCode); } } } From f50ff28387202a866ff0a743dceda6e9270883ef Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 16 Jan 2019 04:37:54 +0100 Subject: [PATCH 09/11] Make ncrunch run again. --- .ncrunch/Avalonia.Desktop.v3.ncrunchproject | 5 +++++ .ncrunch/Avalonia.net461.v3.ncrunchproject | 5 +++++ Avalonia.v3.ncrunchsolution | 1 + 3 files changed, 11 insertions(+) create mode 100644 .ncrunch/Avalonia.Desktop.v3.ncrunchproject create mode 100644 .ncrunch/Avalonia.net461.v3.ncrunchproject diff --git a/.ncrunch/Avalonia.Desktop.v3.ncrunchproject b/.ncrunch/Avalonia.Desktop.v3.ncrunchproject new file mode 100644 index 0000000000..319cd523ce --- /dev/null +++ b/.ncrunch/Avalonia.Desktop.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/.ncrunch/Avalonia.net461.v3.ncrunchproject b/.ncrunch/Avalonia.net461.v3.ncrunchproject new file mode 100644 index 0000000000..319cd523ce --- /dev/null +++ b/.ncrunch/Avalonia.net461.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/Avalonia.v3.ncrunchsolution b/Avalonia.v3.ncrunchsolution index 1b5b0c8930..a2208a9a91 100644 --- a/Avalonia.v3.ncrunchsolution +++ b/Avalonia.v3.ncrunchsolution @@ -2,6 +2,7 @@ tests\TestFiles\**.* + src\Avalonia.Build.Tasks\bin\Debug\netstandard2.0\Avalonia.Build.Tasks.dll True .ncrunch From 6f02e832f8a57624bb80aca6e27666000e64080f Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 16 Jan 2019 04:54:05 +0100 Subject: [PATCH 10/11] Added failing test for buggy TreeViewItem expander. A selector of type `Control /template/ Control:class` is returning `AlwaysThisInstance` instead of `Sometimes`. --- .../SelectorTests_Multiple.cs | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tests/Avalonia.Styling.UnitTests/SelectorTests_Multiple.cs b/tests/Avalonia.Styling.UnitTests/SelectorTests_Multiple.cs index 04b29376b0..ba9b443d92 100644 --- a/tests/Avalonia.Styling.UnitTests/SelectorTests_Multiple.cs +++ b/tests/Avalonia.Styling.UnitTests/SelectorTests_Multiple.cs @@ -85,6 +85,44 @@ namespace Avalonia.Styling.UnitTests Assert.Equal(SelectorMatchResult.NeverThisType, match.Result); } + [Fact] + public void Named_Class_Template_Child_Of_Control() + { + var template = new FuncControlTemplate(parent => + { + return new Border + { + Name = "border", + }; + }); + + var control = new Button + { + Template = template, + }; + + control.ApplyTemplate(); + + var selector = default(Selector) + .OfType