Browse Source

Fixed a few things.

- We don't need ConcurrentQueue in renderer
- DirtyRects coalescing was wrong
- Display number of updated rects for debug until we have dirty rect
rendering
- Animate 2 items at once in RenderTest
scenegraph-after-breakage
Steven Kirk 10 years ago
parent
commit
c9752d32d8
  1. 2
      samples/RenderTest/MainWindow.xaml.cs
  2. 45
      src/Avalonia.Visuals/Rendering/DeferredRenderer.cs
  3. 15
      src/Avalonia.Visuals/Rendering/DirtyRects.cs
  4. 7
      src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs

2
samples/RenderTest/MainWindow.xaml.cs

@ -67,7 +67,7 @@ namespace RenderTest
};
var start = Animate.Stopwatch.Elapsed;
var index = i;
var index = i % (Count / 2);
var degrees = Animate.Timer
.Select(x => (x - start).TotalSeconds)
.Where(x => (x % Count) >= index && (x % Count) < index + 1)

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

@ -17,7 +17,7 @@ namespace Avalonia.Rendering
private Scene _scene;
private IRenderTarget _renderTarget;
private List<IVisual> _dirty = new List<IVisual>();
private ConcurrentQueue<Rect> _renderQueue = new ConcurrentQueue<Rect>();
private DirtyRects _dirtyRects;
private bool _needsUpdate;
private bool _updateQueued;
private bool _rendering;
@ -99,7 +99,7 @@ namespace Avalonia.Rendering
}
}
private void RenderFps(IDrawingContextImpl context)
private void RenderFps(IDrawingContextImpl context, int count)
{
var now = _stopwatch.Elapsed;
var elapsed = now - _lastFpsUpdate;
@ -115,7 +115,7 @@ namespace Avalonia.Rendering
var pt = new Point(40, 40);
using (
var txt = new FormattedText("Frame #" + _totalFrames + " FPS: " + _fps, "Arial", 18,
var txt = new FormattedText($"Frame #{_totalFrames} FPS: {_fps} Updates: {count}", "Arial", 18,
FontStyle.Normal,
TextAlignment.Left,
FontWeight.Normal,
@ -134,31 +134,30 @@ namespace Avalonia.Rendering
try
{
var scene = _scene.Clone();
var dirtyRects = new DirtyRects();
if (_dirty.Count > 0)
{
var dirtyRects = new DirtyRects();
foreach (var visual in _dirty)
{
SceneBuilder.Update(scene, visual, dirtyRects);
}
foreach (var r in dirtyRects.Coalesce())
{
_renderQueue.Enqueue(r);
}
_dirty.Clear();
dirtyRects.Coalesce();
}
else
{
SceneBuilder.UpdateAll(scene);
_renderQueue.Enqueue(new Rect(_root.ClientSize));
dirtyRects.Add(new Rect(_root.ClientSize));
}
_scene = scene;
lock (_scene)
{
_scene = scene;
_dirtyRects = dirtyRects;
}
_dirty.Clear();
_needsUpdate = false;
_root.Invalidate(new Rect(_root.ClientSize));
}
@ -183,7 +182,16 @@ namespace Avalonia.Rendering
_rendering = true;
if (!_renderQueue.IsEmpty)
Scene scene;
DirtyRects dirtyRects;
lock (_scene)
{
scene = _scene;
dirtyRects = _dirtyRects;
}
if (dirtyRects != null)
{
if (_renderTarget == null)
{
@ -194,20 +202,21 @@ namespace Avalonia.Rendering
{
_totalFrames++;
int count = 0;
using (var context = _renderTarget.CreateDrawingContext())
{
Rect rect;
while (_renderQueue.TryDequeue(out rect))
foreach (var rect in dirtyRects)
{
context.PushClip(rect);
Render(context, _scene.Root, rect);
context.PopClip();
++count;
}
if (DrawFps)
{
RenderFps(context);
RenderFps(context, count);
}
}
}

15
src/Avalonia.Visuals/Rendering/DirtyRects.cs

@ -7,7 +7,7 @@ using System.Collections.Generic;
namespace Avalonia.Rendering
{
public class DirtyRects
public class DirtyRects : IEnumerable<Rect>
{
private List<Rect> _rects = new List<Rect>();
@ -17,11 +17,11 @@ namespace Avalonia.Rendering
{
for (var i = 0; i < _rects.Count; ++i)
{
var union = _rects[i].Union(rect);
var r = _rects[i].Inflate(1);
if (union != Rect.Empty)
if (r.Intersects(rect))
{
_rects[i] = union;
_rects[i] = r.Union(rect);
return;
}
}
@ -30,7 +30,7 @@ namespace Avalonia.Rendering
}
}
public IList<Rect> Coalesce()
public void Coalesce()
{
for (var i = _rects.Count - 1; i >= 0; --i)
{
@ -47,8 +47,9 @@ namespace Avalonia.Rendering
}
}
}
return _rects;
}
public IEnumerator<Rect> GetEnumerator() => _rects.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => _rects.GetEnumerator();
}
}

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

@ -183,13 +183,6 @@ namespace Avalonia.Rendering.SceneGraph
return node;
}
private static IList<Rect> Deindex(Scene scene, VisualNode node)
{
var dirty = new DirtyRects();
Deindex(scene, node, dirty);
return dirty.Coalesce();
}
private static void Deindex(Scene scene, VisualNode node, DirtyRects dirty)
{
scene.Remove(node);

Loading…
Cancel
Save