DeferredRendererTests.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reactive.Subjects;
  5. using System.Threading.Tasks;
  6. using Avalonia.Controls;
  7. using Avalonia.Data;
  8. using Avalonia.Media;
  9. using Avalonia.Platform;
  10. using Avalonia.Rendering;
  11. using Avalonia.Rendering.SceneGraph;
  12. using Avalonia.Threading;
  13. using Avalonia.UnitTests;
  14. using Avalonia.Visuals.Media.Imaging;
  15. using Avalonia.VisualTree;
  16. using Moq;
  17. using Xunit;
  18. namespace Avalonia.Visuals.UnitTests.Rendering
  19. {
  20. public class DeferredRendererTests
  21. {
  22. [Fact]
  23. public void First_Frame_Calls_SceneBuilder_UpdateAll()
  24. {
  25. var root = new TestRoot();
  26. var sceneBuilder = MockSceneBuilder(root);
  27. CreateTargetAndRunFrame(root, sceneBuilder: sceneBuilder.Object);
  28. sceneBuilder.Verify(x => x.UpdateAll(It.IsAny<Scene>()));
  29. }
  30. [Fact]
  31. public void Frame_Does_Not_Call_SceneBuilder_If_No_Dirty_Controls()
  32. {
  33. var dispatcher = new ImmediateDispatcher();
  34. var loop = new Mock<IRenderLoop>();
  35. var root = new TestRoot();
  36. var sceneBuilder = MockSceneBuilder(root);
  37. var target = new DeferredRenderer(
  38. root,
  39. loop.Object,
  40. sceneBuilder: sceneBuilder.Object);
  41. target.Start();
  42. IgnoreFirstFrame(target, sceneBuilder);
  43. RunFrame(target);
  44. sceneBuilder.Verify(x => x.UpdateAll(It.IsAny<Scene>()), Times.Never);
  45. sceneBuilder.Verify(x => x.Update(It.IsAny<Scene>(), It.IsAny<Visual>()), Times.Never);
  46. }
  47. [Fact]
  48. public void Should_Update_Dirty_Controls_In_Order()
  49. {
  50. var dispatcher = new ImmediateDispatcher();
  51. var loop = new Mock<IRenderLoop>();
  52. Border border;
  53. Decorator decorator;
  54. Canvas canvas;
  55. var root = new TestRoot
  56. {
  57. Child = decorator = new Decorator
  58. {
  59. Child = border = new Border
  60. {
  61. Child = canvas = new Canvas()
  62. }
  63. }
  64. };
  65. var sceneBuilder = MockSceneBuilder(root);
  66. var target = new DeferredRenderer(
  67. root,
  68. loop.Object,
  69. sceneBuilder: sceneBuilder.Object,
  70. dispatcher: dispatcher);
  71. target.Start();
  72. IgnoreFirstFrame(target, sceneBuilder);
  73. target.AddDirty(border);
  74. target.AddDirty(canvas);
  75. target.AddDirty(root);
  76. target.AddDirty(decorator);
  77. var result = new List<IVisual>();
  78. sceneBuilder.Setup(x => x.Update(It.IsAny<Scene>(), It.IsAny<IVisual>()))
  79. .Callback<Scene, IVisual>((_, v) => result.Add(v));
  80. RunFrame(target);
  81. Assert.Equal(new List<IVisual> { root, decorator, border, canvas }, result);
  82. }
  83. [Fact]
  84. public void Should_Add_Dirty_Rect_On_Child_Remove()
  85. {
  86. var dispatcher = new ImmediateDispatcher();
  87. var loop = new Mock<IRenderLoop>();
  88. Decorator decorator;
  89. Border border;
  90. var root = new TestRoot
  91. {
  92. Width = 100,
  93. Height= 100,
  94. Child = decorator = new Decorator
  95. {
  96. Child = border = new Border
  97. {
  98. Width = 50,
  99. Height = 50,
  100. Background = Brushes.Red,
  101. },
  102. }
  103. };
  104. root.Measure(Size.Infinity);
  105. root.Arrange(new Rect(root.DesiredSize));
  106. var sceneBuilder = new SceneBuilder();
  107. var target = new DeferredRenderer(
  108. root,
  109. loop.Object,
  110. sceneBuilder: sceneBuilder,
  111. dispatcher: dispatcher);
  112. root.Renderer = target;
  113. target.Start();
  114. RunFrame(target);
  115. decorator.Child = null;
  116. RunFrame(target);
  117. var scene = target.UnitTestScene();
  118. var stackNode = scene.FindNode(decorator);
  119. var dirty = scene.Layers[0].Dirty.ToList();
  120. Assert.Equal(1, dirty.Count);
  121. Assert.Equal(new Rect(25, 25, 50, 50), dirty[0]);
  122. }
  123. [Fact]
  124. public void Should_Update_VisualNode_Order_On_Child_Remove_Insert()
  125. {
  126. var dispatcher = new ImmediateDispatcher();
  127. var loop = new Mock<IRenderLoop>();
  128. StackPanel stack;
  129. Canvas canvas1;
  130. Canvas canvas2;
  131. var root = new TestRoot
  132. {
  133. Child = stack = new StackPanel
  134. {
  135. Children=
  136. {
  137. (canvas1 = new Canvas()),
  138. (canvas2 = new Canvas()),
  139. }
  140. }
  141. };
  142. var sceneBuilder = new SceneBuilder();
  143. var target = new DeferredRenderer(
  144. root,
  145. loop.Object,
  146. sceneBuilder: sceneBuilder,
  147. dispatcher: dispatcher);
  148. root.Renderer = target;
  149. target.Start();
  150. RunFrame(target);
  151. stack.Children.Remove(canvas2);
  152. stack.Children.Insert(0, canvas2);
  153. RunFrame(target);
  154. var scene = target.UnitTestScene();
  155. var stackNode = scene.FindNode(stack);
  156. Assert.Same(stackNode.Children[0].Visual, canvas2);
  157. Assert.Same(stackNode.Children[1].Visual, canvas1);
  158. }
  159. [Fact]
  160. public void Should_Update_VisualNode_Order_On_Child_Move()
  161. {
  162. var dispatcher = new ImmediateDispatcher();
  163. var loop = new Mock<IRenderLoop>();
  164. StackPanel stack;
  165. Canvas canvas1;
  166. Canvas canvas2;
  167. var root = new TestRoot
  168. {
  169. Child = stack = new StackPanel
  170. {
  171. Children =
  172. {
  173. (canvas1 = new Canvas()),
  174. (canvas2 = new Canvas()),
  175. }
  176. }
  177. };
  178. var sceneBuilder = new SceneBuilder();
  179. var target = new DeferredRenderer(
  180. root,
  181. loop.Object,
  182. sceneBuilder: sceneBuilder,
  183. dispatcher: dispatcher);
  184. root.Renderer = target;
  185. target.Start();
  186. RunFrame(target);
  187. stack.Children.Move(1, 0);
  188. RunFrame(target);
  189. var scene = target.UnitTestScene();
  190. var stackNode = scene.FindNode(stack);
  191. Assert.Same(stackNode.Children[0].Visual, canvas2);
  192. Assert.Same(stackNode.Children[1].Visual, canvas1);
  193. }
  194. [Fact]
  195. public void Should_Update_VisualNode_Order_On_ZIndex_Change()
  196. {
  197. var dispatcher = new ImmediateDispatcher();
  198. var loop = new Mock<IRenderLoop>();
  199. StackPanel stack;
  200. Canvas canvas1;
  201. Canvas canvas2;
  202. var root = new TestRoot
  203. {
  204. Child = stack = new StackPanel
  205. {
  206. Children =
  207. {
  208. (canvas1 = new Canvas { ZIndex = 1 }),
  209. (canvas2 = new Canvas { ZIndex = 2 }),
  210. }
  211. }
  212. };
  213. var sceneBuilder = new SceneBuilder();
  214. var target = new DeferredRenderer(
  215. root,
  216. loop.Object,
  217. sceneBuilder: sceneBuilder,
  218. dispatcher: dispatcher);
  219. root.Renderer = target;
  220. target.Start();
  221. RunFrame(target);
  222. canvas1.ZIndex = 3;
  223. RunFrame(target);
  224. var scene = target.UnitTestScene();
  225. var stackNode = scene.FindNode(stack);
  226. Assert.Same(stackNode.Children[0].Visual, canvas2);
  227. Assert.Same(stackNode.Children[1].Visual, canvas1);
  228. }
  229. [Fact]
  230. public void Should_Update_VisualNode_Order_On_ZIndex_Change_With_Dirty_Ancestor()
  231. {
  232. var dispatcher = new ImmediateDispatcher();
  233. var loop = new Mock<IRenderLoop>();
  234. StackPanel stack;
  235. Canvas canvas1;
  236. Canvas canvas2;
  237. var root = new TestRoot
  238. {
  239. Child = stack = new StackPanel
  240. {
  241. Children =
  242. {
  243. (canvas1 = new Canvas { ZIndex = 1 }),
  244. (canvas2 = new Canvas { ZIndex = 2 }),
  245. }
  246. }
  247. };
  248. var sceneBuilder = new SceneBuilder();
  249. var target = new DeferredRenderer(
  250. root,
  251. loop.Object,
  252. sceneBuilder: sceneBuilder,
  253. dispatcher: dispatcher);
  254. root.Renderer = target;
  255. target.Start();
  256. RunFrame(target);
  257. root.InvalidateVisual();
  258. canvas1.ZIndex = 3;
  259. RunFrame(target);
  260. var scene = target.UnitTestScene();
  261. var stackNode = scene.FindNode(stack);
  262. Assert.Same(stackNode.Children[0].Visual, canvas2);
  263. Assert.Same(stackNode.Children[1].Visual, canvas1);
  264. }
  265. [Fact]
  266. public void Should_Update_VisualNodes_When_Child_Moved_To_New_Parent()
  267. {
  268. var dispatcher = new ImmediateDispatcher();
  269. var loop = new Mock<IRenderLoop>();
  270. Decorator moveFrom;
  271. Decorator moveTo;
  272. Canvas moveMe;
  273. var root = new TestRoot
  274. {
  275. Child = new StackPanel
  276. {
  277. Children =
  278. {
  279. (moveFrom = new Decorator
  280. {
  281. Child = moveMe = new Canvas(),
  282. }),
  283. (moveTo = new Decorator()),
  284. }
  285. }
  286. };
  287. var sceneBuilder = new SceneBuilder();
  288. var target = new DeferredRenderer(
  289. root,
  290. loop.Object,
  291. sceneBuilder: sceneBuilder,
  292. dispatcher: dispatcher);
  293. root.Renderer = target;
  294. target.Start();
  295. RunFrame(target);
  296. moveFrom.Child = null;
  297. moveTo.Child = moveMe;
  298. RunFrame(target);
  299. var scene = target.UnitTestScene();
  300. var moveFromNode = (VisualNode)scene.FindNode(moveFrom);
  301. var moveToNode = (VisualNode)scene.FindNode(moveTo);
  302. Assert.Empty(moveFromNode.Children);
  303. Assert.Equal(1, moveToNode.Children.Count);
  304. Assert.Same(moveMe, moveToNode.Children[0].Visual);
  305. }
  306. [Fact]
  307. public void Should_Update_VisualNodes_When_Child_Moved_To_New_Parent_And_New_Root()
  308. {
  309. var dispatcher = new ImmediateDispatcher();
  310. var loop = new Mock<IRenderLoop>();
  311. Decorator moveFrom;
  312. Decorator moveTo;
  313. Canvas moveMe;
  314. var root = new TestRoot
  315. {
  316. Child = new StackPanel
  317. {
  318. Children =
  319. {
  320. (moveFrom = new Decorator
  321. {
  322. Child = moveMe = new Canvas(),
  323. })
  324. }
  325. }
  326. };
  327. var otherRoot = new TestRoot
  328. {
  329. Child = new StackPanel
  330. {
  331. Children =
  332. {
  333. (moveTo = new Decorator())
  334. }
  335. }
  336. };
  337. var sceneBuilder = new SceneBuilder();
  338. var target = new DeferredRenderer(
  339. root,
  340. loop.Object,
  341. sceneBuilder: sceneBuilder,
  342. dispatcher: dispatcher);
  343. var otherSceneBuilder = new SceneBuilder();
  344. var otherTarget = new DeferredRenderer(
  345. otherRoot,
  346. loop.Object,
  347. sceneBuilder: otherSceneBuilder,
  348. dispatcher: dispatcher);
  349. root.Renderer = target;
  350. otherRoot.Renderer = otherTarget;
  351. target.Start();
  352. otherTarget.Start();
  353. RunFrame(target);
  354. RunFrame(otherTarget);
  355. moveFrom.Child = null;
  356. moveTo.Child = moveMe;
  357. RunFrame(target);
  358. RunFrame(otherTarget);
  359. var scene = target.UnitTestScene();
  360. var otherScene = otherTarget.UnitTestScene();
  361. var moveFromNode = (VisualNode)scene.FindNode(moveFrom);
  362. var moveToNode = (VisualNode)otherScene.FindNode(moveTo);
  363. Assert.Empty(moveFromNode.Children);
  364. Assert.Equal(1, moveToNode.Children.Count);
  365. Assert.Same(moveMe, moveToNode.Children[0].Visual);
  366. }
  367. [Fact]
  368. public void Should_Push_Opacity_For_Controls_With_Less_Than_1_Opacity()
  369. {
  370. var root = new TestRoot
  371. {
  372. Width = 100,
  373. Height = 100,
  374. Child = new Border
  375. {
  376. Background = Brushes.Red,
  377. Opacity = 0.5,
  378. }
  379. };
  380. root.Measure(Size.Infinity);
  381. root.Arrange(new Rect(root.DesiredSize));
  382. var target = CreateTargetAndRunFrame(root);
  383. var context = GetLayerContext(target, root);
  384. var animation = new BehaviorSubject<double>(0.5);
  385. context.Verify(x => x.PushOpacity(0.5), Times.Once);
  386. context.Verify(x => x.DrawRectangle(Brushes.Red, null, new Rect(0, 0, 100, 100), 0, 0), Times.Once);
  387. context.Verify(x => x.PopOpacity(), Times.Once);
  388. }
  389. [Fact]
  390. public void Should_Not_Draw_Controls_With_0_Opacity()
  391. {
  392. var root = new TestRoot
  393. {
  394. Width = 100,
  395. Height = 100,
  396. Child = new Border
  397. {
  398. Background = Brushes.Red,
  399. Opacity = 0,
  400. Child = new Border
  401. {
  402. Background = Brushes.Green,
  403. }
  404. }
  405. };
  406. root.Measure(Size.Infinity);
  407. root.Arrange(new Rect(root.DesiredSize));
  408. var target = CreateTargetAndRunFrame(root);
  409. var context = GetLayerContext(target, root);
  410. var animation = new BehaviorSubject<double>(0.5);
  411. context.Verify(x => x.PushOpacity(0.5), Times.Never);
  412. context.Verify(x => x.DrawRectangle(Brushes.Red, null, new Rect(0, 0, 100, 100), 0, 0), Times.Never);
  413. context.Verify(x => x.PopOpacity(), Times.Never);
  414. }
  415. [Fact]
  416. public void Should_Push_Opacity_Mask()
  417. {
  418. var root = new TestRoot
  419. {
  420. Width = 100,
  421. Height = 100,
  422. Child = new Border
  423. {
  424. Background = Brushes.Red,
  425. OpacityMask = Brushes.Green,
  426. }
  427. };
  428. root.Measure(Size.Infinity);
  429. root.Arrange(new Rect(root.DesiredSize));
  430. var target = CreateTargetAndRunFrame(root);
  431. var context = GetLayerContext(target, root);
  432. var animation = new BehaviorSubject<double>(0.5);
  433. context.Verify(x => x.PushOpacityMask(Brushes.Green, new Rect(0, 0, 100, 100)), Times.Once);
  434. context.Verify(x => x.DrawRectangle(Brushes.Red, null, new Rect(0, 0, 100, 100), 0, 0), Times.Once);
  435. context.Verify(x => x.PopOpacityMask(), Times.Once);
  436. }
  437. [Fact]
  438. public void Should_Create_Layer_For_Root()
  439. {
  440. var root = new TestRoot();
  441. var rootLayer = new Mock<IRenderTargetBitmapImpl>();
  442. var sceneBuilder = new Mock<ISceneBuilder>();
  443. sceneBuilder.Setup(x => x.UpdateAll(It.IsAny<Scene>()))
  444. .Callback<Scene>(scene =>
  445. {
  446. scene.Size = root.ClientSize;
  447. scene.Layers.Add(root).Dirty.Add(new Rect(root.ClientSize));
  448. });
  449. var renderInterface = new Mock<IPlatformRenderInterface>();
  450. var target = CreateTargetAndRunFrame(root, sceneBuilder: sceneBuilder.Object);
  451. Assert.Single(target.Layers);
  452. }
  453. [Fact]
  454. public void Should_Create_And_Delete_Layers_For_Controls_With_Animated_Opacity()
  455. {
  456. Border border;
  457. var root = new TestRoot
  458. {
  459. Width = 100,
  460. Height = 100,
  461. Child = new Border
  462. {
  463. Background = Brushes.Red,
  464. Child = border = new Border
  465. {
  466. Background = Brushes.Green,
  467. Child = new Canvas(),
  468. Opacity = 0.9,
  469. }
  470. }
  471. };
  472. root.Measure(Size.Infinity);
  473. root.Arrange(new Rect(root.DesiredSize));
  474. var timer = new Mock<IRenderTimer>();
  475. var target = CreateTargetAndRunFrame(root, timer);
  476. Assert.Equal(new[] { root }, target.Layers.Select(x => x.LayerRoot));
  477. var animation = new BehaviorSubject<double>(0.5);
  478. border.Bind(Border.OpacityProperty, animation, BindingPriority.Animation);
  479. RunFrame(target);
  480. Assert.Equal(new IVisual[] { root, border }, target.Layers.Select(x => x.LayerRoot));
  481. animation.OnCompleted();
  482. RunFrame(target);
  483. Assert.Equal(new[] { root }, target.Layers.Select(x => x.LayerRoot));
  484. }
  485. [Fact]
  486. public void Should_Not_Create_Layer_For_Childless_Control_With_Animated_Opacity()
  487. {
  488. Border border;
  489. var root = new TestRoot
  490. {
  491. Width = 100,
  492. Height = 100,
  493. Child = new Border
  494. {
  495. Background = Brushes.Red,
  496. Child = border = new Border
  497. {
  498. Background = Brushes.Green,
  499. }
  500. }
  501. };
  502. var animation = new BehaviorSubject<double>(0.5);
  503. border.Bind(Border.OpacityProperty, animation, BindingPriority.Animation);
  504. root.Measure(Size.Infinity);
  505. root.Arrange(new Rect(root.DesiredSize));
  506. var timer = new Mock<IRenderTimer>();
  507. var target = CreateTargetAndRunFrame(root, timer);
  508. Assert.Single(target.Layers);
  509. }
  510. [Fact]
  511. public void Should_Not_Push_Opacity_For_Transparent_Layer_Root_Control()
  512. {
  513. Border border;
  514. var root = new TestRoot
  515. {
  516. Width = 100,
  517. Height = 100,
  518. Child = border = new Border
  519. {
  520. Background = Brushes.Red,
  521. Child = new Canvas(),
  522. }
  523. };
  524. var animation = new BehaviorSubject<double>(0.5);
  525. border.Bind(Border.OpacityProperty, animation, BindingPriority.Animation);
  526. root.Measure(Size.Infinity);
  527. root.Arrange(new Rect(root.DesiredSize));
  528. var target = CreateTargetAndRunFrame(root);
  529. var context = GetLayerContext(target, border);
  530. context.Verify(x => x.PushOpacity(0.5), Times.Never);
  531. context.Verify(x => x.DrawRectangle(Brushes.Red, null, new Rect(0, 0, 100, 100), 0, 0), Times.Once);
  532. context.Verify(x => x.PopOpacity(), Times.Never);
  533. }
  534. [Fact]
  535. public void Should_Draw_Transparent_Layer_With_Correct_Opacity()
  536. {
  537. Border border;
  538. var root = new TestRoot
  539. {
  540. Width = 100,
  541. Height = 100,
  542. Child = border = new Border
  543. {
  544. Background = Brushes.Red,
  545. Child = new Canvas(),
  546. }
  547. };
  548. var animation = new BehaviorSubject<double>(0.5);
  549. border.Bind(Border.OpacityProperty, animation, BindingPriority.Animation);
  550. root.Measure(Size.Infinity);
  551. root.Arrange(new Rect(root.DesiredSize));
  552. var target = CreateTargetAndRunFrame(root);
  553. var context = Mock.Get(target.RenderTarget.CreateDrawingContext(null));
  554. var borderLayer = target.Layers[border].Bitmap;
  555. context.Verify(x => x.DrawBitmap(borderLayer, 0.5, It.IsAny<Rect>(), It.IsAny<Rect>(), BitmapInterpolationMode.Default));
  556. }
  557. [Fact]
  558. public void Can_Dirty_Control_In_SceneInvalidated()
  559. {
  560. Border border1;
  561. Border border2;
  562. var root = new TestRoot
  563. {
  564. Width = 100,
  565. Height = 100,
  566. Child = new StackPanel
  567. {
  568. Children =
  569. {
  570. (border1 = new Border
  571. {
  572. Background = Brushes.Red,
  573. Child = new Canvas(),
  574. }),
  575. (border2 = new Border
  576. {
  577. Background = Brushes.Red,
  578. Child = new Canvas(),
  579. }),
  580. }
  581. }
  582. };
  583. root.Measure(Size.Infinity);
  584. root.Arrange(new Rect(root.DesiredSize));
  585. var target = CreateTargetAndRunFrame(root);
  586. var invalidated = false;
  587. target.SceneInvalidated += (s, e) =>
  588. {
  589. invalidated = true;
  590. target.AddDirty(border2);
  591. };
  592. target.AddDirty(border1);
  593. target.Paint(new Rect(root.DesiredSize));
  594. Assert.True(invalidated);
  595. Assert.True(((IRenderLoopTask)target).NeedsUpdate);
  596. }
  597. private DeferredRenderer CreateTargetAndRunFrame(
  598. TestRoot root,
  599. Mock<IRenderTimer> timer = null,
  600. ISceneBuilder sceneBuilder = null,
  601. IDispatcher dispatcher = null)
  602. {
  603. timer = timer ?? new Mock<IRenderTimer>();
  604. dispatcher = dispatcher ?? new ImmediateDispatcher();
  605. var target = new DeferredRenderer(
  606. root,
  607. new RenderLoop(timer.Object, dispatcher),
  608. sceneBuilder: sceneBuilder,
  609. dispatcher: dispatcher);
  610. root.Renderer = target;
  611. target.Start();
  612. RunFrame(target);
  613. return target;
  614. }
  615. private Mock<IDrawingContextImpl> GetLayerContext(DeferredRenderer renderer, IControl layerRoot)
  616. {
  617. return Mock.Get(renderer.Layers[layerRoot].Bitmap.Item.CreateDrawingContext(null));
  618. }
  619. private void IgnoreFirstFrame(IRenderLoopTask task, Mock<ISceneBuilder> sceneBuilder)
  620. {
  621. RunFrame(task);
  622. sceneBuilder.ResetCalls();
  623. }
  624. private void RunFrame(IRenderLoopTask task)
  625. {
  626. task.Update(TimeSpan.Zero);
  627. task.Render();
  628. }
  629. private IRenderTargetBitmapImpl CreateLayer()
  630. {
  631. return Mock.Of<IRenderTargetBitmapImpl>(x =>
  632. x.CreateDrawingContext(It.IsAny<IVisualBrushRenderer>()) == Mock.Of<IDrawingContextImpl>());
  633. }
  634. private Mock<ISceneBuilder> MockSceneBuilder(IRenderRoot root)
  635. {
  636. var result = new Mock<ISceneBuilder>();
  637. result.Setup(x => x.UpdateAll(It.IsAny<Scene>()))
  638. .Callback<Scene>(x => x.Layers.Add(root).Dirty.Add(new Rect(root.ClientSize)));
  639. return result;
  640. }
  641. }
  642. }