Browse Source

Merge pull request #1106 from AvaloniaUI/fixes/1096-popup-scene-not-updating

Clear scene for invisible root visuals.
pull/1124/head
Steven Kirk 9 years ago
committed by GitHub
parent
commit
67959eedf7
  1. 42
      src/Avalonia.Visuals/Rendering/DeferredRenderer.cs
  2. 6
      src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs
  3. 27
      tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests_Layers.cs

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

@ -11,6 +11,7 @@ using System.Collections.Generic;
using System.IO;
using Avalonia.Media.Immutable;
using System.Threading;
using System.Linq;
namespace Avalonia.Rendering
{
@ -58,7 +59,6 @@ namespace Avalonia.Rendering
_dispatcher = dispatcher ?? Dispatcher.UIThread;
_root = root;
_sceneBuilder = sceneBuilder ?? new SceneBuilder();
_scene = new Scene(root);
_layerFactory = layerFactory ?? new DefaultRenderLayerFactory();
_layers = new RenderLayers(_layerFactory);
_renderLoop = renderLoop;
@ -86,7 +86,6 @@ namespace Avalonia.Rendering
_root = root;
_renderTarget = renderTarget;
_sceneBuilder = sceneBuilder ?? new SceneBuilder();
_scene = new Scene(root);
_layerFactory = layerFactory ?? new DefaultRenderLayerFactory();
_layers = new RenderLayers(_layerFactory);
}
@ -122,7 +121,7 @@ namespace Avalonia.Rendering
UpdateScene();
}
return _scene.HitTest(p, filter);
return _scene?.HitTest(p, filter) ?? Enumerable.Empty<IVisual>();
}
/// <inheritdoc/>
@ -186,7 +185,7 @@ namespace Avalonia.Rendering
_dirtyRectsDisplay.Tick();
}
if (scene.Size != Size.Empty)
if (scene != null && scene.Size != Size.Empty)
{
if (scene.Generation != _lastSceneId)
{
@ -366,25 +365,32 @@ namespace Avalonia.Rendering
try
{
var scene = _scene.Clone();
if (_dirty == null)
{
_dirty = new DirtyVisuals();
_sceneBuilder.UpdateAll(scene);
}
else if (_dirty.Count > 0)
if (_root.IsVisible)
{
foreach (var visual in _dirty)
var scene = _scene?.Clone() ?? new Scene(_root);
if (_dirty == null)
{
_sceneBuilder.Update(scene, visual);
_dirty = new DirtyVisuals();
_sceneBuilder.UpdateAll(scene);
}
else if (_dirty.Count > 0)
{
foreach (var visual in _dirty)
{
_sceneBuilder.Update(scene, visual);
}
}
}
Interlocked.Exchange(ref _scene, scene);
Interlocked.Exchange(ref _scene, scene);
_dirty.Clear();
(_root as IRenderRoot)?.Invalidate(new Rect(scene.Size));
_dirty.Clear();
(_root as IRenderRoot)?.Invalidate(new Rect(scene.Size));
}
else
{
Interlocked.Exchange(ref _scene, null);
}
}
finally
{

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

@ -36,8 +36,14 @@ namespace Avalonia.Rendering.SceneGraph
{
Contract.Requires<ArgumentNullException>(scene != null);
Contract.Requires<ArgumentNullException>(visual != null);
Dispatcher.UIThread.VerifyAccess();
if (!scene.Root.Visual.IsVisible)
{
throw new AvaloniaInternalException("Cannot update the scene for an invisible root visual.");
}
var node = (VisualNode)scene.FindNode(visual);
if (visual == scene.Root.Visual)

27
tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests_Layers.cs

@ -273,32 +273,5 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
((MockStreamGeometryImpl)borderLayer.GeometryClip).Transform);
}
}
[Fact]
public void Hiding_Root_Should_Not_Remove_Root_Layer()
{
using (TestApplication())
{
Border border;
var tree = new TestRoot
{
Child = border = new Border()
};
var layout = AvaloniaLocator.Current.GetService<ILayoutManager>();
layout.ExecuteInitialLayoutPass(tree);
var scene = new Scene(tree);
var sceneBuilder = new SceneBuilder();
sceneBuilder.UpdateAll(scene);
tree.IsVisible = false;
scene = scene.Clone();
sceneBuilder.Update(scene, tree);
Assert.Equal(1, scene.Layers.Count);
}
}
}
}

Loading…
Cancel
Save