<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <div class="moz-cite-prefix">
      <div class="moz-cite-prefix">Hi Pekka,</div>
      <div class="moz-cite-prefix"><br>
      </div>
      <div class="moz-cite-prefix">
        <blockquote type="cite">
          <pre class="moz-quote-pre" wrap="">Did you try making the "middle" QWidget *not* have a wl_surface of its
own?</pre>
        </blockquote>
        <blockquote type="cite">
          <pre class="moz-quote-pre" wrap="">Hack on Qt, then? Sorry, but I don't understand this insistence that
what sounds like a Qt bug must be workaround-able via Wayland.</pre>
        </blockquote>
        <blockquote type="cite">
          <pre class="moz-quote-pre" wrap="">Hmm, that does not sound right to me, but then again, I don't know Qt.

Wayland certainly does not impose such demand.

</pre>
        </blockquote>
      </div>
      <div class="moz-cite-prefix">Well the way this is supposed to
        work, I believe, is:</div>
      <div class="moz-cite-prefix">
        <ol>
          <li>There are two separate systems in operation here: Qt doing
            the general GUI and GStreamer waylandsink displaying the
            video. These systems know nothing of one another.</li>
          <li>The link between these two systems is a Wayland surface in
            the Wayland server. QWidget will manage this surface (raise,
            lower, position etc.) and can draw into it if it wants.</li>
          <li>Waylandsink creates a subsurface of that QWidget Wayland
            surface, sets it to be de-synced and and then proceeds to
            draw into this at the video frame rate.</li>
          <li>There's quite a lot of hardware engine working going on in
            the background. For example video buffers may be in special
            memory like in a video or 2D hardware engine pipeline etc.
            Qt may be using separate 3D engine hardware etc.<br>
          </li>
        </ol>
      </div>
      <div class="moz-cite-prefix">I am not experienced with Wayland,
        but I think a "middle" surface is needed so this can be moved,
        raised,/lowered etc. relative to the applications main QWidgets
        and the waylandsink does not need to know about this (apart from
        resizes). Another option would be to modify waylandsink to do
        the necessary things with its subsurface. But having a separate
        shared surface from the Qt applications main drawing surface
        seems safer and I am trying to keep with what I think is the
        accepted method with minimal changes to upstream code.<br>
      </div>
      <div class="moz-cite-prefix"><br>
      </div>
      <div class="moz-cite-prefix">This Gstreamer video display method
        came from the older X11 way of doing this with XWindows.</div>
      <div class="moz-cite-prefix"><br>
      </div>
      <div class="moz-cite-prefix">As stated the reason this is not
        working with Qt6/Wayland/Weston is probably a Qt6
        bug/issue/feature. However a way to understand what is happening
        is to look at the shared Wayland level and maybe there is a way
        with Wayland protocol commands of overcoming the issue so I can
        work around the problem I am having in a short time
        (timescales!) before a more proper fix is worked out. For
        example in X11 an <span>XMapWindow() or </span>XRaiseWindow()
        request or positioning/size requests may have worked and I
        wondered if I could do the same sort of thing in Wayland.<span
          class="ILfuVd" lang="en"><span class="hgKElc"></span></span></div>
      <div class="moz-cite-prefix"><br>
      </div>
      <div class="moz-cite-prefix">Even if the QtWayland issue is fixed,
        I may have to do something at the Wayland level as I'm not sure
        if subsurfaces are effectively moved, raised/lowered etc. when
        their parent surface is changed Wayland.</div>
      <div class="moz-cite-prefix"><br>
      </div>
      <div class="moz-cite-prefix">Anyway as David has suggested, I have
        raised an issue on the Qt Jira bugs list at:
        <a class="moz-txt-link-freetext" href="https://bugreports.qt.io/browse/QTBUG-122941">https://bugreports.qt.io/browse/QTBUG-122941</a>.<br>
      </div>
      <div class="moz-cite-prefix"><br>
      </div>
      <div class="moz-cite-prefix">Terry</div>
      <div class="moz-cite-prefix"><br>
      </div>
      <div class="moz-cite-prefix"><br>
      </div>
    </div>
    <div class="moz-cite-prefix">On 29/02/2024 13:39, Pekka Paalanen
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:20240229153928.4bc948d8@eldfell">
      <pre class="moz-quote-pre" wrap="">On Wed, 28 Feb 2024 18:04:28 +0000
Terry Barnaby <a class="moz-txt-link-rfc2396E" href="mailto:terry1@beam.ltd.uk"><terry1@beam.ltd.uk></a> wrote:

</pre>
      <blockquote type="cite">
        <pre class="moz-quote-pre" wrap="">Hi Pekka,

Some questions below:

Thanks

Terry
On 26/02/2024 15:56, Pekka Paalanen wrote:
</pre>
        <blockquote type="cite">
          <pre class="moz-quote-pre" wrap="">Ok. What Wayland API requests cause a surface to actually be mapped  
</pre>
          <blockquote type="cite">
            <pre class="moz-quote-pre" wrap="">(Sorry don't really know Wayland protocol) ?  
</pre>
          </blockquote>
          <pre class="moz-quote-pre" wrap="">Hi Terry,

the basic protocol object is wl_surface. The wl_surface needs to be
given a "role". This is a specific protocol term. xdg_surface and
xdg_toplevel can give a wl_surface the role of a top-level window,
which means it can get mapped when you play by the rules set in the
xdg_toplevel specification.

Sub-surface is another role.

So the rules are always role specific, but at some point they all
require content on the wl_surface, which is given with the attach
request followed by a commit request. Role rules specify when and how
that can be done.  
</pre>
        </blockquote>
        <pre class="moz-quote-pre" wrap="">
Yes, I have heard that. But what I don't knoe is from the client:

 1. How do I find out the surfaces role ?
</pre>
      </blockquote>
      <pre class="moz-quote-pre" wrap="">
It is what you (or Qt, or Gst) set it to. There is no way to query it
(or any other thing) back by Wayland.

If you look at a protocol dump (e.g. WAYLAND_DEBUG=client in
environment), you can could follow the protocol messages and trace back
what the role was set to.

</pre>
      <blockquote type="cite">
        <pre class="moz-quote-pre" wrap=""> 2. How would I set the surface to have a role such that it would be
    mapped and thus visible ? Just wondering if I can work around what I
    think is a QtWayland bug/issue/feature to make sure by second
    Widgets surface is mapped/visible so that the waylandsink subsurface
    can work. With X11 there were API calls to change the Windows state
    and I was looking for something similar with Wayland.
</pre>
      </blockquote>
      <pre class="moz-quote-pre" wrap="">
There is no simple answer to this. You pick a role you need, and then
play by the protocol spec.

You do not have any surfaces without roles, though, so this would not
help you anyway. Roles cannot be changed, only set once per wl_surface
life time. Sub-surface is a role.

</pre>
      <blockquote type="cite">
        <pre class="moz-quote-pre" wrap="">
I need to find some way to actually display video, simply and 
efficiently on an embedded platform, in a Qt application in the year 2024 :)

I have tried lots of work arounds but none have worked due to either Qt 
issues, Wayland restrictions, Gstreamer restrictions, Weston 
issues/restrictions, NXP hardware engine issues/restrictions etc. Any 
ideas gratefully received!

</pre>
      </blockquote>
      <pre class="moz-quote-pre" wrap="">
Did you try making the "middle" QWidget *not* have a wl_surface of its
own?

</pre>
      <blockquote type="cite">
        <blockquote type="cite">
          <pre class="moz-quote-pre" wrap=""> 
</pre>
          <blockquote type="cite">
            <pre class="moz-quote-pre" wrap="">The higher level surfaces are created/managed by QtWayland, but maybe I
can override somehow.
 
</pre>
          </blockquote>
          <pre class="moz-quote-pre" wrap="">That does not feel like a good idea to me. But I also cannot really
help you, because this all seems to be pointing at Qt which I know
nothing about.  
</pre>
        </blockquote>
        <pre class="moz-quote-pre" wrap="">
Yes, thats probably true. But I need to get this to work somehow, even 
if a kludge for now.
</pre>
      </blockquote>
      <pre class="moz-quote-pre" wrap="">
Hack on Qt, then? Sorry, but I don't understand this insistence that
what sounds like a Qt bug must be workaround-able via Wayland.


</pre>
      <blockquote type="cite">
        <blockquote type="cite">
          <pre class="moz-quote-pre" wrap=""> 
</pre>
          <blockquote type="cite">
            <blockquote type="cite">
              <pre class="moz-quote-pre" wrap="">    
</pre>
              <blockquote type="cite">
                <pre class="moz-quote-pre" wrap="">As mentioned before, If I use QPainter to draw into the video QWidget it
actually draws into the top QWidgets 16 surface using Wayland protocol.
I would have thought it would draw into its own QWidget surface 18 as it
has Qt::WA_NativeWindow set ?  
</pre>
              </blockquote>
            </blockquote>
          </blockquote>
          <pre class="moz-quote-pre" wrap="">This question seems to be the essence. If Qt worked like you expected,
then I think the whole program would work.

However, there is no need (from Wayland perspective) to have a
wl_surface as "surface 18" in the middle. What would be best is if you
could somehow have that "middle" QWidget but without it's own
wl_surface. Have the QWidget control the GStreamer wl_surface position
through wl_subsurface interface, while GStreamer plays the video
through wl_surface interface.

Wayland does not relay sub-surface resizing or positioning between two
client-side components at all. There is not even a way query a
sub-surface position. So the positioning and sizing is all done in
Qt<->GStreamer somehow without Wayland in between. Only the end result
gets sent over Wayland to display: Qt sets up the position and
GStreamer sets up the size and content.  
</pre>
        </blockquote>
        <pre class="moz-quote-pre" wrap="">
I think this middle surface is needed so that Qt can manage the 
"Windows" at this level, like raise, lower, resize et. and Wayland 
</pre>
      </blockquote>
      <pre class="moz-quote-pre" wrap="">
Hmm, that does not sound right to me, but then again, I don't know Qt.

Wayland certainly does not impose such demand.

</pre>
      <blockquote type="cite">
        <pre class="moz-quote-pre" wrap="">sink's subsurface that is below this is separate and can be de-synced 
for the video display etc. I normally (on X11 and with Qt5/Wayland), 
respond to QWidget resizes and use the Gstreamer API calls to 
position/resize the waylandsink's sub-surface. This all works quite 
nicely under X11 and worked (although not nicely) under Qt5/Wayland.

</pre>
        <blockquote type="cite">
          <pre class="moz-quote-pre" wrap=""> 
</pre>
          <blockquote type="cite">
            <blockquote type="cite">
              <blockquote type="cite">
                <pre class="moz-quote-pre" wrap="">I assume that Qtwayland is not "activating" the video QWidget's surface
or using it for some reason (send subsurface expose events ?) ?
    
</pre>
              </blockquote>
              <pre class="moz-quote-pre" wrap="">If that's true, then it is very relevant. A sub-surface becomes mapped
and visible when:

- its parent surface is mapped and visible, and

- the parent surface is committed after the sub-surface has been
    created and associated, and

- if the sub-surface is in synchronized mode, there also needs to be a
    parent surface commit after every sub-surface commit you want to
    become visible. So if you do the first sub-surface sync-mode commit
    with a buffer after the parent has already committed the
    sub-surface's creation, the parent surface needs too commit again.

This applies recursively, too, and you have a sub-sub-surface there.

Do you actually need to sub-surface in the middle? Have you tried
without it?  
</pre>
            </blockquote>
            <pre class="moz-quote-pre" wrap="">I am not doing anything with Wayland directly. Qt is managing the higher
level surfaces/subsurfaces and then GStreamers waylandsink is passed one
of these Qt managed surfaces and it creates the subsurface 44. Looking
at waylandsink it should set this subsurface to be desynced so it can
draw into this surface without synchronising to the parents surface
managed by Qt.  
</pre>
          </blockquote>
          <pre class="moz-quote-pre" wrap="">Right, and desync is not enough if its parent is not mapped.
 
</pre>
          <blockquote type="cite">
            <pre class="moz-quote-pre" wrap="">All I am trying to do is use the technique as mentioned in various
forums/lists to get GStreamer to display a video such that it "appears"
where a QWidget is on the screen. Mind you all of this info is very
rough and ready. For X11 it appears stable, but for Qt/Wayland the info,
and it appears functionality, is not quite all there.

When you say a sub-surface in the middle I presume you mean the surface
18 of the lower QWidget ? Well I have tried using the top most QWidget's
surface 16 and the video is displayed, although all over the
application. I really need to manage this surface so it can be raised,
lowered and resizes amongst the other QWidgets somehow. I have tried
using direct Wayland API calls to create a subsurface manually from the
top surface but so far I have just got protocol errors while trying
this. It may be my bad Wayland client code or how it is interfering with
Qt's Wayland interface.

I have even tried using a separate top level surface. Unfortunately as
the standard Wayland protocols do not allow an application to move or
manage top level Windows this is not useful. I guess I could create an
extra Wayland/Weston server protocol to allow my app (embedded system)
to manage these windows, but I was trying to do things in as standard a
way as possible.  
</pre>
          </blockquote>
          <pre class="moz-quote-pre" wrap="">Rather than "more Wayland", I suspect you should look into "more Qt". I
think it would only get even more fragile if you attempted to override
what Qt does. They must have a way to make this work somehow.  
</pre>
        </blockquote>
        <pre class="moz-quote-pre" wrap="">
Well I am coming to the conclusion that it doesn't currently work under 
QtWayland. I will start delving into that, but again there is not much 
documentation on how it works that I have found to give me a pointer on 
where to look. The fact that QWidgets are not drawing into their own 
surfaces is a bit worrying, maybe some issue were actually found when 
trying to do that.
</pre>
      </blockquote>
      <pre class="moz-quote-pre" wrap="">
Right.


Thanks,
pq


</pre>
      <blockquote type="cite">
        <blockquote type="cite">
          <blockquote type="cite">
            <blockquote type="cite">
              <blockquote type="cite">
                <pre class="moz-quote-pre" wrap="">I note in the qtwayland change logs, for the earlier QT5 for subsurface
changes:
dist/changes-5.6.3: - [QTBUG-52118] Fixed subsurface positions sometimes
not being committed.
dist/changes-5.11.2: - [QTBUG-69643] Fixed a bug where subsurfaces would
not be rendered if clients added them before a WaylandQuickItem was
created for the parent surface
dist/changes-5.12.0: - [QTBUG-49809] Added support for
wl_subsurface.place_above and place_below in WaylandQuickItem.
dist/changes-5.15.2: - [QTBUG-86176] We now send subsurface expose
events when a different toplevel (such as a dialog) is configured.

Could any of these be related ?

Terry  
</pre>
              </blockquote>
            </blockquote>
            <pre class="moz-quote-pre" wrap=""> 
</pre>
          </blockquote>
        </blockquote>
      </blockquote>
      <pre class="moz-quote-pre" wrap="">
</pre>
    </blockquote>
    <p><br>
    </p>
  </body>
</html>