Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(130)

Unified Diff: sky/specs/runloop.md

Issue 931333002: Specs: update the run loop and timer stuff to use the new model with task filters, priorities, and … (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sky/specs/elements.md ('k') | sky/specs/style.md » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sky/specs/runloop.md
diff --git a/sky/specs/runloop.md b/sky/specs/runloop.md
index 3ec031ffd0dee86c54acbdd1ccfc5d8d04988b11..7059b8019d9f249296de62ff7346706f55031532 100644
--- a/sky/specs/runloop.md
+++ b/sky/specs/runloop.md
@@ -1,44 +1,104 @@
Sky's Run Loop
==============
+Sky has three task queues, named idle, paint, and nextPaint.
+
+When a task is run, it has a time budget, and if the time budget is
+exceeded, then a catchable DeadlineExceededException exception is
+fired.
+
+```dart
+class DeadlineExceededException implements Exception { }
+```
+
+When Sky is to *process a task queue until a particular time*, with a
+queue *relevant task queue*, bits *filter bits*, a time
+*particular time*, and an *idle rule* which is either "sleep" or
+"abort", it must run the following steps:
+
+1. Let *remaining time* be the time until the given *particular time*.
+2. If *remaining time* is less than or equal to zero, exit this
+ algorithm.
+3. Let *task list* be the list of tasks in the *relevant task queue*
+ that have bits that, when 'or'ed with *filter bits*, are non-zero;
+ whose required budget is less than or equal to *remaining time*;
+ and whose due time, if any, has been reached.
+4. If *task list* is empty, then if *idle rule* is "sleep" then return
+ to step 1, otherwise, exit this algorithm.
+5. Sort *task list* by the priority of each task, highest first.
+6. Remove the top task from *task list* from the *relevant task
+ queue*, and let that be *selected task*.
+7. Run *selected task*, with a budget of *remaining time* or 1ms,
+ whichever is shorter.
+8. Return to step 1.
+
+When Sky is to *drain a task queue for a specified time*, with a queue
+*relevant task queue*, bits *filter bits*, and a duration *budget*, it
+must run the following steps:
+
+2. Let *task list* be the list of tasks in the *relevant task queue*
+ that have bits that, when 'or'ed with *filter bits*, are non-zero;
+ and whose required budget is less than or equal to *budget*.
+4. If *task list* is empty, then exit.
+5. Sort *task list* by the priority of each task, highest first.
+6. Remove the top task from *task list* from the *relevant task
+ queue*, and let that be *selected task*.
+7. Run *selected task*, with a budget of *budget*.
+8. Decrease *budget* with the amount of time that *selected task* took
+ to run.
+9. If *selected task* threw an uncaught DeadlineExceededException
+ exception, then cancel all the tasks in *relevant task queue*.
+ Otherwise, return to step 2.
+
Sky's run loop consists of running the following, at 120Hz (each loop
takes 8.333ms):
-1. Send scroll and resize events if necessary, limiting each handler
- to 1ms, and limiting the total time spent on these handlers to 1ms.
+1. *Drain* the *paint task queue*, with bits
+ `application.paintTaskBits`, for 1ms.
+
+2. Create a task that does the following, then run it with a budget of
+ 1ms:
-2. Fire animation frame callbacks for up to 1ms. Each callback can run
- for up to 1ms. Once 1ms has expired, throw a (catchable)
- EDeadlineExceeded exception. If it's not caught, drop subsequent
- callbacks.
+ 1. Update the render tree, including calling childAdded(),
+ childRemoved(), and getLayoutManager() as needed, catching any
+ exceptions other than DeadlineExceededException exceptions.
-4. Spend up to 1ms to update the render tree, including calling
- childAdded(), childRemoved(), and getLayoutManager() as needed.
- Once 1ms has expired, throw a (catchable) EDeadlineExceeded
- exception, leaving the render tree in whatever state it has
- reached.
+ If an exception is thrown by this, then the RenderNode tree will
+ continue to not quite match the element tree, which is fine.
-3. Update the ElementStyleDeclarationList objects for all elements on
- the RenderTree.
+3. If there are no tasks on the *idle task queue* with bits
+ `LayoutKind`, create a task that tells the root node to layout if
+ it has needsLayout or descendantNeedsLayout, mark that with
+ priority 0 and bits `LayoutKind`, and add it to the *idle task
+ queue*.
-5. Update as much of layout as possible; after 1ms, throw a
- (catchable) EDeadlineExceeded exception, leaving the remaining
- nodes unprepared.
+4. *Process* the *idle task queue*, with bits `LayoutKind`, with a
+ target time of t-1ms, where t is the time at which we have to send
+ the frame to the GPU, and with an *idle rule* of "abort".
-6. Update as much of paint as possible; after 1ms, throw a (catchable)
- EDeadlineExceeded exception, leaving any remaining nodes
- unprepared.
+5. Create a task that does the following, then run it with a budget of
+ 1ms:
-7. Send frame to GPU.
+ 1. If there are no RenderNodes that need paint, abort.
-8. Run pending tasks until the 8.333ms expires. Each task may only run
- for at most 1ms, after 1ms they get a (catchable) EDeadlineExceeded
- exception. While there are no pending tasks, sleep.
- Tasks are things like:
- - timers
- - updating the DOM in response to parsing
- - input events
- - mojo callbacks
+ 2. Call the `paint()` callback of the RenderNode that was least
+ recently marked as needing paint, catching any exceptions other
+ than DeadlineExceededException exceptions.
+
+ 3. Jump to step 1.
+
+ If an exception is thrown by this, then some RenderNode objects
+ will be out-of-date during the paint.
+
+6. Send frame to GPU.
+
+7. Replace the paint queue with the nextPaint queue, and let the
+ nextPaint queue be an empty queue.
+
+8. *Process* the *idle task queue*, with bits
+ `application.idleTaskBits`, with a target time of t, where t is the
+ time at which we have to start the next frame's layout and paint
+ computations, and with an *idle rule* of "sleep".
TODO(ianh): Update the timings above to have some relationship to
reality.
@@ -46,5 +106,17 @@ reality.
TODO(ianh): Define an API so that the application can adjust the
budgets.
-TODO(ianh): Define how scroll notifications get sent, or decide to
-drop them entirely from this model.
+Task kinds and priorities
+-------------------------
+
+```dart
+const IdlePriority = 0;
+const FuturePriority = 10000; // the tasks scheduled by futures resolving have this priority
+
+const IdleKind = 0x01; // tasks that should run during the idle loop
+const LayoutKind = 0x02; // tasks that should run during layout
+const PaintQueueKind = 0x04; // tasks that run on the paint queue
+
+int idleTaskBits = IdleKind;
+int paintTaskBits = PaintQueueKind;
+```
« no previous file with comments | « sky/specs/elements.md ('k') | sky/specs/style.md » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698