| OLD | NEW |
| 1 Sky's Run Loop | 1 Sky's Run Loop |
| 2 ============== | 2 ============== |
| 3 | 3 |
| 4 Sky has three task queues, named idle, paint, and nextPaint. | 4 Sky has three task queues, named idle, frame, and nextFrame. |
| 5 | 5 |
| 6 When a task is run, it has a time budget, and if the time budget is | 6 When a task is run, it has a time budget, and if the time budget is |
| 7 exceeded, then a catchable DeadlineExceededException exception is | 7 exceeded, then a catchable DeadlineExceededException exception is |
| 8 fired. | 8 fired. |
| 9 | 9 |
| 10 ```dart | 10 ```dart |
| 11 class DeadlineExceededException implements Exception { } | 11 class DeadlineExceededException implements Exception { } |
| 12 ``` | 12 ``` |
| 13 | 13 |
| 14 When Sky is to *process a task queue until a particular time*, with a | 14 When Sky is to *process a task queue until a particular time*, with a |
| 15 queue *relevant task queue*, bits *filter bits*, a time | 15 queue *relevant task queue*, bits *filter bits*, a time |
| 16 *particular time*, and an *idle rule* which is either "sleep" or | 16 *particular time*, and an *idle rule* which is either "sleep" or |
| 17 "abort", it must run the following steps: | 17 "abort", it must run the following steps: |
| 18 | 18 |
| 19 1. Let *remaining time* be the time until the given *particular time*. | 19 1. Let *remaining time* be the time until the given *particular time*. |
| 20 2. If *remaining time* is less than or equal to zero, exit this | 20 2. If *remaining time* is less than or equal to zero, exit this |
| 21 algorithm. | 21 algorithm. |
| 22 3. Let *task list* be the list of tasks in the *relevant task queue* | 22 3. Let *task list* be the list of tasks in the *relevant task queue* |
| 23 that have bits that, when 'or'ed with *filter bits*, are non-zero; | 23 that have bits that, when 'and'ed with *filter bits*, are equal to |
| 24 whose required budget is less than or equal to *remaining time*; | 24 *filter bits*, whose required budget is less than or equal to |
| 25 and whose due time, if any, has been reached. | 25 *remaining time*; and whose due time, if any, has been reached. |
| 26 4. If *task list* is empty, then if *idle rule* is "sleep" then return | 26 4. If *task list* is empty, then if *idle rule* is "sleep" then return |
| 27 to step 1, otherwise, exit this algorithm. | 27 to step 1, otherwise, exit this algorithm. |
| 28 5. Sort *task list* by the priority of each task, highest first. | 28 5. Sort *task list* by the priority of each task, highest first. |
| 29 6. Remove the top task from *task list* from the *relevant task | 29 6. Remove the top task from *task list* from the *relevant task |
| 30 queue*, and let that be *selected task*. | 30 queue*, and let that be *selected task*. |
| 31 7. Run *selected task*, with a budget of *remaining time* or 1ms, | 31 7. Run *selected task*, with a budget of *remaining time* or 1ms, |
| 32 whichever is shorter. | 32 whichever is shorter. |
| 33 8. Return to step 1. | 33 8. Return to step 1. |
| 34 | 34 |
| 35 When Sky is to *drain a task queue for a specified time*, with a queue | 35 When Sky is to *drain a task queue for a specified time*, with a queue |
| (...skipping 10 matching lines...) Expand all Loading... |
| 46 7. Run *selected task*, with a budget of *budget*. | 46 7. Run *selected task*, with a budget of *budget*. |
| 47 8. Decrease *budget* with the amount of time that *selected task* took | 47 8. Decrease *budget* with the amount of time that *selected task* took |
| 48 to run. | 48 to run. |
| 49 9. If *selected task* threw an uncaught DeadlineExceededException | 49 9. If *selected task* threw an uncaught DeadlineExceededException |
| 50 exception, then cancel all the tasks in *relevant task queue*. | 50 exception, then cancel all the tasks in *relevant task queue*. |
| 51 Otherwise, return to step 2. | 51 Otherwise, return to step 2. |
| 52 | 52 |
| 53 Sky's run loop consists of running the following, at 120Hz (each loop | 53 Sky's run loop consists of running the following, at 120Hz (each loop |
| 54 takes 8.333ms): | 54 takes 8.333ms): |
| 55 | 55 |
| 56 1. *Drain* the *paint task queue*, with bits | 56 1. *Drain* the *frame task queue*, with bits |
| 57 `application.paintTaskBits`, for 1ms. | 57 `application.frameTaskBits`, for 1ms. |
| 58 | 58 |
| 59 2. Create a task that does the following, then run it with a budget of | 59 2. Create a task that does the following, then run it with a budget of |
| 60 1ms: | 60 1ms: |
| 61 | 61 |
| 62 1. Update the render tree, including calling childAdded(), | 62 1. Update the render tree, including calling childAdded(), |
| 63 childRemoved(), and getLayoutManager() as needed, catching any | 63 childRemoved(), and getLayoutManager() as needed, catching any |
| 64 exceptions other than DeadlineExceededException exceptions. | 64 exceptions other than DeadlineExceededException exceptions. |
| 65 | 65 |
| 66 If an exception is thrown by this, then the RenderNode tree will | 66 If an exception is thrown by this, then the RenderNode tree will |
| 67 continue to not quite match the element tree, which is fine. | 67 continue to not quite match the element tree, which is fine. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 85 recently marked as needing paint, catching any exceptions other | 85 recently marked as needing paint, catching any exceptions other |
| 86 than DeadlineExceededException exceptions. | 86 than DeadlineExceededException exceptions. |
| 87 | 87 |
| 88 3. Jump to step 1. | 88 3. Jump to step 1. |
| 89 | 89 |
| 90 If an exception is thrown by this, then some RenderNode objects | 90 If an exception is thrown by this, then some RenderNode objects |
| 91 will be out-of-date during the paint. | 91 will be out-of-date during the paint. |
| 92 | 92 |
| 93 6. Send frame to GPU. | 93 6. Send frame to GPU. |
| 94 | 94 |
| 95 7. Replace the paint queue with the nextPaint queue, and let the | 95 7. Replace the frame queue with the nextFrame queue, and let the |
| 96 nextPaint queue be an empty queue. | 96 nextFrame queue be an empty queue. |
| 97 | 97 |
| 98 8. *Process* the *idle task queue*, with bits | 98 8. *Process* the *idle task queue*, with bits |
| 99 `application.idleTaskBits`, with a target time of t, where t is the | 99 `application.idleTaskBits`, with a target time of t, where t is the |
| 100 time at which we have to start the next frame's layout and paint | 100 time at which we have to start the next frame's layout and paint |
| 101 computations, and with an *idle rule* of "sleep". | 101 computations, and with an *idle rule* of "sleep". |
| 102 | 102 |
| 103 TODO(ianh): Update the timings above to have some relationship to | 103 TODO(ianh): Update the timings above to have some relationship to |
| 104 reality. | 104 reality. |
| 105 | 105 |
| 106 TODO(ianh): Define an API so that the application can adjust the | 106 TODO(ianh): Define an API so that the application can adjust the |
| 107 budgets. | 107 budgets. |
| 108 | 108 |
| 109 Task kinds and priorities | 109 Task kinds and priorities |
| 110 ------------------------- | 110 ------------------------- |
| 111 | 111 |
| 112 Tasks scheduled by futures get the priority and task kind bits from |
| 113 the task they are scheduled from. |
| 114 |
| 112 ```dart | 115 ```dart |
| 113 const IdlePriority = 0; | 116 int IdlePriority = 0; // tasks that can be delayed arbitrarily |
| 114 const FuturePriority = 10000; // the tasks scheduled by futures resolving have t
his priority | 117 int FutureLayoutPriority = 1000; // async-layout tasks |
| 118 int AnimationPriority = 3000; // animation-related tasks |
| 119 int InputPriority = 4000; // input events |
| 120 int ScrollPriority = 5000; // framework-fired events for scrolling |
| 115 | 121 |
| 116 const IdleKind = 0x01; // tasks that should run during the idle loop | 122 // possible idle queue task bits |
| 117 const LayoutKind = 0x02; // tasks that should run during layout | 123 int IdleKind = 0x01; // tasks that should run during the idle loop |
| 118 const PaintQueueKind = 0x04; // tasks that run on the paint queue | 124 int LayoutKind = 0x02; // tasks that should run during layout |
| 125 int TouchSafeKind = 0x04; // tasks that should keep running while there is a poi
nter down |
| 126 int idleTaskBits = IdleKind; // tasks must have all these bits to run during idl
e loop |
| 127 int layoutTaskBits = LayoutKind; // tasks must have all these bits to run during
layout |
| 119 | 128 |
| 120 int idleTaskBits = IdleKind; | 129 // possible frame queue task bits |
| 121 int paintTaskBits = PaintQueueKind; | 130 // (there are none at this time) |
| 131 int frameTaskBits = 0x00; // tasks must have all these bits to run during the fr
ame loop |
| 122 ``` | 132 ``` |
| OLD | NEW |