Browse Source

revert

try-critical-branch-bringup-2
Jumar Macato 5 years ago
parent
commit
71f46e3923
No known key found for this signature in database GPG Key ID: B19884DAC3A5BF3F
  1. 53
      src/Avalonia.Visuals/Rendering/DeferredRenderer.cs
  2. 77
      src/Avalonia.Visuals/Rendering/ImmediateRenderer.cs
  3. 10
      src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs
  4. 20
      src/Avalonia.Visuals/Visual.cs
  5. 6
      src/Avalonia.Visuals/VisualTree/IVisual.cs

53
src/Avalonia.Visuals/Rendering/DeferredRenderer.cs

@ -276,6 +276,8 @@ namespace Avalonia.Rendering
internal void UnitTestUpdateScene() => UpdateScene();
internal void UnitTestRender() => Render(false);
internal Scene UnitTestScene() => _scene.Item;
private void EnsureCanHitTest()
@ -354,7 +356,7 @@ namespace Avalonia.Rendering
Layers.Update(scene, context);
RenderToLayers(scene, false);
RenderToLayers(scene);
if (DebugFramesPath != null)
{
@ -387,38 +389,14 @@ namespace Avalonia.Rendering
// Indicate that we have updated the layers
return (sceneRef.Clone(), true);
}
var hasCriticalRenderTimeVisualUpdates = Layers.Any(l =>
l.LayerRoot is IRenderTimeCriticalVisual critical && critical.ThreadSafeHasNewFrame);
if (hasCriticalRenderTimeVisualUpdates)
{
Layers.Update(scene, contextFactory());
// Render only layers with critical-time visual roots
RenderToLayers(scene, true);
if (DebugFramesPath != null)
{
SaveDebugFrames(scene.Generation);
}
// Indicate that we have updated the layers
return (sceneRef.Clone(), true);
} else
return (sceneRef.Clone(), false);
// Just return scene, layers weren't updated
return (sceneRef.Clone(), false);
}
}
private void RenderTimeCriticalVisual(IDrawingContextImpl context, VisualNode node,
IRenderTimeCriticalVisual critical, double scaling)
{
var savedTransform = context.Transform;
using (var fullCtx = new DrawingContext(context, false))
using (fullCtx.PushPostTransform(node.Transform))
using (fullCtx.PushTransformContainer())
critical.ThreadSafeRender(fullCtx, node.VisualSize, scaling);
context.Transform = savedTransform;
}
private void Render(IDrawingContextImpl context, VisualNode node, IVisual layer, Rect clipBounds)
{
if (layer == null || node.LayerRoot == layer)
@ -454,7 +432,7 @@ namespace Avalonia.Rendering
}
}
private void RenderToLayers(Scene scene, bool criticalTimeRenderOnly)
private void RenderToLayers(Scene scene)
{
foreach (var layer in scene.Layers)
{
@ -464,18 +442,12 @@ namespace Avalonia.Rendering
var renderTarget = renderLayer.Bitmap;
var node = (VisualNode)scene.FindNode(layer.LayerRoot);
var critical = node.Visual as IRenderTimeCriticalVisual;
if (criticalTimeRenderOnly && critical?.HasNewFrame != true)
continue;
if (node != null)
{
using (var context = renderTarget.Item.CreateDrawingContext(this))
if (criticalTimeRenderOnly && critical?.ThreadSafeHasNewFrame != true)
continue;
{
if (renderLayer.IsEmpty)
{
{
// Render entire layer root node
context.Clear(Colors.Transparent);
context.Transform = Matrix.Identity;
@ -497,19 +469,12 @@ namespace Avalonia.Rendering
{
var snappedRect = SnapToDevicePixels(rect, scale);
context.Transform = Matrix.Identity;
context.PushClip(snappedRect);
context.PushClip(snappedRect);
context.Clear(Colors.Transparent);
Render(context, node, layer.LayerRoot, snappedRect);
if (critical != null)
RenderTimeCriticalVisual(context, node, critical, scene.Scaling);
context.PopClip();
if (DrawDirtyRects)
_dirtyRectsDisplay.Add(node.Bounds);
}
else
{
foreach (var rect in layer.Dirty)
{
_dirtyRectsDisplay.Add(snappedRect);
}

77
src/Avalonia.Visuals/Rendering/ImmediateRenderer.cs

@ -1,9 +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;
using System;
using System.Collections.Generic;
using System.Linq;
using Avalonia.Logging;
using Avalonia.Media;
using Avalonia.Platform;
using Avalonia.VisualTree;
@ -18,26 +16,21 @@ namespace Avalonia.Rendering
/// The immediate renderer supports only clip-bound-based hit testing; a control's geometry is
/// not taken into account.
/// </remarks>
public class ImmediateRenderer : RendererBase, IRenderer, IVisualBrushRenderer,
IRenderLoopTask
public class ImmediateRenderer : RendererBase, IRenderer, IVisualBrushRenderer
{
private readonly IVisual _root;
private readonly IRenderLoop _loop;
private readonly IRenderRoot _renderRoot;
private IRenderTarget _renderTarget;
private RenderPassInfo _lastRenderPassInfo;
/// <summary>
/// Initializes a new instance of the <see cref="ImmediateRenderer"/> class.
/// </summary>
/// <param name="root">The control to render.</param>
/// <param name="loop">Render loop</param>
public ImmediateRenderer(IVisual root, IRenderLoop loop = null)
public ImmediateRenderer(IVisual root)
{
Contract.Requires<ArgumentNullException>(root != null);
_root = root;
_loop = loop;
_renderRoot = root as IRenderRoot;
}
@ -47,6 +40,9 @@ namespace Avalonia.Rendering
/// <inheritdoc/>
public bool DrawDirtyRects { get; set; }
/// <inheritdoc/>
public event EventHandler<SceneInvalidatedEventArgs> SceneInvalidated;
/// <inheritdoc/>
public void Paint(Rect rect)
{
@ -55,7 +51,6 @@ namespace Avalonia.Rendering
_renderTarget = ((IRenderRoot)_root).CreateRenderTarget();
}
var scaling = (_root as IRenderRoot)?.RenderScaling ?? 1;
try
{
using (var context = new DrawingContext(_renderTarget.CreateDrawingContext(this)))
@ -64,9 +59,7 @@ namespace Avalonia.Rendering
using (context.PushTransformContainer())
{
var info = new RenderPassInfo();
Render(context, _root, _root.Bounds, scaling, info);
_lastRenderPassInfo = info;
Render(context, _root, _root.Bounds);
}
if (DrawDirtyRects)
@ -85,10 +78,12 @@ namespace Avalonia.Rendering
}
catch (RenderTargetCorruptedException ex)
{
Logging.Logger.Information("Renderer", this, "Render target was corrupted. Exception: {0}", ex);
Logger.TryGet(LogEventLevel.Information, LogArea.Animations)?.Log(this, "Render target was corrupted. Exception: {0}", ex);
_renderTarget.Dispose();
_renderTarget = null;
}
SceneInvalidated?.Invoke(this, new SceneInvalidatedEventArgs((IRenderRoot)_root, rect));
}
/// <inheritdoc/>
@ -103,10 +98,10 @@ namespace Avalonia.Rendering
/// <param name="target">The render target.</param>
public static void Render(IVisual visual, IRenderTarget target)
{
using (var renderer = new ImmediateRenderer(visual, null))
using (var renderer = new ImmediateRenderer(visual))
using (var context = new DrawingContext(target.CreateDrawingContext(renderer)))
{
renderer.Render(context, visual, visual.Bounds, 1);
renderer.Render(context, visual, visual.Bounds);
}
}
@ -115,11 +110,11 @@ namespace Avalonia.Rendering
/// </summary>
/// <param name="visual">The visual.</param>
/// <param name="context">The drawing context.</param>
public static void Render(IVisual visual, DrawingContext context, double scaling = 1)
public static void Render(IVisual visual, DrawingContext context)
{
using (var renderer = new ImmediateRenderer(visual, null))
using (var renderer = new ImmediateRenderer(visual))
{
renderer.Render(context, visual, visual.Bounds, scaling);
renderer.Render(context, visual, visual.Bounds);
}
}
@ -166,16 +161,22 @@ namespace Avalonia.Rendering
return HitTest(root, p, filter);
}
public IVisual HitTestFirst(Point p, IVisual root, Func<IVisual, bool> filter)
{
return HitTest(root, p, filter).FirstOrDefault();
}
/// <inheritdoc/>
public void RecalculateChildren(IVisual visual) => AddDirty(visual);
/// <inheritdoc/>
public void Start()
{
_loop?.Add(this);
}
/// <inheritdoc/>
public void Stop()
{
_loop?.Remove(this);
}
/// <inheritdoc/>
@ -189,7 +190,7 @@ namespace Avalonia.Rendering
void IVisualBrushRenderer.RenderVisualBrush(IDrawingContextImpl context, IVisualBrush brush)
{
var visual = brush.Visual;
Render(new DrawingContext(context), visual, visual.Bounds, 1);
Render(new DrawingContext(context), visual, visual.Bounds);
}
private static void ClearTransformedBounds(IVisual visual)
@ -253,14 +254,7 @@ namespace Avalonia.Rendering
}
}
class RenderPassInfo
{
public List<IRenderTimeCriticalVisual> RenderTimeCriticalVisuals { get; } =
new List<IRenderTimeCriticalVisual>();
}
private void Render(DrawingContext context, IVisual visual, Rect clipRect,
double scaling, RenderPassInfo info = null)
private void Render(DrawingContext context, IVisual visual, Rect clipRect)
{
var opacity = visual.Opacity;
var clipToBounds = visual.ClipToBounds;
@ -295,16 +289,15 @@ namespace Avalonia.Rendering
using (context.PushPostTransform(m))
using (context.PushOpacity(opacity))
using (clipToBounds ? context.PushClip(bounds) : default(DrawingContext.PushedState))
using (clipToBounds
? visual is IVisualWithRoundRectClip roundClipVisual
? context.PushClip(new RoundedRect(bounds, roundClipVisual.ClipToBoundsRadius))
: context.PushClip(bounds)
: default(DrawingContext.PushedState))
using (visual.Clip != null ? context.PushGeometryClip(visual.Clip) : default(DrawingContext.PushedState))
using (visual.OpacityMask != null ? context.PushOpacityMask(visual.OpacityMask, bounds) : default(DrawingContext.PushedState))
using (context.PushTransformContainer())
{
if (visual is IRenderTimeCriticalVisual critical && critical.HasRenderTimeCriticalContent)
{
critical.ThreadSafeRender(context, bounds.Size, scaling);
info?.RenderTimeCriticalVisuals.Add(critical);
}
visual.Render(context);
#pragma warning disable 0618
@ -323,7 +316,7 @@ namespace Avalonia.Rendering
var childClipRect = child.RenderTransform == null
? clipRect.Translate(-childBounds.Position)
: clipRect;
Render(context, child, childClipRect, scaling, info);
Render(context, child, childClipRect);
}
else
{
@ -338,11 +331,5 @@ namespace Avalonia.Rendering
ClearTransformedBounds(visual);
}
}
public bool NeedsUpdate => _lastRenderPassInfo?.RenderTimeCriticalVisuals.Any(v => v.ThreadSafeHasNewFrame) == true;
public void Update(TimeSpan time) => _root.InvalidateVisual();
public void Render()
{
}
}
}

10
src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs

@ -208,8 +208,7 @@ namespace Avalonia.Rendering.SceneGraph
node.ClipBounds = clipBounds;
node.ClipToBounds = clipToBounds;
node.LayoutBounds = globalBounds;
node.ClipToBoundsRadius = clipToBoundsRadius;
node.VisualSize = visual.Bounds.Size;
node.ClipToBoundsRadius = clipToBoundsRadius;
node.GeometryClip = visual.Clip?.PlatformImpl;
node.Opacity = opacity;
@ -396,10 +395,11 @@ namespace Avalonia.Rendering.SceneGraph
PropagateLayer(child, layer, oldLayer);
}
}
}
// HACK: Disabled layers because they're broken in current renderer. See #2244.
private static bool ShouldStartLayer(IVisual visual) => false;
private static bool ShouldStartLayer(IVisual visual) => false;
private static IGeometryImpl CreateLayerGeometryClip(VisualNode node)
{
IGeometryImpl result = null;

20
src/Avalonia.Visuals/Visual.cs

@ -90,18 +90,10 @@ namespace Avalonia
public static readonly StyledProperty<int> ZIndexProperty =
AvaloniaProperty.Register<Visual, int>(nameof(ZIndex));
/// <summary>
/// Defines the <see cref="WantsLayer"/> property.
/// </summary>
public static readonly DirectProperty<Visual, bool> WantsLayerProperty =
AvaloniaProperty.RegisterDirect<Visual, bool>("WantsLayer", o => o._wantsLayer,
(o, v) => o._wantsLayer = v);
private Rect _bounds;
private TransformedBounds? _transformedBounds;
private IRenderRoot _visualRoot;
private IVisual _visualParent;
private bool _wantsLayer;
/// <summary>
/// Initializes static members of the <see cref="Visual"/> class.
@ -113,8 +105,7 @@ namespace Avalonia
ClipProperty,
ClipToBoundsProperty,
IsVisibleProperty,
OpacityProperty,
WantsLayerProperty);
OpacityProperty);
RenderTransformProperty.Changed.Subscribe(RenderTransformChanged);
ZIndexProperty.Changed.Subscribe(ZIndexChanged);
}
@ -267,15 +258,6 @@ namespace Avalonia
private set;
}
/// <summary>
/// Allows to explicitly force a rendering layer for a particular visual. Use with caution.
/// </summary>
public bool WantsLayer
{
get => GetValue(WantsLayerProperty);
set => SetValue(WantsLayerProperty, value);
}
/// <summary>
/// Gets the root of the visual tree, if the control is attached to a visual tree.
/// </summary>

6
src/Avalonia.Visuals/VisualTree/IVisual.cs

@ -113,11 +113,5 @@ namespace Avalonia.VisualTree
/// </summary>
/// <param name="context">The context.</param>
void Render(DrawingContext context);
/// <summary>
/// Allows to explicitly force a rendering layer for a particular visual. Use with caution.
/// </summary>
bool WantsLayer { get; }
}
}

Loading…
Cancel
Save