Closed vmpstr closed 9 years ago
Should that be defined somewhere like http://www.w3.org/TR/animation-timing/#processingmodel or should there be an in-line or footnote explanation in frame-timing?
I'd be OK with an inline, or a footnote. I think the difficulty is getting a concise one-liner that describes it.
I think it's very important that we be explicit about what idle time includes and excludes - even if it means we are more verbose.
My attempt at a definition for idle time is as follows;
Idle time
for a frame is defined as a the sum of the lengths of the idle periods
for a frame between the startTime and startTime+duration for a frame.idle period
for a frame is defined as a period of time in which no work for this frame
is currently being attempted
.
idle period
only occurs if all threads inside the rendering system are currently not attempting work for this frame
. idle period
s are for a frame so in a system which has multiple frames rendering at the same time, one frame may have an idle period
when another frame does not.being attempted
means that the work is currently trying to be run.
being attempted
even when an operating system has descheduled the thread / process the work is occurring on (no matter the reason for being descheduled).Not entirely happy with it, but it was the best I could come up with.
Oh, I also left out the definition of work for this frame
which also needs to be defined.
My definition above should match the following Python "pseudo code" (as described in https://github.com/w3c/frame-timing/issues/28#issuecomment-67107134).
You could think of it as being like the following almost Python code;
class RenderTimeCounter:
def startFrame(self, t):
self.startTime = t
def startWork(self, t):
self.rendering += 1
# If rendering count is one, we are leaving an idle period and starting to
# render stuff. Record the start time now.
if self.rendering == 1:
self.renderingPeriods.append({'start': t, 'end': None})
def finishWork(self, t):
self.rendering -= 1
assert self.rendering >= 0
# If nobody is rendering anymore then we are entering an idle period. Record
# an end of the rendering time.
if self.rendering == 0:
assert self.renderingPeriods[-1]["end"] is None
self.renderingPeriods[-1]["end"] = t
def nextFrameStarting(self, t):
assert self.rendering == 0
assert self.renderingPeriods[-1]["end"] is not None
self.endTime = t
def getInfo(self):
renderingFor = 0
for work in workPeriods:
renderingFor += work["end"] - work["start"]
assert renderingFor < endTime - startTime
return {"startTime": startTime, "duration": endTime - startTime, "cost": renderingFor}
class WorkerPool:
class Worker:
def run(self, stats):
stats.startWork(Now())
doStuff()
stats.finishWork(Now())
workers = [Worker(), Worker(), Worker()]
def doFrame(self):
# Get the frame time - as defined in the raf spec
raftime = Now()
# Finish the previous stats and send them to javascript
self.last_frame_stats.nextFrameStarting(raftime)
send_stats_to_javascript(self.last_frame_stats.getInfo())
del self.last_frame_stats
# Start a new stats
stats = RenderTimeCounter()
stats.startFrame(raftime)
# Do synchronous javascript work
stats.startWork(t)
do_raf(raftime)
stats.finishWork(t)
# Do some multithreaded painting
for w in self.workers:
w.start()
wait_for_all_to_finish(self.workers)
# Sleep until we are close to frame deadline
time.sleep(now - next_frame_time)
# Do the final fix up rendering work
stats.startWork(t)
do_draw_and_swap()
stats.finishWork(t)
self.last_frame_stats = stats
Closing, summary doc + further discussion: http://lists.w3.org/Archives/Public/public-web-perf/2015Jan/0019.html
We reference IDLE time and we should define it.