<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<div class="moz-cite-prefix">On 10/02/2014, Jason Ekstrand wrote :<br>
</div>
<blockquote
cite="mid:CAOFGe96L_uNKKu7xD+cJ4V+cyjw8Lo8KzN1yNjHWaTNHdE+msA@mail.gmail.com"
type="cite">
<div dir="ltr"><br>
<div class="gmail_extra"><br>
<br>
<div class="gmail_quote">On Mon, Feb 10, 2014 at 3:53 AM,
Pekka Paalanen <span dir="ltr"><<a
moz-do-not-send="true" href="mailto:ppaalanen@gmail.com"
target="_blank">ppaalanen@gmail.com</a>></span>
wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="">On Sat, 8 Feb 2014 15:23:29 -0600<br>
Jason Ekstrand <<a moz-do-not-send="true"
href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>>
wrote:<br>
<br>
> Pekka,<br>
> First off, I think you've done a great job
over-all. I think it will both<br>
> cover most cases and work well I've got a few
comments below.<br>
<br>
</div>
Thank you for the review. :-)<br>
Replies below.<br>
<div>
<div class="h5"><br>
> On Thu, Jan 30, 2014 at 9:35 AM, Pekka Paalanen
<<a moz-do-not-send="true"
href="mailto:ppaalanen@gmail.com">ppaalanen@gmail.com</a>>
wrote:<br>
><br>
> > Hi,<br>
> ><br>
> > it's time for a take two on the Wayland
presentation extension.<br>
> ><br>
> ><br>
> > 1. Introduction<br>
> ><br>
> > The v1 proposal is here:<br>
> ><br>
> > <a moz-do-not-send="true"
href="http://lists.freedesktop.org/archives/wayland-devel/2013-October/011496.html"
target="_blank">http://lists.freedesktop.org/archives/wayland-devel/2013-October/011496.html</a><br>
> ><br>
> > In v2 the basic idea is the same: you can
queue frames with a<br>
> > target presentation time, and you can get
accurate presentation<br>
> > feedback. All the details are new, though.
The re-design started<br>
> > from the wish to handle resizing better,
preferably without<br>
> > clearing the buffer queue.<br>
> ><br>
> > All the changed details are probably too
much to describe here,<br>
> > so it is maybe better to look at this as a
new proposal. It<br>
> > still does build on Frederic's work, and
everyone who commented<br>
> > on it. Special thanks to Axel Davy for his
counter-proposal and<br>
> > fighting with me on IRC. :-)<br>
> ><br>
> > Some highlights:<br>
> ><br>
> > - Accurate presentation feedback is possible
also without<br>
> > queueing.<br>
> ><br>
> > - You can queue also EGL-based rendering,
and get presentation<br>
> > feedback if you want. Also EGL can do this
internally, too, as<br>
> > long as EGL and the app do not try to use
queueing at the same time.<br>
> ><br>
> > - More detailed presentation feedback to
better allow predicting<br>
> > future display refreshes.<br>
> ><br>
> > - If wl_viewport is used, neither video
resolution changes nor<br>
> > surface (window) size changes alone
require clearing the queue.<br>
> > Video can continue playing even during
resizes.<br>
</div>
</div>
...<br>
<div>
<div class="h5">> > <interface
name="presentation" version="1"><br>
> > <description summary="timed
presentation related wl_surface requests"><br>
> > The main features of this interface
are accurate presentation<br>
> > timing feedback, and queued wl_surface
content updates to ensure<br>
> > smooth video playback while
maintaining audio/video<br>
> > synchronization. Some features use the
concept of a presentation<br>
> > clock, which is defined in
presentation.clock_id event.<br>
> ><br>
> > Requests 'feedback' and 'queue' can be
regarded as additional<br>
> > wl_surface methods. They are part of
the double-buffered<br>
> > surface state update mechanism, where
other requests first set<br>
> > up the state and then
wl_surface.commit atomically applies the<br>
> > state into use. In other words,
wl_surface.commit submits a<br>
> > content update.<br>
> ><br>
> > Interface wl_surface has requests to
set surface related state<br>
> > and buffer related state, because
there is no separate interface<br>
> > for buffer state alone. Queueing
requires separating the surface<br>
> > from buffer state, and buffer state
can be queued while surface<br>
> > state cannot.<br>
> ><br>
> > Buffer state includes the wl_buffer
from wl_surface.attach, the<br>
> > state assigned by wl_surface requests
frame,<br>
> > set_buffer_transform and
set_buffer_scale, and any<br>
> > buffer-related state from extensions,
for instance<br>
> > wl_viewport.set_source. This state is
inherent to the buffer<br>
> > and the content update, rather than
the surface.<br>
> ><br>
> > Surface state includes all other state
associated with<br>
> > wl_surfaces, like the x,y arguments of
wl_surface.attach, input<br>
> > and opaque regions, damage, and
extension state like<br>
> > wl_viewport.destination. In general,
anything expressed in<br>
> > surface local coordinates is better as
surface state.<br>
> ><br>
> > The standard way of posting new
content to a surface using the<br>
> > wl_surface requests damage, attach,
and commit is called<br>
> > immediate content submission. This
happens when a<br>
> > presentation.queue request has not
been sent since the last<br>
> > wl_surface.commit.<br>
> ><br>
> > The new way of posting a content
update is a queued content<br>
> > update submission. This happens on a
wl_surface.commit when a<br>
> > presentation.queue request has been
sent since the last<br>
> > wl_surface.commit.<br>
> ><br>
> > Queued content updates do not get
applied immediately in the<br>
> > compositor but are pushed to a queue
on receiving the<br>
> > wl_surface.commit. The queue is
ordered by the submission target<br>
> > timestamp. Each item in the queue
contains the wl_buffer, the<br>
> > target timestamp, and all the buffer
state as defined above. All<br>
> > the queued state is taken from the
pending wl_surface state at<br>
> > the time of the commit, exactly like
an immediate commit would<br>
> > have taken it.<br>
> ><br>
> > For instance on a queueing commit, the
pending buffer is queued<br>
> > and no buffer is pending afterwards.
The stored values of the<br>
> > x,y parameters of wl_surface.attach
are reset to zero, but they<br>
> > also are not queued; queued content
updates do not carry the<br>
> > attach offsets. All other surface
state (that is not queued),<br>
> > e.g. damage, is not applied nor reset.<br>
> ><br>
> > Issuing a queueing commit without a
wl_surface.attach is<br>
> > undefined. However, queueing a commit
with explicitly attached<br>
> > NULL wl_buffer works; when and if the
content update is<br>
> > executed, the surface content is
removed as defined for<br>
> > wl_surface.attach.<br>
> ><br>
> > If a queued content update has been
submitted, and the wl_buffer<br>
> > used in the update is destroyed before
the wl_buffer.release<br>
> > event, the results are undefined. The
compositor may or may not<br>
> > have executed the update, therefore
the surface contents become<br>
> > undefined as explained in
wl_surface.attach. Whether any<br>
> > presentation feedback or frame
callbacks occur is undefined.<br>
> ><br>
> > For each surface, the compositor
maintains an association to a<br>
> > single output that is considered as
the main output for the<br>
> > surface. Queued content updates are
synchronized to the<br>
> > surface's main output, to provide a
consistent and meaningful<br>
> > definition of the moment the update is
displayed to the user.<br>
> > When a compositor updates an output,
it processes only the<br>
> > queues of the surfaces whose main
output is the one being<br>
> > updated. The queues of other surfaces,
even if they are part of<br>
> > the redrawing, are not processed at
that time.<br>
> ><br>
> > When a compositor chooses to update an
output, it must predict<br>
> > the presentation clock value when the
display update will occur.<br>
> > For the definition of the moment of
display update, see<br>
> > presentation_feedback.presented.
Therefore if the prediction is<br>
> > absolutely perfect,
presentation_feedback.presented will carry<br>
> > the same clock value.<br>
> ><br>
> > For each surface with queued content
updates and matching main<br>
> > output, the compositor picks the
update with the highest<br>
> > timestamp no later than a half frame
period after the predicted<br>
> > presentation time. The intent is to
pick the content update<br>
> > whose target timestamp as rounded to
the output refresh period<br>
> > granularity matches the same display
update as the compositor is<br>
> > targeting, while not displaying any
content update more than a<br>
> ><br>
><br>
> I'm not really following 100% here. It's not your
fault, this is just a<br>
> terribly awkward sort of thing to try and put
into English. It sounds to<br>
> me like the following: If P0 is the time of the
next present and P1 is the<br>
> time of the one after that, you look for the
largest thing less than the<br>
> average of P1 and P2. Is this correct? Why go
for the average? The<br>
> client is going to have to adjust anyway.<br>
><br>
><br>
> > half frame period too early. If all
the updates in the queue are<br>
> > already late, the highest timestamp
update is taken regardless<br>
> > of how late it is. Once an update in a
queue has been chosen,<br>
> > all remaining updates with an earlier
timestamp in the queue are<br>
> > discarded.<br>
> ><br>
><br>
> Ok, I think what you are saying works. Again,
it's difficult to parse but<br>
> these things always are.<br>
><br>
<br>
</div>
</div>
Yes, it is hard to write a generic algorithm in English.
Axel did a<br>
nice job clarifying it. I hope I can improve on the
language after I<br>
have actually implemented this and any possible changes we
need to this.<br>
<br>
Also, the inline documentation in the XML file is getting
a bit out of<br>
hand, lacking in expressional power. I would have liked to
use<br>
sub-headings, the algorithm could use pseudo-code, etc,
but they just<br>
don't really exist here. Yet, I want these things to be
part of the<br>
protocol spec, so the semantics of the protocol get
properly defined.<br>
<div class=""><br>
> > 4.5. The frame callback and swap
interval<br>
> ><br>
> > The frame callback needs to be with the buffer
state, so it gets<br>
> > queued. If a client makes e.g. EGL's commits
queued, EGL may<br>
> > still rely on frame callbacks for blocking
apps properly, and<br>
> > that is related to presenting the buffer, not
just the very next<br>
> > output refresh. EGL may also internally use
queueing and<br>
> > feedback to implement swap interval > 1.<br>
> ><br>
><br>
> Doesn't this mean that you need eglSwapInterval(0)
if you're queueing?<br>
> This is probably the case anyway, but it might be
worth noting explicitly.<br>
> I think what you're doing with frame callbacks is
sane, but I'm not sure.<br>
<br>
</div>
Yeah, swapinterval zero is needed indeed. Personally I
would be more<br>
worried about whether an EGL implementation agrees to
allocate new<br>
buffers if the app is queueing in advance. I suspect
queueing many<br>
frames in advance won't work with EGL in practice.<br>
<br>
But you can still queue a frame at a time, that might be
enough for<br>
e.g. GL-based video players under good conditions. That
might not need<br>
swapinterval zero, either.<br>
<div class=""><br>
> My one latent concern is that I still don't think
we're entirely handling<br>
> the case that QtQuick wants. What they want is to
do their rendering a few<br>
> frames in advance in case of CPU/GPU jitter.
Technically, this extension<br>
> handles this by the client simply doing a good job
of guessing presentation<br>
> times on a one-per-frame baseis. However, it
doesn't allow for any damage<br>
> tracking. In the case of QtQuick they want a
linear queue of buffers where<br>
> no buffer ever gets skipped. In this case, you
could do damage tracking by<br>
> allowing it to accumulate from one frame to another
and you get all of the<br>
> damage-tracking advantages that you had before.
I'm not sure how much this<br>
> matters, but it might be worth thinking about it.<br>
<br>
</div>
Does it really want to display *every* frame regardless of
time? It<br>
doesn't matter that if a deadline is missed, the animation
slows down<br>
rather than jumps to keep up with intended velocity?<br>
</blockquote>
<div><br>
</div>
<div>That is my understanding of how it works now. I
*think* they figure the compositor isn't the bottle-kneck
and that it will git its 60 FPS. That said, I don't
actually work on QtQuick. I'm just trying to make sure
they don't get completely left out in the cold.<br>
</div>
<div> </div>
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Axel has a good point, cannot this be just done client
side and<br>
immediate updates based on frame callbacks?<br>
</blockquote>
<div><br>
</div>
<div>Probably not. They're using GLES and EGL so they
can't draw early and just stash the buffer.<br>
</div>
<div> </div>
</div>
</div>
</div>
</blockquote>
That's not a problem.<br>
They can render to a fbo linked to an EGLImage, and we can get a
wl_buffer from an EGLImage.<br>
<br>
Axel Davy<br>
</body>
</html>