2008-12-02 23:15:01 +03:00
|
|
|
/*
|
Change remaining GPLv2 headers to MIT
The files in question are copyright Benjamin Franzke (who agrees),
Intel Corporation, Red Hat and myself. On behalf of Red Hat,
Richard Fontana says:
"Therefore, to the extent that Red Hat, Inc. has any copyright
interest in the files you cited as of this date (compositor-drm.c,
compositor.c, compositor.h, screenshooter.c in
http://cgit.freedesktop.org/wayland/wayland-demos/tree/compositor),
Red Hat hereby elects to apply the CC0 1.0 Universal Public Domain
Dedication to such copyrighted material. See:
http://creativecommons.org/publicdomain/zero/1.0/legalcode .
Thanks,
Richard E. Fontana
Open Source Licensing and Patent Counsel
Red Hat, Inc."
2011-09-15 23:43:14 +04:00
|
|
|
* Copyright © 2010-2011 Intel Corporation
|
|
|
|
* Copyright © 2008-2011 Kristian Høgsberg
|
2015-02-09 14:16:57 +03:00
|
|
|
* Copyright © 2012-2015 Collabora, Ltd.
|
2008-12-02 23:15:01 +03:00
|
|
|
*
|
2015-06-12 01:35:43 +03:00
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining
|
|
|
|
* a copy of this software and associated documentation files (the
|
|
|
|
* "Software"), to deal in the Software without restriction, including
|
|
|
|
* without limitation the rights to use, copy, modify, merge, publish,
|
|
|
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
|
|
* permit persons to whom the Software is furnished to do so, subject to
|
|
|
|
* the following conditions:
|
2008-12-02 23:15:01 +03:00
|
|
|
*
|
2015-06-12 01:35:43 +03:00
|
|
|
* The above copyright notice and this permission notice (including the
|
|
|
|
* next paragraph) shall be included in all copies or substantial
|
|
|
|
* portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
|
|
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
|
|
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
|
* SOFTWARE.
|
2008-12-02 23:15:01 +03:00
|
|
|
*/
|
|
|
|
|
2011-01-15 01:22:35 +03:00
|
|
|
#include "config.h"
|
|
|
|
|
2012-06-01 15:14:06 +04:00
|
|
|
#include <fcntl.h>
|
2008-10-09 06:51:32 +04:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdint.h>
|
2011-03-11 18:39:20 +03:00
|
|
|
#include <limits.h>
|
2008-11-09 08:22:51 +03:00
|
|
|
#include <stdarg.h>
|
2011-06-21 21:34:19 +04:00
|
|
|
#include <assert.h>
|
2008-10-09 06:51:32 +04:00
|
|
|
#include <sys/ioctl.h>
|
2012-06-01 15:14:06 +04:00
|
|
|
#include <sys/mman.h>
|
2011-06-22 01:32:25 +04:00
|
|
|
#include <sys/wait.h>
|
2011-12-02 17:30:21 +04:00
|
|
|
#include <sys/socket.h>
|
2012-06-11 02:57:39 +04:00
|
|
|
#include <sys/utsname.h>
|
2012-06-18 22:15:18 +04:00
|
|
|
#include <sys/stat.h>
|
2008-10-09 06:51:32 +04:00
|
|
|
#include <unistd.h>
|
2008-11-24 01:07:32 +03:00
|
|
|
#include <math.h>
|
2010-06-11 20:56:24 +04:00
|
|
|
#include <linux/input.h>
|
2011-04-23 21:04:11 +04:00
|
|
|
#include <dlfcn.h>
|
2011-05-02 20:11:07 +04:00
|
|
|
#include <signal.h>
|
2012-01-16 20:53:54 +04:00
|
|
|
#include <setjmp.h>
|
2012-06-09 00:16:52 +04:00
|
|
|
#include <sys/time.h>
|
|
|
|
#include <time.h>
|
2014-08-27 14:31:26 +04:00
|
|
|
#include <errno.h>
|
2008-12-30 22:31:33 +03:00
|
|
|
|
compositor: Implement JSON-timeline logging
Logging is activated and deactivated with the debug key binding 't'.
When activated, it creates a new log file, where it records the events.
The log file contains events and detailed object information entries in
JSON format, and is meant to be parsed in sequence from beginning to the
end.
The emitted events are mostly related to the output repaint cycle, like
when repaint begins, is submitted to GPU, and when it completes on a
vblank. This is recorded per-output. Also some per-surface events are
recorded, including when surface damage is flushed.
To reduce the log size, events refer to objects like outputs and
surfaces by id numbers. Detailed object information is emitted only as
needed: on the first object occurrence, and afterwards only if
weston_timeline_object::force_refresh asks for it.
The detailed information for surfaces includes the string returned by
weston_surface::get_label. Therefore it is important to set
weston_timeline_object::force_refresh = 1 whenever the string would
change, so that the new details get recorded.
A rudimentary parser and SVG generator can be found at:
https://github.com/ppaalanen/wesgr
The timeline logs can answer questions including:
- How does the compositor repaint cycle work timing-wise?
- When was the vblank deadline missed?
- What is the latency from surface commit to showing the new content on
screen?
- How long does it take to process the scenegraph?
v2: weston_surface::get_description renamed to get_label.
v3: reafctor a bit into fprint_quoted_string().
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2014-11-12 16:09:24 +03:00
|
|
|
#include "timeline.h"
|
|
|
|
|
2010-06-05 05:52:02 +04:00
|
|
|
#include "compositor.h"
|
2016-04-15 14:47:08 +03:00
|
|
|
#include "viewporter-server-protocol.h"
|
2016-02-18 17:53:27 +03:00
|
|
|
#include "presentation-time-server-protocol.h"
|
2015-06-16 01:37:08 +03:00
|
|
|
#include "shared/helpers.h"
|
2015-06-16 01:37:07 +03:00
|
|
|
#include "shared/os-compatibility.h"
|
2016-08-04 03:40:52 +03:00
|
|
|
#include "shared/string-helpers.h"
|
2015-07-03 15:44:50 +03:00
|
|
|
#include "shared/timespec-util.h"
|
2012-06-09 00:16:52 +04:00
|
|
|
#include "git-version.h"
|
2013-02-16 05:53:20 +04:00
|
|
|
#include "version.h"
|
2016-06-29 12:54:26 +03:00
|
|
|
#include "plugin-registry.h"
|
2008-12-12 07:18:45 +03:00
|
|
|
|
2014-05-21 17:17:27 +04:00
|
|
|
#define DEFAULT_REPAINT_WINDOW 7 /* milliseconds */
|
|
|
|
|
2012-12-14 19:37:25 +04:00
|
|
|
static void
|
2013-05-28 18:23:36 +04:00
|
|
|
weston_output_transform_scale_init(struct weston_output *output,
|
|
|
|
uint32_t transform, uint32_t scale);
|
2012-12-14 19:37:25 +04:00
|
|
|
|
2013-06-26 21:08:46 +04:00
|
|
|
static void
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_compositor_build_view_list(struct weston_compositor *compositor);
|
2013-06-26 21:08:46 +04:00
|
|
|
|
2014-11-04 19:47:33 +03:00
|
|
|
static void weston_mode_switch_finish(struct weston_output *output,
|
|
|
|
int mode_changed,
|
|
|
|
int scale_changed)
|
2012-04-17 13:20:47 +04:00
|
|
|
{
|
2012-12-14 19:37:26 +04:00
|
|
|
struct weston_seat *seat;
|
2013-09-19 01:56:36 +04:00
|
|
|
struct wl_resource *resource;
|
2012-12-14 19:37:26 +04:00
|
|
|
pixman_region32_t old_output_region;
|
2014-11-05 22:26:57 +03:00
|
|
|
int version;
|
2013-05-28 18:23:38 +04:00
|
|
|
|
2012-12-14 19:37:26 +04:00
|
|
|
pixman_region32_init(&old_output_region);
|
|
|
|
pixman_region32_copy(&old_output_region, &output->region);
|
|
|
|
|
2012-12-14 19:37:25 +04:00
|
|
|
/* Update output region and transformation matrix */
|
2013-09-19 01:56:35 +04:00
|
|
|
weston_output_transform_scale_init(output, output->transform, output->current_scale);
|
2012-12-14 19:37:25 +04:00
|
|
|
|
|
|
|
pixman_region32_init(&output->previous_damage);
|
|
|
|
pixman_region32_init_rect(&output->region, output->x, output->y,
|
|
|
|
output->width, output->height);
|
|
|
|
|
|
|
|
weston_output_update_matrix(output);
|
|
|
|
|
2012-12-14 19:37:26 +04:00
|
|
|
/* If a pointer falls outside the outputs new geometry, move it to its
|
|
|
|
* lower-right corner */
|
|
|
|
wl_list_for_each(seat, &output->compositor->seat_list, link) {
|
2015-08-01 00:55:32 +03:00
|
|
|
struct weston_pointer *pointer = weston_seat_get_pointer(seat);
|
2012-12-14 19:37:26 +04:00
|
|
|
int32_t x, y;
|
|
|
|
|
|
|
|
if (!pointer)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
x = wl_fixed_to_int(pointer->x);
|
|
|
|
y = wl_fixed_to_int(pointer->y);
|
|
|
|
|
|
|
|
if (!pixman_region32_contains_point(&old_output_region,
|
|
|
|
x, y, NULL) ||
|
|
|
|
pixman_region32_contains_point(&output->region,
|
|
|
|
x, y, NULL))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (x >= output->x + output->width)
|
|
|
|
x = output->x + output->width - 1;
|
|
|
|
if (y >= output->y + output->height)
|
|
|
|
y = output->y + output->height - 1;
|
|
|
|
|
|
|
|
pointer->x = wl_fixed_from_int(x);
|
|
|
|
pointer->y = wl_fixed_from_int(y);
|
|
|
|
}
|
|
|
|
|
|
|
|
pixman_region32_fini(&old_output_region);
|
|
|
|
|
2014-11-10 19:29:59 +03:00
|
|
|
if (!mode_changed && !scale_changed)
|
|
|
|
return;
|
|
|
|
|
2013-09-19 01:56:36 +04:00
|
|
|
/* notify clients of the changes */
|
2014-11-04 19:47:33 +03:00
|
|
|
wl_resource_for_each(resource, &output->resource_list) {
|
|
|
|
if (mode_changed) {
|
|
|
|
wl_output_send_mode(resource,
|
|
|
|
output->current_mode->flags,
|
|
|
|
output->current_mode->width,
|
|
|
|
output->current_mode->height,
|
|
|
|
output->current_mode->refresh);
|
|
|
|
}
|
|
|
|
|
2014-11-05 22:26:57 +03:00
|
|
|
version = wl_resource_get_version(resource);
|
|
|
|
if (version >= WL_OUTPUT_SCALE_SINCE_VERSION && scale_changed)
|
2014-11-04 19:47:33 +03:00
|
|
|
wl_output_send_scale(resource, output->current_scale);
|
|
|
|
|
2014-11-05 22:26:57 +03:00
|
|
|
if (version >= WL_OUTPUT_DONE_SINCE_VERSION)
|
|
|
|
wl_output_send_done(resource);
|
2014-11-04 19:47:33 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-28 00:22:57 +03:00
|
|
|
|
|
|
|
static void
|
|
|
|
weston_compositor_reflow_outputs(struct weston_compositor *compositor,
|
|
|
|
struct weston_output *resized_output, int delta_width);
|
|
|
|
|
2014-11-04 19:47:33 +03:00
|
|
|
WL_EXPORT int
|
|
|
|
weston_output_mode_set_native(struct weston_output *output,
|
|
|
|
struct weston_mode *mode,
|
|
|
|
int32_t scale)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
int mode_changed = 0, scale_changed = 0;
|
2016-05-28 00:22:57 +03:00
|
|
|
int32_t old_width;
|
2014-11-04 19:47:33 +03:00
|
|
|
|
|
|
|
if (!output->switch_mode)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (!output->original_mode) {
|
|
|
|
mode_changed = 1;
|
|
|
|
ret = output->switch_mode(output, mode);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
if (output->current_scale != scale) {
|
|
|
|
scale_changed = 1;
|
|
|
|
output->current_scale = scale;
|
2013-09-19 01:56:36 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-28 00:22:57 +03:00
|
|
|
old_width = output->width;
|
2014-11-04 19:47:33 +03:00
|
|
|
output->native_mode = mode;
|
|
|
|
output->native_scale = scale;
|
|
|
|
|
|
|
|
weston_mode_switch_finish(output, mode_changed, scale_changed);
|
|
|
|
|
2016-05-28 00:22:57 +03:00
|
|
|
if (mode_changed || scale_changed) {
|
|
|
|
weston_compositor_reflow_outputs(output->compositor, output, output->width - old_width);
|
|
|
|
|
|
|
|
wl_signal_emit(&output->compositor->output_resized_signal, output);
|
|
|
|
}
|
2014-11-04 19:47:33 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
WL_EXPORT int
|
|
|
|
weston_output_mode_switch_to_native(struct weston_output *output)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
int mode_changed = 0, scale_changed = 0;
|
|
|
|
|
|
|
|
if (!output->switch_mode)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (!output->original_mode) {
|
|
|
|
weston_log("already in the native mode\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
/* the non fullscreen clients haven't seen a mode set since we
|
|
|
|
* switched into a temporary, so we need to notify them if the
|
|
|
|
* mode at that time is different from the native mode now.
|
|
|
|
*/
|
|
|
|
mode_changed = (output->original_mode != output->native_mode);
|
|
|
|
scale_changed = (output->original_scale != output->native_scale);
|
|
|
|
|
|
|
|
ret = output->switch_mode(output, output->native_mode);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
output->current_scale = output->native_scale;
|
|
|
|
|
|
|
|
output->original_mode = NULL;
|
|
|
|
output->original_scale = 0;
|
|
|
|
|
|
|
|
weston_mode_switch_finish(output, mode_changed, scale_changed);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
WL_EXPORT int
|
|
|
|
weston_output_mode_switch_to_temporary(struct weston_output *output,
|
|
|
|
struct weston_mode *mode,
|
|
|
|
int32_t scale)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!output->switch_mode)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
/* original_mode is the last mode non full screen clients have seen,
|
|
|
|
* so we shouldn't change it if we already have one set.
|
|
|
|
*/
|
|
|
|
if (!output->original_mode) {
|
|
|
|
output->original_mode = output->native_mode;
|
|
|
|
output->original_scale = output->native_scale;
|
|
|
|
}
|
|
|
|
ret = output->switch_mode(output, mode);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
output->current_scale = scale;
|
|
|
|
|
|
|
|
weston_mode_switch_finish(output, 0, 0);
|
|
|
|
|
|
|
|
return 0;
|
2012-04-17 13:20:47 +04:00
|
|
|
}
|
|
|
|
|
2012-02-28 19:59:33 +04:00
|
|
|
static void
|
2012-10-10 13:49:28 +04:00
|
|
|
region_init_infinite(pixman_region32_t *region)
|
2012-02-28 19:59:33 +04:00
|
|
|
{
|
2012-10-10 13:49:28 +04:00
|
|
|
pixman_region32_init_rect(region, INT32_MIN, INT32_MIN,
|
|
|
|
UINT32_MAX, UINT32_MAX);
|
2012-02-28 19:59:33 +04:00
|
|
|
}
|
|
|
|
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
static struct weston_subsurface *
|
|
|
|
weston_surface_to_subsurface(struct weston_surface *surface);
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
WL_EXPORT struct weston_view *
|
|
|
|
weston_view_create(struct weston_surface *surface)
|
|
|
|
{
|
|
|
|
struct weston_view *view;
|
|
|
|
|
2014-11-21 09:21:57 +03:00
|
|
|
view = zalloc(sizeof *view);
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
if (view == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
view->surface = surface;
|
compositor: Assign new views to the primary plane
When we create a new view, assign it to the primary plane from the
beginning.
Currently, every view across the compositor will be assigned to a plane
during every repaint cycle of every output: the DRM renderer's
assign_planes hook will either move a view to a drm_plane, or to the
primary plane if a suitable drm_plane could not be found for the output
it is on. There are no other assign_planes implementation, and the
fallback when none is provided, is to assign every view to the primary
plane.
DRM's behaviour is undesirable in multi-output situations, since it
means that views which were on a plane on one output will be demoted to
the primary plane; doing this causes damage, which will cause a spurious
repaint for the output. This spurious repaint will have no effect on the
other output, but it will do the same demotion of views to the primary
plane, which will again provoke a repaint on the other output.
With a simple fix for this behaviour (i.e. not moving views which are
only visible on other outputs), the following behaviour is observed:
- outputs A and B are present
- views A and B are created for those outputs respectively, with SHM
buffers attached; view->plane == NULL for both
- current buffer content for views A and B are uploaded to the
renderer
- output A runs its repaint cycle, and sets keep_buffer to false on
surface B's output, as it can never be promoted to a plane; it does
not move view B to another plane
- output B runs its repaint cycle, and moves view B to the primary
plane
- weston_view_assign_to_plane has work to do (as the plane is changing
from NULL to the primary plane), calls weston_surface_damage and
calls weston_surface_damage
- weston_surface_damage re-uploads buffer content, possibly from
nowhere at all; e508ce6a notes that this behaviour is broken
Assigning views to the primary plane when created makes it possible to
fix the DRM assign_planes implementation: assign_planes will always set
keep_buffer to true if there is any chance the buffer can ever be
promoted to a plane, regardless of view configruation. If the buffer
cannot be promoted to a plane, it must by definition never migrate from
the primary plane. This means that there is no opportunity to hit the
same issue, where the buffer content has already been discarded, but
weston_view_assign_to_plane is not a no-op.
Signed-off-by: Daniel Stone <daniels@collabora.com>
Reviewed: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2016-12-09 19:27:54 +03:00
|
|
|
view->plane = &surface->compositor->primary_plane;
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
|
|
|
|
/* Assign to surface */
|
|
|
|
wl_list_insert(&surface->views, &view->surface_link);
|
|
|
|
|
|
|
|
wl_signal_init(&view->destroy_signal);
|
|
|
|
wl_list_init(&view->link);
|
2014-07-09 23:12:56 +04:00
|
|
|
wl_list_init(&view->layer_link.link);
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
|
|
|
|
pixman_region32_init(&view->clip);
|
|
|
|
|
|
|
|
view->alpha = 1.0;
|
|
|
|
pixman_region32_init(&view->transform.opaque);
|
|
|
|
|
|
|
|
wl_list_init(&view->geometry.transformation_list);
|
|
|
|
wl_list_insert(&view->geometry.transformation_list,
|
|
|
|
&view->transform.position.link);
|
|
|
|
weston_matrix_init(&view->transform.position.matrix);
|
|
|
|
wl_list_init(&view->geometry.child_list);
|
2015-02-16 15:39:11 +03:00
|
|
|
pixman_region32_init(&view->geometry.scissor);
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
pixman_region32_init(&view->transform.boundingbox);
|
|
|
|
view->transform.dirty = 1;
|
|
|
|
|
|
|
|
return view;
|
|
|
|
}
|
|
|
|
|
2014-06-26 21:04:49 +04:00
|
|
|
struct weston_frame_callback {
|
|
|
|
struct wl_resource *resource;
|
|
|
|
struct wl_list link;
|
|
|
|
};
|
|
|
|
|
2014-09-24 06:08:46 +04:00
|
|
|
struct weston_presentation_feedback {
|
|
|
|
struct wl_resource *resource;
|
|
|
|
|
|
|
|
/* XXX: could use just wl_resource_get_link() instead */
|
|
|
|
struct wl_list link;
|
2014-12-17 17:20:41 +03:00
|
|
|
|
|
|
|
/* The per-surface feedback flags */
|
|
|
|
uint32_t psf_flags;
|
2014-09-24 06:08:46 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
weston_presentation_feedback_discard(
|
|
|
|
struct weston_presentation_feedback *feedback)
|
|
|
|
{
|
2016-02-18 17:53:27 +03:00
|
|
|
wp_presentation_feedback_send_discarded(feedback->resource);
|
2014-09-24 06:08:46 +04:00
|
|
|
wl_resource_destroy(feedback->resource);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
weston_presentation_feedback_discard_list(struct wl_list *list)
|
|
|
|
{
|
|
|
|
struct weston_presentation_feedback *feedback, *tmp;
|
|
|
|
|
|
|
|
wl_list_for_each_safe(feedback, tmp, list, link)
|
|
|
|
weston_presentation_feedback_discard(feedback);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
weston_presentation_feedback_present(
|
|
|
|
struct weston_presentation_feedback *feedback,
|
|
|
|
struct weston_output *output,
|
|
|
|
uint32_t refresh_nsec,
|
|
|
|
const struct timespec *ts,
|
compositor: set presentation.presented flags
Change weston_output_finish_frame() signature so that backends are
required to set the flags, that will be reported on the Presentation
'presented' event. This is meant for output-wide feedback flags. Flags
that vary per wl_surface are subject for the following patch.
All start_repaint_loop functions use the special private flag
PRESENTATION_FEEDBACK_INVALID to mark, that this call of
weston_output_finish_frame() cannot trigger the 'presented' event. If it
does, we now hit an assert, and should then investigate why a fake update
triggered Presentation feedback.
DRM:
Page flip is always vsync'd, and always gets the completion timestamp
from the kernel which should correspond well to hardware. Completion is
triggered by the kernel/hardware.
Vblank handler is only used with the broken planes path, therefore do
not report VSYNC, because we cannot guarantee all the planes updated at
the same time. We cannot set the INVALID, because it would abort the
compositor if the broken planes path was ever used. This is a hack that
will get fixed with nuclear pageflip support in the future.
fbdev:
No vsync, update done by copy, no completion event from hardware, and
completion time is totally fake.
headless:
No real output to update.
RDP:
Guessing that maybe no vsync, fake time, and copy make sense (pixels
sent over network). Also no event that the pixels have been shown?
RPI:
Presumably Dispmanx updates are vsync'd. We get a completion event from
the driver, but need to read the clock ourselves, so the completion time
is somewhat unreliable. Zero-copy flag not implemented though it would
be theoretically possible with EGL clients (zero-copy is a per-surface
flag anyway, so in this patch).
Wayland:
No information how the host compositor is doing updates, so make a safe
guess without assuming vsync or hardware completion event. While we do
get some timestamp from the host compositor, it is not the completion
time. Would need to hook to the Presentation extension of the host
compositor to get more accurate flags.
X11:
No idea about vsync, completion event, or copying. Also the timestamp is
a fake.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Reviewed-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Tested-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Acked-by: Mario Kleiner <mario.kleiner.de@gmail.com>
2014-12-17 17:20:40 +03:00
|
|
|
uint64_t seq,
|
|
|
|
uint32_t flags)
|
2014-09-24 06:08:46 +04:00
|
|
|
{
|
|
|
|
struct wl_client *client = wl_resource_get_client(feedback->resource);
|
|
|
|
struct wl_resource *o;
|
|
|
|
uint64_t secs;
|
|
|
|
|
|
|
|
wl_resource_for_each(o, &output->resource_list) {
|
|
|
|
if (wl_resource_get_client(o) != client)
|
|
|
|
continue;
|
|
|
|
|
2016-02-18 17:53:27 +03:00
|
|
|
wp_presentation_feedback_send_sync_output(feedback->resource, o);
|
2014-09-24 06:08:46 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
secs = ts->tv_sec;
|
2016-02-18 17:53:27 +03:00
|
|
|
wp_presentation_feedback_send_presented(feedback->resource,
|
|
|
|
secs >> 32, secs & 0xffffffff,
|
|
|
|
ts->tv_nsec,
|
|
|
|
refresh_nsec,
|
|
|
|
seq >> 32, seq & 0xffffffff,
|
|
|
|
flags | feedback->psf_flags);
|
2014-09-24 06:08:46 +04:00
|
|
|
wl_resource_destroy(feedback->resource);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
weston_presentation_feedback_present_list(struct wl_list *list,
|
|
|
|
struct weston_output *output,
|
|
|
|
uint32_t refresh_nsec,
|
|
|
|
const struct timespec *ts,
|
compositor: set presentation.presented flags
Change weston_output_finish_frame() signature so that backends are
required to set the flags, that will be reported on the Presentation
'presented' event. This is meant for output-wide feedback flags. Flags
that vary per wl_surface are subject for the following patch.
All start_repaint_loop functions use the special private flag
PRESENTATION_FEEDBACK_INVALID to mark, that this call of
weston_output_finish_frame() cannot trigger the 'presented' event. If it
does, we now hit an assert, and should then investigate why a fake update
triggered Presentation feedback.
DRM:
Page flip is always vsync'd, and always gets the completion timestamp
from the kernel which should correspond well to hardware. Completion is
triggered by the kernel/hardware.
Vblank handler is only used with the broken planes path, therefore do
not report VSYNC, because we cannot guarantee all the planes updated at
the same time. We cannot set the INVALID, because it would abort the
compositor if the broken planes path was ever used. This is a hack that
will get fixed with nuclear pageflip support in the future.
fbdev:
No vsync, update done by copy, no completion event from hardware, and
completion time is totally fake.
headless:
No real output to update.
RDP:
Guessing that maybe no vsync, fake time, and copy make sense (pixels
sent over network). Also no event that the pixels have been shown?
RPI:
Presumably Dispmanx updates are vsync'd. We get a completion event from
the driver, but need to read the clock ourselves, so the completion time
is somewhat unreliable. Zero-copy flag not implemented though it would
be theoretically possible with EGL clients (zero-copy is a per-surface
flag anyway, so in this patch).
Wayland:
No information how the host compositor is doing updates, so make a safe
guess without assuming vsync or hardware completion event. While we do
get some timestamp from the host compositor, it is not the completion
time. Would need to hook to the Presentation extension of the host
compositor to get more accurate flags.
X11:
No idea about vsync, completion event, or copying. Also the timestamp is
a fake.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Reviewed-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Tested-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Acked-by: Mario Kleiner <mario.kleiner.de@gmail.com>
2014-12-17 17:20:40 +03:00
|
|
|
uint64_t seq,
|
|
|
|
uint32_t flags)
|
2014-09-24 06:08:46 +04:00
|
|
|
{
|
|
|
|
struct weston_presentation_feedback *feedback, *tmp;
|
|
|
|
|
2016-02-18 17:53:27 +03:00
|
|
|
assert(!(flags & WP_PRESENTATION_FEEDBACK_INVALID) ||
|
compositor: set presentation.presented flags
Change weston_output_finish_frame() signature so that backends are
required to set the flags, that will be reported on the Presentation
'presented' event. This is meant for output-wide feedback flags. Flags
that vary per wl_surface are subject for the following patch.
All start_repaint_loop functions use the special private flag
PRESENTATION_FEEDBACK_INVALID to mark, that this call of
weston_output_finish_frame() cannot trigger the 'presented' event. If it
does, we now hit an assert, and should then investigate why a fake update
triggered Presentation feedback.
DRM:
Page flip is always vsync'd, and always gets the completion timestamp
from the kernel which should correspond well to hardware. Completion is
triggered by the kernel/hardware.
Vblank handler is only used with the broken planes path, therefore do
not report VSYNC, because we cannot guarantee all the planes updated at
the same time. We cannot set the INVALID, because it would abort the
compositor if the broken planes path was ever used. This is a hack that
will get fixed with nuclear pageflip support in the future.
fbdev:
No vsync, update done by copy, no completion event from hardware, and
completion time is totally fake.
headless:
No real output to update.
RDP:
Guessing that maybe no vsync, fake time, and copy make sense (pixels
sent over network). Also no event that the pixels have been shown?
RPI:
Presumably Dispmanx updates are vsync'd. We get a completion event from
the driver, but need to read the clock ourselves, so the completion time
is somewhat unreliable. Zero-copy flag not implemented though it would
be theoretically possible with EGL clients (zero-copy is a per-surface
flag anyway, so in this patch).
Wayland:
No information how the host compositor is doing updates, so make a safe
guess without assuming vsync or hardware completion event. While we do
get some timestamp from the host compositor, it is not the completion
time. Would need to hook to the Presentation extension of the host
compositor to get more accurate flags.
X11:
No idea about vsync, completion event, or copying. Also the timestamp is
a fake.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Reviewed-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Tested-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Acked-by: Mario Kleiner <mario.kleiner.de@gmail.com>
2014-12-17 17:20:40 +03:00
|
|
|
wl_list_empty(list));
|
|
|
|
|
2014-09-24 06:08:46 +04:00
|
|
|
wl_list_for_each_safe(feedback, tmp, list, link)
|
|
|
|
weston_presentation_feedback_present(feedback, output,
|
compositor: set presentation.presented flags
Change weston_output_finish_frame() signature so that backends are
required to set the flags, that will be reported on the Presentation
'presented' event. This is meant for output-wide feedback flags. Flags
that vary per wl_surface are subject for the following patch.
All start_repaint_loop functions use the special private flag
PRESENTATION_FEEDBACK_INVALID to mark, that this call of
weston_output_finish_frame() cannot trigger the 'presented' event. If it
does, we now hit an assert, and should then investigate why a fake update
triggered Presentation feedback.
DRM:
Page flip is always vsync'd, and always gets the completion timestamp
from the kernel which should correspond well to hardware. Completion is
triggered by the kernel/hardware.
Vblank handler is only used with the broken planes path, therefore do
not report VSYNC, because we cannot guarantee all the planes updated at
the same time. We cannot set the INVALID, because it would abort the
compositor if the broken planes path was ever used. This is a hack that
will get fixed with nuclear pageflip support in the future.
fbdev:
No vsync, update done by copy, no completion event from hardware, and
completion time is totally fake.
headless:
No real output to update.
RDP:
Guessing that maybe no vsync, fake time, and copy make sense (pixels
sent over network). Also no event that the pixels have been shown?
RPI:
Presumably Dispmanx updates are vsync'd. We get a completion event from
the driver, but need to read the clock ourselves, so the completion time
is somewhat unreliable. Zero-copy flag not implemented though it would
be theoretically possible with EGL clients (zero-copy is a per-surface
flag anyway, so in this patch).
Wayland:
No information how the host compositor is doing updates, so make a safe
guess without assuming vsync or hardware completion event. While we do
get some timestamp from the host compositor, it is not the completion
time. Would need to hook to the Presentation extension of the host
compositor to get more accurate flags.
X11:
No idea about vsync, completion event, or copying. Also the timestamp is
a fake.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Reviewed-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Tested-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Acked-by: Mario Kleiner <mario.kleiner.de@gmail.com>
2014-12-17 17:20:40 +03:00
|
|
|
refresh_nsec, ts, seq,
|
|
|
|
flags);
|
2014-09-24 06:08:46 +04:00
|
|
|
}
|
|
|
|
|
2014-05-20 23:33:03 +04:00
|
|
|
static void
|
|
|
|
surface_state_handle_buffer_destroy(struct wl_listener *listener, void *data)
|
|
|
|
{
|
|
|
|
struct weston_surface_state *state =
|
|
|
|
container_of(listener, struct weston_surface_state,
|
|
|
|
buffer_destroy_listener);
|
|
|
|
|
|
|
|
state->buffer = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
weston_surface_state_init(struct weston_surface_state *state)
|
|
|
|
{
|
|
|
|
state->newly_attached = 0;
|
|
|
|
state->buffer = NULL;
|
|
|
|
state->buffer_destroy_listener.notify =
|
|
|
|
surface_state_handle_buffer_destroy;
|
|
|
|
state->sx = 0;
|
|
|
|
state->sy = 0;
|
|
|
|
|
2015-11-26 23:17:48 +03:00
|
|
|
pixman_region32_init(&state->damage_surface);
|
|
|
|
pixman_region32_init(&state->damage_buffer);
|
2014-05-20 23:33:03 +04:00
|
|
|
pixman_region32_init(&state->opaque);
|
|
|
|
region_init_infinite(&state->input);
|
|
|
|
|
|
|
|
wl_list_init(&state->frame_callback_list);
|
2014-09-24 06:08:46 +04:00
|
|
|
wl_list_init(&state->feedback_list);
|
2014-05-20 23:33:03 +04:00
|
|
|
|
|
|
|
state->buffer_viewport.buffer.transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
|
|
|
state->buffer_viewport.buffer.scale = 1;
|
|
|
|
state->buffer_viewport.buffer.src_width = wl_fixed_from_int(-1);
|
|
|
|
state->buffer_viewport.surface.width = -1;
|
|
|
|
state->buffer_viewport.changed = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
weston_surface_state_fini(struct weston_surface_state *state)
|
|
|
|
{
|
|
|
|
struct weston_frame_callback *cb, *next;
|
|
|
|
|
|
|
|
wl_list_for_each_safe(cb, next,
|
|
|
|
&state->frame_callback_list, link)
|
|
|
|
wl_resource_destroy(cb->resource);
|
|
|
|
|
2014-09-24 06:08:46 +04:00
|
|
|
weston_presentation_feedback_discard_list(&state->feedback_list);
|
|
|
|
|
2014-05-20 23:33:03 +04:00
|
|
|
pixman_region32_fini(&state->input);
|
|
|
|
pixman_region32_fini(&state->opaque);
|
2015-11-26 23:17:48 +03:00
|
|
|
pixman_region32_fini(&state->damage_surface);
|
|
|
|
pixman_region32_fini(&state->damage_buffer);
|
2014-05-20 23:33:03 +04:00
|
|
|
|
|
|
|
if (state->buffer)
|
|
|
|
wl_list_remove(&state->buffer_destroy_listener.link);
|
|
|
|
state->buffer = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
weston_surface_state_set_buffer(struct weston_surface_state *state,
|
|
|
|
struct weston_buffer *buffer)
|
|
|
|
{
|
|
|
|
if (state->buffer == buffer)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (state->buffer)
|
|
|
|
wl_list_remove(&state->buffer_destroy_listener.link);
|
|
|
|
state->buffer = buffer;
|
|
|
|
if (state->buffer)
|
|
|
|
wl_signal_add(&state->buffer->destroy_signal,
|
|
|
|
&state->buffer_destroy_listener);
|
|
|
|
}
|
|
|
|
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
WL_EXPORT struct weston_surface *
|
2012-01-27 20:58:31 +04:00
|
|
|
weston_surface_create(struct weston_compositor *compositor)
|
2009-02-10 22:20:26 +03:00
|
|
|
{
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
struct weston_surface *surface;
|
2010-08-16 18:38:29 +04:00
|
|
|
|
2014-11-21 09:21:57 +03:00
|
|
|
surface = zalloc(sizeof *surface);
|
2010-08-16 18:38:29 +04:00
|
|
|
if (surface == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
2013-06-07 07:34:41 +04:00
|
|
|
wl_signal_init(&surface->destroy_signal);
|
2016-07-22 12:48:03 +03:00
|
|
|
wl_signal_init(&surface->commit_signal);
|
2013-06-07 07:34:41 +04:00
|
|
|
|
2009-02-10 22:20:26 +03:00
|
|
|
surface->compositor = compositor;
|
2013-08-14 01:10:14 +04:00
|
|
|
surface->ref_count = 1;
|
2010-06-07 06:23:21 +04:00
|
|
|
|
2014-03-14 16:38:15 +04:00
|
|
|
surface->buffer_viewport.buffer.transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
|
|
|
surface->buffer_viewport.buffer.scale = 1;
|
2014-03-14 16:38:16 +04:00
|
|
|
surface->buffer_viewport.buffer.src_width = wl_fixed_from_int(-1);
|
|
|
|
surface->buffer_viewport.surface.width = -1;
|
2014-05-20 23:33:03 +04:00
|
|
|
|
|
|
|
weston_surface_state_init(&surface->pending);
|
|
|
|
|
2011-06-24 04:29:12 +04:00
|
|
|
pixman_region32_init(&surface->damage);
|
2012-02-24 01:11:59 +04:00
|
|
|
pixman_region32_init(&surface->opaque);
|
2012-10-10 13:49:32 +04:00
|
|
|
region_init_infinite(&surface->input);
|
2011-06-24 04:29:12 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
wl_list_init(&surface->views);
|
|
|
|
|
|
|
|
wl_list_init(&surface->frame_callback_list);
|
2014-09-24 06:08:46 +04:00
|
|
|
wl_list_init(&surface->feedback_list);
|
2008-11-24 01:07:32 +03:00
|
|
|
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
wl_list_init(&surface->subsurface_list);
|
|
|
|
wl_list_init(&surface->subsurface_list_pending);
|
|
|
|
|
2014-10-16 19:55:19 +04:00
|
|
|
weston_matrix_init(&surface->buffer_to_surface_matrix);
|
|
|
|
weston_matrix_init(&surface->surface_to_buffer_matrix);
|
|
|
|
|
2016-07-22 12:56:31 +03:00
|
|
|
wl_list_init(&surface->pointer_constraints);
|
|
|
|
|
2010-08-16 18:38:29 +04:00
|
|
|
return surface;
|
2008-11-24 01:07:32 +03:00
|
|
|
}
|
|
|
|
|
2012-02-28 14:07:54 +04:00
|
|
|
WL_EXPORT void
|
2012-01-26 19:00:23 +04:00
|
|
|
weston_surface_set_color(struct weston_surface *surface,
|
2012-09-30 04:57:21 +04:00
|
|
|
float red, float green, float blue, float alpha)
|
2012-01-26 19:00:23 +04:00
|
|
|
{
|
2012-11-13 22:10:23 +04:00
|
|
|
surface->compositor->renderer->surface_set_color(surface, red, green, blue, alpha);
|
2012-01-26 19:00:23 +04:00
|
|
|
}
|
|
|
|
|
2012-06-18 21:17:32 +04:00
|
|
|
WL_EXPORT void
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_to_global_float(struct weston_view *view,
|
|
|
|
float sx, float sy, float *x, float *y)
|
2012-02-08 17:23:15 +04:00
|
|
|
{
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
if (view->transform.enabled) {
|
2012-02-08 17:23:15 +04:00
|
|
|
struct weston_vector v = { { sx, sy, 0.0f, 1.0f } };
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_matrix_transform(&view->transform.matrix, &v);
|
2012-02-08 17:23:15 +04:00
|
|
|
|
|
|
|
if (fabsf(v.f[3]) < 1e-6) {
|
2012-06-07 20:01:59 +04:00
|
|
|
weston_log("warning: numerical instability in "
|
2013-02-11 15:45:38 +04:00
|
|
|
"%s(), divisor = %g\n", __func__,
|
2012-02-08 17:23:15 +04:00
|
|
|
v.f[3]);
|
|
|
|
*x = 0;
|
|
|
|
*y = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
*x = v.f[0] / v.f[3];
|
|
|
|
*y = v.f[1] / v.f[3];
|
|
|
|
} else {
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
*x = sx + view->geometry.x;
|
|
|
|
*y = sy + view->geometry.y;
|
2012-02-08 17:23:15 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-21 20:35:16 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_transformed_coord(int width, int height,
|
|
|
|
enum wl_output_transform transform,
|
2013-05-24 15:09:43 +04:00
|
|
|
int32_t scale,
|
2013-02-21 20:35:16 +04:00
|
|
|
float sx, float sy, float *bx, float *by)
|
|
|
|
{
|
|
|
|
switch (transform) {
|
|
|
|
case WL_OUTPUT_TRANSFORM_NORMAL:
|
|
|
|
default:
|
|
|
|
*bx = sx;
|
|
|
|
*by = sy;
|
|
|
|
break;
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED:
|
|
|
|
*bx = width - sx;
|
|
|
|
*by = sy;
|
|
|
|
break;
|
|
|
|
case WL_OUTPUT_TRANSFORM_90:
|
|
|
|
*bx = height - sy;
|
|
|
|
*by = sx;
|
|
|
|
break;
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
|
|
|
|
*bx = height - sy;
|
|
|
|
*by = width - sx;
|
|
|
|
break;
|
|
|
|
case WL_OUTPUT_TRANSFORM_180:
|
|
|
|
*bx = width - sx;
|
|
|
|
*by = height - sy;
|
|
|
|
break;
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
|
|
|
|
*bx = sx;
|
|
|
|
*by = height - sy;
|
|
|
|
break;
|
|
|
|
case WL_OUTPUT_TRANSFORM_270:
|
|
|
|
*bx = sy;
|
|
|
|
*by = width - sx;
|
|
|
|
break;
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
|
|
|
|
*bx = sy;
|
|
|
|
*by = sx;
|
|
|
|
break;
|
|
|
|
}
|
2013-05-22 16:41:37 +04:00
|
|
|
|
|
|
|
*bx *= scale;
|
|
|
|
*by *= scale;
|
2013-02-21 20:35:16 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
WL_EXPORT pixman_box32_t
|
|
|
|
weston_transformed_rect(int width, int height,
|
|
|
|
enum wl_output_transform transform,
|
2013-05-24 15:09:43 +04:00
|
|
|
int32_t scale,
|
2013-02-21 20:35:16 +04:00
|
|
|
pixman_box32_t rect)
|
|
|
|
{
|
|
|
|
float x1, x2, y1, y2;
|
|
|
|
|
|
|
|
pixman_box32_t ret;
|
|
|
|
|
2013-05-22 16:41:37 +04:00
|
|
|
weston_transformed_coord(width, height, transform, scale,
|
2013-02-21 20:35:16 +04:00
|
|
|
rect.x1, rect.y1, &x1, &y1);
|
2013-05-22 16:41:37 +04:00
|
|
|
weston_transformed_coord(width, height, transform, scale,
|
2013-02-21 20:35:16 +04:00
|
|
|
rect.x2, rect.y2, &x2, &y2);
|
|
|
|
|
|
|
|
if (x1 <= x2) {
|
|
|
|
ret.x1 = x1;
|
|
|
|
ret.x2 = x2;
|
|
|
|
} else {
|
|
|
|
ret.x1 = x2;
|
|
|
|
ret.x2 = x1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (y1 <= y2) {
|
|
|
|
ret.y1 = y1;
|
|
|
|
ret.y2 = y2;
|
|
|
|
} else {
|
|
|
|
ret.y1 = y2;
|
|
|
|
ret.y2 = y1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-11-19 01:32:30 +03:00
|
|
|
/** Transform a region by a matrix, restricted to axis-aligned transformations
|
|
|
|
*
|
|
|
|
* Warning: This function does not work for projective, affine, or matrices
|
|
|
|
* that encode arbitrary rotations. Only 90-degree step rotations are
|
|
|
|
* supported.
|
|
|
|
*/
|
|
|
|
WL_EXPORT void
|
|
|
|
weston_matrix_transform_region(pixman_region32_t *dest,
|
|
|
|
struct weston_matrix *matrix,
|
|
|
|
pixman_region32_t *src)
|
|
|
|
{
|
|
|
|
pixman_box32_t *src_rects, *dest_rects;
|
|
|
|
int nrects, i;
|
|
|
|
|
|
|
|
src_rects = pixman_region32_rectangles(src, &nrects);
|
|
|
|
dest_rects = malloc(nrects * sizeof(*dest_rects));
|
|
|
|
if (!dest_rects)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (i = 0; i < nrects; i++) {
|
|
|
|
struct weston_vector vec1 = {{
|
|
|
|
src_rects[i].x1, src_rects[i].y1, 0, 1
|
|
|
|
}};
|
|
|
|
weston_matrix_transform(matrix, &vec1);
|
|
|
|
vec1.f[0] /= vec1.f[3];
|
|
|
|
vec1.f[1] /= vec1.f[3];
|
|
|
|
|
|
|
|
struct weston_vector vec2 = {{
|
|
|
|
src_rects[i].x2, src_rects[i].y2, 0, 1
|
|
|
|
}};
|
|
|
|
weston_matrix_transform(matrix, &vec2);
|
|
|
|
vec2.f[0] /= vec2.f[3];
|
|
|
|
vec2.f[1] /= vec2.f[3];
|
|
|
|
|
|
|
|
if (vec1.f[0] < vec2.f[0]) {
|
|
|
|
dest_rects[i].x1 = floor(vec1.f[0]);
|
|
|
|
dest_rects[i].x2 = ceil(vec2.f[0]);
|
|
|
|
} else {
|
|
|
|
dest_rects[i].x1 = floor(vec2.f[0]);
|
|
|
|
dest_rects[i].x2 = ceil(vec1.f[0]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vec1.f[1] < vec2.f[1]) {
|
|
|
|
dest_rects[i].y1 = floor(vec1.f[1]);
|
|
|
|
dest_rects[i].y2 = ceil(vec2.f[1]);
|
|
|
|
} else {
|
|
|
|
dest_rects[i].y1 = floor(vec2.f[1]);
|
|
|
|
dest_rects[i].y2 = ceil(vec1.f[1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pixman_region32_clear(dest);
|
|
|
|
pixman_region32_init_rects(dest, dest_rects, nrects);
|
|
|
|
free(dest_rects);
|
|
|
|
}
|
|
|
|
|
2013-10-28 07:25:01 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_transformed_region(int width, int height,
|
|
|
|
enum wl_output_transform transform,
|
|
|
|
int32_t scale,
|
|
|
|
pixman_region32_t *src, pixman_region32_t *dest)
|
|
|
|
{
|
|
|
|
pixman_box32_t *src_rects, *dest_rects;
|
|
|
|
int nrects, i;
|
|
|
|
|
|
|
|
if (transform == WL_OUTPUT_TRANSFORM_NORMAL && scale == 1) {
|
|
|
|
if (src != dest)
|
|
|
|
pixman_region32_copy(dest, src);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
src_rects = pixman_region32_rectangles(src, &nrects);
|
|
|
|
dest_rects = malloc(nrects * sizeof(*dest_rects));
|
|
|
|
if (!dest_rects)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (transform == WL_OUTPUT_TRANSFORM_NORMAL) {
|
|
|
|
memcpy(dest_rects, src_rects, nrects * sizeof(*dest_rects));
|
|
|
|
} else {
|
|
|
|
for (i = 0; i < nrects; i++) {
|
|
|
|
switch (transform) {
|
|
|
|
default:
|
|
|
|
case WL_OUTPUT_TRANSFORM_NORMAL:
|
|
|
|
dest_rects[i].x1 = src_rects[i].x1;
|
|
|
|
dest_rects[i].y1 = src_rects[i].y1;
|
|
|
|
dest_rects[i].x2 = src_rects[i].x2;
|
|
|
|
dest_rects[i].y2 = src_rects[i].y2;
|
|
|
|
break;
|
|
|
|
case WL_OUTPUT_TRANSFORM_90:
|
|
|
|
dest_rects[i].x1 = height - src_rects[i].y2;
|
|
|
|
dest_rects[i].y1 = src_rects[i].x1;
|
|
|
|
dest_rects[i].x2 = height - src_rects[i].y1;
|
|
|
|
dest_rects[i].y2 = src_rects[i].x2;
|
|
|
|
break;
|
|
|
|
case WL_OUTPUT_TRANSFORM_180:
|
|
|
|
dest_rects[i].x1 = width - src_rects[i].x2;
|
|
|
|
dest_rects[i].y1 = height - src_rects[i].y2;
|
|
|
|
dest_rects[i].x2 = width - src_rects[i].x1;
|
|
|
|
dest_rects[i].y2 = height - src_rects[i].y1;
|
|
|
|
break;
|
|
|
|
case WL_OUTPUT_TRANSFORM_270:
|
|
|
|
dest_rects[i].x1 = src_rects[i].y1;
|
|
|
|
dest_rects[i].y1 = width - src_rects[i].x2;
|
|
|
|
dest_rects[i].x2 = src_rects[i].y2;
|
|
|
|
dest_rects[i].y2 = width - src_rects[i].x1;
|
|
|
|
break;
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED:
|
|
|
|
dest_rects[i].x1 = width - src_rects[i].x2;
|
|
|
|
dest_rects[i].y1 = src_rects[i].y1;
|
|
|
|
dest_rects[i].x2 = width - src_rects[i].x1;
|
|
|
|
dest_rects[i].y2 = src_rects[i].y2;
|
|
|
|
break;
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
|
|
|
|
dest_rects[i].x1 = height - src_rects[i].y2;
|
|
|
|
dest_rects[i].y1 = width - src_rects[i].x2;
|
|
|
|
dest_rects[i].x2 = height - src_rects[i].y1;
|
|
|
|
dest_rects[i].y2 = width - src_rects[i].x1;
|
|
|
|
break;
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
|
|
|
|
dest_rects[i].x1 = src_rects[i].x1;
|
|
|
|
dest_rects[i].y1 = height - src_rects[i].y2;
|
|
|
|
dest_rects[i].x2 = src_rects[i].x2;
|
|
|
|
dest_rects[i].y2 = height - src_rects[i].y1;
|
|
|
|
break;
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
|
|
|
|
dest_rects[i].x1 = src_rects[i].y1;
|
|
|
|
dest_rects[i].y1 = src_rects[i].x1;
|
|
|
|
dest_rects[i].x2 = src_rects[i].y2;
|
|
|
|
dest_rects[i].y2 = src_rects[i].x2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scale != 1) {
|
|
|
|
for (i = 0; i < nrects; i++) {
|
|
|
|
dest_rects[i].x1 *= scale;
|
|
|
|
dest_rects[i].x2 *= scale;
|
|
|
|
dest_rects[i].y1 *= scale;
|
|
|
|
dest_rects[i].y2 *= scale;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pixman_region32_clear(dest);
|
|
|
|
pixman_region32_init_rects(dest, dest_rects, nrects);
|
|
|
|
free(dest_rects);
|
|
|
|
}
|
|
|
|
|
2013-11-26 21:19:46 +04:00
|
|
|
static void
|
2016-04-15 16:42:49 +03:00
|
|
|
viewport_surface_to_buffer(struct weston_surface *surface,
|
|
|
|
float sx, float sy, float *bx, float *by)
|
2013-11-26 21:19:46 +04:00
|
|
|
{
|
2014-03-14 16:38:15 +04:00
|
|
|
struct weston_buffer_viewport *vp = &surface->buffer_viewport;
|
2014-03-14 16:38:17 +04:00
|
|
|
double src_width, src_height;
|
|
|
|
double src_x, src_y;
|
2014-03-14 16:38:15 +04:00
|
|
|
|
2014-03-14 16:38:17 +04:00
|
|
|
if (vp->buffer.src_width == wl_fixed_from_int(-1)) {
|
|
|
|
if (vp->surface.width == -1) {
|
|
|
|
*bx = sx;
|
|
|
|
*by = sy;
|
|
|
|
return;
|
|
|
|
}
|
2013-11-26 21:19:46 +04:00
|
|
|
|
2014-03-14 16:38:17 +04:00
|
|
|
src_x = 0.0;
|
|
|
|
src_y = 0.0;
|
|
|
|
src_width = surface->width_from_buffer;
|
|
|
|
src_height = surface->height_from_buffer;
|
2013-11-26 21:19:46 +04:00
|
|
|
} else {
|
2014-03-14 16:38:17 +04:00
|
|
|
src_x = wl_fixed_to_double(vp->buffer.src_x);
|
|
|
|
src_y = wl_fixed_to_double(vp->buffer.src_y);
|
|
|
|
src_width = wl_fixed_to_double(vp->buffer.src_width);
|
|
|
|
src_height = wl_fixed_to_double(vp->buffer.src_height);
|
2013-11-26 21:19:46 +04:00
|
|
|
}
|
2014-03-14 16:38:17 +04:00
|
|
|
|
|
|
|
*bx = sx * src_width / surface->width + src_x;
|
|
|
|
*by = sy * src_height / surface->height + src_y;
|
2013-11-26 21:19:46 +04:00
|
|
|
}
|
|
|
|
|
2012-11-28 19:10:26 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_surface_to_buffer_float(struct weston_surface *surface,
|
|
|
|
float sx, float sy, float *bx, float *by)
|
|
|
|
{
|
2014-03-14 16:38:15 +04:00
|
|
|
struct weston_buffer_viewport *vp = &surface->buffer_viewport;
|
|
|
|
|
2016-04-15 16:42:49 +03:00
|
|
|
/* first transform coordinates if the viewport is set */
|
|
|
|
viewport_surface_to_buffer(surface, sx, sy, bx, by);
|
2013-11-26 21:19:46 +04:00
|
|
|
|
2014-04-22 05:56:46 +04:00
|
|
|
weston_transformed_coord(surface->width_from_buffer,
|
|
|
|
surface->height_from_buffer,
|
2014-03-14 16:38:15 +04:00
|
|
|
vp->buffer.transform, vp->buffer.scale,
|
2013-11-26 21:19:46 +04:00
|
|
|
*bx, *by, bx, by);
|
2012-11-28 19:10:26 +04:00
|
|
|
}
|
|
|
|
|
2015-12-04 01:38:11 +03:00
|
|
|
/** Transform a rectangle from surface coordinates to buffer coordinates
|
|
|
|
*
|
2016-04-15 14:47:08 +03:00
|
|
|
* \param surface The surface to fetch wp_viewport and buffer transformation
|
2015-12-04 01:38:11 +03:00
|
|
|
* from.
|
|
|
|
* \param rect The rectangle to transform.
|
|
|
|
* \return The transformed rectangle.
|
|
|
|
*
|
|
|
|
* Viewport and buffer transformations can only do translation, scaling,
|
|
|
|
* and rotations in 90-degree steps. Therefore the only loss in the
|
|
|
|
* conversion is coordinate rounding.
|
|
|
|
*
|
|
|
|
* However, some coordinate rounding takes place as an intermediate
|
|
|
|
* step before the buffer scale factor is applied, so the rectangle
|
|
|
|
* boundary may not be exactly as expected.
|
|
|
|
*
|
|
|
|
* This is OK for damage tracking since a little extra coverage is
|
|
|
|
* not a problem.
|
|
|
|
*/
|
2012-11-28 19:10:26 +04:00
|
|
|
WL_EXPORT pixman_box32_t
|
|
|
|
weston_surface_to_buffer_rect(struct weston_surface *surface,
|
|
|
|
pixman_box32_t rect)
|
|
|
|
{
|
2014-03-14 16:38:15 +04:00
|
|
|
struct weston_buffer_viewport *vp = &surface->buffer_viewport;
|
2013-11-26 21:19:46 +04:00
|
|
|
float xf, yf;
|
|
|
|
|
2016-04-15 16:42:49 +03:00
|
|
|
/* first transform box coordinates if the viewport is set */
|
|
|
|
viewport_surface_to_buffer(surface, rect.x1, rect.y1, &xf, &yf);
|
2013-11-26 21:19:46 +04:00
|
|
|
rect.x1 = floorf(xf);
|
|
|
|
rect.y1 = floorf(yf);
|
|
|
|
|
2016-04-15 16:42:49 +03:00
|
|
|
viewport_surface_to_buffer(surface, rect.x2, rect.y2, &xf, &yf);
|
2015-12-01 22:00:43 +03:00
|
|
|
rect.x2 = ceilf(xf);
|
|
|
|
rect.y2 = ceilf(yf);
|
2013-11-26 21:19:46 +04:00
|
|
|
|
2014-04-22 05:56:46 +04:00
|
|
|
return weston_transformed_rect(surface->width_from_buffer,
|
|
|
|
surface->height_from_buffer,
|
2014-03-14 16:38:15 +04:00
|
|
|
vp->buffer.transform, vp->buffer.scale,
|
2013-05-22 16:41:37 +04:00
|
|
|
rect);
|
2012-11-28 19:10:26 +04:00
|
|
|
}
|
|
|
|
|
2015-03-04 15:23:28 +03:00
|
|
|
/** Transform a region from surface coordinates to buffer coordinates
|
|
|
|
*
|
2016-04-15 14:47:08 +03:00
|
|
|
* \param surface The surface to fetch wp_viewport and buffer transformation
|
2015-03-04 15:23:28 +03:00
|
|
|
* from.
|
|
|
|
* \param surface_region[in] The region in surface coordinates.
|
|
|
|
* \param buffer_region[out] The region converted to buffer coordinates.
|
|
|
|
*
|
|
|
|
* Buffer_region must be init'd, but will be completely overwritten.
|
|
|
|
*
|
|
|
|
* Viewport and buffer transformations can only do translation, scaling,
|
|
|
|
* and rotations in 90-degree steps. Therefore the only loss in the
|
2015-12-04 01:38:11 +03:00
|
|
|
* conversion is from the coordinate rounding that takes place in
|
|
|
|
* \ref weston_surface_to_buffer_rect.
|
2015-03-04 15:23:28 +03:00
|
|
|
*/
|
|
|
|
WL_EXPORT void
|
|
|
|
weston_surface_to_buffer_region(struct weston_surface *surface,
|
|
|
|
pixman_region32_t *surface_region,
|
|
|
|
pixman_region32_t *buffer_region)
|
|
|
|
{
|
|
|
|
pixman_box32_t *src_rects, *dest_rects;
|
|
|
|
int nrects, i;
|
|
|
|
|
|
|
|
src_rects = pixman_region32_rectangles(surface_region, &nrects);
|
|
|
|
dest_rects = malloc(nrects * sizeof(*dest_rects));
|
|
|
|
if (!dest_rects)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (i = 0; i < nrects; i++) {
|
|
|
|
dest_rects[i] = weston_surface_to_buffer_rect(surface,
|
|
|
|
src_rects[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
pixman_region32_fini(buffer_region);
|
|
|
|
pixman_region32_init_rects(buffer_region, dest_rects, nrects);
|
|
|
|
free(dest_rects);
|
|
|
|
}
|
|
|
|
|
2012-08-03 19:30:18 +04:00
|
|
|
WL_EXPORT void
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_move_to_plane(struct weston_view *view,
|
2012-08-03 19:30:18 +04:00
|
|
|
struct weston_plane *plane)
|
|
|
|
{
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
if (view->plane == plane)
|
2012-08-03 19:30:18 +04:00
|
|
|
return;
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_damage_below(view);
|
|
|
|
view->plane = plane;
|
|
|
|
weston_surface_damage(view->surface);
|
2012-08-03 19:30:18 +04:00
|
|
|
}
|
|
|
|
|
2015-02-17 14:10:01 +03:00
|
|
|
/** Inflict damage on the plane where the view is visible.
|
|
|
|
*
|
|
|
|
* \param view The view that causes the damage.
|
|
|
|
*
|
|
|
|
* If the view is currently on a plane (including the primary plane),
|
|
|
|
* take the view's boundingbox, subtract all the opaque views that cover it,
|
|
|
|
* and add the remaining region as damage to the plane. This corresponds
|
|
|
|
* to the damage inflicted to the plane if this view disappeared.
|
|
|
|
*
|
|
|
|
* A repaint is scheduled for this view.
|
|
|
|
*
|
|
|
|
* The region of all opaque views covering this view is stored in
|
|
|
|
* weston_view::clip and updated by view_accumulate_damage() during
|
|
|
|
* weston_output_repaint(). Specifically, that region matches the
|
|
|
|
* scenegraph as it was last painted.
|
|
|
|
*/
|
2012-02-24 08:03:14 +04:00
|
|
|
WL_EXPORT void
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_damage_below(struct weston_view *view)
|
2012-02-08 16:49:37 +04:00
|
|
|
{
|
2012-02-29 07:47:14 +04:00
|
|
|
pixman_region32_t damage;
|
|
|
|
|
|
|
|
pixman_region32_init(&damage);
|
2015-02-19 12:15:33 +03:00
|
|
|
pixman_region32_subtract(&damage, &view->transform.boundingbox,
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
&view->clip);
|
2013-10-23 09:58:31 +04:00
|
|
|
if (view->plane)
|
|
|
|
pixman_region32_union(&view->plane->damage,
|
|
|
|
&view->plane->damage, &damage);
|
2012-02-29 07:47:14 +04:00
|
|
|
pixman_region32_fini(&damage);
|
2013-11-14 09:33:43 +04:00
|
|
|
weston_view_schedule_repaint(view);
|
2012-02-08 16:49:37 +04:00
|
|
|
}
|
|
|
|
|
2015-12-23 22:01:58 +03:00
|
|
|
/**
|
|
|
|
* \param es The surface
|
|
|
|
* \param mask The new set of outputs for the surface
|
|
|
|
*
|
|
|
|
* Sets the surface's set of outputs to the ones specified by
|
|
|
|
* the new output mask provided. Identifies the outputs that
|
|
|
|
* have changed, the posts enter and leave events for these
|
|
|
|
* outputs as appropriate.
|
|
|
|
*/
|
2012-09-25 22:48:04 +04:00
|
|
|
static void
|
|
|
|
weston_surface_update_output_mask(struct weston_surface *es, uint32_t mask)
|
|
|
|
{
|
|
|
|
uint32_t different = es->output_mask ^ mask;
|
|
|
|
uint32_t entered = mask & different;
|
|
|
|
uint32_t left = es->output_mask & different;
|
|
|
|
struct weston_output *output;
|
|
|
|
struct wl_resource *resource = NULL;
|
2013-06-07 07:34:41 +04:00
|
|
|
struct wl_client *client;
|
2012-09-25 22:48:04 +04:00
|
|
|
|
|
|
|
es->output_mask = mask;
|
2013-06-07 07:34:41 +04:00
|
|
|
if (es->resource == NULL)
|
2012-09-25 22:48:04 +04:00
|
|
|
return;
|
|
|
|
if (different == 0)
|
|
|
|
return;
|
|
|
|
|
2013-06-07 07:34:41 +04:00
|
|
|
client = wl_resource_get_client(es->resource);
|
|
|
|
|
2012-09-25 22:48:04 +04:00
|
|
|
wl_list_for_each(output, &es->compositor->output_list, link) {
|
2015-12-24 05:38:07 +03:00
|
|
|
if (1u << output->id & different)
|
2012-09-25 22:48:04 +04:00
|
|
|
resource =
|
2013-06-14 19:08:01 +04:00
|
|
|
wl_resource_find_for_client(&output->resource_list,
|
2012-09-25 22:48:04 +04:00
|
|
|
client);
|
|
|
|
if (resource == NULL)
|
|
|
|
continue;
|
2015-12-24 05:38:07 +03:00
|
|
|
if (1u << output->id & entered)
|
2013-06-07 07:34:41 +04:00
|
|
|
wl_surface_send_enter(es->resource, resource);
|
2015-12-24 05:38:07 +03:00
|
|
|
if (1u << output->id & left)
|
2013-06-07 07:34:41 +04:00
|
|
|
wl_surface_send_leave(es->resource, resource);
|
2012-09-25 22:48:04 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-23 22:01:58 +03:00
|
|
|
/** Recalculate which output(s) the surface has views displayed on
|
|
|
|
*
|
|
|
|
* \param es The surface to remap to outputs
|
|
|
|
*
|
|
|
|
* Finds the output that is showing the largest amount of one
|
|
|
|
* of the surface's various views. This output becomes the
|
2016-03-30 14:33:33 +03:00
|
|
|
* surface's primary output for vsync and frame callback purposes.
|
2015-12-23 22:01:58 +03:00
|
|
|
*
|
2016-03-30 14:33:33 +03:00
|
|
|
* Also notes all outputs of all of the surface's views
|
2015-12-23 22:01:58 +03:00
|
|
|
* in the output_mask for the surface.
|
|
|
|
*/
|
2012-09-25 22:48:04 +04:00
|
|
|
static void
|
|
|
|
weston_surface_assign_output(struct weston_surface *es)
|
|
|
|
{
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
struct weston_output *new_output;
|
|
|
|
struct weston_view *view;
|
|
|
|
pixman_region32_t region;
|
|
|
|
uint32_t max, area, mask;
|
|
|
|
pixman_box32_t *e;
|
|
|
|
|
|
|
|
new_output = NULL;
|
|
|
|
max = 0;
|
|
|
|
mask = 0;
|
|
|
|
pixman_region32_init(®ion);
|
|
|
|
wl_list_for_each(view, &es->views, surface_link) {
|
|
|
|
if (!view->output)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
pixman_region32_intersect(®ion, &view->transform.boundingbox,
|
|
|
|
&view->output->region);
|
|
|
|
|
|
|
|
e = pixman_region32_extents(®ion);
|
|
|
|
area = (e->x2 - e->x1) * (e->y2 - e->y1);
|
|
|
|
|
|
|
|
mask |= view->output_mask;
|
|
|
|
|
|
|
|
if (area >= max) {
|
|
|
|
new_output = view->output;
|
|
|
|
max = area;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pixman_region32_fini(®ion);
|
|
|
|
|
|
|
|
es->output = new_output;
|
|
|
|
weston_surface_update_output_mask(es, mask);
|
|
|
|
}
|
|
|
|
|
2015-12-23 22:01:58 +03:00
|
|
|
/** Recalculate which output(s) the view is displayed on
|
|
|
|
*
|
|
|
|
* \param ev The view to remap to outputs
|
|
|
|
*
|
|
|
|
* Identifies the set of outputs that the view is visible on,
|
|
|
|
* noting them into the output_mask. The output that the view
|
2016-03-30 14:33:33 +03:00
|
|
|
* is most visible on is set as the view's primary output.
|
2015-12-23 22:01:58 +03:00
|
|
|
*
|
|
|
|
* Also does the same for the view's surface. See
|
|
|
|
* weston_surface_assign_output().
|
|
|
|
*/
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
static void
|
|
|
|
weston_view_assign_output(struct weston_view *ev)
|
|
|
|
{
|
|
|
|
struct weston_compositor *ec = ev->surface->compositor;
|
2012-09-25 22:48:04 +04:00
|
|
|
struct weston_output *output, *new_output;
|
|
|
|
pixman_region32_t region;
|
|
|
|
uint32_t max, area, mask;
|
|
|
|
pixman_box32_t *e;
|
|
|
|
|
|
|
|
new_output = NULL;
|
|
|
|
max = 0;
|
|
|
|
mask = 0;
|
|
|
|
pixman_region32_init(®ion);
|
|
|
|
wl_list_for_each(output, &ec->output_list, link) {
|
2015-07-12 10:52:32 +03:00
|
|
|
if (output->destroying)
|
|
|
|
continue;
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
pixman_region32_intersect(®ion, &ev->transform.boundingbox,
|
2012-09-25 22:48:04 +04:00
|
|
|
&output->region);
|
|
|
|
|
|
|
|
e = pixman_region32_extents(®ion);
|
|
|
|
area = (e->x2 - e->x1) * (e->y2 - e->y1);
|
|
|
|
|
|
|
|
if (area > 0)
|
2015-12-24 05:38:07 +03:00
|
|
|
mask |= 1u << output->id;
|
2012-09-25 22:48:04 +04:00
|
|
|
|
|
|
|
if (area >= max) {
|
|
|
|
new_output = output;
|
|
|
|
max = area;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pixman_region32_fini(®ion);
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
ev->output = new_output;
|
|
|
|
ev->output_mask = mask;
|
|
|
|
|
|
|
|
weston_surface_assign_output(ev->surface);
|
2012-09-25 22:48:04 +04:00
|
|
|
}
|
|
|
|
|
2015-02-16 15:39:11 +03:00
|
|
|
static void
|
|
|
|
weston_view_to_view_map(struct weston_view *from, struct weston_view *to,
|
|
|
|
int from_x, int from_y, int *to_x, int *to_y)
|
|
|
|
{
|
|
|
|
float x, y;
|
|
|
|
|
|
|
|
weston_view_to_global_float(from, from_x, from_y, &x, &y);
|
|
|
|
weston_view_from_global_float(to, x, y, &x, &y);
|
|
|
|
|
|
|
|
*to_x = round(x);
|
|
|
|
*to_y = round(y);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
weston_view_transfer_scissor(struct weston_view *from, struct weston_view *to)
|
|
|
|
{
|
|
|
|
pixman_box32_t *a;
|
|
|
|
pixman_box32_t b;
|
|
|
|
|
|
|
|
a = pixman_region32_extents(&from->geometry.scissor);
|
|
|
|
|
|
|
|
weston_view_to_view_map(from, to, a->x1, a->y1, &b.x1, &b.y1);
|
|
|
|
weston_view_to_view_map(from, to, a->x2, a->y2, &b.x2, &b.y2);
|
|
|
|
|
|
|
|
pixman_region32_fini(&to->geometry.scissor);
|
|
|
|
pixman_region32_init_with_extents(&to->geometry.scissor, &b);
|
|
|
|
}
|
|
|
|
|
2012-01-25 17:17:40 +04:00
|
|
|
static void
|
2015-02-23 13:27:00 +03:00
|
|
|
view_compute_bbox(struct weston_view *view, const pixman_box32_t *inbox,
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
pixman_region32_t *bbox)
|
2012-01-25 17:17:40 +04:00
|
|
|
{
|
2012-09-30 04:57:21 +04:00
|
|
|
float min_x = HUGE_VALF, min_y = HUGE_VALF;
|
|
|
|
float max_x = -HUGE_VALF, max_y = -HUGE_VALF;
|
2012-01-25 17:17:40 +04:00
|
|
|
int32_t s[4][2] = {
|
2015-02-23 13:27:00 +03:00
|
|
|
{ inbox->x1, inbox->y1 },
|
|
|
|
{ inbox->x1, inbox->y2 },
|
|
|
|
{ inbox->x2, inbox->y1 },
|
|
|
|
{ inbox->x2, inbox->y2 },
|
2012-01-25 17:17:40 +04:00
|
|
|
};
|
2012-09-30 04:57:21 +04:00
|
|
|
float int_x, int_y;
|
2012-01-25 17:17:40 +04:00
|
|
|
int i;
|
|
|
|
|
2015-02-23 13:27:00 +03:00
|
|
|
if (inbox->x1 == inbox->x2 || inbox->y1 == inbox->y2) {
|
2012-09-04 14:55:44 +04:00
|
|
|
/* avoid rounding empty bbox to 1x1 */
|
|
|
|
pixman_region32_init(bbox);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-01-25 17:17:40 +04:00
|
|
|
for (i = 0; i < 4; ++i) {
|
2012-09-30 04:57:21 +04:00
|
|
|
float x, y;
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_to_global_float(view, s[i][0], s[i][1], &x, &y);
|
2012-01-25 17:17:40 +04:00
|
|
|
if (x < min_x)
|
|
|
|
min_x = x;
|
|
|
|
if (x > max_x)
|
|
|
|
max_x = x;
|
|
|
|
if (y < min_y)
|
|
|
|
min_y = y;
|
|
|
|
if (y > max_y)
|
|
|
|
max_y = y;
|
|
|
|
}
|
|
|
|
|
2012-02-08 17:38:37 +04:00
|
|
|
int_x = floorf(min_x);
|
|
|
|
int_y = floorf(min_y);
|
|
|
|
pixman_region32_init_rect(bbox, int_x, int_y,
|
|
|
|
ceilf(max_x) - int_x, ceilf(max_y) - int_y);
|
2012-01-25 17:17:40 +04:00
|
|
|
}
|
|
|
|
|
2012-02-08 17:14:17 +04:00
|
|
|
static void
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_update_transform_disable(struct weston_view *view)
|
2012-02-08 17:14:17 +04:00
|
|
|
{
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
view->transform.enabled = 0;
|
2012-02-08 17:14:17 +04:00
|
|
|
|
2012-02-13 12:34:04 +04:00
|
|
|
/* round off fractions when not transformed */
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
view->geometry.x = roundf(view->geometry.x);
|
|
|
|
view->geometry.y = roundf(view->geometry.y);
|
2012-02-13 12:34:04 +04:00
|
|
|
|
2013-02-20 02:04:50 +04:00
|
|
|
/* Otherwise identity matrix, but with x and y translation. */
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
view->transform.position.matrix.type = WESTON_MATRIX_TRANSFORM_TRANSLATE;
|
|
|
|
view->transform.position.matrix.d[12] = view->geometry.x;
|
|
|
|
view->transform.position.matrix.d[13] = view->geometry.y;
|
2013-02-20 02:04:50 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
view->transform.matrix = view->transform.position.matrix;
|
2013-02-20 02:04:50 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
view->transform.inverse = view->transform.position.matrix;
|
|
|
|
view->transform.inverse.d[12] = -view->geometry.x;
|
|
|
|
view->transform.inverse.d[13] = -view->geometry.y;
|
2013-02-20 02:04:50 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
pixman_region32_init_rect(&view->transform.boundingbox,
|
2015-02-16 15:39:11 +03:00
|
|
|
0, 0,
|
2013-12-03 07:01:53 +04:00
|
|
|
view->surface->width,
|
|
|
|
view->surface->height);
|
2015-02-16 15:39:11 +03:00
|
|
|
if (view->geometry.scissor_enabled)
|
|
|
|
pixman_region32_intersect(&view->transform.boundingbox,
|
|
|
|
&view->transform.boundingbox,
|
|
|
|
&view->geometry.scissor);
|
|
|
|
|
|
|
|
pixman_region32_translate(&view->transform.boundingbox,
|
|
|
|
view->geometry.x, view->geometry.y);
|
2012-02-24 01:11:59 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
if (view->alpha == 1.0) {
|
|
|
|
pixman_region32_copy(&view->transform.opaque,
|
|
|
|
&view->surface->opaque);
|
|
|
|
pixman_region32_translate(&view->transform.opaque,
|
|
|
|
view->geometry.x,
|
|
|
|
view->geometry.y);
|
2012-02-28 18:19:39 +04:00
|
|
|
}
|
2012-02-08 17:14:17 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_update_transform_enable(struct weston_view *view)
|
2012-01-20 16:24:25 +04:00
|
|
|
{
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
struct weston_view *parent = view->geometry.parent;
|
|
|
|
struct weston_matrix *matrix = &view->transform.matrix;
|
|
|
|
struct weston_matrix *inverse = &view->transform.inverse;
|
2012-01-20 16:24:25 +04:00
|
|
|
struct weston_transform *tform;
|
2015-02-16 15:39:11 +03:00
|
|
|
pixman_region32_t surfregion;
|
|
|
|
const pixman_box32_t *surfbox;
|
2012-01-20 16:24:25 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
view->transform.enabled = 1;
|
2012-01-20 16:24:25 +04:00
|
|
|
|
2012-02-08 17:14:17 +04:00
|
|
|
/* Otherwise identity matrix, but with x and y translation. */
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
view->transform.position.matrix.type = WESTON_MATRIX_TRANSFORM_TRANSLATE;
|
|
|
|
view->transform.position.matrix.d[12] = view->geometry.x;
|
|
|
|
view->transform.position.matrix.d[13] = view->geometry.y;
|
2012-01-25 15:37:39 +04:00
|
|
|
|
2012-01-20 16:24:25 +04:00
|
|
|
weston_matrix_init(matrix);
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
wl_list_for_each(tform, &view->geometry.transformation_list, link)
|
2012-01-20 16:24:25 +04:00
|
|
|
weston_matrix_multiply(matrix, &tform->matrix);
|
|
|
|
|
2013-03-08 16:56:50 +04:00
|
|
|
if (parent)
|
|
|
|
weston_matrix_multiply(matrix, &parent->transform.matrix);
|
|
|
|
|
2012-01-23 12:02:47 +04:00
|
|
|
if (weston_matrix_invert(inverse, matrix) < 0) {
|
|
|
|
/* Oops, bad total transformation, not invertible */
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_log("error: weston_view %p"
|
|
|
|
" transformation not invertible.\n", view);
|
2012-02-08 17:14:17 +04:00
|
|
|
return -1;
|
2012-01-23 12:02:47 +04:00
|
|
|
}
|
2012-01-25 17:17:40 +04:00
|
|
|
|
2016-09-04 18:50:46 +03:00
|
|
|
if (view->alpha == 1.0 &&
|
|
|
|
matrix->type == WESTON_MATRIX_TRANSFORM_TRANSLATE) {
|
|
|
|
pixman_region32_copy(&view->transform.opaque,
|
|
|
|
&view->surface->opaque);
|
|
|
|
pixman_region32_translate(&view->transform.opaque,
|
|
|
|
matrix->d[12],
|
|
|
|
matrix->d[13]);
|
|
|
|
}
|
|
|
|
|
2015-02-16 15:39:11 +03:00
|
|
|
pixman_region32_init_rect(&surfregion, 0, 0,
|
|
|
|
view->surface->width, view->surface->height);
|
|
|
|
if (view->geometry.scissor_enabled)
|
|
|
|
pixman_region32_intersect(&surfregion, &surfregion,
|
|
|
|
&view->geometry.scissor);
|
|
|
|
surfbox = pixman_region32_extents(&surfregion);
|
|
|
|
|
|
|
|
view_compute_bbox(view, surfbox, &view->transform.boundingbox);
|
|
|
|
pixman_region32_fini(&surfregion);
|
2012-02-24 01:11:59 +04:00
|
|
|
|
2012-02-08 17:14:17 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-07-09 23:12:57 +04:00
|
|
|
static struct weston_layer *
|
|
|
|
get_view_layer(struct weston_view *view)
|
|
|
|
{
|
|
|
|
if (view->parent_view)
|
|
|
|
return get_view_layer(view->parent_view);
|
|
|
|
return view->layer_link.layer;
|
|
|
|
}
|
|
|
|
|
2012-02-08 17:14:17 +04:00
|
|
|
WL_EXPORT void
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_update_transform(struct weston_view *view)
|
2012-02-08 17:14:17 +04:00
|
|
|
{
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
struct weston_view *parent = view->geometry.parent;
|
2014-07-09 23:12:57 +04:00
|
|
|
struct weston_layer *layer;
|
|
|
|
pixman_region32_t mask;
|
2013-03-08 16:56:50 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
if (!view->transform.dirty)
|
2012-02-08 17:14:17 +04:00
|
|
|
return;
|
|
|
|
|
2013-03-08 16:56:50 +04:00
|
|
|
if (parent)
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_update_transform(parent);
|
2013-03-08 16:56:50 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
view->transform.dirty = 0;
|
2012-02-08 17:14:17 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_damage_below(view);
|
2012-02-09 17:32:15 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
pixman_region32_fini(&view->transform.boundingbox);
|
|
|
|
pixman_region32_fini(&view->transform.opaque);
|
|
|
|
pixman_region32_init(&view->transform.opaque);
|
2012-02-24 01:11:59 +04:00
|
|
|
|
2012-02-08 17:14:17 +04:00
|
|
|
/* transform.position is always in transformation_list */
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
if (view->geometry.transformation_list.next ==
|
|
|
|
&view->transform.position.link &&
|
|
|
|
view->geometry.transformation_list.prev ==
|
|
|
|
&view->transform.position.link &&
|
2013-03-08 16:56:50 +04:00
|
|
|
!parent) {
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_update_transform_disable(view);
|
2012-02-08 17:14:17 +04:00
|
|
|
} else {
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
if (weston_view_update_transform_enable(view) < 0)
|
|
|
|
weston_view_update_transform_disable(view);
|
2012-02-08 17:14:17 +04:00
|
|
|
}
|
2012-02-09 17:32:15 +04:00
|
|
|
|
2014-07-09 23:12:57 +04:00
|
|
|
layer = get_view_layer(view);
|
|
|
|
if (layer) {
|
|
|
|
pixman_region32_init_with_extents(&mask, &layer->mask);
|
2015-02-19 12:15:33 +03:00
|
|
|
pixman_region32_intersect(&view->transform.boundingbox,
|
|
|
|
&view->transform.boundingbox, &mask);
|
2015-02-18 17:30:47 +03:00
|
|
|
pixman_region32_intersect(&view->transform.opaque,
|
|
|
|
&view->transform.opaque, &mask);
|
2014-07-09 23:12:57 +04:00
|
|
|
pixman_region32_fini(&mask);
|
|
|
|
}
|
|
|
|
|
2015-02-16 15:39:11 +03:00
|
|
|
if (parent) {
|
|
|
|
if (parent->geometry.scissor_enabled) {
|
|
|
|
view->geometry.scissor_enabled = true;
|
|
|
|
weston_view_transfer_scissor(parent, view);
|
|
|
|
} else {
|
|
|
|
view->geometry.scissor_enabled = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_damage_below(view);
|
2012-02-09 17:32:15 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_assign_output(view);
|
2013-06-12 22:43:21 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
wl_signal_emit(&view->surface->compositor->transform_signal,
|
|
|
|
view->surface);
|
2012-01-20 16:24:25 +04:00
|
|
|
}
|
|
|
|
|
2013-03-08 16:56:49 +04:00
|
|
|
WL_EXPORT void
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_geometry_dirty(struct weston_view *view)
|
2013-03-08 16:56:49 +04:00
|
|
|
{
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
struct weston_view *child;
|
2013-03-08 16:56:50 +04:00
|
|
|
|
|
|
|
/*
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
* The invariant: if view->geometry.dirty, then all views
|
|
|
|
* in view->geometry.child_list have geometry.dirty too.
|
2013-03-08 16:56:50 +04:00
|
|
|
* Corollary: if not parent->geometry.dirty, then all ancestors
|
|
|
|
* are not dirty.
|
|
|
|
*/
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
if (view->transform.dirty)
|
2013-03-08 16:56:50 +04:00
|
|
|
return;
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
view->transform.dirty = 1;
|
2013-03-08 16:56:50 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
wl_list_for_each(child, &view->geometry.child_list,
|
2013-03-08 16:56:50 +04:00
|
|
|
geometry.parent_link)
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_geometry_dirty(child);
|
2013-03-08 16:56:49 +04:00
|
|
|
}
|
|
|
|
|
2012-05-08 20:17:53 +04:00
|
|
|
WL_EXPORT void
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_to_global_fixed(struct weston_view *view,
|
|
|
|
wl_fixed_t vx, wl_fixed_t vy,
|
|
|
|
wl_fixed_t *x, wl_fixed_t *y)
|
2012-05-08 20:17:53 +04:00
|
|
|
{
|
2012-09-30 04:57:21 +04:00
|
|
|
float xf, yf;
|
2012-05-08 20:17:53 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_to_global_float(view,
|
|
|
|
wl_fixed_to_double(vx),
|
|
|
|
wl_fixed_to_double(vy),
|
|
|
|
&xf, &yf);
|
2012-05-08 20:17:53 +04:00
|
|
|
*x = wl_fixed_from_double(xf);
|
|
|
|
*y = wl_fixed_from_double(yf);
|
|
|
|
}
|
|
|
|
|
2012-09-06 05:59:35 +04:00
|
|
|
WL_EXPORT void
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_from_global_float(struct weston_view *view,
|
|
|
|
float x, float y, float *vx, float *vy)
|
2012-01-24 11:59:29 +04:00
|
|
|
{
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
if (view->transform.enabled) {
|
2012-01-24 11:59:29 +04:00
|
|
|
struct weston_vector v = { { x, y, 0.0f, 1.0f } };
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_matrix_transform(&view->transform.inverse, &v);
|
2012-01-24 11:59:29 +04:00
|
|
|
|
|
|
|
if (fabsf(v.f[3]) < 1e-6) {
|
2012-06-07 20:01:59 +04:00
|
|
|
weston_log("warning: numerical instability in "
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
"weston_view_from_global(), divisor = %g\n",
|
2012-01-24 11:59:29 +04:00
|
|
|
v.f[3]);
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
*vx = 0;
|
|
|
|
*vy = 0;
|
2012-01-24 11:59:29 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
*vx = v.f[0] / v.f[3];
|
|
|
|
*vy = v.f[1] / v.f[3];
|
2012-01-24 11:59:29 +04:00
|
|
|
} else {
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
*vx = x - view->geometry.x;
|
|
|
|
*vy = y - view->geometry.y;
|
2012-01-24 11:59:29 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-08 20:17:53 +04:00
|
|
|
WL_EXPORT void
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_from_global_fixed(struct weston_view *view,
|
|
|
|
wl_fixed_t x, wl_fixed_t y,
|
|
|
|
wl_fixed_t *vx, wl_fixed_t *vy)
|
2012-05-08 20:17:53 +04:00
|
|
|
{
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
float vxf, vyf;
|
2012-05-08 20:17:53 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_from_global_float(view,
|
|
|
|
wl_fixed_to_double(x),
|
|
|
|
wl_fixed_to_double(y),
|
|
|
|
&vxf, &vyf);
|
|
|
|
*vx = wl_fixed_from_double(vxf);
|
|
|
|
*vy = wl_fixed_from_double(vyf);
|
2012-05-08 20:17:53 +04:00
|
|
|
}
|
|
|
|
|
2012-01-24 16:47:37 +04:00
|
|
|
WL_EXPORT void
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_from_global(struct weston_view *view,
|
|
|
|
int32_t x, int32_t y, int32_t *vx, int32_t *vy)
|
2012-01-24 16:47:37 +04:00
|
|
|
{
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
float vxf, vyf;
|
2012-01-24 16:47:37 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_from_global_float(view, x, y, &vxf, &vyf);
|
|
|
|
*vx = floorf(vxf);
|
|
|
|
*vy = floorf(vyf);
|
2012-01-24 16:47:37 +04:00
|
|
|
}
|
|
|
|
|
2015-12-23 22:01:58 +03:00
|
|
|
/**
|
|
|
|
* \param surface The surface to be repainted
|
|
|
|
*
|
|
|
|
* Marks the output(s) that the surface is shown on as needing to be
|
|
|
|
* repainted. See weston_output_schedule_repaint().
|
|
|
|
*/
|
2012-08-04 00:29:12 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_surface_schedule_repaint(struct weston_surface *surface)
|
|
|
|
{
|
|
|
|
struct weston_output *output;
|
|
|
|
|
|
|
|
wl_list_for_each(output, &surface->compositor->output_list, link)
|
2015-12-24 05:38:07 +03:00
|
|
|
if (surface->output_mask & (1u << output->id))
|
2012-08-04 00:29:12 +04:00
|
|
|
weston_output_schedule_repaint(output);
|
|
|
|
}
|
|
|
|
|
2015-12-23 22:01:58 +03:00
|
|
|
/**
|
|
|
|
* \param view The view to be repainted
|
|
|
|
*
|
|
|
|
* Marks the output(s) that the view is shown on as needing to be
|
|
|
|
* repainted. See weston_output_schedule_repaint().
|
|
|
|
*/
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_view_schedule_repaint(struct weston_view *view)
|
|
|
|
{
|
|
|
|
struct weston_output *output;
|
|
|
|
|
|
|
|
wl_list_for_each(output, &view->surface->compositor->output_list, link)
|
2015-12-24 05:38:07 +03:00
|
|
|
if (view->output_mask & (1u << output->id))
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_output_schedule_repaint(output);
|
|
|
|
}
|
|
|
|
|
2015-02-19 14:59:55 +03:00
|
|
|
/**
|
|
|
|
* XXX: This function does it the wrong way.
|
|
|
|
* surface->damage is the damage from the client, and causes
|
|
|
|
* surface_flush_damage() to copy pixels. No window management action can
|
|
|
|
* cause damage to the client-provided content, warranting re-upload!
|
|
|
|
*
|
|
|
|
* Instead of surface->damage, this function should record the damage
|
|
|
|
* with all the views for this surface to avoid extraneous texture
|
|
|
|
* uploads.
|
|
|
|
*/
|
2011-04-23 21:04:11 +04:00
|
|
|
WL_EXPORT void
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
weston_surface_damage(struct weston_surface *surface)
|
2011-02-13 21:00:51 +03:00
|
|
|
{
|
2012-06-18 23:09:11 +04:00
|
|
|
pixman_region32_union_rect(&surface->damage, &surface->damage,
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
0, 0, surface->width,
|
|
|
|
surface->height);
|
2012-01-26 15:12:45 +04:00
|
|
|
|
2012-08-04 00:29:12 +04:00
|
|
|
weston_surface_schedule_repaint(surface);
|
2011-02-13 21:00:51 +03:00
|
|
|
}
|
|
|
|
|
2012-02-13 15:03:59 +04:00
|
|
|
WL_EXPORT void
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_set_position(struct weston_view *view, float x, float y)
|
2012-02-13 15:03:59 +04:00
|
|
|
{
|
2013-12-03 07:01:53 +04:00
|
|
|
if (view->geometry.x == x && view->geometry.y == y)
|
|
|
|
return;
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
view->geometry.x = x;
|
|
|
|
view->geometry.y = y;
|
|
|
|
weston_view_geometry_dirty(view);
|
2012-02-13 15:03:59 +04:00
|
|
|
}
|
|
|
|
|
2013-03-08 16:56:50 +04:00
|
|
|
static void
|
|
|
|
transform_parent_handle_parent_destroy(struct wl_listener *listener,
|
|
|
|
void *data)
|
|
|
|
{
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
struct weston_view *view =
|
|
|
|
container_of(listener, struct weston_view,
|
2013-03-08 16:56:50 +04:00
|
|
|
geometry.parent_destroy_listener);
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_set_transform_parent(view, NULL);
|
2013-03-08 16:56:50 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
WL_EXPORT void
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_set_transform_parent(struct weston_view *view,
|
2015-02-16 15:39:11 +03:00
|
|
|
struct weston_view *parent)
|
2013-03-08 16:56:50 +04:00
|
|
|
{
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
if (view->geometry.parent) {
|
|
|
|
wl_list_remove(&view->geometry.parent_destroy_listener.link);
|
|
|
|
wl_list_remove(&view->geometry.parent_link);
|
2015-02-16 15:39:11 +03:00
|
|
|
|
|
|
|
if (!parent)
|
|
|
|
view->geometry.scissor_enabled = false;
|
2013-03-08 16:56:50 +04:00
|
|
|
}
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
view->geometry.parent = parent;
|
2013-03-08 16:56:50 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
view->geometry.parent_destroy_listener.notify =
|
2013-03-08 16:56:50 +04:00
|
|
|
transform_parent_handle_parent_destroy;
|
|
|
|
if (parent) {
|
2013-06-07 07:34:41 +04:00
|
|
|
wl_signal_add(&parent->destroy_signal,
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
&view->geometry.parent_destroy_listener);
|
2013-03-08 16:56:50 +04:00
|
|
|
wl_list_insert(&parent->geometry.child_list,
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
&view->geometry.parent_link);
|
2013-03-08 16:56:50 +04:00
|
|
|
}
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_geometry_dirty(view);
|
|
|
|
}
|
|
|
|
|
2015-02-16 15:39:11 +03:00
|
|
|
/** Set a clip mask rectangle on a view
|
|
|
|
*
|
|
|
|
* \param view The view to set the clip mask on.
|
|
|
|
* \param x Top-left corner X coordinate of the clip rectangle.
|
|
|
|
* \param y Top-left corner Y coordinate of the clip rectangle.
|
|
|
|
* \param width Width of the clip rectangle, non-negative.
|
|
|
|
* \param height Height of the clip rectangle, non-negative.
|
|
|
|
*
|
|
|
|
* A shell may set a clip mask rectangle on a view. Everything outside
|
|
|
|
* the rectangle is cut away for input and output purposes: it is
|
|
|
|
* not drawn and cannot be hit by hit-test based input like pointer
|
|
|
|
* motion or touch-downs. Everything inside the rectangle will behave
|
|
|
|
* normally. Clients are unaware of clipping.
|
|
|
|
*
|
2016-04-28 19:59:10 +03:00
|
|
|
* The rectangle is set in surface-local coordinates. Setting a clip
|
2015-02-16 15:39:11 +03:00
|
|
|
* mask rectangle does not affect the view position, the view is positioned
|
|
|
|
* as it would be without a clip. The clip also does not change
|
|
|
|
* weston_surface::width,height.
|
|
|
|
*
|
|
|
|
* The clip mask rectangle is part of transformation inheritance
|
|
|
|
* (weston_view_set_transform_parent()). A clip set in the root of the
|
|
|
|
* transformation inheritance tree will affect all views in the tree.
|
|
|
|
* A clip can be set only on the root view. Attempting to set a clip
|
|
|
|
* on view that has a transformation parent will fail. Assigning a parent
|
|
|
|
* to a view that has a clip set will cause the clip to be forgotten.
|
|
|
|
*
|
|
|
|
* Because the clip mask is an axis-aligned rectangle, it poses restrictions
|
|
|
|
* on the additional transformations in the child views. These transformations
|
|
|
|
* may not rotate the coordinate axes, i.e., only translation and scaling
|
|
|
|
* are allowed. Violating this restriction causes the clipping to malfunction.
|
|
|
|
* Furthermore, using scaling may cause rounding errors in child clipping.
|
|
|
|
*
|
|
|
|
* The clip mask rectangle is not automatically adjusted based on
|
|
|
|
* wl_surface.attach dx and dy arguments.
|
|
|
|
*
|
|
|
|
* A clip mask rectangle can be set only if the compositor capability
|
|
|
|
* WESTON_CAP_VIEW_CLIP_MASK is present.
|
|
|
|
*
|
|
|
|
* This function sets the clip mask rectangle and schedules a repaint for
|
|
|
|
* the view.
|
|
|
|
*/
|
|
|
|
WL_EXPORT void
|
|
|
|
weston_view_set_mask(struct weston_view *view,
|
|
|
|
int x, int y, int width, int height)
|
|
|
|
{
|
|
|
|
struct weston_compositor *compositor = view->surface->compositor;
|
|
|
|
|
|
|
|
if (!(compositor->capabilities & WESTON_CAP_VIEW_CLIP_MASK)) {
|
|
|
|
weston_log("%s not allowed without capability!\n", __func__);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (view->geometry.parent) {
|
|
|
|
weston_log("view %p has a parent, clip forbidden!\n", view);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (width < 0 || height < 0) {
|
|
|
|
weston_log("%s: illegal args %d, %d, %d, %d\n", __func__,
|
|
|
|
x, y, width, height);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
pixman_region32_fini(&view->geometry.scissor);
|
|
|
|
pixman_region32_init_rect(&view->geometry.scissor, x, y, width, height);
|
|
|
|
view->geometry.scissor_enabled = true;
|
|
|
|
weston_view_geometry_dirty(view);
|
|
|
|
weston_view_schedule_repaint(view);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Remove the clip mask from a view
|
|
|
|
*
|
|
|
|
* \param view The view to remove the clip mask from.
|
|
|
|
*
|
|
|
|
* Removed the clip mask rectangle and schedules a repaint.
|
|
|
|
*
|
|
|
|
* \sa weston_view_set_mask
|
|
|
|
*/
|
|
|
|
WL_EXPORT void
|
|
|
|
weston_view_set_mask_infinite(struct weston_view *view)
|
|
|
|
{
|
|
|
|
view->geometry.scissor_enabled = false;
|
|
|
|
weston_view_geometry_dirty(view);
|
|
|
|
weston_view_schedule_repaint(view);
|
|
|
|
}
|
|
|
|
|
2016-06-30 07:04:33 +03:00
|
|
|
/* Check if view should be displayed
|
|
|
|
*
|
|
|
|
* The indicator is set manually when assigning
|
|
|
|
* a view to a surface.
|
|
|
|
*
|
|
|
|
* This needs reworking. See the thread starting at:
|
|
|
|
*
|
|
|
|
* https://lists.freedesktop.org/archives/wayland-devel/2016-June/029656.html
|
|
|
|
*/
|
2014-10-03 22:13:42 +04:00
|
|
|
WL_EXPORT bool
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_is_mapped(struct weston_view *view)
|
|
|
|
{
|
2016-06-30 07:04:33 +03:00
|
|
|
return view->is_mapped;
|
2013-03-08 16:56:50 +04:00
|
|
|
}
|
|
|
|
|
2016-06-30 07:04:33 +03:00
|
|
|
/* Check if a surface has a view assigned to it
|
|
|
|
*
|
|
|
|
* The indicator is set manually when mapping
|
|
|
|
* a surface and creating a view for it.
|
|
|
|
*
|
|
|
|
* This needs to go. See the thread starting at:
|
|
|
|
*
|
|
|
|
* https://lists.freedesktop.org/archives/wayland-devel/2016-June/029656.html
|
|
|
|
*
|
|
|
|
*/
|
2014-10-03 22:13:42 +04:00
|
|
|
WL_EXPORT bool
|
2012-03-27 18:36:36 +04:00
|
|
|
weston_surface_is_mapped(struct weston_surface *surface)
|
|
|
|
{
|
2016-06-30 07:04:33 +03:00
|
|
|
return surface->is_mapped;
|
2012-03-27 18:36:36 +04:00
|
|
|
}
|
|
|
|
|
2013-12-03 07:01:53 +04:00
|
|
|
static void
|
2013-12-05 06:32:03 +04:00
|
|
|
surface_set_size(struct weston_surface *surface, int32_t width, int32_t height)
|
2013-12-03 07:01:53 +04:00
|
|
|
{
|
|
|
|
struct weston_view *view;
|
|
|
|
|
|
|
|
if (surface->width == width && surface->height == height)
|
|
|
|
return;
|
|
|
|
|
|
|
|
surface->width = width;
|
|
|
|
surface->height = height;
|
|
|
|
|
|
|
|
wl_list_for_each(view, &surface->views, surface_link)
|
|
|
|
weston_view_geometry_dirty(view);
|
|
|
|
}
|
|
|
|
|
2013-12-05 06:32:03 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_surface_set_size(struct weston_surface *surface,
|
|
|
|
int32_t width, int32_t height)
|
|
|
|
{
|
|
|
|
assert(!surface->resource);
|
|
|
|
surface_set_size(surface, width, height);
|
|
|
|
}
|
|
|
|
|
2014-03-14 16:38:17 +04:00
|
|
|
static int
|
|
|
|
fixed_round_up_to_int(wl_fixed_t f)
|
|
|
|
{
|
|
|
|
return wl_fixed_to_int(wl_fixed_from_int(1) - 1 + f);
|
|
|
|
}
|
|
|
|
|
2013-11-26 21:19:43 +04:00
|
|
|
static void
|
2016-04-26 15:50:59 +03:00
|
|
|
convert_size_by_transform_scale(int32_t *width_out, int32_t *height_out,
|
|
|
|
int32_t width, int32_t height,
|
|
|
|
uint32_t transform,
|
|
|
|
int32_t scale)
|
2012-11-27 19:03:42 +04:00
|
|
|
{
|
2016-04-26 15:50:59 +03:00
|
|
|
assert(scale > 0);
|
2013-11-26 21:19:46 +04:00
|
|
|
|
2016-04-26 15:50:59 +03:00
|
|
|
switch (transform) {
|
|
|
|
case WL_OUTPUT_TRANSFORM_NORMAL:
|
|
|
|
case WL_OUTPUT_TRANSFORM_180:
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED:
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
|
|
|
|
*width_out = width / scale;
|
|
|
|
*height_out = height / scale;
|
|
|
|
break;
|
2012-11-27 19:03:42 +04:00
|
|
|
case WL_OUTPUT_TRANSFORM_90:
|
|
|
|
case WL_OUTPUT_TRANSFORM_270:
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
|
2016-04-26 15:50:59 +03:00
|
|
|
*width_out = height / scale;
|
|
|
|
*height_out = width / scale;
|
2013-11-26 21:19:43 +04:00
|
|
|
break;
|
2012-11-27 19:03:42 +04:00
|
|
|
default:
|
2016-04-26 15:50:59 +03:00
|
|
|
assert(0 && "invalid transform");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
weston_surface_calculate_size_from_buffer(struct weston_surface *surface)
|
|
|
|
{
|
|
|
|
struct weston_buffer_viewport *vp = &surface->buffer_viewport;
|
|
|
|
|
|
|
|
if (!surface->buffer_ref.buffer) {
|
|
|
|
surface->width_from_buffer = 0;
|
|
|
|
surface->height_from_buffer = 0;
|
|
|
|
return;
|
2012-11-27 19:03:42 +04:00
|
|
|
}
|
2013-11-26 21:19:43 +04:00
|
|
|
|
2016-04-26 15:50:59 +03:00
|
|
|
convert_size_by_transform_scale(&surface->width_from_buffer,
|
|
|
|
&surface->height_from_buffer,
|
|
|
|
surface->buffer_ref.buffer->width,
|
|
|
|
surface->buffer_ref.buffer->height,
|
|
|
|
vp->buffer.transform,
|
|
|
|
vp->buffer.scale);
|
2014-06-13 20:14:20 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
weston_surface_update_size(struct weston_surface *surface)
|
|
|
|
{
|
|
|
|
struct weston_buffer_viewport *vp = &surface->buffer_viewport;
|
|
|
|
int32_t width, height;
|
|
|
|
|
|
|
|
width = surface->width_from_buffer;
|
|
|
|
height = surface->height_from_buffer;
|
2014-03-14 16:38:17 +04:00
|
|
|
|
2014-06-13 20:14:20 +04:00
|
|
|
if (width != 0 && vp->surface.width != -1) {
|
2014-03-14 16:38:17 +04:00
|
|
|
surface_set_size(surface,
|
|
|
|
vp->surface.width, vp->surface.height);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-06-13 20:14:20 +04:00
|
|
|
if (width != 0 && vp->buffer.src_width != wl_fixed_from_int(-1)) {
|
2014-04-04 15:22:13 +04:00
|
|
|
int32_t w = fixed_round_up_to_int(vp->buffer.src_width);
|
|
|
|
int32_t h = fixed_round_up_to_int(vp->buffer.src_height);
|
|
|
|
|
|
|
|
surface_set_size(surface, w ?: 1, h ?: 1);
|
2014-03-14 16:38:17 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-12-05 06:32:03 +04:00
|
|
|
surface_set_size(surface, width, height);
|
2012-11-27 19:03:42 +04:00
|
|
|
}
|
|
|
|
|
2011-04-23 21:04:11 +04:00
|
|
|
WL_EXPORT uint32_t
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
weston_compositor_get_time(void)
|
2010-12-07 05:41:10 +03:00
|
|
|
{
|
2012-04-12 06:42:15 +04:00
|
|
|
struct timeval tv;
|
2010-12-07 05:41:10 +03:00
|
|
|
|
2012-04-12 06:42:15 +04:00
|
|
|
gettimeofday(&tv, NULL);
|
2010-12-07 05:41:10 +03:00
|
|
|
|
2012-04-12 06:42:15 +04:00
|
|
|
return tv.tv_sec * 1000 + tv.tv_usec / 1000;
|
2010-12-07 05:41:10 +03:00
|
|
|
}
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
WL_EXPORT struct weston_view *
|
|
|
|
weston_compositor_pick_view(struct weston_compositor *compositor,
|
|
|
|
wl_fixed_t x, wl_fixed_t y,
|
|
|
|
wl_fixed_t *vx, wl_fixed_t *vy)
|
2012-02-10 18:26:19 +04:00
|
|
|
{
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
struct weston_view *view;
|
2015-02-18 16:08:29 +03:00
|
|
|
wl_fixed_t view_x, view_y;
|
|
|
|
int view_ix, view_iy;
|
|
|
|
int ix = wl_fixed_to_int(x);
|
|
|
|
int iy = wl_fixed_to_int(y);
|
2012-02-10 18:26:19 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
wl_list_for_each(view, &compositor->view_list, link) {
|
2015-02-18 16:08:29 +03:00
|
|
|
if (!pixman_region32_contains_point(
|
|
|
|
&view->transform.boundingbox, ix, iy, NULL))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
weston_view_from_global_fixed(view, x, y, &view_x, &view_y);
|
|
|
|
view_ix = wl_fixed_to_int(view_x);
|
|
|
|
view_iy = wl_fixed_to_int(view_y);
|
|
|
|
|
|
|
|
if (!pixman_region32_contains_point(&view->surface->input,
|
|
|
|
view_ix, view_iy, NULL))
|
|
|
|
continue;
|
|
|
|
|
2015-02-16 15:39:11 +03:00
|
|
|
if (view->geometry.scissor_enabled &&
|
|
|
|
!pixman_region32_contains_point(&view->geometry.scissor,
|
|
|
|
view_ix, view_iy, NULL))
|
|
|
|
continue;
|
|
|
|
|
2015-02-18 16:08:29 +03:00
|
|
|
*vx = view_x;
|
|
|
|
*vy = view_y;
|
|
|
|
return view;
|
2012-02-10 18:26:19 +04:00
|
|
|
}
|
|
|
|
|
2015-05-11 23:40:11 +03:00
|
|
|
*vx = wl_fixed_from_int(-1000000);
|
|
|
|
*vy = wl_fixed_from_int(-1000000);
|
2012-02-10 18:26:19 +04:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-06-19 00:48:27 +04:00
|
|
|
static void
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
weston_compositor_repick(struct weston_compositor *compositor)
|
2011-10-12 06:20:37 +04:00
|
|
|
{
|
2012-05-16 21:45:18 +04:00
|
|
|
struct weston_seat *seat;
|
2011-10-12 06:20:37 +04:00
|
|
|
|
2013-10-22 23:40:54 +04:00
|
|
|
if (!compositor->session_active)
|
2011-11-16 01:39:55 +04:00
|
|
|
return;
|
|
|
|
|
2012-05-16 21:45:18 +04:00
|
|
|
wl_list_for_each(seat, &compositor->seat_list, link)
|
2013-05-07 05:51:21 +04:00
|
|
|
weston_seat_repick(seat);
|
2011-10-12 06:20:37 +04:00
|
|
|
}
|
|
|
|
|
2012-06-27 05:19:23 +04:00
|
|
|
WL_EXPORT void
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_unmap(struct weston_view *view)
|
2012-02-17 21:43:56 +04:00
|
|
|
{
|
2012-05-30 19:31:53 +04:00
|
|
|
struct weston_seat *seat;
|
2012-03-02 02:09:37 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
if (!weston_view_is_mapped(view))
|
|
|
|
return;
|
|
|
|
|
|
|
|
weston_view_damage_below(view);
|
|
|
|
view->output = NULL;
|
2013-10-23 09:58:31 +04:00
|
|
|
view->plane = NULL;
|
2016-06-30 07:04:28 +03:00
|
|
|
view->is_mapped = false;
|
2014-07-09 23:12:56 +04:00
|
|
|
weston_layer_entry_remove(&view->layer_link);
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
wl_list_remove(&view->link);
|
|
|
|
wl_list_init(&view->link);
|
|
|
|
view->output_mask = 0;
|
|
|
|
weston_surface_assign_output(view->surface);
|
|
|
|
|
|
|
|
if (weston_surface_is_mapped(view->surface))
|
|
|
|
return;
|
2012-03-02 02:09:37 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
wl_list_for_each(seat, &view->surface->compositor->seat_list, link) {
|
2015-08-01 00:55:32 +03:00
|
|
|
struct weston_touch *touch = weston_seat_get_touch(seat);
|
|
|
|
struct weston_pointer *pointer = weston_seat_get_pointer(seat);
|
|
|
|
struct weston_keyboard *keyboard =
|
|
|
|
weston_seat_get_keyboard(seat);
|
|
|
|
|
|
|
|
if (keyboard && keyboard->focus == view->surface)
|
|
|
|
weston_keyboard_set_focus(keyboard, NULL);
|
|
|
|
if (pointer && pointer->focus == view)
|
2015-05-11 23:40:11 +03:00
|
|
|
weston_pointer_clear_focus(pointer);
|
2015-08-01 00:55:32 +03:00
|
|
|
if (touch && touch->focus == view)
|
|
|
|
weston_touch_set_focus(touch, NULL);
|
2012-05-30 19:31:53 +04:00
|
|
|
}
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
}
|
2012-03-02 02:09:37 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_surface_unmap(struct weston_surface *surface)
|
|
|
|
{
|
|
|
|
struct weston_view *view;
|
|
|
|
|
2016-06-30 07:04:28 +03:00
|
|
|
surface->is_mapped = false;
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
wl_list_for_each(view, &surface->views, surface_link)
|
|
|
|
weston_view_unmap(view);
|
|
|
|
surface->output = NULL;
|
2012-02-17 21:43:56 +04:00
|
|
|
}
|
|
|
|
|
2014-03-14 16:38:13 +04:00
|
|
|
static void
|
|
|
|
weston_surface_reset_pending_buffer(struct weston_surface *surface)
|
|
|
|
{
|
2014-05-20 23:33:03 +04:00
|
|
|
weston_surface_state_set_buffer(&surface->pending, NULL);
|
2014-03-14 16:38:13 +04:00
|
|
|
surface->pending.sx = 0;
|
|
|
|
surface->pending.sy = 0;
|
|
|
|
surface->pending.newly_attached = 0;
|
2014-06-13 20:14:20 +04:00
|
|
|
surface->pending.buffer_viewport.changed = 0;
|
2014-03-14 16:38:13 +04:00
|
|
|
}
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_view_destroy(struct weston_view *view)
|
|
|
|
{
|
|
|
|
wl_signal_emit(&view->destroy_signal, view);
|
|
|
|
|
|
|
|
assert(wl_list_empty(&view->geometry.child_list));
|
|
|
|
|
|
|
|
if (weston_view_is_mapped(view)) {
|
|
|
|
weston_view_unmap(view);
|
|
|
|
weston_compositor_build_view_list(view->surface->compositor);
|
|
|
|
}
|
|
|
|
|
|
|
|
wl_list_remove(&view->link);
|
2014-07-09 23:12:56 +04:00
|
|
|
weston_layer_entry_remove(&view->layer_link);
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
|
|
|
|
pixman_region32_fini(&view->clip);
|
2015-02-16 15:39:11 +03:00
|
|
|
pixman_region32_fini(&view->geometry.scissor);
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
pixman_region32_fini(&view->transform.boundingbox);
|
2015-02-18 17:30:47 +03:00
|
|
|
pixman_region32_fini(&view->transform.opaque);
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
|
|
|
|
weston_view_set_transform_parent(view, NULL);
|
|
|
|
|
|
|
|
wl_list_remove(&view->surface_link);
|
|
|
|
|
|
|
|
free(view);
|
|
|
|
}
|
2013-06-07 07:34:41 +04:00
|
|
|
|
|
|
|
WL_EXPORT void
|
|
|
|
weston_surface_destroy(struct weston_surface *surface)
|
2008-11-24 01:07:32 +03:00
|
|
|
{
|
2012-07-22 19:33:14 +04:00
|
|
|
struct weston_frame_callback *cb, *next;
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
struct weston_view *ev, *nv;
|
2016-07-22 12:56:31 +03:00
|
|
|
struct weston_pointer_constraint *constraint, *next_constraint;
|
2009-03-11 06:17:00 +03:00
|
|
|
|
2013-08-14 01:10:14 +04:00
|
|
|
if (--surface->ref_count > 0)
|
|
|
|
return;
|
|
|
|
|
2015-04-17 14:00:24 +03:00
|
|
|
assert(surface->resource == NULL);
|
|
|
|
|
2015-04-17 14:23:38 +03:00
|
|
|
wl_signal_emit(&surface->destroy_signal, surface);
|
2013-08-14 01:10:14 +04:00
|
|
|
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
assert(wl_list_empty(&surface->subsurface_list_pending));
|
|
|
|
assert(wl_list_empty(&surface->subsurface_list));
|
2013-03-08 16:56:50 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
wl_list_for_each_safe(ev, nv, &surface->views, surface_link)
|
|
|
|
weston_view_destroy(ev);
|
2011-10-12 06:20:37 +04:00
|
|
|
|
2014-05-20 23:33:03 +04:00
|
|
|
weston_surface_state_fini(&surface->pending);
|
2012-10-10 13:49:23 +04:00
|
|
|
|
compositor: introduce weston_buffer_reference
The wl_buffer reference counting API has been inconsistent. You would
manually increment the refcount and register a destroy listener, as
opposed to calling weston_buffer_post_release(), which internally
decremented the refcount, and then removing a list item.
Replace both cases with a single function:
weston_buffer_reference(weston_buffer_reference *ref, wl_buffer *buffer)
Buffer is assigned to ref->buffer, while taking care of all the refcounting
and release posting. You take a reference by passing a non-NULL buffer, and
release a reference by passing NULL as buffer. The function uses an
internal wl_buffer destroy listener, so the pointer gets reset on
destruction automatically.
This is inspired by the pipe_resource_reference() of Mesa, and modified
by krh's suggestion to add struct weston_buffer_reference.
Additionally, when a surface gets destroyed, the associated wl_buffer
will send a release event. Often the buffer is already destroyed on
client side, so the event will be discarded by libwayland-client.
Compositor-drm.c is converted to use weston_buffer_reference.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2012-12-04 17:58:12 +04:00
|
|
|
weston_buffer_reference(&surface->buffer_ref, NULL);
|
2009-09-19 01:05:13 +04:00
|
|
|
|
2012-01-03 12:23:24 +04:00
|
|
|
pixman_region32_fini(&surface->damage);
|
2012-02-24 01:11:59 +04:00
|
|
|
pixman_region32_fini(&surface->opaque);
|
2012-10-10 13:49:28 +04:00
|
|
|
pixman_region32_fini(&surface->input);
|
2012-01-03 12:23:24 +04:00
|
|
|
|
2012-07-22 19:33:14 +04:00
|
|
|
wl_list_for_each_safe(cb, next, &surface->frame_callback_list, link)
|
2013-06-14 19:07:57 +04:00
|
|
|
wl_resource_destroy(cb->resource);
|
2012-07-22 19:33:14 +04:00
|
|
|
|
2014-09-24 06:08:46 +04:00
|
|
|
weston_presentation_feedback_discard_list(&surface->feedback_list);
|
|
|
|
|
2016-07-22 12:56:31 +03:00
|
|
|
wl_list_for_each_safe(constraint, next_constraint,
|
|
|
|
&surface->pointer_constraints,
|
|
|
|
link)
|
|
|
|
weston_pointer_constraint_destroy(constraint);
|
|
|
|
|
2009-03-11 06:17:00 +03:00
|
|
|
free(surface);
|
2008-11-24 01:07:32 +03:00
|
|
|
}
|
|
|
|
|
2013-06-07 07:34:41 +04:00
|
|
|
static void
|
|
|
|
destroy_surface(struct wl_resource *resource)
|
2012-02-28 14:07:54 +04:00
|
|
|
{
|
2013-06-07 07:34:41 +04:00
|
|
|
struct weston_surface *surface = wl_resource_get_user_data(resource);
|
2012-02-28 14:07:54 +04:00
|
|
|
|
2015-04-17 14:00:24 +03:00
|
|
|
assert(surface);
|
|
|
|
|
2013-11-16 01:06:15 +04:00
|
|
|
/* Set the resource to NULL, since we don't want to leave a
|
|
|
|
* dangling pointer if the surface was refcounted and survives
|
|
|
|
* the weston_surface_destroy() call. */
|
|
|
|
surface->resource = NULL;
|
2016-04-22 14:14:38 +03:00
|
|
|
|
|
|
|
if (surface->viewport_resource)
|
|
|
|
wl_resource_set_user_data(surface->viewport_resource, NULL);
|
|
|
|
|
2013-06-07 07:34:41 +04:00
|
|
|
weston_surface_destroy(surface);
|
2012-02-28 14:07:54 +04:00
|
|
|
}
|
|
|
|
|
2013-06-21 05:38:23 +04:00
|
|
|
static void
|
|
|
|
weston_buffer_destroy_handler(struct wl_listener *listener, void *data)
|
|
|
|
{
|
|
|
|
struct weston_buffer *buffer =
|
|
|
|
container_of(listener, struct weston_buffer, destroy_listener);
|
|
|
|
|
|
|
|
wl_signal_emit(&buffer->destroy_signal, buffer);
|
|
|
|
free(buffer);
|
|
|
|
}
|
|
|
|
|
2013-12-12 17:14:29 +04:00
|
|
|
WL_EXPORT struct weston_buffer *
|
2013-06-21 05:38:23 +04:00
|
|
|
weston_buffer_from_resource(struct wl_resource *resource)
|
|
|
|
{
|
|
|
|
struct weston_buffer *buffer;
|
|
|
|
struct wl_listener *listener;
|
2014-01-18 01:19:01 +04:00
|
|
|
|
2013-06-21 05:38:23 +04:00
|
|
|
listener = wl_resource_get_destroy_listener(resource,
|
|
|
|
weston_buffer_destroy_handler);
|
|
|
|
|
2013-08-15 23:26:42 +04:00
|
|
|
if (listener)
|
|
|
|
return container_of(listener, struct weston_buffer,
|
|
|
|
destroy_listener);
|
|
|
|
|
|
|
|
buffer = zalloc(sizeof *buffer);
|
|
|
|
if (buffer == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
buffer->resource = resource;
|
|
|
|
wl_signal_init(&buffer->destroy_signal);
|
|
|
|
buffer->destroy_listener.notify = weston_buffer_destroy_handler;
|
2013-08-29 11:36:44 +04:00
|
|
|
buffer->y_inverted = 1;
|
2013-08-15 23:26:42 +04:00
|
|
|
wl_resource_add_destroy_listener(resource, &buffer->destroy_listener);
|
2014-01-18 01:19:01 +04:00
|
|
|
|
2013-06-21 05:38:23 +04:00
|
|
|
return buffer;
|
|
|
|
}
|
|
|
|
|
2011-02-21 18:24:53 +03:00
|
|
|
static void
|
compositor: introduce weston_buffer_reference
The wl_buffer reference counting API has been inconsistent. You would
manually increment the refcount and register a destroy listener, as
opposed to calling weston_buffer_post_release(), which internally
decremented the refcount, and then removing a list item.
Replace both cases with a single function:
weston_buffer_reference(weston_buffer_reference *ref, wl_buffer *buffer)
Buffer is assigned to ref->buffer, while taking care of all the refcounting
and release posting. You take a reference by passing a non-NULL buffer, and
release a reference by passing NULL as buffer. The function uses an
internal wl_buffer destroy listener, so the pointer gets reset on
destruction automatically.
This is inspired by the pipe_resource_reference() of Mesa, and modified
by krh's suggestion to add struct weston_buffer_reference.
Additionally, when a surface gets destroyed, the associated wl_buffer
will send a release event. Often the buffer is already destroyed on
client side, so the event will be discarded by libwayland-client.
Compositor-drm.c is converted to use weston_buffer_reference.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2012-12-04 17:58:12 +04:00
|
|
|
weston_buffer_reference_handle_destroy(struct wl_listener *listener,
|
|
|
|
void *data)
|
|
|
|
{
|
|
|
|
struct weston_buffer_reference *ref =
|
|
|
|
container_of(listener, struct weston_buffer_reference,
|
|
|
|
destroy_listener);
|
|
|
|
|
2013-06-21 05:38:23 +04:00
|
|
|
assert((struct weston_buffer *)data == ref->buffer);
|
compositor: introduce weston_buffer_reference
The wl_buffer reference counting API has been inconsistent. You would
manually increment the refcount and register a destroy listener, as
opposed to calling weston_buffer_post_release(), which internally
decremented the refcount, and then removing a list item.
Replace both cases with a single function:
weston_buffer_reference(weston_buffer_reference *ref, wl_buffer *buffer)
Buffer is assigned to ref->buffer, while taking care of all the refcounting
and release posting. You take a reference by passing a non-NULL buffer, and
release a reference by passing NULL as buffer. The function uses an
internal wl_buffer destroy listener, so the pointer gets reset on
destruction automatically.
This is inspired by the pipe_resource_reference() of Mesa, and modified
by krh's suggestion to add struct weston_buffer_reference.
Additionally, when a surface gets destroyed, the associated wl_buffer
will send a release event. Often the buffer is already destroyed on
client side, so the event will be discarded by libwayland-client.
Compositor-drm.c is converted to use weston_buffer_reference.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2012-12-04 17:58:12 +04:00
|
|
|
ref->buffer = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
WL_EXPORT void
|
|
|
|
weston_buffer_reference(struct weston_buffer_reference *ref,
|
2013-06-21 05:38:23 +04:00
|
|
|
struct weston_buffer *buffer)
|
2011-02-21 18:24:53 +03:00
|
|
|
{
|
compositor: introduce weston_buffer_reference
The wl_buffer reference counting API has been inconsistent. You would
manually increment the refcount and register a destroy listener, as
opposed to calling weston_buffer_post_release(), which internally
decremented the refcount, and then removing a list item.
Replace both cases with a single function:
weston_buffer_reference(weston_buffer_reference *ref, wl_buffer *buffer)
Buffer is assigned to ref->buffer, while taking care of all the refcounting
and release posting. You take a reference by passing a non-NULL buffer, and
release a reference by passing NULL as buffer. The function uses an
internal wl_buffer destroy listener, so the pointer gets reset on
destruction automatically.
This is inspired by the pipe_resource_reference() of Mesa, and modified
by krh's suggestion to add struct weston_buffer_reference.
Additionally, when a surface gets destroyed, the associated wl_buffer
will send a release event. Often the buffer is already destroyed on
client side, so the event will be discarded by libwayland-client.
Compositor-drm.c is converted to use weston_buffer_reference.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2012-12-04 17:58:12 +04:00
|
|
|
if (ref->buffer && buffer != ref->buffer) {
|
2013-03-04 21:07:46 +04:00
|
|
|
ref->buffer->busy_count--;
|
|
|
|
if (ref->buffer->busy_count == 0) {
|
2013-06-21 05:38:23 +04:00
|
|
|
assert(wl_resource_get_client(ref->buffer->resource));
|
|
|
|
wl_resource_queue_event(ref->buffer->resource,
|
2013-03-04 21:07:46 +04:00
|
|
|
WL_BUFFER_RELEASE);
|
|
|
|
}
|
compositor: introduce weston_buffer_reference
The wl_buffer reference counting API has been inconsistent. You would
manually increment the refcount and register a destroy listener, as
opposed to calling weston_buffer_post_release(), which internally
decremented the refcount, and then removing a list item.
Replace both cases with a single function:
weston_buffer_reference(weston_buffer_reference *ref, wl_buffer *buffer)
Buffer is assigned to ref->buffer, while taking care of all the refcounting
and release posting. You take a reference by passing a non-NULL buffer, and
release a reference by passing NULL as buffer. The function uses an
internal wl_buffer destroy listener, so the pointer gets reset on
destruction automatically.
This is inspired by the pipe_resource_reference() of Mesa, and modified
by krh's suggestion to add struct weston_buffer_reference.
Additionally, when a surface gets destroyed, the associated wl_buffer
will send a release event. Often the buffer is already destroyed on
client side, so the event will be discarded by libwayland-client.
Compositor-drm.c is converted to use weston_buffer_reference.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2012-12-04 17:58:12 +04:00
|
|
|
wl_list_remove(&ref->destroy_listener.link);
|
2012-03-27 18:36:40 +04:00
|
|
|
}
|
|
|
|
|
compositor: introduce weston_buffer_reference
The wl_buffer reference counting API has been inconsistent. You would
manually increment the refcount and register a destroy listener, as
opposed to calling weston_buffer_post_release(), which internally
decremented the refcount, and then removing a list item.
Replace both cases with a single function:
weston_buffer_reference(weston_buffer_reference *ref, wl_buffer *buffer)
Buffer is assigned to ref->buffer, while taking care of all the refcounting
and release posting. You take a reference by passing a non-NULL buffer, and
release a reference by passing NULL as buffer. The function uses an
internal wl_buffer destroy listener, so the pointer gets reset on
destruction automatically.
This is inspired by the pipe_resource_reference() of Mesa, and modified
by krh's suggestion to add struct weston_buffer_reference.
Additionally, when a surface gets destroyed, the associated wl_buffer
will send a release event. Often the buffer is already destroyed on
client side, so the event will be discarded by libwayland-client.
Compositor-drm.c is converted to use weston_buffer_reference.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2012-12-04 17:58:12 +04:00
|
|
|
if (buffer && buffer != ref->buffer) {
|
2012-09-06 06:38:18 +04:00
|
|
|
buffer->busy_count++;
|
2013-06-21 05:38:23 +04:00
|
|
|
wl_signal_add(&buffer->destroy_signal,
|
compositor: introduce weston_buffer_reference
The wl_buffer reference counting API has been inconsistent. You would
manually increment the refcount and register a destroy listener, as
opposed to calling weston_buffer_post_release(), which internally
decremented the refcount, and then removing a list item.
Replace both cases with a single function:
weston_buffer_reference(weston_buffer_reference *ref, wl_buffer *buffer)
Buffer is assigned to ref->buffer, while taking care of all the refcounting
and release posting. You take a reference by passing a non-NULL buffer, and
release a reference by passing NULL as buffer. The function uses an
internal wl_buffer destroy listener, so the pointer gets reset on
destruction automatically.
This is inspired by the pipe_resource_reference() of Mesa, and modified
by krh's suggestion to add struct weston_buffer_reference.
Additionally, when a surface gets destroyed, the associated wl_buffer
will send a release event. Often the buffer is already destroyed on
client side, so the event will be discarded by libwayland-client.
Compositor-drm.c is converted to use weston_buffer_reference.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2012-12-04 17:58:12 +04:00
|
|
|
&ref->destroy_listener);
|
2012-12-04 17:58:10 +04:00
|
|
|
}
|
|
|
|
|
compositor: introduce weston_buffer_reference
The wl_buffer reference counting API has been inconsistent. You would
manually increment the refcount and register a destroy listener, as
opposed to calling weston_buffer_post_release(), which internally
decremented the refcount, and then removing a list item.
Replace both cases with a single function:
weston_buffer_reference(weston_buffer_reference *ref, wl_buffer *buffer)
Buffer is assigned to ref->buffer, while taking care of all the refcounting
and release posting. You take a reference by passing a non-NULL buffer, and
release a reference by passing NULL as buffer. The function uses an
internal wl_buffer destroy listener, so the pointer gets reset on
destruction automatically.
This is inspired by the pipe_resource_reference() of Mesa, and modified
by krh's suggestion to add struct weston_buffer_reference.
Additionally, when a surface gets destroyed, the associated wl_buffer
will send a release event. Often the buffer is already destroyed on
client side, so the event will be discarded by libwayland-client.
Compositor-drm.c is converted to use weston_buffer_reference.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2012-12-04 17:58:12 +04:00
|
|
|
ref->buffer = buffer;
|
|
|
|
ref->destroy_listener.notify = weston_buffer_reference_handle_destroy;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-06-21 05:38:23 +04:00
|
|
|
weston_surface_attach(struct weston_surface *surface,
|
|
|
|
struct weston_buffer *buffer)
|
compositor: introduce weston_buffer_reference
The wl_buffer reference counting API has been inconsistent. You would
manually increment the refcount and register a destroy listener, as
opposed to calling weston_buffer_post_release(), which internally
decremented the refcount, and then removing a list item.
Replace both cases with a single function:
weston_buffer_reference(weston_buffer_reference *ref, wl_buffer *buffer)
Buffer is assigned to ref->buffer, while taking care of all the refcounting
and release posting. You take a reference by passing a non-NULL buffer, and
release a reference by passing NULL as buffer. The function uses an
internal wl_buffer destroy listener, so the pointer gets reset on
destruction automatically.
This is inspired by the pipe_resource_reference() of Mesa, and modified
by krh's suggestion to add struct weston_buffer_reference.
Additionally, when a surface gets destroyed, the associated wl_buffer
will send a release event. Often the buffer is already destroyed on
client side, so the event will be discarded by libwayland-client.
Compositor-drm.c is converted to use weston_buffer_reference.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2012-12-04 17:58:12 +04:00
|
|
|
{
|
|
|
|
weston_buffer_reference(&surface->buffer_ref, buffer);
|
|
|
|
|
2012-12-04 17:58:10 +04:00
|
|
|
if (!buffer) {
|
2012-10-10 13:49:23 +04:00
|
|
|
if (weston_surface_is_mapped(surface))
|
|
|
|
weston_surface_unmap(surface);
|
2012-03-27 18:36:40 +04:00
|
|
|
}
|
|
|
|
|
2012-10-10 13:49:23 +04:00
|
|
|
surface->compositor->renderer->attach(surface, buffer);
|
2014-03-14 16:38:11 +04:00
|
|
|
|
2014-06-13 20:14:20 +04:00
|
|
|
weston_surface_calculate_size_from_buffer(surface);
|
2014-09-24 06:08:46 +04:00
|
|
|
weston_presentation_feedback_discard_list(&surface->feedback_list);
|
2011-02-21 18:24:53 +03:00
|
|
|
}
|
|
|
|
|
2011-04-23 21:04:11 +04:00
|
|
|
WL_EXPORT void
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
weston_compositor_damage_all(struct weston_compositor *compositor)
|
2011-04-22 22:01:18 +04:00
|
|
|
{
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
struct weston_output *output;
|
2011-04-22 22:01:18 +04:00
|
|
|
|
|
|
|
wl_list_for_each(output, &compositor->output_list, link)
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
weston_output_damage(output);
|
2011-04-22 22:01:18 +04:00
|
|
|
}
|
|
|
|
|
2011-04-23 21:04:11 +04:00
|
|
|
WL_EXPORT void
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
weston_output_damage(struct weston_output *output)
|
2011-04-22 22:01:18 +04:00
|
|
|
{
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
struct weston_compositor *compositor = output->compositor;
|
2011-11-11 20:48:12 +04:00
|
|
|
|
2012-08-03 19:30:18 +04:00
|
|
|
pixman_region32_union(&compositor->primary_plane.damage,
|
|
|
|
&compositor->primary_plane.damage,
|
|
|
|
&output->region);
|
2012-06-20 08:35:59 +04:00
|
|
|
weston_output_schedule_repaint(output);
|
2011-04-22 22:01:18 +04:00
|
|
|
}
|
|
|
|
|
2012-06-18 23:09:11 +04:00
|
|
|
static void
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
surface_flush_damage(struct weston_surface *surface)
|
2012-06-18 23:09:11 +04:00
|
|
|
{
|
compositor: introduce weston_buffer_reference
The wl_buffer reference counting API has been inconsistent. You would
manually increment the refcount and register a destroy listener, as
opposed to calling weston_buffer_post_release(), which internally
decremented the refcount, and then removing a list item.
Replace both cases with a single function:
weston_buffer_reference(weston_buffer_reference *ref, wl_buffer *buffer)
Buffer is assigned to ref->buffer, while taking care of all the refcounting
and release posting. You take a reference by passing a non-NULL buffer, and
release a reference by passing NULL as buffer. The function uses an
internal wl_buffer destroy listener, so the pointer gets reset on
destruction automatically.
This is inspired by the pipe_resource_reference() of Mesa, and modified
by krh's suggestion to add struct weston_buffer_reference.
Additionally, when a surface gets destroyed, the associated wl_buffer
will send a release event. Often the buffer is already destroyed on
client side, so the event will be discarded by libwayland-client.
Compositor-drm.c is converted to use weston_buffer_reference.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2012-12-04 17:58:12 +04:00
|
|
|
if (surface->buffer_ref.buffer &&
|
2013-06-21 05:38:23 +04:00
|
|
|
wl_shm_buffer_get(surface->buffer_ref.buffer->resource))
|
2012-09-06 06:49:55 +04:00
|
|
|
surface->compositor->renderer->flush_damage(surface);
|
2012-06-18 23:09:11 +04:00
|
|
|
|
compositor: Implement JSON-timeline logging
Logging is activated and deactivated with the debug key binding 't'.
When activated, it creates a new log file, where it records the events.
The log file contains events and detailed object information entries in
JSON format, and is meant to be parsed in sequence from beginning to the
end.
The emitted events are mostly related to the output repaint cycle, like
when repaint begins, is submitted to GPU, and when it completes on a
vblank. This is recorded per-output. Also some per-surface events are
recorded, including when surface damage is flushed.
To reduce the log size, events refer to objects like outputs and
surfaces by id numbers. Detailed object information is emitted only as
needed: on the first object occurrence, and afterwards only if
weston_timeline_object::force_refresh asks for it.
The detailed information for surfaces includes the string returned by
weston_surface::get_label. Therefore it is important to set
weston_timeline_object::force_refresh = 1 whenever the string would
change, so that the new details get recorded.
A rudimentary parser and SVG generator can be found at:
https://github.com/ppaalanen/wesgr
The timeline logs can answer questions including:
- How does the compositor repaint cycle work timing-wise?
- When was the vblank deadline missed?
- What is the latency from surface commit to showing the new content on
screen?
- How long does it take to process the scenegraph?
v2: weston_surface::get_description renamed to get_label.
v3: reafctor a bit into fprint_quoted_string().
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2014-11-12 16:09:24 +03:00
|
|
|
if (weston_timeline_enabled_ &&
|
|
|
|
pixman_region32_not_empty(&surface->damage))
|
|
|
|
TL_POINT("core_flush_damage", TLP_SURFACE(surface),
|
|
|
|
TLP_OUTPUT(surface->output), TLP_END);
|
|
|
|
|
2014-06-26 21:37:36 +04:00
|
|
|
pixman_region32_clear(&surface->damage);
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
view_accumulate_damage(struct weston_view *view,
|
|
|
|
pixman_region32_t *opaque)
|
|
|
|
{
|
|
|
|
pixman_region32_t damage;
|
|
|
|
|
|
|
|
pixman_region32_init(&damage);
|
|
|
|
if (view->transform.enabled) {
|
2012-06-18 23:09:11 +04:00
|
|
|
pixman_box32_t *extents;
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
extents = pixman_region32_extents(&view->surface->damage);
|
2015-02-23 13:27:00 +03:00
|
|
|
view_compute_bbox(view, extents, &damage);
|
2012-06-18 23:09:11 +04:00
|
|
|
} else {
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
pixman_region32_copy(&damage, &view->surface->damage);
|
|
|
|
pixman_region32_translate(&damage,
|
2015-02-23 15:08:25 +03:00
|
|
|
view->geometry.x, view->geometry.y);
|
2012-06-18 23:09:11 +04:00
|
|
|
}
|
|
|
|
|
2015-02-16 15:39:11 +03:00
|
|
|
pixman_region32_intersect(&damage, &damage,
|
|
|
|
&view->transform.boundingbox);
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
pixman_region32_subtract(&damage, &damage, opaque);
|
|
|
|
pixman_region32_union(&view->plane->damage,
|
|
|
|
&view->plane->damage, &damage);
|
|
|
|
pixman_region32_fini(&damage);
|
|
|
|
pixman_region32_copy(&view->clip, opaque);
|
2015-02-18 17:30:47 +03:00
|
|
|
pixman_region32_union(opaque, opaque, &view->transform.opaque);
|
2012-06-18 23:09:11 +04:00
|
|
|
}
|
|
|
|
|
2013-03-05 19:30:27 +04:00
|
|
|
static void
|
|
|
|
compositor_accumulate_damage(struct weston_compositor *ec)
|
|
|
|
{
|
|
|
|
struct weston_plane *plane;
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
struct weston_view *ev;
|
2013-03-05 19:30:29 +04:00
|
|
|
pixman_region32_t opaque, clip;
|
2013-03-05 19:30:27 +04:00
|
|
|
|
2013-03-05 19:30:29 +04:00
|
|
|
pixman_region32_init(&clip);
|
2013-03-05 19:30:27 +04:00
|
|
|
|
|
|
|
wl_list_for_each(plane, &ec->plane_list, link) {
|
2013-03-05 19:30:29 +04:00
|
|
|
pixman_region32_copy(&plane->clip, &clip);
|
|
|
|
|
|
|
|
pixman_region32_init(&opaque);
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
wl_list_for_each(ev, &ec->view_list, link) {
|
|
|
|
if (ev->plane != plane)
|
2013-03-05 19:30:29 +04:00
|
|
|
continue;
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
view_accumulate_damage(ev, &opaque);
|
2013-03-05 19:30:29 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
pixman_region32_union(&clip, &clip, &opaque);
|
|
|
|
pixman_region32_fini(&opaque);
|
2013-03-05 19:30:27 +04:00
|
|
|
}
|
|
|
|
|
2013-03-05 19:30:29 +04:00
|
|
|
pixman_region32_fini(&clip);
|
2013-03-05 19:30:27 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
wl_list_for_each(ev, &ec->view_list, link)
|
2015-11-19 01:32:26 +03:00
|
|
|
ev->surface->touched = false;
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
|
|
|
|
wl_list_for_each(ev, &ec->view_list, link) {
|
|
|
|
if (ev->surface->touched)
|
|
|
|
continue;
|
2015-11-19 01:32:26 +03:00
|
|
|
ev->surface->touched = true;
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
|
|
|
|
surface_flush_damage(ev->surface);
|
|
|
|
|
2013-03-05 19:30:27 +04:00
|
|
|
/* Both the renderer and the backend have seen the buffer
|
|
|
|
* by now. If renderer needs the buffer, it has its own
|
|
|
|
* reference set. If the backend wants to keep the buffer
|
|
|
|
* around for migrating the surface into a non-primary plane
|
|
|
|
* later, keep_buffer is true. Otherwise, drop the core
|
|
|
|
* reference now, and allow early buffer release. This enables
|
|
|
|
* clients to use single-buffering.
|
|
|
|
*/
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
if (!ev->surface->keep_buffer)
|
|
|
|
weston_buffer_reference(&ev->surface->buffer_ref, NULL);
|
2013-03-05 19:30:27 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
static void
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
surface_stash_subsurface_views(struct weston_surface *surface)
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
{
|
|
|
|
struct weston_subsurface *sub;
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
wl_list_for_each(sub, &surface->subsurface_list, parent_link) {
|
|
|
|
if (sub->surface == surface)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
wl_list_insert_list(&sub->unused_views, &sub->surface->views);
|
|
|
|
wl_list_init(&sub->surface->views);
|
|
|
|
|
|
|
|
surface_stash_subsurface_views(sub->surface);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
}
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
surface_free_unused_subsurface_views(struct weston_surface *surface)
|
|
|
|
{
|
|
|
|
struct weston_subsurface *sub;
|
|
|
|
struct weston_view *view, *nv;
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
|
|
|
|
wl_list_for_each(sub, &surface->subsurface_list, parent_link) {
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
if (sub->surface == surface)
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
continue;
|
|
|
|
|
2014-06-13 20:10:26 +04:00
|
|
|
wl_list_for_each_safe(view, nv, &sub->unused_views, surface_link) {
|
|
|
|
weston_view_unmap (view);
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_destroy(view);
|
2014-06-13 20:10:26 +04:00
|
|
|
}
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
|
|
|
|
surface_free_unused_subsurface_views(sub->surface);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
view_list_add_subsurface_view(struct weston_compositor *compositor,
|
|
|
|
struct weston_subsurface *sub,
|
|
|
|
struct weston_view *parent)
|
|
|
|
{
|
|
|
|
struct weston_subsurface *child;
|
|
|
|
struct weston_view *view = NULL, *iv;
|
|
|
|
|
compositor: ignore unmapped sub-surfaces for view_list
It looks like that in the great conversion introducing weston_view, one
conditional was forgotten from the code that builds the global flat list
of views. Sub-surfaces are added to the view list specially, as they are
not governed by their presence in a layer's view list, and therefore
need an explicit check for mappedness.
The bug, missing the explicit check, caused sub-surfaces to enter the
global view_list regardless of their state. This lead to the pointer
focus picking code processing them, and as the input region defaults to
infinite, picking these unmapped surfaces. Clients then get confused
about the wl_pointer.enter events with unexpected wl_surface.
To trigger this issue, it is enough to just create one additional
wl_surface and make it a sub-surface of a main surface that is or gets
mapped. Literally, just a wl_subsomcpositor_get_subsurface() call is
enough. At some point later, the unmapped sub-surface will get pointer
focus, depending on view stacking order.
Fix the issue by adding a is_mapped check when building the view_list.
Note, that 95ec0f95aa2df74c2da19e7dda24528fa8f765cc accidentally also
prevents this bug from happening, because it adds a test against the
transform.masked_boundingbox in weston_compositor_pick_view().
Reported-by: George Kiagiadakis <george.kiagiadakis@collabora.com>
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
2014-07-28 13:49:24 +04:00
|
|
|
if (!weston_surface_is_mapped(sub->surface))
|
|
|
|
return;
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
wl_list_for_each(iv, &sub->unused_views, surface_link) {
|
|
|
|
if (iv->geometry.parent == parent) {
|
|
|
|
view = iv;
|
|
|
|
break;
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
}
|
|
|
|
}
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
|
|
|
|
if (view) {
|
|
|
|
/* Put it back in the surface's list of views */
|
|
|
|
wl_list_remove(&view->surface_link);
|
|
|
|
wl_list_insert(&sub->surface->views, &view->surface_link);
|
|
|
|
} else {
|
|
|
|
view = weston_view_create(sub->surface);
|
2013-12-03 07:01:53 +04:00
|
|
|
weston_view_set_position(view,
|
|
|
|
sub->position.x,
|
|
|
|
sub->position.y);
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_set_transform_parent(view, parent);
|
|
|
|
}
|
|
|
|
|
2014-07-09 23:12:57 +04:00
|
|
|
view->parent_view = parent;
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_update_transform(view);
|
2016-06-30 07:04:28 +03:00
|
|
|
view->is_mapped = true;
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
|
compositor: fix sub-surface view stacking order
If you opened a window with sub-surfaces, and then raised another window
on top of that, the underlaying window's main surface was stacked
properly, but the sub-surfaces remained on top of the raised window.
IOW, the raised window was in between the other window and its
sub-surfaces.
This got broken in a7af70436b7dccfacd736626d6719b3e751fd985, "Split the
geometry information from weston_surface out into weston_view".
Fix the issues:
In view_list_add_subsurface_view(), the views need to be added to the
end of the list, not to the head. This alone fixes the above problem,
but causes the sub-surface views to be stacked irrespective of their
surface stacking order. The stacking order in this test case is fixed by
the changes to view_list_add(), but for sub-sub-surfaces a similar
change is needed in view_list_add_subsurface_view() too.
In view_list_add(), build the view list in the sub-surface stacking
order, instead of pulling the parent surface always on top. Also handle
the case, when the subsurface_list is completely empty: the parent
surface's view must still be added.
Reported-by: Julien Isorce <julien.isorce@collabora.com>
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Cc: Jason Ekstrand <jason@jlekstrand.net>
2013-11-19 16:03:35 +04:00
|
|
|
if (wl_list_empty(&sub->surface->subsurface_list)) {
|
|
|
|
wl_list_insert(compositor->view_list.prev, &view->link);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
wl_list_for_each(child, &sub->surface->subsurface_list, parent_link) {
|
|
|
|
if (child->surface == sub->surface)
|
|
|
|
wl_list_insert(compositor->view_list.prev, &view->link);
|
|
|
|
else
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
view_list_add_subsurface_view(compositor, child, view);
|
compositor: fix sub-surface view stacking order
If you opened a window with sub-surfaces, and then raised another window
on top of that, the underlaying window's main surface was stacked
properly, but the sub-surfaces remained on top of the raised window.
IOW, the raised window was in between the other window and its
sub-surfaces.
This got broken in a7af70436b7dccfacd736626d6719b3e751fd985, "Split the
geometry information from weston_surface out into weston_view".
Fix the issues:
In view_list_add_subsurface_view(), the views need to be added to the
end of the list, not to the head. This alone fixes the above problem,
but causes the sub-surface views to be stacked irrespective of their
surface stacking order. The stacking order in this test case is fixed by
the changes to view_list_add(), but for sub-sub-surfaces a similar
change is needed in view_list_add_subsurface_view() too.
In view_list_add(), build the view list in the sub-surface stacking
order, instead of pulling the parent surface always on top. Also handle
the case, when the subsurface_list is completely empty: the parent
surface's view must still be added.
Reported-by: Julien Isorce <julien.isorce@collabora.com>
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Cc: Jason Ekstrand <jason@jlekstrand.net>
2013-11-19 16:03:35 +04:00
|
|
|
}
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
view_list_add(struct weston_compositor *compositor,
|
|
|
|
struct weston_view *view)
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
{
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
struct weston_subsurface *sub;
|
|
|
|
|
|
|
|
weston_view_update_transform(view);
|
|
|
|
|
compositor: fix sub-surface view stacking order
If you opened a window with sub-surfaces, and then raised another window
on top of that, the underlaying window's main surface was stacked
properly, but the sub-surfaces remained on top of the raised window.
IOW, the raised window was in between the other window and its
sub-surfaces.
This got broken in a7af70436b7dccfacd736626d6719b3e751fd985, "Split the
geometry information from weston_surface out into weston_view".
Fix the issues:
In view_list_add_subsurface_view(), the views need to be added to the
end of the list, not to the head. This alone fixes the above problem,
but causes the sub-surface views to be stacked irrespective of their
surface stacking order. The stacking order in this test case is fixed by
the changes to view_list_add(), but for sub-sub-surfaces a similar
change is needed in view_list_add_subsurface_view() too.
In view_list_add(), build the view list in the sub-surface stacking
order, instead of pulling the parent surface always on top. Also handle
the case, when the subsurface_list is completely empty: the parent
surface's view must still be added.
Reported-by: Julien Isorce <julien.isorce@collabora.com>
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Cc: Jason Ekstrand <jason@jlekstrand.net>
2013-11-19 16:03:35 +04:00
|
|
|
if (wl_list_empty(&view->surface->subsurface_list)) {
|
|
|
|
wl_list_insert(compositor->view_list.prev, &view->link);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
wl_list_for_each(sub, &view->surface->subsurface_list, parent_link) {
|
|
|
|
if (sub->surface == view->surface)
|
|
|
|
wl_list_insert(compositor->view_list.prev, &view->link);
|
|
|
|
else
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
view_list_add_subsurface_view(compositor, sub, view);
|
compositor: fix sub-surface view stacking order
If you opened a window with sub-surfaces, and then raised another window
on top of that, the underlaying window's main surface was stacked
properly, but the sub-surfaces remained on top of the raised window.
IOW, the raised window was in between the other window and its
sub-surfaces.
This got broken in a7af70436b7dccfacd736626d6719b3e751fd985, "Split the
geometry information from weston_surface out into weston_view".
Fix the issues:
In view_list_add_subsurface_view(), the views need to be added to the
end of the list, not to the head. This alone fixes the above problem,
but causes the sub-surface views to be stacked irrespective of their
surface stacking order. The stacking order in this test case is fixed by
the changes to view_list_add(), but for sub-sub-surfaces a similar
change is needed in view_list_add_subsurface_view() too.
In view_list_add(), build the view list in the sub-surface stacking
order, instead of pulling the parent surface always on top. Also handle
the case, when the subsurface_list is completely empty: the parent
surface's view must still be added.
Reported-by: Julien Isorce <julien.isorce@collabora.com>
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Cc: Jason Ekstrand <jason@jlekstrand.net>
2013-11-19 16:03:35 +04:00
|
|
|
}
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
weston_compositor_build_view_list(struct weston_compositor *compositor)
|
|
|
|
{
|
|
|
|
struct weston_view *view;
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
struct weston_layer *layer;
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
wl_list_for_each(layer, &compositor->layer_list, link)
|
2014-07-09 23:12:56 +04:00
|
|
|
wl_list_for_each(view, &layer->view_list.link, layer_link.link)
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
surface_stash_subsurface_views(view->surface);
|
|
|
|
|
|
|
|
wl_list_init(&compositor->view_list);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
wl_list_for_each(layer, &compositor->layer_list, link) {
|
2014-07-09 23:12:56 +04:00
|
|
|
wl_list_for_each(view, &layer->view_list.link, layer_link.link) {
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
view_list_add(compositor, view);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
}
|
|
|
|
}
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
|
|
|
|
wl_list_for_each(layer, &compositor->layer_list, link)
|
2014-07-09 23:12:56 +04:00
|
|
|
wl_list_for_each(view, &layer->view_list.link, layer_link.link)
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
surface_free_unused_subsurface_views(view->surface);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
}
|
|
|
|
|
2014-12-17 17:20:41 +03:00
|
|
|
static void
|
|
|
|
weston_output_take_feedback_list(struct weston_output *output,
|
|
|
|
struct weston_surface *surface)
|
|
|
|
{
|
|
|
|
struct weston_view *view;
|
|
|
|
struct weston_presentation_feedback *feedback;
|
|
|
|
uint32_t flags = 0xffffffff;
|
|
|
|
|
|
|
|
if (wl_list_empty(&surface->feedback_list))
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* All views must have the flag for the flag to survive. */
|
|
|
|
wl_list_for_each(view, &surface->views, surface_link) {
|
|
|
|
/* ignore views that are not on this output at all */
|
|
|
|
if (view->output_mask & (1u << output->id))
|
|
|
|
flags &= view->psf_flags;
|
|
|
|
}
|
|
|
|
|
|
|
|
wl_list_for_each(feedback, &surface->feedback_list, link)
|
|
|
|
feedback->psf_flags = flags;
|
|
|
|
|
|
|
|
wl_list_insert_list(&output->feedback_list, &surface->feedback_list);
|
|
|
|
wl_list_init(&surface->feedback_list);
|
|
|
|
}
|
|
|
|
|
2013-10-22 19:11:26 +04:00
|
|
|
static int
|
2014-09-24 06:08:45 +04:00
|
|
|
weston_output_repaint(struct weston_output *output)
|
2008-10-12 05:21:39 +04:00
|
|
|
{
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
struct weston_compositor *ec = output->compositor;
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
struct weston_view *ev;
|
2012-01-26 17:40:37 +04:00
|
|
|
struct weston_animation *animation, *next;
|
|
|
|
struct weston_frame_callback *cb, *cnext;
|
2012-06-13 02:01:21 +04:00
|
|
|
struct wl_list frame_callback_list;
|
2013-03-05 19:30:27 +04:00
|
|
|
pixman_region32_t output_damage;
|
2013-10-22 19:11:26 +04:00
|
|
|
int r;
|
2008-11-29 01:06:06 +03:00
|
|
|
|
2013-12-14 00:10:55 +04:00
|
|
|
if (output->destroying)
|
|
|
|
return 0;
|
|
|
|
|
compositor: Implement JSON-timeline logging
Logging is activated and deactivated with the debug key binding 't'.
When activated, it creates a new log file, where it records the events.
The log file contains events and detailed object information entries in
JSON format, and is meant to be parsed in sequence from beginning to the
end.
The emitted events are mostly related to the output repaint cycle, like
when repaint begins, is submitted to GPU, and when it completes on a
vblank. This is recorded per-output. Also some per-surface events are
recorded, including when surface damage is flushed.
To reduce the log size, events refer to objects like outputs and
surfaces by id numbers. Detailed object information is emitted only as
needed: on the first object occurrence, and afterwards only if
weston_timeline_object::force_refresh asks for it.
The detailed information for surfaces includes the string returned by
weston_surface::get_label. Therefore it is important to set
weston_timeline_object::force_refresh = 1 whenever the string would
change, so that the new details get recorded.
A rudimentary parser and SVG generator can be found at:
https://github.com/ppaalanen/wesgr
The timeline logs can answer questions including:
- How does the compositor repaint cycle work timing-wise?
- When was the vblank deadline missed?
- What is the latency from surface commit to showing the new content on
screen?
- How long does it take to process the scenegraph?
v2: weston_surface::get_description renamed to get_label.
v3: reafctor a bit into fprint_quoted_string().
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2014-11-12 16:09:24 +03:00
|
|
|
TL_POINT("core_repaint_begin", TLP_OUTPUT(output), TLP_END);
|
|
|
|
|
2012-02-29 21:42:35 +04:00
|
|
|
/* Rebuild the surface list and update surface transforms up front. */
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_compositor_build_view_list(ec);
|
2012-01-27 16:38:33 +04:00
|
|
|
|
2014-12-17 17:20:41 +03:00
|
|
|
if (output->assign_planes && !output->disable_planes) {
|
2012-02-10 01:12:57 +04:00
|
|
|
output->assign_planes(output);
|
2014-12-17 17:20:41 +03:00
|
|
|
} else {
|
|
|
|
wl_list_for_each(ev, &ec->view_list, link) {
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_move_to_plane(ev, &ec->primary_plane);
|
2014-12-17 17:20:41 +03:00
|
|
|
ev->psf_flags = 0;
|
|
|
|
}
|
|
|
|
}
|
2012-08-03 23:45:23 +04:00
|
|
|
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
wl_list_init(&frame_callback_list);
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
wl_list_for_each(ev, &ec->view_list, link) {
|
|
|
|
/* Note: This operation is safe to do multiple times on the
|
|
|
|
* same surface.
|
|
|
|
*/
|
|
|
|
if (ev->surface->output == output) {
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
wl_list_insert_list(&frame_callback_list,
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
&ev->surface->frame_callback_list);
|
|
|
|
wl_list_init(&ev->surface->frame_callback_list);
|
2014-09-24 06:08:46 +04:00
|
|
|
|
2014-12-17 17:20:41 +03:00
|
|
|
weston_output_take_feedback_list(output, ev->surface);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-05 19:30:27 +04:00
|
|
|
compositor_accumulate_damage(ec);
|
compositor: Clear only the the damage that was actually repainted
Instead of clearing the whole output region after a repaint, clear
only the regions that were actually painted. This way, the damage
added when a surface moves from the primary plane to another one is
kept while this region is obscured by the opaque region. This allows
the contents below an overlaid surface to be culled, but to make this
work properly, it is also necessary to change the way previous damage
is drawn.
Consider the following scenario: a surface is moved to an overlay plane
leaving some damage in the primary plane. On the following frame, the
surface on the overlay moves, revealing part of the damaged region on
the primary plane. On the frame after that, the overlaid surface moves
back to its previous position obscuring the region of the primary plane
repainted before. At this point, the repainted region was added to the
output's previous damage so that it is draw to both buffers. But since
this region is now obscured, the redrawing is skipped. If the overlaid
surface moves again revealing this region, one of the buffers actually
contains the wrong content.
To fix this problem, this patch ensures that any previous damage that
would be lost is actually preserved by folding it back into the
primary plane damage just before repainting.
2012-08-15 22:02:05 +04:00
|
|
|
|
2012-02-29 07:31:58 +04:00
|
|
|
pixman_region32_init(&output_damage);
|
|
|
|
pixman_region32_intersect(&output_damage,
|
compositor: Clear only the the damage that was actually repainted
Instead of clearing the whole output region after a repaint, clear
only the regions that were actually painted. This way, the damage
added when a surface moves from the primary plane to another one is
kept while this region is obscured by the opaque region. This allows
the contents below an overlaid surface to be culled, but to make this
work properly, it is also necessary to change the way previous damage
is drawn.
Consider the following scenario: a surface is moved to an overlay plane
leaving some damage in the primary plane. On the following frame, the
surface on the overlay moves, revealing part of the damaged region on
the primary plane. On the frame after that, the overlaid surface moves
back to its previous position obscuring the region of the primary plane
repainted before. At this point, the repainted region was added to the
output's previous damage so that it is draw to both buffers. But since
this region is now obscured, the redrawing is skipped. If the overlaid
surface moves again revealing this region, one of the buffers actually
contains the wrong content.
To fix this problem, this patch ensures that any previous damage that
would be lost is actually preserved by folding it back into the
primary plane damage just before repainting.
2012-08-15 22:02:05 +04:00
|
|
|
&ec->primary_plane.damage, &output->region);
|
2013-03-05 19:30:29 +04:00
|
|
|
pixman_region32_subtract(&output_damage,
|
|
|
|
&output_damage, &ec->primary_plane.clip);
|
2011-06-24 05:11:19 +04:00
|
|
|
|
2012-02-23 01:21:41 +04:00
|
|
|
if (output->dirty)
|
|
|
|
weston_output_update_matrix(output);
|
|
|
|
|
2013-10-22 19:11:26 +04:00
|
|
|
r = output->repaint(output, &output_damage);
|
2008-10-12 05:21:39 +04:00
|
|
|
|
2012-02-29 07:31:58 +04:00
|
|
|
pixman_region32_fini(&output_damage);
|
2009-01-01 00:18:42 +03:00
|
|
|
|
2011-06-21 23:02:12 +04:00
|
|
|
output->repaint_needed = 0;
|
2011-03-14 14:07:26 +03:00
|
|
|
|
2012-03-12 00:35:16 +04:00
|
|
|
weston_compositor_repick(ec);
|
|
|
|
|
2012-06-13 02:01:21 +04:00
|
|
|
wl_list_for_each_safe(cb, cnext, &frame_callback_list, link) {
|
2014-09-24 06:08:45 +04:00
|
|
|
wl_callback_send_done(cb->resource, output->frame_time);
|
2013-06-14 19:07:57 +04:00
|
|
|
wl_resource_destroy(cb->resource);
|
2011-03-14 14:07:26 +03:00
|
|
|
}
|
2010-06-11 20:56:24 +04:00
|
|
|
|
2012-06-09 05:40:54 +04:00
|
|
|
wl_list_for_each_safe(animation, next, &output->animation_list, link) {
|
|
|
|
animation->frame_counter++;
|
2014-09-24 06:08:45 +04:00
|
|
|
animation->frame(animation, output, output->frame_time);
|
2012-06-09 05:40:54 +04:00
|
|
|
}
|
2013-10-22 19:11:26 +04:00
|
|
|
|
compositor: Implement JSON-timeline logging
Logging is activated and deactivated with the debug key binding 't'.
When activated, it creates a new log file, where it records the events.
The log file contains events and detailed object information entries in
JSON format, and is meant to be parsed in sequence from beginning to the
end.
The emitted events are mostly related to the output repaint cycle, like
when repaint begins, is submitted to GPU, and when it completes on a
vblank. This is recorded per-output. Also some per-surface events are
recorded, including when surface damage is flushed.
To reduce the log size, events refer to objects like outputs and
surfaces by id numbers. Detailed object information is emitted only as
needed: on the first object occurrence, and afterwards only if
weston_timeline_object::force_refresh asks for it.
The detailed information for surfaces includes the string returned by
weston_surface::get_label. Therefore it is important to set
weston_timeline_object::force_refresh = 1 whenever the string would
change, so that the new details get recorded.
A rudimentary parser and SVG generator can be found at:
https://github.com/ppaalanen/wesgr
The timeline logs can answer questions including:
- How does the compositor repaint cycle work timing-wise?
- When was the vblank deadline missed?
- What is the latency from surface commit to showing the new content on
screen?
- How long does it take to process the scenegraph?
v2: weston_surface::get_description renamed to get_label.
v3: reafctor a bit into fprint_quoted_string().
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2014-11-12 16:09:24 +03:00
|
|
|
TL_POINT("core_repaint_posted", TLP_OUTPUT(output), TLP_END);
|
|
|
|
|
2013-10-22 19:11:26 +04:00
|
|
|
return r;
|
2011-06-21 23:02:12 +04:00
|
|
|
}
|
2011-04-22 20:27:57 +04:00
|
|
|
|
2014-05-21 14:51:49 +04:00
|
|
|
static void
|
|
|
|
weston_output_schedule_repaint_reset(struct weston_output *output)
|
|
|
|
{
|
|
|
|
output->repaint_scheduled = 0;
|
|
|
|
TL_POINT("core_repaint_exit_loop", TLP_OUTPUT(output), TLP_END);
|
|
|
|
}
|
|
|
|
|
2014-05-21 17:17:27 +04:00
|
|
|
static int
|
|
|
|
output_repaint_timer_handler(void *data)
|
|
|
|
{
|
|
|
|
struct weston_output *output = data;
|
|
|
|
struct weston_compositor *compositor = output->compositor;
|
|
|
|
|
|
|
|
if (output->repaint_needed &&
|
2016-08-30 22:05:16 +03:00
|
|
|
compositor->state != WESTON_COMPOSITOR_SLEEPING &&
|
2014-05-21 17:17:27 +04:00
|
|
|
compositor->state != WESTON_COMPOSITOR_OFFSCREEN &&
|
|
|
|
weston_output_repaint(output) == 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
weston_output_schedule_repaint_reset(output);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-06-21 23:02:12 +04:00
|
|
|
WL_EXPORT void
|
2014-09-24 06:08:45 +04:00
|
|
|
weston_output_finish_frame(struct weston_output *output,
|
compositor: set presentation.presented flags
Change weston_output_finish_frame() signature so that backends are
required to set the flags, that will be reported on the Presentation
'presented' event. This is meant for output-wide feedback flags. Flags
that vary per wl_surface are subject for the following patch.
All start_repaint_loop functions use the special private flag
PRESENTATION_FEEDBACK_INVALID to mark, that this call of
weston_output_finish_frame() cannot trigger the 'presented' event. If it
does, we now hit an assert, and should then investigate why a fake update
triggered Presentation feedback.
DRM:
Page flip is always vsync'd, and always gets the completion timestamp
from the kernel which should correspond well to hardware. Completion is
triggered by the kernel/hardware.
Vblank handler is only used with the broken planes path, therefore do
not report VSYNC, because we cannot guarantee all the planes updated at
the same time. We cannot set the INVALID, because it would abort the
compositor if the broken planes path was ever used. This is a hack that
will get fixed with nuclear pageflip support in the future.
fbdev:
No vsync, update done by copy, no completion event from hardware, and
completion time is totally fake.
headless:
No real output to update.
RDP:
Guessing that maybe no vsync, fake time, and copy make sense (pixels
sent over network). Also no event that the pixels have been shown?
RPI:
Presumably Dispmanx updates are vsync'd. We get a completion event from
the driver, but need to read the clock ourselves, so the completion time
is somewhat unreliable. Zero-copy flag not implemented though it would
be theoretically possible with EGL clients (zero-copy is a per-surface
flag anyway, so in this patch).
Wayland:
No information how the host compositor is doing updates, so make a safe
guess without assuming vsync or hardware completion event. While we do
get some timestamp from the host compositor, it is not the completion
time. Would need to hook to the Presentation extension of the host
compositor to get more accurate flags.
X11:
No idea about vsync, completion event, or copying. Also the timestamp is
a fake.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Reviewed-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Tested-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Acked-by: Mario Kleiner <mario.kleiner.de@gmail.com>
2014-12-17 17:20:40 +03:00
|
|
|
const struct timespec *stamp,
|
|
|
|
uint32_t presented_flags)
|
2011-06-21 23:02:12 +04:00
|
|
|
{
|
2012-03-06 04:50:08 +04:00
|
|
|
struct weston_compositor *compositor = output->compositor;
|
2014-05-21 17:17:27 +04:00
|
|
|
int32_t refresh_nsec;
|
|
|
|
struct timespec now;
|
|
|
|
struct timespec gone;
|
|
|
|
int msec;
|
2014-09-24 06:08:46 +04:00
|
|
|
|
compositor: Implement JSON-timeline logging
Logging is activated and deactivated with the debug key binding 't'.
When activated, it creates a new log file, where it records the events.
The log file contains events and detailed object information entries in
JSON format, and is meant to be parsed in sequence from beginning to the
end.
The emitted events are mostly related to the output repaint cycle, like
when repaint begins, is submitted to GPU, and when it completes on a
vblank. This is recorded per-output. Also some per-surface events are
recorded, including when surface damage is flushed.
To reduce the log size, events refer to objects like outputs and
surfaces by id numbers. Detailed object information is emitted only as
needed: on the first object occurrence, and afterwards only if
weston_timeline_object::force_refresh asks for it.
The detailed information for surfaces includes the string returned by
weston_surface::get_label. Therefore it is important to set
weston_timeline_object::force_refresh = 1 whenever the string would
change, so that the new details get recorded.
A rudimentary parser and SVG generator can be found at:
https://github.com/ppaalanen/wesgr
The timeline logs can answer questions including:
- How does the compositor repaint cycle work timing-wise?
- When was the vblank deadline missed?
- What is the latency from surface commit to showing the new content on
screen?
- How long does it take to process the scenegraph?
v2: weston_surface::get_description renamed to get_label.
v3: reafctor a bit into fprint_quoted_string().
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2014-11-12 16:09:24 +03:00
|
|
|
TL_POINT("core_repaint_finished", TLP_OUTPUT(output),
|
|
|
|
TLP_VBLANK(stamp), TLP_END);
|
|
|
|
|
2015-07-03 15:08:53 +03:00
|
|
|
refresh_nsec = millihz_to_nsec(output->current_mode->refresh);
|
2014-09-24 06:08:46 +04:00
|
|
|
weston_presentation_feedback_present_list(&output->feedback_list,
|
|
|
|
output, refresh_nsec, stamp,
|
compositor: set presentation.presented flags
Change weston_output_finish_frame() signature so that backends are
required to set the flags, that will be reported on the Presentation
'presented' event. This is meant for output-wide feedback flags. Flags
that vary per wl_surface are subject for the following patch.
All start_repaint_loop functions use the special private flag
PRESENTATION_FEEDBACK_INVALID to mark, that this call of
weston_output_finish_frame() cannot trigger the 'presented' event. If it
does, we now hit an assert, and should then investigate why a fake update
triggered Presentation feedback.
DRM:
Page flip is always vsync'd, and always gets the completion timestamp
from the kernel which should correspond well to hardware. Completion is
triggered by the kernel/hardware.
Vblank handler is only used with the broken planes path, therefore do
not report VSYNC, because we cannot guarantee all the planes updated at
the same time. We cannot set the INVALID, because it would abort the
compositor if the broken planes path was ever used. This is a hack that
will get fixed with nuclear pageflip support in the future.
fbdev:
No vsync, update done by copy, no completion event from hardware, and
completion time is totally fake.
headless:
No real output to update.
RDP:
Guessing that maybe no vsync, fake time, and copy make sense (pixels
sent over network). Also no event that the pixels have been shown?
RPI:
Presumably Dispmanx updates are vsync'd. We get a completion event from
the driver, but need to read the clock ourselves, so the completion time
is somewhat unreliable. Zero-copy flag not implemented though it would
be theoretically possible with EGL clients (zero-copy is a per-surface
flag anyway, so in this patch).
Wayland:
No information how the host compositor is doing updates, so make a safe
guess without assuming vsync or hardware completion event. While we do
get some timestamp from the host compositor, it is not the completion
time. Would need to hook to the Presentation extension of the host
compositor to get more accurate flags.
X11:
No idea about vsync, completion event, or copying. Also the timestamp is
a fake.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Reviewed-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Tested-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Acked-by: Mario Kleiner <mario.kleiner.de@gmail.com>
2014-12-17 17:20:40 +03:00
|
|
|
output->msc,
|
|
|
|
presented_flags);
|
2012-03-06 04:50:08 +04:00
|
|
|
|
2014-09-24 06:08:45 +04:00
|
|
|
output->frame_time = stamp->tv_sec * 1000 + stamp->tv_nsec / 1000000;
|
2013-10-16 22:10:12 +04:00
|
|
|
|
2014-05-21 17:17:27 +04:00
|
|
|
weston_compositor_read_presentation_clock(compositor, &now);
|
|
|
|
timespec_sub(&gone, &now, stamp);
|
|
|
|
msec = (refresh_nsec - timespec_to_nsec(&gone)) / 1000000; /* floor */
|
|
|
|
msec -= compositor->repaint_msec;
|
2012-03-06 04:50:08 +04:00
|
|
|
|
2015-03-19 13:27:29 +03:00
|
|
|
if (msec < -1000 || msec > 1000) {
|
|
|
|
static bool warned;
|
|
|
|
|
|
|
|
if (!warned)
|
|
|
|
weston_log("Warning: computed repaint delay is "
|
|
|
|
"insane: %d msec\n", msec);
|
|
|
|
warned = true;
|
|
|
|
|
|
|
|
msec = 0;
|
|
|
|
}
|
|
|
|
|
2015-06-21 22:25:15 +03:00
|
|
|
/* Called from restart_repaint_loop and restart happens already after
|
|
|
|
* the deadline given by repaint_msec? In that case we delay until
|
|
|
|
* the deadline of the next frame, to give clients a more predictable
|
|
|
|
* timing of the repaint cycle to lock on. */
|
2016-02-18 17:53:27 +03:00
|
|
|
if (presented_flags == WP_PRESENTATION_FEEDBACK_INVALID && msec < 0)
|
2015-06-21 22:25:15 +03:00
|
|
|
msec += refresh_nsec / 1000000;
|
|
|
|
|
2015-03-19 13:27:29 +03:00
|
|
|
if (msec < 1)
|
2014-05-21 17:17:27 +04:00
|
|
|
output_repaint_timer_handler(output);
|
|
|
|
else
|
|
|
|
wl_event_source_timer_update(output->repaint_timer, msec);
|
2012-03-06 04:50:08 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
idle_repaint(void *data)
|
|
|
|
{
|
|
|
|
struct weston_output *output = data;
|
|
|
|
|
2013-04-06 01:07:11 +04:00
|
|
|
output->start_repaint_loop(output);
|
2008-10-12 05:21:39 +04:00
|
|
|
}
|
|
|
|
|
2014-07-09 23:12:56 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_layer_entry_insert(struct weston_layer_entry *list,
|
|
|
|
struct weston_layer_entry *entry)
|
|
|
|
{
|
|
|
|
wl_list_insert(&list->link, &entry->link);
|
|
|
|
entry->layer = list->layer;
|
|
|
|
}
|
|
|
|
|
|
|
|
WL_EXPORT void
|
|
|
|
weston_layer_entry_remove(struct weston_layer_entry *entry)
|
|
|
|
{
|
|
|
|
wl_list_remove(&entry->link);
|
|
|
|
wl_list_init(&entry->link);
|
|
|
|
entry->layer = NULL;
|
|
|
|
}
|
|
|
|
|
2012-02-29 21:42:35 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_layer_init(struct weston_layer *layer, struct wl_list *below)
|
|
|
|
{
|
2014-07-09 23:12:56 +04:00
|
|
|
wl_list_init(&layer->view_list.link);
|
|
|
|
layer->view_list.layer = layer;
|
2014-07-09 23:12:57 +04:00
|
|
|
weston_layer_set_mask_infinite(layer);
|
2012-06-13 02:01:22 +04:00
|
|
|
if (below != NULL)
|
|
|
|
wl_list_insert(below, &layer->link);
|
2012-02-29 21:42:35 +04:00
|
|
|
}
|
|
|
|
|
2014-07-09 23:12:57 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_layer_set_mask(struct weston_layer *layer,
|
|
|
|
int x, int y, int width, int height)
|
|
|
|
{
|
|
|
|
struct weston_view *view;
|
|
|
|
|
|
|
|
layer->mask.x1 = x;
|
|
|
|
layer->mask.x2 = x + width;
|
|
|
|
layer->mask.y1 = y;
|
|
|
|
layer->mask.y2 = y + height;
|
|
|
|
|
|
|
|
wl_list_for_each(view, &layer->view_list.link, layer_link.link) {
|
|
|
|
weston_view_geometry_dirty(view);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
WL_EXPORT void
|
|
|
|
weston_layer_set_mask_infinite(struct weston_layer *layer)
|
|
|
|
{
|
|
|
|
weston_layer_set_mask(layer, INT32_MIN, INT32_MIN,
|
|
|
|
UINT32_MAX, UINT32_MAX);
|
|
|
|
}
|
|
|
|
|
2011-04-23 21:04:11 +04:00
|
|
|
WL_EXPORT void
|
2012-06-20 08:35:59 +04:00
|
|
|
weston_output_schedule_repaint(struct weston_output *output)
|
2008-10-12 05:21:39 +04:00
|
|
|
{
|
2012-06-20 08:35:59 +04:00
|
|
|
struct weston_compositor *compositor = output->compositor;
|
2011-06-21 23:02:12 +04:00
|
|
|
struct wl_event_loop *loop;
|
2011-03-14 14:07:26 +03:00
|
|
|
|
2016-08-30 22:05:16 +03:00
|
|
|
if (compositor->state == WESTON_COMPOSITOR_SLEEPING ||
|
|
|
|
compositor->state == WESTON_COMPOSITOR_OFFSCREEN)
|
2011-04-22 22:01:18 +04:00
|
|
|
return;
|
|
|
|
|
compositor: Implement JSON-timeline logging
Logging is activated and deactivated with the debug key binding 't'.
When activated, it creates a new log file, where it records the events.
The log file contains events and detailed object information entries in
JSON format, and is meant to be parsed in sequence from beginning to the
end.
The emitted events are mostly related to the output repaint cycle, like
when repaint begins, is submitted to GPU, and when it completes on a
vblank. This is recorded per-output. Also some per-surface events are
recorded, including when surface damage is flushed.
To reduce the log size, events refer to objects like outputs and
surfaces by id numbers. Detailed object information is emitted only as
needed: on the first object occurrence, and afterwards only if
weston_timeline_object::force_refresh asks for it.
The detailed information for surfaces includes the string returned by
weston_surface::get_label. Therefore it is important to set
weston_timeline_object::force_refresh = 1 whenever the string would
change, so that the new details get recorded.
A rudimentary parser and SVG generator can be found at:
https://github.com/ppaalanen/wesgr
The timeline logs can answer questions including:
- How does the compositor repaint cycle work timing-wise?
- When was the vblank deadline missed?
- What is the latency from surface commit to showing the new content on
screen?
- How long does it take to process the scenegraph?
v2: weston_surface::get_description renamed to get_label.
v3: reafctor a bit into fprint_quoted_string().
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2014-11-12 16:09:24 +03:00
|
|
|
if (!output->repaint_needed)
|
|
|
|
TL_POINT("core_repaint_req", TLP_OUTPUT(output), TLP_END);
|
|
|
|
|
2011-06-21 23:02:12 +04:00
|
|
|
loop = wl_display_get_event_loop(compositor->wl_display);
|
2012-06-20 08:35:59 +04:00
|
|
|
output->repaint_needed = 1;
|
|
|
|
if (output->repaint_scheduled)
|
|
|
|
return;
|
2011-03-14 14:07:26 +03:00
|
|
|
|
2012-06-20 08:35:59 +04:00
|
|
|
wl_event_loop_add_idle(loop, idle_repaint, output);
|
|
|
|
output->repaint_scheduled = 1;
|
compositor: Implement JSON-timeline logging
Logging is activated and deactivated with the debug key binding 't'.
When activated, it creates a new log file, where it records the events.
The log file contains events and detailed object information entries in
JSON format, and is meant to be parsed in sequence from beginning to the
end.
The emitted events are mostly related to the output repaint cycle, like
when repaint begins, is submitted to GPU, and when it completes on a
vblank. This is recorded per-output. Also some per-surface events are
recorded, including when surface damage is flushed.
To reduce the log size, events refer to objects like outputs and
surfaces by id numbers. Detailed object information is emitted only as
needed: on the first object occurrence, and afterwards only if
weston_timeline_object::force_refresh asks for it.
The detailed information for surfaces includes the string returned by
weston_surface::get_label. Therefore it is important to set
weston_timeline_object::force_refresh = 1 whenever the string would
change, so that the new details get recorded.
A rudimentary parser and SVG generator can be found at:
https://github.com/ppaalanen/wesgr
The timeline logs can answer questions including:
- How does the compositor repaint cycle work timing-wise?
- When was the vblank deadline missed?
- What is the latency from surface commit to showing the new content on
screen?
- How long does it take to process the scenegraph?
v2: weston_surface::get_description renamed to get_label.
v3: reafctor a bit into fprint_quoted_string().
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2014-11-12 16:09:24 +03:00
|
|
|
TL_POINT("core_repaint_enter_loop", TLP_OUTPUT(output), TLP_END);
|
2008-10-12 05:21:39 +04:00
|
|
|
}
|
2009-02-09 23:17:46 +03:00
|
|
|
|
2012-06-20 08:35:59 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_compositor_schedule_repaint(struct weston_compositor *compositor)
|
|
|
|
{
|
|
|
|
struct weston_output *output;
|
|
|
|
|
|
|
|
wl_list_for_each(output, &compositor->output_list, link)
|
|
|
|
weston_output_schedule_repaint(output);
|
|
|
|
}
|
|
|
|
|
2008-11-06 18:38:17 +03:00
|
|
|
static void
|
2011-08-19 01:55:30 +04:00
|
|
|
surface_destroy(struct wl_client *client, struct wl_resource *resource)
|
2008-10-09 06:51:32 +04:00
|
|
|
{
|
2012-04-12 06:42:15 +04:00
|
|
|
wl_resource_destroy(resource);
|
2008-10-09 06:51:32 +04:00
|
|
|
}
|
|
|
|
|
2012-03-27 18:36:40 +04:00
|
|
|
static void
|
|
|
|
surface_attach(struct wl_client *client,
|
|
|
|
struct wl_resource *resource,
|
|
|
|
struct wl_resource *buffer_resource, int32_t sx, int32_t sy)
|
|
|
|
{
|
2013-06-14 19:07:53 +04:00
|
|
|
struct weston_surface *surface = wl_resource_get_user_data(resource);
|
2013-06-21 05:38:23 +04:00
|
|
|
struct weston_buffer *buffer = NULL;
|
2012-03-27 18:36:40 +04:00
|
|
|
|
2013-08-20 22:30:54 +04:00
|
|
|
if (buffer_resource) {
|
2013-06-21 05:38:23 +04:00
|
|
|
buffer = weston_buffer_from_resource(buffer_resource);
|
2013-08-20 22:30:54 +04:00
|
|
|
if (buffer == NULL) {
|
|
|
|
wl_client_post_no_memory(client);
|
|
|
|
return;
|
|
|
|
}
|
2013-08-15 23:26:42 +04:00
|
|
|
}
|
2011-06-24 05:43:50 +04:00
|
|
|
|
compositor: introduce weston_buffer_reference
The wl_buffer reference counting API has been inconsistent. You would
manually increment the refcount and register a destroy listener, as
opposed to calling weston_buffer_post_release(), which internally
decremented the refcount, and then removing a list item.
Replace both cases with a single function:
weston_buffer_reference(weston_buffer_reference *ref, wl_buffer *buffer)
Buffer is assigned to ref->buffer, while taking care of all the refcounting
and release posting. You take a reference by passing a non-NULL buffer, and
release a reference by passing NULL as buffer. The function uses an
internal wl_buffer destroy listener, so the pointer gets reset on
destruction automatically.
This is inspired by the pipe_resource_reference() of Mesa, and modified
by krh's suggestion to add struct weston_buffer_reference.
Additionally, when a surface gets destroyed, the associated wl_buffer
will send a release event. Often the buffer is already destroyed on
client side, so the event will be discarded by libwayland-client.
Compositor-drm.c is converted to use weston_buffer_reference.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2012-12-04 17:58:12 +04:00
|
|
|
/* Attach, attach, without commit in between does not send
|
|
|
|
* wl_buffer.release. */
|
2014-05-20 23:33:03 +04:00
|
|
|
weston_surface_state_set_buffer(&surface->pending, buffer);
|
2012-03-27 18:36:40 +04:00
|
|
|
|
2012-10-10 13:49:23 +04:00
|
|
|
surface->pending.sx = sx;
|
|
|
|
surface->pending.sy = sy;
|
2013-02-21 14:29:21 +04:00
|
|
|
surface->pending.newly_attached = 1;
|
2008-10-09 06:51:32 +04:00
|
|
|
}
|
|
|
|
|
2012-04-11 17:19:37 +04:00
|
|
|
static void
|
|
|
|
surface_damage(struct wl_client *client,
|
|
|
|
struct wl_resource *resource,
|
|
|
|
int32_t x, int32_t y, int32_t width, int32_t height)
|
|
|
|
{
|
2013-06-14 19:07:53 +04:00
|
|
|
struct weston_surface *surface = wl_resource_get_user_data(resource);
|
2012-04-11 17:19:37 +04:00
|
|
|
|
2015-11-17 23:11:35 +03:00
|
|
|
if (width <= 0 || height <= 0)
|
|
|
|
return;
|
|
|
|
|
2015-11-26 23:17:48 +03:00
|
|
|
pixman_region32_union_rect(&surface->pending.damage_surface,
|
|
|
|
&surface->pending.damage_surface,
|
|
|
|
x, y, width, height);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
surface_damage_buffer(struct wl_client *client,
|
|
|
|
struct wl_resource *resource,
|
|
|
|
int32_t x, int32_t y, int32_t width, int32_t height)
|
|
|
|
{
|
|
|
|
struct weston_surface *surface = wl_resource_get_user_data(resource);
|
|
|
|
|
|
|
|
if (width <= 0 || height <= 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
pixman_region32_union_rect(&surface->pending.damage_buffer,
|
|
|
|
&surface->pending.damage_buffer,
|
2012-06-18 23:09:11 +04:00
|
|
|
x, y, width, height);
|
2008-11-29 01:06:06 +03:00
|
|
|
}
|
|
|
|
|
2011-08-17 07:01:28 +04:00
|
|
|
static void
|
2011-08-19 01:55:30 +04:00
|
|
|
destroy_frame_callback(struct wl_resource *resource)
|
2011-08-17 07:01:28 +04:00
|
|
|
{
|
2013-06-14 19:07:57 +04:00
|
|
|
struct weston_frame_callback *cb = wl_resource_get_user_data(resource);
|
2011-08-19 01:55:30 +04:00
|
|
|
|
|
|
|
wl_list_remove(&cb->link);
|
2011-11-15 13:45:42 +04:00
|
|
|
free(cb);
|
2011-08-17 07:01:28 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
surface_frame(struct wl_client *client,
|
2011-08-19 01:55:30 +04:00
|
|
|
struct wl_resource *resource, uint32_t callback)
|
2011-08-17 07:01:28 +04:00
|
|
|
{
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
struct weston_frame_callback *cb;
|
2013-06-14 19:07:53 +04:00
|
|
|
struct weston_surface *surface = wl_resource_get_user_data(resource);
|
2011-08-17 07:01:28 +04:00
|
|
|
|
|
|
|
cb = malloc(sizeof *cb);
|
|
|
|
if (cb == NULL) {
|
2011-09-01 17:54:57 +04:00
|
|
|
wl_resource_post_no_memory(resource);
|
2011-08-17 07:01:28 +04:00
|
|
|
return;
|
|
|
|
}
|
2012-10-10 13:49:31 +04:00
|
|
|
|
2013-08-07 03:46:25 +04:00
|
|
|
cb->resource = wl_resource_create(client, &wl_callback_interface, 1,
|
|
|
|
callback);
|
|
|
|
if (cb->resource == NULL) {
|
|
|
|
free(cb);
|
|
|
|
wl_resource_post_no_memory(resource);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-06-28 05:17:02 +04:00
|
|
|
wl_resource_set_implementation(cb->resource, NULL, cb,
|
|
|
|
destroy_frame_callback);
|
2011-08-17 07:01:28 +04:00
|
|
|
|
2012-10-10 13:49:31 +04:00
|
|
|
wl_list_insert(surface->pending.frame_callback_list.prev, &cb->link);
|
2011-08-17 07:01:28 +04:00
|
|
|
}
|
|
|
|
|
2012-02-24 01:11:59 +04:00
|
|
|
static void
|
|
|
|
surface_set_opaque_region(struct wl_client *client,
|
|
|
|
struct wl_resource *resource,
|
|
|
|
struct wl_resource *region_resource)
|
|
|
|
{
|
2013-06-14 19:07:53 +04:00
|
|
|
struct weston_surface *surface = wl_resource_get_user_data(resource);
|
2012-02-24 01:11:59 +04:00
|
|
|
struct weston_region *region;
|
|
|
|
|
|
|
|
if (region_resource) {
|
2013-06-14 19:07:56 +04:00
|
|
|
region = wl_resource_get_user_data(region_resource);
|
2012-10-10 13:49:27 +04:00
|
|
|
pixman_region32_copy(&surface->pending.opaque,
|
|
|
|
®ion->region);
|
2012-02-24 01:11:59 +04:00
|
|
|
} else {
|
2014-06-26 21:37:36 +04:00
|
|
|
pixman_region32_clear(&surface->pending.opaque);
|
2012-02-24 01:11:59 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
surface_set_input_region(struct wl_client *client,
|
|
|
|
struct wl_resource *resource,
|
|
|
|
struct wl_resource *region_resource)
|
|
|
|
{
|
2013-06-14 19:07:53 +04:00
|
|
|
struct weston_surface *surface = wl_resource_get_user_data(resource);
|
2012-02-24 02:30:45 +04:00
|
|
|
struct weston_region *region;
|
2012-02-24 01:11:59 +04:00
|
|
|
|
|
|
|
if (region_resource) {
|
2013-06-14 19:07:56 +04:00
|
|
|
region = wl_resource_get_user_data(region_resource);
|
2012-10-10 13:49:28 +04:00
|
|
|
pixman_region32_copy(&surface->pending.input,
|
|
|
|
®ion->region);
|
2012-02-24 01:11:59 +04:00
|
|
|
} else {
|
2012-10-10 13:49:28 +04:00
|
|
|
pixman_region32_fini(&surface->pending.input);
|
|
|
|
region_init_infinite(&surface->pending.input);
|
2012-02-24 01:11:59 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-10 13:49:23 +04:00
|
|
|
static void
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
weston_surface_commit_subsurface_order(struct weston_surface *surface)
|
|
|
|
{
|
|
|
|
struct weston_subsurface *sub;
|
|
|
|
|
|
|
|
wl_list_for_each_reverse(sub, &surface->subsurface_list_pending,
|
|
|
|
parent_link_pending) {
|
|
|
|
wl_list_remove(&sub->parent_link);
|
|
|
|
wl_list_insert(&surface->subsurface_list, &sub->parent_link);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-16 19:55:19 +04:00
|
|
|
static void
|
2016-04-26 15:50:58 +03:00
|
|
|
weston_surface_build_buffer_matrix(const struct weston_surface *surface,
|
2014-10-16 19:55:19 +04:00
|
|
|
struct weston_matrix *matrix)
|
|
|
|
{
|
2016-04-26 15:50:58 +03:00
|
|
|
const struct weston_buffer_viewport *vp = &surface->buffer_viewport;
|
2014-10-16 19:55:19 +04:00
|
|
|
double src_width, src_height, dest_width, dest_height;
|
|
|
|
|
|
|
|
weston_matrix_init(matrix);
|
|
|
|
|
|
|
|
if (vp->buffer.src_width == wl_fixed_from_int(-1)) {
|
|
|
|
src_width = surface->width_from_buffer;
|
|
|
|
src_height = surface->height_from_buffer;
|
|
|
|
} else {
|
|
|
|
src_width = wl_fixed_to_double(vp->buffer.src_width);
|
|
|
|
src_height = wl_fixed_to_double(vp->buffer.src_height);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vp->surface.width == -1) {
|
|
|
|
dest_width = src_width;
|
|
|
|
dest_height = src_height;
|
|
|
|
} else {
|
|
|
|
dest_width = vp->surface.width;
|
|
|
|
dest_height = vp->surface.height;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (src_width != dest_width || src_height != dest_height)
|
|
|
|
weston_matrix_scale(matrix,
|
|
|
|
src_width / dest_width,
|
|
|
|
src_height / dest_height, 1);
|
|
|
|
|
|
|
|
if (vp->buffer.src_width != wl_fixed_from_int(-1))
|
|
|
|
weston_matrix_translate(matrix,
|
|
|
|
wl_fixed_to_double(vp->buffer.src_x),
|
|
|
|
wl_fixed_to_double(vp->buffer.src_y),
|
|
|
|
0);
|
|
|
|
|
|
|
|
switch (vp->buffer.transform) {
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED:
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
|
|
|
|
weston_matrix_scale(matrix, -1, 1, 1);
|
|
|
|
weston_matrix_translate(matrix,
|
|
|
|
surface->width_from_buffer, 0, 0);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (vp->buffer.transform) {
|
|
|
|
default:
|
|
|
|
case WL_OUTPUT_TRANSFORM_NORMAL:
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED:
|
|
|
|
break;
|
|
|
|
case WL_OUTPUT_TRANSFORM_90:
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
|
|
|
|
weston_matrix_rotate_xy(matrix, 0, 1);
|
|
|
|
weston_matrix_translate(matrix,
|
|
|
|
surface->height_from_buffer, 0, 0);
|
|
|
|
break;
|
|
|
|
case WL_OUTPUT_TRANSFORM_180:
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
|
|
|
|
weston_matrix_rotate_xy(matrix, -1, 0);
|
|
|
|
weston_matrix_translate(matrix,
|
|
|
|
surface->width_from_buffer,
|
|
|
|
surface->height_from_buffer, 0);
|
|
|
|
break;
|
|
|
|
case WL_OUTPUT_TRANSFORM_270:
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
|
|
|
|
weston_matrix_rotate_xy(matrix, 0, -1);
|
|
|
|
weston_matrix_translate(matrix,
|
|
|
|
0, surface->width_from_buffer, 0);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
weston_matrix_scale(matrix, vp->buffer.scale, vp->buffer.scale, 1);
|
|
|
|
}
|
|
|
|
|
2016-04-26 13:46:38 +03:00
|
|
|
/**
|
|
|
|
* Compute a + b > c while being safe to overflows.
|
|
|
|
*/
|
|
|
|
static bool
|
|
|
|
fixed_sum_gt(wl_fixed_t a, wl_fixed_t b, wl_fixed_t c)
|
|
|
|
{
|
|
|
|
return (int64_t)a + (int64_t)b > (int64_t)c;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool
|
|
|
|
weston_surface_is_pending_viewport_source_valid(
|
|
|
|
const struct weston_surface *surface)
|
|
|
|
{
|
|
|
|
const struct weston_surface_state *pend = &surface->pending;
|
|
|
|
const struct weston_buffer_viewport *vp = &pend->buffer_viewport;
|
|
|
|
int width_from_buffer = 0;
|
|
|
|
int height_from_buffer = 0;
|
|
|
|
wl_fixed_t w;
|
|
|
|
wl_fixed_t h;
|
|
|
|
|
|
|
|
/* If viewport source rect is not set, it is always ok. */
|
|
|
|
if (vp->buffer.src_width == wl_fixed_from_int(-1))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (pend->newly_attached) {
|
|
|
|
if (pend->buffer) {
|
|
|
|
convert_size_by_transform_scale(&width_from_buffer,
|
|
|
|
&height_from_buffer,
|
|
|
|
pend->buffer->width,
|
|
|
|
pend->buffer->height,
|
|
|
|
vp->buffer.transform,
|
|
|
|
vp->buffer.scale);
|
|
|
|
} else {
|
|
|
|
/* No buffer: viewport is irrelevant. */
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
width_from_buffer = surface->width_from_buffer;
|
|
|
|
height_from_buffer = surface->height_from_buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert((width_from_buffer == 0) == (height_from_buffer == 0));
|
|
|
|
assert(width_from_buffer >= 0 && height_from_buffer >= 0);
|
|
|
|
|
|
|
|
/* No buffer: viewport is irrelevant. */
|
|
|
|
if (width_from_buffer == 0 || height_from_buffer == 0)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
/* overflow checks for wl_fixed_from_int() */
|
|
|
|
if (width_from_buffer > wl_fixed_to_int(INT32_MAX))
|
|
|
|
return false;
|
|
|
|
if (height_from_buffer > wl_fixed_to_int(INT32_MAX))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
w = wl_fixed_from_int(width_from_buffer);
|
|
|
|
h = wl_fixed_from_int(height_from_buffer);
|
|
|
|
|
|
|
|
if (fixed_sum_gt(vp->buffer.src_x, vp->buffer.src_width, w))
|
|
|
|
return false;
|
|
|
|
if (fixed_sum_gt(vp->buffer.src_y, vp->buffer.src_height, h))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-04-26 14:28:28 +03:00
|
|
|
static bool
|
|
|
|
fixed_is_integer(wl_fixed_t v)
|
|
|
|
{
|
|
|
|
return (v & 0xff) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool
|
|
|
|
weston_surface_is_pending_viewport_dst_size_int(
|
|
|
|
const struct weston_surface *surface)
|
|
|
|
{
|
|
|
|
const struct weston_buffer_viewport *vp =
|
|
|
|
&surface->pending.buffer_viewport;
|
|
|
|
|
|
|
|
if (vp->surface.width != -1) {
|
|
|
|
assert(vp->surface.width > 0 && vp->surface.height > 0);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fixed_is_integer(vp->buffer.src_width) &&
|
|
|
|
fixed_is_integer(vp->buffer.src_height);
|
|
|
|
}
|
|
|
|
|
2015-11-26 23:17:48 +03:00
|
|
|
/* Translate pending damage in buffer co-ordinates to surface
|
|
|
|
* co-ordinates and union it with a pixman_region32_t.
|
|
|
|
* This should only be called after the buffer is attached.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
apply_damage_buffer(pixman_region32_t *dest,
|
|
|
|
struct weston_surface *surface,
|
|
|
|
struct weston_surface_state *state)
|
|
|
|
{
|
|
|
|
struct weston_buffer *buffer = surface->buffer_ref.buffer;
|
|
|
|
|
|
|
|
/* wl_surface.damage_buffer needs to be clipped to the buffer,
|
|
|
|
* translated into surface co-ordinates and unioned with
|
|
|
|
* any other surface damage.
|
|
|
|
* None of this makes sense if there is no buffer though.
|
|
|
|
*/
|
|
|
|
if (buffer && pixman_region32_not_empty(&state->damage_buffer)) {
|
|
|
|
pixman_region32_t buffer_damage;
|
|
|
|
|
|
|
|
pixman_region32_intersect_rect(&state->damage_buffer,
|
|
|
|
&state->damage_buffer,
|
|
|
|
0, 0, buffer->width,
|
|
|
|
buffer->height);
|
|
|
|
pixman_region32_init(&buffer_damage);
|
|
|
|
weston_matrix_transform_region(&buffer_damage,
|
|
|
|
&surface->buffer_to_surface_matrix,
|
|
|
|
&state->damage_buffer);
|
|
|
|
pixman_region32_union(dest, dest, &buffer_damage);
|
|
|
|
pixman_region32_fini(&buffer_damage);
|
|
|
|
}
|
|
|
|
/* We should clear this on commit even if there was no buffer */
|
|
|
|
pixman_region32_clear(&state->damage_buffer);
|
|
|
|
}
|
|
|
|
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
static void
|
2014-05-20 23:33:03 +04:00
|
|
|
weston_surface_commit_state(struct weston_surface *surface,
|
|
|
|
struct weston_surface_state *state)
|
2012-10-10 13:49:23 +04:00
|
|
|
{
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
struct weston_view *view;
|
2012-10-30 19:44:01 +04:00
|
|
|
pixman_region32_t opaque;
|
|
|
|
|
2013-05-22 16:41:37 +04:00
|
|
|
/* wl_surface.set_buffer_transform */
|
|
|
|
/* wl_surface.set_buffer_scale */
|
2016-04-15 14:47:08 +03:00
|
|
|
/* wp_viewport.set_source */
|
|
|
|
/* wp_viewport.set_destination */
|
2014-05-20 23:33:03 +04:00
|
|
|
surface->buffer_viewport = state->buffer_viewport;
|
2013-05-22 16:41:37 +04:00
|
|
|
|
2012-10-10 13:49:23 +04:00
|
|
|
/* wl_surface.attach */
|
2014-05-20 23:33:03 +04:00
|
|
|
if (state->newly_attached)
|
|
|
|
weston_surface_attach(surface, state->buffer);
|
|
|
|
weston_surface_state_set_buffer(state, NULL);
|
2013-02-21 14:29:21 +04:00
|
|
|
|
2014-10-16 19:55:19 +04:00
|
|
|
weston_surface_build_buffer_matrix(surface,
|
|
|
|
&surface->surface_to_buffer_matrix);
|
|
|
|
weston_matrix_invert(&surface->buffer_to_surface_matrix,
|
|
|
|
&surface->surface_to_buffer_matrix);
|
|
|
|
|
2014-05-20 23:33:03 +04:00
|
|
|
if (state->newly_attached || state->buffer_viewport.changed) {
|
2014-06-13 20:14:20 +04:00
|
|
|
weston_surface_update_size(surface);
|
2016-08-12 11:41:33 +03:00
|
|
|
if (surface->committed)
|
|
|
|
surface->committed(surface, state->sx, state->sy);
|
2014-06-13 20:14:20 +04:00
|
|
|
}
|
2013-02-21 14:29:21 +04:00
|
|
|
|
2014-05-20 23:33:03 +04:00
|
|
|
state->sx = 0;
|
|
|
|
state->sy = 0;
|
|
|
|
state->newly_attached = 0;
|
|
|
|
state->buffer_viewport.changed = 0;
|
2012-10-10 13:49:25 +04:00
|
|
|
|
2015-11-26 23:17:48 +03:00
|
|
|
/* wl_surface.damage and wl_surface.damage_buffer */
|
compositor: Implement JSON-timeline logging
Logging is activated and deactivated with the debug key binding 't'.
When activated, it creates a new log file, where it records the events.
The log file contains events and detailed object information entries in
JSON format, and is meant to be parsed in sequence from beginning to the
end.
The emitted events are mostly related to the output repaint cycle, like
when repaint begins, is submitted to GPU, and when it completes on a
vblank. This is recorded per-output. Also some per-surface events are
recorded, including when surface damage is flushed.
To reduce the log size, events refer to objects like outputs and
surfaces by id numbers. Detailed object information is emitted only as
needed: on the first object occurrence, and afterwards only if
weston_timeline_object::force_refresh asks for it.
The detailed information for surfaces includes the string returned by
weston_surface::get_label. Therefore it is important to set
weston_timeline_object::force_refresh = 1 whenever the string would
change, so that the new details get recorded.
A rudimentary parser and SVG generator can be found at:
https://github.com/ppaalanen/wesgr
The timeline logs can answer questions including:
- How does the compositor repaint cycle work timing-wise?
- When was the vblank deadline missed?
- What is the latency from surface commit to showing the new content on
screen?
- How long does it take to process the scenegraph?
v2: weston_surface::get_description renamed to get_label.
v3: reafctor a bit into fprint_quoted_string().
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2014-11-12 16:09:24 +03:00
|
|
|
if (weston_timeline_enabled_ &&
|
2015-11-26 23:17:48 +03:00
|
|
|
(pixman_region32_not_empty(&state->damage_surface) ||
|
|
|
|
pixman_region32_not_empty(&state->damage_buffer)))
|
compositor: Implement JSON-timeline logging
Logging is activated and deactivated with the debug key binding 't'.
When activated, it creates a new log file, where it records the events.
The log file contains events and detailed object information entries in
JSON format, and is meant to be parsed in sequence from beginning to the
end.
The emitted events are mostly related to the output repaint cycle, like
when repaint begins, is submitted to GPU, and when it completes on a
vblank. This is recorded per-output. Also some per-surface events are
recorded, including when surface damage is flushed.
To reduce the log size, events refer to objects like outputs and
surfaces by id numbers. Detailed object information is emitted only as
needed: on the first object occurrence, and afterwards only if
weston_timeline_object::force_refresh asks for it.
The detailed information for surfaces includes the string returned by
weston_surface::get_label. Therefore it is important to set
weston_timeline_object::force_refresh = 1 whenever the string would
change, so that the new details get recorded.
A rudimentary parser and SVG generator can be found at:
https://github.com/ppaalanen/wesgr
The timeline logs can answer questions including:
- How does the compositor repaint cycle work timing-wise?
- When was the vblank deadline missed?
- What is the latency from surface commit to showing the new content on
screen?
- How long does it take to process the scenegraph?
v2: weston_surface::get_description renamed to get_label.
v3: reafctor a bit into fprint_quoted_string().
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2014-11-12 16:09:24 +03:00
|
|
|
TL_POINT("core_commit_damage", TLP_SURFACE(surface), TLP_END);
|
2015-11-26 23:17:48 +03:00
|
|
|
|
2012-10-10 13:49:25 +04:00
|
|
|
pixman_region32_union(&surface->damage, &surface->damage,
|
2015-11-26 23:17:48 +03:00
|
|
|
&state->damage_surface);
|
|
|
|
|
|
|
|
apply_damage_buffer(&surface->damage, surface, state);
|
|
|
|
|
2012-11-08 20:36:02 +04:00
|
|
|
pixman_region32_intersect_rect(&surface->damage, &surface->damage,
|
2014-06-26 21:37:36 +04:00
|
|
|
0, 0, surface->width, surface->height);
|
2015-11-26 23:17:48 +03:00
|
|
|
pixman_region32_clear(&state->damage_surface);
|
2012-10-10 13:49:27 +04:00
|
|
|
|
|
|
|
/* wl_surface.set_opaque_region */
|
2014-05-20 23:33:03 +04:00
|
|
|
pixman_region32_init(&opaque);
|
|
|
|
pixman_region32_intersect_rect(&opaque, &state->opaque,
|
|
|
|
0, 0, surface->width, surface->height);
|
2012-10-30 19:44:01 +04:00
|
|
|
|
|
|
|
if (!pixman_region32_equal(&opaque, &surface->opaque)) {
|
|
|
|
pixman_region32_copy(&surface->opaque, &opaque);
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
wl_list_for_each(view, &surface->views, surface_link)
|
|
|
|
weston_view_geometry_dirty(view);
|
2012-10-30 19:44:01 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
pixman_region32_fini(&opaque);
|
2012-10-10 13:49:28 +04:00
|
|
|
|
|
|
|
/* wl_surface.set_input_region */
|
2014-05-20 23:33:03 +04:00
|
|
|
pixman_region32_intersect_rect(&surface->input, &state->input,
|
|
|
|
0, 0, surface->width, surface->height);
|
2012-10-10 13:49:28 +04:00
|
|
|
|
2012-10-10 13:49:31 +04:00
|
|
|
/* wl_surface.frame */
|
|
|
|
wl_list_insert_list(&surface->frame_callback_list,
|
2014-05-20 23:33:03 +04:00
|
|
|
&state->frame_callback_list);
|
|
|
|
wl_list_init(&state->frame_callback_list);
|
2014-09-24 06:08:46 +04:00
|
|
|
|
|
|
|
/* XXX:
|
|
|
|
* What should happen with a feedback request, if there
|
|
|
|
* is no wl_buffer attached for this commit?
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* presentation.feedback */
|
|
|
|
wl_list_insert_list(&surface->feedback_list,
|
|
|
|
&state->feedback_list);
|
|
|
|
wl_list_init(&state->feedback_list);
|
2016-07-22 12:48:03 +03:00
|
|
|
|
|
|
|
wl_signal_emit(&surface->commit_signal, surface);
|
2014-05-20 23:33:03 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
weston_surface_commit(struct weston_surface *surface)
|
|
|
|
{
|
|
|
|
weston_surface_commit_state(surface, &surface->pending);
|
2012-10-10 13:49:31 +04:00
|
|
|
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
weston_surface_commit_subsurface_order(surface);
|
|
|
|
|
2012-10-10 13:49:28 +04:00
|
|
|
weston_surface_schedule_repaint(surface);
|
2012-10-10 13:49:23 +04:00
|
|
|
}
|
|
|
|
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
static void
|
|
|
|
weston_subsurface_commit(struct weston_subsurface *sub);
|
|
|
|
|
|
|
|
static void
|
|
|
|
weston_subsurface_parent_commit(struct weston_subsurface *sub,
|
|
|
|
int parent_is_synchronized);
|
|
|
|
|
|
|
|
static void
|
|
|
|
surface_commit(struct wl_client *client, struct wl_resource *resource)
|
|
|
|
{
|
2013-06-14 19:07:53 +04:00
|
|
|
struct weston_surface *surface = wl_resource_get_user_data(resource);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
struct weston_subsurface *sub = weston_surface_to_subsurface(surface);
|
|
|
|
|
2016-04-26 13:46:38 +03:00
|
|
|
if (!weston_surface_is_pending_viewport_source_valid(surface)) {
|
|
|
|
assert(surface->viewport_resource);
|
|
|
|
|
|
|
|
wl_resource_post_error(surface->viewport_resource,
|
|
|
|
WP_VIEWPORT_ERROR_OUT_OF_BUFFER,
|
|
|
|
"wl_surface@%d has viewport source outside buffer",
|
|
|
|
wl_resource_get_id(resource));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-04-26 14:28:28 +03:00
|
|
|
if (!weston_surface_is_pending_viewport_dst_size_int(surface)) {
|
|
|
|
assert(surface->viewport_resource);
|
|
|
|
|
|
|
|
wl_resource_post_error(surface->viewport_resource,
|
|
|
|
WP_VIEWPORT_ERROR_BAD_SIZE,
|
|
|
|
"wl_surface@%d viewport dst size not integer",
|
|
|
|
wl_resource_get_id(resource));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
if (sub) {
|
|
|
|
weston_subsurface_commit(sub);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
weston_surface_commit(surface);
|
|
|
|
|
|
|
|
wl_list_for_each(sub, &surface->subsurface_list, parent_link) {
|
|
|
|
if (sub->surface != surface)
|
|
|
|
weston_subsurface_parent_commit(sub, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-27 19:03:42 +04:00
|
|
|
static void
|
|
|
|
surface_set_buffer_transform(struct wl_client *client,
|
|
|
|
struct wl_resource *resource, int transform)
|
|
|
|
{
|
2013-06-14 19:07:53 +04:00
|
|
|
struct weston_surface *surface = wl_resource_get_user_data(resource);
|
2012-11-27 19:03:42 +04:00
|
|
|
|
2014-05-30 14:07:15 +04:00
|
|
|
/* if wl_output.transform grows more members this will need to be updated. */
|
|
|
|
if (transform < 0 ||
|
|
|
|
transform > WL_OUTPUT_TRANSFORM_FLIPPED_270) {
|
|
|
|
wl_resource_post_error(resource,
|
|
|
|
WL_SURFACE_ERROR_INVALID_TRANSFORM,
|
|
|
|
"buffer transform must be a valid transform "
|
|
|
|
"('%d' specified)", transform);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-03-14 16:38:15 +04:00
|
|
|
surface->pending.buffer_viewport.buffer.transform = transform;
|
2014-06-13 20:14:20 +04:00
|
|
|
surface->pending.buffer_viewport.changed = 1;
|
2012-11-27 19:03:42 +04:00
|
|
|
}
|
|
|
|
|
2013-05-22 16:41:37 +04:00
|
|
|
static void
|
|
|
|
surface_set_buffer_scale(struct wl_client *client,
|
|
|
|
struct wl_resource *resource,
|
2013-05-24 15:09:43 +04:00
|
|
|
int32_t scale)
|
2013-05-22 16:41:37 +04:00
|
|
|
{
|
2013-06-14 19:07:53 +04:00
|
|
|
struct weston_surface *surface = wl_resource_get_user_data(resource);
|
2013-05-22 16:41:37 +04:00
|
|
|
|
2014-05-30 14:07:15 +04:00
|
|
|
if (scale < 1) {
|
|
|
|
wl_resource_post_error(resource,
|
|
|
|
WL_SURFACE_ERROR_INVALID_SCALE,
|
|
|
|
"buffer scale must be at least one "
|
|
|
|
"('%d' specified)", scale);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-03-14 16:38:15 +04:00
|
|
|
surface->pending.buffer_viewport.buffer.scale = scale;
|
2014-06-13 20:14:20 +04:00
|
|
|
surface->pending.buffer_viewport.changed = 1;
|
2013-05-22 16:41:37 +04:00
|
|
|
}
|
|
|
|
|
2012-03-30 19:52:39 +04:00
|
|
|
static const struct wl_surface_interface surface_interface = {
|
2008-12-16 04:35:24 +03:00
|
|
|
surface_destroy,
|
|
|
|
surface_attach,
|
2011-08-17 07:01:28 +04:00
|
|
|
surface_damage,
|
2012-02-24 01:11:59 +04:00
|
|
|
surface_frame,
|
|
|
|
surface_set_opaque_region,
|
2012-10-10 13:49:23 +04:00
|
|
|
surface_set_input_region,
|
2012-11-27 19:03:42 +04:00
|
|
|
surface_commit,
|
2013-05-22 16:41:37 +04:00
|
|
|
surface_set_buffer_transform,
|
2015-11-26 23:17:48 +03:00
|
|
|
surface_set_buffer_scale,
|
|
|
|
surface_damage_buffer
|
2008-12-16 04:35:24 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
compositor_create_surface(struct wl_client *client,
|
2011-08-19 01:55:30 +04:00
|
|
|
struct wl_resource *resource, uint32_t id)
|
2008-11-07 16:39:37 +03:00
|
|
|
{
|
2013-06-25 23:34:33 +04:00
|
|
|
struct weston_compositor *ec = wl_resource_get_user_data(resource);
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
struct weston_surface *surface;
|
2008-11-07 16:39:37 +03:00
|
|
|
|
2012-01-27 20:58:31 +04:00
|
|
|
surface = weston_surface_create(ec);
|
2010-08-09 22:43:33 +04:00
|
|
|
if (surface == NULL) {
|
2011-09-01 17:54:57 +04:00
|
|
|
wl_resource_post_no_memory(resource);
|
2008-12-16 04:35:24 +03:00
|
|
|
return;
|
2010-08-09 22:43:33 +04:00
|
|
|
}
|
2008-11-29 01:06:06 +03:00
|
|
|
|
2013-06-28 05:17:02 +04:00
|
|
|
surface->resource =
|
|
|
|
wl_resource_create(client, &wl_surface_interface,
|
|
|
|
wl_resource_get_version(resource), id);
|
2013-08-07 03:46:25 +04:00
|
|
|
if (surface->resource == NULL) {
|
|
|
|
weston_surface_destroy(surface);
|
|
|
|
wl_resource_post_no_memory(resource);
|
|
|
|
return;
|
|
|
|
}
|
2013-06-28 05:17:02 +04:00
|
|
|
wl_resource_set_implementation(surface->resource, &surface_interface,
|
|
|
|
surface, destroy_surface);
|
2014-04-07 09:04:50 +04:00
|
|
|
|
|
|
|
wl_signal_emit(&ec->create_surface_signal, surface);
|
2008-12-16 04:35:24 +03:00
|
|
|
}
|
|
|
|
|
2012-02-24 01:11:59 +04:00
|
|
|
static void
|
|
|
|
destroy_region(struct wl_resource *resource)
|
|
|
|
{
|
2013-06-14 19:07:56 +04:00
|
|
|
struct weston_region *region = wl_resource_get_user_data(resource);
|
2012-02-24 01:11:59 +04:00
|
|
|
|
|
|
|
pixman_region32_fini(®ion->region);
|
|
|
|
free(region);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
region_destroy(struct wl_client *client, struct wl_resource *resource)
|
|
|
|
{
|
2012-04-12 06:42:15 +04:00
|
|
|
wl_resource_destroy(resource);
|
2012-02-24 01:11:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
region_add(struct wl_client *client, struct wl_resource *resource,
|
|
|
|
int32_t x, int32_t y, int32_t width, int32_t height)
|
|
|
|
{
|
2013-06-14 19:07:56 +04:00
|
|
|
struct weston_region *region = wl_resource_get_user_data(resource);
|
2012-02-24 01:11:59 +04:00
|
|
|
|
|
|
|
pixman_region32_union_rect(®ion->region, ®ion->region,
|
|
|
|
x, y, width, height);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
region_subtract(struct wl_client *client, struct wl_resource *resource,
|
|
|
|
int32_t x, int32_t y, int32_t width, int32_t height)
|
|
|
|
{
|
2013-06-14 19:07:56 +04:00
|
|
|
struct weston_region *region = wl_resource_get_user_data(resource);
|
2012-02-24 01:11:59 +04:00
|
|
|
pixman_region32_t rect;
|
|
|
|
|
|
|
|
pixman_region32_init_rect(&rect, x, y, width, height);
|
|
|
|
pixman_region32_subtract(®ion->region, ®ion->region, &rect);
|
|
|
|
pixman_region32_fini(&rect);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct wl_region_interface region_interface = {
|
|
|
|
region_destroy,
|
|
|
|
region_add,
|
|
|
|
region_subtract
|
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
compositor_create_region(struct wl_client *client,
|
|
|
|
struct wl_resource *resource, uint32_t id)
|
|
|
|
{
|
|
|
|
struct weston_region *region;
|
|
|
|
|
|
|
|
region = malloc(sizeof *region);
|
|
|
|
if (region == NULL) {
|
|
|
|
wl_resource_post_no_memory(resource);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
pixman_region32_init(®ion->region);
|
|
|
|
|
2013-06-28 05:17:02 +04:00
|
|
|
region->resource =
|
|
|
|
wl_resource_create(client, &wl_region_interface, 1, id);
|
2013-08-07 03:46:25 +04:00
|
|
|
if (region->resource == NULL) {
|
|
|
|
free(region);
|
|
|
|
wl_resource_post_no_memory(resource);
|
|
|
|
return;
|
|
|
|
}
|
2013-06-28 05:17:02 +04:00
|
|
|
wl_resource_set_implementation(region->resource, ®ion_interface,
|
|
|
|
region, destroy_region);
|
2012-02-24 01:11:59 +04:00
|
|
|
}
|
|
|
|
|
2012-03-30 19:52:39 +04:00
|
|
|
static const struct wl_compositor_interface compositor_interface = {
|
2008-12-16 04:35:24 +03:00
|
|
|
compositor_create_surface,
|
2012-02-24 01:11:59 +04:00
|
|
|
compositor_create_region
|
2008-12-16 04:35:24 +03:00
|
|
|
};
|
|
|
|
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
static void
|
|
|
|
weston_subsurface_commit_from_cache(struct weston_subsurface *sub)
|
|
|
|
{
|
|
|
|
struct weston_surface *surface = sub->surface;
|
2014-06-13 20:14:20 +04:00
|
|
|
|
2014-05-20 23:33:03 +04:00
|
|
|
weston_surface_commit_state(surface, &sub->cached);
|
|
|
|
weston_buffer_reference(&sub->cached_buffer_ref, NULL);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
|
|
|
|
weston_surface_commit_subsurface_order(surface);
|
|
|
|
|
|
|
|
weston_surface_schedule_repaint(surface);
|
|
|
|
|
2014-05-20 23:33:03 +04:00
|
|
|
sub->has_cached_data = 0;
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
weston_subsurface_commit_to_cache(struct weston_subsurface *sub)
|
|
|
|
{
|
|
|
|
struct weston_surface *surface = sub->surface;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If this commit would cause the surface to move by the
|
|
|
|
* attach(dx, dy) parameters, the old damage region must be
|
|
|
|
* translated to correspond to the new surface coordinate system
|
2015-11-26 19:30:00 +03:00
|
|
|
* origin.
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
*/
|
2015-11-26 23:17:48 +03:00
|
|
|
pixman_region32_translate(&sub->cached.damage_surface,
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
-surface->pending.sx, -surface->pending.sy);
|
2015-11-26 23:17:48 +03:00
|
|
|
pixman_region32_union(&sub->cached.damage_surface,
|
|
|
|
&sub->cached.damage_surface,
|
|
|
|
&surface->pending.damage_surface);
|
|
|
|
pixman_region32_clear(&surface->pending.damage_surface);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
|
|
|
|
if (surface->pending.newly_attached) {
|
|
|
|
sub->cached.newly_attached = 1;
|
2014-05-20 23:33:03 +04:00
|
|
|
weston_surface_state_set_buffer(&sub->cached,
|
|
|
|
surface->pending.buffer);
|
|
|
|
weston_buffer_reference(&sub->cached_buffer_ref,
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
surface->pending.buffer);
|
2014-09-24 06:08:46 +04:00
|
|
|
weston_presentation_feedback_discard_list(
|
|
|
|
&sub->cached.feedback_list);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
}
|
|
|
|
sub->cached.sx += surface->pending.sx;
|
|
|
|
sub->cached.sy += surface->pending.sy;
|
2014-03-14 16:38:12 +04:00
|
|
|
|
2015-11-26 23:17:48 +03:00
|
|
|
apply_damage_buffer(&sub->cached.damage_surface, surface, &surface->pending);
|
|
|
|
|
2014-06-13 20:14:20 +04:00
|
|
|
sub->cached.buffer_viewport.changed |=
|
|
|
|
surface->pending.buffer_viewport.changed;
|
|
|
|
sub->cached.buffer_viewport.buffer =
|
|
|
|
surface->pending.buffer_viewport.buffer;
|
|
|
|
sub->cached.buffer_viewport.surface =
|
|
|
|
surface->pending.buffer_viewport.surface;
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
|
2014-06-13 20:14:20 +04:00
|
|
|
weston_surface_reset_pending_buffer(surface);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
|
|
|
|
pixman_region32_copy(&sub->cached.opaque, &surface->pending.opaque);
|
|
|
|
|
|
|
|
pixman_region32_copy(&sub->cached.input, &surface->pending.input);
|
|
|
|
|
|
|
|
wl_list_insert_list(&sub->cached.frame_callback_list,
|
|
|
|
&surface->pending.frame_callback_list);
|
|
|
|
wl_list_init(&surface->pending.frame_callback_list);
|
|
|
|
|
2014-09-24 06:08:46 +04:00
|
|
|
wl_list_insert_list(&sub->cached.feedback_list,
|
|
|
|
&surface->pending.feedback_list);
|
|
|
|
wl_list_init(&surface->pending.feedback_list);
|
|
|
|
|
2014-05-20 23:33:03 +04:00
|
|
|
sub->has_cached_data = 1;
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
}
|
|
|
|
|
2014-10-03 22:13:42 +04:00
|
|
|
static bool
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
weston_subsurface_is_synchronized(struct weston_subsurface *sub)
|
|
|
|
{
|
|
|
|
while (sub) {
|
|
|
|
if (sub->synchronized)
|
2014-10-03 22:13:42 +04:00
|
|
|
return true;
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
|
|
|
|
if (!sub->parent)
|
2014-10-03 22:13:42 +04:00
|
|
|
return false;
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
|
|
|
|
sub = weston_surface_to_subsurface(sub->parent);
|
|
|
|
}
|
|
|
|
|
2014-11-04 16:38:39 +03:00
|
|
|
return false;
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
weston_subsurface_commit(struct weston_subsurface *sub)
|
|
|
|
{
|
|
|
|
struct weston_surface *surface = sub->surface;
|
|
|
|
struct weston_subsurface *tmp;
|
|
|
|
|
|
|
|
/* Recursive check for effectively synchronized. */
|
|
|
|
if (weston_subsurface_is_synchronized(sub)) {
|
|
|
|
weston_subsurface_commit_to_cache(sub);
|
|
|
|
} else {
|
2014-05-20 23:33:03 +04:00
|
|
|
if (sub->has_cached_data) {
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
/* flush accumulated state from cache */
|
|
|
|
weston_subsurface_commit_to_cache(sub);
|
|
|
|
weston_subsurface_commit_from_cache(sub);
|
|
|
|
} else {
|
|
|
|
weston_surface_commit(surface);
|
|
|
|
}
|
|
|
|
|
|
|
|
wl_list_for_each(tmp, &surface->subsurface_list, parent_link) {
|
|
|
|
if (tmp->surface != surface)
|
|
|
|
weston_subsurface_parent_commit(tmp, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-05-17 17:46:05 +04:00
|
|
|
weston_subsurface_synchronized_commit(struct weston_subsurface *sub)
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
{
|
|
|
|
struct weston_surface *surface = sub->surface;
|
|
|
|
struct weston_subsurface *tmp;
|
|
|
|
|
|
|
|
/* From now on, commit_from_cache the whole sub-tree, regardless of
|
|
|
|
* the synchronized mode of each child. This sub-surface or some
|
|
|
|
* of its ancestors were synchronized, so we are synchronized
|
|
|
|
* all the way down.
|
|
|
|
*/
|
|
|
|
|
2014-05-20 23:33:03 +04:00
|
|
|
if (sub->has_cached_data)
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
weston_subsurface_commit_from_cache(sub);
|
|
|
|
|
|
|
|
wl_list_for_each(tmp, &surface->subsurface_list, parent_link) {
|
|
|
|
if (tmp->surface != surface)
|
|
|
|
weston_subsurface_parent_commit(tmp, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-17 17:46:05 +04:00
|
|
|
static void
|
|
|
|
weston_subsurface_parent_commit(struct weston_subsurface *sub,
|
|
|
|
int parent_is_synchronized)
|
|
|
|
{
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
struct weston_view *view;
|
2013-05-17 17:46:05 +04:00
|
|
|
if (sub->position.set) {
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
wl_list_for_each(view, &sub->surface->views, surface_link)
|
|
|
|
weston_view_set_position(view,
|
|
|
|
sub->position.x,
|
|
|
|
sub->position.y);
|
|
|
|
|
2013-05-17 17:46:05 +04:00
|
|
|
sub->position.set = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (parent_is_synchronized || sub->synchronized)
|
|
|
|
weston_subsurface_synchronized_commit(sub);
|
|
|
|
}
|
|
|
|
|
compositor: add weston_surface_set_label_func()
When printing out logs from Weston's actions, mainly for debugging, it
can be very difficult to identify the different surfaces. Inspecting
the configure function pointer is not useful, as the configure functions
may live in modules.
Add vfunc get_label to weston_surface, which will produce a short,
human-readable description of the surface, which allows identifying it
better, rather than just looking at the surface size, for instance.
Set the label function from most parts of Weston, to identify cursors and
drag icons, and panels, backgrounds, screensavers and lock surfaces, and
the desktop shell's application surfaces.
v2: renamed 'description' to 'label', so we get
weston_surface_set_label_func().
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2014-08-06 20:36:51 +04:00
|
|
|
static int
|
|
|
|
subsurface_get_label(struct weston_surface *surface, char *buf, size_t len)
|
|
|
|
{
|
|
|
|
return snprintf(buf, len, "sub-surface");
|
|
|
|
}
|
|
|
|
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
static void
|
2016-08-12 11:41:33 +03:00
|
|
|
subsurface_committed(struct weston_surface *surface, int32_t dx, int32_t dy)
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
{
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
struct weston_view *view;
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
wl_list_for_each(view, &surface->views, surface_link)
|
2013-12-03 07:01:53 +04:00
|
|
|
weston_view_set_position(view,
|
|
|
|
view->geometry.x + dx,
|
|
|
|
view->geometry.y + dy);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
|
|
|
|
/* No need to check parent mappedness, because if parent is not
|
|
|
|
* mapped, parent is not in a visible layer, so this sub-surface
|
|
|
|
* will not be drawn either.
|
|
|
|
*/
|
2016-06-30 07:04:28 +03:00
|
|
|
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
if (!weston_surface_is_mapped(surface)) {
|
2016-06-30 07:04:28 +03:00
|
|
|
surface->is_mapped = true;
|
compositor: quick fix for sub-surface mapping
If a client does this:
1. create a main window and map it
2. create a wl_surface, and make it a sub-surface of the main window
3. set the sub-surface to desync
4. commit content to the sub-surface to map it
Then step 4 should cause the sub-surface to become mapped. However,
Weston fails to schedule a repaint in that case, so the sub-surface will
not appear until something else causes a repaint on that output, e.g.
the main window.
A quick and dirty fix is to set the output mask for the surface in
Weston, which allows the repaint to be scheduled. This patch implements
that, and might only work right on single-output systems.
A proper fix would involve rewriting the whole "is surface mapped"
mechanism in Weston, to not rely on output assignments but to have a
separate flag for "mapped", and figuring out how to schedule repaints
for the right outputs.
Following is the actual protocol sequence used to trigger the problem:
[3224648.125] -> wl_compositor@4.create_surface(new id wl_surface@3)
[3224648.206] -> xdg_shell@7.get_xdg_surface(new id xdg_surface@8, wl_surface@3)
[3224648.311] -> xdg_surface@8.set_title("simple-shm")
[3224648.378] -> wl_surface@3.damage(0, 0, 250, 250)
[3224649.888] -> wl_shm@6.create_pool(new id wl_shm_pool@9, fd 6, 250000)
[3224650.031] -> wl_shm_pool@9.create_buffer(new id wl_buffer@10, 0, 250, 250, 1000, 1)
[3224650.244] -> wl_shm_pool@9.destroy()
[3224651.975] -> wl_surface@3.attach(wl_buffer@10, 0, 0)
[3224652.100] -> wl_surface@3.damage(20, 20, 210, 210)
[3224652.243] -> wl_surface@3.frame(new id wl_callback@11)
[3224652.317] -> wl_surface@3.commit()
[3228652.535] -> wl_compositor@4.create_surface(new id wl_surface@12)
[3228652.610] -> wl_subcompositor@5.get_subsurface(new id wl_subsurface@13, wl_surface@12, wl_surface@3)
[3228652.644] -> wl_subsurface@13.set_desync()
[3228652.659] -> wl_subsurface@13.set_position(100, 100)
[3228654.090] -> wl_shm@6.create_pool(new id wl_shm_pool@14, fd 6, 250000)
[3228654.140] -> wl_shm_pool@14.create_buffer(new id wl_buffer@15, 0, 250, 250, 1000, 1)
[3228654.180] -> wl_shm_pool@14.destroy()
[3228654.408] -> wl_surface@12.attach(wl_buffer@15, 0, 0)
[3228654.436] -> wl_surface@12.damage(0, 0, 250, 250)
[3228654.462] -> wl_surface@12.commit()
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Cc: George Kiagiadakis <george.kiagiadakis@collabora.com>
Cc: Jason Ekstrand <jason.ekstrand@intel.com>
2014-06-30 12:52:07 +04:00
|
|
|
|
2014-09-11 00:37:33 +04:00
|
|
|
/* Cannot call weston_view_update_transform(),
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
* because that would call it also for the parent surface,
|
|
|
|
* which might not be mapped yet. That would lead to
|
|
|
|
* inconsistent state, where the window could never be
|
|
|
|
* mapped.
|
|
|
|
*
|
2016-06-30 07:04:28 +03:00
|
|
|
* Instead just force the is_mapped flag on, to make
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
* weston_surface_is_mapped() return true, so that when the
|
|
|
|
* parent surface does get mapped, this one will get
|
compositor: quick fix for sub-surface mapping
If a client does this:
1. create a main window and map it
2. create a wl_surface, and make it a sub-surface of the main window
3. set the sub-surface to desync
4. commit content to the sub-surface to map it
Then step 4 should cause the sub-surface to become mapped. However,
Weston fails to schedule a repaint in that case, so the sub-surface will
not appear until something else causes a repaint on that output, e.g.
the main window.
A quick and dirty fix is to set the output mask for the surface in
Weston, which allows the repaint to be scheduled. This patch implements
that, and might only work right on single-output systems.
A proper fix would involve rewriting the whole "is surface mapped"
mechanism in Weston, to not rely on output assignments but to have a
separate flag for "mapped", and figuring out how to schedule repaints
for the right outputs.
Following is the actual protocol sequence used to trigger the problem:
[3224648.125] -> wl_compositor@4.create_surface(new id wl_surface@3)
[3224648.206] -> xdg_shell@7.get_xdg_surface(new id xdg_surface@8, wl_surface@3)
[3224648.311] -> xdg_surface@8.set_title("simple-shm")
[3224648.378] -> wl_surface@3.damage(0, 0, 250, 250)
[3224649.888] -> wl_shm@6.create_pool(new id wl_shm_pool@9, fd 6, 250000)
[3224650.031] -> wl_shm_pool@9.create_buffer(new id wl_buffer@10, 0, 250, 250, 1000, 1)
[3224650.244] -> wl_shm_pool@9.destroy()
[3224651.975] -> wl_surface@3.attach(wl_buffer@10, 0, 0)
[3224652.100] -> wl_surface@3.damage(20, 20, 210, 210)
[3224652.243] -> wl_surface@3.frame(new id wl_callback@11)
[3224652.317] -> wl_surface@3.commit()
[3228652.535] -> wl_compositor@4.create_surface(new id wl_surface@12)
[3228652.610] -> wl_subcompositor@5.get_subsurface(new id wl_subsurface@13, wl_surface@12, wl_surface@3)
[3228652.644] -> wl_subsurface@13.set_desync()
[3228652.659] -> wl_subsurface@13.set_position(100, 100)
[3228654.090] -> wl_shm@6.create_pool(new id wl_shm_pool@14, fd 6, 250000)
[3228654.140] -> wl_shm_pool@14.create_buffer(new id wl_buffer@15, 0, 250, 250, 1000, 1)
[3228654.180] -> wl_shm_pool@14.destroy()
[3228654.408] -> wl_surface@12.attach(wl_buffer@15, 0, 0)
[3228654.436] -> wl_surface@12.damage(0, 0, 250, 250)
[3228654.462] -> wl_surface@12.commit()
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Cc: George Kiagiadakis <george.kiagiadakis@collabora.com>
Cc: Jason Ekstrand <jason.ekstrand@intel.com>
2014-06-30 12:52:07 +04:00
|
|
|
* included, too. See view_list_add().
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct weston_subsurface *
|
|
|
|
weston_surface_to_subsurface(struct weston_surface *surface)
|
|
|
|
{
|
2016-08-12 11:41:33 +03:00
|
|
|
if (surface->committed == subsurface_committed)
|
|
|
|
return surface->committed_private;
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
shell: keyboard focus and restacking fixes for sub-surfaces
The shell needs to redirect some actions to the parent surface, when
they originally target a sub-surface. This patch implements the
following:
- Move, resize, and rotate bindings always target the parent surface.
- Opacity (full-surface alpha) binding targets the parent surface. This
is broken, because it should change the opacity of the whole compound
window, which is difficult to implement in the renderer.
- click_to_activate_binding() needs to check the shell surface type from
the main surface, because sub-surface would produce SHELL_SURFACE_NONE
and prevent activation.
- Also activate() needs to check the type from the main surface, and
restack the main surface. Keyboard focus is assigned to the original
(sub-)surface.
- focus_state_surface_destroy() needs to handle sub-surfaces: only the
main surface will be in a layer list. If the destroyed surface is
indeed a sub-surface, activate the main surface next. This way a
client that destroys a focused sub-surface still retains focus in the
same window.
- The workspace_manager.move_surface request can accept also
sub-surfaces, and it will move the corresponding main surface.
Changes in v2:
- do not special-case keyboard focus for sub-surfaces
- fix surface type checks for sub-surfaces in shell, fix restacking of
sub-surfaces in shell, fix focus_state_surface_destroy()
Changes in v3:
- Renamed weston_surface_get_parent() to
weston_surface_get_main_surface() to be more explicit that this is
about sub-surfaces
- Fixed move_surface_to_workspace() to handle keyboard focus on a
sub-surface.
- Used a temporary variable in several places to clarify code, instead
of reassigning a variable.
- Fixed workspace_manager_move_surface() to deal with sub-surfaces.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:44 +04:00
|
|
|
WL_EXPORT struct weston_surface *
|
|
|
|
weston_surface_get_main_surface(struct weston_surface *surface)
|
|
|
|
{
|
|
|
|
struct weston_subsurface *sub;
|
|
|
|
|
|
|
|
while (surface && (sub = weston_surface_to_subsurface(surface)))
|
|
|
|
surface = sub->parent;
|
|
|
|
|
|
|
|
return surface;
|
|
|
|
}
|
|
|
|
|
compositor: send error for surface role resets
With the more accurate definition of wl_surface roles in Wayland,
enforce the restriction: a role is always set permanently, and
attempting to change it is a protocol error.
This patch is based on Jasper's patch:
http://lists.freedesktop.org/archives/wayland-devel/2014-August/016811.html
The difference in this patch compared to his are:
- send role errors on the interface whose request triggers it, not on
wl_surface
- an interface could have several requests assigning different roles,
cannot use wl_interface as the unique key; use an arbitary string
instead
- ensure in window-manager.c that create_shell_surface() ->
create_common_surface() is never called with surface->configure set,
to avoid compositor abort
- use wl_resource_post_no_memory() where appropriate instead of
hand-rolling it with wl_resource_post_error()
Ideally we would not add weston_surface::role_name field, but use
weston_surface::configure. At the moment this is not possible though,
because at least shell.c uses several different roles with the same
configure function. Drag'n'drop uses two configure functions for the
same role. The configure hook is also reset in several places,
which is not good for role tracking.
This patch overlooks the wl_surface roles assigned in privileged
extensions: screensaver, panel, background, lock, input panel.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Reviewed-by: Jasper St. Pierre <jstpierre@mecheye.net>
2014-10-01 16:02:41 +04:00
|
|
|
WL_EXPORT int
|
|
|
|
weston_surface_set_role(struct weston_surface *surface,
|
|
|
|
const char *role_name,
|
|
|
|
struct wl_resource *error_resource,
|
|
|
|
uint32_t error_code)
|
|
|
|
{
|
|
|
|
assert(role_name);
|
|
|
|
|
|
|
|
if (surface->role_name == NULL ||
|
|
|
|
surface->role_name == role_name ||
|
|
|
|
strcmp(surface->role_name, role_name) == 0) {
|
|
|
|
surface->role_name = role_name;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
wl_resource_post_error(error_resource, error_code,
|
|
|
|
"Cannot assign role %s to wl_surface@%d,"
|
|
|
|
" already has role %s\n",
|
|
|
|
role_name,
|
|
|
|
wl_resource_get_id(surface->resource),
|
|
|
|
surface->role_name);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2016-08-12 11:41:37 +03:00
|
|
|
WL_EXPORT const char *
|
|
|
|
weston_surface_get_role(struct weston_surface *surface)
|
|
|
|
{
|
|
|
|
return surface->role_name;
|
|
|
|
}
|
|
|
|
|
compositor: add weston_surface_set_label_func()
When printing out logs from Weston's actions, mainly for debugging, it
can be very difficult to identify the different surfaces. Inspecting
the configure function pointer is not useful, as the configure functions
may live in modules.
Add vfunc get_label to weston_surface, which will produce a short,
human-readable description of the surface, which allows identifying it
better, rather than just looking at the surface size, for instance.
Set the label function from most parts of Weston, to identify cursors and
drag icons, and panels, backgrounds, screensavers and lock surfaces, and
the desktop shell's application surfaces.
v2: renamed 'description' to 'label', so we get
weston_surface_set_label_func().
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2014-08-06 20:36:51 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_surface_set_label_func(struct weston_surface *surface,
|
|
|
|
int (*desc)(struct weston_surface *,
|
|
|
|
char *, size_t))
|
|
|
|
{
|
|
|
|
surface->get_label = desc;
|
compositor: Implement JSON-timeline logging
Logging is activated and deactivated with the debug key binding 't'.
When activated, it creates a new log file, where it records the events.
The log file contains events and detailed object information entries in
JSON format, and is meant to be parsed in sequence from beginning to the
end.
The emitted events are mostly related to the output repaint cycle, like
when repaint begins, is submitted to GPU, and when it completes on a
vblank. This is recorded per-output. Also some per-surface events are
recorded, including when surface damage is flushed.
To reduce the log size, events refer to objects like outputs and
surfaces by id numbers. Detailed object information is emitted only as
needed: on the first object occurrence, and afterwards only if
weston_timeline_object::force_refresh asks for it.
The detailed information for surfaces includes the string returned by
weston_surface::get_label. Therefore it is important to set
weston_timeline_object::force_refresh = 1 whenever the string would
change, so that the new details get recorded.
A rudimentary parser and SVG generator can be found at:
https://github.com/ppaalanen/wesgr
The timeline logs can answer questions including:
- How does the compositor repaint cycle work timing-wise?
- When was the vblank deadline missed?
- What is the latency from surface commit to showing the new content on
screen?
- How long does it take to process the scenegraph?
v2: weston_surface::get_description renamed to get_label.
v3: reafctor a bit into fprint_quoted_string().
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2014-11-12 16:09:24 +03:00
|
|
|
surface->timeline.force_refresh = 1;
|
compositor: add weston_surface_set_label_func()
When printing out logs from Weston's actions, mainly for debugging, it
can be very difficult to identify the different surfaces. Inspecting
the configure function pointer is not useful, as the configure functions
may live in modules.
Add vfunc get_label to weston_surface, which will produce a short,
human-readable description of the surface, which allows identifying it
better, rather than just looking at the surface size, for instance.
Set the label function from most parts of Weston, to identify cursors and
drag icons, and panels, backgrounds, screensavers and lock surfaces, and
the desktop shell's application surfaces.
v2: renamed 'description' to 'label', so we get
weston_surface_set_label_func().
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2014-08-06 20:36:51 +04:00
|
|
|
}
|
|
|
|
|
2015-02-09 14:16:57 +03:00
|
|
|
/** Get the size of surface contents
|
|
|
|
*
|
|
|
|
* \param surface The surface to query.
|
|
|
|
* \param width Returns the width of raw contents.
|
|
|
|
* \param height Returns the height of raw contents.
|
|
|
|
*
|
|
|
|
* Retrieves the raw surface content size in pixels for the given surface.
|
|
|
|
* This is the whole content size in buffer pixels. If the surface
|
|
|
|
* has no content or the renderer does not implement this feature,
|
|
|
|
* zeroes are returned.
|
|
|
|
*
|
|
|
|
* This function is used to determine the buffer size needed for
|
|
|
|
* a weston_surface_copy_content() call.
|
|
|
|
*/
|
|
|
|
WL_EXPORT void
|
|
|
|
weston_surface_get_content_size(struct weston_surface *surface,
|
|
|
|
int *width, int *height)
|
|
|
|
{
|
|
|
|
struct weston_renderer *rer = surface->compositor->renderer;
|
|
|
|
|
|
|
|
if (!rer->surface_get_content_size) {
|
|
|
|
*width = 0;
|
|
|
|
*height = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
rer->surface_get_content_size(surface, width, height);
|
|
|
|
}
|
|
|
|
|
2016-08-12 11:41:34 +03:00
|
|
|
/** Get the bounding box of a surface and its subsurfaces
|
|
|
|
*
|
|
|
|
* \param surface The surface to query.
|
|
|
|
* \return The bounding box relative to the surface origin.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
WL_EXPORT struct weston_geometry
|
|
|
|
weston_surface_get_bounding_box(struct weston_surface *surface)
|
|
|
|
{
|
|
|
|
pixman_region32_t region;
|
|
|
|
pixman_box32_t *box;
|
|
|
|
struct weston_subsurface *subsurface;
|
|
|
|
|
|
|
|
pixman_region32_init_rect(®ion,
|
|
|
|
0, 0,
|
|
|
|
surface->width, surface->height);
|
|
|
|
|
|
|
|
wl_list_for_each(subsurface, &surface->subsurface_list, parent_link)
|
|
|
|
pixman_region32_union_rect(®ion, ®ion,
|
|
|
|
subsurface->position.x,
|
|
|
|
subsurface->position.y,
|
|
|
|
subsurface->surface->width,
|
|
|
|
subsurface->surface->height);
|
|
|
|
|
|
|
|
box = pixman_region32_extents(®ion);
|
|
|
|
struct weston_geometry geometry = {
|
|
|
|
.x = box->x1,
|
|
|
|
.y = box->y1,
|
|
|
|
.width = box->x2 - box->x1,
|
|
|
|
.height = box->y2 - box->y1,
|
|
|
|
};
|
|
|
|
|
|
|
|
pixman_region32_fini(®ion);
|
|
|
|
|
|
|
|
return geometry;
|
|
|
|
}
|
|
|
|
|
2015-02-09 14:16:57 +03:00
|
|
|
/** Copy surface contents to system memory.
|
|
|
|
*
|
|
|
|
* \param surface The surface to copy from.
|
|
|
|
* \param target Pointer to the target memory buffer.
|
|
|
|
* \param size Size of the target buffer in bytes.
|
|
|
|
* \param src_x X location on contents to copy from.
|
|
|
|
* \param src_y Y location on contents to copy from.
|
|
|
|
* \param width Width in pixels of the area to copy.
|
|
|
|
* \param height Height in pixels of the area to copy.
|
|
|
|
* \return 0 for success, -1 for failure.
|
|
|
|
*
|
|
|
|
* Surface contents are maintained by the renderer. They can be in a
|
|
|
|
* reserved weston_buffer or as a copy, e.g. a GL texture, or something
|
|
|
|
* else.
|
|
|
|
*
|
|
|
|
* Surface contents are copied into memory pointed to by target,
|
|
|
|
* which has size bytes of space available. The target memory
|
|
|
|
* may be larger than needed, but being smaller returns an error.
|
|
|
|
* The extra bytes in target may or may not be written; their content is
|
|
|
|
* unspecified. Size must be large enough to hold the image.
|
|
|
|
*
|
|
|
|
* The image in the target memory will be arranged in rows from
|
|
|
|
* top to bottom, and pixels on a row from left to right. The pixel
|
|
|
|
* format is PIXMAN_a8b8g8r8, 4 bytes per pixel, and stride is exactly
|
|
|
|
* width * 4.
|
|
|
|
*
|
|
|
|
* Parameters src_x and src_y define the upper-left corner in buffer
|
|
|
|
* coordinates (pixels) to copy from. Parameters width and height
|
|
|
|
* define the size of the area to copy in pixels.
|
|
|
|
*
|
|
|
|
* The rectangle defined by src_x, src_y, width, height must fit in
|
|
|
|
* the surface contents. Otherwise an error is returned.
|
|
|
|
*
|
|
|
|
* Use surface_get_data_size to determine the content size; the
|
|
|
|
* needed target buffer size and rectangle limits.
|
|
|
|
*
|
|
|
|
* CURRENT IMPLEMENTATION RESTRICTIONS:
|
|
|
|
* - the machine must be little-endian due to Pixman formats.
|
|
|
|
*
|
|
|
|
* NOTE: Pixman formats are premultiplied.
|
|
|
|
*/
|
|
|
|
WL_EXPORT int
|
|
|
|
weston_surface_copy_content(struct weston_surface *surface,
|
|
|
|
void *target, size_t size,
|
|
|
|
int src_x, int src_y,
|
|
|
|
int width, int height)
|
|
|
|
{
|
|
|
|
struct weston_renderer *rer = surface->compositor->renderer;
|
|
|
|
int cw, ch;
|
|
|
|
const size_t bytespp = 4; /* PIXMAN_a8b8g8r8 */
|
|
|
|
|
|
|
|
if (!rer->surface_copy_content)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
weston_surface_get_content_size(surface, &cw, &ch);
|
|
|
|
|
|
|
|
if (src_x < 0 || src_y < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (width <= 0 || height <= 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (src_x + width > cw || src_y + height > ch)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (width * bytespp * height > size)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return rer->surface_copy_content(surface, target, size,
|
|
|
|
src_x, src_y, width, height);
|
|
|
|
}
|
|
|
|
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
static void
|
|
|
|
subsurface_set_position(struct wl_client *client,
|
|
|
|
struct wl_resource *resource, int32_t x, int32_t y)
|
|
|
|
{
|
2013-06-14 19:08:02 +04:00
|
|
|
struct weston_subsurface *sub = wl_resource_get_user_data(resource);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
|
|
|
|
if (!sub)
|
|
|
|
return;
|
|
|
|
|
|
|
|
sub->position.x = x;
|
|
|
|
sub->position.y = y;
|
|
|
|
sub->position.set = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct weston_subsurface *
|
2016-06-08 19:37:57 +03:00
|
|
|
subsurface_find_sibling(struct weston_subsurface *sub,
|
|
|
|
struct weston_surface *surface)
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
{
|
2016-06-08 19:37:57 +03:00
|
|
|
struct weston_surface *parent = sub->parent;
|
|
|
|
struct weston_subsurface *sibling;
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
|
2016-06-08 19:37:57 +03:00
|
|
|
wl_list_for_each(sibling, &parent->subsurface_list, parent_link) {
|
|
|
|
if (sibling->surface == surface && sibling != sub)
|
|
|
|
return sibling;
|
|
|
|
}
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct weston_subsurface *
|
|
|
|
subsurface_sibling_check(struct weston_subsurface *sub,
|
|
|
|
struct weston_surface *surface,
|
|
|
|
const char *request)
|
|
|
|
{
|
|
|
|
struct weston_subsurface *sibling;
|
|
|
|
|
2016-06-08 19:37:57 +03:00
|
|
|
sibling = subsurface_find_sibling(sub, surface);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
if (!sibling) {
|
|
|
|
wl_resource_post_error(sub->resource,
|
|
|
|
WL_SUBSURFACE_ERROR_BAD_SURFACE,
|
|
|
|
"%s: wl_surface@%d is not a parent or sibling",
|
2013-06-07 07:34:41 +04:00
|
|
|
request, wl_resource_get_id(surface->resource));
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2016-06-08 19:37:57 +03:00
|
|
|
assert(sibling->parent == sub->parent);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
|
|
|
|
return sibling;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
subsurface_place_above(struct wl_client *client,
|
|
|
|
struct wl_resource *resource,
|
|
|
|
struct wl_resource *sibling_resource)
|
|
|
|
{
|
2013-06-14 19:08:02 +04:00
|
|
|
struct weston_subsurface *sub = wl_resource_get_user_data(resource);
|
2013-06-14 19:07:53 +04:00
|
|
|
struct weston_surface *surface =
|
|
|
|
wl_resource_get_user_data(sibling_resource);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
struct weston_subsurface *sibling;
|
|
|
|
|
|
|
|
if (!sub)
|
|
|
|
return;
|
|
|
|
|
|
|
|
sibling = subsurface_sibling_check(sub, surface, "place_above");
|
|
|
|
if (!sibling)
|
|
|
|
return;
|
|
|
|
|
|
|
|
wl_list_remove(&sub->parent_link_pending);
|
|
|
|
wl_list_insert(sibling->parent_link_pending.prev,
|
|
|
|
&sub->parent_link_pending);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
subsurface_place_below(struct wl_client *client,
|
|
|
|
struct wl_resource *resource,
|
|
|
|
struct wl_resource *sibling_resource)
|
|
|
|
{
|
2013-06-14 19:08:02 +04:00
|
|
|
struct weston_subsurface *sub = wl_resource_get_user_data(resource);
|
2013-06-14 19:07:53 +04:00
|
|
|
struct weston_surface *surface =
|
|
|
|
wl_resource_get_user_data(sibling_resource);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
struct weston_subsurface *sibling;
|
|
|
|
|
|
|
|
if (!sub)
|
|
|
|
return;
|
|
|
|
|
|
|
|
sibling = subsurface_sibling_check(sub, surface, "place_below");
|
|
|
|
if (!sibling)
|
|
|
|
return;
|
|
|
|
|
|
|
|
wl_list_remove(&sub->parent_link_pending);
|
|
|
|
wl_list_insert(&sibling->parent_link_pending,
|
|
|
|
&sub->parent_link_pending);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
subsurface_set_sync(struct wl_client *client, struct wl_resource *resource)
|
|
|
|
{
|
2013-06-14 19:08:02 +04:00
|
|
|
struct weston_subsurface *sub = wl_resource_get_user_data(resource);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
|
|
|
|
if (sub)
|
|
|
|
sub->synchronized = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
subsurface_set_desync(struct wl_client *client, struct wl_resource *resource)
|
|
|
|
{
|
2013-06-14 19:08:02 +04:00
|
|
|
struct weston_subsurface *sub = wl_resource_get_user_data(resource);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
|
2013-05-17 17:46:05 +04:00
|
|
|
if (sub && sub->synchronized) {
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
sub->synchronized = 0;
|
2013-05-17 17:46:05 +04:00
|
|
|
|
|
|
|
/* If sub became effectively desynchronized, flush. */
|
|
|
|
if (!weston_subsurface_is_synchronized(sub))
|
|
|
|
weston_subsurface_synchronized_commit(sub);
|
|
|
|
}
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
weston_subsurface_unlink_parent(struct weston_subsurface *sub)
|
|
|
|
{
|
|
|
|
wl_list_remove(&sub->parent_link);
|
|
|
|
wl_list_remove(&sub->parent_link_pending);
|
|
|
|
wl_list_remove(&sub->parent_destroy_listener.link);
|
|
|
|
sub->parent = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
weston_subsurface_destroy(struct weston_subsurface *sub);
|
|
|
|
|
|
|
|
static void
|
|
|
|
subsurface_handle_surface_destroy(struct wl_listener *listener, void *data)
|
|
|
|
{
|
|
|
|
struct weston_subsurface *sub =
|
|
|
|
container_of(listener, struct weston_subsurface,
|
|
|
|
surface_destroy_listener);
|
2015-04-17 14:23:38 +03:00
|
|
|
assert(data == sub->surface);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
|
|
|
|
/* The protocol object (wl_resource) is left inert. */
|
|
|
|
if (sub->resource)
|
2013-06-14 19:08:02 +04:00
|
|
|
wl_resource_set_user_data(sub->resource, NULL);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
|
|
|
|
weston_subsurface_destroy(sub);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
subsurface_handle_parent_destroy(struct wl_listener *listener, void *data)
|
|
|
|
{
|
|
|
|
struct weston_subsurface *sub =
|
|
|
|
container_of(listener, struct weston_subsurface,
|
|
|
|
parent_destroy_listener);
|
2015-04-17 14:23:38 +03:00
|
|
|
assert(data == sub->parent);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
assert(sub->surface != sub->parent);
|
|
|
|
|
|
|
|
if (weston_surface_is_mapped(sub->surface))
|
|
|
|
weston_surface_unmap(sub->surface);
|
|
|
|
|
|
|
|
weston_subsurface_unlink_parent(sub);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
subsurface_resource_destroy(struct wl_resource *resource)
|
|
|
|
{
|
2013-06-14 19:08:02 +04:00
|
|
|
struct weston_subsurface *sub = wl_resource_get_user_data(resource);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
|
|
|
|
if (sub)
|
|
|
|
weston_subsurface_destroy(sub);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
subsurface_destroy(struct wl_client *client, struct wl_resource *resource)
|
|
|
|
{
|
|
|
|
wl_resource_destroy(resource);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
weston_subsurface_link_parent(struct weston_subsurface *sub,
|
|
|
|
struct weston_surface *parent)
|
|
|
|
{
|
|
|
|
sub->parent = parent;
|
|
|
|
sub->parent_destroy_listener.notify = subsurface_handle_parent_destroy;
|
2013-06-07 07:34:41 +04:00
|
|
|
wl_signal_add(&parent->destroy_signal,
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
&sub->parent_destroy_listener);
|
|
|
|
|
|
|
|
wl_list_insert(&parent->subsurface_list, &sub->parent_link);
|
|
|
|
wl_list_insert(&parent->subsurface_list_pending,
|
|
|
|
&sub->parent_link_pending);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
weston_subsurface_link_surface(struct weston_subsurface *sub,
|
|
|
|
struct weston_surface *surface)
|
|
|
|
{
|
|
|
|
sub->surface = surface;
|
|
|
|
sub->surface_destroy_listener.notify =
|
|
|
|
subsurface_handle_surface_destroy;
|
2013-06-07 07:34:41 +04:00
|
|
|
wl_signal_add(&surface->destroy_signal,
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
&sub->surface_destroy_listener);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
weston_subsurface_destroy(struct weston_subsurface *sub)
|
|
|
|
{
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
struct weston_view *view, *next;
|
|
|
|
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
assert(sub->surface);
|
|
|
|
|
|
|
|
if (sub->resource) {
|
|
|
|
assert(weston_surface_to_subsurface(sub->surface) == sub);
|
|
|
|
assert(sub->parent_destroy_listener.notify ==
|
|
|
|
subsurface_handle_parent_destroy);
|
|
|
|
|
2014-06-13 20:10:26 +04:00
|
|
|
wl_list_for_each_safe(view, next, &sub->surface->views, surface_link) {
|
|
|
|
weston_view_unmap(view);
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_view_destroy(view);
|
2014-06-13 20:10:26 +04:00
|
|
|
}
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
if (sub->parent)
|
|
|
|
weston_subsurface_unlink_parent(sub);
|
|
|
|
|
2014-05-20 23:33:03 +04:00
|
|
|
weston_surface_state_fini(&sub->cached);
|
|
|
|
weston_buffer_reference(&sub->cached_buffer_ref, NULL);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
|
2016-08-12 11:41:33 +03:00
|
|
|
sub->surface->committed = NULL;
|
|
|
|
sub->surface->committed_private = NULL;
|
compositor: add weston_surface_set_label_func()
When printing out logs from Weston's actions, mainly for debugging, it
can be very difficult to identify the different surfaces. Inspecting
the configure function pointer is not useful, as the configure functions
may live in modules.
Add vfunc get_label to weston_surface, which will produce a short,
human-readable description of the surface, which allows identifying it
better, rather than just looking at the surface size, for instance.
Set the label function from most parts of Weston, to identify cursors and
drag icons, and panels, backgrounds, screensavers and lock surfaces, and
the desktop shell's application surfaces.
v2: renamed 'description' to 'label', so we get
weston_surface_set_label_func().
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2014-08-06 20:36:51 +04:00
|
|
|
weston_surface_set_label_func(sub->surface, NULL);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
} else {
|
|
|
|
/* the dummy weston_subsurface for the parent itself */
|
|
|
|
assert(sub->parent_destroy_listener.notify == NULL);
|
|
|
|
wl_list_remove(&sub->parent_link);
|
|
|
|
wl_list_remove(&sub->parent_link_pending);
|
|
|
|
}
|
|
|
|
|
|
|
|
wl_list_remove(&sub->surface_destroy_listener.link);
|
|
|
|
free(sub);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct wl_subsurface_interface subsurface_implementation = {
|
|
|
|
subsurface_destroy,
|
|
|
|
subsurface_set_position,
|
|
|
|
subsurface_place_above,
|
|
|
|
subsurface_place_below,
|
|
|
|
subsurface_set_sync,
|
|
|
|
subsurface_set_desync
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct weston_subsurface *
|
|
|
|
weston_subsurface_create(uint32_t id, struct weston_surface *surface,
|
|
|
|
struct weston_surface *parent)
|
|
|
|
{
|
|
|
|
struct weston_subsurface *sub;
|
2013-06-07 07:34:41 +04:00
|
|
|
struct wl_client *client = wl_resource_get_client(surface->resource);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
|
2014-11-21 09:21:57 +03:00
|
|
|
sub = zalloc(sizeof *sub);
|
|
|
|
if (sub == NULL)
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
return NULL;
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
wl_list_init(&sub->unused_views);
|
|
|
|
|
2013-06-28 05:17:02 +04:00
|
|
|
sub->resource =
|
|
|
|
wl_resource_create(client, &wl_subsurface_interface, 1, id);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
if (!sub->resource) {
|
|
|
|
free(sub);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-06-28 05:17:02 +04:00
|
|
|
wl_resource_set_implementation(sub->resource,
|
|
|
|
&subsurface_implementation,
|
|
|
|
sub, subsurface_resource_destroy);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
weston_subsurface_link_surface(sub, surface);
|
|
|
|
weston_subsurface_link_parent(sub, parent);
|
2014-05-20 23:33:03 +04:00
|
|
|
weston_surface_state_init(&sub->cached);
|
|
|
|
sub->cached_buffer_ref.buffer = NULL;
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
sub->synchronized = 1;
|
|
|
|
|
|
|
|
return sub;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create a dummy subsurface for having the parent itself in its
|
|
|
|
* sub-surface lists. Makes stacking order manipulation easy.
|
|
|
|
*/
|
|
|
|
static struct weston_subsurface *
|
|
|
|
weston_subsurface_create_for_parent(struct weston_surface *parent)
|
|
|
|
{
|
|
|
|
struct weston_subsurface *sub;
|
|
|
|
|
2014-11-21 09:21:57 +03:00
|
|
|
sub = zalloc(sizeof *sub);
|
|
|
|
if (sub == NULL)
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
weston_subsurface_link_surface(sub, parent);
|
|
|
|
sub->parent = parent;
|
|
|
|
wl_list_insert(&parent->subsurface_list, &sub->parent_link);
|
|
|
|
wl_list_insert(&parent->subsurface_list_pending,
|
|
|
|
&sub->parent_link_pending);
|
|
|
|
|
|
|
|
return sub;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
subcompositor_get_subsurface(struct wl_client *client,
|
|
|
|
struct wl_resource *resource,
|
|
|
|
uint32_t id,
|
|
|
|
struct wl_resource *surface_resource,
|
|
|
|
struct wl_resource *parent_resource)
|
|
|
|
{
|
2013-06-14 19:07:53 +04:00
|
|
|
struct weston_surface *surface =
|
|
|
|
wl_resource_get_user_data(surface_resource);
|
|
|
|
struct weston_surface *parent =
|
|
|
|
wl_resource_get_user_data(parent_resource);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
struct weston_subsurface *sub;
|
|
|
|
static const char where[] = "get_subsurface: wl_subsurface@";
|
|
|
|
|
|
|
|
if (surface == parent) {
|
|
|
|
wl_resource_post_error(resource,
|
|
|
|
WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
|
|
|
|
"%s%d: wl_surface@%d cannot be its own parent",
|
2013-06-14 19:08:02 +04:00
|
|
|
where, id, wl_resource_get_id(surface_resource));
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (weston_surface_to_subsurface(surface)) {
|
|
|
|
wl_resource_post_error(resource,
|
|
|
|
WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
|
|
|
|
"%s%d: wl_surface@%d is already a sub-surface",
|
2013-06-14 19:08:02 +04:00
|
|
|
where, id, wl_resource_get_id(surface_resource));
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
compositor: send error for surface role resets
With the more accurate definition of wl_surface roles in Wayland,
enforce the restriction: a role is always set permanently, and
attempting to change it is a protocol error.
This patch is based on Jasper's patch:
http://lists.freedesktop.org/archives/wayland-devel/2014-August/016811.html
The difference in this patch compared to his are:
- send role errors on the interface whose request triggers it, not on
wl_surface
- an interface could have several requests assigning different roles,
cannot use wl_interface as the unique key; use an arbitary string
instead
- ensure in window-manager.c that create_shell_surface() ->
create_common_surface() is never called with surface->configure set,
to avoid compositor abort
- use wl_resource_post_no_memory() where appropriate instead of
hand-rolling it with wl_resource_post_error()
Ideally we would not add weston_surface::role_name field, but use
weston_surface::configure. At the moment this is not possible though,
because at least shell.c uses several different roles with the same
configure function. Drag'n'drop uses two configure functions for the
same role. The configure hook is also reset in several places,
which is not good for role tracking.
This patch overlooks the wl_surface roles assigned in privileged
extensions: screensaver, panel, background, lock, input panel.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Reviewed-by: Jasper St. Pierre <jstpierre@mecheye.net>
2014-10-01 16:02:41 +04:00
|
|
|
if (weston_surface_set_role(surface, "wl_subsurface", resource,
|
|
|
|
WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE) < 0)
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
return;
|
|
|
|
|
2013-05-17 17:46:07 +04:00
|
|
|
if (weston_surface_get_main_surface(parent) == surface) {
|
|
|
|
wl_resource_post_error(resource,
|
|
|
|
WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
|
|
|
|
"%s%d: wl_surface@%d is an ancestor of parent",
|
2013-06-14 19:08:02 +04:00
|
|
|
where, id, wl_resource_get_id(surface_resource));
|
2013-05-17 17:46:07 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
/* make sure the parent is in its own list */
|
|
|
|
if (wl_list_empty(&parent->subsurface_list)) {
|
|
|
|
if (!weston_subsurface_create_for_parent(parent)) {
|
|
|
|
wl_resource_post_no_memory(resource);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sub = weston_subsurface_create(id, surface, parent);
|
|
|
|
if (!sub) {
|
|
|
|
wl_resource_post_no_memory(resource);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-08-12 11:41:33 +03:00
|
|
|
surface->committed = subsurface_committed;
|
|
|
|
surface->committed_private = sub;
|
compositor: add weston_surface_set_label_func()
When printing out logs from Weston's actions, mainly for debugging, it
can be very difficult to identify the different surfaces. Inspecting
the configure function pointer is not useful, as the configure functions
may live in modules.
Add vfunc get_label to weston_surface, which will produce a short,
human-readable description of the surface, which allows identifying it
better, rather than just looking at the surface size, for instance.
Set the label function from most parts of Weston, to identify cursors and
drag icons, and panels, backgrounds, screensavers and lock surfaces, and
the desktop shell's application surfaces.
v2: renamed 'description' to 'label', so we get
weston_surface_set_label_func().
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2014-08-06 20:36:51 +04:00
|
|
|
weston_surface_set_label_func(surface, subsurface_get_label);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
subcompositor_destroy(struct wl_client *client, struct wl_resource *resource)
|
|
|
|
{
|
|
|
|
wl_resource_destroy(resource);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct wl_subcompositor_interface subcompositor_interface = {
|
|
|
|
subcompositor_destroy,
|
|
|
|
subcompositor_get_subsurface
|
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
bind_subcompositor(struct wl_client *client,
|
|
|
|
void *data, uint32_t version, uint32_t id)
|
|
|
|
{
|
|
|
|
struct weston_compositor *compositor = data;
|
2013-06-28 05:17:02 +04:00
|
|
|
struct wl_resource *resource;
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
|
2013-06-28 05:17:02 +04:00
|
|
|
resource =
|
|
|
|
wl_resource_create(client, &wl_subcompositor_interface, 1, id);
|
2013-08-07 03:46:25 +04:00
|
|
|
if (resource == NULL) {
|
|
|
|
wl_client_post_no_memory(client);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
wl_resource_set_implementation(resource, &subcompositor_interface,
|
|
|
|
compositor, NULL);
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
}
|
|
|
|
|
2016-08-30 22:04:26 +03:00
|
|
|
/** Set a DPMS mode on all of the compositor's outputs
|
2015-12-12 00:11:38 +03:00
|
|
|
*
|
|
|
|
* \param compositor The compositor instance
|
|
|
|
* \param state The DPMS state the outputs will be set to
|
|
|
|
*/
|
2012-02-29 21:53:50 +04:00
|
|
|
static void
|
2013-02-21 20:35:22 +04:00
|
|
|
weston_compositor_dpms(struct weston_compositor *compositor,
|
|
|
|
enum dpms_enum state)
|
2012-02-29 21:53:50 +04:00
|
|
|
{
|
|
|
|
struct weston_output *output;
|
|
|
|
|
2016-08-30 22:05:16 +03:00
|
|
|
wl_list_for_each(output, &compositor->output_list, link)
|
|
|
|
if (output->set_dpms)
|
|
|
|
output->set_dpms(output, state);
|
2012-02-29 21:53:50 +04:00
|
|
|
}
|
|
|
|
|
2015-12-12 00:11:38 +03:00
|
|
|
/** Restores the compositor to active status
|
|
|
|
*
|
|
|
|
* \param compositor The compositor instance
|
|
|
|
*
|
|
|
|
* If the compositor was in a sleeping mode, all outputs are powered
|
|
|
|
* back on via DPMS. Otherwise if the compositor was inactive
|
|
|
|
* (idle/locked, offscreen, or sleeping) then the compositor's wake
|
|
|
|
* signal will fire.
|
|
|
|
*
|
|
|
|
* Restarts the idle timer.
|
|
|
|
*/
|
2011-11-15 15:34:49 +04:00
|
|
|
WL_EXPORT void
|
2013-02-21 20:35:22 +04:00
|
|
|
weston_compositor_wake(struct weston_compositor *compositor)
|
2011-11-15 15:34:49 +04:00
|
|
|
{
|
2013-09-30 16:14:47 +04:00
|
|
|
uint32_t old_state = compositor->state;
|
|
|
|
|
|
|
|
/* The state needs to be changed before emitting the wake
|
|
|
|
* signal because that may try to schedule a repaint which
|
|
|
|
* will not work if the compositor is still sleeping */
|
|
|
|
compositor->state = WESTON_COMPOSITOR_ACTIVE;
|
|
|
|
|
|
|
|
switch (old_state) {
|
2013-02-21 20:35:22 +04:00
|
|
|
case WESTON_COMPOSITOR_SLEEPING:
|
|
|
|
case WESTON_COMPOSITOR_IDLE:
|
2013-03-29 16:01:56 +04:00
|
|
|
case WESTON_COMPOSITOR_OFFSCREEN:
|
2016-11-08 18:47:09 +03:00
|
|
|
weston_compositor_dpms(compositor, WESTON_DPMS_ON);
|
2013-02-21 20:35:23 +04:00
|
|
|
wl_signal_emit(&compositor->wake_signal, compositor);
|
2013-02-21 20:35:22 +04:00
|
|
|
/* fall through */
|
|
|
|
default:
|
|
|
|
wl_event_source_timer_update(compositor->idle_source,
|
|
|
|
compositor->idle_time * 1000);
|
2011-11-15 15:34:49 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-12 00:11:38 +03:00
|
|
|
/** Turns off rendering and frame events for the compositor.
|
|
|
|
*
|
|
|
|
* \param compositor The compositor instance
|
|
|
|
*
|
|
|
|
* This is used for example to prevent further rendering while the
|
|
|
|
* compositor is shutting down.
|
|
|
|
*
|
|
|
|
* Stops the idle timer.
|
|
|
|
*/
|
2013-03-29 16:01:56 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_compositor_offscreen(struct weston_compositor *compositor)
|
|
|
|
{
|
|
|
|
switch (compositor->state) {
|
|
|
|
case WESTON_COMPOSITOR_OFFSCREEN:
|
|
|
|
return;
|
|
|
|
case WESTON_COMPOSITOR_SLEEPING:
|
|
|
|
default:
|
|
|
|
compositor->state = WESTON_COMPOSITOR_OFFSCREEN;
|
|
|
|
wl_event_source_timer_update(compositor->idle_source, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-12 00:11:38 +03:00
|
|
|
/** Powers down all attached output devices
|
|
|
|
*
|
|
|
|
* \param compositor The compositor instance
|
|
|
|
*
|
|
|
|
* Causes rendering to the outputs to cease, and no frame events to be
|
|
|
|
* sent. Only powers down the outputs if the compositor is not already
|
|
|
|
* in sleep mode.
|
|
|
|
*
|
|
|
|
* Stops the idle timer.
|
|
|
|
*/
|
2013-02-21 20:35:22 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_compositor_sleep(struct weston_compositor *compositor)
|
|
|
|
{
|
|
|
|
if (compositor->state == WESTON_COMPOSITOR_SLEEPING)
|
|
|
|
return;
|
|
|
|
|
2013-03-29 16:01:56 +04:00
|
|
|
wl_event_source_timer_update(compositor->idle_source, 0);
|
2013-02-21 20:35:22 +04:00
|
|
|
compositor->state = WESTON_COMPOSITOR_SLEEPING;
|
|
|
|
weston_compositor_dpms(compositor, WESTON_DPMS_OFF);
|
|
|
|
}
|
|
|
|
|
2015-12-12 00:11:38 +03:00
|
|
|
/** Sets compositor to idle mode
|
|
|
|
*
|
|
|
|
* \param data The compositor instance
|
|
|
|
*
|
|
|
|
* This is called when the idle timer fires. Once the compositor is in
|
|
|
|
* idle mode it requires a wake action (e.g. via
|
|
|
|
* weston_compositor_wake()) to restore it. The compositor's
|
|
|
|
* idle_signal will be triggered when the idle event occurs.
|
|
|
|
*
|
|
|
|
* Idleness can be inhibited by setting the compositor's idle_inhibit
|
|
|
|
* property.
|
|
|
|
*/
|
2011-04-22 22:01:18 +04:00
|
|
|
static int
|
|
|
|
idle_handler(void *data)
|
|
|
|
{
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
struct weston_compositor *compositor = data;
|
2011-04-22 22:01:18 +04:00
|
|
|
|
|
|
|
if (compositor->idle_inhibit)
|
|
|
|
return 1;
|
|
|
|
|
compositor: Move fade animation out of core Weston into shell
Previously, it was impossible to override the fade in/out behavior of
Weston using a different shell, since this was implemented in core
Weston. This also led to complicated interaction between the shell and
the core when displaying lock surfaces and screensavers.
This patch starts to solve this issue by moving the fade animation out
of the core. On compositor.c, besides deleting the fade code, the idle
handler had to be changed to emit the lock signal, since it was called
from the fade_frame() function before. This causes a slight change of
behavior, since before the fade would happen with the compositor being
active, while now it is already in the idle state. That leads to the
dpms state being set when cancelling the fade with mouse movement, and
in turn, to a slight freeze with drm compositor. This problem will be
fixed in a follow up patch.
On the shell side, the fade was re-implemented in a slightly different
manner. Instead of using a custom frame function, the fade animation
from animation.c is used. The interface for starting the fade was also
changed to take the value of an enum instead of a float alpha value,
in order to improve readability.
2013-02-21 20:35:20 +04:00
|
|
|
compositor->state = WESTON_COMPOSITOR_IDLE;
|
2013-02-21 20:35:23 +04:00
|
|
|
wl_signal_emit(&compositor->idle_signal, compositor);
|
2011-04-22 22:01:18 +04:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2012-08-03 19:30:18 +04:00
|
|
|
WL_EXPORT void
|
2013-10-23 09:58:31 +04:00
|
|
|
weston_plane_init(struct weston_plane *plane,
|
|
|
|
struct weston_compositor *ec,
|
|
|
|
int32_t x, int32_t y)
|
2012-08-03 19:30:18 +04:00
|
|
|
{
|
|
|
|
pixman_region32_init(&plane->damage);
|
2013-03-05 19:30:29 +04:00
|
|
|
pixman_region32_init(&plane->clip);
|
2012-08-03 19:30:18 +04:00
|
|
|
plane->x = x;
|
|
|
|
plane->y = y;
|
2013-10-23 09:58:31 +04:00
|
|
|
plane->compositor = ec;
|
2013-07-05 17:05:26 +04:00
|
|
|
|
|
|
|
/* Init the link so that the call to wl_list_remove() when releasing
|
|
|
|
* the plane without ever stacking doesn't lead to a crash */
|
|
|
|
wl_list_init(&plane->link);
|
2012-08-03 19:30:18 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
WL_EXPORT void
|
|
|
|
weston_plane_release(struct weston_plane *plane)
|
|
|
|
{
|
2013-10-23 09:58:31 +04:00
|
|
|
struct weston_view *view;
|
|
|
|
|
2012-08-03 19:30:18 +04:00
|
|
|
pixman_region32_fini(&plane->damage);
|
2013-03-05 19:30:29 +04:00
|
|
|
pixman_region32_fini(&plane->clip);
|
2013-07-05 17:05:26 +04:00
|
|
|
|
2013-10-23 09:58:31 +04:00
|
|
|
wl_list_for_each(view, &plane->compositor->view_list, link) {
|
|
|
|
if (view->plane == plane)
|
|
|
|
view->plane = NULL;
|
|
|
|
}
|
|
|
|
|
2013-07-05 17:05:26 +04:00
|
|
|
wl_list_remove(&plane->link);
|
2012-08-03 19:30:18 +04:00
|
|
|
}
|
|
|
|
|
2013-03-05 19:30:27 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_compositor_stack_plane(struct weston_compositor *ec,
|
|
|
|
struct weston_plane *plane,
|
|
|
|
struct weston_plane *above)
|
|
|
|
{
|
|
|
|
if (above)
|
|
|
|
wl_list_insert(above->link.prev, &plane->link);
|
|
|
|
else
|
|
|
|
wl_list_insert(&ec->plane_list, &plane->link);
|
|
|
|
}
|
|
|
|
|
2016-07-05 21:44:33 +03:00
|
|
|
static void
|
|
|
|
output_release(struct wl_client *client, struct wl_resource *resource)
|
|
|
|
{
|
|
|
|
wl_resource_destroy(resource);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct wl_output_interface output_interface = {
|
|
|
|
output_release,
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2012-04-20 06:50:09 +04:00
|
|
|
static void unbind_resource(struct wl_resource *resource)
|
2011-10-12 06:20:37 +04:00
|
|
|
{
|
2013-06-14 19:08:01 +04:00
|
|
|
wl_list_remove(wl_resource_get_link(resource));
|
2011-10-12 06:20:37 +04:00
|
|
|
}
|
|
|
|
|
2009-01-01 00:18:42 +03:00
|
|
|
static void
|
2011-08-27 01:21:20 +04:00
|
|
|
bind_output(struct wl_client *client,
|
|
|
|
void *data, uint32_t version, uint32_t id)
|
2009-01-01 00:18:42 +03:00
|
|
|
{
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
struct weston_output *output = data;
|
|
|
|
struct weston_mode *mode;
|
2011-08-29 23:03:09 +04:00
|
|
|
struct wl_resource *resource;
|
|
|
|
|
2013-06-28 05:17:02 +04:00
|
|
|
resource = wl_resource_create(client, &wl_output_interface,
|
2015-11-26 23:17:47 +03:00
|
|
|
version, id);
|
2013-08-07 03:46:25 +04:00
|
|
|
if (resource == NULL) {
|
|
|
|
wl_client_post_no_memory(client);
|
|
|
|
return;
|
|
|
|
}
|
2009-01-01 00:18:42 +03:00
|
|
|
|
2013-06-14 19:08:01 +04:00
|
|
|
wl_list_insert(&output->resource_list, wl_resource_get_link(resource));
|
2016-07-05 21:44:33 +03:00
|
|
|
wl_resource_set_implementation(resource, &output_interface, data, unbind_resource);
|
2012-04-20 06:50:09 +04:00
|
|
|
|
2012-03-05 06:57:37 +04:00
|
|
|
wl_output_send_geometry(resource,
|
|
|
|
output->x,
|
|
|
|
output->y,
|
|
|
|
output->mm_width,
|
|
|
|
output->mm_height,
|
|
|
|
output->subpixel,
|
2012-07-22 23:49:57 +04:00
|
|
|
output->make, output->model,
|
2012-08-10 18:09:20 +04:00
|
|
|
output->transform);
|
2014-08-08 00:43:11 +04:00
|
|
|
if (version >= WL_OUTPUT_SCALE_SINCE_VERSION)
|
2013-05-22 16:41:37 +04:00
|
|
|
wl_output_send_scale(resource,
|
2013-09-19 01:56:35 +04:00
|
|
|
output->current_scale);
|
2011-06-21 19:16:58 +04:00
|
|
|
|
|
|
|
wl_list_for_each (mode, &output->mode_list, link) {
|
2012-03-05 06:57:37 +04:00
|
|
|
wl_output_send_mode(resource,
|
|
|
|
mode->flags,
|
|
|
|
mode->width,
|
|
|
|
mode->height,
|
|
|
|
mode->refresh);
|
2011-06-21 19:16:58 +04:00
|
|
|
}
|
2013-05-22 16:41:37 +04:00
|
|
|
|
2014-08-08 00:43:11 +04:00
|
|
|
if (version >= WL_OUTPUT_DONE_SINCE_VERSION)
|
2013-05-22 16:41:37 +04:00
|
|
|
wl_output_send_done(resource);
|
2009-01-01 00:18:42 +03:00
|
|
|
}
|
|
|
|
|
2016-05-28 00:22:57 +03:00
|
|
|
/* Move other outputs when one is resized so the space remains contiguous. */
|
2013-12-14 00:10:51 +04:00
|
|
|
static void
|
2016-05-28 00:22:57 +03:00
|
|
|
weston_compositor_reflow_outputs(struct weston_compositor *compositor,
|
|
|
|
struct weston_output *resized_output, int delta_width)
|
2013-12-14 00:10:51 +04:00
|
|
|
{
|
|
|
|
struct weston_output *output;
|
2016-05-28 00:22:57 +03:00
|
|
|
bool start_resizing = false;
|
|
|
|
|
|
|
|
if (!delta_width)
|
|
|
|
return;
|
2013-12-14 00:10:51 +04:00
|
|
|
|
|
|
|
wl_list_for_each(output, &compositor->output_list, link) {
|
2016-05-28 00:22:57 +03:00
|
|
|
if (output == resized_output) {
|
|
|
|
start_resizing = true;
|
2013-12-14 00:10:51 +04:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2016-05-28 00:22:57 +03:00
|
|
|
if (start_resizing) {
|
|
|
|
weston_output_move(output, output->x + delta_width, output->y);
|
2013-12-14 00:10:51 +04:00
|
|
|
output->dirty = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-23 01:21:41 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_output_update_matrix(struct weston_output *output)
|
|
|
|
{
|
2012-05-22 01:21:25 +04:00
|
|
|
float magnification;
|
2010-06-14 19:54:00 +04:00
|
|
|
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
weston_matrix_init(&output->matrix);
|
2014-10-16 19:55:21 +04:00
|
|
|
weston_matrix_translate(&output->matrix, -output->x, -output->y, 0);
|
2012-08-18 11:04:05 +04:00
|
|
|
|
2012-02-23 01:21:41 +04:00
|
|
|
if (output->zoom.active) {
|
2012-06-11 23:07:51 +04:00
|
|
|
magnification = 1 / (1 - output->zoom.spring_z.current);
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
weston_output_update_zoom(output);
|
2014-04-25 16:19:37 +04:00
|
|
|
weston_matrix_translate(&output->matrix, -output->zoom.trans_x,
|
2014-10-16 19:55:21 +04:00
|
|
|
-output->zoom.trans_y, 0);
|
2014-04-25 16:19:37 +04:00
|
|
|
weston_matrix_scale(&output->matrix, magnification,
|
|
|
|
magnification, 1.0);
|
2012-02-23 01:21:41 +04:00
|
|
|
}
|
2010-06-14 19:54:00 +04:00
|
|
|
|
2014-10-16 19:55:21 +04:00
|
|
|
switch (output->transform) {
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED:
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
|
|
|
|
weston_matrix_translate(&output->matrix, -output->width, 0, 0);
|
|
|
|
weston_matrix_scale(&output->matrix, -1, 1, 1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (output->transform) {
|
|
|
|
default:
|
|
|
|
case WL_OUTPUT_TRANSFORM_NORMAL:
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED:
|
|
|
|
break;
|
|
|
|
case WL_OUTPUT_TRANSFORM_90:
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
|
|
|
|
weston_matrix_translate(&output->matrix, 0, -output->height, 0);
|
|
|
|
weston_matrix_rotate_xy(&output->matrix, 0, 1);
|
|
|
|
break;
|
|
|
|
case WL_OUTPUT_TRANSFORM_180:
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
|
|
|
|
weston_matrix_translate(&output->matrix,
|
|
|
|
-output->width, -output->height, 0);
|
|
|
|
weston_matrix_rotate_xy(&output->matrix, -1, 0);
|
|
|
|
break;
|
|
|
|
case WL_OUTPUT_TRANSFORM_270:
|
|
|
|
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
|
|
|
|
weston_matrix_translate(&output->matrix, -output->width, 0, 0);
|
|
|
|
weston_matrix_rotate_xy(&output->matrix, 0, -1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (output->current_scale != 1)
|
|
|
|
weston_matrix_scale(&output->matrix,
|
|
|
|
output->current_scale,
|
|
|
|
output->current_scale, 1);
|
2014-05-06 22:04:15 +04:00
|
|
|
|
2012-02-23 01:21:41 +04:00
|
|
|
output->dirty = 0;
|
2015-03-24 19:36:13 +03:00
|
|
|
|
|
|
|
weston_matrix_invert(&output->inverse_matrix, &output->matrix);
|
2012-02-23 01:21:41 +04:00
|
|
|
}
|
|
|
|
|
2012-08-18 11:04:05 +04:00
|
|
|
static void
|
2013-05-28 18:23:36 +04:00
|
|
|
weston_output_transform_scale_init(struct weston_output *output, uint32_t transform, uint32_t scale)
|
2012-08-18 11:04:05 +04:00
|
|
|
{
|
|
|
|
output->transform = transform;
|
2016-04-26 15:50:59 +03:00
|
|
|
output->native_scale = scale;
|
|
|
|
output->current_scale = scale;
|
2012-08-18 11:04:05 +04:00
|
|
|
|
2016-04-26 15:50:59 +03:00
|
|
|
convert_size_by_transform_scale(&output->width, &output->height,
|
|
|
|
output->current_mode->width,
|
|
|
|
output->current_mode->height,
|
|
|
|
transform, scale);
|
2013-05-22 16:41:37 +04:00
|
|
|
}
|
|
|
|
|
2013-12-14 00:10:53 +04:00
|
|
|
static void
|
|
|
|
weston_output_init_geometry(struct weston_output *output, int x, int y)
|
2012-02-23 01:21:41 +04:00
|
|
|
{
|
|
|
|
output->x = x;
|
|
|
|
output->y = y;
|
|
|
|
|
2012-11-16 19:23:52 +04:00
|
|
|
pixman_region32_init(&output->previous_damage);
|
2012-02-23 01:21:41 +04:00
|
|
|
pixman_region32_init_rect(&output->region, x, y,
|
2012-08-18 11:04:05 +04:00
|
|
|
output->width,
|
|
|
|
output->height);
|
2011-03-15 17:08:41 +03:00
|
|
|
}
|
|
|
|
|
2013-12-14 00:10:53 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_output_move(struct weston_output *output, int x, int y)
|
|
|
|
{
|
|
|
|
struct wl_resource *resource;
|
|
|
|
|
|
|
|
output->move_x = x - output->x;
|
|
|
|
output->move_y = y - output->y;
|
|
|
|
|
|
|
|
if (output->move_x == 0 && output->move_y == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
weston_output_init_geometry(output, x, y);
|
|
|
|
|
|
|
|
output->dirty = 1;
|
|
|
|
|
|
|
|
/* Move views on this output. */
|
2014-01-29 20:47:52 +04:00
|
|
|
wl_signal_emit(&output->compositor->output_moved_signal, output);
|
2013-12-14 00:10:53 +04:00
|
|
|
|
|
|
|
/* Notify clients of the change for output position. */
|
2014-03-14 05:16:25 +04:00
|
|
|
wl_resource_for_each(resource, &output->resource_list) {
|
2013-12-14 00:10:53 +04:00
|
|
|
wl_output_send_geometry(resource,
|
|
|
|
output->x,
|
|
|
|
output->y,
|
|
|
|
output->mm_width,
|
|
|
|
output->mm_height,
|
|
|
|
output->subpixel,
|
|
|
|
output->make,
|
|
|
|
output->model,
|
|
|
|
output->transform);
|
2014-03-14 05:16:25 +04:00
|
|
|
|
2016-04-27 00:34:06 +03:00
|
|
|
if (wl_resource_get_version(resource) >= WL_OUTPUT_DONE_SINCE_VERSION)
|
2014-03-14 05:16:25 +04:00
|
|
|
wl_output_send_done(resource);
|
|
|
|
}
|
2013-12-14 00:10:53 +04:00
|
|
|
}
|
|
|
|
|
2015-05-06 21:41:57 +03:00
|
|
|
/** Adds an output to the compositor's output list and
|
|
|
|
* send the compositor's output_created signal.
|
|
|
|
*
|
|
|
|
* \param compositor The compositor instance.
|
|
|
|
* \param output The output to be added.
|
|
|
|
*/
|
|
|
|
WL_EXPORT void
|
|
|
|
weston_compositor_add_output(struct weston_compositor *compositor,
|
|
|
|
struct weston_output *output)
|
|
|
|
{
|
2016-08-05 16:28:29 +03:00
|
|
|
struct weston_view *view, *next;
|
|
|
|
|
2015-05-06 21:41:57 +03:00
|
|
|
wl_list_insert(compositor->output_list.prev, &output->link);
|
|
|
|
wl_signal_emit(&compositor->output_created_signal, output);
|
2016-08-05 16:28:29 +03:00
|
|
|
|
|
|
|
wl_list_for_each_safe(view, next, &compositor->view_list, link)
|
|
|
|
weston_view_geometry_dirty(view);
|
2010-06-14 19:54:00 +04:00
|
|
|
}
|
|
|
|
|
2013-07-23 01:33:42 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_output_transform_coordinate(struct weston_output *output,
|
2016-03-22 18:44:54 +03:00
|
|
|
double device_x, double device_y,
|
|
|
|
double *x, double *y)
|
2013-07-23 01:33:42 +04:00
|
|
|
{
|
2014-10-02 22:41:17 +04:00
|
|
|
struct weston_vector p = { {
|
2016-03-22 18:44:54 +03:00
|
|
|
device_x,
|
|
|
|
device_y,
|
2014-10-02 22:41:17 +04:00
|
|
|
0.0,
|
|
|
|
1.0 } };
|
2013-07-23 01:33:42 +04:00
|
|
|
|
2015-03-24 19:36:14 +03:00
|
|
|
weston_matrix_transform(&output->inverse_matrix, &p);
|
2013-07-23 01:33:42 +04:00
|
|
|
|
2016-03-22 18:44:54 +03:00
|
|
|
*x = p.f[0] / p.f[3];
|
|
|
|
*y = p.f[1] / p.f[3];
|
2013-07-23 01:33:42 +04:00
|
|
|
}
|
|
|
|
|
2016-09-30 15:11:02 +03:00
|
|
|
/** Undoes changes to an output done by weston_output_enable()
|
|
|
|
*
|
|
|
|
* \param output The weston_output object that needs the changes undone.
|
|
|
|
*
|
|
|
|
* Removes the repaint timer.
|
|
|
|
* Destroys the Wayland global assigned to the output.
|
|
|
|
* Destroys pixman regions allocated to the output.
|
|
|
|
* Deallocates output's ID and updates compositor's output_id_pool.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
weston_output_enable_undo(struct weston_output *output)
|
|
|
|
{
|
|
|
|
wl_event_source_remove(output->repaint_timer);
|
|
|
|
|
|
|
|
wl_global_destroy(output->global);
|
|
|
|
|
|
|
|
pixman_region32_fini(&output->region);
|
|
|
|
pixman_region32_fini(&output->previous_damage);
|
|
|
|
output->compositor->output_id_pool &= ~(1u << output->id);
|
|
|
|
|
|
|
|
output->enabled = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Removes output from compositor's output list
|
|
|
|
*
|
|
|
|
* \param output The weston_output object that is being removed.
|
|
|
|
*
|
|
|
|
* Presentation feedback is discarded.
|
|
|
|
* Compositor is notified that outputs were changed and
|
|
|
|
* applies the necessary changes.
|
|
|
|
* All views assigned to the weston_output object are
|
|
|
|
* moved to a new output.
|
|
|
|
* Signal is emited to notify all users of the weston_output
|
|
|
|
* object that the output is being destroyed.
|
|
|
|
* wl_output protocol objects referencing this weston_output
|
|
|
|
* are made inert.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
weston_compositor_remove_output(struct weston_output *output)
|
|
|
|
{
|
|
|
|
struct wl_resource *resource;
|
|
|
|
struct weston_view *view;
|
|
|
|
|
|
|
|
assert(output->destroying);
|
|
|
|
|
|
|
|
wl_list_for_each(view, &output->compositor->view_list, link) {
|
|
|
|
if (view->output_mask & (1u << output->id))
|
|
|
|
weston_view_assign_output(view);
|
|
|
|
}
|
|
|
|
|
|
|
|
weston_presentation_feedback_discard_list(&output->feedback_list);
|
|
|
|
|
|
|
|
weston_compositor_reflow_outputs(output->compositor, output, output->width);
|
|
|
|
wl_list_remove(&output->link);
|
|
|
|
|
|
|
|
wl_signal_emit(&output->compositor->output_destroyed_signal, output);
|
|
|
|
wl_signal_emit(&output->destroy_signal, output);
|
|
|
|
|
|
|
|
wl_resource_for_each(resource, &output->resource_list) {
|
|
|
|
wl_resource_set_destructor(resource, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Sets the output scale for a given output.
|
|
|
|
*
|
|
|
|
* \param output The weston_output object that the scale is set for.
|
|
|
|
* \param scale Scale factor for the given output.
|
|
|
|
*
|
|
|
|
* It only supports setting scale for an output that
|
|
|
|
* is not enabled and it can only be ran once.
|
|
|
|
*/
|
|
|
|
WL_EXPORT void
|
|
|
|
weston_output_set_scale(struct weston_output *output,
|
|
|
|
int32_t scale)
|
|
|
|
{
|
|
|
|
/* We can only set scale on a disabled output */
|
|
|
|
assert(!output->enabled);
|
|
|
|
|
|
|
|
/* We only want to set scale once */
|
|
|
|
assert(!output->scale);
|
|
|
|
|
|
|
|
output->scale = scale;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Sets the output transform for a given output.
|
|
|
|
*
|
|
|
|
* \param output The weston_output object that the transform is set for.
|
|
|
|
* \param transform Transform value for the given output.
|
|
|
|
*
|
|
|
|
* It only supports setting transform for an output that is
|
|
|
|
* not enabled and it can only be ran once.
|
|
|
|
*
|
|
|
|
* Refer to wl_output::transform section located at
|
|
|
|
* https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_output
|
|
|
|
* for list of values that can be passed to this function.
|
|
|
|
*/
|
|
|
|
WL_EXPORT void
|
|
|
|
weston_output_set_transform(struct weston_output *output,
|
|
|
|
uint32_t transform)
|
|
|
|
{
|
|
|
|
/* We can only set transform on a disabled output */
|
|
|
|
assert(!output->enabled);
|
|
|
|
|
|
|
|
/* We only want to set transform once */
|
|
|
|
assert(output->transform == UINT32_MAX);
|
|
|
|
|
|
|
|
output->transform = transform;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Initializes a weston_output object with enough data so
|
|
|
|
** an output can be configured.
|
|
|
|
*
|
|
|
|
* \param output The weston_output object to initialize
|
|
|
|
* \param compositor The compositor instance.
|
|
|
|
*
|
|
|
|
* Sets initial values for fields that are expected to be
|
|
|
|
* configured either by compositors or backends.
|
|
|
|
*/
|
|
|
|
WL_EXPORT void
|
2016-09-30 15:11:12 +03:00
|
|
|
weston_output_init(struct weston_output *output,
|
|
|
|
struct weston_compositor *compositor)
|
2016-09-30 15:11:02 +03:00
|
|
|
{
|
|
|
|
output->compositor = compositor;
|
|
|
|
output->destroying = 0;
|
|
|
|
|
|
|
|
/* Backends must set output->name */
|
|
|
|
assert(output->name);
|
|
|
|
|
|
|
|
wl_list_init(&output->link);
|
|
|
|
|
|
|
|
output->enabled = false;
|
|
|
|
|
|
|
|
/* Add some (in)sane defaults which can be used
|
|
|
|
* for checking if an output was properly configured
|
|
|
|
*/
|
|
|
|
output->mm_width = 0;
|
|
|
|
output->mm_height = 0;
|
|
|
|
output->scale = 0;
|
|
|
|
/* Can't use -1 on uint32_t and 0 is valid enum value */
|
|
|
|
output->transform = UINT32_MAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Adds weston_output object to pending output list.
|
|
|
|
*
|
|
|
|
* \param output The weston_output object to add
|
|
|
|
* \param compositor The compositor instance.
|
|
|
|
*
|
|
|
|
* Also notifies the compositor that an output is pending for
|
|
|
|
* configuration.
|
|
|
|
*/
|
|
|
|
WL_EXPORT void
|
|
|
|
weston_compositor_add_pending_output(struct weston_output *output,
|
|
|
|
struct weston_compositor *compositor)
|
|
|
|
{
|
|
|
|
wl_list_insert(compositor->pending_output_list.prev, &output->link);
|
|
|
|
wl_signal_emit(&compositor->output_pending_signal, output);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Constructs a weston_output object that can be used by the compositor.
|
|
|
|
*
|
|
|
|
* \param output The weston_output object that needs to be enabled.
|
|
|
|
*
|
|
|
|
* Output coordinates are calculated and each new output is by default
|
|
|
|
* assigned to the right of previous one.
|
|
|
|
*
|
|
|
|
* Sets up the transformation, zoom, and geometry of the output using
|
|
|
|
* the properties that need to be configured by the compositor.
|
|
|
|
*
|
|
|
|
* Establishes a repaint timer for the output with the relevant display
|
|
|
|
* object's event loop. See output_repaint_timer_handler().
|
|
|
|
*
|
|
|
|
* The output is assigned an ID. Weston can support up to 32 distinct
|
|
|
|
* outputs, with IDs numbered from 0-31; the compositor's output_id_pool
|
|
|
|
* is referred to and used to find the first available ID number, and
|
|
|
|
* then this ID is marked as used in output_id_pool.
|
|
|
|
*
|
|
|
|
* The output is also assigned a Wayland global with the wl_output
|
|
|
|
* external interface.
|
|
|
|
*
|
|
|
|
* Backend specific function is called to set up the output output.
|
|
|
|
*
|
|
|
|
* Output is added to the compositor's output list
|
|
|
|
*
|
|
|
|
* If the backend specific function fails, the weston_output object
|
|
|
|
* is returned to a state it was before calling this function and
|
|
|
|
* is added to the compositor's pending_output_list in case it needs
|
|
|
|
* to be reconfigured or just so it can be destroyed at shutdown.
|
|
|
|
*
|
|
|
|
* 0 is returned on success, -1 on failure.
|
|
|
|
*/
|
|
|
|
WL_EXPORT int
|
|
|
|
weston_output_enable(struct weston_output *output)
|
|
|
|
{
|
2016-09-30 15:11:11 +03:00
|
|
|
struct weston_compositor *c = output->compositor;
|
2016-09-30 15:11:02 +03:00
|
|
|
struct weston_output *iterator;
|
2016-09-30 15:11:11 +03:00
|
|
|
struct wl_event_loop *loop;
|
2016-09-30 15:11:02 +03:00
|
|
|
int x = 0, y = 0;
|
|
|
|
|
|
|
|
assert(output->enable);
|
|
|
|
|
2016-09-30 15:11:11 +03:00
|
|
|
iterator = container_of(c->output_list.prev,
|
2016-09-30 15:11:02 +03:00
|
|
|
struct weston_output, link);
|
|
|
|
|
2016-09-30 15:11:11 +03:00
|
|
|
if (!wl_list_empty(&c->output_list))
|
2016-09-30 15:11:02 +03:00
|
|
|
x = iterator->x + iterator->width;
|
|
|
|
|
|
|
|
/* Make sure the scale is set up */
|
|
|
|
assert(output->scale);
|
|
|
|
|
|
|
|
/* Make sure we have a transform set */
|
|
|
|
assert(output->transform != UINT32_MAX);
|
|
|
|
|
|
|
|
/* Remove it from pending/disabled output list */
|
|
|
|
wl_list_remove(&output->link);
|
|
|
|
|
2016-09-30 15:11:11 +03:00
|
|
|
/* Verify we haven't reached the limit of 32 available output IDs */
|
|
|
|
assert(ffs(~c->output_id_pool) > 0);
|
|
|
|
|
|
|
|
output->x = x;
|
|
|
|
output->y = y;
|
|
|
|
output->dirty = 1;
|
|
|
|
output->original_scale = output->scale;
|
|
|
|
|
|
|
|
weston_output_transform_scale_init(output, output->transform, output->scale);
|
|
|
|
weston_output_init_zoom(output);
|
|
|
|
|
|
|
|
weston_output_init_geometry(output, x, y);
|
|
|
|
weston_output_damage(output);
|
|
|
|
|
|
|
|
wl_signal_init(&output->frame_signal);
|
|
|
|
wl_signal_init(&output->destroy_signal);
|
|
|
|
wl_list_init(&output->animation_list);
|
|
|
|
wl_list_init(&output->resource_list);
|
|
|
|
wl_list_init(&output->feedback_list);
|
|
|
|
wl_list_init(&output->link);
|
|
|
|
|
|
|
|
loop = wl_display_get_event_loop(c->wl_display);
|
|
|
|
output->repaint_timer = wl_event_loop_add_timer(loop,
|
|
|
|
output_repaint_timer_handler, output);
|
|
|
|
|
|
|
|
/* Invert the output id pool and look for the lowest numbered
|
|
|
|
* switch (the least significant bit). Take that bit's position
|
|
|
|
* as our ID, and mark it used in the compositor's output_id_pool.
|
|
|
|
*/
|
|
|
|
output->id = ffs(~output->compositor->output_id_pool) - 1;
|
|
|
|
output->compositor->output_id_pool |= 1u << output->id;
|
|
|
|
|
|
|
|
output->global =
|
|
|
|
wl_global_create(c->wl_display, &wl_output_interface, 3,
|
|
|
|
output, bind_output);
|
|
|
|
|
|
|
|
output->enabled = true;
|
2016-09-30 15:11:02 +03:00
|
|
|
|
|
|
|
/* Enable the output (set up the crtc or create a
|
|
|
|
* window representing the output, set up the
|
|
|
|
* renderer, etc)
|
|
|
|
*/
|
|
|
|
if (output->enable(output) < 0) {
|
|
|
|
weston_log("Enabling output \"%s\" failed.\n", output->name);
|
|
|
|
|
|
|
|
weston_output_enable_undo(output);
|
|
|
|
wl_list_insert(output->compositor->pending_output_list.prev,
|
|
|
|
&output->link);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
weston_compositor_add_output(output->compositor, output);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Converts a weston_output object to a pending output state, so it
|
|
|
|
** can be configured again or destroyed.
|
|
|
|
*
|
|
|
|
* \param output The weston_output object that needs to be disabled.
|
|
|
|
*
|
2016-09-30 15:11:12 +03:00
|
|
|
* See weston_output_init() for more information on the
|
2016-09-30 15:11:02 +03:00
|
|
|
* state output is returned to.
|
|
|
|
*
|
|
|
|
* Calls a backend specific function to disable an output, in case
|
|
|
|
* such function exists.
|
|
|
|
*
|
|
|
|
* If the output is being used by the compositor, it is first removed
|
|
|
|
* from weston's output_list (see weston_compositor_remove_output())
|
|
|
|
* and is returned to a state it was before weston_output_enable()
|
|
|
|
* was ran (see weston_output_enable_undo()).
|
|
|
|
*
|
|
|
|
* Output is added to pending_output_list so it will get destroyed
|
|
|
|
* if the output does not get configured again when the compositor
|
|
|
|
* shuts down. If an output is to be used immediately, it needs to
|
|
|
|
* be manually removed from the list (the compositor specific functions
|
|
|
|
* for handling pending outputs will take care of that).
|
|
|
|
*
|
|
|
|
* If backend specific disable function returns negative value,
|
|
|
|
* this function will return too. It can be used as an indicator
|
|
|
|
* that output cannot be disabled at the present time. In that case
|
|
|
|
* backend needs to make sure the output is disabled when it is
|
|
|
|
* possible.
|
|
|
|
*/
|
|
|
|
WL_EXPORT void
|
|
|
|
weston_output_disable(struct weston_output *output)
|
|
|
|
{
|
|
|
|
assert(output->disable);
|
|
|
|
|
|
|
|
/* Should we rename this? */
|
|
|
|
output->destroying = 1;
|
|
|
|
|
|
|
|
if (output->disable(output) < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (output->enabled) {
|
|
|
|
weston_compositor_remove_output(output);
|
|
|
|
weston_output_enable_undo(output);
|
|
|
|
|
|
|
|
/* We need to preserve it somewhere so it can be destroyed on shutdown
|
|
|
|
if nobody wants to configure it again */
|
|
|
|
wl_list_insert(output->compositor->pending_output_list.prev, &output->link);
|
|
|
|
}
|
|
|
|
|
|
|
|
output->destroying = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Emits a signal to indicate that there are outputs waiting to be configured.
|
|
|
|
*
|
|
|
|
* \param compositor The compositor instance
|
|
|
|
*/
|
|
|
|
WL_EXPORT void
|
|
|
|
weston_pending_output_coldplug(struct weston_compositor *compositor)
|
|
|
|
{
|
|
|
|
struct weston_output *output, *next;
|
|
|
|
|
|
|
|
wl_list_for_each_safe(output, next, &compositor->pending_output_list, link)
|
|
|
|
wl_signal_emit(&compositor->output_pending_signal, output);
|
|
|
|
}
|
|
|
|
|
|
|
|
WL_EXPORT void
|
|
|
|
weston_output_destroy(struct weston_output *output)
|
|
|
|
{
|
|
|
|
output->destroying = 1;
|
|
|
|
|
|
|
|
if (output->enabled) {
|
|
|
|
weston_compositor_remove_output(output);
|
|
|
|
weston_output_enable_undo(output);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(output->name);
|
|
|
|
}
|
|
|
|
|
2013-11-26 21:19:45 +04:00
|
|
|
static void
|
2014-01-08 17:39:17 +04:00
|
|
|
destroy_viewport(struct wl_resource *resource)
|
2013-11-26 21:19:45 +04:00
|
|
|
{
|
2013-11-26 21:19:46 +04:00
|
|
|
struct weston_surface *surface =
|
|
|
|
wl_resource_get_user_data(resource);
|
|
|
|
|
2016-04-22 14:14:38 +03:00
|
|
|
if (!surface)
|
|
|
|
return;
|
|
|
|
|
2014-01-08 17:39:17 +04:00
|
|
|
surface->viewport_resource = NULL;
|
2014-03-14 16:38:16 +04:00
|
|
|
surface->pending.buffer_viewport.buffer.src_width =
|
|
|
|
wl_fixed_from_int(-1);
|
|
|
|
surface->pending.buffer_viewport.surface.width = -1;
|
2014-06-13 20:14:20 +04:00
|
|
|
surface->pending.buffer_viewport.changed = 1;
|
2013-11-26 21:19:45 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-01-08 17:39:17 +04:00
|
|
|
viewport_destroy(struct wl_client *client,
|
|
|
|
struct wl_resource *resource)
|
2013-11-26 21:19:45 +04:00
|
|
|
{
|
|
|
|
wl_resource_destroy(resource);
|
|
|
|
}
|
|
|
|
|
2014-03-14 16:38:17 +04:00
|
|
|
static void
|
|
|
|
viewport_set_source(struct wl_client *client,
|
|
|
|
struct wl_resource *resource,
|
|
|
|
wl_fixed_t src_x,
|
|
|
|
wl_fixed_t src_y,
|
|
|
|
wl_fixed_t src_width,
|
|
|
|
wl_fixed_t src_height)
|
|
|
|
{
|
|
|
|
struct weston_surface *surface =
|
|
|
|
wl_resource_get_user_data(resource);
|
|
|
|
|
2016-04-22 14:14:38 +03:00
|
|
|
if (!surface) {
|
|
|
|
wl_resource_post_error(resource,
|
|
|
|
WP_VIEWPORT_ERROR_NO_SURFACE,
|
|
|
|
"wl_surface for this viewport is no longer exists");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(surface->viewport_resource == resource);
|
2016-04-26 14:42:11 +03:00
|
|
|
assert(surface->resource);
|
2014-03-14 16:38:17 +04:00
|
|
|
|
2014-04-04 15:22:12 +04:00
|
|
|
if (src_width == wl_fixed_from_int(-1) &&
|
2016-04-26 14:42:11 +03:00
|
|
|
src_height == wl_fixed_from_int(-1) &&
|
|
|
|
src_x == wl_fixed_from_int(-1) &&
|
|
|
|
src_y == wl_fixed_from_int(-1)) {
|
|
|
|
/* unset source rect */
|
2014-03-14 16:38:17 +04:00
|
|
|
surface->pending.buffer_viewport.buffer.src_width =
|
|
|
|
wl_fixed_from_int(-1);
|
2014-06-13 20:14:20 +04:00
|
|
|
surface->pending.buffer_viewport.changed = 1;
|
2014-04-04 15:22:12 +04:00
|
|
|
return;
|
2014-03-14 16:38:17 +04:00
|
|
|
}
|
2014-04-04 15:22:12 +04:00
|
|
|
|
2016-04-26 14:42:11 +03:00
|
|
|
if (src_width <= 0 || src_height <= 0 || src_x < 0 || src_y < 0) {
|
2014-04-04 15:22:12 +04:00
|
|
|
wl_resource_post_error(resource,
|
2016-04-15 14:47:08 +03:00
|
|
|
WP_VIEWPORT_ERROR_BAD_VALUE,
|
2016-04-26 14:42:11 +03:00
|
|
|
"wl_surface@%d viewport source "
|
|
|
|
"w=%f <= 0, h=%f <= 0, x=%f < 0, or y=%f < 0",
|
|
|
|
wl_resource_get_id(surface->resource),
|
2014-04-04 15:22:12 +04:00
|
|
|
wl_fixed_to_double(src_width),
|
2016-04-26 14:42:11 +03:00
|
|
|
wl_fixed_to_double(src_height),
|
|
|
|
wl_fixed_to_double(src_x),
|
|
|
|
wl_fixed_to_double(src_y));
|
2014-04-04 15:22:12 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
surface->pending.buffer_viewport.buffer.src_x = src_x;
|
|
|
|
surface->pending.buffer_viewport.buffer.src_y = src_y;
|
|
|
|
surface->pending.buffer_viewport.buffer.src_width = src_width;
|
|
|
|
surface->pending.buffer_viewport.buffer.src_height = src_height;
|
2014-06-13 20:14:20 +04:00
|
|
|
surface->pending.buffer_viewport.changed = 1;
|
2014-03-14 16:38:17 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
viewport_set_destination(struct wl_client *client,
|
|
|
|
struct wl_resource *resource,
|
|
|
|
int32_t dst_width,
|
|
|
|
int32_t dst_height)
|
|
|
|
{
|
|
|
|
struct weston_surface *surface =
|
|
|
|
wl_resource_get_user_data(resource);
|
|
|
|
|
2016-04-22 14:14:38 +03:00
|
|
|
if (!surface) {
|
|
|
|
wl_resource_post_error(resource,
|
|
|
|
WP_VIEWPORT_ERROR_NO_SURFACE,
|
|
|
|
"wl_surface for this viewport no longer exists");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(surface->viewport_resource == resource);
|
2014-03-14 16:38:17 +04:00
|
|
|
|
2014-04-04 15:22:12 +04:00
|
|
|
if (dst_width == -1 && dst_height == -1) {
|
|
|
|
/* unset destination size */
|
2014-03-14 16:38:17 +04:00
|
|
|
surface->pending.buffer_viewport.surface.width = -1;
|
2014-06-13 20:14:20 +04:00
|
|
|
surface->pending.buffer_viewport.changed = 1;
|
2014-04-04 15:22:12 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dst_width <= 0 || dst_height <= 0) {
|
|
|
|
wl_resource_post_error(resource,
|
2016-04-15 14:47:08 +03:00
|
|
|
WP_VIEWPORT_ERROR_BAD_VALUE,
|
2014-04-04 15:22:12 +04:00
|
|
|
"destination size must be positive (%dx%d)",
|
|
|
|
dst_width, dst_height);
|
|
|
|
return;
|
2014-03-14 16:38:17 +04:00
|
|
|
}
|
2014-04-04 15:22:12 +04:00
|
|
|
|
|
|
|
surface->pending.buffer_viewport.surface.width = dst_width;
|
|
|
|
surface->pending.buffer_viewport.surface.height = dst_height;
|
2014-06-13 20:14:20 +04:00
|
|
|
surface->pending.buffer_viewport.changed = 1;
|
2014-03-14 16:38:17 +04:00
|
|
|
}
|
|
|
|
|
2016-04-15 14:47:08 +03:00
|
|
|
static const struct wp_viewport_interface viewport_interface = {
|
2014-01-08 17:39:17 +04:00
|
|
|
viewport_destroy,
|
2014-03-14 16:38:17 +04:00
|
|
|
viewport_set_source,
|
|
|
|
viewport_set_destination
|
2013-11-26 21:19:45 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
2016-04-15 16:42:49 +03:00
|
|
|
viewporter_destroy(struct wl_client *client,
|
|
|
|
struct wl_resource *resource)
|
2013-11-26 21:19:45 +04:00
|
|
|
{
|
|
|
|
wl_resource_destroy(resource);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2016-04-15 16:42:49 +03:00
|
|
|
viewporter_get_viewport(struct wl_client *client,
|
|
|
|
struct wl_resource *viewporter,
|
|
|
|
uint32_t id,
|
|
|
|
struct wl_resource *surface_resource)
|
2013-11-26 21:19:45 +04:00
|
|
|
{
|
2016-04-15 16:42:49 +03:00
|
|
|
int version = wl_resource_get_version(viewporter);
|
2014-03-14 16:38:17 +04:00
|
|
|
struct weston_surface *surface =
|
|
|
|
wl_resource_get_user_data(surface_resource);
|
2013-11-26 21:19:45 +04:00
|
|
|
struct wl_resource *resource;
|
|
|
|
|
2014-01-08 17:39:17 +04:00
|
|
|
if (surface->viewport_resource) {
|
2016-04-15 16:42:49 +03:00
|
|
|
wl_resource_post_error(viewporter,
|
2016-04-15 14:47:08 +03:00
|
|
|
WP_VIEWPORTER_ERROR_VIEWPORT_EXISTS,
|
2014-01-08 17:39:17 +04:00
|
|
|
"a viewport for that surface already exists");
|
2013-11-26 21:19:46 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-04-15 14:47:08 +03:00
|
|
|
resource = wl_resource_create(client, &wp_viewport_interface,
|
2014-03-14 16:38:17 +04:00
|
|
|
version, id);
|
2013-11-26 21:19:45 +04:00
|
|
|
if (resource == NULL) {
|
|
|
|
wl_client_post_no_memory(client);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-01-08 17:39:17 +04:00
|
|
|
wl_resource_set_implementation(resource, &viewport_interface,
|
|
|
|
surface, destroy_viewport);
|
2013-11-26 21:19:46 +04:00
|
|
|
|
2014-01-08 17:39:17 +04:00
|
|
|
surface->viewport_resource = resource;
|
2013-11-26 21:19:45 +04:00
|
|
|
}
|
|
|
|
|
2016-04-15 16:42:49 +03:00
|
|
|
static const struct wp_viewporter_interface viewporter_interface = {
|
|
|
|
viewporter_destroy,
|
|
|
|
viewporter_get_viewport
|
2013-11-26 21:19:45 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
2016-04-15 16:42:49 +03:00
|
|
|
bind_viewporter(struct wl_client *client,
|
|
|
|
void *data, uint32_t version, uint32_t id)
|
2013-11-26 21:19:45 +04:00
|
|
|
{
|
|
|
|
struct wl_resource *resource;
|
|
|
|
|
2016-04-15 14:47:08 +03:00
|
|
|
resource = wl_resource_create(client, &wp_viewporter_interface,
|
2015-11-26 23:17:47 +03:00
|
|
|
version, id);
|
2013-11-26 21:19:45 +04:00
|
|
|
if (resource == NULL) {
|
|
|
|
wl_client_post_no_memory(client);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-04-15 16:42:49 +03:00
|
|
|
wl_resource_set_implementation(resource, &viewporter_interface,
|
2013-11-26 21:19:45 +04:00
|
|
|
NULL, NULL);
|
|
|
|
}
|
|
|
|
|
2014-09-24 06:08:46 +04:00
|
|
|
static void
|
|
|
|
destroy_presentation_feedback(struct wl_resource *feedback_resource)
|
|
|
|
{
|
|
|
|
struct weston_presentation_feedback *feedback;
|
|
|
|
|
|
|
|
feedback = wl_resource_get_user_data(feedback_resource);
|
|
|
|
|
|
|
|
wl_list_remove(&feedback->link);
|
|
|
|
free(feedback);
|
|
|
|
}
|
|
|
|
|
2014-09-24 06:08:43 +04:00
|
|
|
static void
|
|
|
|
presentation_destroy(struct wl_client *client, struct wl_resource *resource)
|
|
|
|
{
|
|
|
|
wl_resource_destroy(resource);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
presentation_feedback(struct wl_client *client,
|
2014-09-24 06:08:46 +04:00
|
|
|
struct wl_resource *presentation_resource,
|
|
|
|
struct wl_resource *surface_resource,
|
2014-09-24 06:08:43 +04:00
|
|
|
uint32_t callback)
|
|
|
|
{
|
2014-09-24 06:08:46 +04:00
|
|
|
struct weston_surface *surface;
|
|
|
|
struct weston_presentation_feedback *feedback;
|
|
|
|
|
|
|
|
surface = wl_resource_get_user_data(surface_resource);
|
|
|
|
|
2014-11-21 09:21:57 +03:00
|
|
|
feedback = zalloc(sizeof *feedback);
|
|
|
|
if (feedback == NULL)
|
2014-09-24 06:08:46 +04:00
|
|
|
goto err_calloc;
|
|
|
|
|
|
|
|
feedback->resource = wl_resource_create(client,
|
2016-02-18 17:53:27 +03:00
|
|
|
&wp_presentation_feedback_interface,
|
2014-09-24 06:08:46 +04:00
|
|
|
1, callback);
|
|
|
|
if (!feedback->resource)
|
|
|
|
goto err_create;
|
|
|
|
|
|
|
|
wl_resource_set_implementation(feedback->resource, NULL, feedback,
|
|
|
|
destroy_presentation_feedback);
|
|
|
|
|
|
|
|
wl_list_insert(&surface->pending.feedback_list, &feedback->link);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
err_create:
|
|
|
|
free(feedback);
|
|
|
|
|
|
|
|
err_calloc:
|
|
|
|
wl_client_post_no_memory(client);
|
2014-09-24 06:08:43 +04:00
|
|
|
}
|
|
|
|
|
2016-02-18 17:53:27 +03:00
|
|
|
static const struct wp_presentation_interface presentation_implementation = {
|
2014-09-24 06:08:43 +04:00
|
|
|
presentation_destroy,
|
|
|
|
presentation_feedback
|
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
bind_presentation(struct wl_client *client,
|
|
|
|
void *data, uint32_t version, uint32_t id)
|
|
|
|
{
|
|
|
|
struct weston_compositor *compositor = data;
|
|
|
|
struct wl_resource *resource;
|
|
|
|
|
2016-02-18 17:53:27 +03:00
|
|
|
resource = wl_resource_create(client, &wp_presentation_interface,
|
2015-11-26 23:17:47 +03:00
|
|
|
version, id);
|
2014-09-24 06:08:43 +04:00
|
|
|
if (resource == NULL) {
|
|
|
|
wl_client_post_no_memory(client);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
wl_resource_set_implementation(resource, &presentation_implementation,
|
|
|
|
compositor, NULL);
|
2016-02-18 17:53:27 +03:00
|
|
|
wp_presentation_send_clock_id(resource, compositor->presentation_clock);
|
2014-09-24 06:08:43 +04:00
|
|
|
}
|
|
|
|
|
2011-11-23 19:39:34 +04:00
|
|
|
static void
|
|
|
|
compositor_bind(struct wl_client *client,
|
|
|
|
void *data, uint32_t version, uint32_t id)
|
|
|
|
{
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
struct weston_compositor *compositor = data;
|
2013-06-28 05:17:02 +04:00
|
|
|
struct wl_resource *resource;
|
2011-11-23 19:39:34 +04:00
|
|
|
|
2013-06-28 05:17:02 +04:00
|
|
|
resource = wl_resource_create(client, &wl_compositor_interface,
|
2015-11-26 23:17:47 +03:00
|
|
|
version, id);
|
2013-08-07 03:46:25 +04:00
|
|
|
if (resource == NULL) {
|
|
|
|
wl_client_post_no_memory(client);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
wl_resource_set_implementation(resource, &compositor_interface,
|
|
|
|
compositor, NULL);
|
2011-11-23 19:39:34 +04:00
|
|
|
}
|
|
|
|
|
2013-02-21 20:35:16 +04:00
|
|
|
WL_EXPORT int
|
|
|
|
weston_environment_get_fd(const char *env)
|
|
|
|
{
|
2016-08-04 03:40:52 +03:00
|
|
|
char *e;
|
2013-02-21 20:35:16 +04:00
|
|
|
int fd, flags;
|
|
|
|
|
|
|
|
e = getenv(env);
|
2016-08-04 03:40:52 +03:00
|
|
|
if (!e || !safe_strtoint(e, &fd))
|
2013-02-21 20:35:16 +04:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
flags = fcntl(fd, F_GETFD);
|
|
|
|
if (flags == -1)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
|
|
|
|
unsetenv(env);
|
|
|
|
|
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
compositor: Implement JSON-timeline logging
Logging is activated and deactivated with the debug key binding 't'.
When activated, it creates a new log file, where it records the events.
The log file contains events and detailed object information entries in
JSON format, and is meant to be parsed in sequence from beginning to the
end.
The emitted events are mostly related to the output repaint cycle, like
when repaint begins, is submitted to GPU, and when it completes on a
vblank. This is recorded per-output. Also some per-surface events are
recorded, including when surface damage is flushed.
To reduce the log size, events refer to objects like outputs and
surfaces by id numbers. Detailed object information is emitted only as
needed: on the first object occurrence, and afterwards only if
weston_timeline_object::force_refresh asks for it.
The detailed information for surfaces includes the string returned by
weston_surface::get_label. Therefore it is important to set
weston_timeline_object::force_refresh = 1 whenever the string would
change, so that the new details get recorded.
A rudimentary parser and SVG generator can be found at:
https://github.com/ppaalanen/wesgr
The timeline logs can answer questions including:
- How does the compositor repaint cycle work timing-wise?
- When was the vblank deadline missed?
- What is the latency from surface commit to showing the new content on
screen?
- How long does it take to process the scenegraph?
v2: weston_surface::get_description renamed to get_label.
v3: reafctor a bit into fprint_quoted_string().
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2014-11-12 16:09:24 +03:00
|
|
|
static void
|
2015-07-15 21:00:36 +03:00
|
|
|
timeline_key_binding_handler(struct weston_keyboard *keyboard, uint32_t time,
|
compositor: Implement JSON-timeline logging
Logging is activated and deactivated with the debug key binding 't'.
When activated, it creates a new log file, where it records the events.
The log file contains events and detailed object information entries in
JSON format, and is meant to be parsed in sequence from beginning to the
end.
The emitted events are mostly related to the output repaint cycle, like
when repaint begins, is submitted to GPU, and when it completes on a
vblank. This is recorded per-output. Also some per-surface events are
recorded, including when surface damage is flushed.
To reduce the log size, events refer to objects like outputs and
surfaces by id numbers. Detailed object information is emitted only as
needed: on the first object occurrence, and afterwards only if
weston_timeline_object::force_refresh asks for it.
The detailed information for surfaces includes the string returned by
weston_surface::get_label. Therefore it is important to set
weston_timeline_object::force_refresh = 1 whenever the string would
change, so that the new details get recorded.
A rudimentary parser and SVG generator can be found at:
https://github.com/ppaalanen/wesgr
The timeline logs can answer questions including:
- How does the compositor repaint cycle work timing-wise?
- When was the vblank deadline missed?
- What is the latency from surface commit to showing the new content on
screen?
- How long does it take to process the scenegraph?
v2: weston_surface::get_description renamed to get_label.
v3: reafctor a bit into fprint_quoted_string().
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2014-11-12 16:09:24 +03:00
|
|
|
uint32_t key, void *data)
|
|
|
|
{
|
|
|
|
struct weston_compositor *compositor = data;
|
|
|
|
|
|
|
|
if (weston_timeline_enabled_)
|
|
|
|
weston_timeline_close();
|
|
|
|
else
|
|
|
|
weston_timeline_open(compositor);
|
|
|
|
}
|
|
|
|
|
2014-10-12 00:56:24 +04:00
|
|
|
/** Create the compositor.
|
|
|
|
*
|
|
|
|
* This functions creates and initializes a compositor instance.
|
|
|
|
*
|
|
|
|
* \param display The Wayland display to be used.
|
|
|
|
* \param user_data A pointer to an object that can later be retrieved
|
|
|
|
* using the \ref weston_compositor_get_user_data function.
|
|
|
|
* \return The compositor instance on success or NULL on failure.
|
|
|
|
*/
|
|
|
|
WL_EXPORT struct weston_compositor *
|
|
|
|
weston_compositor_create(struct wl_display *display, void *user_data)
|
2010-06-14 19:54:00 +04:00
|
|
|
{
|
2014-10-12 00:56:24 +04:00
|
|
|
struct weston_compositor *ec;
|
2010-06-14 19:54:00 +04:00
|
|
|
struct wl_event_loop *loop;
|
2013-05-14 20:48:26 +04:00
|
|
|
|
2014-10-12 00:56:24 +04:00
|
|
|
ec = zalloc(sizeof *ec);
|
|
|
|
if (!ec)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
ec->wl_display = display;
|
|
|
|
ec->user_data = user_data;
|
2012-04-12 17:55:26 +04:00
|
|
|
wl_signal_init(&ec->destroy_signal);
|
2014-04-07 09:04:50 +04:00
|
|
|
wl_signal_init(&ec->create_surface_signal);
|
2012-04-12 17:55:26 +04:00
|
|
|
wl_signal_init(&ec->activate_signal);
|
2013-06-12 22:43:21 +04:00
|
|
|
wl_signal_init(&ec->transform_signal);
|
2012-09-27 18:48:36 +04:00
|
|
|
wl_signal_init(&ec->kill_signal);
|
2013-02-21 20:35:23 +04:00
|
|
|
wl_signal_init(&ec->idle_signal);
|
|
|
|
wl_signal_init(&ec->wake_signal);
|
2012-06-21 23:52:17 +04:00
|
|
|
wl_signal_init(&ec->show_input_panel_signal);
|
|
|
|
wl_signal_init(&ec->hide_input_panel_signal);
|
2013-04-18 18:47:28 +04:00
|
|
|
wl_signal_init(&ec->update_input_panel_signal);
|
2012-11-18 22:06:42 +04:00
|
|
|
wl_signal_init(&ec->seat_created_signal);
|
2016-09-30 15:11:02 +03:00
|
|
|
wl_signal_init(&ec->output_pending_signal);
|
2013-05-02 00:52:11 +04:00
|
|
|
wl_signal_init(&ec->output_created_signal);
|
2014-01-29 20:47:51 +04:00
|
|
|
wl_signal_init(&ec->output_destroyed_signal);
|
2014-01-29 20:47:52 +04:00
|
|
|
wl_signal_init(&ec->output_moved_signal);
|
2016-05-28 00:22:57 +03:00
|
|
|
wl_signal_init(&ec->output_resized_signal);
|
2013-09-18 03:02:57 +04:00
|
|
|
wl_signal_init(&ec->session_signal);
|
|
|
|
ec->session_active = 1;
|
2008-10-09 06:51:32 +04:00
|
|
|
|
2012-04-20 06:50:08 +04:00
|
|
|
ec->output_id_pool = 0;
|
2014-10-12 01:24:25 +04:00
|
|
|
ec->repaint_msec = DEFAULT_REPAINT_WINDOW;
|
2012-04-20 06:50:08 +04:00
|
|
|
|
2014-10-18 20:42:19 +04:00
|
|
|
ec->activate_serial = 1;
|
|
|
|
|
2015-11-26 23:17:48 +03:00
|
|
|
if (!wl_global_create(ec->wl_display, &wl_compositor_interface, 4,
|
2013-07-09 03:03:57 +04:00
|
|
|
ec, compositor_bind))
|
2014-10-12 00:56:24 +04:00
|
|
|
goto fail;
|
2008-12-22 07:37:12 +03:00
|
|
|
|
2014-10-11 19:27:30 +04:00
|
|
|
if (!wl_global_create(ec->wl_display, &wl_subcompositor_interface, 1,
|
2013-07-09 03:03:57 +04:00
|
|
|
ec, bind_subcompositor))
|
2014-10-12 00:56:24 +04:00
|
|
|
goto fail;
|
compositor: introduce sub-surfaces
Implement the basic protocol for sub-surfaces:
- expose wl_subcompositor global interface
- error checking on protocol calls
- associate a parent wl_surface to a sub-surface
- introduce the sub-surface role, which is exclusive
- an implementation of the wl_subsurface interface
- allow nesting of sub-surfaces
- proper surface transformation inheritance from parent to sub-surfaces
- two different modes of wl_surface.commit for sub-surfaces
- hook sub-surfaces up to repaint by modifying the repaint list code
Struct weston_subsurface is dynamically allocated. For sub-surfaces, it
is completely populated.
For parent surfaces, weston_subsurface acts only as a link for stacking
order purposes. The wl_resource is unused, parent_destroy_listener is
not registered, the transform is not linked, etc.
Sub-surfaces are not added directly into layers for display or input.
Instead, they are hooked up via the sub-surface list present in parent
weston_surface. This way sub-surfaces are inherently linked to the
parent surface, and cannot be displayed unless the parent is mapped,
too. This also eases restacking, as only the parent will be in a layer
list. Also, only the main surface should be subject to shell actions.
The surface list rebuilding in weston_output_repaint() is modified to
process sub-surface lists, if they are non-empty. The sub-surface list
always contains the parent, too, unless empty. The collection of
frame_callback_list is moved to a later loop, to streamline the surface
list rebuild functions.
Features still lacking are:
- full-surface alpha support for compound windows
Changes in v2:
- fix a bug in surface mapping: commit a sub-surface would cause the
main surface to never be mapped.
- remove debug printfs
- detect attempt of making a surface its own parent
- always zero-alloc weston_subsurface
- apply wl_subsurface.set_position in commit, not immediately
- add weston_surface_to_subsurface()
- implement sub-surface commit modes parent-cached and independent
- implement wl_subcompositor.destroy and wl_subsurface.destroy
Changes in v3:
- rebased, and use the new transform inheritance code
- squashed the commit "add sub-surfaces to repaint list"
- fixed a buffer reference leak in commit_from_cache()
- Rewrite the sub-surface destructor code, and make it leave the
wl_subsurface protocol object inert, if one destroys the corresponding
wl_surface.
- replaced set_commit_mode with set_sync and set_desync
- allowed sub-surface nesting, and fixed repaint accordingly
- implemented nested sub-surface commit modes
- Made the sub-surface order changes from wl_subsurface.place_above and
.place_below to be applied when the parent surface state is applied,
instead of immediately. This conforms with the protocol specification
now.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2013-04-25 14:57:42 +04:00
|
|
|
|
2016-04-15 14:47:08 +03:00
|
|
|
if (!wl_global_create(ec->wl_display, &wp_viewporter_interface, 1,
|
2016-04-15 16:42:49 +03:00
|
|
|
ec, bind_viewporter))
|
2014-10-12 00:56:24 +04:00
|
|
|
goto fail;
|
2013-11-26 21:19:45 +04:00
|
|
|
|
2016-02-18 17:53:27 +03:00
|
|
|
if (!wl_global_create(ec->wl_display, &wp_presentation_interface, 1,
|
2014-09-24 06:08:43 +04:00
|
|
|
ec, bind_presentation))
|
2014-10-12 00:56:24 +04:00
|
|
|
goto fail;
|
2014-09-24 06:08:43 +04:00
|
|
|
|
2014-10-22 23:21:17 +04:00
|
|
|
if (weston_input_init(ec) != 0)
|
|
|
|
goto fail;
|
|
|
|
|
Split the geometry information from weston_surface out into weston_view
The weston_surface structure is split into two structures:
* The weston_surface structure storres everything required for a
client-side or server-side surface. This includes buffers; callbacks;
backend private data; input, damage, and opaque regions; and a few other
bookkeeping bits.
* The weston_view structure represents an entity in the scenegraph and
storres all of the geometry information. This includes clip region,
alpha, position, and the transformation list as well as all of the
temporary information derived from the geometry state. Because a view,
and not a surface, is a scenegraph element, the view is what is placed
in layers and planes.
There are a few things worth noting about the surface/view split:
1. This is *not* a modification to the protocol. It is, instead, a
modification to Weston's internal scenegraph to allow a single surface
to exist in multiple places at a time. Clients are completely unaware
of how many views to a particular surface exist.
2. A view is considered a direct child of a surface and is destroyed when
the surface is destroyed. Because of this, the view.surface pointer is
always valid and non-null.
3. The compositor's surface_list is replaced with a view_list. Due to
subsurfaces, building the view list is a little more complicated than
it used to be and involves building a tree of views on the fly whenever
subsurfaces are used. However, this means that backends can remain
completely subsurface-agnostic.
4. Surfaces and views both keep track of which outputs they are on.
5. The weston_surface structure now has width and height fields. These
are populated when a new buffer is attached before surface.configure
is called. This is because there are many surface-based operations
that really require the width and height and digging through the views
didn't work well.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
2013-10-13 07:38:11 +04:00
|
|
|
wl_list_init(&ec->view_list);
|
2013-03-05 19:30:27 +04:00
|
|
|
wl_list_init(&ec->plane_list);
|
2012-06-22 17:04:36 +04:00
|
|
|
wl_list_init(&ec->layer_list);
|
|
|
|
wl_list_init(&ec->seat_list);
|
2016-09-30 15:11:02 +03:00
|
|
|
wl_list_init(&ec->pending_output_list);
|
2012-06-22 17:04:36 +04:00
|
|
|
wl_list_init(&ec->output_list);
|
|
|
|
wl_list_init(&ec->key_binding_list);
|
2013-11-19 14:37:12 +04:00
|
|
|
wl_list_init(&ec->modifier_binding_list);
|
2012-06-22 17:04:36 +04:00
|
|
|
wl_list_init(&ec->button_binding_list);
|
2013-10-03 19:43:04 +04:00
|
|
|
wl_list_init(&ec->touch_binding_list);
|
2012-06-22 17:04:36 +04:00
|
|
|
wl_list_init(&ec->axis_binding_list);
|
2012-11-08 19:20:45 +04:00
|
|
|
wl_list_init(&ec->debug_binding_list);
|
2012-06-22 17:04:36 +04:00
|
|
|
|
2016-06-29 12:54:26 +03:00
|
|
|
wl_list_init(&ec->plugin_api_list);
|
|
|
|
|
2013-10-23 09:58:31 +04:00
|
|
|
weston_plane_init(&ec->primary_plane, ec, 0, 0);
|
2013-03-05 19:30:27 +04:00
|
|
|
weston_compositor_stack_plane(ec, &ec->primary_plane, NULL);
|
2012-08-03 19:30:18 +04:00
|
|
|
|
2014-10-12 00:56:24 +04:00
|
|
|
wl_data_device_manager_init(ec->wl_display);
|
|
|
|
|
|
|
|
wl_display_init_shm(ec->wl_display);
|
|
|
|
|
|
|
|
loop = wl_display_get_event_loop(ec->wl_display);
|
|
|
|
ec->idle_source = wl_event_loop_add_timer(loop, idle_handler, ec);
|
|
|
|
|
|
|
|
weston_layer_init(&ec->fade_layer, &ec->layer_list);
|
|
|
|
weston_layer_init(&ec->cursor_layer, &ec->fade_layer.link);
|
|
|
|
|
|
|
|
weston_compositor_add_debug_binding(ec, KEY_T,
|
|
|
|
timeline_key_binding_handler, ec);
|
|
|
|
|
|
|
|
return ec;
|
|
|
|
|
|
|
|
fail:
|
|
|
|
free(ec);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-08-30 13:32:47 +04:00
|
|
|
WL_EXPORT void
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
weston_compositor_shutdown(struct weston_compositor *ec)
|
2011-08-30 00:52:23 +04:00
|
|
|
{
|
Rename wayland-compositor to weston
This rename addresses a few problems around the split between core
Wayland and the wayland-demos repository.
1) Initially, we had one big repository with protocol code, sample
compositor and sample clients. We split that repository to make it
possible to implement the protocol without pulling in the sample/demo
code. At this point, the compositor is more than just a "demo" and
wayland-demos doesn't send the right message. The sample compositor
is a useful, self-contained project in it's own right, and we want to
move away from the "demos" label.
2) Another problem is that the wayland-demos compositor is often
called "the wayland compsitor", but it's really just one possible
compositor. Existing X11 compositors are expected to add Wayland
support and then gradually phase out/modularize the X11 support, for
example. Conversely, it's hard to talk about the wayland-demos
compositor specifically as opposed to, eg, the wayland protocol or a
wayland compositor in general.
We are also renaming the repo to weston, and the compositor
subdirectory to src/, to emphasize that the main "output" is the
compositor.
2012-01-03 19:29:47 +04:00
|
|
|
struct weston_output *output, *next;
|
2011-08-30 00:52:23 +04:00
|
|
|
|
2012-01-02 18:06:56 +04:00
|
|
|
wl_event_source_remove(ec->idle_source);
|
|
|
|
|
2011-08-30 00:52:23 +04:00
|
|
|
/* Destroy all outputs associated with this compositor */
|
2011-12-19 00:27:40 +04:00
|
|
|
wl_list_for_each_safe(output, next, &ec->output_list, link)
|
2011-08-30 00:52:23 +04:00
|
|
|
output->destroy(output);
|
2012-01-02 17:47:07 +04:00
|
|
|
|
2016-09-30 15:11:02 +03:00
|
|
|
/* Destroy all pending outputs associated with this compositor */
|
|
|
|
wl_list_for_each_safe(output, next, &ec->pending_output_list, link)
|
|
|
|
output->destroy(output);
|
|
|
|
|
2013-12-20 23:07:00 +04:00
|
|
|
if (ec->renderer)
|
|
|
|
ec->renderer->destroy(ec);
|
|
|
|
|
2012-05-30 19:31:58 +04:00
|
|
|
weston_binding_list_destroy_all(&ec->key_binding_list);
|
2015-07-17 07:07:42 +03:00
|
|
|
weston_binding_list_destroy_all(&ec->modifier_binding_list);
|
2012-05-30 19:31:58 +04:00
|
|
|
weston_binding_list_destroy_all(&ec->button_binding_list);
|
2013-10-03 19:43:04 +04:00
|
|
|
weston_binding_list_destroy_all(&ec->touch_binding_list);
|
2012-05-30 19:31:58 +04:00
|
|
|
weston_binding_list_destroy_all(&ec->axis_binding_list);
|
2012-11-08 19:20:45 +04:00
|
|
|
weston_binding_list_destroy_all(&ec->debug_binding_list);
|
2012-01-02 18:06:56 +04:00
|
|
|
|
2012-08-03 19:30:18 +04:00
|
|
|
weston_plane_release(&ec->primary_plane);
|
2011-08-30 00:52:23 +04:00
|
|
|
}
|
|
|
|
|
2014-10-29 21:44:33 +03:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_compositor_exit_with_code(struct weston_compositor *compositor,
|
|
|
|
int exit_code)
|
|
|
|
{
|
2014-11-18 16:57:04 +03:00
|
|
|
if (compositor->exit_code == EXIT_SUCCESS)
|
|
|
|
compositor->exit_code = exit_code;
|
|
|
|
|
2014-10-12 00:56:24 +04:00
|
|
|
weston_compositor_exit(compositor);
|
2014-10-29 21:44:33 +03:00
|
|
|
}
|
|
|
|
|
2013-11-15 02:42:53 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_compositor_set_default_pointer_grab(struct weston_compositor *ec,
|
|
|
|
const struct weston_pointer_grab_interface *interface)
|
|
|
|
{
|
|
|
|
struct weston_seat *seat;
|
|
|
|
|
|
|
|
ec->default_pointer_grab = interface;
|
|
|
|
wl_list_for_each(seat, &ec->seat_list, link) {
|
2015-08-01 00:55:32 +03:00
|
|
|
struct weston_pointer *pointer = weston_seat_get_pointer(seat);
|
|
|
|
|
|
|
|
if (pointer)
|
|
|
|
weston_pointer_set_default_grab(pointer, interface);
|
2013-11-15 02:42:53 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-24 06:08:45 +04:00
|
|
|
WL_EXPORT int
|
|
|
|
weston_compositor_set_presentation_clock(struct weston_compositor *compositor,
|
|
|
|
clockid_t clk_id)
|
|
|
|
{
|
|
|
|
struct timespec ts;
|
|
|
|
|
|
|
|
if (clock_gettime(clk_id, &ts) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
compositor->presentation_clock = clk_id;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* For choosing the software clock, when the display hardware or API
|
|
|
|
* does not expose a compatible presentation timestamp.
|
|
|
|
*/
|
|
|
|
WL_EXPORT int
|
|
|
|
weston_compositor_set_presentation_clock_software(
|
|
|
|
struct weston_compositor *compositor)
|
|
|
|
{
|
|
|
|
/* In order of preference */
|
|
|
|
static const clockid_t clocks[] = {
|
|
|
|
CLOCK_MONOTONIC_RAW, /* no jumps, no crawling */
|
|
|
|
CLOCK_MONOTONIC_COARSE, /* no jumps, may crawl, fast & coarse */
|
|
|
|
CLOCK_MONOTONIC, /* no jumps, may crawl */
|
|
|
|
CLOCK_REALTIME_COARSE, /* may jump and crawl, fast & coarse */
|
|
|
|
CLOCK_REALTIME /* may jump and crawl */
|
|
|
|
};
|
|
|
|
unsigned i;
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_LENGTH(clocks); i++)
|
|
|
|
if (weston_compositor_set_presentation_clock(compositor,
|
|
|
|
clocks[i]) == 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
weston_log("Error: no suitable presentation clock available.\n");
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2015-03-18 13:17:26 +03:00
|
|
|
/** Read the current time from the Presentation clock
|
|
|
|
*
|
|
|
|
* \param compositor
|
|
|
|
* \param ts[out] The current time.
|
|
|
|
*
|
|
|
|
* \note Reading the current time in user space is always imprecise to some
|
|
|
|
* degree.
|
|
|
|
*
|
|
|
|
* This function is never meant to fail. If reading the clock does fail,
|
|
|
|
* an error message is logged and a zero time is returned. Callers are not
|
|
|
|
* supposed to detect or react to failures.
|
|
|
|
*/
|
|
|
|
WL_EXPORT void
|
|
|
|
weston_compositor_read_presentation_clock(
|
|
|
|
const struct weston_compositor *compositor,
|
|
|
|
struct timespec *ts)
|
|
|
|
{
|
|
|
|
static bool warned;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = clock_gettime(compositor->presentation_clock, ts);
|
|
|
|
if (ret < 0) {
|
|
|
|
ts->tv_sec = 0;
|
|
|
|
ts->tv_nsec = 0;
|
|
|
|
|
|
|
|
if (!warned)
|
|
|
|
weston_log("Error: failure to read "
|
|
|
|
"the presentation clock %#x: '%m' (%d)\n",
|
|
|
|
compositor->presentation_clock, errno);
|
|
|
|
warned = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-29 22:18:40 +04:00
|
|
|
/** Import dmabuf buffer into current renderer
|
|
|
|
*
|
|
|
|
* \param compositor
|
|
|
|
* \param buffer the dmabuf buffer to import
|
|
|
|
* \return true on usable buffers, false otherwise
|
|
|
|
*
|
|
|
|
* This function tests that the linux_dmabuf_buffer is usable
|
|
|
|
* for the current renderer. Returns false on unusable buffers. Usually
|
|
|
|
* usability is tested by importing the dmabufs for composition.
|
|
|
|
*
|
|
|
|
* This hook is also used for detecting if the renderer supports
|
|
|
|
* dmabufs at all. If the renderer hook is NULL, dmabufs are not
|
|
|
|
* supported.
|
|
|
|
* */
|
|
|
|
WL_EXPORT bool
|
|
|
|
weston_compositor_import_dmabuf(struct weston_compositor *compositor,
|
|
|
|
struct linux_dmabuf_buffer *buffer)
|
|
|
|
{
|
|
|
|
struct weston_renderer *renderer;
|
|
|
|
|
|
|
|
renderer = compositor->renderer;
|
|
|
|
|
|
|
|
if (renderer->import_dmabuf == NULL)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return renderer->import_dmabuf(compositor, buffer);
|
|
|
|
}
|
|
|
|
|
2013-02-16 05:53:20 +04:00
|
|
|
WL_EXPORT void
|
|
|
|
weston_version(int *major, int *minor, int *micro)
|
|
|
|
{
|
|
|
|
*major = WESTON_VERSION_MAJOR;
|
|
|
|
*minor = WESTON_VERSION_MINOR;
|
|
|
|
*micro = WESTON_VERSION_MICRO;
|
|
|
|
}
|
|
|
|
|
2013-10-14 16:57:11 +04:00
|
|
|
WL_EXPORT void *
|
|
|
|
weston_load_module(const char *name, const char *entrypoint)
|
2011-05-03 06:09:20 +04:00
|
|
|
{
|
2015-06-08 19:46:54 +03:00
|
|
|
const char *builddir = getenv("WESTON_BUILD_DIR");
|
2011-05-03 06:09:20 +04:00
|
|
|
char path[PATH_MAX];
|
|
|
|
void *module, *init;
|
2016-11-28 15:13:54 +03:00
|
|
|
size_t len;
|
2011-05-03 06:09:20 +04:00
|
|
|
|
2014-01-18 01:19:01 +04:00
|
|
|
if (name == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
2015-06-08 19:46:54 +03:00
|
|
|
if (name[0] != '/') {
|
|
|
|
if (builddir)
|
2016-11-28 15:13:54 +03:00
|
|
|
len = snprintf(path, sizeof path, "%s/.libs/%s",
|
|
|
|
builddir, name);
|
2015-06-08 19:46:54 +03:00
|
|
|
else
|
2016-11-28 15:13:54 +03:00
|
|
|
len = snprintf(path, sizeof path, "%s/%s",
|
|
|
|
LIBWESTON_MODULEDIR, name);
|
2015-06-08 19:46:54 +03:00
|
|
|
} else {
|
2016-11-28 15:13:54 +03:00
|
|
|
len = snprintf(path, sizeof path, "%s", name);
|
2015-06-08 19:46:54 +03:00
|
|
|
}
|
2011-05-03 06:09:20 +04:00
|
|
|
|
2016-11-28 15:13:54 +03:00
|
|
|
/* snprintf returns the length of the string it would've written,
|
|
|
|
* _excluding_ the NUL byte. So even being equal to the size of
|
|
|
|
* our buffer is an error here. */
|
|
|
|
if (len >= sizeof path)
|
|
|
|
return NULL;
|
|
|
|
|
2012-09-12 20:21:01 +04:00
|
|
|
module = dlopen(path, RTLD_NOW | RTLD_NOLOAD);
|
|
|
|
if (module) {
|
|
|
|
weston_log("Module '%s' already loaded\n", path);
|
|
|
|
dlclose(module);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-06-11 15:06:04 +04:00
|
|
|
weston_log("Loading module '%s'\n", path);
|
2012-07-26 19:39:26 +04:00
|
|
|
module = dlopen(path, RTLD_NOW);
|
2011-05-03 06:09:20 +04:00
|
|
|
if (!module) {
|
2012-06-11 15:06:04 +04:00
|
|
|
weston_log("Failed to load module: %s\n", dlerror());
|
2011-05-03 06:09:20 +04:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
init = dlsym(module, entrypoint);
|
|
|
|
if (!init) {
|
2012-06-11 15:06:04 +04:00
|
|
|
weston_log("Failed to lookup init function: %s\n", dlerror());
|
2012-12-05 22:47:10 +04:00
|
|
|
dlclose(module);
|
2011-05-03 06:09:20 +04:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return init;
|
|
|
|
}
|
|
|
|
|
2014-10-12 00:56:24 +04:00
|
|
|
|
|
|
|
/** Destroys the compositor.
|
|
|
|
*
|
|
|
|
* This function cleans up the compositor state and destroys it.
|
|
|
|
*
|
|
|
|
* \param compositor The compositor to be destroyed.
|
|
|
|
*/
|
|
|
|
WL_EXPORT void
|
|
|
|
weston_compositor_destroy(struct weston_compositor *compositor)
|
|
|
|
{
|
|
|
|
/* prevent further rendering while shutting down */
|
|
|
|
compositor->state = WESTON_COMPOSITOR_OFFSCREEN;
|
|
|
|
|
|
|
|
wl_signal_emit(&compositor->destroy_signal, compositor);
|
|
|
|
|
|
|
|
weston_compositor_xkb_destroy(compositor);
|
|
|
|
|
2015-10-03 16:25:15 +03:00
|
|
|
if (compositor->backend)
|
|
|
|
compositor->backend->destroy(compositor);
|
2016-06-29 12:54:26 +03:00
|
|
|
|
|
|
|
weston_plugin_api_destroy_list(compositor);
|
|
|
|
|
2014-10-12 00:56:24 +04:00
|
|
|
free(compositor);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Instruct the compositor to exit.
|
|
|
|
*
|
|
|
|
* This functions does not directly destroy the compositor object, it merely
|
|
|
|
* command it to start the tear down process. It is not guaranteed that the
|
|
|
|
* tear down will happen immediately.
|
|
|
|
*
|
|
|
|
* \param compositor The compositor to tear down.
|
|
|
|
*/
|
|
|
|
WL_EXPORT void
|
|
|
|
weston_compositor_exit(struct weston_compositor *compositor)
|
|
|
|
{
|
|
|
|
compositor->exit(compositor);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Return the user data stored in the compositor.
|
|
|
|
*
|
|
|
|
* This function returns the user data pointer set with user_data parameter
|
|
|
|
* to the \ref weston_compositor_create function.
|
|
|
|
*/
|
|
|
|
WL_EXPORT void *
|
|
|
|
weston_compositor_get_user_data(struct weston_compositor *compositor)
|
|
|
|
{
|
|
|
|
return compositor->user_data;
|
|
|
|
}
|
2016-06-03 14:49:54 +03:00
|
|
|
|
2016-06-03 15:23:46 +03:00
|
|
|
static const char * const backend_map[] = {
|
|
|
|
[WESTON_BACKEND_DRM] = "drm-backend.so",
|
|
|
|
[WESTON_BACKEND_FBDEV] = "fbdev-backend.so",
|
|
|
|
[WESTON_BACKEND_HEADLESS] = "headless-backend.so",
|
|
|
|
[WESTON_BACKEND_RDP] = "rdp-backend.so",
|
|
|
|
[WESTON_BACKEND_WAYLAND] = "wayland-backend.so",
|
|
|
|
[WESTON_BACKEND_X11] = "x11-backend.so",
|
|
|
|
};
|
|
|
|
|
2016-06-03 14:49:54 +03:00
|
|
|
/** Load a backend into a weston_compositor
|
|
|
|
*
|
|
|
|
* A backend must be loaded to make a weston_compositor work. A backend
|
|
|
|
* provides input and output capabilities, and determines the renderer to use.
|
|
|
|
*
|
|
|
|
* \param compositor A compositor that has not had a backend loaded yet.
|
|
|
|
* \param backend Name of the backend file.
|
|
|
|
* \param config_base A pointer to a backend-specific configuration
|
|
|
|
* structure's 'base' member.
|
|
|
|
*
|
|
|
|
* \return 0 on success, or -1 on error.
|
|
|
|
*/
|
|
|
|
WL_EXPORT int
|
|
|
|
weston_compositor_load_backend(struct weston_compositor *compositor,
|
2016-06-03 15:23:46 +03:00
|
|
|
enum weston_compositor_backend backend,
|
2016-06-03 14:49:54 +03:00
|
|
|
struct weston_backend_config *config_base)
|
|
|
|
{
|
|
|
|
int (*backend_init)(struct weston_compositor *c,
|
|
|
|
struct weston_backend_config *config_base);
|
|
|
|
|
2016-07-10 12:00:53 +03:00
|
|
|
if (backend >= ARRAY_LENGTH(backend_map))
|
2016-06-03 15:23:46 +03:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
backend_init = weston_load_module(backend_map[backend], "backend_init");
|
2016-06-03 14:49:54 +03:00
|
|
|
if (!backend_init)
|
|
|
|
return -1;
|
|
|
|
|
2016-06-03 14:56:18 +03:00
|
|
|
return backend_init(compositor, config_base);
|
2016-06-03 14:49:54 +03:00
|
|
|
}
|
2016-06-29 12:54:27 +03:00
|
|
|
|
|
|
|
WL_EXPORT int
|
|
|
|
weston_compositor_load_xwayland(struct weston_compositor *compositor)
|
|
|
|
{
|
|
|
|
int (*module_init)(struct weston_compositor *ec,
|
|
|
|
int *argc, char *argv[]);
|
|
|
|
int argc = 0;
|
|
|
|
|
|
|
|
module_init = weston_load_module("xwayland.so", "module_init");
|
|
|
|
if (!module_init)
|
|
|
|
return -1;
|
|
|
|
if (module_init(compositor, &argc, NULL) < 0)
|
|
|
|
return -1;
|
|
|
|
return 0;
|
|
|
|
}
|