Browse Source

Removed IRenderLayerFactory

And use `IDrawingContextImpl.CreateLayer` instead.
pull/1184/head
Steven Kirk 9 years ago
parent
commit
bb5a7f0cd3
  1. 34
      src/Avalonia.Visuals/Rendering/DefaultRenderLayerFactory.cs
  2. 153
      src/Avalonia.Visuals/Rendering/DeferredRenderer.cs
  3. 11
      src/Avalonia.Visuals/Rendering/IRenderLayerFactory.cs
  4. 10
      src/Avalonia.Visuals/Rendering/RenderLayer.cs
  5. 9
      src/Avalonia.Visuals/Rendering/RenderLayers.cs
  6. 220
      tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests.cs

34
src/Avalonia.Visuals/Rendering/DefaultRenderLayerFactory.cs

@ -1,34 +0,0 @@
using System;
using Avalonia.Platform;
using Avalonia.VisualTree;
namespace Avalonia.Rendering
{
public class DefaultRenderLayerFactory : IRenderLayerFactory
{
private IPlatformRenderInterface _renderInterface;
public DefaultRenderLayerFactory()
: this(AvaloniaLocator.Current.GetService<IPlatformRenderInterface>())
{
}
public DefaultRenderLayerFactory(IPlatformRenderInterface renderInterface)
{
_renderInterface = renderInterface;
}
public IRenderTargetBitmapImpl CreateLayer(
IVisual layerRoot,
Size size,
double dpiX,
double dpiY)
{
return _renderInterface.CreateRenderTargetBitmap(
(int)Math.Ceiling(size.Width),
(int)Math.Ceiling(size.Height),
dpiX,
dpiY);
}
}
}

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

@ -26,7 +26,6 @@ namespace Avalonia.Rendering
private readonly IVisual _root; private readonly IVisual _root;
private readonly ISceneBuilder _sceneBuilder; private readonly ISceneBuilder _sceneBuilder;
private readonly RenderLayers _layers; private readonly RenderLayers _layers;
private readonly IRenderLayerFactory _layerFactory;
private bool _running; private bool _running;
private Scene _scene; private Scene _scene;
@ -45,13 +44,11 @@ namespace Avalonia.Rendering
/// <param name="root">The control to render.</param> /// <param name="root">The control to render.</param>
/// <param name="renderLoop">The render loop.</param> /// <param name="renderLoop">The render loop.</param>
/// <param name="sceneBuilder">The scene builder to use. Optional.</param> /// <param name="sceneBuilder">The scene builder to use. Optional.</param>
/// <param name="layerFactory">The layer factory to use. Optional.</param>
/// <param name="dispatcher">The dispatcher to use. Optional.</param> /// <param name="dispatcher">The dispatcher to use. Optional.</param>
public DeferredRenderer( public DeferredRenderer(
IRenderRoot root, IRenderRoot root,
IRenderLoop renderLoop, IRenderLoop renderLoop,
ISceneBuilder sceneBuilder = null, ISceneBuilder sceneBuilder = null,
IRenderLayerFactory layerFactory = null,
IDispatcher dispatcher = null) IDispatcher dispatcher = null)
{ {
Contract.Requires<ArgumentNullException>(root != null); Contract.Requires<ArgumentNullException>(root != null);
@ -59,8 +56,7 @@ namespace Avalonia.Rendering
_dispatcher = dispatcher ?? Dispatcher.UIThread; _dispatcher = dispatcher ?? Dispatcher.UIThread;
_root = root; _root = root;
_sceneBuilder = sceneBuilder ?? new SceneBuilder(); _sceneBuilder = sceneBuilder ?? new SceneBuilder();
_layerFactory = layerFactory ?? new DefaultRenderLayerFactory(); _layers = new RenderLayers();
_layers = new RenderLayers(_layerFactory);
_renderLoop = renderLoop; _renderLoop = renderLoop;
} }
@ -70,15 +66,13 @@ namespace Avalonia.Rendering
/// <param name="root">The control to render.</param> /// <param name="root">The control to render.</param>
/// <param name="renderTarget">The render target.</param> /// <param name="renderTarget">The render target.</param>
/// <param name="sceneBuilder">The scene builder to use. Optional.</param> /// <param name="sceneBuilder">The scene builder to use. Optional.</param>
/// <param name="layerFactory">The layer factory to use. Optional.</param>
/// <remarks> /// <remarks>
/// This constructor is intended to be used for unit testing. /// This constructor is intended to be used for unit testing.
/// </remarks> /// </remarks>
public DeferredRenderer( public DeferredRenderer(
IVisual root, IVisual root,
IRenderTarget renderTarget, IRenderTarget renderTarget,
ISceneBuilder sceneBuilder = null, ISceneBuilder sceneBuilder = null)
IRenderLayerFactory layerFactory = null)
{ {
Contract.Requires<ArgumentNullException>(root != null); Contract.Requires<ArgumentNullException>(root != null);
Contract.Requires<ArgumentNullException>(renderTarget != null); Contract.Requires<ArgumentNullException>(renderTarget != null);
@ -86,8 +80,7 @@ namespace Avalonia.Rendering
_root = root; _root = root;
_renderTarget = renderTarget; _renderTarget = renderTarget;
_sceneBuilder = sceneBuilder ?? new SceneBuilder(); _sceneBuilder = sceneBuilder ?? new SceneBuilder();
_layerFactory = layerFactory ?? new DefaultRenderLayerFactory(); _layers = new RenderLayers();
_layers = new RenderLayers(_layerFactory);
} }
/// <inheritdoc/> /// <inheritdoc/>
@ -180,38 +173,56 @@ namespace Avalonia.Rendering
bool renderOverlay = DrawDirtyRects || DrawFps; bool renderOverlay = DrawDirtyRects || DrawFps;
bool composite = false; bool composite = false;
if (_renderTarget == null)
{
_renderTarget = ((IRenderRoot)_root).CreateRenderTarget();
}
if (renderOverlay) if (renderOverlay)
{ {
_dirtyRectsDisplay.Tick(); _dirtyRectsDisplay.Tick();
} }
if (scene != null && scene.Size != Size.Empty) try
{ {
if (scene.Generation != _lastSceneId) using (var context = _renderTarget.CreateDrawingContext(this))
{ {
_layers.Update(scene); if (scene != null && scene.Size != Size.Empty)
RenderToLayers(scene);
if (DebugFramesPath != null)
{ {
SaveDebugFrames(scene.Generation); if (scene.Generation != _lastSceneId)
} {
_layers.Update(scene, context);
_lastSceneId = scene.Generation; RenderToLayers(scene);
composite = true; if (DebugFramesPath != null)
} {
SaveDebugFrames(scene.Generation);
}
if (renderOverlay) _lastSceneId = scene.Generation;
{
RenderOverlay(scene); composite = true;
RenderComposite(scene); }
}
else if(composite) if (renderOverlay)
{ {
RenderComposite(scene); RenderOverlay(scene, context);
RenderComposite(scene, context);
}
else if (composite)
{
RenderComposite(scene, context);
}
}
} }
} }
catch (RenderTargetCorruptedException ex)
{
Logging.Logger.Information("Renderer", this, "Render target was corrupted. Exception: {0}", ex);
_renderTarget?.Dispose();
_renderTarget = null;
}
} }
private void Render(IDrawingContextImpl context, VisualNode node, IVisual layer, Rect clipBounds) private void Render(IDrawingContextImpl context, VisualNode node, IVisual layer, Rect clipBounds)
@ -273,11 +284,11 @@ namespace Avalonia.Rendering
} }
} }
private void RenderOverlay(Scene scene) private void RenderOverlay(Scene scene, IDrawingContextImpl parentContent)
{ {
if (DrawDirtyRects) if (DrawDirtyRects)
{ {
var overlay = GetOverlay(scene.Size, scene.Scaling); var overlay = GetOverlay(parentContent, scene.Size, scene.Scaling);
using (var context = overlay.CreateDrawingContext(this)) using (var context = overlay.CreateDrawingContext(this))
{ {
@ -301,61 +312,44 @@ namespace Avalonia.Rendering
} }
} }
private void RenderComposite(Scene scene) private void RenderComposite(Scene scene, IDrawingContextImpl context)
{ {
try var clientRect = new Rect(scene.Size);
foreach (var layer in scene.Layers)
{ {
if (_renderTarget == null) var bitmap = _layers[layer.LayerRoot].Bitmap;
var sourceRect = new Rect(0, 0, bitmap.PixelWidth, bitmap.PixelHeight);
if (layer.GeometryClip != null)
{ {
_renderTarget = ((IRenderRoot)_root).CreateRenderTarget(); context.PushGeometryClip(layer.GeometryClip);
} }
using (var context = _renderTarget.CreateDrawingContext(this)) if (layer.OpacityMask == null)
{ {
var clientRect = new Rect(scene.Size); context.DrawImage(bitmap, layer.Opacity, sourceRect, clientRect);
}
foreach (var layer in scene.Layers) else
{ {
var bitmap = _layers[layer.LayerRoot].Bitmap; context.DrawImage(bitmap, layer.OpacityMask, layer.OpacityMaskRect, sourceRect);
var sourceRect = new Rect(0, 0, bitmap.PixelWidth, bitmap.PixelHeight); }
if (layer.GeometryClip != null)
{
context.PushGeometryClip(layer.GeometryClip);
}
if (layer.OpacityMask == null)
{
context.DrawImage(bitmap, layer.Opacity, sourceRect, clientRect);
}
else
{
context.DrawImage(bitmap, layer.OpacityMask, layer.OpacityMaskRect, sourceRect);
}
if (layer.GeometryClip != null)
{
context.PopGeometryClip();
}
}
if (_overlay != null)
{
var sourceRect = new Rect(0, 0, _overlay.PixelWidth, _overlay.PixelHeight);
context.DrawImage(_overlay, 0.5, sourceRect, clientRect);
}
if (DrawFps) if (layer.GeometryClip != null)
{ {
RenderFps(context, clientRect, true); context.PopGeometryClip();
}
} }
} }
catch (RenderTargetCorruptedException ex)
if (_overlay != null)
{ {
Logging.Logger.Information("Renderer", this, "Render target was corrupted. Exception: {0}", ex); var sourceRect = new Rect(0, 0, _overlay.PixelWidth, _overlay.PixelHeight);
_renderTarget?.Dispose(); context.DrawImage(_overlay, 0.5, sourceRect, clientRect);
_renderTarget = null; }
if (DrawFps)
{
RenderFps(context, clientRect, true);
} }
} }
@ -422,7 +416,10 @@ namespace Avalonia.Rendering
} }
} }
private IRenderTargetBitmapImpl GetOverlay(Size size, double scaling) private IRenderTargetBitmapImpl GetOverlay(
IDrawingContextImpl parentContext,
Size size,
double scaling)
{ {
size = new Size(size.Width * scaling, size.Height * scaling); size = new Size(size.Width * scaling, size.Height * scaling);
@ -431,7 +428,7 @@ namespace Avalonia.Rendering
_overlay.PixelHeight != size.Height) _overlay.PixelHeight != size.Height)
{ {
_overlay?.Dispose(); _overlay?.Dispose();
_overlay = _layerFactory.CreateLayer(null, size, 96 * scaling, 96 * scaling); _overlay = parentContext.CreateLayer(size);
} }
return _overlay; return _overlay;

11
src/Avalonia.Visuals/Rendering/IRenderLayerFactory.cs

@ -1,11 +0,0 @@
using System;
using Avalonia.Platform;
using Avalonia.VisualTree;
namespace Avalonia.Rendering
{
public interface IRenderLayerFactory
{
IRenderTargetBitmapImpl CreateLayer(IVisual layerRoot, Size size, double dpiX, double dpiY);
}
}

10
src/Avalonia.Visuals/Rendering/RenderLayer.cs

@ -7,16 +7,16 @@ namespace Avalonia.Rendering
{ {
public class RenderLayer public class RenderLayer
{ {
private readonly IRenderLayerFactory _factory; private readonly IDrawingContextImpl _drawingContext;
public RenderLayer( public RenderLayer(
IRenderLayerFactory factory, IDrawingContextImpl drawingContext,
Size size, Size size,
double scaling, double scaling,
IVisual layerRoot) IVisual layerRoot)
{ {
_factory = factory; _drawingContext = drawingContext;
Bitmap = factory.CreateLayer(layerRoot, size * scaling, 96 * scaling, 96 * scaling); Bitmap = drawingContext.CreateLayer(size);
Size = size; Size = size;
Scaling = scaling; Scaling = scaling;
LayerRoot = layerRoot; LayerRoot = layerRoot;
@ -31,7 +31,7 @@ namespace Avalonia.Rendering
{ {
if (Size != size || Scaling != scaling) if (Size != size || Scaling != scaling)
{ {
var resized = _factory.CreateLayer(LayerRoot, size * scaling, 96 * scaling, 96 * scaling); var resized = _drawingContext.CreateLayer(size);
using (var context = resized.CreateDrawingContext(null)) using (var context = resized.CreateDrawingContext(null))
{ {

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

@ -1,6 +1,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using Avalonia.Platform;
using Avalonia.Rendering.SceneGraph; using Avalonia.Rendering.SceneGraph;
using Avalonia.VisualTree; using Avalonia.VisualTree;
@ -8,19 +9,17 @@ namespace Avalonia.Rendering
{ {
public class RenderLayers : IEnumerable<RenderLayer> public class RenderLayers : IEnumerable<RenderLayer>
{ {
private readonly IRenderLayerFactory _factory;
private List<RenderLayer> _inner = new List<RenderLayer>(); private List<RenderLayer> _inner = new List<RenderLayer>();
private Dictionary<IVisual, RenderLayer> _index = new Dictionary<IVisual, RenderLayer>(); private Dictionary<IVisual, RenderLayer> _index = new Dictionary<IVisual, RenderLayer>();
public RenderLayers(IRenderLayerFactory factory) public RenderLayers()
{ {
_factory = factory;
} }
public int Count => _inner.Count; public int Count => _inner.Count;
public RenderLayer this[IVisual layerRoot] => _index[layerRoot]; public RenderLayer this[IVisual layerRoot] => _index[layerRoot];
public void Update(Scene scene) public void Update(Scene scene, IDrawingContextImpl context)
{ {
for (var i = scene.Layers.Count - 1; i >= 0; --i) for (var i = scene.Layers.Count - 1; i >= 0; --i)
{ {
@ -29,7 +28,7 @@ namespace Avalonia.Rendering
if (!_index.TryGetValue(src.LayerRoot, out layer)) if (!_index.TryGetValue(src.LayerRoot, out layer))
{ {
layer = new RenderLayer(_factory, scene.Size, scene.Scaling, src.LayerRoot); layer = new RenderLayer(context, scene.Size, scene.Scaling, src.LayerRoot);
_inner.Add(layer); _inner.Add(layer);
_index.Add(src.LayerRoot, layer); _index.Add(src.LayerRoot, layer);
} }

220
tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests.cs

@ -30,7 +30,6 @@ namespace Avalonia.Visuals.UnitTests.Rendering
root, root,
loop.Object, loop.Object,
sceneBuilder: MockSceneBuilder(root).Object, sceneBuilder: MockSceneBuilder(root).Object,
layerFactory: MockLayerFactory(root).Object,
dispatcher: dispatcher.Object); dispatcher: dispatcher.Object);
target.Start(); target.Start();
@ -55,7 +54,6 @@ namespace Avalonia.Visuals.UnitTests.Rendering
root, root,
loop.Object, loop.Object,
sceneBuilder: sceneBuilder.Object, sceneBuilder: sceneBuilder.Object,
layerFactory: MockLayerFactory(root).Object,
dispatcher: dispatcher); dispatcher: dispatcher);
target.Start(); target.Start();
@ -75,7 +73,6 @@ namespace Avalonia.Visuals.UnitTests.Rendering
root, root,
loop.Object, loop.Object,
sceneBuilder: sceneBuilder.Object, sceneBuilder: sceneBuilder.Object,
layerFactory: MockLayerFactory(root).Object,
dispatcher: dispatcher); dispatcher: dispatcher);
target.Start(); target.Start();
@ -111,7 +108,6 @@ namespace Avalonia.Visuals.UnitTests.Rendering
root, root,
loop.Object, loop.Object,
sceneBuilder: sceneBuilder.Object, sceneBuilder: sceneBuilder.Object,
layerFactory: MockLayerFactory(root).Object,
dispatcher: dispatcher); dispatcher: dispatcher);
target.Start(); target.Start();
@ -133,100 +129,102 @@ namespace Avalonia.Visuals.UnitTests.Rendering
[Fact] [Fact]
public void Frame_Should_Create_Layer_For_Root() public void Frame_Should_Create_Layer_For_Root()
{ {
var loop = new Mock<IRenderLoop>(); throw new NotImplementedException();
var root = new TestRoot(); //var loop = new Mock<IRenderLoop>();
var rootLayer = new Mock<IRenderTargetBitmapImpl>(); //var root = new TestRoot();
var dispatcher = new ImmediateDispatcher(); //var rootLayer = new Mock<IRenderTargetBitmapImpl>();
//var dispatcher = new ImmediateDispatcher();
var sceneBuilder = new Mock<ISceneBuilder>();
sceneBuilder.Setup(x => x.UpdateAll(It.IsAny<Scene>())) //var sceneBuilder = new Mock<ISceneBuilder>();
.Callback<Scene>(scene => //sceneBuilder.Setup(x => x.UpdateAll(It.IsAny<Scene>()))
{ // .Callback<Scene>(scene =>
scene.Size = root.ClientSize; // {
scene.Layers.Add(root).Dirty.Add(new Rect(root.ClientSize)); // scene.Size = root.ClientSize;
}); // scene.Layers.Add(root).Dirty.Add(new Rect(root.ClientSize));
// });
var layers = new Mock<IRenderLayerFactory>();
layers.Setup(x => x.CreateLayer(root, root.ClientSize, 96, 96)).Returns(CreateLayer()); //var layers = new Mock<IRenderLayerFactory>();
//layers.Setup(x => x.CreateLayer(root, root.ClientSize, 96, 96)).Returns(CreateLayer());
var renderInterface = new Mock<IPlatformRenderInterface>();
//var renderInterface = new Mock<IPlatformRenderInterface>();
var target = new DeferredRenderer(
root, //var target = new DeferredRenderer(
loop.Object, // root,
sceneBuilder: sceneBuilder.Object, // loop.Object,
layerFactory: layers.Object, // sceneBuilder: sceneBuilder.Object,
dispatcher: dispatcher); // layerFactory: layers.Object,
// dispatcher: dispatcher);
target.Start();
RunFrame(loop); //target.Start();
//RunFrame(loop);
layers.Verify(x => x.CreateLayer(root, root.ClientSize, 96, 96));
//layers.Verify(x => x.CreateLayer(root, root.ClientSize, 96, 96));
} }
[Fact] [Fact]
public void Should_Create_And_Delete_Layers_For_Transparent_Controls() public void Should_Create_And_Delete_Layers_For_Transparent_Controls()
{ {
Border border; throw new NotImplementedException();
var root = new TestRoot //Border border;
{ //var root = new TestRoot
Width = 100, //{
Height = 100, // Width = 100,
Child = new Border // Height = 100,
{ // Child = new Border
Background = Brushes.Red, // {
Child = border = new Border // Background = Brushes.Red,
{ // Child = border = new Border
Background = Brushes.Green, // {
} // Background = Brushes.Green,
} // }
}; // }
//};
root.Measure(Size.Infinity);
root.Arrange(new Rect(root.DesiredSize)); //root.Measure(Size.Infinity);
//root.Arrange(new Rect(root.DesiredSize));
var loop = new Mock<IRenderLoop>();
var layerFactory = new MockRenderLayerFactory(new Dictionary<IVisual, IRenderTargetBitmapImpl> //var loop = new Mock<IRenderLoop>();
{ //var layerFactory = new MockRenderLayerFactory(new Dictionary<IVisual, IRenderTargetBitmapImpl>
{ root, CreateLayer() }, //{
{ border, CreateLayer() }, // { root, CreateLayer() },
}); // { border, CreateLayer() },
//});
var target = new DeferredRenderer(
root, //var target = new DeferredRenderer(
loop.Object, // root,
layerFactory: layerFactory, // loop.Object,
dispatcher: new ImmediateDispatcher()); // layerFactory: layerFactory,
root.Renderer = target; // dispatcher: new ImmediateDispatcher());
//root.Renderer = target;
target.Start();
RunFrame(loop); //target.Start();
//RunFrame(loop);
var rootContext = layerFactory.GetMockDrawingContext(root);
var borderContext = layerFactory.GetMockDrawingContext(border); //var rootContext = layerFactory.GetMockDrawingContext(root);
//var borderContext = layerFactory.GetMockDrawingContext(border);
rootContext.Verify(x => x.FillRectangle(Brushes.Red, new Rect(0, 0, 100, 100), 0), Times.Once);
rootContext.Verify(x => x.FillRectangle(Brushes.Green, new Rect(0, 0, 100, 100), 0), Times.Once); //rootContext.Verify(x => x.FillRectangle(Brushes.Red, new Rect(0, 0, 100, 100), 0), Times.Once);
borderContext.Verify(x => x.FillRectangle(It.IsAny<IBrush>(), It.IsAny<Rect>(), It.IsAny<float>()), Times.Never); //rootContext.Verify(x => x.FillRectangle(Brushes.Green, new Rect(0, 0, 100, 100), 0), Times.Once);
//borderContext.Verify(x => x.FillRectangle(It.IsAny<IBrush>(), It.IsAny<Rect>(), It.IsAny<float>()), Times.Never);
rootContext.ResetCalls();
borderContext.ResetCalls(); //rootContext.ResetCalls();
border.Opacity = 0.5; //borderContext.ResetCalls();
RunFrame(loop); //border.Opacity = 0.5;
//RunFrame(loop);
rootContext.Verify(x => x.FillRectangle(Brushes.Red, new Rect(0, 0, 100, 100), 0), Times.Once);
rootContext.Verify(x => x.FillRectangle(Brushes.Green, new Rect(0, 0, 100, 100), 0), Times.Never); //rootContext.Verify(x => x.FillRectangle(Brushes.Red, new Rect(0, 0, 100, 100), 0), Times.Once);
borderContext.Verify(x => x.FillRectangle(Brushes.Green, new Rect(0, 0, 100, 100), 0), Times.Once); //rootContext.Verify(x => x.FillRectangle(Brushes.Green, new Rect(0, 0, 100, 100), 0), Times.Never);
//borderContext.Verify(x => x.FillRectangle(Brushes.Green, new Rect(0, 0, 100, 100), 0), Times.Once);
rootContext.ResetCalls();
borderContext.ResetCalls(); //rootContext.ResetCalls();
border.Opacity = 1; //borderContext.ResetCalls();
RunFrame(loop); //border.Opacity = 1;
//RunFrame(loop);
layerFactory.GetMockBitmap(border).Verify(x => x.Dispose());
rootContext.Verify(x => x.FillRectangle(Brushes.Red, new Rect(0, 0, 100, 100), 0), Times.Once); //layerFactory.GetMockBitmap(border).Verify(x => x.Dispose());
rootContext.Verify(x => x.FillRectangle(Brushes.Green, new Rect(0, 0, 100, 100), 0), Times.Once); //rootContext.Verify(x => x.FillRectangle(Brushes.Red, new Rect(0, 0, 100, 100), 0), Times.Once);
borderContext.Verify(x => x.FillRectangle(It.IsAny<IBrush>(), It.IsAny<Rect>(), It.IsAny<float>()), Times.Never); //rootContext.Verify(x => x.FillRectangle(Brushes.Green, new Rect(0, 0, 100, 100), 0), Times.Once);
//borderContext.Verify(x => x.FillRectangle(It.IsAny<IBrush>(), It.IsAny<Rect>(), It.IsAny<float>()), Times.Never);
} }
private void IgnoreFirstFrame(Mock<IRenderLoop> loop, Mock<ISceneBuilder> sceneBuilder) private void IgnoreFirstFrame(Mock<IRenderLoop> loop, Mock<ISceneBuilder> sceneBuilder)
@ -246,13 +244,6 @@ namespace Avalonia.Visuals.UnitTests.Rendering
x.CreateDrawingContext(It.IsAny<IVisualBrushRenderer>()) == Mock.Of<IDrawingContextImpl>()); x.CreateDrawingContext(It.IsAny<IVisualBrushRenderer>()) == Mock.Of<IDrawingContextImpl>());
} }
private Mock<IRenderLayerFactory> MockLayerFactory(IRenderRoot root)
{
var result = new Mock<IRenderLayerFactory>();
result.Setup(x => x.CreateLayer(root, root.ClientSize, 96, 96)).Returns(CreateLayer());
return result;
}
private Mock<ISceneBuilder> MockSceneBuilder(IRenderRoot root) private Mock<ISceneBuilder> MockSceneBuilder(IRenderRoot root)
{ {
var result = new Mock<ISceneBuilder>(); var result = new Mock<ISceneBuilder>();
@ -260,34 +251,5 @@ namespace Avalonia.Visuals.UnitTests.Rendering
.Callback<Scene>(x => x.Layers.Add(root).Dirty.Add(new Rect(root.ClientSize))); .Callback<Scene>(x => x.Layers.Add(root).Dirty.Add(new Rect(root.ClientSize)));
return result; return result;
} }
private class MockRenderLayerFactory : IRenderLayerFactory
{
private IDictionary<IVisual, IRenderTargetBitmapImpl> _layers;
public MockRenderLayerFactory(IDictionary<IVisual, IRenderTargetBitmapImpl> layers)
{
_layers = layers;
}
public IRenderTargetBitmapImpl CreateLayer(
IVisual layerRoot,
Size size,
double dpiX,
double dpiY)
{
return _layers[layerRoot];
}
public Mock<IRenderTargetBitmapImpl> GetMockBitmap(IVisual layerRoot)
{
return Mock.Get(_layers[layerRoot]);
}
public Mock<IDrawingContextImpl> GetMockDrawingContext(IVisual layerRoot)
{
return Mock.Get(_layers[layerRoot].CreateDrawingContext(null));
}
}
} }
} }

Loading…
Cancel
Save