Browse Source

More work on deferred renderer.

Getting opacity layers working.
scenegraph-after-breakage
Steven Kirk 10 years ago
parent
commit
97ea14d58c
  1. 2
      src/Avalonia.Visuals/Rendering/DisplayDirtyRect.cs
  2. 2
      src/Avalonia.Visuals/Rendering/RenderLayers.cs
  3. 25
      src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs
  4. 7
      src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs
  5. 10
      tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs

2
src/Avalonia.Visuals/Rendering/DisplayDirtyRect.cs

@ -4,7 +4,7 @@ namespace Avalonia.Rendering
{
public class DisplayDirtyRect
{
public static readonly TimeSpan TimeToLive = TimeSpan.FromMilliseconds(500);
public static readonly TimeSpan TimeToLive = TimeSpan.FromMilliseconds(250);
public DisplayDirtyRect(Rect rect)
{

2
src/Avalonia.Visuals/Rendering/RenderLayers.cs

@ -47,7 +47,7 @@ namespace Avalonia.Rendering
var layer = _inner[i];
var node = (VisualNode)scene.FindNode(layer.LayerRoot);
if (node == null || node.LayerRoot != layer.LayerRoot)
if (node == null || node.LayerRoot.VisualRoot == null || node.LayerRoot != layer.LayerRoot)
{
layer.Bitmap.Dispose();
_inner.RemoveAt(i);

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

@ -154,11 +154,11 @@ namespace Avalonia.Rendering.SceneGraph
node.Opacity = opacity;
node.OpacityMask = visual.OpacityMask;
if (opacity < 1)
if (opacity < 1 && node.LayerRoot != visual)
{
SetLayer(node, node.Visual);
SetLayer(node, node.Visual, contextImpl.Dirty);
}
else if (node.LayerRoot == node.Visual && node.Parent != null)
else if (opacity >= 1 && node.LayerRoot == node.Visual && node.Parent != null)
{
ClearLayer(node, contextImpl.Dirty);
}
@ -185,10 +185,6 @@ namespace Avalonia.Rendering.SceneGraph
node.SubTreeUpdated = true;
contextImpl.TrimChildren();
}
else if (node.OpacityChanged)
{
AddSubtreeBounds(node, contextImpl.Dirty);
}
}
}
}
@ -251,19 +247,28 @@ namespace Avalonia.Rendering.SceneGraph
dirty.Remove(node.LayerRoot);
SetLayer(node, newLayerRoot);
SetLayer(node, newLayerRoot, dirty);
}
private static void SetLayer(VisualNode node, IVisual layerRoot)
private static void SetLayer(VisualNode node, IVisual layerRoot, LayerDirtyRects dirty)
{
if (node.LayerRoot == layerRoot)
{
throw new AvaloniaInternalException("Called SetLayer with unchanged LayerRoot.");
}
var oldLayerRoot = node.LayerRoot;
node.LayerRoot = layerRoot;
dirty.Add(oldLayerRoot, node.Bounds);
dirty.Add(layerRoot, node.Bounds);
foreach (VisualNode child in node.Children)
{
// If the child is not the start of a new layer, recurse.
if (child.LayerRoot != child.Visual)
{
SetLayer(child, layerRoot);
SetLayer(child, layerRoot, dirty);
}
}
}

7
src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs

@ -220,12 +220,13 @@ namespace Avalonia.Rendering.SceneGraph
/// <inheritdoc/>
public void BeginRender(IDrawingContextImpl context)
{
context.Transform = Transform;
if (ClipToBounds)
{
context.PushClip(ClipBounds * Transform.Invert());
context.Transform = Matrix.Identity;
context.PushClip(ClipBounds);
}
context.Transform = Transform;
}
/// <inheritdoc/>

10
tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs

@ -571,9 +571,13 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
Assert.Same(tree, borderNode.LayerRoot);
Assert.Same(tree, canvasNode.LayerRoot);
Assert.Equal(1, dirty.Count());
Assert.Equal(tree, dirty.Single().Key);
Assert.Equal(new Rect(21, 21, 58, 78), dirty.Single().Value.Single());
var rootDirty = dirty[tree];
var borderDirty = dirty[border];
Assert.Equal(1, rootDirty.Count());
Assert.Equal(1, borderDirty.Count());
Assert.Equal(new Rect(21, 21, 58, 78), rootDirty.Single());
Assert.Equal(new Rect(21, 21, 58, 78), borderDirty.Single());
}
}

Loading…
Cancel
Save