Hi Jonas,
On 17 March 2013 09:13, Jonas Ådahl <[email protected]> wrote:
> A logical surface is a special kind of surface that never gets its own
> buffer attached, or opaque region set etc. It is obtained by using a
> surface handle that can be shared in some way between clients. A handle
> is a server wide unique identifier retrieved from the server given a
> real surface. Currently a logical surface is limited to only be usable
> as a sub-surface.
>
I've been thinking about exactly the same thing, but with additional
complications to the usecases. There are two I think we need to support:
- export a surface from client A such client B can create a subsurface
with it
- export a surface from client A such that client B can act as its own
compositor, i.e. being notified of incoming buffers and being able to
import them
The latter is required for things like WebGL where you end up rendering to
a transformed surface.
I do really like the acquire_handle vs. release_handle semantics, but I've
gone a slightly different way here. For the exporting client (let's call
it the child), the surface becomes a new surface role, which is only
capable of being exported; it can't, e.g., be a shell surface at the same
time. For the importing client, it gets a new surface type which can
either be used as a child to construct a new surface, or provide the
importing client with notifications that a new buffer has been attached and
is available for usage.
If used in the latter mode, in theory new buffers could be used as
EGLImages or SHM buffers, as well as being attachable to an existing
surface. To support resizes, the surface would still need an out-of-band
notification that a resize was beginning, as well as the target size, but
the dx/dy/width/height parameters in buffer_available should hopefully be
enough to provide the acknowledgement from the exporter to importer that
the resize has been completed. In this sense, it works quite similarly to
the wl_subsurface parent vs. independent commit modes.
I've gone the separate object route rather than sharing objects, because I
think that way is seriously painful, and is wide open for abuse, with
multiple clients stepping on each others' toes in an X11 fashion. I think
having the clean separation is really useful, and has the minimum potential
for anything to go wrong.
So it's a little more complicated (and comes without a proof of concept),
but I think hopefully should cover everything. Any comments?
Cheers,
Daniel
<protocol name="surface_export">
<copyright>
Copyright © 2013 Jonas Ådahl
Copyright © 2013 Collabora, Ltd.
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that copyright notice and this permission
notice appear in supporting documentation, and that the name of
the copyright holders not be used in advertising or publicity
pertaining to distribution of the software without specific,
written prior permission. The copyright holders make no
representations about the suitability of this software for any
purpose. It is provided "as is" without express or implied
warranty.
THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
</copyright>
<!-- XXX: All the integration around this is missing, e.g.:
- support in wl_subsurface to build a new subsurface from
a wl_surface parent and a wl_foreign_surface child
- support for creating a new wl_shm_buffer from a foreign
buffer
- any EGL integration of EGL_WAYLAND_FOREIGN_BUFFER_WL
- probably some other stuff too -->
<interface name="wl_foreign_compositor" version="1">
<description summary="support for foreign and exported surfaces">
This extension includes a new surface subtype, wl_export_surface,
which can only return a handle to be passed to another client to
generate a wl_foreign_surface. Foreign surfaces (i.e. on the
import side) can either be used as a subsurface child, or
generate notifications every time a new buffer is attached, so the
importer can perform its own compositing of the scene.
</description>
<request name="get_export_surface">
<description summary="mark a surface as exportable">
Given a surface handle, wrap it in a wl_export_surface object,
such that it can be exported to other clients. The surface
must not already have another role such as wl_shell_surface.
</description>
<arg name="surface" type="new_id" interface="wl_surface"
summary="the new logical surface object id"/>
<arg name="export" type="new_id" interface="wl_export_surface"
summary="new export surface wrapper"/>
</request>
<request name="get_foreign_surface">
<description summary="import an external surface">
Imports a wl_export_surface from another client, creating
a new wl_foreign_surface object.
</description>
<arg name="foreign" type="new_id" interface="wl_foreign_surface"
summary="new foreign surface wrapper"/>
<arg name="handle" type="uint"
summary="handle from wl_export_surface::acquire_handle"/>
</request>
</interface>
<interface name="wl_export_surface" version="1">
<description summary="surface to export to another client">
This object provides a role for an existing surface, which is to
be exported to another client. Once a handle is acquired, it can
be passed to another client to construct a wl_foreign_surface
with.
</description>
<request name="acquire_handle">
<description summary="acquire surface handle">
Acquire a handle to this surface which can be used to create a
wl_foreign_surface in another client.
</description>
</request>
<request name="release_handle">
<description summary="release surface handle">
Release a surface handle; the handle will no longer be valid,
however existing surfaces created using this handle will not be
destroyed.
</description>
<arg name="handle" type="uint"/>
</request>
<event name="handle">
<description summary="surface handle">
In response to the "acquire_handle" request, provide a unique handle
that can be used by another client to import a foreign surface.
</description>
<arg name="handle" type="uint"/>
</event>
</interface>
<interface name="wl_foreign_surface" version="1">
<description summary="surface imported from another client">
This interface represents a surface imported from another client's
wl_export_surface, which is able to either be used as a subsurface
child, or, if the importer wants to implement its own compositing,
each buffer attached to the originating surface can be delivered to
the wl_foreign_surface for use in client-side compositing.
</description>
<enum name="compositing_mode">
<description summary="compositing mode for this surface">
This request sets the compositing mode for the surface, namely
whether it will be automatically composited by the server, or
whether the client will do its own composition, e.g. through
OpenGL. If the mode is set to server, the server will not
notify the surface of new buffers, and any composition of this
surface on to the display (e.g. through subsurfaces) will be
performed automatically by the server when buffers are attached
to the originating surface. If the mode is set to client, the
server will pass new buffer attachments through the
register_buffer and buffer_available events, so the importing
client may implement its own composition.
</description>
<value name="server" value="0"
summary="server performs composition, no buffer notification"/>
<value name="client" value="1"
summary="client performs composition, receives buffer notification"/>
</enum>
<request name="set_compositing_mode">
<description summary="change compositing mode">
Changes the compositing mode of the surface to one of the values
in the WL_FOREIGN_SURFACE_COMPOSITING_MODE enum. The change will
take effect immediately, however when changing from client to
server, any existing buffers held by the client will not be
destroyed; this has to be done explicitly.
</description>
<arg name="mode" type="uint"/>
</request>
<enum name="buffer_usage">
<description summary="acceptable targets for this buffer">
These values provide the supported targets for this buffer, as a
bitmask; e.g. if the EGLImage and SHM members are both set, the
buffer may be imported through the EGL interface or mapped
through shared memory.
</description>
<entry name="eglimage" value="1"
summary="EGLImage through EGL_WAYLAND_FOREIGN_BUFFER_WL"/>
<entry name="shm" value="2" summary="POSIX shared memory"/>
</enum>
<event name="register_buffer">
<description summary="introduce a new buffer">
Notifies the client of a new buffer; however, clients must not yet
attempt to use the buffer (e.g. for compositing) when this event
is received. This event is only to register the new buffer with the
client; it will not actually be valid until a buffer_available event
is received.
</description>
<arg name="buffer" type="new_id" interface="wl_buffer"
summary="the new buffer object"/>
<arg name="usage" type="uint"
summary="list of acceptable targets"/>
</event>
<event name="buffer_available">
<description summary="buffer available for usage">
A new buffer has been attached to the surface, and should either
be made current or destroyed by the client. The presence of a
new buffer does not cause destruction of an existing buffer.
</description>
<arg name="buffer" type="object" interface="wl_buffer"
summary="the new buffer object"/>
<arg name="dx" type="int"
summary="x position relative to previous buffer"/>
<arg name="dy" type="int"
summary="y position relative to previous buffer"/>
<arg name="width" type="uint" summary="visible width"/>
<arg name="height" type="uint" summary="visible height"/>
</event>
</interface>
</protocol>
_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel