diff --git a/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs b/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs index 9398dc4b7c..a17a5119a5 100644 --- a/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs +++ b/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs @@ -124,6 +124,10 @@ namespace Avalonia.Rendering } } + internal void UnitTestUpdateScene() => UpdateScene(); + + internal void UnitTestRender() => Render(_scene); + private void Render(Scene scene) { _rendering = true; diff --git a/src/Shared/SharedAssemblyInfo.cs b/src/Shared/SharedAssemblyInfo.cs index 63111eebf4..f72e6f7eef 100644 --- a/src/Shared/SharedAssemblyInfo.cs +++ b/src/Shared/SharedAssemblyInfo.cs @@ -3,6 +3,7 @@ using System.Reflection; using System.Resources; +using System.Runtime.CompilerServices; [assembly: AssemblyCompany("")] [assembly: AssemblyConfiguration("")] @@ -16,3 +17,7 @@ using System.Resources; [assembly: AssemblyVersion("0.4.1")] [assembly: AssemblyFileVersion("0.4.1")] [assembly: AssemblyInformationalVersion("0.4.1")] + +[assembly: InternalsVisibleTo("Avalonia.Cairo.RenderTests")] +[assembly: InternalsVisibleTo("Avalonia.Direct2D1.RenderTests")] +[assembly: InternalsVisibleTo("Avalonia.Skia.RenderTests")] \ No newline at end of file diff --git a/tests/Avalonia.RenderTests/Avalonia.Direct2D1.RenderTests.v3.ncrunchproject b/tests/Avalonia.RenderTests/Avalonia.Direct2D1.RenderTests.v3.ncrunchproject new file mode 100644 index 0000000000..5ca3dbf2e3 --- /dev/null +++ b/tests/Avalonia.RenderTests/Avalonia.Direct2D1.RenderTests.v3.ncrunchproject @@ -0,0 +1,83 @@ + + + 1000 + + + Avalonia.Direct2D1.RenderTests.Media.ImageBrushTests.ImageBrush_NoStretch_FlipX_TopLeftDest + + + Avalonia.Direct2D1.RenderTests.Media.LinearGradientBrushTests + + + Avalonia.Direct2D1.RenderTests.Media.VisualBrushTests + + + Avalonia.Direct2D1.RenderTests.Controls.BorderTests + + + Avalonia.Direct2D1.RenderTests.Media.ImageBrushTests.ImageBrush_NoStretch_FlipXY_TopLeftDest + + + Avalonia.Direct2D1.RenderTests.Media.ImageBrushTests.ImageBrush_NoStretch_FlipY_TopLeftDest + + + Avalonia.Direct2D1.RenderTests.Media.ImageBrushTests.ImageBrush_NoStretch_NoTile_Alignment_BottomRight + + + Avalonia.Direct2D1.RenderTests.Media.ImageBrushTests.ImageBrush_NoStretch_NoTile_Alignment_Center + + + Avalonia.Direct2D1.RenderTests.Media.ImageBrushTests.ImageBrush_NoStretch_NoTile_Alignment_TopLeft + + + Avalonia.Direct2D1.RenderTests.Media.ImageBrushTests.ImageBrush_NoStretch_NoTile_BottomRightQuarterDest + + + Avalonia.Direct2D1.RenderTests.Media.ImageBrushTests.ImageBrush_NoStretch_NoTile_BottomRightQuarterSource + + + Avalonia.Direct2D1.RenderTests.Media.ImageBrushTests.ImageBrush_NoStretch_NoTile_BottomRightQuarterSource_BottomRightQuarterDest + + + Avalonia.Direct2D1.RenderTests.Media.ImageBrushTests.ImageBrush_NoStretch_Tile_BottomRightQuarterSource_CenterQuarterDest + + + Avalonia.Direct2D1.RenderTests.Media.ImageBrushTests.ImageBrush_Uniform_NoTile + + + Avalonia.Direct2D1.RenderTests.Media.ImageBrushTests.ImageBrush_UniformToFill_NoTile + + + Avalonia.Direct2D1.RenderTests.Controls.ImageTests + + + Avalonia.Direct2D1.RenderTests.GeometryClippingTests + + + Avalonia.Direct2D1.RenderTests.Media.FormattedTextImplTests + + + Avalonia.Direct2D1.RenderTests.OpacityMaskTests + + + Avalonia.Direct2D1.RenderTests.Shapes.EllipseTests + + + Avalonia.Direct2D1.RenderTests.Shapes.LineTests + + + Avalonia.Direct2D1.RenderTests.Shapes.PathTests + + + Avalonia.Direct2D1.RenderTests.Shapes.PolygonTests + + + Avalonia.Direct2D1.RenderTests.Shapes.PolylineTests + + + Avalonia.Direct2D1.RenderTests.Shapes.RectangleTests + + + True + + \ No newline at end of file diff --git a/tests/Avalonia.RenderTests/Controls/BorderTests.cs b/tests/Avalonia.RenderTests/Controls/BorderTests.cs index e960070f82..6cc3e63c14 100644 --- a/tests/Avalonia.RenderTests/Controls/BorderTests.cs +++ b/tests/Avalonia.RenderTests/Controls/BorderTests.cs @@ -1,6 +1,7 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. +using System.Threading.Tasks; using Avalonia.Controls; using Avalonia.Layout; using Avalonia.Media; @@ -22,7 +23,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls } [Fact] - public void Border_1px_Border() + public async Task Border_1px_Border() { Decorator target = new Decorator { @@ -36,12 +37,12 @@ namespace Avalonia.Direct2D1.RenderTests.Controls } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } [Fact] - public void Border_2px_Border() + public async Task Border_2px_Border() { Decorator target = new Decorator { @@ -55,12 +56,12 @@ namespace Avalonia.Direct2D1.RenderTests.Controls } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } [Fact] - public void Border_Fill() + public async Task Border_Fill() { Decorator target = new Decorator { @@ -73,12 +74,12 @@ namespace Avalonia.Direct2D1.RenderTests.Controls } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } [Fact] - public void Border_Brush_Offsets_Content() + public async Task Border_Brush_Offsets_Content() { Decorator target = new Decorator { @@ -96,12 +97,12 @@ namespace Avalonia.Direct2D1.RenderTests.Controls } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } [Fact] - public void Border_Padding_Offsets_Content() + public async Task Border_Padding_Offsets_Content() { Decorator target = new Decorator { @@ -120,12 +121,12 @@ namespace Avalonia.Direct2D1.RenderTests.Controls } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } [Fact] - public void Border_Margin_Offsets_Content() + public async Task Border_Margin_Offsets_Content() { Decorator target = new Decorator { @@ -144,7 +145,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -153,7 +154,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls #else [Fact] #endif - public void Border_Centers_Content_Horizontally() + public async Task Border_Centers_Content_Horizontally() { Decorator target = new Decorator { @@ -175,7 +176,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -186,7 +187,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls #else [Fact] #endif - public void Border_Centers_Content_Vertically() + public async Task Border_Centers_Content_Vertically() { Decorator target = new Decorator { @@ -208,7 +209,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -217,7 +218,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls #else [Fact] #endif - public void Border_Stretches_Content_Horizontally() + public async Task Border_Stretches_Content_Horizontally() { Decorator target = new Decorator { @@ -239,7 +240,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -248,7 +249,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls #else [Fact] #endif - public void Border_Stretches_Content_Vertically() + public async Task Border_Stretches_Content_Vertically() { Decorator target = new Decorator { @@ -270,7 +271,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -279,7 +280,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls #else [Fact] #endif - public void Border_Left_Aligns_Content() + public async Task Border_Left_Aligns_Content() { Decorator target = new Decorator { @@ -301,7 +302,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -310,7 +311,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls #else [Fact] #endif - public void Border_Right_Aligns_Content() + public async Task Border_Right_Aligns_Content() { Decorator target = new Decorator { @@ -332,7 +333,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -343,7 +344,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls #else [Fact] #endif - public void Border_Top_Aligns_Content() + public async Task Border_Top_Aligns_Content() { Decorator target = new Decorator { @@ -365,7 +366,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -376,7 +377,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls #else [Fact] #endif - public void Border_Bottom_Aligns_Content() + public async Task Border_Bottom_Aligns_Content() { Decorator target = new Decorator { @@ -398,12 +399,12 @@ namespace Avalonia.Direct2D1.RenderTests.Controls } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } [Fact] - public void Border_Nested_Rotate() + public async Task Border_Nested_Rotate() { Decorator target = new Decorator { @@ -426,7 +427,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } } diff --git a/tests/Avalonia.RenderTests/Controls/ImageTests.cs b/tests/Avalonia.RenderTests/Controls/ImageTests.cs index fcc99398f9..9c1d3624d1 100644 --- a/tests/Avalonia.RenderTests/Controls/ImageTests.cs +++ b/tests/Avalonia.RenderTests/Controls/ImageTests.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using System.IO; +using System.Threading.Tasks; using Avalonia.Controls; using Avalonia.Media; using Avalonia.Media.Imaging; @@ -26,7 +27,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls } [Fact] - public void Image_Stretch_None() + public async Task Image_Stretch_None() { Decorator target = new Decorator { @@ -44,12 +45,12 @@ namespace Avalonia.Direct2D1.RenderTests.Controls } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } [Fact] - public void Image_Stretch_Fill() + public async Task Image_Stretch_Fill() { Decorator target = new Decorator { @@ -67,12 +68,12 @@ namespace Avalonia.Direct2D1.RenderTests.Controls } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } [Fact] - public void Image_Stretch_Uniform() + public async Task Image_Stretch_Uniform() { Decorator target = new Decorator { @@ -90,12 +91,12 @@ namespace Avalonia.Direct2D1.RenderTests.Controls } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } [Fact] - public void Image_Stretch_UniformToFill() + public async Task Image_Stretch_UniformToFill() { Decorator target = new Decorator { @@ -113,7 +114,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } } diff --git a/tests/Avalonia.RenderTests/GeometryClippingTests.cs b/tests/Avalonia.RenderTests/GeometryClippingTests.cs index 355606bb43..64b1720819 100644 --- a/tests/Avalonia.RenderTests/GeometryClippingTests.cs +++ b/tests/Avalonia.RenderTests/GeometryClippingTests.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Text; using Xunit; +using System.Threading.Tasks; #if AVALONIA_CAIRO namespace Avalonia.Cairo.RenderTests @@ -22,7 +23,7 @@ namespace Avalonia.Direct2D1.RenderTests } [Fact] - public void Geometry_Clip_Clips_Path() + public async Task Geometry_Clip_Clips_Path() { var target = new Canvas { @@ -44,7 +45,7 @@ namespace Avalonia.Direct2D1.RenderTests } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } } diff --git a/tests/Avalonia.RenderTests/Media/ImageBrushTests.cs b/tests/Avalonia.RenderTests/Media/ImageBrushTests.cs index cbf11504c1..1cfbe60f1d 100644 --- a/tests/Avalonia.RenderTests/Media/ImageBrushTests.cs +++ b/tests/Avalonia.RenderTests/Media/ImageBrushTests.cs @@ -1,6 +1,7 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. +using System.Threading.Tasks; using Avalonia.Controls; using Avalonia.Controls.Shapes; using Avalonia.Layout; @@ -29,7 +30,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media } [Fact] - public void ImageBrush_NoStretch_NoTile_Alignment_TopLeft() + public async Task ImageBrush_NoStretch_NoTile_Alignment_TopLeft() { Decorator target = new Decorator { @@ -49,12 +50,12 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } [Fact] - public void ImageBrush_NoStretch_NoTile_Alignment_Center() + public async Task ImageBrush_NoStretch_NoTile_Alignment_Center() { Decorator target = new Decorator { @@ -74,12 +75,12 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } [Fact] - public void ImageBrush_NoStretch_NoTile_Alignment_BottomRight() + public async Task ImageBrush_NoStretch_NoTile_Alignment_BottomRight() { Decorator target = new Decorator { @@ -99,7 +100,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } #if AVALONIA_SKIA_SKIP_FAIL @@ -107,7 +108,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media #else [Fact] #endif - public void ImageBrush_Fill_NoTile() + public async Task ImageBrush_Fill_NoTile() { Decorator target = new Decorator { @@ -125,7 +126,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -134,7 +135,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media #else [Fact] #endif - public void ImageBrush_Uniform_NoTile() + public async Task ImageBrush_Uniform_NoTile() { Decorator target = new Decorator { @@ -152,7 +153,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -161,7 +162,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media #else [Fact] #endif - public void ImageBrush_UniformToFill_NoTile() + public async Task ImageBrush_UniformToFill_NoTile() { Decorator target = new Decorator { @@ -179,12 +180,12 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } [Fact] - public void ImageBrush_NoStretch_NoTile_BottomRightQuarterSource() + public async Task ImageBrush_NoStretch_NoTile_BottomRightQuarterSource() { Decorator target = new Decorator { @@ -203,7 +204,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -212,7 +213,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media #else [Fact] #endif - public void ImageBrush_NoStretch_NoTile_BottomRightQuarterDest() + public async Task ImageBrush_NoStretch_NoTile_BottomRightQuarterDest() { Decorator target = new Decorator { @@ -231,7 +232,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -240,7 +241,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media #else [Fact] #endif - public void ImageBrush_NoStretch_NoTile_BottomRightQuarterSource_BottomRightQuarterDest() + public async Task ImageBrush_NoStretch_NoTile_BottomRightQuarterSource_BottomRightQuarterDest() { Decorator target = new Decorator { @@ -260,12 +261,12 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } [Fact] - public void ImageBrush_NoStretch_Tile_BottomRightQuarterSource_CenterQuarterDest() + public async Task ImageBrush_NoStretch_Tile_BottomRightQuarterSource_CenterQuarterDest() { Decorator target = new Decorator { @@ -285,7 +286,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -294,7 +295,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media #else [Fact] #endif - public void ImageBrush_NoStretch_FlipX_TopLeftDest() + public async Task ImageBrush_NoStretch_FlipX_TopLeftDest() { Decorator target = new Decorator { @@ -313,7 +314,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -322,7 +323,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media #else [Fact] #endif - public void ImageBrush_NoStretch_FlipY_TopLeftDest() + public async Task ImageBrush_NoStretch_FlipY_TopLeftDest() { Decorator target = new Decorator { @@ -341,12 +342,12 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } [Fact] - public void ImageBrush_NoStretch_FlipXY_TopLeftDest() + public async Task ImageBrush_NoStretch_FlipXY_TopLeftDest() { Decorator target = new Decorator { @@ -365,7 +366,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } } diff --git a/tests/Avalonia.RenderTests/Media/LinearGradientBrushTests.cs b/tests/Avalonia.RenderTests/Media/LinearGradientBrushTests.cs index 104edf04e5..776910ca5a 100644 --- a/tests/Avalonia.RenderTests/Media/LinearGradientBrushTests.cs +++ b/tests/Avalonia.RenderTests/Media/LinearGradientBrushTests.cs @@ -29,7 +29,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media #else [Fact] #endif - public void LinearGradientBrush_RedBlue_Horizontal_Fill() + public async Task LinearGradientBrush_RedBlue_Horizontal_Fill() { Decorator target = new Decorator { @@ -51,7 +51,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -60,7 +60,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media #else [Fact] #endif - public void LinearGradientBrush_RedBlue_Vertical_Fill() + public async Task LinearGradientBrush_RedBlue_Vertical_Fill() { Decorator target = new Decorator { @@ -82,7 +82,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } } diff --git a/tests/Avalonia.RenderTests/Media/VisualBrushTests.cs b/tests/Avalonia.RenderTests/Media/VisualBrushTests.cs index 15573f1d23..9ff5cb6354 100644 --- a/tests/Avalonia.RenderTests/Media/VisualBrushTests.cs +++ b/tests/Avalonia.RenderTests/Media/VisualBrushTests.cs @@ -1,6 +1,7 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. +using System.Threading.Tasks; using Avalonia.Controls; using Avalonia.Controls.Shapes; using Avalonia.Layout; @@ -61,7 +62,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media } [Fact] - public void VisualBrush_NoStretch_NoTile_Alignment_TopLeft() + public async Task VisualBrush_NoStretch_NoTile_Alignment_TopLeft() { Decorator target = new Decorator { @@ -81,7 +82,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -92,7 +93,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media #else [Fact] #endif - public void VisualBrush_NoStretch_NoTile_Alignment_Center() + public async Task VisualBrush_NoStretch_NoTile_Alignment_Center() { Decorator target = new Decorator { @@ -112,12 +113,12 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } [Fact] - public void VisualBrush_NoStretch_NoTile_Alignment_BottomRight() + public async Task VisualBrush_NoStretch_NoTile_Alignment_BottomRight() { Decorator target = new Decorator { @@ -137,7 +138,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -148,7 +149,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media #else [Fact] #endif - public void VisualBrush_Fill_NoTile() + public async Task VisualBrush_Fill_NoTile() { Decorator target = new Decorator { @@ -166,7 +167,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -177,7 +178,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media #else [Fact] #endif - public void VisualBrush_Uniform_NoTile() + public async Task VisualBrush_Uniform_NoTile() { Decorator target = new Decorator { @@ -195,7 +196,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -206,7 +207,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media #else [Fact] #endif - public void VisualBrush_UniformToFill_NoTile() + public async Task VisualBrush_UniformToFill_NoTile() { Decorator target = new Decorator { @@ -224,12 +225,12 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } [Fact] - public void VisualBrush_NoStretch_NoTile_BottomRightQuarterSource() + public async Task VisualBrush_NoStretch_NoTile_BottomRightQuarterSource() { Decorator target = new Decorator { @@ -248,7 +249,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -259,7 +260,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media #else [Fact] #endif - public void VisualBrush_NoStretch_NoTile_BottomRightQuarterDest() + public async Task VisualBrush_NoStretch_NoTile_BottomRightQuarterDest() { Decorator target = new Decorator { @@ -278,7 +279,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -287,7 +288,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media #else [Fact] #endif - public void VisualBrush_NoStretch_NoTile_BottomRightQuarterSource_BottomRightQuarterDest() + public async Task VisualBrush_NoStretch_NoTile_BottomRightQuarterSource_BottomRightQuarterDest() { Decorator target = new Decorator { @@ -307,12 +308,12 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } [Fact] - public void VisualBrush_NoStretch_Tile_BottomRightQuarterSource_CenterQuarterDest() + public async Task VisualBrush_NoStretch_Tile_BottomRightQuarterSource_CenterQuarterDest() { Decorator target = new Decorator { @@ -332,7 +333,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -343,7 +344,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media #else [Fact] #endif - public void VisualBrush_NoStretch_FlipX_TopLeftDest() + public async Task VisualBrush_NoStretch_FlipX_TopLeftDest() { Decorator target = new Decorator { @@ -362,7 +363,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -373,7 +374,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media #else [Fact] #endif - public void VisualBrush_NoStretch_FlipY_TopLeftDest() + public async Task VisualBrush_NoStretch_FlipY_TopLeftDest() { Decorator target = new Decorator { @@ -392,7 +393,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -403,7 +404,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media #else [Fact] #endif - public void VisualBrush_NoStretch_FlipXY_TopLeftDest() + public async Task VisualBrush_NoStretch_FlipXY_TopLeftDest() { Decorator target = new Decorator { @@ -422,12 +423,12 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } [Fact] - public void VisualBrush_InTree_Visual() + public async Task VisualBrush_InTree_Visual() { Border source; Decorator target = new Decorator @@ -449,9 +450,9 @@ namespace Avalonia.Direct2D1.RenderTests.Media Text = "Visual" } }), - new Rectangle + new Border { - Fill = new VisualBrush + Background = new VisualBrush { Stretch = Stretch.Uniform, Visual = source, @@ -462,7 +463,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } } diff --git a/tests/Avalonia.RenderTests/OpacityMaskTests.cs b/tests/Avalonia.RenderTests/OpacityMaskTests.cs index b23f231f2e..b49f04f3ee 100644 --- a/tests/Avalonia.RenderTests/OpacityMaskTests.cs +++ b/tests/Avalonia.RenderTests/OpacityMaskTests.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Text; using Xunit; +using System.Threading.Tasks; #if AVALONIA_CAIRO namespace Avalonia.Cairo.RenderTests @@ -22,7 +23,7 @@ namespace Avalonia.Direct2D1.RenderTests } [Fact] - public void Opacity_Mask_Masks_Element() + public async Task Opacity_Mask_Masks_Element() { var target = new Canvas { @@ -53,7 +54,7 @@ namespace Avalonia.Direct2D1.RenderTests } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } } diff --git a/tests/Avalonia.RenderTests/Shapes/LineTests.cs b/tests/Avalonia.RenderTests/Shapes/LineTests.cs index 80a4771c1f..05974e75f1 100644 --- a/tests/Avalonia.RenderTests/Shapes/LineTests.cs +++ b/tests/Avalonia.RenderTests/Shapes/LineTests.cs @@ -1,6 +1,7 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. +using System.Threading.Tasks; using Avalonia.Controls; using Avalonia.Controls.Shapes; using Avalonia.Media; @@ -22,7 +23,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } [Fact] - public void Line_1px_Stroke() + public async Task Line_1px_Stroke() { Decorator target = new Decorator { @@ -37,12 +38,12 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } [Fact] - public void Line_1px_Stroke_Reversed() + public async Task Line_1px_Stroke_Reversed() { Decorator target = new Decorator { @@ -57,12 +58,12 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } [Fact] - public void Line_1px_Stroke_Vertical() + public async Task Line_1px_Stroke_Vertical() { Decorator target = new Decorator { @@ -77,7 +78,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } } diff --git a/tests/Avalonia.RenderTests/Shapes/PathTests.cs b/tests/Avalonia.RenderTests/Shapes/PathTests.cs index 2e5d528bce..f95be89f99 100644 --- a/tests/Avalonia.RenderTests/Shapes/PathTests.cs +++ b/tests/Avalonia.RenderTests/Shapes/PathTests.cs @@ -15,6 +15,7 @@ namespace Avalonia.Skia.RenderTests namespace Avalonia.Direct2D1.RenderTests.Shapes #endif { + using System.Threading.Tasks; using Avalonia.Collections; public class PathTests : TestBase @@ -29,7 +30,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes #else [Fact] #endif - public void Line_Absolute() + public async Task Line_Absolute() { Decorator target = new Decorator { @@ -45,7 +46,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -54,7 +55,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes #else [Fact] #endif - public void Line_Relative() + public async Task Line_Relative() { Decorator target = new Decorator { @@ -70,7 +71,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -79,7 +80,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes #else [Fact] #endif - public void HorizontalLine_Absolute() + public async Task HorizontalLine_Absolute() { Decorator target = new Decorator { @@ -95,7 +96,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -104,7 +105,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes #else [Fact] #endif - public void HorizontalLine_Relative() + public async Task HorizontalLine_Relative() { Decorator target = new Decorator { @@ -120,7 +121,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -129,7 +130,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes #else [Fact] #endif - public void VerticalLine_Absolute() + public async Task VerticalLine_Absolute() { Decorator target = new Decorator { @@ -145,7 +146,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -154,7 +155,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes #else [Fact] #endif - public void VerticalLine_Relative() + public async Task VerticalLine_Relative() { Decorator target = new Decorator { @@ -170,7 +171,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -179,7 +180,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes #else [Fact] #endif - public void CubicBezier_Absolute() + public async Task CubicBezier_Absolute() { Decorator target = new Decorator { @@ -196,7 +197,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -205,7 +206,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes #else [Fact] #endif - public void CubicBezier_Relative() + public async Task CubicBezier_Relative() { Decorator target = new Decorator { @@ -222,7 +223,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -231,7 +232,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes #else [Fact] #endif - public void Arc_Absolute() + public async Task Arc_Absolute() { Decorator target = new Decorator { @@ -248,7 +249,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -257,7 +258,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes #else [Fact] #endif - public void Arc_Relative() + public async Task Arc_Relative() { Decorator target = new Decorator { @@ -274,12 +275,12 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } [Fact] - public void Path_100px_Triangle_Centered() + public async Task Path_100px_Triangle_Centered() { Decorator target = new Decorator { @@ -296,7 +297,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } #if AVALONIA_SKIA_SKIP_FAIL @@ -304,7 +305,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes #else [Fact] #endif - public void Path_Tick_Scaled() + public async Task Path_Tick_Scaled() { Decorator target = new Decorator { @@ -322,7 +323,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -331,7 +332,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes #else [Fact] #endif - public void Path_Tick_Scaled_Stroke_8px() + public async Task Path_Tick_Scaled_Stroke_8px() { Decorator target = new Decorator { @@ -349,12 +350,12 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } [Fact] - public void Path_Expander_With_Border() + public async Task Path_Expander_With_Border() { Decorator target = new Decorator { @@ -377,7 +378,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -388,7 +389,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes #else [Fact] #endif - public void Path_With_PenLineCap() + public async Task Path_With_PenLineCap() { Decorator target = new Decorator { @@ -408,7 +409,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } } diff --git a/tests/Avalonia.RenderTests/Shapes/PolygonTests.cs b/tests/Avalonia.RenderTests/Shapes/PolygonTests.cs index 21a48b6b64..d7e166839b 100644 --- a/tests/Avalonia.RenderTests/Shapes/PolygonTests.cs +++ b/tests/Avalonia.RenderTests/Shapes/PolygonTests.cs @@ -1,6 +1,7 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. +using System.Threading.Tasks; using Avalonia.Controls; using Avalonia.Controls.Shapes; using Avalonia.Media; @@ -28,7 +29,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes #else [Fact] #endif - public void Polygon_1px_Stroke() + public async Task Polygon_1px_Stroke() { Decorator target = new Decorator { @@ -45,7 +46,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -56,7 +57,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes #else [Fact] #endif - public void Polygon_NonUniformFill() + public async Task Polygon_NonUniformFill() { Decorator target = new Decorator { @@ -73,7 +74,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } } diff --git a/tests/Avalonia.RenderTests/Shapes/PolylineTests.cs b/tests/Avalonia.RenderTests/Shapes/PolylineTests.cs index 5506b29971..7b9aac220b 100644 --- a/tests/Avalonia.RenderTests/Shapes/PolylineTests.cs +++ b/tests/Avalonia.RenderTests/Shapes/PolylineTests.cs @@ -1,6 +1,7 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. +using System.Threading.Tasks; using Avalonia.Controls; using Avalonia.Controls.Shapes; using Avalonia.Media; @@ -28,7 +29,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes #else [Fact] #endif - public void Polyline_1px_Stroke() + public async Task Polyline_1px_Stroke() { var polylinePoints = new Point[] { new Point(0, 0), new Point(5, 0), new Point(6, -2), new Point(7, 3), new Point(8, -3), new Point(9, 1), new Point(10, 0), new Point(15, 0) }; @@ -47,7 +48,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } @@ -58,7 +59,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes #else [Fact] #endif - public void Polyline_10px_Stroke_PenLineJoin() + public async Task Polyline_10px_Stroke_PenLineJoin() { var polylinePoints = new Point[] { new Point(0, 0), new Point(5, 0), new Point(6, -2), new Point(7, 3), new Point(8, -3), new Point(9, 1), new Point(10, 0), new Point(15, 0) }; @@ -80,7 +81,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } } diff --git a/tests/Avalonia.RenderTests/Shapes/RectangleTests.cs b/tests/Avalonia.RenderTests/Shapes/RectangleTests.cs index 1bd102b676..5fa424103f 100644 --- a/tests/Avalonia.RenderTests/Shapes/RectangleTests.cs +++ b/tests/Avalonia.RenderTests/Shapes/RectangleTests.cs @@ -1,6 +1,7 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. +using System.Threading.Tasks; using Avalonia.Controls; using Avalonia.Controls.Shapes; using Avalonia.Media; @@ -22,7 +23,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } [Fact] - public void Rectangle_1px_Stroke() + public async Task Rectangle_1px_Stroke() { Decorator target = new Decorator { @@ -36,12 +37,12 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } [Fact] - public void Rectangle_2px_Stroke() + public async Task Rectangle_2px_Stroke() { Decorator target = new Decorator { @@ -55,12 +56,12 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } [Fact] - public void Rectangle_Stroke_Fill() + public async Task Rectangle_Stroke_Fill() { Decorator target = new Decorator { @@ -75,12 +76,12 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } [Fact] - public void Rectangle_Stroke_Fill_ClipToBounds() + public async Task Rectangle_Stroke_Fill_ClipToBounds() { Decorator target = new Decorator { @@ -96,7 +97,7 @@ namespace Avalonia.Direct2D1.RenderTests.Shapes } }; - RenderToFile(target); + await RenderToFile(target); CompareImages(); } } diff --git a/tests/Avalonia.RenderTests/TestBase.cs b/tests/Avalonia.RenderTests/TestBase.cs index a7ecc35717..4157c9d24d 100644 --- a/tests/Avalonia.RenderTests/TestBase.cs +++ b/tests/Avalonia.RenderTests/TestBase.cs @@ -10,6 +10,9 @@ using Avalonia.Rendering; using Xunit; using Avalonia.Platform; +using System.Threading.Tasks; +using System; +using System.Threading; #if AVALONIA_CAIRO using Avalonia.Cairo; @@ -29,6 +32,9 @@ namespace Avalonia.Direct2D1.RenderTests { public class TestBase { + private static readonly TestThreadingInterface threadingInterface = + new TestThreadingInterface(); + static TestBase() { #if AVALONIA_CAIRO @@ -38,6 +44,10 @@ namespace Avalonia.Direct2D1.RenderTests #else Direct2D1Platform.Initialize(); #endif + AvaloniaLocator.CurrentMutable + .Bind() + .ToConstant(threadingInterface); + } public TestBase(string outputPath) @@ -50,6 +60,8 @@ namespace Avalonia.Direct2D1.RenderTests string testFiles = Path.GetFullPath(@"..\..\tests\TestFiles\Direct2D1"); #endif OutputPath = Path.Combine(testFiles, outputPath); + + threadingInterface.MainThread = Thread.CurrentThread; } public string OutputPath @@ -57,7 +69,7 @@ namespace Avalonia.Direct2D1.RenderTests get; } - protected void RenderToFile(Control target, [CallerMemberName] string testName = "") + protected async Task RenderToFile(Control target, [CallerMemberName] string testName = "") { if (!Directory.Exists(OutputPath)) { @@ -85,7 +97,12 @@ namespace Avalonia.Direct2D1.RenderTests Size size = new Size(target.Width, target.Height); target.Measure(size); target.Arrange(new Rect(size)); - renderer.Render(target.Bounds); + renderer.UnitTestUpdateScene(); + + // Do the deferred render on a background thread to expose any threading errors in + // the deferred rendering path. + await Task.Run((Action)renderer.UnitTestRender); + rtb.Save(deferredPath); } } @@ -114,5 +131,29 @@ namespace Avalonia.Direct2D1.RenderTests } } } + + private class TestThreadingInterface : IPlatformThreadingInterface + { + public bool CurrentThreadIsLoopThread => MainThread.ManagedThreadId == Thread.CurrentThread.ManagedThreadId; + + public Thread MainThread { get; set; } + + public event Action Signaled; + + public void RunLoop(CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public void Signal() + { + throw new NotImplementedException(); + } + + public IDisposable StartTimer(TimeSpan interval, Action tick) + { + throw new NotImplementedException(); + } + } } }