You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
weston/libweston/compositor.c

8817 lines
238 KiB

/*
* Copyright © 2010-2011 Intel Corporation
* Copyright © 2008-2011 Kristian Høgsberg
* Copyright © 2012-2018, 2021 Collabora, Ltd.
* Copyright © 2017, 2018 General Electric Company
*
* 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:
*
* 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.
*/
#include "config.h"
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <limits.h>
#include <stdarg.h>
#include <assert.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/utsname.h>
#include <sys/stat.h>
#include <unistd.h>
#include <math.h>
#include <linux/input.h>
#include <dlfcn.h>
#include <signal.h>
#include <setjmp.h>
#include <sys/time.h>
#include <time.h>
#include <errno.h>
libweston: Support zwp_surface_synchronization_v1.set_acquire_fence Implement the set_acquire_fence request of the zwp_surface_synchronization_v1 interface. The implementation uses the acquire fence in two ways: 1. If the associated buffer is used as GL render source, an EGLSyncKHR is created from the fence and used to synchronize access. 2. If the associated buffer is used as a plane framebuffer, the acquire fence is treated as an in-fence for the atomic commit operation. If in-fences are not supported and the buffer has an acquire fence, we don't consider it for plane placement. If the used compositor/renderer doesn't support explicit synchronization, we don't advertise the protocol at all. Currently only the DRM and X11 backends when using the GL renderer advertise the protocol for production use. Issues for discussion --------------------- a. Currently, a server-side wait of EGLSyncKHR is performed before using the EGLImage/texture during rendering. Unfortunately, it's not clear from the specs whether this is generally safe to do, or we need to sync before glEGLImageTargetTexture2DOES. The exception is TEXTURE_EXTERNAL_OES where the spec mentions it's enough to sync and then glBindTexture for any changes to take effect. Changes in v5: - Meson support. - Make explicit sync server error reporting more generic, supporting all explicit sync related interfaces not just wp_linux_surface_synchronization. - Fix typo in warning for missing EGL_KHR_wait_sync extension. - Support minor version 2 of the explicit sync protocol (i.e., support fences for opaque EGL buffers). Changes in v4: - Introduce and use fd_clear and and fd_move helpers. - Don't check for a valid buffer when updating surface acquire fence fd from state. - Assert that pending state acquire fence fd is always clear after a commit. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to just the renderer. - Check for EGL_KHR_wait_sync before using eglWaitSyncKHR. - Dup the acquire fence before passing to EGL. Changes in v3: - Keep acquire_fence_fd in surface instead of buffer. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to both backend and renderer. - Move comment about non-ownership of in_fence_fd to struct drm_plane_state definition. - Assert that we don't try to use planes with in-fences when using the legacy KMS API. - Remove unnecessary info from wayland error messages. - Handle acquire fence for subsurface commits. - Guard against self-update in fd_update. - Disconnect the client if acquire fence EGLSyncKHR creation or wait fails. - Use updated protocol interface names. - User correct format specifier for resource ids. - Advertise protocol for X11 backend with GL renderer. Changes in v2: - Remove sync file wait fallbacks. - Raise UNSUPPORTED_BUFFER error at commit if we have an acquire fence, but the committed buffer is not a valid linux_dmabuf. - Don't put buffers with in-fences on planes that don't support in-fences. - Don't advertise explicit sync protocol if backend does not support explicit sync. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
6 years ago
#include <inttypes.h>
#include <drm_fourcc.h>
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>
10 years ago
#include "timeline.h"
#include <libweston/libweston.h>
#include <libweston/weston-log.h>
#include "linux-dmabuf.h"
#include "viewporter-server-protocol.h"
#include "presentation-time-server-protocol.h"
#include "xdg-output-unstable-v1-server-protocol.h"
libweston: Support zwp_surface_synchronization_v1.set_acquire_fence Implement the set_acquire_fence request of the zwp_surface_synchronization_v1 interface. The implementation uses the acquire fence in two ways: 1. If the associated buffer is used as GL render source, an EGLSyncKHR is created from the fence and used to synchronize access. 2. If the associated buffer is used as a plane framebuffer, the acquire fence is treated as an in-fence for the atomic commit operation. If in-fences are not supported and the buffer has an acquire fence, we don't consider it for plane placement. If the used compositor/renderer doesn't support explicit synchronization, we don't advertise the protocol at all. Currently only the DRM and X11 backends when using the GL renderer advertise the protocol for production use. Issues for discussion --------------------- a. Currently, a server-side wait of EGLSyncKHR is performed before using the EGLImage/texture during rendering. Unfortunately, it's not clear from the specs whether this is generally safe to do, or we need to sync before glEGLImageTargetTexture2DOES. The exception is TEXTURE_EXTERNAL_OES where the spec mentions it's enough to sync and then glBindTexture for any changes to take effect. Changes in v5: - Meson support. - Make explicit sync server error reporting more generic, supporting all explicit sync related interfaces not just wp_linux_surface_synchronization. - Fix typo in warning for missing EGL_KHR_wait_sync extension. - Support minor version 2 of the explicit sync protocol (i.e., support fences for opaque EGL buffers). Changes in v4: - Introduce and use fd_clear and and fd_move helpers. - Don't check for a valid buffer when updating surface acquire fence fd from state. - Assert that pending state acquire fence fd is always clear after a commit. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to just the renderer. - Check for EGL_KHR_wait_sync before using eglWaitSyncKHR. - Dup the acquire fence before passing to EGL. Changes in v3: - Keep acquire_fence_fd in surface instead of buffer. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to both backend and renderer. - Move comment about non-ownership of in_fence_fd to struct drm_plane_state definition. - Assert that we don't try to use planes with in-fences when using the legacy KMS API. - Remove unnecessary info from wayland error messages. - Handle acquire fence for subsurface commits. - Guard against self-update in fd_update. - Disconnect the client if acquire fence EGLSyncKHR creation or wait fails. - Use updated protocol interface names. - User correct format specifier for resource ids. - Advertise protocol for X11 backend with GL renderer. Changes in v2: - Remove sync file wait fallbacks. - Raise UNSUPPORTED_BUFFER error at commit if we have an acquire fence, but the committed buffer is not a valid linux_dmabuf. - Don't put buffers with in-fences on planes that don't support in-fences. - Don't advertise explicit sync protocol if backend does not support explicit sync. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
6 years ago
#include "linux-explicit-synchronization-unstable-v1-server-protocol.h"
libweston: Support zwp_surface_synchronization_v1.get_release Implement the get_release request of the zwp_surface_synchronization_v1 interface. This commit implements the zwp_buffer_release_v1 interface. It supports the zwp_buffer_release_v1.fenced_release event for surfaces rendered by the GL renderer, and the zwp_buffer_release_v1.immediate_release event for other cases. Note that the immediate_release event is safe to be used for surface buffers used as planes in the DRM backend, since the backend releases them only after the next page flip that doesn't use the buffers has finished. Changes in v7: - Remove "partial" from commit title and description. - Fix inverted check when clearing used_in_output_repaint flag. Changes in v5: - Use the new, generic explicit sync server error reporting function. - Introduce and use weston_buffer_release_move. - Introduce internally and use weston_buffer_release_destroy. Changes in v4: - Support the zwp_buffer_release_v1.fenced_release event. - Support release fences in the GL renderer. - Assert that pending state buffer_release is always NULL after a commit. - Simplify weston_buffer_release_reference. - Move removal of destroy listener before resource destruction to avoid concerns about use-after-free in weston_buffer_release_reference - Rename weston_buffer_release_reference.busy_count to ref_count. - Add documentation for weston_buffer_release and ..._reference. Changes in v3: - Raise NO_BUFFER for get_release if no buffer has been committed, don't raise UNSUPPORTED_BUFFER for non-dmabuf buffers, so get_release works for all valid buffers. - Destroy the buffer_release object after sending an event. - Track lifetime of buffer_release objects per commit, independently of any buffers. - Use updated protocol interface names. - Use correct format specifier for resource ids. Changes in v2: - Raise UNSUPPORTED_BUFFER at commit if client has requested a buffer_release, but the committed buffer is not a valid linux_dmabuf. - Remove tests that are not viable anymore due to our inability to create dmabuf buffers and fences in a unit-test environment. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
6 years ago
#include "linux-explicit-synchronization.h"
libweston: Support zwp_surface_synchronization_v1.set_acquire_fence Implement the set_acquire_fence request of the zwp_surface_synchronization_v1 interface. The implementation uses the acquire fence in two ways: 1. If the associated buffer is used as GL render source, an EGLSyncKHR is created from the fence and used to synchronize access. 2. If the associated buffer is used as a plane framebuffer, the acquire fence is treated as an in-fence for the atomic commit operation. If in-fences are not supported and the buffer has an acquire fence, we don't consider it for plane placement. If the used compositor/renderer doesn't support explicit synchronization, we don't advertise the protocol at all. Currently only the DRM and X11 backends when using the GL renderer advertise the protocol for production use. Issues for discussion --------------------- a. Currently, a server-side wait of EGLSyncKHR is performed before using the EGLImage/texture during rendering. Unfortunately, it's not clear from the specs whether this is generally safe to do, or we need to sync before glEGLImageTargetTexture2DOES. The exception is TEXTURE_EXTERNAL_OES where the spec mentions it's enough to sync and then glBindTexture for any changes to take effect. Changes in v5: - Meson support. - Make explicit sync server error reporting more generic, supporting all explicit sync related interfaces not just wp_linux_surface_synchronization. - Fix typo in warning for missing EGL_KHR_wait_sync extension. - Support minor version 2 of the explicit sync protocol (i.e., support fences for opaque EGL buffers). Changes in v4: - Introduce and use fd_clear and and fd_move helpers. - Don't check for a valid buffer when updating surface acquire fence fd from state. - Assert that pending state acquire fence fd is always clear after a commit. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to just the renderer. - Check for EGL_KHR_wait_sync before using eglWaitSyncKHR. - Dup the acquire fence before passing to EGL. Changes in v3: - Keep acquire_fence_fd in surface instead of buffer. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to both backend and renderer. - Move comment about non-ownership of in_fence_fd to struct drm_plane_state definition. - Assert that we don't try to use planes with in-fences when using the legacy KMS API. - Remove unnecessary info from wayland error messages. - Handle acquire fence for subsurface commits. - Guard against self-update in fd_update. - Disconnect the client if acquire fence EGLSyncKHR creation or wait fails. - Use updated protocol interface names. - User correct format specifier for resource ids. - Advertise protocol for X11 backend with GL renderer. Changes in v2: - Remove sync file wait fallbacks. - Raise UNSUPPORTED_BUFFER error at commit if we have an acquire fence, but the committed buffer is not a valid linux_dmabuf. - Don't put buffers with in-fences on planes that don't support in-fences. - Don't advertise explicit sync protocol if backend does not support explicit sync. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
6 years ago
#include "shared/fd-util.h"
#include "shared/helpers.h"
#include "shared/os-compatibility.h"
#include "shared/string-helpers.h"
#include "shared/timespec-util.h"
#include "shared/signal.h"
#include "git-version.h"
#include <libweston/version.h>
#include <libweston/plugin-registry.h>
#include "pixel-formats.h"
#include "backend.h"
#include "libweston-internal.h"
libweston: introduce CMS component architecture See: https://gitlab.freedesktop.org/wayland/weston/-/issues/467#note_814985 This starts building the framework required for implementing color management. The main new interface is struct weston_color_manager. This commit also adds a no-op color manager implementation, which is used if no other color manager is loaded. This no-op color manager simply provides identity color transforms for everything, so that Weston keeps running exactly like before. weston_color_manager interface is incomplete and will be extended later. Colorspace objects are not introduced in this commit. However, when client content colorspace and output colorspace definitions are combined, they will produce color transformations from client content to output blending space and from output blending space to output space. This commit introduces a placeholder struct for color transforms, weston_color_transform. Objects of this type are expected to be heavy to create and store, which is why they are designed to be shared as much as possible, ideally making their instances unique. As color transform description is intended to be generic in libweston core, renderers and backends are expected to derive their own state for each transform object as necessary. Creating and storing the derived state maybe be expensive as well, more the reason to re-use these objects as much as possible. E.g. GL-renderer might upload a 3D LUT into a texture and keep the texture around. DRM-backend might create a KMS blob for a LUT and keep that around. As a color transform depends on both the surface and the output, a transform object may need to be created for each unique pair of them. Therefore color transforms are referenced from weston_paint_node. As paint nodes exist for not just surface+output but surface+view+output triplets, the code ensures that all paint nodes (having different view) for the same surface+output have the same color transform state. As a special case, if weston_color_transform is NULL, it means identity transform. This short-circuits some checks and memory allocations, but it does mean we use a separate member on weston_paint_node to know if the color transform has been initialized or not. Color transformations are pre-created at the weston_output paint_node_z_order_list creation step. Currently the z order lists contain all views globally, which means we populate color transforms we may never need, e.g. a view is never shown on a particular output. This problem should get fixed naturally when z order lists are constructed "pruned" in the future: to contain only those paint nodes that actually contribute to the output's image. As nothing actually supports color transforms yet, both renderers and the DRM-backend assert that they only get identity transforms. This check has the side-effect that all surface-output pairs actually get a weston_surface_color_transform_ref even though it points to NULL weston_color_transform. This design is inspired by Sebastian Wick's Weston color management work. Co-authored-by: Sebastian Wick <sebastian@sebastianwick.net> Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
4 years ago
#include "color.h"
#include "weston-log-internal.h"
/**
* \defgroup head Head
* \defgroup output Output
* \defgroup compositor Compositor
*/
compositor: add repaint delay timer This timer delays the output_repaint towards the end of the refresh period, reducing the time from repaint to present. The length of the repaint window can be set in weston.ini. The call to weston_output_schedule_repaint_reset() is delayed by one more period. If we exit the continuous repaint loop (set output->repaint_scheduled to false) in finish_frame, we may call start_repaint_loop() unnecessarily. The problem case was actually observed with two outputs on the DRM backend at 60 Hz, and 7 ms repaint-window. During a window move, one output was constantly falling off the continuous repaint loop and introducing additional one frame latency, leading to jerky window motion. This code now avoids the problem. Changes in v2: - Rename repaint_delay_timer to repaint_timer and output_repaint_delay_handler to output_repaint_timer_handler. - When computing the delay, take the current time into account. The timer uses a relative timeout, so we have to subtract any time already gone. Note, that 'gone' may also be negative. DRM has a habit of predicting the page flip timestamp so it may be still in the future when we get the completion event. - Do also a sanity check 'msec > 1000'. In the unlikely case that something fails to provide a good timestamp, never delay for more than one second. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-By: Derek Foreman <derekf@osg.samsung.com> Reviewed-by: Bryce Harrington <bryce@osg.samsung.com>
11 years ago
#define DEFAULT_REPAINT_WINDOW 7 /* milliseconds */
static void
weston_output_update_matrix(struct weston_output *output);
static void
weston_output_transform_scale_init(struct weston_output *output,
uint32_t transform, uint32_t scale);
static void
weston_compositor_build_view_list(struct weston_compositor *compositor,
struct weston_output *output);
static char *
weston_output_create_heads_string(struct weston_output *output);
static struct weston_paint_node *
weston_paint_node_create(struct weston_surface *surface,
struct weston_view *view,
struct weston_output *output)
{
struct weston_paint_node *pnode;
libweston: introduce CMS component architecture See: https://gitlab.freedesktop.org/wayland/weston/-/issues/467#note_814985 This starts building the framework required for implementing color management. The main new interface is struct weston_color_manager. This commit also adds a no-op color manager implementation, which is used if no other color manager is loaded. This no-op color manager simply provides identity color transforms for everything, so that Weston keeps running exactly like before. weston_color_manager interface is incomplete and will be extended later. Colorspace objects are not introduced in this commit. However, when client content colorspace and output colorspace definitions are combined, they will produce color transformations from client content to output blending space and from output blending space to output space. This commit introduces a placeholder struct for color transforms, weston_color_transform. Objects of this type are expected to be heavy to create and store, which is why they are designed to be shared as much as possible, ideally making their instances unique. As color transform description is intended to be generic in libweston core, renderers and backends are expected to derive their own state for each transform object as necessary. Creating and storing the derived state maybe be expensive as well, more the reason to re-use these objects as much as possible. E.g. GL-renderer might upload a 3D LUT into a texture and keep the texture around. DRM-backend might create a KMS blob for a LUT and keep that around. As a color transform depends on both the surface and the output, a transform object may need to be created for each unique pair of them. Therefore color transforms are referenced from weston_paint_node. As paint nodes exist for not just surface+output but surface+view+output triplets, the code ensures that all paint nodes (having different view) for the same surface+output have the same color transform state. As a special case, if weston_color_transform is NULL, it means identity transform. This short-circuits some checks and memory allocations, but it does mean we use a separate member on weston_paint_node to know if the color transform has been initialized or not. Color transformations are pre-created at the weston_output paint_node_z_order_list creation step. Currently the z order lists contain all views globally, which means we populate color transforms we may never need, e.g. a view is never shown on a particular output. This problem should get fixed naturally when z order lists are constructed "pruned" in the future: to contain only those paint nodes that actually contribute to the output's image. As nothing actually supports color transforms yet, both renderers and the DRM-backend assert that they only get identity transforms. This check has the side-effect that all surface-output pairs actually get a weston_surface_color_transform_ref even though it points to NULL weston_color_transform. This design is inspired by Sebastian Wick's Weston color management work. Co-authored-by: Sebastian Wick <sebastian@sebastianwick.net> Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
4 years ago
struct weston_paint_node *existing_node;
assert(view->surface == surface);
pnode = zalloc(sizeof *pnode);
if (!pnode)
return NULL;
libweston: introduce CMS component architecture See: https://gitlab.freedesktop.org/wayland/weston/-/issues/467#note_814985 This starts building the framework required for implementing color management. The main new interface is struct weston_color_manager. This commit also adds a no-op color manager implementation, which is used if no other color manager is loaded. This no-op color manager simply provides identity color transforms for everything, so that Weston keeps running exactly like before. weston_color_manager interface is incomplete and will be extended later. Colorspace objects are not introduced in this commit. However, when client content colorspace and output colorspace definitions are combined, they will produce color transformations from client content to output blending space and from output blending space to output space. This commit introduces a placeholder struct for color transforms, weston_color_transform. Objects of this type are expected to be heavy to create and store, which is why they are designed to be shared as much as possible, ideally making their instances unique. As color transform description is intended to be generic in libweston core, renderers and backends are expected to derive their own state for each transform object as necessary. Creating and storing the derived state maybe be expensive as well, more the reason to re-use these objects as much as possible. E.g. GL-renderer might upload a 3D LUT into a texture and keep the texture around. DRM-backend might create a KMS blob for a LUT and keep that around. As a color transform depends on both the surface and the output, a transform object may need to be created for each unique pair of them. Therefore color transforms are referenced from weston_paint_node. As paint nodes exist for not just surface+output but surface+view+output triplets, the code ensures that all paint nodes (having different view) for the same surface+output have the same color transform state. As a special case, if weston_color_transform is NULL, it means identity transform. This short-circuits some checks and memory allocations, but it does mean we use a separate member on weston_paint_node to know if the color transform has been initialized or not. Color transformations are pre-created at the weston_output paint_node_z_order_list creation step. Currently the z order lists contain all views globally, which means we populate color transforms we may never need, e.g. a view is never shown on a particular output. This problem should get fixed naturally when z order lists are constructed "pruned" in the future: to contain only those paint nodes that actually contribute to the output's image. As nothing actually supports color transforms yet, both renderers and the DRM-backend assert that they only get identity transforms. This check has the side-effect that all surface-output pairs actually get a weston_surface_color_transform_ref even though it points to NULL weston_color_transform. This design is inspired by Sebastian Wick's Weston color management work. Co-authored-by: Sebastian Wick <sebastian@sebastianwick.net> Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
4 years ago
/*
* Invariant: all paint nodes with the same surface+output have the
* same surf_xform state.
*/
libweston: fix paint node color invariant The invariant is clearly documented in code comments, but the code failed to ensure it in all cases. Fix it. There is one very specific protocol sequence triggered by a development version of the Wine Wayland driver when Chrome (win64 app) is switched from window to fullscreen and then back by pressing F11 key. The switch back triggered weston: ../libweston/color.c:217: weston_paint_node_ensure_color_transform: Assertion 'it->surf_xform_valid == false' failed For some reason, that specific protocol sequence causes weston_compositor_build_view_list() to create a transient second view for a sub-surface. In the Chrome traces, I have seen that happen twice per run. The first time it works, the old view gets immediately destroyed. The second time (during un-fullscreening) a new transient view is create and then it fails the invariant check. The fix is in weston_paint_node_create() which is supposed to ensure the invariant. However, it went through the (new) view's paint node list, which will not contain paint nodes from other views. In hindsight this is an obvious bug, but perhaps all views having exactly one associated surface each somehow confused the author. Since the invariant is about surface+output, go through the surface's paint node list instead. That list contains all the relevant paint nodes by definition. Fixes: https://gitlab.freedesktop.org/wayland/weston/-/issues/568 Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
3 years ago
wl_list_for_each(existing_node, &surface->paint_node_list, surface_link) {
libweston: introduce CMS component architecture See: https://gitlab.freedesktop.org/wayland/weston/-/issues/467#note_814985 This starts building the framework required for implementing color management. The main new interface is struct weston_color_manager. This commit also adds a no-op color manager implementation, which is used if no other color manager is loaded. This no-op color manager simply provides identity color transforms for everything, so that Weston keeps running exactly like before. weston_color_manager interface is incomplete and will be extended later. Colorspace objects are not introduced in this commit. However, when client content colorspace and output colorspace definitions are combined, they will produce color transformations from client content to output blending space and from output blending space to output space. This commit introduces a placeholder struct for color transforms, weston_color_transform. Objects of this type are expected to be heavy to create and store, which is why they are designed to be shared as much as possible, ideally making their instances unique. As color transform description is intended to be generic in libweston core, renderers and backends are expected to derive their own state for each transform object as necessary. Creating and storing the derived state maybe be expensive as well, more the reason to re-use these objects as much as possible. E.g. GL-renderer might upload a 3D LUT into a texture and keep the texture around. DRM-backend might create a KMS blob for a LUT and keep that around. As a color transform depends on both the surface and the output, a transform object may need to be created for each unique pair of them. Therefore color transforms are referenced from weston_paint_node. As paint nodes exist for not just surface+output but surface+view+output triplets, the code ensures that all paint nodes (having different view) for the same surface+output have the same color transform state. As a special case, if weston_color_transform is NULL, it means identity transform. This short-circuits some checks and memory allocations, but it does mean we use a separate member on weston_paint_node to know if the color transform has been initialized or not. Color transformations are pre-created at the weston_output paint_node_z_order_list creation step. Currently the z order lists contain all views globally, which means we populate color transforms we may never need, e.g. a view is never shown on a particular output. This problem should get fixed naturally when z order lists are constructed "pruned" in the future: to contain only those paint nodes that actually contribute to the output's image. As nothing actually supports color transforms yet, both renderers and the DRM-backend assert that they only get identity transforms. This check has the side-effect that all surface-output pairs actually get a weston_surface_color_transform_ref even though it points to NULL weston_color_transform. This design is inspired by Sebastian Wick's Weston color management work. Co-authored-by: Sebastian Wick <sebastian@sebastianwick.net> Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
4 years ago
assert(existing_node->surface == surface);
if (existing_node->output != output)
continue;
weston_surface_color_transform_copy(&pnode->surf_xform,
&existing_node->surf_xform);
pnode->surf_xform_valid = existing_node->surf_xform_valid;
break;
}
pnode->surface = surface;
wl_list_insert(&surface->paint_node_list, &pnode->surface_link);
pnode->view = view;
wl_list_insert(&view->paint_node_list, &pnode->view_link);
pnode->output = output;
wl_list_insert(&output->paint_node_list, &pnode->output_link);
wl_list_init(&pnode->z_order_link);
return pnode;
}
static void
weston_paint_node_destroy(struct weston_paint_node *pnode)
{
assert(pnode->view->surface == pnode->surface);
wl_list_remove(&pnode->surface_link);
wl_list_remove(&pnode->view_link);
wl_list_remove(&pnode->output_link);
wl_list_remove(&pnode->z_order_link);
libweston: introduce CMS component architecture See: https://gitlab.freedesktop.org/wayland/weston/-/issues/467#note_814985 This starts building the framework required for implementing color management. The main new interface is struct weston_color_manager. This commit also adds a no-op color manager implementation, which is used if no other color manager is loaded. This no-op color manager simply provides identity color transforms for everything, so that Weston keeps running exactly like before. weston_color_manager interface is incomplete and will be extended later. Colorspace objects are not introduced in this commit. However, when client content colorspace and output colorspace definitions are combined, they will produce color transformations from client content to output blending space and from output blending space to output space. This commit introduces a placeholder struct for color transforms, weston_color_transform. Objects of this type are expected to be heavy to create and store, which is why they are designed to be shared as much as possible, ideally making their instances unique. As color transform description is intended to be generic in libweston core, renderers and backends are expected to derive their own state for each transform object as necessary. Creating and storing the derived state maybe be expensive as well, more the reason to re-use these objects as much as possible. E.g. GL-renderer might upload a 3D LUT into a texture and keep the texture around. DRM-backend might create a KMS blob for a LUT and keep that around. As a color transform depends on both the surface and the output, a transform object may need to be created for each unique pair of them. Therefore color transforms are referenced from weston_paint_node. As paint nodes exist for not just surface+output but surface+view+output triplets, the code ensures that all paint nodes (having different view) for the same surface+output have the same color transform state. As a special case, if weston_color_transform is NULL, it means identity transform. This short-circuits some checks and memory allocations, but it does mean we use a separate member on weston_paint_node to know if the color transform has been initialized or not. Color transformations are pre-created at the weston_output paint_node_z_order_list creation step. Currently the z order lists contain all views globally, which means we populate color transforms we may never need, e.g. a view is never shown on a particular output. This problem should get fixed naturally when z order lists are constructed "pruned" in the future: to contain only those paint nodes that actually contribute to the output's image. As nothing actually supports color transforms yet, both renderers and the DRM-backend assert that they only get identity transforms. This check has the side-effect that all surface-output pairs actually get a weston_surface_color_transform_ref even though it points to NULL weston_color_transform. This design is inspired by Sebastian Wick's Weston color management work. Co-authored-by: Sebastian Wick <sebastian@sebastianwick.net> Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
4 years ago
assert(pnode->surf_xform_valid || !pnode->surf_xform.transform);
weston_surface_color_transform_fini(&pnode->surf_xform);
free(pnode);
}
/** Send wl_output events for mode and scale changes
*
* \param head Send on all resources bound to this head.
* \param mode_changed If true, send the current mode.
* \param scale_changed If true, send the current scale.
*/
static void
weston_mode_switch_send_events(struct weston_head *head,
bool mode_changed, bool scale_changed)
{
struct weston_output *output = head->output;
struct wl_resource *resource;
int version;
wl_resource_for_each(resource, &head->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);
}
version = wl_resource_get_version(resource);
if (version >= WL_OUTPUT_SCALE_SINCE_VERSION && scale_changed)
wl_output_send_scale(resource, output->current_scale);
if (version >= WL_OUTPUT_DONE_SINCE_VERSION)
wl_output_send_done(resource);
}
wl_resource_for_each(resource, &head->xdg_output_resource_list) {
zxdg_output_v1_send_logical_position(resource,
output->x,
output->y);
zxdg_output_v1_send_logical_size(resource,
output->width,
output->height);
zxdg_output_v1_send_done(resource);
}
}
static void
weston_mode_switch_finish(struct weston_output *output,
int mode_changed, int scale_changed)
{
struct weston_seat *seat;
struct weston_head *head;
pixman_region32_t old_output_region;
pixman_region32_init(&old_output_region);
pixman_region32_copy(&old_output_region, &output->region);
/* Update output region and transformation matrix */
weston_output_transform_scale_init(output, output->transform, output->current_scale);
pixman_region32_init_rect(&output->region, output->x, output->y,
output->width, output->height);
weston_output_update_matrix(output);
/* 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) {
struct weston_pointer *pointer = weston_seat_get_pointer(seat);
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);
if (!mode_changed && !scale_changed)
return;
/* notify clients of the changes */
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
wl_list_for_each(head, &output->head_list, output_link)
weston_mode_switch_send_events(head,
mode_changed, scale_changed);
}
static void
weston_compositor_reflow_outputs(struct weston_compositor *compositor,
struct weston_output *resized_output, int delta_width);
/**
* \ingroup output
*/
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;
int32_t old_width;
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;
}
}
old_width = output->width;
output->native_mode = mode;
output->native_scale = scale;
weston_mode_switch_finish(output, mode_changed, scale_changed);
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);
}
return 0;
}
/**
* \ingroup output
*/
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;
}
/**
* \ingroup output
*/
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;
}
static void
region_init_infinite(pixman_region32_t *region)
{
pixman_region32_init_rect(region, INT32_MIN, INT32_MIN,
UINT32_MAX, UINT32_MAX);
}
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>
12 years ago
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>
11 years ago
WL_EXPORT struct weston_view *
weston_view_create(struct weston_surface *surface)
{
struct weston_view *view;
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>
11 years ago
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>
8 years ago
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>
11 years ago
/* Assign to surface */
wl_list_insert(&surface->views, &view->surface_link);
wl_signal_init(&view->destroy_signal);
wl_list_init(&view->link);
wl_list_init(&view->layer_link.link);
wl_list_init(&view->paint_node_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>
11 years ago
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);
compositor: add weston_view_set_mask() API and state Add API for setting a clip ('scissor' in the code) rectangle per view, in surface coordinates. Ivi-shell requires this feature to be able to implement the IVI Layer Manager API, which includes clipping of surfaces. The names weston_view_set_mask() and weston_view_set_mask_infinite() mirror the existing weston_layer_set_mask*() functions. This view clipping complements the weston_layer clipping, because view clipping is defined in surface local coordinates, while layer mask/clipping is defined in global coordinates. View clipping requires explicit support from the renderers. Therefore a new Weston capability bit is added: WESTON_CAP_VIEW_CLIP_MASK. Shells (and all users) of this new API are required to check the capability bit is set before using the API. Otherwise the rendering will not be what they expect. View clips are inherited through the transformation inheritance mechanism. However, there are restrictions. The clip rectangle can be set only on the root view of a transformation inheritance tree. The additional transformations in child views must not rotate the coordinate axes. These restrictions avoid corner cases in clip inheritance, and keep the renderer implementations as simple as they are right now. Renderers only need to do an additional intersection with the clip rectangle which is always aligned to the surface coordinate system. For more details, see the API documentation in the patch. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Tested-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Reviewed-By: Derek Foreman <derekf@osg.samsung.com>
10 years ago
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>
11 years ago
pixman_region32_init(&view->transform.boundingbox);
view->transform.dirty = 1;
return view;
}
struct weston_presentation_feedback {
struct wl_resource *resource;
/* XXX: could use just wl_resource_get_link() instead */
struct wl_list link;
/* The per-surface feedback flags */
uint32_t psf_flags;
};
static void
weston_presentation_feedback_discard(
struct weston_presentation_feedback *feedback)
{
wp_presentation_feedback_send_discarded(feedback->resource);
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>
10 years ago
uint64_t seq,
uint32_t flags)
{
struct wl_client *client = wl_resource_get_client(feedback->resource);
struct weston_head *head;
struct wl_resource *o;
uint32_t tv_sec_hi;
uint32_t tv_sec_lo;
uint32_t tv_nsec;
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
bool done = false;
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
wl_list_for_each(head, &output->head_list, output_link) {
wl_resource_for_each(o, &head->resource_list) {
if (wl_resource_get_client(o) != client)
continue;
wp_presentation_feedback_send_sync_output(feedback->resource, o);
done = true;
}
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
/* For clone mode, send it for just one wl_output global,
* they are all equivalent anyway.
*/
if (done)
break;
}
timespec_to_proto(ts, &tv_sec_hi, &tv_sec_lo, &tv_nsec);
wp_presentation_feedback_send_presented(feedback->resource,
tv_sec_hi, tv_sec_lo, tv_nsec,
refresh_nsec,
seq >> 32, seq & 0xffffffff,
flags | feedback->psf_flags);
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>
10 years ago
uint64_t seq,
uint32_t flags)
{
struct weston_presentation_feedback *feedback, *tmp;
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>
10 years ago
wl_list_empty(list));
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>
10 years ago
refresh_nsec, ts, seq,
flags);
}
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;
pixman_region32_init(&state->damage_surface);
pixman_region32_init(&state->damage_buffer);
pixman_region32_init(&state->opaque);
region_init_infinite(&state->input);
wl_list_init(&state->frame_callback_list);
wl_list_init(&state->feedback_list);
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;
libweston: Support zwp_surface_synchronization_v1.set_acquire_fence Implement the set_acquire_fence request of the zwp_surface_synchronization_v1 interface. The implementation uses the acquire fence in two ways: 1. If the associated buffer is used as GL render source, an EGLSyncKHR is created from the fence and used to synchronize access. 2. If the associated buffer is used as a plane framebuffer, the acquire fence is treated as an in-fence for the atomic commit operation. If in-fences are not supported and the buffer has an acquire fence, we don't consider it for plane placement. If the used compositor/renderer doesn't support explicit synchronization, we don't advertise the protocol at all. Currently only the DRM and X11 backends when using the GL renderer advertise the protocol for production use. Issues for discussion --------------------- a. Currently, a server-side wait of EGLSyncKHR is performed before using the EGLImage/texture during rendering. Unfortunately, it's not clear from the specs whether this is generally safe to do, or we need to sync before glEGLImageTargetTexture2DOES. The exception is TEXTURE_EXTERNAL_OES where the spec mentions it's enough to sync and then glBindTexture for any changes to take effect. Changes in v5: - Meson support. - Make explicit sync server error reporting more generic, supporting all explicit sync related interfaces not just wp_linux_surface_synchronization. - Fix typo in warning for missing EGL_KHR_wait_sync extension. - Support minor version 2 of the explicit sync protocol (i.e., support fences for opaque EGL buffers). Changes in v4: - Introduce and use fd_clear and and fd_move helpers. - Don't check for a valid buffer when updating surface acquire fence fd from state. - Assert that pending state acquire fence fd is always clear after a commit. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to just the renderer. - Check for EGL_KHR_wait_sync before using eglWaitSyncKHR. - Dup the acquire fence before passing to EGL. Changes in v3: - Keep acquire_fence_fd in surface instead of buffer. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to both backend and renderer. - Move comment about non-ownership of in_fence_fd to struct drm_plane_state definition. - Assert that we don't try to use planes with in-fences when using the legacy KMS API. - Remove unnecessary info from wayland error messages. - Handle acquire fence for subsurface commits. - Guard against self-update in fd_update. - Disconnect the client if acquire fence EGLSyncKHR creation or wait fails. - Use updated protocol interface names. - User correct format specifier for resource ids. - Advertise protocol for X11 backend with GL renderer. Changes in v2: - Remove sync file wait fallbacks. - Raise UNSUPPORTED_BUFFER error at commit if we have an acquire fence, but the committed buffer is not a valid linux_dmabuf. - Don't put buffers with in-fences on planes that don't support in-fences. - Don't advertise explicit sync protocol if backend does not support explicit sync. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
6 years ago
state->acquire_fence_fd = -1;
state->desired_protection = WESTON_HDCP_DISABLE;
state->protection_mode = WESTON_SURFACE_PROTECTION_MODE_RELAXED;
}
static void
weston_surface_state_fini(struct weston_surface_state *state)
{
struct wl_resource *cb, *next;
wl_resource_for_each_safe(cb, next, &state->frame_callback_list)
wl_resource_destroy(cb);
weston_presentation_feedback_discard_list(&state->feedback_list);
pixman_region32_fini(&state->input);
pixman_region32_fini(&state->opaque);
pixman_region32_fini(&state->damage_surface);
pixman_region32_fini(&state->damage_buffer);
if (state->buffer)
wl_list_remove(&state->buffer_destroy_listener.link);
state->buffer = NULL;
libweston: Support zwp_surface_synchronization_v1.set_acquire_fence Implement the set_acquire_fence request of the zwp_surface_synchronization_v1 interface. The implementation uses the acquire fence in two ways: 1. If the associated buffer is used as GL render source, an EGLSyncKHR is created from the fence and used to synchronize access. 2. If the associated buffer is used as a plane framebuffer, the acquire fence is treated as an in-fence for the atomic commit operation. If in-fences are not supported and the buffer has an acquire fence, we don't consider it for plane placement. If the used compositor/renderer doesn't support explicit synchronization, we don't advertise the protocol at all. Currently only the DRM and X11 backends when using the GL renderer advertise the protocol for production use. Issues for discussion --------------------- a. Currently, a server-side wait of EGLSyncKHR is performed before using the EGLImage/texture during rendering. Unfortunately, it's not clear from the specs whether this is generally safe to do, or we need to sync before glEGLImageTargetTexture2DOES. The exception is TEXTURE_EXTERNAL_OES where the spec mentions it's enough to sync and then glBindTexture for any changes to take effect. Changes in v5: - Meson support. - Make explicit sync server error reporting more generic, supporting all explicit sync related interfaces not just wp_linux_surface_synchronization. - Fix typo in warning for missing EGL_KHR_wait_sync extension. - Support minor version 2 of the explicit sync protocol (i.e., support fences for opaque EGL buffers). Changes in v4: - Introduce and use fd_clear and and fd_move helpers. - Don't check for a valid buffer when updating surface acquire fence fd from state. - Assert that pending state acquire fence fd is always clear after a commit. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to just the renderer. - Check for EGL_KHR_wait_sync before using eglWaitSyncKHR. - Dup the acquire fence before passing to EGL. Changes in v3: - Keep acquire_fence_fd in surface instead of buffer. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to both backend and renderer. - Move comment about non-ownership of in_fence_fd to struct drm_plane_state definition. - Assert that we don't try to use planes with in-fences when using the legacy KMS API. - Remove unnecessary info from wayland error messages. - Handle acquire fence for subsurface commits. - Guard against self-update in fd_update. - Disconnect the client if acquire fence EGLSyncKHR creation or wait fails. - Use updated protocol interface names. - User correct format specifier for resource ids. - Advertise protocol for X11 backend with GL renderer. Changes in v2: - Remove sync file wait fallbacks. - Raise UNSUPPORTED_BUFFER error at commit if we have an acquire fence, but the committed buffer is not a valid linux_dmabuf. - Don't put buffers with in-fences on planes that don't support in-fences. - Don't advertise explicit sync protocol if backend does not support explicit sync. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
6 years ago
fd_clear(&state->acquire_fence_fd);
libweston: Support zwp_surface_synchronization_v1.get_release Implement the get_release request of the zwp_surface_synchronization_v1 interface. This commit implements the zwp_buffer_release_v1 interface. It supports the zwp_buffer_release_v1.fenced_release event for surfaces rendered by the GL renderer, and the zwp_buffer_release_v1.immediate_release event for other cases. Note that the immediate_release event is safe to be used for surface buffers used as planes in the DRM backend, since the backend releases them only after the next page flip that doesn't use the buffers has finished. Changes in v7: - Remove "partial" from commit title and description. - Fix inverted check when clearing used_in_output_repaint flag. Changes in v5: - Use the new, generic explicit sync server error reporting function. - Introduce and use weston_buffer_release_move. - Introduce internally and use weston_buffer_release_destroy. Changes in v4: - Support the zwp_buffer_release_v1.fenced_release event. - Support release fences in the GL renderer. - Assert that pending state buffer_release is always NULL after a commit. - Simplify weston_buffer_release_reference. - Move removal of destroy listener before resource destruction to avoid concerns about use-after-free in weston_buffer_release_reference - Rename weston_buffer_release_reference.busy_count to ref_count. - Add documentation for weston_buffer_release and ..._reference. Changes in v3: - Raise NO_BUFFER for get_release if no buffer has been committed, don't raise UNSUPPORTED_BUFFER for non-dmabuf buffers, so get_release works for all valid buffers. - Destroy the buffer_release object after sending an event. - Track lifetime of buffer_release objects per commit, independently of any buffers. - Use updated protocol interface names. - Use correct format specifier for resource ids. Changes in v2: - Raise UNSUPPORTED_BUFFER at commit if client has requested a buffer_release, but the committed buffer is not a valid linux_dmabuf. - Remove tests that are not viable anymore due to our inability to create dmabuf buffers and fences in a unit-test environment. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
6 years ago
weston_buffer_release_reference(&state->buffer_release_ref, 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);
}
WL_EXPORT struct weston_surface *
weston_surface_create(struct weston_compositor *compositor)
{
struct weston_surface *surface;
surface = zalloc(sizeof *surface);
if (surface == NULL)
return NULL;
wl_signal_init(&surface->destroy_signal);
wl_signal_init(&surface->commit_signal);
surface->compositor = compositor;
surface->ref_count = 1;
surface->buffer_viewport.buffer.transform = WL_OUTPUT_TRANSFORM_NORMAL;
surface->buffer_viewport.buffer.scale = 1;
surface->buffer_viewport.buffer.src_width = wl_fixed_from_int(-1);
surface->buffer_viewport.surface.width = -1;
weston_surface_state_init(&surface->pending);
pixman_region32_init(&surface->damage);
pixman_region32_init(&surface->opaque);
region_init_infinite(&surface->input);
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>
11 years ago
wl_list_init(&surface->views);
wl_list_init(&surface->paint_node_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>
11 years ago
wl_list_init(&surface->frame_callback_list);
wl_list_init(&surface->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>
12 years ago
wl_list_init(&surface->subsurface_list);
wl_list_init(&surface->subsurface_list_pending);
weston_matrix_init(&surface->buffer_to_surface_matrix);
weston_matrix_init(&surface->surface_to_buffer_matrix);
wl_list_init(&surface->pointer_constraints);
libweston: Support zwp_surface_synchronization_v1.set_acquire_fence Implement the set_acquire_fence request of the zwp_surface_synchronization_v1 interface. The implementation uses the acquire fence in two ways: 1. If the associated buffer is used as GL render source, an EGLSyncKHR is created from the fence and used to synchronize access. 2. If the associated buffer is used as a plane framebuffer, the acquire fence is treated as an in-fence for the atomic commit operation. If in-fences are not supported and the buffer has an acquire fence, we don't consider it for plane placement. If the used compositor/renderer doesn't support explicit synchronization, we don't advertise the protocol at all. Currently only the DRM and X11 backends when using the GL renderer advertise the protocol for production use. Issues for discussion --------------------- a. Currently, a server-side wait of EGLSyncKHR is performed before using the EGLImage/texture during rendering. Unfortunately, it's not clear from the specs whether this is generally safe to do, or we need to sync before glEGLImageTargetTexture2DOES. The exception is TEXTURE_EXTERNAL_OES where the spec mentions it's enough to sync and then glBindTexture for any changes to take effect. Changes in v5: - Meson support. - Make explicit sync server error reporting more generic, supporting all explicit sync related interfaces not just wp_linux_surface_synchronization. - Fix typo in warning for missing EGL_KHR_wait_sync extension. - Support minor version 2 of the explicit sync protocol (i.e., support fences for opaque EGL buffers). Changes in v4: - Introduce and use fd_clear and and fd_move helpers. - Don't check for a valid buffer when updating surface acquire fence fd from state. - Assert that pending state acquire fence fd is always clear after a commit. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to just the renderer. - Check for EGL_KHR_wait_sync before using eglWaitSyncKHR. - Dup the acquire fence before passing to EGL. Changes in v3: - Keep acquire_fence_fd in surface instead of buffer. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to both backend and renderer. - Move comment about non-ownership of in_fence_fd to struct drm_plane_state definition. - Assert that we don't try to use planes with in-fences when using the legacy KMS API. - Remove unnecessary info from wayland error messages. - Handle acquire fence for subsurface commits. - Guard against self-update in fd_update. - Disconnect the client if acquire fence EGLSyncKHR creation or wait fails. - Use updated protocol interface names. - User correct format specifier for resource ids. - Advertise protocol for X11 backend with GL renderer. Changes in v2: - Remove sync file wait fallbacks. - Raise UNSUPPORTED_BUFFER error at commit if we have an acquire fence, but the committed buffer is not a valid linux_dmabuf. - Don't put buffers with in-fences on planes that don't support in-fences. - Don't advertise explicit sync protocol if backend does not support explicit sync. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
6 years ago
surface->acquire_fence_fd = -1;
surface->desired_protection = WESTON_HDCP_DISABLE;
surface->current_protection = WESTON_HDCP_DISABLE;
surface->protection_mode = WESTON_SURFACE_PROTECTION_MODE_RELAXED;
return surface;
}
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>
11 years ago
weston_view_to_global_float(struct weston_view *view,
float sx, float sy, float *x, float *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>
11 years ago
if (view->transform.enabled) {
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>
11 years ago
weston_matrix_transform(&view->transform.matrix, &v);
if (fabsf(v.f[3]) < 1e-6) {
weston_log("warning: numerical instability in "
"%s(), divisor = %g\n", __func__,
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>
11 years ago
*x = sx + view->geometry.x;
*y = sy + view->geometry.y;
}
}
/** Transform a point to buffer coordinates
*
* \param width Surface width.
* \param height Surface height.
* \param transform Buffer transform.
* \param scale Buffer scale.
* \param sx Surface x coordinate of a point.
* \param sy Surface y coordinate of a point.
* \param[out] bx Buffer x coordinate of the point.
* \param[out] by Buffer Y coordinate of the point.
*
* Converts the given surface-local coordinates to buffer coordinates
* according to the given buffer transform and scale.
* This ignores wp_viewport.
*
* The given width and height must be the result of inverse scaled and
* inverse transformed buffer size.
*/
WL_EXPORT void
weston_transformed_coord(int width, int height,
enum wl_output_transform transform,
int32_t scale,
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 = sy;
*by = width - sx;
break;
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
*bx = sy;
*by = 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 = height - sy;
*by = sx;
break;
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
*bx = height - sy;
*by = width - sx;
break;
}
*bx *= scale;
*by *= scale;
}
/** Transform a rectangle to buffer coordinates
*
* \param width Surface width.
* \param height Surface height.
* \param transform Buffer transform.
* \param scale Buffer scale.
* \param rect Rectangle in surface coordinates.
* \return Rectangle in buffer coordinates.
*
* Converts the given surface-local rectangle to buffer coordinates
* according to the given buffer transform and scale. The resulting
* rectangle is guaranteed to be well-formed.
* This ignores wp_viewport.
*
* The given width and height must be the result of inverse scaled and
* inverse transformed buffer size.
*/
WL_EXPORT pixman_box32_t
weston_transformed_rect(int width, int height,
enum wl_output_transform transform,
int32_t scale,
pixman_box32_t rect)
{
float x1, x2, y1, y2;
pixman_box32_t ret;
weston_transformed_coord(width, height, transform, scale,
rect.x1, rect.y1, &x1, &y1);
weston_transformed_coord(width, height, transform, scale,
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;
}
/** 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);
}
/** Transform a region to buffer coordinates
*
* \param width Surface width.
* \param height Surface height.
* \param transform Buffer transform.
* \param scale Buffer scale.
* \param[in] src Region in surface coordinates.
* \param[out] dest Resulting region in buffer coordinates.
*
* Converts the given surface-local region to buffer coordinates
* according to the given buffer transform and scale.
* This ignores wp_viewport.
*
* The given width and height must be the result of inverse scaled and
* inverse transformed buffer size.
*
* src and dest are allowed to point to the same memory for in-place conversion.
*/
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 = 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_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 = 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_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 = 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;
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 = 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;
}
}
}
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);
}
static void
viewport_surface_to_buffer(struct weston_surface *surface,
float sx, float sy, float *bx, float *by)
{
struct weston_buffer_viewport *vp = &surface->buffer_viewport;
double src_width, src_height;
double src_x, src_y;
if (vp->buffer.src_width == wl_fixed_from_int(-1)) {
if (vp->surface.width == -1) {
*bx = sx;
*by = sy;
return;
}
src_x = 0.0;
src_y = 0.0;
src_width = surface->width_from_buffer;
src_height = surface->height_from_buffer;
} else {
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);
}
*bx = sx * src_width / surface->width + src_x;
*by = sy * src_height / surface->height + src_y;
}
WL_EXPORT void
weston_surface_to_buffer_float(struct weston_surface *surface,
float sx, float sy, float *bx, float *by)
{
struct weston_buffer_viewport *vp = &surface->buffer_viewport;
/* first transform coordinates if the viewport is set */
viewport_surface_to_buffer(surface, sx, sy, bx, by);
weston_transformed_coord(surface->width_from_buffer,
surface->height_from_buffer,
vp->buffer.transform, vp->buffer.scale,
*bx, *by, bx, by);
}
/** Transform a rectangle from surface coordinates to buffer coordinates
*
* \param surface The surface to fetch wp_viewport and buffer transformation
* 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.
*/
WL_EXPORT pixman_box32_t
weston_surface_to_buffer_rect(struct weston_surface *surface,
pixman_box32_t rect)
{
struct weston_buffer_viewport *vp = &surface->buffer_viewport;
float xf, yf;
/* first transform box coordinates if the viewport is set */
viewport_surface_to_buffer(surface, rect.x1, rect.y1, &xf, &yf);
rect.x1 = floorf(xf);
rect.y1 = floorf(yf);
viewport_surface_to_buffer(surface, rect.x2, rect.y2, &xf, &yf);
rect.x2 = ceilf(xf);
rect.y2 = ceilf(yf);
return weston_transformed_rect(surface->width_from_buffer,
surface->height_from_buffer,
vp->buffer.transform, vp->buffer.scale,
rect);
}
/** Transform a region from surface coordinates to buffer coordinates
*
* \param surface The surface to fetch wp_viewport and buffer transformation
* from.
* \param[in] surface_region The region in surface coordinates.
* \param[out] buffer_region 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
* conversion is from the coordinate rounding that takes place in
* \ref weston_surface_to_buffer_rect.
*
*/
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);
}
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>
11 years ago
weston_view_move_to_plane(struct weston_view *view,
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>
11 years ago
if (view->plane == plane)
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>
11 years ago
weston_view_damage_below(view);
view->plane = plane;
weston_surface_damage(view->surface);
}
/** 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.
*/
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>
11 years ago
weston_view_damage_below(struct weston_view *view)
{
pixman_region32_t damage;
pixman_region32_init(&damage);
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>
11 years ago
&view->clip);
if (view->plane)
pixman_region32_union(&view->plane->damage,
&view->plane->damage, &damage);
pixman_region32_fini(&damage);
weston_view_schedule_repaint(view);
}
/** Send wl_surface.enter/leave events
*
* \param surface The surface.
* \param head A head of the entered/left output.
* \param enter True if entered.
* \param leave True if left.
*
* Send the enter/leave events for all protocol objects bound to the given
* output by the client owning the surface.
*/
static void
weston_surface_send_enter_leave(struct weston_surface *surface,
struct weston_head *head,
bool enter,
bool leave)
{
struct wl_resource *wloutput;
struct wl_client *client;
assert(enter != leave);
client = wl_resource_get_client(surface->resource);
wl_resource_for_each(wloutput, &head->resource_list) {
if (wl_resource_get_client(wloutput) != client)
continue;
if (enter)
wl_surface_send_enter(surface->resource, wloutput);
if (leave)
wl_surface_send_leave(surface->resource, wloutput);
}
}
static void
weston_surface_compute_protection(struct protected_surface *psurface)
{
enum weston_hdcp_protection min_protection;
bool min_protection_valid = false;
struct weston_surface *surface = psurface->surface;
struct weston_output *output;
wl_list_for_each(output, &surface->compositor->output_list, link)
if (surface->output_mask & (1u << output->id)) {
/*
* If the content-protection is enabled with protection
* mode as RELAXED for a surface, and if
* content-recording features like: screen-shooter,
* recorder, screen-sharing, etc are on, then notify the
* client, that the protection is disabled.
*
* Note: If the protection mode is ENFORCED then there
* is no need to bother the client as the renderer takes
* care of censoring the visibility of the protected
* content.
*/
if (output->disable_planes > 0 &&
surface->protection_mode == WESTON_SURFACE_PROTECTION_MODE_RELAXED) {
min_protection = WESTON_HDCP_DISABLE;
min_protection_valid = true;
break;
}
if (!min_protection_valid) {
min_protection = output->current_protection;
min_protection_valid = true;
}
if (output->current_protection < min_protection)
min_protection = output->current_protection;
}
if (!min_protection_valid)
min_protection = WESTON_HDCP_DISABLE;
surface->current_protection = min_protection;
weston_protected_surface_send_event(psurface, surface->current_protection);
}
static void
notify_surface_protection_change(void *data)
{
struct weston_compositor *compositor = data;
struct content_protection *cp;
struct protected_surface *psurface;
cp = compositor->content_protection;
cp->surface_protection_update = NULL;
/* Notify the clients, whose surfaces are changed */
wl_list_for_each(psurface, &cp->protected_list, link)
if (psurface && psurface->surface)
weston_surface_compute_protection(psurface);
}
/**
* \param compositor weston_compositor
*
* Schedule an idle task to notify surface about the update in protection,
* if not already scheduled.
*/
static void
weston_schedule_surface_protection_update(struct weston_compositor *compositor)
{
struct content_protection *cp = compositor->content_protection;
struct wl_event_loop *loop;
if (!cp || cp->surface_protection_update)
return;
loop = wl_display_get_event_loop(compositor->wl_display);
cp->surface_protection_update = wl_event_loop_add_idle(loop,
notify_surface_protection_change,
compositor);
}
/**
* \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.
*/
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;
uint32_t output_bit;
struct weston_output *output;
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
struct weston_head *head;
es->output_mask = mask;
if (es->resource == NULL)
return;
if (different == 0)
return;
wl_list_for_each(output, &es->compositor->output_list, link) {
output_bit = 1u << output->id;
if (!(output_bit & different))
continue;
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
wl_list_for_each(head, &output->head_list, output_link) {
weston_surface_send_enter_leave(es, head,
output_bit & entered,
output_bit & left);
}
}
/*
* Change in surfaces' output mask might trigger a change in its
* protection.
*/
weston_schedule_surface_protection_update(es->compositor);
}
static void
notify_view_output_destroy(struct wl_listener *listener, void *data)
{
struct weston_view *view =
container_of(listener,
struct weston_view, output_destroy_listener);
view->output = NULL;
view->output_destroy_listener.notify = NULL;
}
/** Set the primary output of the view
*
* \param view The view whose primary output to set
* \param output The new primary output for the view
*
* Set \a output to be the primary output of the \a view.
*
* Notice that the assignment may be temporary; the primary output could be
* automatically changed. Hence, one cannot rely on the value persisting.
*
* Passing NULL as /a output will set the primary output to NULL.
*/
WL_EXPORT void
weston_view_set_output(struct weston_view *view, struct weston_output *output)
{
if (view->output_destroy_listener.notify) {
wl_list_remove(&view->output_destroy_listener.link);
view->output_destroy_listener.notify = NULL;
}
view->output = output;
if (output) {
view->output_destroy_listener.notify =
notify_view_output_destroy;
wl_signal_add(&output->destroy_signal,
&view->output_destroy_listener);
}
}
/** 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
* surface's primary output for vsync and frame callback purposes.
*
* Also notes all outputs of all of the surface's views
* in the output_mask for the surface.
*/
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>
11 years ago
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(&region);
wl_list_for_each(view, &es->views, surface_link) {
if (!view->output)
continue;
pixman_region32_intersect(&region, &view->transform.boundingbox,
&view->output->region);
e = pixman_region32_extents(&region);
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(&region);
es->output = new_output;
weston_surface_update_output_mask(es, mask);
}
/** 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
* is most visible on is set as the view's primary output.
*
* 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>
11 years ago
static void
weston_view_assign_output(struct weston_view *ev)
{
struct weston_compositor *ec = ev->surface->compositor;
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(&region);
wl_list_for_each(output, &ec->output_list, link) {
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>
11 years ago
pixman_region32_intersect(&region, &ev->transform.boundingbox,
&output->region);
e = pixman_region32_extents(&region);
area = (e->x2 - e->x1) * (e->y2 - e->y1);
if (area > 0)
mask |= 1u << output->id;
if (area >= max) {
new_output = output;
max = area;
}
}
pixman_region32_fini(&region);
weston_view_set_output(ev, new_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>
11 years ago
ev->output_mask = mask;
weston_surface_assign_output(ev->surface);
}
compositor: add weston_view_set_mask() API and state Add API for setting a clip ('scissor' in the code) rectangle per view, in surface coordinates. Ivi-shell requires this feature to be able to implement the IVI Layer Manager API, which includes clipping of surfaces. The names weston_view_set_mask() and weston_view_set_mask_infinite() mirror the existing weston_layer_set_mask*() functions. This view clipping complements the weston_layer clipping, because view clipping is defined in surface local coordinates, while layer mask/clipping is defined in global coordinates. View clipping requires explicit support from the renderers. Therefore a new Weston capability bit is added: WESTON_CAP_VIEW_CLIP_MASK. Shells (and all users) of this new API are required to check the capability bit is set before using the API. Otherwise the rendering will not be what they expect. View clips are inherited through the transformation inheritance mechanism. However, there are restrictions. The clip rectangle can be set only on the root view of a transformation inheritance tree. The additional transformations in child views must not rotate the coordinate axes. These restrictions avoid corner cases in clip inheritance, and keep the renderer implementations as simple as they are right now. Renderers only need to do an additional intersection with the clip rectangle which is always aligned to the surface coordinate system. For more details, see the API documentation in the patch. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Tested-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Reviewed-By: Derek Foreman <derekf@osg.samsung.com>
10 years ago
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);
}
static void
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>
11 years ago
pixman_region32_t *bbox)
{
float min_x = HUGE_VALF, min_y = HUGE_VALF;
float max_x = -HUGE_VALF, max_y = -HUGE_VALF;
int32_t s[4][2] = {
{ inbox->x1, inbox->y1 },
{ inbox->x1, inbox->y2 },
{ inbox->x2, inbox->y1 },
{ inbox->x2, inbox->y2 },
};
float int_x, int_y;
int i;
if (inbox->x1 == inbox->x2 || inbox->y1 == inbox->y2) {
/* avoid rounding empty bbox to 1x1 */
pixman_region32_init(bbox);
return;
}
for (i = 0; i < 4; ++i) {
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>
11 years ago
weston_view_to_global_float(view, s[i][0], s[i][1], &x, &y);
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;
}
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);
}
static void
weston_view_update_transform_scissor(struct weston_view *view,
pixman_region32_t *region)
{
struct weston_view *parent = view->geometry.parent;
if (parent) {
if (parent->geometry.scissor_enabled) {
view->geometry.scissor_enabled = true;
weston_view_transfer_scissor(parent, view);
} else {
view->geometry.scissor_enabled = false;
}
}
if (view->geometry.scissor_enabled)
pixman_region32_intersect(region, region,
&view->geometry.scissor);
}
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>
11 years ago
weston_view_update_transform_disable(struct weston_view *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>
11 years ago
view->transform.enabled = 0;
/* 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>
11 years ago
view->geometry.x = roundf(view->geometry.x);
view->geometry.y = roundf(view->geometry.y);
/* 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>
11 years ago
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;
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>
11 years ago
view->transform.matrix = view->transform.position.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>
11 years ago
view->transform.inverse = view->transform.position.matrix;
view->transform.inverse.d[12] = -view->geometry.x;
view->transform.inverse.d[13] = -view->geometry.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>
11 years ago
pixman_region32_init_rect(&view->transform.boundingbox,
compositor: add weston_view_set_mask() API and state Add API for setting a clip ('scissor' in the code) rectangle per view, in surface coordinates. Ivi-shell requires this feature to be able to implement the IVI Layer Manager API, which includes clipping of surfaces. The names weston_view_set_mask() and weston_view_set_mask_infinite() mirror the existing weston_layer_set_mask*() functions. This view clipping complements the weston_layer clipping, because view clipping is defined in surface local coordinates, while layer mask/clipping is defined in global coordinates. View clipping requires explicit support from the renderers. Therefore a new Weston capability bit is added: WESTON_CAP_VIEW_CLIP_MASK. Shells (and all users) of this new API are required to check the capability bit is set before using the API. Otherwise the rendering will not be what they expect. View clips are inherited through the transformation inheritance mechanism. However, there are restrictions. The clip rectangle can be set only on the root view of a transformation inheritance tree. The additional transformations in child views must not rotate the coordinate axes. These restrictions avoid corner cases in clip inheritance, and keep the renderer implementations as simple as they are right now. Renderers only need to do an additional intersection with the clip rectangle which is always aligned to the surface coordinate system. For more details, see the API documentation in the patch. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Tested-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Reviewed-By: Derek Foreman <derekf@osg.samsung.com>
10 years ago
0, 0,
view->surface->width,
view->surface->height);
weston_view_update_transform_scissor(view, &view->transform.boundingbox);
compositor: add weston_view_set_mask() API and state Add API for setting a clip ('scissor' in the code) rectangle per view, in surface coordinates. Ivi-shell requires this feature to be able to implement the IVI Layer Manager API, which includes clipping of surfaces. The names weston_view_set_mask() and weston_view_set_mask_infinite() mirror the existing weston_layer_set_mask*() functions. This view clipping complements the weston_layer clipping, because view clipping is defined in surface local coordinates, while layer mask/clipping is defined in global coordinates. View clipping requires explicit support from the renderers. Therefore a new Weston capability bit is added: WESTON_CAP_VIEW_CLIP_MASK. Shells (and all users) of this new API are required to check the capability bit is set before using the API. Otherwise the rendering will not be what they expect. View clips are inherited through the transformation inheritance mechanism. However, there are restrictions. The clip rectangle can be set only on the root view of a transformation inheritance tree. The additional transformations in child views must not rotate the coordinate axes. These restrictions avoid corner cases in clip inheritance, and keep the renderer implementations as simple as they are right now. Renderers only need to do an additional intersection with the clip rectangle which is always aligned to the surface coordinate system. For more details, see the API documentation in the patch. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Tested-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Reviewed-By: Derek Foreman <derekf@osg.samsung.com>
10 years ago
pixman_region32_translate(&view->transform.boundingbox,
view->geometry.x, view->geometry.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>
11 years ago
if (view->alpha == 1.0) {
if (view->surface->is_opaque) {
pixman_region32_copy(&view->transform.opaque,
&view->transform.boundingbox);
} else {
pixman_region32_copy(&view->transform.opaque,
&view->surface->opaque);
if (view->geometry.scissor_enabled)
pixman_region32_intersect(&view->transform.opaque,
&view->transform.opaque,
&view->geometry.scissor);
pixman_region32_translate(&view->transform.opaque,
view->geometry.x,
view->geometry.y);
}
}
}
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>
11 years ago
weston_view_update_transform_enable(struct weston_view *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>
11 years ago
struct weston_view *parent = view->geometry.parent;
struct weston_matrix *matrix = &view->transform.matrix;
struct weston_matrix *inverse = &view->transform.inverse;
struct weston_transform *tform;
compositor: add weston_view_set_mask() API and state Add API for setting a clip ('scissor' in the code) rectangle per view, in surface coordinates. Ivi-shell requires this feature to be able to implement the IVI Layer Manager API, which includes clipping of surfaces. The names weston_view_set_mask() and weston_view_set_mask_infinite() mirror the existing weston_layer_set_mask*() functions. This view clipping complements the weston_layer clipping, because view clipping is defined in surface local coordinates, while layer mask/clipping is defined in global coordinates. View clipping requires explicit support from the renderers. Therefore a new Weston capability bit is added: WESTON_CAP_VIEW_CLIP_MASK. Shells (and all users) of this new API are required to check the capability bit is set before using the API. Otherwise the rendering will not be what they expect. View clips are inherited through the transformation inheritance mechanism. However, there are restrictions. The clip rectangle can be set only on the root view of a transformation inheritance tree. The additional transformations in child views must not rotate the coordinate axes. These restrictions avoid corner cases in clip inheritance, and keep the renderer implementations as simple as they are right now. Renderers only need to do an additional intersection with the clip rectangle which is always aligned to the surface coordinate system. For more details, see the API documentation in the patch. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Tested-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Reviewed-By: Derek Foreman <derekf@osg.samsung.com>
10 years ago
pixman_region32_t surfregion;
const pixman_box32_t *surfbox;
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>
11 years ago
view->transform.enabled = 1;
/* 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>
11 years ago
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;
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>
11 years ago
wl_list_for_each(tform, &view->geometry.transformation_list, link)
weston_matrix_multiply(matrix, &tform->matrix);
if (parent)
weston_matrix_multiply(matrix, &parent->transform.matrix);
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>
11 years ago
weston_log("error: weston_view %p"
" transformation not invertible.\n", view);
return -1;
}
compositor: add weston_view_set_mask() API and state Add API for setting a clip ('scissor' in the code) rectangle per view, in surface coordinates. Ivi-shell requires this feature to be able to implement the IVI Layer Manager API, which includes clipping of surfaces. The names weston_view_set_mask() and weston_view_set_mask_infinite() mirror the existing weston_layer_set_mask*() functions. This view clipping complements the weston_layer clipping, because view clipping is defined in surface local coordinates, while layer mask/clipping is defined in global coordinates. View clipping requires explicit support from the renderers. Therefore a new Weston capability bit is added: WESTON_CAP_VIEW_CLIP_MASK. Shells (and all users) of this new API are required to check the capability bit is set before using the API. Otherwise the rendering will not be what they expect. View clips are inherited through the transformation inheritance mechanism. However, there are restrictions. The clip rectangle can be set only on the root view of a transformation inheritance tree. The additional transformations in child views must not rotate the coordinate axes. These restrictions avoid corner cases in clip inheritance, and keep the renderer implementations as simple as they are right now. Renderers only need to do an additional intersection with the clip rectangle which is always aligned to the surface coordinate system. For more details, see the API documentation in the patch. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Tested-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Reviewed-By: Derek Foreman <derekf@osg.samsung.com>
10 years ago
pixman_region32_init_rect(&surfregion, 0, 0,
view->surface->width, view->surface->height);
weston_view_update_transform_scissor(view, &surfregion);
compositor: add weston_view_set_mask() API and state Add API for setting a clip ('scissor' in the code) rectangle per view, in surface coordinates. Ivi-shell requires this feature to be able to implement the IVI Layer Manager API, which includes clipping of surfaces. The names weston_view_set_mask() and weston_view_set_mask_infinite() mirror the existing weston_layer_set_mask*() functions. This view clipping complements the weston_layer clipping, because view clipping is defined in surface local coordinates, while layer mask/clipping is defined in global coordinates. View clipping requires explicit support from the renderers. Therefore a new Weston capability bit is added: WESTON_CAP_VIEW_CLIP_MASK. Shells (and all users) of this new API are required to check the capability bit is set before using the API. Otherwise the rendering will not be what they expect. View clips are inherited through the transformation inheritance mechanism. However, there are restrictions. The clip rectangle can be set only on the root view of a transformation inheritance tree. The additional transformations in child views must not rotate the coordinate axes. These restrictions avoid corner cases in clip inheritance, and keep the renderer implementations as simple as they are right now. Renderers only need to do an additional intersection with the clip rectangle which is always aligned to the surface coordinate system. For more details, see the API documentation in the patch. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Tested-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Reviewed-By: Derek Foreman <derekf@osg.samsung.com>
10 years ago
surfbox = pixman_region32_extents(&surfregion);
view_compute_bbox(view, surfbox, &view->transform.boundingbox);
if (view->alpha == 1.0 &&
matrix->type == WESTON_MATRIX_TRANSFORM_TRANSLATE) {
if (view->surface->is_opaque) {
pixman_region32_copy(&view->transform.opaque,
&view->transform.boundingbox);
} else {
pixman_region32_copy(&view->transform.opaque,
&view->surface->opaque);
if (view->geometry.scissor_enabled)
pixman_region32_intersect(&view->transform.opaque,
&view->transform.opaque,
&view->geometry.scissor);
pixman_region32_translate(&view->transform.opaque,
matrix->d[12],
matrix->d[13]);
}
} else if (view->alpha == 1.0 &&
matrix->type < WESTON_MATRIX_TRANSFORM_ROTATE &&
pixman_region32_n_rects(&surfregion) == 1 &&
(pixman_region32_equal(&surfregion, &view->surface->opaque) ||
view->surface->is_opaque)) {
/* The whole surface is opaque and it is only translated and
* scaled and after applying the scissor, the result is still
* a single rectangle. In this case the boundingbox matches the
* view exactly and can be used as opaque area. */
pixman_region32_copy(&view->transform.opaque,
&view->transform.boundingbox);
}
pixman_region32_fini(&surfregion);
return 0;
}
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;
}
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>
11 years ago
weston_view_update_transform(struct weston_view *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>
11 years ago
struct weston_view *parent = view->geometry.parent;
struct weston_layer *layer;
pixman_region32_t mask;
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>
11 years ago
if (!view->transform.dirty)
return;
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>
11 years ago
weston_view_update_transform(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>
11 years ago
view->transform.dirty = 0;
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>
11 years ago
weston_view_damage_below(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>
11 years ago
pixman_region32_fini(&view->transform.boundingbox);
pixman_region32_fini(&view->transform.opaque);
pixman_region32_init(&view->transform.opaque);
/* 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>
11 years ago
if (view->geometry.transformation_list.next ==
&view->transform.position.link &&
view->geometry.transformation_list.prev ==
&view->transform.position.link &&
!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>
11 years ago
weston_view_update_transform_disable(view);
} 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>
11 years ago
if (weston_view_update_transform_enable(view) < 0)
weston_view_update_transform_disable(view);
}
layer = get_view_layer(view);
if (layer) {
pixman_region32_init_with_extents(&mask, &layer->mask);
pixman_region32_intersect(&view->transform.boundingbox,
&view->transform.boundingbox, &mask);
pixman_region32_intersect(&view->transform.opaque,
&view->transform.opaque, &mask);
pixman_region32_fini(&mask);
}
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>
11 years ago
weston_view_damage_below(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>
11 years ago
weston_view_assign_output(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>
11 years ago
wl_signal_emit(&view->surface->compositor->transform_signal,
view->surface);
}
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>
11 years ago
weston_view_geometry_dirty(struct weston_view *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>
11 years ago
struct weston_view *child;
/*
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>
11 years ago
* The invariant: if view->geometry.dirty, then all views
* in view->geometry.child_list have geometry.dirty too.
* 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>
11 years ago
if (view->transform.dirty)
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>
11 years ago
view->transform.dirty = 1;
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>
11 years ago
wl_list_for_each(child, &view->geometry.child_list,
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>
11 years ago
weston_view_geometry_dirty(child);
}
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>
11 years ago
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)
{
float xf, yf;
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>
11 years ago
weston_view_to_global_float(view,
wl_fixed_to_double(vx),
wl_fixed_to_double(vy),
&xf, &yf);
*x = wl_fixed_from_double(xf);
*y = wl_fixed_from_double(yf);
}
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>
11 years ago
weston_view_from_global_float(struct weston_view *view,
float x, float y, float *vx, float *vy)
{
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>
11 years ago
if (view->transform.enabled) {
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>
11 years ago
weston_matrix_transform(&view->transform.inverse, &v);
if (fabsf(v.f[3]) < 1e-6) {
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>
11 years ago
"weston_view_from_global(), divisor = %g\n",
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>
11 years ago
*vx = 0;
*vy = 0;
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>
11 years ago
*vx = v.f[0] / v.f[3];
*vy = 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>
11 years ago
*vx = x - view->geometry.x;
*vy = y - view->geometry.y;
}
}
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>
11 years ago
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)
{
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>
11 years ago
float vxf, vyf;
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>
11 years ago
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);
}
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>
11 years ago
weston_view_from_global(struct weston_view *view,
int32_t x, int32_t y, int32_t *vx, int32_t *vy)
{
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>
11 years ago
float vxf, vyf;
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>
11 years ago
weston_view_from_global_float(view, x, y, &vxf, &vyf);
*vx = floorf(vxf);
*vy = floorf(vyf);
}
/**
* \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().
*/
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)
if (surface->output_mask & (1u << output->id))
weston_output_schedule_repaint(output);
}
/**
* \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>
11 years ago
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)
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>
11 years ago
weston_output_schedule_repaint(output);
}
/**
* 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.
*/
WL_EXPORT void
weston_surface_damage(struct weston_surface *surface)
{
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>
11 years ago
0, 0, surface->width,
surface->height);
weston_surface_schedule_repaint(surface);
}
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>
11 years ago
weston_view_set_position(struct weston_view *view, float x, float y)
{
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>
11 years ago
view->geometry.x = x;
view->geometry.y = y;
weston_view_geometry_dirty(view);
}
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>
11 years ago
struct weston_view *view =
container_of(listener, struct weston_view,
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>
11 years ago
weston_view_set_transform_parent(view, NULL);
}
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>
11 years ago
weston_view_set_transform_parent(struct weston_view *view,
compositor: add weston_view_set_mask() API and state Add API for setting a clip ('scissor' in the code) rectangle per view, in surface coordinates. Ivi-shell requires this feature to be able to implement the IVI Layer Manager API, which includes clipping of surfaces. The names weston_view_set_mask() and weston_view_set_mask_infinite() mirror the existing weston_layer_set_mask*() functions. This view clipping complements the weston_layer clipping, because view clipping is defined in surface local coordinates, while layer mask/clipping is defined in global coordinates. View clipping requires explicit support from the renderers. Therefore a new Weston capability bit is added: WESTON_CAP_VIEW_CLIP_MASK. Shells (and all users) of this new API are required to check the capability bit is set before using the API. Otherwise the rendering will not be what they expect. View clips are inherited through the transformation inheritance mechanism. However, there are restrictions. The clip rectangle can be set only on the root view of a transformation inheritance tree. The additional transformations in child views must not rotate the coordinate axes. These restrictions avoid corner cases in clip inheritance, and keep the renderer implementations as simple as they are right now. Renderers only need to do an additional intersection with the clip rectangle which is always aligned to the surface coordinate system. For more details, see the API documentation in the patch. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Tested-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Reviewed-By: Derek Foreman <derekf@osg.samsung.com>
10 years ago
struct weston_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>
11 years ago
if (view->geometry.parent) {
wl_list_remove(&view->geometry.parent_destroy_listener.link);
wl_list_remove(&view->geometry.parent_link);
compositor: add weston_view_set_mask() API and state Add API for setting a clip ('scissor' in the code) rectangle per view, in surface coordinates. Ivi-shell requires this feature to be able to implement the IVI Layer Manager API, which includes clipping of surfaces. The names weston_view_set_mask() and weston_view_set_mask_infinite() mirror the existing weston_layer_set_mask*() functions. This view clipping complements the weston_layer clipping, because view clipping is defined in surface local coordinates, while layer mask/clipping is defined in global coordinates. View clipping requires explicit support from the renderers. Therefore a new Weston capability bit is added: WESTON_CAP_VIEW_CLIP_MASK. Shells (and all users) of this new API are required to check the capability bit is set before using the API. Otherwise the rendering will not be what they expect. View clips are inherited through the transformation inheritance mechanism. However, there are restrictions. The clip rectangle can be set only on the root view of a transformation inheritance tree. The additional transformations in child views must not rotate the coordinate axes. These restrictions avoid corner cases in clip inheritance, and keep the renderer implementations as simple as they are right now. Renderers only need to do an additional intersection with the clip rectangle which is always aligned to the surface coordinate system. For more details, see the API documentation in the patch. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Tested-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Reviewed-By: Derek Foreman <derekf@osg.samsung.com>
10 years ago
if (!parent)
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>
11 years ago
view->geometry.parent = 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>
11 years ago
view->geometry.parent_destroy_listener.notify =
transform_parent_handle_parent_destroy;
if (parent) {
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>
11 years ago
&view->geometry.parent_destroy_listener);
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>
11 years ago
&view->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>
11 years ago
weston_view_geometry_dirty(view);
}
compositor: add weston_view_set_mask() API and state Add API for setting a clip ('scissor' in the code) rectangle per view, in surface coordinates. Ivi-shell requires this feature to be able to implement the IVI Layer Manager API, which includes clipping of surfaces. The names weston_view_set_mask() and weston_view_set_mask_infinite() mirror the existing weston_layer_set_mask*() functions. This view clipping complements the weston_layer clipping, because view clipping is defined in surface local coordinates, while layer mask/clipping is defined in global coordinates. View clipping requires explicit support from the renderers. Therefore a new Weston capability bit is added: WESTON_CAP_VIEW_CLIP_MASK. Shells (and all users) of this new API are required to check the capability bit is set before using the API. Otherwise the rendering will not be what they expect. View clips are inherited through the transformation inheritance mechanism. However, there are restrictions. The clip rectangle can be set only on the root view of a transformation inheritance tree. The additional transformations in child views must not rotate the coordinate axes. These restrictions avoid corner cases in clip inheritance, and keep the renderer implementations as simple as they are right now. Renderers only need to do an additional intersection with the clip rectangle which is always aligned to the surface coordinate system. For more details, see the API documentation in the patch. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Tested-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Reviewed-By: Derek Foreman <derekf@osg.samsung.com>
10 years ago
/** 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.
*
* The rectangle is set in surface-local coordinates. Setting a clip
compositor: add weston_view_set_mask() API and state Add API for setting a clip ('scissor' in the code) rectangle per view, in surface coordinates. Ivi-shell requires this feature to be able to implement the IVI Layer Manager API, which includes clipping of surfaces. The names weston_view_set_mask() and weston_view_set_mask_infinite() mirror the existing weston_layer_set_mask*() functions. This view clipping complements the weston_layer clipping, because view clipping is defined in surface local coordinates, while layer mask/clipping is defined in global coordinates. View clipping requires explicit support from the renderers. Therefore a new Weston capability bit is added: WESTON_CAP_VIEW_CLIP_MASK. Shells (and all users) of this new API are required to check the capability bit is set before using the API. Otherwise the rendering will not be what they expect. View clips are inherited through the transformation inheritance mechanism. However, there are restrictions. The clip rectangle can be set only on the root view of a transformation inheritance tree. The additional transformations in child views must not rotate the coordinate axes. These restrictions avoid corner cases in clip inheritance, and keep the renderer implementations as simple as they are right now. Renderers only need to do an additional intersection with the clip rectangle which is always aligned to the surface coordinate system. For more details, see the API documentation in the patch. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Tested-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Reviewed-By: Derek Foreman <derekf@osg.samsung.com>
10 years ago
* 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);
}
/* 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
*/
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>
11 years ago
weston_view_is_mapped(struct weston_view *view)
{
return view->is_mapped;
}
/* Check if view is opaque in specified region
*
* \param view The view to check for opacity.
* \param region The region to check for opacity, in view coordinates.
*
* Returns true if the view is opaque in the specified region, because view
* alpha is 1.0 and either the opaque region set by the client contains the
* specified region, or the buffer pixel format or solid color is opaque.
*/
WL_EXPORT bool
weston_view_is_opaque(struct weston_view *ev, pixman_region32_t *region)
{
pixman_region32_t r;
bool ret = false;
if (ev->alpha < 1.0)
return false;
if (ev->surface->is_opaque)
return true;
if (ev->transform.dirty)
return false;
pixman_region32_init(&r);
pixman_region32_subtract(&r, region, &ev->transform.opaque);
if (!pixman_region32_not_empty(&r))
ret = true;
pixman_region32_fini(&r);
return ret;
}
/** Check if the view has a valid buffer available
*
* @param ev The view to check if it has a valid buffer.
*
* Returns true if the view has a valid buffer or false otherwise.
*/
WL_EXPORT bool
weston_view_has_valid_buffer(struct weston_view *ev)
{
if (!ev->surface->buffer_ref.buffer)
return false;
if (!ev->surface->buffer_ref.buffer->resource)
return false;
return true;
}
/** Check if the view matches the entire output
*
* @param ev The view to check.
* @param output The output to check against.
*
* Returns true if the view does indeed matches the entire output.
*/
WL_EXPORT bool
weston_view_matches_output_entirely(struct weston_view *ev,
struct weston_output *output)
{
pixman_box32_t *extents =
pixman_region32_extents(&ev->transform.boundingbox);
if (extents->x1 != output->x ||
extents->y1 != output->y ||
extents->x2 != output->x + output->width ||
extents->y2 != output->y + output->height)
return false;
return true;
}
/** Find paint node for the given view and output
*/
WL_EXPORT struct weston_paint_node *
weston_view_find_paint_node(struct weston_view *view,
struct weston_output *output)
{
struct weston_paint_node *pnode;
wl_list_for_each(pnode, &view->paint_node_list, view_link) {
assert(pnode->surface == view->surface);
if (pnode->output == output)
return pnode;
}
return NULL;
}
/* 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
*
*/
WL_EXPORT bool
weston_surface_is_mapped(struct weston_surface *surface)
{
return surface->is_mapped;
}
static void
surface_set_size(struct weston_surface *surface, int32_t width, int32_t height)
{
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);
}
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);
}
static int
fixed_round_up_to_int(wl_fixed_t f)
{
return wl_fixed_to_int(wl_fixed_from_int(1) - 1 + f);
}
static void
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)
{
assert(scale > 0);
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;
case WL_OUTPUT_TRANSFORM_90:
case WL_OUTPUT_TRANSFORM_270:
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
*width_out = height / scale;
*height_out = width / scale;
break;
default:
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;
}
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);
}
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;
if (width != 0 && vp->surface.width != -1) {
surface_set_size(surface,
vp->surface.width, vp->surface.height);
return;
}
if (width != 0 && vp->buffer.src_width != wl_fixed_from_int(-1)) {
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);
return;
}
surface_set_size(surface, width, height);
}
/** weston_compositor_get_time
* \ingroup compositor
*/
WL_EXPORT void
weston_compositor_get_time(struct timespec *time)
{
clock_gettime(CLOCK_REALTIME, time);
}
/** weston_compositor_pick_view
* \ingroup 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>
11 years ago
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)
{
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>
11 years ago
struct weston_view *view;
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);
/* Can't use paint node list: occlusion by input regions, not 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>
11 years ago
wl_list_for_each(view, &compositor->view_list, link) {
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;
compositor: add weston_view_set_mask() API and state Add API for setting a clip ('scissor' in the code) rectangle per view, in surface coordinates. Ivi-shell requires this feature to be able to implement the IVI Layer Manager API, which includes clipping of surfaces. The names weston_view_set_mask() and weston_view_set_mask_infinite() mirror the existing weston_layer_set_mask*() functions. This view clipping complements the weston_layer clipping, because view clipping is defined in surface local coordinates, while layer mask/clipping is defined in global coordinates. View clipping requires explicit support from the renderers. Therefore a new Weston capability bit is added: WESTON_CAP_VIEW_CLIP_MASK. Shells (and all users) of this new API are required to check the capability bit is set before using the API. Otherwise the rendering will not be what they expect. View clips are inherited through the transformation inheritance mechanism. However, there are restrictions. The clip rectangle can be set only on the root view of a transformation inheritance tree. The additional transformations in child views must not rotate the coordinate axes. These restrictions avoid corner cases in clip inheritance, and keep the renderer implementations as simple as they are right now. Renderers only need to do an additional intersection with the clip rectangle which is always aligned to the surface coordinate system. For more details, see the API documentation in the patch. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Tested-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Reviewed-By: Derek Foreman <derekf@osg.samsung.com>
10 years ago
if (view->geometry.scissor_enabled &&
!pixman_region32_contains_point(&view->geometry.scissor,
view_ix, view_iy, NULL))
continue;
*vx = view_x;
*vy = view_y;
return view;
}
*vx = wl_fixed_from_int(-1000000);
*vy = wl_fixed_from_int(-1000000);
return NULL;
}
static void
weston_compositor_repick(struct weston_compositor *compositor)
{
struct weston_seat *seat;
if (!compositor->session_active)
return;
wl_list_for_each(seat, &compositor->seat_list, link)
weston_seat_repick(seat);
}
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>
11 years ago
weston_view_unmap(struct weston_view *view)
{
struct weston_seat *seat;
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>
11 years ago
if (!weston_view_is_mapped(view))
return;
weston_view_damage_below(view);
weston_view_set_output(view, NULL);
view->plane = NULL;
view->is_mapped = false;
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>
11 years ago
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;
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>
11 years ago
wl_list_for_each(seat, &view->surface->compositor->seat_list, link) {
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)
weston_pointer_clear_focus(pointer);
if (touch && touch->focus == view)
weston_touch_set_focus(touch, 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>
11 years ago
}
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>
11 years ago
WL_EXPORT void
weston_surface_unmap(struct weston_surface *surface)
{
struct weston_view *view;
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>
11 years ago
wl_list_for_each(view, &surface->views, surface_link)
weston_view_unmap(view);
surface->output = NULL;
}
static void
weston_surface_reset_pending_buffer(struct weston_surface *surface)
{
weston_surface_state_set_buffer(&surface->pending, NULL);
surface->pending.sx = 0;
surface->pending.sy = 0;
surface->pending.newly_attached = 0;
surface->pending.buffer_viewport.changed = 0;
}
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>
11 years ago
WL_EXPORT void
weston_view_destroy(struct weston_view *view)
{
struct weston_paint_node *pnode, *pntmp;
weston_signal_emit_mutable(&view->destroy_signal, 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>
11 years ago
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,
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>
11 years ago
}
wl_list_for_each_safe(pnode, pntmp, &view->paint_node_list, view_link)
weston_paint_node_destroy(pnode);
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>
11 years ago
wl_list_remove(&view->link);
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>
11 years ago
pixman_region32_fini(&view->clip);
compositor: add weston_view_set_mask() API and state Add API for setting a clip ('scissor' in the code) rectangle per view, in surface coordinates. Ivi-shell requires this feature to be able to implement the IVI Layer Manager API, which includes clipping of surfaces. The names weston_view_set_mask() and weston_view_set_mask_infinite() mirror the existing weston_layer_set_mask*() functions. This view clipping complements the weston_layer clipping, because view clipping is defined in surface local coordinates, while layer mask/clipping is defined in global coordinates. View clipping requires explicit support from the renderers. Therefore a new Weston capability bit is added: WESTON_CAP_VIEW_CLIP_MASK. Shells (and all users) of this new API are required to check the capability bit is set before using the API. Otherwise the rendering will not be what they expect. View clips are inherited through the transformation inheritance mechanism. However, there are restrictions. The clip rectangle can be set only on the root view of a transformation inheritance tree. The additional transformations in child views must not rotate the coordinate axes. These restrictions avoid corner cases in clip inheritance, and keep the renderer implementations as simple as they are right now. Renderers only need to do an additional intersection with the clip rectangle which is always aligned to the surface coordinate system. For more details, see the API documentation in the patch. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Tested-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Reviewed-By: Derek Foreman <derekf@osg.samsung.com>
10 years ago
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>
11 years ago
pixman_region32_fini(&view->transform.boundingbox);
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>
11 years ago
weston_view_set_transform_parent(view, NULL);
weston_view_set_output(view, 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>
11 years ago
wl_list_remove(&view->surface_link);
free(view);
}
libweston, desktop-shell: Add a wrapper for weston_surface reference Similar to how we do it with drm_fb ref counts, increase a reference count and return the same object. Plug-in in desktop-shell when we map up the view in order to survive a weston_surface destruction. Astute readers will notice that this patch removes weston_view_destroy() while keeping the balance between removing and adding a weston_surface_unref() call in desktop_shell_destroy_surface(). The reason is to let weston_surface_unref() handle destruction on its own. If multiple references are taken, then weston_surface_unref() doesn't destroy the view, it just decreases the reference, with a latter call to weston_surface_unref() to determine if the view should be destroyed as well. This situation happens if we have close animation enabled, were we have more than one reference taken: one when mapping the view/surface and when when the surface itself was created, (what we call, a weak reference). If only a single reference is taken (for instance if we don't have close animations enabled) then this weston_surface_unref() call is inert as that reference is not set-up, leaving libweston to handle the view destruction. Following that with a weston_view_destroy() explicit call would cause a UAF as the view was previous destroyed by a weston_surface_unref() call. A side-effect of not keeping the weston_view_destroy() call would happen when tearing down the compositor. If close animations are enabled, weston_surface_unref() would not destroy the view, and because weston_view_destroy() no longer exists, we would still have the view in the other layers by the time we check-up if layers have views present. Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
3 years ago
WL_EXPORT struct weston_surface *
weston_surface_ref(struct weston_surface *surface)
{
assert(surface->ref_count < INT32_MAX &&
surface->ref_count > 0);
surface->ref_count++;
return surface;
}
WL_EXPORT void
weston_surface_unref(struct weston_surface *surface)
{
struct wl_resource *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>
11 years ago
struct weston_view *ev, *nv;
struct weston_pointer_constraint *constraint, *next_constraint;
struct weston_paint_node *pnode, *pntmp;
if (!surface)
return;
assert(surface->ref_count > 0);
if (--surface->ref_count > 0)
return;
assert(surface->resource == NULL);
weston_signal_emit_mutable(&surface->destroy_signal, 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>
12 years ago
assert(wl_list_empty(&surface->subsurface_list_pending));
assert(wl_list_empty(&surface->subsurface_list));
if (surface->dmabuf_feedback)
weston_dmabuf_feedback_destroy(surface->dmabuf_feedback);
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>
11 years ago
wl_list_for_each_safe(ev, nv, &surface->views, surface_link)
weston_view_destroy(ev);
wl_list_for_each_safe(pnode, pntmp,
&surface->paint_node_list, surface_link) {
weston_paint_node_destroy(pnode);
}
weston_surface_state_fini(&surface->pending);
weston_buffer_reference(&surface->buffer_ref, NULL,
BUFFER_WILL_NOT_BE_ACCESSED);
libweston: Support zwp_surface_synchronization_v1.get_release Implement the get_release request of the zwp_surface_synchronization_v1 interface. This commit implements the zwp_buffer_release_v1 interface. It supports the zwp_buffer_release_v1.fenced_release event for surfaces rendered by the GL renderer, and the zwp_buffer_release_v1.immediate_release event for other cases. Note that the immediate_release event is safe to be used for surface buffers used as planes in the DRM backend, since the backend releases them only after the next page flip that doesn't use the buffers has finished. Changes in v7: - Remove "partial" from commit title and description. - Fix inverted check when clearing used_in_output_repaint flag. Changes in v5: - Use the new, generic explicit sync server error reporting function. - Introduce and use weston_buffer_release_move. - Introduce internally and use weston_buffer_release_destroy. Changes in v4: - Support the zwp_buffer_release_v1.fenced_release event. - Support release fences in the GL renderer. - Assert that pending state buffer_release is always NULL after a commit. - Simplify weston_buffer_release_reference. - Move removal of destroy listener before resource destruction to avoid concerns about use-after-free in weston_buffer_release_reference - Rename weston_buffer_release_reference.busy_count to ref_count. - Add documentation for weston_buffer_release and ..._reference. Changes in v3: - Raise NO_BUFFER for get_release if no buffer has been committed, don't raise UNSUPPORTED_BUFFER for non-dmabuf buffers, so get_release works for all valid buffers. - Destroy the buffer_release object after sending an event. - Track lifetime of buffer_release objects per commit, independently of any buffers. - Use updated protocol interface names. - Use correct format specifier for resource ids. Changes in v2: - Raise UNSUPPORTED_BUFFER at commit if client has requested a buffer_release, but the committed buffer is not a valid linux_dmabuf. - Remove tests that are not viable anymore due to our inability to create dmabuf buffers and fences in a unit-test environment. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
6 years ago
weston_buffer_release_reference(&surface->buffer_release_ref, NULL);
pixman_region32_fini(&surface->damage);
pixman_region32_fini(&surface->opaque);
pixman_region32_fini(&surface->input);
wl_resource_for_each_safe(cb, next, &surface->frame_callback_list)
wl_resource_destroy(cb);
weston_presentation_feedback_discard_list(&surface->feedback_list);
wl_list_for_each_safe(constraint, next_constraint,
&surface->pointer_constraints,
link)
weston_pointer_constraint_destroy(constraint);
libweston: Support zwp_surface_synchronization_v1.set_acquire_fence Implement the set_acquire_fence request of the zwp_surface_synchronization_v1 interface. The implementation uses the acquire fence in two ways: 1. If the associated buffer is used as GL render source, an EGLSyncKHR is created from the fence and used to synchronize access. 2. If the associated buffer is used as a plane framebuffer, the acquire fence is treated as an in-fence for the atomic commit operation. If in-fences are not supported and the buffer has an acquire fence, we don't consider it for plane placement. If the used compositor/renderer doesn't support explicit synchronization, we don't advertise the protocol at all. Currently only the DRM and X11 backends when using the GL renderer advertise the protocol for production use. Issues for discussion --------------------- a. Currently, a server-side wait of EGLSyncKHR is performed before using the EGLImage/texture during rendering. Unfortunately, it's not clear from the specs whether this is generally safe to do, or we need to sync before glEGLImageTargetTexture2DOES. The exception is TEXTURE_EXTERNAL_OES where the spec mentions it's enough to sync and then glBindTexture for any changes to take effect. Changes in v5: - Meson support. - Make explicit sync server error reporting more generic, supporting all explicit sync related interfaces not just wp_linux_surface_synchronization. - Fix typo in warning for missing EGL_KHR_wait_sync extension. - Support minor version 2 of the explicit sync protocol (i.e., support fences for opaque EGL buffers). Changes in v4: - Introduce and use fd_clear and and fd_move helpers. - Don't check for a valid buffer when updating surface acquire fence fd from state. - Assert that pending state acquire fence fd is always clear after a commit. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to just the renderer. - Check for EGL_KHR_wait_sync before using eglWaitSyncKHR. - Dup the acquire fence before passing to EGL. Changes in v3: - Keep acquire_fence_fd in surface instead of buffer. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to both backend and renderer. - Move comment about non-ownership of in_fence_fd to struct drm_plane_state definition. - Assert that we don't try to use planes with in-fences when using the legacy KMS API. - Remove unnecessary info from wayland error messages. - Handle acquire fence for subsurface commits. - Guard against self-update in fd_update. - Disconnect the client if acquire fence EGLSyncKHR creation or wait fails. - Use updated protocol interface names. - User correct format specifier for resource ids. - Advertise protocol for X11 backend with GL renderer. Changes in v2: - Remove sync file wait fallbacks. - Raise UNSUPPORTED_BUFFER error at commit if we have an acquire fence, but the committed buffer is not a valid linux_dmabuf. - Don't put buffers with in-fences on planes that don't support in-fences. - Don't advertise explicit sync protocol if backend does not support explicit sync. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
6 years ago
fd_clear(&surface->acquire_fence_fd);
free(surface);
}
static void
destroy_surface(struct wl_resource *resource)
{
struct weston_surface *surface = wl_resource_get_user_data(resource);
assert(surface);
/* 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_unref() call. */
surface->resource = NULL;
if (surface->viewport_resource)
wl_resource_set_user_data(surface->viewport_resource, NULL);
libweston: Introduce zwp_linux_explicit_synchronization_v1 Introduce support for the zwp_linux_explicit_synchronization_unstable_v1 protocol with an implementation of the zwp_linux_explicit_synchronization_v1 interface. Explicit synchronization provides a more versatile notification mechanism for buffer readiness and availability, and can be used to improve efficiency by integrating with related functionality in display and graphics APIs. In addition, the per-commit nature of the release events provided by this protocol potentially offers a solution to a deficiency of the wl_buffer.release event (see https://gitlab.freedesktop.org/wayland/wayland/issues/46). Support for this protocol depends on the capabilities of the backend, so we don't register it by default but provide a function which each backend will need to call. In this commit only the headless backend when using the noop renderer supports this to enable testing. Note that the zwp_surface_synchronization_v1 interface, which contains the core functionality of the protocol, is not implemented in this commit. Support for it will be added in future commits. Changes in v7: - Added some information in the commit message about the benefits of the explicit sync protocol. Changes in v6: - Fall back to advertising minor version 1 of the explicit sync protocol, although we support minor version 2 features, until the new wayland-protocols version is released. Changes in v5: - Meson support. - Advertise minor version 2 of the explicit sync protocol. Changes in v4: - Enable explicit sync support in the headless backend for all renderers. Changes in v3: - Use wl_resource_get_version() instead of hardcoding version 1. - Use updated protocol interface names. - Use correct format specifier for resource id. - Change test name to 'linux-explicit-synchronization.weston' (s/_/-/g). Changes in v2: - Move implementation to separate file so protocol can be registered on demand by backends. - Register protocol in headless+noop backend for testing purposes. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
6 years ago
if (surface->synchronization_resource) {
wl_resource_set_user_data(surface->synchronization_resource,
NULL);
}
weston_surface_unref(surface);
}
static void
weston_buffer_destroy_handler(struct wl_listener *listener, void *data)
{
struct weston_buffer *buffer =
container_of(listener, struct weston_buffer, destroy_listener);
buffer->resource = NULL;
buffer->shm_buffer = NULL;
if (buffer->busy_count + buffer->passive_count > 0)
return;
weston_signal_emit_mutable(&buffer->destroy_signal, buffer);
free(buffer);
}
WL_EXPORT struct weston_buffer *
weston_buffer_from_resource(struct weston_compositor *ec,
struct wl_resource *resource)
{
struct weston_buffer *buffer;
struct wl_shm_buffer *shm;
struct linux_dmabuf_buffer *dmabuf;
struct wl_listener *listener;
listener = wl_resource_get_destroy_listener(resource,
weston_buffer_destroy_handler);
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;
wl_resource_add_destroy_listener(resource, &buffer->destroy_listener);
if ((shm = wl_shm_buffer_get(buffer->resource))) {
buffer->type = WESTON_BUFFER_SHM;
buffer->shm_buffer = shm;
buffer->width = wl_shm_buffer_get_width(shm);
buffer->height = wl_shm_buffer_get_height(shm);
buffer->buffer_origin = ORIGIN_TOP_LEFT;
/* wl_shm might create a buffer with an unknown format, so check
* and reject */
buffer->pixel_format =
pixel_format_get_info_shm(wl_shm_buffer_get_format(shm));
buffer->format_modifier = DRM_FORMAT_MOD_LINEAR;
if (!buffer->pixel_format || buffer->pixel_format->hide_from_clients)
goto fail;
} else if ((dmabuf = linux_dmabuf_buffer_get(buffer->resource))) {
buffer->type = WESTON_BUFFER_DMABUF;
buffer->dmabuf = dmabuf;
buffer->direct_display = dmabuf->direct_display;
buffer->width = dmabuf->attributes.width;
buffer->height = dmabuf->attributes.height;
buffer->pixel_format =
pixel_format_get_info(dmabuf->attributes.format);
/* dmabuf import should assure we don't create a buffer with an
* unknown format */
assert(buffer->pixel_format && !buffer->pixel_format->hide_from_clients);
buffer->format_modifier = dmabuf->attributes.modifier[0];
if (dmabuf->attributes.flags & ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT)
buffer->buffer_origin = ORIGIN_BOTTOM_LEFT;
else
buffer->buffer_origin = ORIGIN_TOP_LEFT;
} else {
/* Only taken for legacy EGL buffers */
if (!ec->renderer->fill_buffer_info ||
!ec->renderer->fill_buffer_info(ec, buffer)) {
goto fail;
}
buffer->type = WESTON_BUFFER_RENDERER_OPAQUE;
}
/* Don't accept any formats we can't reason about: the importer should
* make sure this never happens */
assert(buffer->pixel_format);
return buffer;
fail:
wl_list_remove(&buffer->destroy_listener.link);
free(buffer);
return NULL;
}
WL_EXPORT void
weston_buffer_reference(struct weston_buffer_reference *ref,
struct weston_buffer *buffer,
enum weston_buffer_reference_type type)
{
struct weston_buffer_reference old_ref = *ref;
assert(buffer != NULL || type == BUFFER_WILL_NOT_BE_ACCESSED);
if (buffer == ref->buffer && type == ref->type)
return;
/* First ref the incoming buffer, so we keep positive refcount */
if (buffer) {
if (type == BUFFER_MAY_BE_ACCESSED)
buffer->busy_count++;
else
buffer->passive_count++;
}
ref->buffer = buffer;
ref->type = type;
/* Now drop refs to the old buffer, if any */
if (!old_ref.buffer)
return;
ref = NULL; /* will no longer be accessed */
if (old_ref.type == BUFFER_MAY_BE_ACCESSED) {
assert(old_ref.buffer->busy_count > 0);
old_ref.buffer->busy_count--;
/* If the wl_buffer lives, then hold on to the weston_buffer,
* but send a release event to the client */
if (old_ref.buffer->busy_count == 0 &&
old_ref.buffer->resource) {
assert(wl_resource_get_client(old_ref.buffer->resource));
wl_buffer_send_release(old_ref.buffer->resource);
}
} else if (old_ref.type == BUFFER_WILL_NOT_BE_ACCESSED) {
assert(old_ref.buffer->passive_count > 0);
old_ref.buffer->passive_count--;
} else {
assert(!"unknown buffer ref type");
}
/* If the wl_buffer has gone and this was the last ref, destroy the
* weston_buffer, since we'll never need it again */
if (old_ref.buffer->busy_count + old_ref.buffer->passive_count == 0 &&
!old_ref.buffer->resource) {
weston_signal_emit_mutable(&old_ref.buffer->destroy_signal,
old_ref.buffer);
free(old_ref.buffer);
}
}
libweston: Support zwp_surface_synchronization_v1.get_release Implement the get_release request of the zwp_surface_synchronization_v1 interface. This commit implements the zwp_buffer_release_v1 interface. It supports the zwp_buffer_release_v1.fenced_release event for surfaces rendered by the GL renderer, and the zwp_buffer_release_v1.immediate_release event for other cases. Note that the immediate_release event is safe to be used for surface buffers used as planes in the DRM backend, since the backend releases them only after the next page flip that doesn't use the buffers has finished. Changes in v7: - Remove "partial" from commit title and description. - Fix inverted check when clearing used_in_output_repaint flag. Changes in v5: - Use the new, generic explicit sync server error reporting function. - Introduce and use weston_buffer_release_move. - Introduce internally and use weston_buffer_release_destroy. Changes in v4: - Support the zwp_buffer_release_v1.fenced_release event. - Support release fences in the GL renderer. - Assert that pending state buffer_release is always NULL after a commit. - Simplify weston_buffer_release_reference. - Move removal of destroy listener before resource destruction to avoid concerns about use-after-free in weston_buffer_release_reference - Rename weston_buffer_release_reference.busy_count to ref_count. - Add documentation for weston_buffer_release and ..._reference. Changes in v3: - Raise NO_BUFFER for get_release if no buffer has been committed, don't raise UNSUPPORTED_BUFFER for non-dmabuf buffers, so get_release works for all valid buffers. - Destroy the buffer_release object after sending an event. - Track lifetime of buffer_release objects per commit, independently of any buffers. - Use updated protocol interface names. - Use correct format specifier for resource ids. Changes in v2: - Raise UNSUPPORTED_BUFFER at commit if client has requested a buffer_release, but the committed buffer is not a valid linux_dmabuf. - Remove tests that are not viable anymore due to our inability to create dmabuf buffers and fences in a unit-test environment. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
6 years ago
static void
weston_buffer_release_reference_handle_destroy(struct wl_listener *listener,
void *data)
{
struct weston_buffer_release_reference *ref =
container_of(listener, struct weston_buffer_release_reference,
destroy_listener);
assert((struct wl_resource *)data == ref->buffer_release->resource);
ref->buffer_release = NULL;
}
static void
weston_buffer_release_destroy(struct weston_buffer_release *buffer_release)
{
struct wl_resource *resource = buffer_release->resource;
int release_fence_fd = buffer_release->fence_fd;
if (release_fence_fd >= 0) {
zwp_linux_buffer_release_v1_send_fenced_release(
resource, release_fence_fd);
} else {
zwp_linux_buffer_release_v1_send_immediate_release(
resource);
}
wl_resource_destroy(resource);
}
WL_EXPORT void
weston_buffer_release_reference(struct weston_buffer_release_reference *ref,
struct weston_buffer_release *buffer_release)
{
if (buffer_release == ref->buffer_release)
return;
if (ref->buffer_release) {
ref->buffer_release->ref_count--;
wl_list_remove(&ref->destroy_listener.link);
if (ref->buffer_release->ref_count == 0)
weston_buffer_release_destroy(ref->buffer_release);
}
if (buffer_release) {
buffer_release->ref_count++;
wl_resource_add_destroy_listener(buffer_release->resource,
&ref->destroy_listener);
}
ref->buffer_release = buffer_release;
ref->destroy_listener.notify =
weston_buffer_release_reference_handle_destroy;
}
WL_EXPORT void
weston_buffer_release_move(struct weston_buffer_release_reference *dest,
struct weston_buffer_release_reference *src)
{
weston_buffer_release_reference(dest, src->buffer_release);
weston_buffer_release_reference(src, NULL);
}
WL_EXPORT struct weston_buffer_reference *
weston_buffer_create_solid_rgba(struct weston_compositor *compositor,
float r, float g, float b, float a)
{
struct weston_buffer_reference *ret = zalloc(sizeof(*ret));
struct weston_buffer *buffer;
if (!ret)
return NULL;
buffer = zalloc(sizeof(*buffer));
if (!buffer) {
free(ret);
return NULL;
}
wl_signal_init(&buffer->destroy_signal);
buffer->type = WESTON_BUFFER_SOLID;
buffer->width = 1;
buffer->height = 1;
buffer->buffer_origin = ORIGIN_TOP_LEFT;
buffer->solid.r = r;
buffer->solid.g = g;
buffer->solid.b = b;
buffer->solid.a = a;
if (a == 1.0) {
buffer->pixel_format =
pixel_format_get_info_shm(WL_SHM_FORMAT_XRGB8888);
} else {
buffer->pixel_format =
pixel_format_get_info_shm(WL_SHM_FORMAT_ARGB8888);
}
buffer->format_modifier = DRM_FORMAT_MOD_LINEAR;
weston_buffer_reference(ret, buffer, BUFFER_MAY_BE_ACCESSED);
return ret;
}
WL_EXPORT void
weston_surface_attach_solid(struct weston_surface *surface,
struct weston_buffer_reference *buffer_ref,
int w, int h)
{
struct weston_buffer *buffer = buffer_ref->buffer;
assert(buffer);
assert(buffer->type == WESTON_BUFFER_SOLID);
weston_buffer_reference(&surface->buffer_ref, buffer,
BUFFER_MAY_BE_ACCESSED);
surface->compositor->renderer->attach(surface, buffer);
weston_surface_set_size(surface, w, h);
pixman_region32_fini(&surface->opaque);
if (buffer->solid.a == 1.0) {
surface->is_opaque = true;
pixman_region32_init_rect(&surface->opaque, 0, 0, w, h);
} else {
surface->is_opaque = false;
pixman_region32_init(&surface->opaque);
}
}
WL_EXPORT void
weston_buffer_destroy_solid(struct weston_buffer_reference *buffer_ref)
{
assert(buffer_ref);
assert(buffer_ref->buffer);
assert(buffer_ref->type == BUFFER_MAY_BE_ACCESSED);
assert(buffer_ref->buffer->type == WESTON_BUFFER_SOLID);
weston_buffer_reference(buffer_ref, NULL, BUFFER_WILL_NOT_BE_ACCESSED);
free(buffer_ref);
}
static void
weston_surface_attach(struct weston_surface *surface,
struct weston_buffer *buffer)
{
weston_buffer_reference(&surface->buffer_ref, buffer,
buffer ? BUFFER_MAY_BE_ACCESSED :
BUFFER_WILL_NOT_BE_ACCESSED);
if (!buffer) {
if (weston_surface_is_mapped(surface))
weston_surface_unmap(surface);
}
surface->compositor->renderer->attach(surface, buffer);
weston_surface_calculate_size_from_buffer(surface);
weston_presentation_feedback_discard_list(&surface->feedback_list);
if (buffer)
surface->is_opaque = pixel_format_is_opaque(buffer->pixel_format);
}
/** weston_compositor_damage_all
* \ingroup compositor
*/
WL_EXPORT void
weston_compositor_damage_all(struct weston_compositor *compositor)
{
struct weston_output *output;
wl_list_for_each(output, &compositor->output_list, link)
weston_output_damage(output);
}
/**
* \ingroup output
*/
WL_EXPORT void
weston_output_damage(struct weston_output *output)
{
struct weston_compositor *compositor = output->compositor;
pixman_region32_union(&compositor->primary_plane.damage,
&compositor->primary_plane.damage,
&output->region);
weston_output_schedule_repaint(output);
}
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>
11 years ago
surface_flush_damage(struct weston_surface *surface)
{
struct weston_buffer *buffer = surface->buffer_ref.buffer;
if (buffer && buffer->type == WESTON_BUFFER_SHM)
surface->compositor->renderer->flush_damage(surface, buffer);
if (pixman_region32_not_empty(&surface->damage))
TL_POINT(surface->compositor, "core_flush_damage", TLP_SURFACE(surface),
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>
10 years ago
TLP_OUTPUT(surface->output), TLP_END);
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>
11 years ago
}
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) {
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>
11 years ago
extents = pixman_region32_extents(&view->surface->damage);
view_compute_bbox(view, extents, &damage);
} 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>
11 years ago
pixman_region32_copy(&damage, &view->surface->damage);
pixman_region32_translate(&damage,
view->geometry.x, view->geometry.y);
}
compositor: add weston_view_set_mask() API and state Add API for setting a clip ('scissor' in the code) rectangle per view, in surface coordinates. Ivi-shell requires this feature to be able to implement the IVI Layer Manager API, which includes clipping of surfaces. The names weston_view_set_mask() and weston_view_set_mask_infinite() mirror the existing weston_layer_set_mask*() functions. This view clipping complements the weston_layer clipping, because view clipping is defined in surface local coordinates, while layer mask/clipping is defined in global coordinates. View clipping requires explicit support from the renderers. Therefore a new Weston capability bit is added: WESTON_CAP_VIEW_CLIP_MASK. Shells (and all users) of this new API are required to check the capability bit is set before using the API. Otherwise the rendering will not be what they expect. View clips are inherited through the transformation inheritance mechanism. However, there are restrictions. The clip rectangle can be set only on the root view of a transformation inheritance tree. The additional transformations in child views must not rotate the coordinate axes. These restrictions avoid corner cases in clip inheritance, and keep the renderer implementations as simple as they are right now. Renderers only need to do an additional intersection with the clip rectangle which is always aligned to the surface coordinate system. For more details, see the API documentation in the patch. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Tested-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Reviewed-By: Derek Foreman <derekf@osg.samsung.com>
10 years ago
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>
11 years ago
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);
pixman_region32_union(opaque, opaque, &view->transform.opaque);
}
static void
output_accumulate_damage(struct weston_output *output)
{
struct weston_compositor *ec = output->compositor;
struct weston_plane *plane;
struct weston_paint_node *pnode;
pixman_region32_t opaque, clip;
pixman_region32_init(&clip);
wl_list_for_each(plane, &ec->plane_list, link) {
pixman_region32_copy(&plane->clip, &clip);
pixman_region32_init(&opaque);
wl_list_for_each(pnode, &output->paint_node_z_order_list,
z_order_link) {
if (pnode->view->plane != plane)
continue;
view_accumulate_damage(pnode->view, &opaque);
}
pixman_region32_union(&clip, &clip, &opaque);
pixman_region32_fini(&opaque);
}
pixman_region32_fini(&clip);
wl_list_for_each(pnode, &output->paint_node_z_order_list,
z_order_link) {
pnode->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>
11 years ago
wl_list_for_each(pnode, &output->paint_node_z_order_list,
z_order_link) {
/* Ignore views not visible on the current output */
/* TODO: turn this into assert once z_order_list is pruned. */
if (!(pnode->view->output_mask & (1u << output->id)))
continue;
if (pnode->surface->touched)
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>
11 years ago
continue;
pnode->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>
11 years ago
surface_flush_damage(pnode->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>
11 years ago
/* 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.
*/
if (!pnode->surface->keep_buffer) {
weston_buffer_reference(&pnode->surface->buffer_ref,
pnode->surface->buffer_ref.buffer,
BUFFER_WILL_NOT_BE_ACCESSED);
libweston: Support zwp_surface_synchronization_v1.get_release Implement the get_release request of the zwp_surface_synchronization_v1 interface. This commit implements the zwp_buffer_release_v1 interface. It supports the zwp_buffer_release_v1.fenced_release event for surfaces rendered by the GL renderer, and the zwp_buffer_release_v1.immediate_release event for other cases. Note that the immediate_release event is safe to be used for surface buffers used as planes in the DRM backend, since the backend releases them only after the next page flip that doesn't use the buffers has finished. Changes in v7: - Remove "partial" from commit title and description. - Fix inverted check when clearing used_in_output_repaint flag. Changes in v5: - Use the new, generic explicit sync server error reporting function. - Introduce and use weston_buffer_release_move. - Introduce internally and use weston_buffer_release_destroy. Changes in v4: - Support the zwp_buffer_release_v1.fenced_release event. - Support release fences in the GL renderer. - Assert that pending state buffer_release is always NULL after a commit. - Simplify weston_buffer_release_reference. - Move removal of destroy listener before resource destruction to avoid concerns about use-after-free in weston_buffer_release_reference - Rename weston_buffer_release_reference.busy_count to ref_count. - Add documentation for weston_buffer_release and ..._reference. Changes in v3: - Raise NO_BUFFER for get_release if no buffer has been committed, don't raise UNSUPPORTED_BUFFER for non-dmabuf buffers, so get_release works for all valid buffers. - Destroy the buffer_release object after sending an event. - Track lifetime of buffer_release objects per commit, independently of any buffers. - Use updated protocol interface names. - Use correct format specifier for resource ids. Changes in v2: - Raise UNSUPPORTED_BUFFER at commit if client has requested a buffer_release, but the committed buffer is not a valid linux_dmabuf. - Remove tests that are not viable anymore due to our inability to create dmabuf buffers and fences in a unit-test environment. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
6 years ago
weston_buffer_release_reference(
&pnode->surface->buffer_release_ref, NULL);
libweston: Support zwp_surface_synchronization_v1.get_release Implement the get_release request of the zwp_surface_synchronization_v1 interface. This commit implements the zwp_buffer_release_v1 interface. It supports the zwp_buffer_release_v1.fenced_release event for surfaces rendered by the GL renderer, and the zwp_buffer_release_v1.immediate_release event for other cases. Note that the immediate_release event is safe to be used for surface buffers used as planes in the DRM backend, since the backend releases them only after the next page flip that doesn't use the buffers has finished. Changes in v7: - Remove "partial" from commit title and description. - Fix inverted check when clearing used_in_output_repaint flag. Changes in v5: - Use the new, generic explicit sync server error reporting function. - Introduce and use weston_buffer_release_move. - Introduce internally and use weston_buffer_release_destroy. Changes in v4: - Support the zwp_buffer_release_v1.fenced_release event. - Support release fences in the GL renderer. - Assert that pending state buffer_release is always NULL after a commit. - Simplify weston_buffer_release_reference. - Move removal of destroy listener before resource destruction to avoid concerns about use-after-free in weston_buffer_release_reference - Rename weston_buffer_release_reference.busy_count to ref_count. - Add documentation for weston_buffer_release and ..._reference. Changes in v3: - Raise NO_BUFFER for get_release if no buffer has been committed, don't raise UNSUPPORTED_BUFFER for non-dmabuf buffers, so get_release works for all valid buffers. - Destroy the buffer_release object after sending an event. - Track lifetime of buffer_release objects per commit, independently of any buffers. - Use updated protocol interface names. - Use correct format specifier for resource ids. Changes in v2: - Raise UNSUPPORTED_BUFFER at commit if client has requested a buffer_release, but the committed buffer is not a valid linux_dmabuf. - Remove tests that are not viable anymore due to our inability to create dmabuf buffers and fences in a unit-test environment. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
6 years ago
}
}
}
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>
12 years ago
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>
11 years ago
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>
12 years ago
{
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>
11 years ago
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>
12 years ago
}
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>
11 years ago
}
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>
12 years ago
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>
11 years ago
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>
12 years ago
continue;
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>
11 years ago
weston_view_destroy(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>
11 years ago
surface_free_unused_subsurface_views(sub->surface);
}
}
static struct weston_paint_node *
view_ensure_paint_node(struct weston_view *view, struct weston_output *output)
{
struct weston_paint_node *pnode;
if (!output)
return NULL;
pnode = weston_view_find_paint_node(view, output);
if (pnode)
return pnode;
return weston_paint_node_create(view->surface, view, output);
}
static void
add_to_z_order_list(struct weston_output *output,
struct weston_paint_node *pnode)
{
if (!pnode)
return;
wl_list_remove(&pnode->z_order_link);
wl_list_insert(output->paint_node_z_order_list.prev,
&pnode->z_order_link);
libweston: introduce CMS component architecture See: https://gitlab.freedesktop.org/wayland/weston/-/issues/467#note_814985 This starts building the framework required for implementing color management. The main new interface is struct weston_color_manager. This commit also adds a no-op color manager implementation, which is used if no other color manager is loaded. This no-op color manager simply provides identity color transforms for everything, so that Weston keeps running exactly like before. weston_color_manager interface is incomplete and will be extended later. Colorspace objects are not introduced in this commit. However, when client content colorspace and output colorspace definitions are combined, they will produce color transformations from client content to output blending space and from output blending space to output space. This commit introduces a placeholder struct for color transforms, weston_color_transform. Objects of this type are expected to be heavy to create and store, which is why they are designed to be shared as much as possible, ideally making their instances unique. As color transform description is intended to be generic in libweston core, renderers and backends are expected to derive their own state for each transform object as necessary. Creating and storing the derived state maybe be expensive as well, more the reason to re-use these objects as much as possible. E.g. GL-renderer might upload a 3D LUT into a texture and keep the texture around. DRM-backend might create a KMS blob for a LUT and keep that around. As a color transform depends on both the surface and the output, a transform object may need to be created for each unique pair of them. Therefore color transforms are referenced from weston_paint_node. As paint nodes exist for not just surface+output but surface+view+output triplets, the code ensures that all paint nodes (having different view) for the same surface+output have the same color transform state. As a special case, if weston_color_transform is NULL, it means identity transform. This short-circuits some checks and memory allocations, but it does mean we use a separate member on weston_paint_node to know if the color transform has been initialized or not. Color transformations are pre-created at the weston_output paint_node_z_order_list creation step. Currently the z order lists contain all views globally, which means we populate color transforms we may never need, e.g. a view is never shown on a particular output. This problem should get fixed naturally when z order lists are constructed "pruned" in the future: to contain only those paint nodes that actually contribute to the output's image. As nothing actually supports color transforms yet, both renderers and the DRM-backend assert that they only get identity transforms. This check has the side-effect that all surface-output pairs actually get a weston_surface_color_transform_ref even though it points to NULL weston_color_transform. This design is inspired by Sebastian Wick's Weston color management work. Co-authored-by: Sebastian Wick <sebastian@sebastianwick.net> Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
4 years ago
/*
* Building weston_output::paint_node_z_order_list ensures all
* necessary color transform objects are installed.
*/
weston_paint_node_ensure_color_transform(pnode);
}
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>
11 years ago
static void
view_list_add_subsurface_view(struct weston_compositor *compositor,
struct weston_subsurface *sub,
struct weston_view *parent,
struct weston_output *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>
11 years ago
{
struct weston_subsurface *child;
struct weston_view *view = NULL, *iv;
struct weston_paint_node *pnode;
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>
11 years ago
10 years ago
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>
11 years ago
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>
12 years ago
}
}
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>
11 years ago
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);
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>
11 years ago
weston_view_set_transform_parent(view, parent);
}
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>
11 years ago
weston_view_update_transform(view);
view->is_mapped = true;
pnode = view_ensure_paint_node(view, 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>
11 years ago
if (wl_list_empty(&sub->surface->subsurface_list)) {
wl_list_insert(compositor->view_list.prev, &view->link);
add_to_z_order_list(output, pnode);
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);
add_to_z_order_list(output, pnode);
} else {
view_list_add_subsurface_view(compositor, child, view, 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>
12 years ago
}
/* This recursively adds the sub-surfaces for a view, relying on the
* sub-surface order. Thus, if a client restacks the sub-surfaces, that
* change first happens to the sub-surface list, and then automatically
* propagates here. See weston_surface_damage_subsurfaces() for how the
* sub-surfaces receive damage when the client changes the state.
*/
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>
12 years ago
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>
11 years ago
view_list_add(struct weston_compositor *compositor,
struct weston_view *view,
struct weston_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>
12 years ago
{
struct weston_paint_node *pnode;
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>
11 years ago
struct weston_subsurface *sub;
weston_view_update_transform(view);
pnode = view_ensure_paint_node(view, 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>
11 years ago
if (wl_list_empty(&view->surface->subsurface_list)) {
wl_list_insert(compositor->view_list.prev, &view->link);
add_to_z_order_list(output, pnode);
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);
add_to_z_order_list(output, pnode);
} else {
view_list_add_subsurface_view(compositor, sub, view, 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>
11 years ago
}
static void
weston_compositor_build_view_list(struct weston_compositor *compositor,
struct weston_output *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>
11 years ago
{
struct weston_view *view, *tmp;
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>
12 years ago
struct weston_layer *layer;
if (output) {
wl_list_remove(&output->paint_node_z_order_list);
wl_list_init(&output->paint_node_z_order_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>
11 years ago
wl_list_for_each(layer, &compositor->layer_list, link)
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>
11 years ago
surface_stash_subsurface_views(view->surface);
wl_list_for_each_safe(view, tmp, &compositor->view_list, link)
wl_list_init(&view->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>
11 years ago
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>
12 years ago
wl_list_for_each(layer, &compositor->layer_list, link) {
wl_list_for_each(view, &layer->view_list.link, layer_link.link) {
view_list_add(compositor, view, 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>
12 years ago
}
}
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>
11 years ago
wl_list_for_each(layer, &compositor->layer_list, link)
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>
11 years ago
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>
12 years ago
}
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);
}
static int
weston_output_repaint(struct weston_output *output)
{
struct weston_compositor *ec = output->compositor;
struct weston_paint_node *pnode;
struct weston_animation *animation, *next;
struct wl_resource *cb, *cnext;
struct wl_list frame_callback_list;
pixman_region32_t output_damage;
int r;
uint32_t frame_time_msec;
enum weston_hdcp_protection highest_requested = WESTON_HDCP_DISABLE;
if (output->destroying)
return 0;
TL_POINT(ec, "core_repaint_begin", TLP_OUTPUT(output), TLP_END);
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>
10 years ago
/* Rebuild the surface list and update surface transforms up front. */
weston_compositor_build_view_list(ec, output);
/* Find the highest protection desired for an output */
wl_list_for_each(pnode, &output->paint_node_z_order_list,
z_order_link) {
/* TODO: turn this into assert once z_order_list is pruned. */
if ((pnode->surface->output_mask & (1u << output->id)) == 0)
continue;
/*
* The desired_protection of the output should be the
* maximum of the desired_protection of the surfaces,
* that are displayed on that output, to avoid
* reducing the protection for existing surfaces.
*/
if (pnode->surface->desired_protection > highest_requested)
highest_requested = pnode->surface->desired_protection;
}
output->desired_protection = highest_requested;
if (output->assign_planes && !output->disable_planes) {
output->assign_planes(output);
} else {
wl_list_for_each(pnode, &output->paint_node_z_order_list,
z_order_link) {
weston_view_move_to_plane(pnode->view, &ec->primary_plane);
pnode->view->psf_flags = 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>
12 years ago
wl_list_init(&frame_callback_list);
wl_list_for_each(pnode, &output->paint_node_z_order_list,
z_order_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>
11 years ago
/* Note: This operation is safe to do multiple times on the
* same surface.
*/
if (pnode->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>
12 years ago
wl_list_insert_list(&frame_callback_list,
&pnode->surface->frame_callback_list);
wl_list_init(&pnode->surface->frame_callback_list);
weston_output_take_feedback_list(output, pnode->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>
12 years ago
}
}
output_accumulate_damage(output);
pixman_region32_init(&output_damage);
pixman_region32_intersect(&output_damage,
&ec->primary_plane.damage, &output->region);
pixman_region32_subtract(&output_damage,
&output_damage, &ec->primary_plane.clip);
if (output->dirty)
weston_output_update_matrix(output);
r = output->repaint(output, &output_damage);
pixman_region32_fini(&output_damage);
output->repaint_needed = false;
if (r == 0)
output->repaint_status = REPAINT_AWAITING_COMPLETION;
weston_compositor_repick(ec);
frame_time_msec = timespec_to_msec(&output->frame_time);
wl_resource_for_each_safe(cb, cnext, &frame_callback_list) {
wl_callback_send_done(cb, frame_time_msec);
wl_resource_destroy(cb);
}
wl_list_for_each_safe(animation, next, &output->animation_list, link) {
animation->frame_counter++;
animation->frame(animation, output, &output->frame_time);
}
TL_POINT(ec, "core_repaint_posted", TLP_OUTPUT(output), TLP_END);
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>
10 years ago
return r;
}
static void
weston_output_schedule_repaint_reset(struct weston_output *output)
{
output->repaint_status = REPAINT_NOT_SCHEDULED;
TL_POINT(output->compositor, "core_repaint_exit_loop",
TLP_OUTPUT(output), TLP_END);
}
static int
weston_output_maybe_repaint(struct weston_output *output, struct timespec *now)
compositor: add repaint delay timer This timer delays the output_repaint towards the end of the refresh period, reducing the time from repaint to present. The length of the repaint window can be set in weston.ini. The call to weston_output_schedule_repaint_reset() is delayed by one more period. If we exit the continuous repaint loop (set output->repaint_scheduled to false) in finish_frame, we may call start_repaint_loop() unnecessarily. The problem case was actually observed with two outputs on the DRM backend at 60 Hz, and 7 ms repaint-window. During a window move, one output was constantly falling off the continuous repaint loop and introducing additional one frame latency, leading to jerky window motion. This code now avoids the problem. Changes in v2: - Rename repaint_delay_timer to repaint_timer and output_repaint_delay_handler to output_repaint_timer_handler. - When computing the delay, take the current time into account. The timer uses a relative timeout, so we have to subtract any time already gone. Note, that 'gone' may also be negative. DRM has a habit of predicting the page flip timestamp so it may be still in the future when we get the completion event. - Do also a sanity check 'msec > 1000'. In the unlikely case that something fails to provide a good timestamp, never delay for more than one second. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-By: Derek Foreman <derekf@osg.samsung.com> Reviewed-by: Bryce Harrington <bryce@osg.samsung.com>
11 years ago
{
struct weston_compositor *compositor = output->compositor;
int ret = 0;
int64_t msec_to_repaint;
compositor: add repaint delay timer This timer delays the output_repaint towards the end of the refresh period, reducing the time from repaint to present. The length of the repaint window can be set in weston.ini. The call to weston_output_schedule_repaint_reset() is delayed by one more period. If we exit the continuous repaint loop (set output->repaint_scheduled to false) in finish_frame, we may call start_repaint_loop() unnecessarily. The problem case was actually observed with two outputs on the DRM backend at 60 Hz, and 7 ms repaint-window. During a window move, one output was constantly falling off the continuous repaint loop and introducing additional one frame latency, leading to jerky window motion. This code now avoids the problem. Changes in v2: - Rename repaint_delay_timer to repaint_timer and output_repaint_delay_handler to output_repaint_timer_handler. - When computing the delay, take the current time into account. The timer uses a relative timeout, so we have to subtract any time already gone. Note, that 'gone' may also be negative. DRM has a habit of predicting the page flip timestamp so it may be still in the future when we get the completion event. - Do also a sanity check 'msec > 1000'. In the unlikely case that something fails to provide a good timestamp, never delay for more than one second. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-By: Derek Foreman <derekf@osg.samsung.com> Reviewed-by: Bryce Harrington <bryce@osg.samsung.com>
11 years ago
/* We're not ready yet; come back to make a decision later. */
if (output->repaint_status != REPAINT_SCHEDULED)
return ret;
msec_to_repaint = timespec_sub_to_msec(&output->next_repaint, now);
if (msec_to_repaint > 1)
return ret;
/* If we're sleeping, drop the repaint machinery entirely; we will
* explicitly repaint all outputs when we come back. */
if (compositor->state == WESTON_COMPOSITOR_SLEEPING ||
compositor->state == WESTON_COMPOSITOR_OFFSCREEN)
goto err;
compositor: add repaint delay timer This timer delays the output_repaint towards the end of the refresh period, reducing the time from repaint to present. The length of the repaint window can be set in weston.ini. The call to weston_output_schedule_repaint_reset() is delayed by one more period. If we exit the continuous repaint loop (set output->repaint_scheduled to false) in finish_frame, we may call start_repaint_loop() unnecessarily. The problem case was actually observed with two outputs on the DRM backend at 60 Hz, and 7 ms repaint-window. During a window move, one output was constantly falling off the continuous repaint loop and introducing additional one frame latency, leading to jerky window motion. This code now avoids the problem. Changes in v2: - Rename repaint_delay_timer to repaint_timer and output_repaint_delay_handler to output_repaint_timer_handler. - When computing the delay, take the current time into account. The timer uses a relative timeout, so we have to subtract any time already gone. Note, that 'gone' may also be negative. DRM has a habit of predicting the page flip timestamp so it may be still in the future when we get the completion event. - Do also a sanity check 'msec > 1000'. In the unlikely case that something fails to provide a good timestamp, never delay for more than one second. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-By: Derek Foreman <derekf@osg.samsung.com> Reviewed-by: Bryce Harrington <bryce@osg.samsung.com>
11 years ago
/* We don't actually need to repaint this output; drop it from
* repaint until something causes damage. */
if (!output->repaint_needed)
goto err;
/* If repaint fails, we aren't going to get weston_output_finish_frame
* to trigger a new repaint, so drop it from repaint and hope
* something schedules a successful repaint later. As repainting may
* take some time, re-read our clock as a courtesy to the next
* output. */
ret = weston_output_repaint(output);
weston_compositor_read_presentation_clock(compositor, now);
if (ret != 0)
goto err;
compositor: add repaint delay timer This timer delays the output_repaint towards the end of the refresh period, reducing the time from repaint to present. The length of the repaint window can be set in weston.ini. The call to weston_output_schedule_repaint_reset() is delayed by one more period. If we exit the continuous repaint loop (set output->repaint_scheduled to false) in finish_frame, we may call start_repaint_loop() unnecessarily. The problem case was actually observed with two outputs on the DRM backend at 60 Hz, and 7 ms repaint-window. During a window move, one output was constantly falling off the continuous repaint loop and introducing additional one frame latency, leading to jerky window motion. This code now avoids the problem. Changes in v2: - Rename repaint_delay_timer to repaint_timer and output_repaint_delay_handler to output_repaint_timer_handler. - When computing the delay, take the current time into account. The timer uses a relative timeout, so we have to subtract any time already gone. Note, that 'gone' may also be negative. DRM has a habit of predicting the page flip timestamp so it may be still in the future when we get the completion event. - Do also a sanity check 'msec > 1000'. In the unlikely case that something fails to provide a good timestamp, never delay for more than one second. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-By: Derek Foreman <derekf@osg.samsung.com> Reviewed-by: Bryce Harrington <bryce@osg.samsung.com>
11 years ago
output->repainted = true;
return ret;
err:
weston_output_schedule_repaint_reset(output);
return ret;
}
static void
output_repaint_timer_arm(struct weston_compositor *compositor)
{
struct weston_output *output;
bool any_should_repaint = false;
struct timespec now;
int64_t msec_to_next = INT64_MAX;
weston_compositor_read_presentation_clock(compositor, &now);
wl_list_for_each(output, &compositor->output_list, link) {
int64_t msec_to_this;
if (output->repaint_status != REPAINT_SCHEDULED)
continue;
msec_to_this = timespec_sub_to_msec(&output->next_repaint,
&now);
if (!any_should_repaint || msec_to_this < msec_to_next)
msec_to_next = msec_to_this;
any_should_repaint = true;
}
if (!any_should_repaint)
return;
/* Even if we should repaint immediately, add the minimum 1 ms delay.
* This is a workaround to allow coalescing multiple output repaints
* particularly from weston_output_finish_frame()
* into the same call, which would not happen if we called
* output_repaint_timer_handler() directly.
*/
if (msec_to_next < 1)
msec_to_next = 1;
wl_event_source_timer_update(compositor->repaint_timer, msec_to_next);
}
static int
output_repaint_timer_handler(void *data)
{
struct weston_compositor *compositor = data;
struct weston_output *output;
struct timespec now;
int ret = 0;
weston_compositor_read_presentation_clock(compositor, &now);
gl-renderer: garbage-collect old shaders This adds a heuristic for freeing shader programs that have not been needed for a while. The intention is to stop Weston accumulating shader programs indefinitely, especially in the future when color management will explode the number of possible different shader programs. Shader programs that have not been used in the past minute are freed, except always keep the ten most recently used shader programs anyway. The former rule is to ensure we keep shader programs that are actively used regardless of how many. The latter rule is to prevent freeing too many shader programs after Weston has been idle for a long time and then repaints just a small area. Many of the shader programs could still be relevant even though not needed in the first repaint after idle. The numbers ten and one minute in the above are arbitrary and not based on anything. These heuristics are simpler to implement than e.g. views taking references on shader programs. Expiry by time allows shader programs to survive a while even after their last user is gone, with the hope of being re-used soon. Tracking actual use instead of references also adapts to what is actually visible rather than what merely exists. Keeping the shader list in most recently used order might also make gl_renderer_get_program() more efficient on average. last_repaint_start time is used for shader timestamp to avoid calling clock_gettime() more often. Adding that variable is an ABI break, but libweston major has already been bumped to 10 since last release. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
4 years ago
compositor->last_repaint_start = now;
if (compositor->backend->repaint_begin)
compositor->backend->repaint_begin(compositor);
wl_list_for_each(output, &compositor->output_list, link) {
ret = weston_output_maybe_repaint(output, &now);
if (ret)
break;
}
if (ret == 0) {
if (compositor->backend->repaint_flush)
ret = compositor->backend->repaint_flush(compositor);
} else {
if (compositor->backend->repaint_cancel)
compositor->backend->repaint_cancel(compositor);
}
if (ret != 0) {
wl_list_for_each(output, &compositor->output_list, link) {
if (output->repainted)
weston_output_schedule_repaint_reset(output);
}
}
wl_list_for_each(output, &compositor->output_list, link)
output->repainted = false;
output_repaint_timer_arm(compositor);
return 0;
compositor: add repaint delay timer This timer delays the output_repaint towards the end of the refresh period, reducing the time from repaint to present. The length of the repaint window can be set in weston.ini. The call to weston_output_schedule_repaint_reset() is delayed by one more period. If we exit the continuous repaint loop (set output->repaint_scheduled to false) in finish_frame, we may call start_repaint_loop() unnecessarily. The problem case was actually observed with two outputs on the DRM backend at 60 Hz, and 7 ms repaint-window. During a window move, one output was constantly falling off the continuous repaint loop and introducing additional one frame latency, leading to jerky window motion. This code now avoids the problem. Changes in v2: - Rename repaint_delay_timer to repaint_timer and output_repaint_delay_handler to output_repaint_timer_handler. - When computing the delay, take the current time into account. The timer uses a relative timeout, so we have to subtract any time already gone. Note, that 'gone' may also be negative. DRM has a habit of predicting the page flip timestamp so it may be still in the future when we get the completion event. - Do also a sanity check 'msec > 1000'. In the unlikely case that something fails to provide a good timestamp, never delay for more than one second. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-By: Derek Foreman <derekf@osg.samsung.com> Reviewed-by: Bryce Harrington <bryce@osg.samsung.com>
11 years ago
}
/** Convert a presentation timestamp to another clock domain
*
* \param compositor The compositor defines the presentation clock domain.
* \param presentation_stamp The timestamp in presentation clock domain.
* \param presentation_now Current time in presentation clock domain.
* \param target_clock Defines the target clock domain.
*
* This approximation relies on presentation_stamp to be close to current time.
* The further it is from current time and the bigger the speed difference
* between the two clock domains, the bigger the conversion error.
*
* Conversion error due to system load is biased and unbounded.
*/
static struct timespec
convert_presentation_time_now(struct weston_compositor *compositor,
const struct timespec *presentation_stamp,
const struct timespec *presentation_now,
clockid_t target_clock)
{
struct timespec target_now = {};
struct timespec target_stamp;
int64_t delta_ns;
if (compositor->presentation_clock == target_clock)
return *presentation_stamp;
clock_gettime(target_clock, &target_now);
delta_ns = timespec_sub_to_nsec(presentation_stamp, presentation_now);
timespec_add_nsec(&target_stamp, &target_now, delta_ns);
return target_stamp;
}
/**
* \ingroup output
*/
WL_EXPORT void
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>
10 years ago
const struct timespec *stamp,
uint32_t presented_flags)
{
struct weston_compositor *compositor = output->compositor;
compositor: add repaint delay timer This timer delays the output_repaint towards the end of the refresh period, reducing the time from repaint to present. The length of the repaint window can be set in weston.ini. The call to weston_output_schedule_repaint_reset() is delayed by one more period. If we exit the continuous repaint loop (set output->repaint_scheduled to false) in finish_frame, we may call start_repaint_loop() unnecessarily. The problem case was actually observed with two outputs on the DRM backend at 60 Hz, and 7 ms repaint-window. During a window move, one output was constantly falling off the continuous repaint loop and introducing additional one frame latency, leading to jerky window motion. This code now avoids the problem. Changes in v2: - Rename repaint_delay_timer to repaint_timer and output_repaint_delay_handler to output_repaint_timer_handler. - When computing the delay, take the current time into account. The timer uses a relative timeout, so we have to subtract any time already gone. Note, that 'gone' may also be negative. DRM has a habit of predicting the page flip timestamp so it may be still in the future when we get the completion event. - Do also a sanity check 'msec > 1000'. In the unlikely case that something fails to provide a good timestamp, never delay for more than one second. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-By: Derek Foreman <derekf@osg.samsung.com> Reviewed-by: Bryce Harrington <bryce@osg.samsung.com>
11 years ago
int32_t refresh_nsec;
struct timespec now;
struct timespec vblank_monotonic;
int64_t msec_rel;
assert(output->repaint_status == REPAINT_AWAITING_COMPLETION);
/*
* If timestamp of latest vblank is given, it must always go forwards.
* If not given, INVALID flag must be set.
*/
if (stamp)
assert(timespec_sub_to_nsec(stamp, &output->frame_time) >= 0);
else
assert(presented_flags & WP_PRESENTATION_FEEDBACK_INVALID);
weston_compositor_read_presentation_clock(compositor, &now);
/* If we haven't been supplied any timestamp at all, we don't have a
* timebase to work against, so any delay just wastes time. Push a
* repaint as soon as possible so we can get on with it. */
if (!stamp) {
output->next_repaint = now;
goto out;
}
vblank_monotonic = convert_presentation_time_now(compositor,
stamp, &now,
CLOCK_MONOTONIC);
TL_POINT(compositor, "core_repaint_finished", TLP_OUTPUT(output),
TLP_VBLANK(&vblank_monotonic), TLP_END);
refresh_nsec = millihz_to_nsec(output->current_mode->refresh);
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>
10 years ago
output->msc,
presented_flags);
output->frame_time = *stamp;
timespec_add_nsec(&output->next_repaint, stamp, refresh_nsec);
timespec_add_msec(&output->next_repaint, &output->next_repaint,
-compositor->repaint_msec);
msec_rel = timespec_sub_to_msec(&output->next_repaint, &now);
if (msec_rel < -1000 || msec_rel > 1000) {
static bool warned;
if (!warned)
weston_log("Warning: computed repaint delay is "
"insane: %lld msec\n", (long long) msec_rel);
warned = true;
output->next_repaint = now;
}
compositor: Respect repaint-window when restarting repaint loop. If a stopped repaint loop gets restarted due to posting of new damage, and this restart of the repaint loop happens late in the video refresh cycle, ie. already inside the repaint-window and thereby after the composition deadline for the current frame, then defer the actual output repaint to the composition deadline of the next video refresh cycle by setting the repaint timer accordingly. This tries to make sure that: a) Client(s) posting damage timely before the composition deadline (video refresh duration - "repaint-window" duration) of the current refresh cycle will trigger a repaint within the current refresh cycle, thereby avoiding one extra frame of compositor lag due to the needed restart of the repaint loop if the loop was stopped. This allows them to benefit from the earlier "instant repaint restart" commit to keep latency low. b) Late clients which post damage close to the end of a refresh cycle can't race other clients if the repaint loop is restarted. Instead they will get deferred to the next compositor cycle, just as if the repaint loop would have been already running - the semantic of the "repaint-window" parameter is preserved. This is especially important to prevent a very late client from triggering a repaint very close to the vblank, which would cause the compositor to certainly miss the vblank and skip one frame and then cause a delay of another frame for other clients which posted their damage in time for the following frame. Iow. this provides clients with a more predictable compositor timing and makes it easier for them to latch onto the compositors repaint cycle. Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com> Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
10 years ago
/* 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. */
if (presented_flags == WP_PRESENTATION_FEEDBACK_INVALID &&
msec_rel < 0) {
while (timespec_sub_to_nsec(&output->next_repaint, &now) < 0) {
timespec_add_nsec(&output->next_repaint,
&output->next_repaint,
refresh_nsec);
}
}
compositor: Respect repaint-window when restarting repaint loop. If a stopped repaint loop gets restarted due to posting of new damage, and this restart of the repaint loop happens late in the video refresh cycle, ie. already inside the repaint-window and thereby after the composition deadline for the current frame, then defer the actual output repaint to the composition deadline of the next video refresh cycle by setting the repaint timer accordingly. This tries to make sure that: a) Client(s) posting damage timely before the composition deadline (video refresh duration - "repaint-window" duration) of the current refresh cycle will trigger a repaint within the current refresh cycle, thereby avoiding one extra frame of compositor lag due to the needed restart of the repaint loop if the loop was stopped. This allows them to benefit from the earlier "instant repaint restart" commit to keep latency low. b) Late clients which post damage close to the end of a refresh cycle can't race other clients if the repaint loop is restarted. Instead they will get deferred to the next compositor cycle, just as if the repaint loop would have been already running - the semantic of the "repaint-window" parameter is preserved. This is especially important to prevent a very late client from triggering a repaint very close to the vblank, which would cause the compositor to certainly miss the vblank and skip one frame and then cause a delay of another frame for other clients which posted their damage in time for the following frame. Iow. this provides clients with a more predictable compositor timing and makes it easier for them to latch onto the compositors repaint cycle. Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com> Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
10 years ago
out:
output->repaint_status = REPAINT_SCHEDULED;
output_repaint_timer_arm(compositor);
}
WL_EXPORT void
weston_output_repaint_failed(struct weston_output *output)
{
weston_log("Clearing repaint status.\n");
assert(output->repaint_status == REPAINT_AWAITING_COMPLETION);
output->repaint_status = REPAINT_NOT_SCHEDULED;
}
static void
idle_repaint(void *data)
{
struct weston_output *output = data;
int ret;
assert(output->repaint_status == REPAINT_BEGIN_FROM_IDLE);
output->repaint_status = REPAINT_AWAITING_COMPLETION;
output->idle_repaint_source = NULL;
ret = output->start_repaint_loop(output);
if (ret != 0)
weston_output_schedule_repaint_reset(output);
}
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;
}
/** Initialize the weston_layer struct.
*
* \param compositor The compositor instance
* \param layer The layer to initialize
*/
WL_EXPORT void
weston_layer_init(struct weston_layer *layer,
struct weston_compositor *compositor)
{
layer->compositor = compositor;
wl_list_init(&layer->link);
wl_list_init(&layer->view_list.link);
layer->view_list.layer = layer;
weston_layer_set_mask_infinite(layer);
}
/** Finalize the weston_layer struct.
*
* \param layer The layer to finalize.
*/
WL_EXPORT void
weston_layer_fini(struct weston_layer *layer)
{
wl_list_remove(&layer->link);
if (!wl_list_empty(&layer->view_list.link))
weston_log("BUG: finalizing a layer with views still on it.\n");
wl_list_remove(&layer->view_list.link);
}
/** Sets the position of the layer in the layer list. The layer will be placed
* below any layer with the same position value, if any.
* This function is safe to call if the layer is already on the list, but the
* layer may be moved below other layers at the same position, if any.
*
* \param layer The layer to modify
* \param position The position the layer will be placed at
*/
WL_EXPORT void
weston_layer_set_position(struct weston_layer *layer,
enum weston_layer_position position)
{
struct weston_layer *below;
wl_list_remove(&layer->link);
/* layer_list is ordered from top to bottom, the last layer being the
* background with the smallest position value */
layer->position = position;
wl_list_for_each_reverse(below, &layer->compositor->layer_list, link) {
if (below->position >= layer->position) {
wl_list_insert(&below->link, &layer->link);
return;
}
}
wl_list_insert(&layer->compositor->layer_list, &layer->link);
}
/** Hide a layer by taking it off the layer list.
* This function is safe to call if the layer is not on the list.
*
* \param layer The layer to hide
*/
WL_EXPORT void
weston_layer_unset_position(struct weston_layer *layer)
{
wl_list_remove(&layer->link);
wl_list_init(&layer->link);
}
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)
{
struct weston_view *view;
layer->mask.x1 = INT32_MIN;
layer->mask.x2 = INT32_MAX;
layer->mask.y1 = INT32_MIN;
layer->mask.y2 = INT32_MAX;
wl_list_for_each(view, &layer->view_list.link, layer_link.link) {
weston_view_geometry_dirty(view);
}
}
WL_EXPORT bool
weston_layer_mask_is_infinite(struct weston_layer *layer)
{
return layer->mask.x1 == INT32_MIN &&
layer->mask.y1 == INT32_MIN &&
layer->mask.x2 == INT32_MAX &&
layer->mask.y2 == INT32_MAX;
}
/**
* \ingroup output
*/
WL_EXPORT void
weston_output_schedule_repaint(struct weston_output *output)
{
struct weston_compositor *compositor = output->compositor;
struct wl_event_loop *loop;
if (compositor->state == WESTON_COMPOSITOR_SLEEPING ||
compositor->state == WESTON_COMPOSITOR_OFFSCREEN)
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>
10 years ago
if (!output->repaint_needed)
TL_POINT(compositor, "core_repaint_req", TLP_OUTPUT(output), TLP_END);
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>
10 years ago
loop = wl_display_get_event_loop(compositor->wl_display);
output->repaint_needed = true;
/* If we already have a repaint scheduled for our idle handler,
* no need to set it again. If the repaint has been called but
* not finished, then weston_output_finish_frame() will notice
* that a repaint is needed and schedule one. */
if (output->repaint_status != REPAINT_NOT_SCHEDULED)
return;
output->repaint_status = REPAINT_BEGIN_FROM_IDLE;
assert(!output->idle_repaint_source);
output->idle_repaint_source = wl_event_loop_add_idle(loop, idle_repaint,
output);
TL_POINT(compositor, "core_repaint_enter_loop", TLP_OUTPUT(output), TLP_END);
}
/** weston_compositor_schedule_repaint
* \ingroup compositor
*/
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);
}
static void
surface_destroy(struct wl_client *client, struct wl_resource *resource)
{
wl_resource_destroy(resource);
}
static void
surface_attach(struct wl_client *client,
struct wl_resource *resource,
struct wl_resource *buffer_resource, int32_t sx, int32_t sy)
{
struct weston_surface *surface = wl_resource_get_user_data(resource);
struct weston_compositor *ec = surface->compositor;
struct weston_buffer *buffer = NULL;
if (buffer_resource) {
buffer = weston_buffer_from_resource(ec, buffer_resource);
if (buffer == NULL) {
wl_client_post_no_memory(client);
return;
}
}
/* Attach, attach, without commit in between does not send
* wl_buffer.release. */
weston_surface_state_set_buffer(&surface->pending, buffer);
surface->pending.sx = sx;
surface->pending.sy = sy;
surface->pending.newly_attached = 1;
}
static void
surface_damage(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_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,
x, y, width, height);
}
static void
destroy_frame_callback(struct wl_resource *resource)
{
wl_list_remove(wl_resource_get_link(resource));
}
static void
surface_frame(struct wl_client *client,
struct wl_resource *resource, uint32_t callback)
{
struct wl_resource *cb;
struct weston_surface *surface = wl_resource_get_user_data(resource);
cb = wl_resource_create(client, &wl_callback_interface, 1, callback);
if (cb == NULL) {
wl_resource_post_no_memory(resource);
return;
}
wl_resource_set_implementation(cb, NULL, NULL,
destroy_frame_callback);
wl_list_insert(surface->pending.frame_callback_list.prev,
wl_resource_get_link(cb));
}
static void
surface_set_opaque_region(struct wl_client *client,
struct wl_resource *resource,
struct wl_resource *region_resource)
{
struct weston_surface *surface = wl_resource_get_user_data(resource);
struct weston_region *region;
if (region_resource) {
region = wl_resource_get_user_data(region_resource);
pixman_region32_copy(&surface->pending.opaque,
&region->region);
} else {
pixman_region32_clear(&surface->pending.opaque);
}
}
static void
surface_set_input_region(struct wl_client *client,
struct wl_resource *resource,
struct wl_resource *region_resource)
{
struct weston_surface *surface = wl_resource_get_user_data(resource);
struct weston_region *region;
if (region_resource) {
region = wl_resource_get_user_data(region_resource);
pixman_region32_copy(&surface->pending.input,
&region->region);
} else {
pixman_region32_fini(&surface->pending.input);
region_init_infinite(&surface->pending.input);
}
}
/* Cause damage to this sub-surface and all its children.
*
* This is useful when there are state changes that need an implicit
* damage, e.g. a z-order change.
*/
static void
weston_surface_damage_subsurfaces(struct weston_subsurface *sub)
{
struct weston_subsurface *child;
weston_surface_damage(sub->surface);
sub->reordered = false;
wl_list_for_each(child, &sub->surface->subsurface_list, parent_link)
if (child != sub)
weston_surface_damage_subsurfaces(child);
}
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>
12 years ago
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);
if (sub->reordered)
weston_surface_damage_subsurfaces(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>
12 years ago
}
}
static void
weston_surface_build_buffer_matrix(const struct weston_surface *surface,
struct weston_matrix *matrix)
{
const struct weston_buffer_viewport *vp = &surface->buffer_viewport;
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,
0, surface->width_from_buffer, 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,
surface->height_from_buffer, 0, 0);
break;
}
weston_matrix_scale(matrix, vp->buffer.scale, vp->buffer.scale, 1);
}
/**
* 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;
}
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);
}
/* 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);
}
static void
weston_surface_set_desired_protection(struct weston_surface *surface,
enum weston_hdcp_protection protection)
{
if (surface->desired_protection == protection)
return;
surface->desired_protection = protection;
weston_surface_damage(surface);
}
static void
weston_surface_set_protection_mode(struct weston_surface *surface,
enum weston_surface_protection_mode p_mode)
{
struct content_protection *cp = surface->compositor->content_protection;
struct protected_surface *psurface;
surface->protection_mode = p_mode;
wl_list_for_each(psurface, &cp->protected_list, link) {
if (!psurface || psurface->surface != surface)
continue;
weston_protected_surface_send_event(psurface,
surface->current_protection);
}
}
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>
12 years ago
static void
weston_surface_commit_state(struct weston_surface *surface,
struct weston_surface_state *state)
{
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>
11 years ago
struct weston_view *view;
pixman_region32_t opaque;
/* wl_surface.set_buffer_transform */
/* wl_surface.set_buffer_scale */
/* wp_viewport.set_source */
/* wp_viewport.set_destination */
surface->buffer_viewport = state->buffer_viewport;
/* wl_surface.attach */
libweston: Support zwp_surface_synchronization_v1.set_acquire_fence Implement the set_acquire_fence request of the zwp_surface_synchronization_v1 interface. The implementation uses the acquire fence in two ways: 1. If the associated buffer is used as GL render source, an EGLSyncKHR is created from the fence and used to synchronize access. 2. If the associated buffer is used as a plane framebuffer, the acquire fence is treated as an in-fence for the atomic commit operation. If in-fences are not supported and the buffer has an acquire fence, we don't consider it for plane placement. If the used compositor/renderer doesn't support explicit synchronization, we don't advertise the protocol at all. Currently only the DRM and X11 backends when using the GL renderer advertise the protocol for production use. Issues for discussion --------------------- a. Currently, a server-side wait of EGLSyncKHR is performed before using the EGLImage/texture during rendering. Unfortunately, it's not clear from the specs whether this is generally safe to do, or we need to sync before glEGLImageTargetTexture2DOES. The exception is TEXTURE_EXTERNAL_OES where the spec mentions it's enough to sync and then glBindTexture for any changes to take effect. Changes in v5: - Meson support. - Make explicit sync server error reporting more generic, supporting all explicit sync related interfaces not just wp_linux_surface_synchronization. - Fix typo in warning for missing EGL_KHR_wait_sync extension. - Support minor version 2 of the explicit sync protocol (i.e., support fences for opaque EGL buffers). Changes in v4: - Introduce and use fd_clear and and fd_move helpers. - Don't check for a valid buffer when updating surface acquire fence fd from state. - Assert that pending state acquire fence fd is always clear after a commit. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to just the renderer. - Check for EGL_KHR_wait_sync before using eglWaitSyncKHR. - Dup the acquire fence before passing to EGL. Changes in v3: - Keep acquire_fence_fd in surface instead of buffer. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to both backend and renderer. - Move comment about non-ownership of in_fence_fd to struct drm_plane_state definition. - Assert that we don't try to use planes with in-fences when using the legacy KMS API. - Remove unnecessary info from wayland error messages. - Handle acquire fence for subsurface commits. - Guard against self-update in fd_update. - Disconnect the client if acquire fence EGLSyncKHR creation or wait fails. - Use updated protocol interface names. - User correct format specifier for resource ids. - Advertise protocol for X11 backend with GL renderer. Changes in v2: - Remove sync file wait fallbacks. - Raise UNSUPPORTED_BUFFER error at commit if we have an acquire fence, but the committed buffer is not a valid linux_dmabuf. - Don't put buffers with in-fences on planes that don't support in-fences. - Don't advertise explicit sync protocol if backend does not support explicit sync. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
6 years ago
if (state->newly_attached) {
/* zwp_surface_synchronization_v1.set_acquire_fence */
fd_move(&surface->acquire_fence_fd,
&state->acquire_fence_fd);
libweston: Support zwp_surface_synchronization_v1.get_release Implement the get_release request of the zwp_surface_synchronization_v1 interface. This commit implements the zwp_buffer_release_v1 interface. It supports the zwp_buffer_release_v1.fenced_release event for surfaces rendered by the GL renderer, and the zwp_buffer_release_v1.immediate_release event for other cases. Note that the immediate_release event is safe to be used for surface buffers used as planes in the DRM backend, since the backend releases them only after the next page flip that doesn't use the buffers has finished. Changes in v7: - Remove "partial" from commit title and description. - Fix inverted check when clearing used_in_output_repaint flag. Changes in v5: - Use the new, generic explicit sync server error reporting function. - Introduce and use weston_buffer_release_move. - Introduce internally and use weston_buffer_release_destroy. Changes in v4: - Support the zwp_buffer_release_v1.fenced_release event. - Support release fences in the GL renderer. - Assert that pending state buffer_release is always NULL after a commit. - Simplify weston_buffer_release_reference. - Move removal of destroy listener before resource destruction to avoid concerns about use-after-free in weston_buffer_release_reference - Rename weston_buffer_release_reference.busy_count to ref_count. - Add documentation for weston_buffer_release and ..._reference. Changes in v3: - Raise NO_BUFFER for get_release if no buffer has been committed, don't raise UNSUPPORTED_BUFFER for non-dmabuf buffers, so get_release works for all valid buffers. - Destroy the buffer_release object after sending an event. - Track lifetime of buffer_release objects per commit, independently of any buffers. - Use updated protocol interface names. - Use correct format specifier for resource ids. Changes in v2: - Raise UNSUPPORTED_BUFFER at commit if client has requested a buffer_release, but the committed buffer is not a valid linux_dmabuf. - Remove tests that are not viable anymore due to our inability to create dmabuf buffers and fences in a unit-test environment. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
6 years ago
/* zwp_surface_synchronization_v1.get_release */
weston_buffer_release_move(&surface->buffer_release_ref,
&state->buffer_release_ref);
weston_surface_attach(surface, state->buffer);
libweston: Support zwp_surface_synchronization_v1.set_acquire_fence Implement the set_acquire_fence request of the zwp_surface_synchronization_v1 interface. The implementation uses the acquire fence in two ways: 1. If the associated buffer is used as GL render source, an EGLSyncKHR is created from the fence and used to synchronize access. 2. If the associated buffer is used as a plane framebuffer, the acquire fence is treated as an in-fence for the atomic commit operation. If in-fences are not supported and the buffer has an acquire fence, we don't consider it for plane placement. If the used compositor/renderer doesn't support explicit synchronization, we don't advertise the protocol at all. Currently only the DRM and X11 backends when using the GL renderer advertise the protocol for production use. Issues for discussion --------------------- a. Currently, a server-side wait of EGLSyncKHR is performed before using the EGLImage/texture during rendering. Unfortunately, it's not clear from the specs whether this is generally safe to do, or we need to sync before glEGLImageTargetTexture2DOES. The exception is TEXTURE_EXTERNAL_OES where the spec mentions it's enough to sync and then glBindTexture for any changes to take effect. Changes in v5: - Meson support. - Make explicit sync server error reporting more generic, supporting all explicit sync related interfaces not just wp_linux_surface_synchronization. - Fix typo in warning for missing EGL_KHR_wait_sync extension. - Support minor version 2 of the explicit sync protocol (i.e., support fences for opaque EGL buffers). Changes in v4: - Introduce and use fd_clear and and fd_move helpers. - Don't check for a valid buffer when updating surface acquire fence fd from state. - Assert that pending state acquire fence fd is always clear after a commit. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to just the renderer. - Check for EGL_KHR_wait_sync before using eglWaitSyncKHR. - Dup the acquire fence before passing to EGL. Changes in v3: - Keep acquire_fence_fd in surface instead of buffer. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to both backend and renderer. - Move comment about non-ownership of in_fence_fd to struct drm_plane_state definition. - Assert that we don't try to use planes with in-fences when using the legacy KMS API. - Remove unnecessary info from wayland error messages. - Handle acquire fence for subsurface commits. - Guard against self-update in fd_update. - Disconnect the client if acquire fence EGLSyncKHR creation or wait fails. - Use updated protocol interface names. - User correct format specifier for resource ids. - Advertise protocol for X11 backend with GL renderer. Changes in v2: - Remove sync file wait fallbacks. - Raise UNSUPPORTED_BUFFER error at commit if we have an acquire fence, but the committed buffer is not a valid linux_dmabuf. - Don't put buffers with in-fences on planes that don't support in-fences. - Don't advertise explicit sync protocol if backend does not support explicit sync. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
6 years ago
}
weston_surface_state_set_buffer(state, NULL);
libweston: Support zwp_surface_synchronization_v1.set_acquire_fence Implement the set_acquire_fence request of the zwp_surface_synchronization_v1 interface. The implementation uses the acquire fence in two ways: 1. If the associated buffer is used as GL render source, an EGLSyncKHR is created from the fence and used to synchronize access. 2. If the associated buffer is used as a plane framebuffer, the acquire fence is treated as an in-fence for the atomic commit operation. If in-fences are not supported and the buffer has an acquire fence, we don't consider it for plane placement. If the used compositor/renderer doesn't support explicit synchronization, we don't advertise the protocol at all. Currently only the DRM and X11 backends when using the GL renderer advertise the protocol for production use. Issues for discussion --------------------- a. Currently, a server-side wait of EGLSyncKHR is performed before using the EGLImage/texture during rendering. Unfortunately, it's not clear from the specs whether this is generally safe to do, or we need to sync before glEGLImageTargetTexture2DOES. The exception is TEXTURE_EXTERNAL_OES where the spec mentions it's enough to sync and then glBindTexture for any changes to take effect. Changes in v5: - Meson support. - Make explicit sync server error reporting more generic, supporting all explicit sync related interfaces not just wp_linux_surface_synchronization. - Fix typo in warning for missing EGL_KHR_wait_sync extension. - Support minor version 2 of the explicit sync protocol (i.e., support fences for opaque EGL buffers). Changes in v4: - Introduce and use fd_clear and and fd_move helpers. - Don't check for a valid buffer when updating surface acquire fence fd from state. - Assert that pending state acquire fence fd is always clear after a commit. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to just the renderer. - Check for EGL_KHR_wait_sync before using eglWaitSyncKHR. - Dup the acquire fence before passing to EGL. Changes in v3: - Keep acquire_fence_fd in surface instead of buffer. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to both backend and renderer. - Move comment about non-ownership of in_fence_fd to struct drm_plane_state definition. - Assert that we don't try to use planes with in-fences when using the legacy KMS API. - Remove unnecessary info from wayland error messages. - Handle acquire fence for subsurface commits. - Guard against self-update in fd_update. - Disconnect the client if acquire fence EGLSyncKHR creation or wait fails. - Use updated protocol interface names. - User correct format specifier for resource ids. - Advertise protocol for X11 backend with GL renderer. Changes in v2: - Remove sync file wait fallbacks. - Raise UNSUPPORTED_BUFFER error at commit if we have an acquire fence, but the committed buffer is not a valid linux_dmabuf. - Don't put buffers with in-fences on planes that don't support in-fences. - Don't advertise explicit sync protocol if backend does not support explicit sync. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
6 years ago
assert(state->acquire_fence_fd == -1);
libweston: Support zwp_surface_synchronization_v1.get_release Implement the get_release request of the zwp_surface_synchronization_v1 interface. This commit implements the zwp_buffer_release_v1 interface. It supports the zwp_buffer_release_v1.fenced_release event for surfaces rendered by the GL renderer, and the zwp_buffer_release_v1.immediate_release event for other cases. Note that the immediate_release event is safe to be used for surface buffers used as planes in the DRM backend, since the backend releases them only after the next page flip that doesn't use the buffers has finished. Changes in v7: - Remove "partial" from commit title and description. - Fix inverted check when clearing used_in_output_repaint flag. Changes in v5: - Use the new, generic explicit sync server error reporting function. - Introduce and use weston_buffer_release_move. - Introduce internally and use weston_buffer_release_destroy. Changes in v4: - Support the zwp_buffer_release_v1.fenced_release event. - Support release fences in the GL renderer. - Assert that pending state buffer_release is always NULL after a commit. - Simplify weston_buffer_release_reference. - Move removal of destroy listener before resource destruction to avoid concerns about use-after-free in weston_buffer_release_reference - Rename weston_buffer_release_reference.busy_count to ref_count. - Add documentation for weston_buffer_release and ..._reference. Changes in v3: - Raise NO_BUFFER for get_release if no buffer has been committed, don't raise UNSUPPORTED_BUFFER for non-dmabuf buffers, so get_release works for all valid buffers. - Destroy the buffer_release object after sending an event. - Track lifetime of buffer_release objects per commit, independently of any buffers. - Use updated protocol interface names. - Use correct format specifier for resource ids. Changes in v2: - Raise UNSUPPORTED_BUFFER at commit if client has requested a buffer_release, but the committed buffer is not a valid linux_dmabuf. - Remove tests that are not viable anymore due to our inability to create dmabuf buffers and fences in a unit-test environment. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
6 years ago
assert(state->buffer_release_ref.buffer_release == NULL);
weston_surface_build_buffer_matrix(surface,
&surface->surface_to_buffer_matrix);
weston_matrix_invert(&surface->buffer_to_surface_matrix,
&surface->surface_to_buffer_matrix);
if (state->newly_attached || state->buffer_viewport.changed) {
weston_surface_update_size(surface);
if (surface->committed)
surface->committed(surface, state->sx, state->sy);
}
state->sx = 0;
state->sy = 0;
state->newly_attached = 0;
state->buffer_viewport.changed = 0;
/* wl_surface.damage and wl_surface.damage_buffer */
if (pixman_region32_not_empty(&state->damage_surface) ||
pixman_region32_not_empty(&state->damage_buffer))
TL_POINT(surface->compositor, "core_commit_damage", TLP_SURFACE(surface), TLP_END);
pixman_region32_union(&surface->damage, &surface->damage,
&state->damage_surface);
apply_damage_buffer(&surface->damage, surface, state);
pixman_region32_intersect_rect(&surface->damage, &surface->damage,
0, 0, surface->width, surface->height);
pixman_region32_clear(&state->damage_surface);
/* wl_surface.set_opaque_region */
pixman_region32_init(&opaque);
pixman_region32_intersect_rect(&opaque, &state->opaque,
0, 0, surface->width, surface->height);
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>
11 years ago
wl_list_for_each(view, &surface->views, surface_link)
weston_view_geometry_dirty(view);
}
pixman_region32_fini(&opaque);
/* wl_surface.set_input_region */
pixman_region32_intersect_rect(&surface->input, &state->input,
0, 0, surface->width, surface->height);
/* wl_surface.frame */
wl_list_insert_list(&surface->frame_callback_list,
&state->frame_callback_list);
wl_list_init(&state->frame_callback_list);
/* 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);
/* weston_protected_surface.enforced/relaxed */
if (surface->protection_mode != state->protection_mode)
weston_surface_set_protection_mode(surface,
state->protection_mode);
/* weston_protected_surface.set_type */
weston_surface_set_desired_protection(surface, state->desired_protection);
wl_signal_emit(&surface->commit_signal, surface);
}
static void
weston_surface_commit(struct weston_surface *surface)
{
weston_surface_commit_state(surface, &surface->pending);
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>
12 years ago
weston_surface_commit_subsurface_order(surface);
weston_surface_schedule_repaint(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>
12 years ago
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)
{
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>
12 years ago
struct weston_subsurface *sub = weston_surface_to_subsurface(surface);
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;
}
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;
}
libweston: Support zwp_surface_synchronization_v1.set_acquire_fence Implement the set_acquire_fence request of the zwp_surface_synchronization_v1 interface. The implementation uses the acquire fence in two ways: 1. If the associated buffer is used as GL render source, an EGLSyncKHR is created from the fence and used to synchronize access. 2. If the associated buffer is used as a plane framebuffer, the acquire fence is treated as an in-fence for the atomic commit operation. If in-fences are not supported and the buffer has an acquire fence, we don't consider it for plane placement. If the used compositor/renderer doesn't support explicit synchronization, we don't advertise the protocol at all. Currently only the DRM and X11 backends when using the GL renderer advertise the protocol for production use. Issues for discussion --------------------- a. Currently, a server-side wait of EGLSyncKHR is performed before using the EGLImage/texture during rendering. Unfortunately, it's not clear from the specs whether this is generally safe to do, or we need to sync before glEGLImageTargetTexture2DOES. The exception is TEXTURE_EXTERNAL_OES where the spec mentions it's enough to sync and then glBindTexture for any changes to take effect. Changes in v5: - Meson support. - Make explicit sync server error reporting more generic, supporting all explicit sync related interfaces not just wp_linux_surface_synchronization. - Fix typo in warning for missing EGL_KHR_wait_sync extension. - Support minor version 2 of the explicit sync protocol (i.e., support fences for opaque EGL buffers). Changes in v4: - Introduce and use fd_clear and and fd_move helpers. - Don't check for a valid buffer when updating surface acquire fence fd from state. - Assert that pending state acquire fence fd is always clear after a commit. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to just the renderer. - Check for EGL_KHR_wait_sync before using eglWaitSyncKHR. - Dup the acquire fence before passing to EGL. Changes in v3: - Keep acquire_fence_fd in surface instead of buffer. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to both backend and renderer. - Move comment about non-ownership of in_fence_fd to struct drm_plane_state definition. - Assert that we don't try to use planes with in-fences when using the legacy KMS API. - Remove unnecessary info from wayland error messages. - Handle acquire fence for subsurface commits. - Guard against self-update in fd_update. - Disconnect the client if acquire fence EGLSyncKHR creation or wait fails. - Use updated protocol interface names. - User correct format specifier for resource ids. - Advertise protocol for X11 backend with GL renderer. Changes in v2: - Remove sync file wait fallbacks. - Raise UNSUPPORTED_BUFFER error at commit if we have an acquire fence, but the committed buffer is not a valid linux_dmabuf. - Don't put buffers with in-fences on planes that don't support in-fences. - Don't advertise explicit sync protocol if backend does not support explicit sync. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
6 years ago
if (surface->pending.acquire_fence_fd >= 0) {
assert(surface->synchronization_resource);
if (!surface->pending.buffer) {
fd_clear(&surface->pending.acquire_fence_fd);
wl_resource_post_error(surface->synchronization_resource,
ZWP_LINUX_SURFACE_SYNCHRONIZATION_V1_ERROR_NO_BUFFER,
"wl_surface@%"PRIu32" no buffer for synchronization",
wl_resource_get_id(resource));
return;
}
if (surface->pending.buffer->type == WESTON_BUFFER_SHM) {
libweston: Support zwp_surface_synchronization_v1.set_acquire_fence Implement the set_acquire_fence request of the zwp_surface_synchronization_v1 interface. The implementation uses the acquire fence in two ways: 1. If the associated buffer is used as GL render source, an EGLSyncKHR is created from the fence and used to synchronize access. 2. If the associated buffer is used as a plane framebuffer, the acquire fence is treated as an in-fence for the atomic commit operation. If in-fences are not supported and the buffer has an acquire fence, we don't consider it for plane placement. If the used compositor/renderer doesn't support explicit synchronization, we don't advertise the protocol at all. Currently only the DRM and X11 backends when using the GL renderer advertise the protocol for production use. Issues for discussion --------------------- a. Currently, a server-side wait of EGLSyncKHR is performed before using the EGLImage/texture during rendering. Unfortunately, it's not clear from the specs whether this is generally safe to do, or we need to sync before glEGLImageTargetTexture2DOES. The exception is TEXTURE_EXTERNAL_OES where the spec mentions it's enough to sync and then glBindTexture for any changes to take effect. Changes in v5: - Meson support. - Make explicit sync server error reporting more generic, supporting all explicit sync related interfaces not just wp_linux_surface_synchronization. - Fix typo in warning for missing EGL_KHR_wait_sync extension. - Support minor version 2 of the explicit sync protocol (i.e., support fences for opaque EGL buffers). Changes in v4: - Introduce and use fd_clear and and fd_move helpers. - Don't check for a valid buffer when updating surface acquire fence fd from state. - Assert that pending state acquire fence fd is always clear after a commit. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to just the renderer. - Check for EGL_KHR_wait_sync before using eglWaitSyncKHR. - Dup the acquire fence before passing to EGL. Changes in v3: - Keep acquire_fence_fd in surface instead of buffer. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to both backend and renderer. - Move comment about non-ownership of in_fence_fd to struct drm_plane_state definition. - Assert that we don't try to use planes with in-fences when using the legacy KMS API. - Remove unnecessary info from wayland error messages. - Handle acquire fence for subsurface commits. - Guard against self-update in fd_update. - Disconnect the client if acquire fence EGLSyncKHR creation or wait fails. - Use updated protocol interface names. - User correct format specifier for resource ids. - Advertise protocol for X11 backend with GL renderer. Changes in v2: - Remove sync file wait fallbacks. - Raise UNSUPPORTED_BUFFER error at commit if we have an acquire fence, but the committed buffer is not a valid linux_dmabuf. - Don't put buffers with in-fences on planes that don't support in-fences. - Don't advertise explicit sync protocol if backend does not support explicit sync. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
6 years ago
fd_clear(&surface->pending.acquire_fence_fd);
wl_resource_post_error(surface->synchronization_resource,
ZWP_LINUX_SURFACE_SYNCHRONIZATION_V1_ERROR_UNSUPPORTED_BUFFER,
"wl_surface@%"PRIu32" unsupported buffer for synchronization",
wl_resource_get_id(resource));
return;
}
}
libweston: Support zwp_surface_synchronization_v1.get_release Implement the get_release request of the zwp_surface_synchronization_v1 interface. This commit implements the zwp_buffer_release_v1 interface. It supports the zwp_buffer_release_v1.fenced_release event for surfaces rendered by the GL renderer, and the zwp_buffer_release_v1.immediate_release event for other cases. Note that the immediate_release event is safe to be used for surface buffers used as planes in the DRM backend, since the backend releases them only after the next page flip that doesn't use the buffers has finished. Changes in v7: - Remove "partial" from commit title and description. - Fix inverted check when clearing used_in_output_repaint flag. Changes in v5: - Use the new, generic explicit sync server error reporting function. - Introduce and use weston_buffer_release_move. - Introduce internally and use weston_buffer_release_destroy. Changes in v4: - Support the zwp_buffer_release_v1.fenced_release event. - Support release fences in the GL renderer. - Assert that pending state buffer_release is always NULL after a commit. - Simplify weston_buffer_release_reference. - Move removal of destroy listener before resource destruction to avoid concerns about use-after-free in weston_buffer_release_reference - Rename weston_buffer_release_reference.busy_count to ref_count. - Add documentation for weston_buffer_release and ..._reference. Changes in v3: - Raise NO_BUFFER for get_release if no buffer has been committed, don't raise UNSUPPORTED_BUFFER for non-dmabuf buffers, so get_release works for all valid buffers. - Destroy the buffer_release object after sending an event. - Track lifetime of buffer_release objects per commit, independently of any buffers. - Use updated protocol interface names. - Use correct format specifier for resource ids. Changes in v2: - Raise UNSUPPORTED_BUFFER at commit if client has requested a buffer_release, but the committed buffer is not a valid linux_dmabuf. - Remove tests that are not viable anymore due to our inability to create dmabuf buffers and fences in a unit-test environment. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
6 years ago
if (surface->pending.buffer_release_ref.buffer_release &&
!surface->pending.buffer) {
assert(surface->synchronization_resource);
wl_resource_post_error(surface->synchronization_resource,
ZWP_LINUX_SURFACE_SYNCHRONIZATION_V1_ERROR_NO_BUFFER,
"wl_surface@%"PRIu32" no buffer for synchronization",
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>
12 years ago
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);
}
}
static void
surface_set_buffer_transform(struct wl_client *client,
struct wl_resource *resource, int transform)
{
struct weston_surface *surface = wl_resource_get_user_data(resource);
/* 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;
}
surface->pending.buffer_viewport.buffer.transform = transform;
surface->pending.buffer_viewport.changed = 1;
}
static void
surface_set_buffer_scale(struct wl_client *client,
struct wl_resource *resource,
int32_t scale)
{
struct weston_surface *surface = wl_resource_get_user_data(resource);
if (scale < 1) {
wl_resource_post_error(resource,
WL_SURFACE_ERROR_INVALID_SCALE,
"buffer scale must be at least one "
"('%d' specified)", scale);
return;
}
surface->pending.buffer_viewport.buffer.scale = scale;
surface->pending.buffer_viewport.changed = 1;
}
static const struct wl_surface_interface surface_interface = {
surface_destroy,
surface_attach,
surface_damage,
surface_frame,
surface_set_opaque_region,
surface_set_input_region,
surface_commit,
surface_set_buffer_transform,
surface_set_buffer_scale,
surface_damage_buffer
};
static void
compositor_create_surface(struct wl_client *client,
struct wl_resource *resource, uint32_t id)
{
struct weston_compositor *ec = wl_resource_get_user_data(resource);
struct weston_surface *surface;
surface = weston_surface_create(ec);
if (surface == NULL)
goto err;
surface->resource =
wl_resource_create(client, &wl_surface_interface,
wl_resource_get_version(resource), id);
if (surface->resource == NULL)
goto err_res;
wl_resource_set_implementation(surface->resource, &surface_interface,
surface, destroy_surface);
wl_signal_emit(&ec->create_surface_signal, surface);
return;
err_res:
weston_surface_unref(surface);
err:
wl_resource_post_no_memory(resource);
}
static void
destroy_region(struct wl_resource *resource)
{
struct weston_region *region = wl_resource_get_user_data(resource);
pixman_region32_fini(&region->region);
free(region);
}
static void
region_destroy(struct wl_client *client, struct wl_resource *resource)
{
wl_resource_destroy(resource);
}
static void
region_add(struct wl_client *client, struct wl_resource *resource,
int32_t x, int32_t y, int32_t width, int32_t height)
{
struct weston_region *region = wl_resource_get_user_data(resource);
pixman_region32_union_rect(&region->region, &region->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)
{
struct weston_region *region = wl_resource_get_user_data(resource);
pixman_region32_t rect;
pixman_region32_init_rect(&rect, x, y, width, height);
pixman_region32_subtract(&region->region, &region->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(&region->region);
region->resource =
wl_resource_create(client, &wl_region_interface, 1, id);
if (region->resource == NULL) {
free(region);
wl_resource_post_no_memory(resource);
return;
}
wl_resource_set_implementation(region->resource, &region_interface,
region, destroy_region);
}
static const struct wl_compositor_interface compositor_interface = {
compositor_create_surface,
compositor_create_region
};
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>
12 years ago
static void
weston_subsurface_commit_from_cache(struct weston_subsurface *sub)
{
struct weston_surface *surface = sub->surface;
weston_surface_commit_state(surface, &sub->cached);
weston_buffer_reference(&sub->cached_buffer_ref, NULL,
BUFFER_WILL_NOT_BE_ACCESSED);
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>
12 years ago
weston_surface_commit_subsurface_order(surface);
weston_surface_schedule_repaint(surface);
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>
12 years ago
}
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
* 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>
12 years ago
*/
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>
12 years ago
-surface->pending.sx, -surface->pending.sy);
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>
12 years ago
pixman_region32_union(&sub->cached.damage_buffer,
&sub->cached.damage_buffer,
&surface->pending.damage_buffer);
pixman_region32_clear(&surface->pending.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>
12 years ago
if (surface->pending.newly_attached) {
sub->cached.newly_attached = 1;
weston_surface_state_set_buffer(&sub->cached,
surface->pending.buffer);
weston_buffer_reference(&sub->cached_buffer_ref,
surface->pending.buffer,
surface->pending.buffer ?
BUFFER_MAY_BE_ACCESSED :
BUFFER_WILL_NOT_BE_ACCESSED);
weston_presentation_feedback_discard_list(
&sub->cached.feedback_list);
libweston: Support zwp_surface_synchronization_v1.set_acquire_fence Implement the set_acquire_fence request of the zwp_surface_synchronization_v1 interface. The implementation uses the acquire fence in two ways: 1. If the associated buffer is used as GL render source, an EGLSyncKHR is created from the fence and used to synchronize access. 2. If the associated buffer is used as a plane framebuffer, the acquire fence is treated as an in-fence for the atomic commit operation. If in-fences are not supported and the buffer has an acquire fence, we don't consider it for plane placement. If the used compositor/renderer doesn't support explicit synchronization, we don't advertise the protocol at all. Currently only the DRM and X11 backends when using the GL renderer advertise the protocol for production use. Issues for discussion --------------------- a. Currently, a server-side wait of EGLSyncKHR is performed before using the EGLImage/texture during rendering. Unfortunately, it's not clear from the specs whether this is generally safe to do, or we need to sync before glEGLImageTargetTexture2DOES. The exception is TEXTURE_EXTERNAL_OES where the spec mentions it's enough to sync and then glBindTexture for any changes to take effect. Changes in v5: - Meson support. - Make explicit sync server error reporting more generic, supporting all explicit sync related interfaces not just wp_linux_surface_synchronization. - Fix typo in warning for missing EGL_KHR_wait_sync extension. - Support minor version 2 of the explicit sync protocol (i.e., support fences for opaque EGL buffers). Changes in v4: - Introduce and use fd_clear and and fd_move helpers. - Don't check for a valid buffer when updating surface acquire fence fd from state. - Assert that pending state acquire fence fd is always clear after a commit. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to just the renderer. - Check for EGL_KHR_wait_sync before using eglWaitSyncKHR. - Dup the acquire fence before passing to EGL. Changes in v3: - Keep acquire_fence_fd in surface instead of buffer. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to both backend and renderer. - Move comment about non-ownership of in_fence_fd to struct drm_plane_state definition. - Assert that we don't try to use planes with in-fences when using the legacy KMS API. - Remove unnecessary info from wayland error messages. - Handle acquire fence for subsurface commits. - Guard against self-update in fd_update. - Disconnect the client if acquire fence EGLSyncKHR creation or wait fails. - Use updated protocol interface names. - User correct format specifier for resource ids. - Advertise protocol for X11 backend with GL renderer. Changes in v2: - Remove sync file wait fallbacks. - Raise UNSUPPORTED_BUFFER error at commit if we have an acquire fence, but the committed buffer is not a valid linux_dmabuf. - Don't put buffers with in-fences on planes that don't support in-fences. - Don't advertise explicit sync protocol if backend does not support explicit sync. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
6 years ago
/* zwp_surface_synchronization_v1.set_acquire_fence */
fd_move(&sub->cached.acquire_fence_fd,
&surface->pending.acquire_fence_fd);
libweston: Support zwp_surface_synchronization_v1.get_release Implement the get_release request of the zwp_surface_synchronization_v1 interface. This commit implements the zwp_buffer_release_v1 interface. It supports the zwp_buffer_release_v1.fenced_release event for surfaces rendered by the GL renderer, and the zwp_buffer_release_v1.immediate_release event for other cases. Note that the immediate_release event is safe to be used for surface buffers used as planes in the DRM backend, since the backend releases them only after the next page flip that doesn't use the buffers has finished. Changes in v7: - Remove "partial" from commit title and description. - Fix inverted check when clearing used_in_output_repaint flag. Changes in v5: - Use the new, generic explicit sync server error reporting function. - Introduce and use weston_buffer_release_move. - Introduce internally and use weston_buffer_release_destroy. Changes in v4: - Support the zwp_buffer_release_v1.fenced_release event. - Support release fences in the GL renderer. - Assert that pending state buffer_release is always NULL after a commit. - Simplify weston_buffer_release_reference. - Move removal of destroy listener before resource destruction to avoid concerns about use-after-free in weston_buffer_release_reference - Rename weston_buffer_release_reference.busy_count to ref_count. - Add documentation for weston_buffer_release and ..._reference. Changes in v3: - Raise NO_BUFFER for get_release if no buffer has been committed, don't raise UNSUPPORTED_BUFFER for non-dmabuf buffers, so get_release works for all valid buffers. - Destroy the buffer_release object after sending an event. - Track lifetime of buffer_release objects per commit, independently of any buffers. - Use updated protocol interface names. - Use correct format specifier for resource ids. Changes in v2: - Raise UNSUPPORTED_BUFFER at commit if client has requested a buffer_release, but the committed buffer is not a valid linux_dmabuf. - Remove tests that are not viable anymore due to our inability to create dmabuf buffers and fences in a unit-test environment. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
6 years ago
/* zwp_surface_synchronization_v1.get_release */
weston_buffer_release_move(&sub->cached.buffer_release_ref,
&surface->pending.buffer_release_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>
12 years ago
}
sub->cached.desired_protection = surface->pending.desired_protection;
sub->cached.protection_mode = surface->pending.protection_mode;
libweston: Support zwp_surface_synchronization_v1.set_acquire_fence Implement the set_acquire_fence request of the zwp_surface_synchronization_v1 interface. The implementation uses the acquire fence in two ways: 1. If the associated buffer is used as GL render source, an EGLSyncKHR is created from the fence and used to synchronize access. 2. If the associated buffer is used as a plane framebuffer, the acquire fence is treated as an in-fence for the atomic commit operation. If in-fences are not supported and the buffer has an acquire fence, we don't consider it for plane placement. If the used compositor/renderer doesn't support explicit synchronization, we don't advertise the protocol at all. Currently only the DRM and X11 backends when using the GL renderer advertise the protocol for production use. Issues for discussion --------------------- a. Currently, a server-side wait of EGLSyncKHR is performed before using the EGLImage/texture during rendering. Unfortunately, it's not clear from the specs whether this is generally safe to do, or we need to sync before glEGLImageTargetTexture2DOES. The exception is TEXTURE_EXTERNAL_OES where the spec mentions it's enough to sync and then glBindTexture for any changes to take effect. Changes in v5: - Meson support. - Make explicit sync server error reporting more generic, supporting all explicit sync related interfaces not just wp_linux_surface_synchronization. - Fix typo in warning for missing EGL_KHR_wait_sync extension. - Support minor version 2 of the explicit sync protocol (i.e., support fences for opaque EGL buffers). Changes in v4: - Introduce and use fd_clear and and fd_move helpers. - Don't check for a valid buffer when updating surface acquire fence fd from state. - Assert that pending state acquire fence fd is always clear after a commit. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to just the renderer. - Check for EGL_KHR_wait_sync before using eglWaitSyncKHR. - Dup the acquire fence before passing to EGL. Changes in v3: - Keep acquire_fence_fd in surface instead of buffer. - Clarify that WESTON_CAP_EXPLICIT_SYNC applies to both backend and renderer. - Move comment about non-ownership of in_fence_fd to struct drm_plane_state definition. - Assert that we don't try to use planes with in-fences when using the legacy KMS API. - Remove unnecessary info from wayland error messages. - Handle acquire fence for subsurface commits. - Guard against self-update in fd_update. - Disconnect the client if acquire fence EGLSyncKHR creation or wait fails. - Use updated protocol interface names. - User correct format specifier for resource ids. - Advertise protocol for X11 backend with GL renderer. Changes in v2: - Remove sync file wait fallbacks. - Raise UNSUPPORTED_BUFFER error at commit if we have an acquire fence, but the committed buffer is not a valid linux_dmabuf. - Don't put buffers with in-fences on planes that don't support in-fences. - Don't advertise explicit sync protocol if backend does not support explicit sync. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
6 years ago
assert(surface->pending.acquire_fence_fd == -1);
libweston: Support zwp_surface_synchronization_v1.get_release Implement the get_release request of the zwp_surface_synchronization_v1 interface. This commit implements the zwp_buffer_release_v1 interface. It supports the zwp_buffer_release_v1.fenced_release event for surfaces rendered by the GL renderer, and the zwp_buffer_release_v1.immediate_release event for other cases. Note that the immediate_release event is safe to be used for surface buffers used as planes in the DRM backend, since the backend releases them only after the next page flip that doesn't use the buffers has finished. Changes in v7: - Remove "partial" from commit title and description. - Fix inverted check when clearing used_in_output_repaint flag. Changes in v5: - Use the new, generic explicit sync server error reporting function. - Introduce and use weston_buffer_release_move. - Introduce internally and use weston_buffer_release_destroy. Changes in v4: - Support the zwp_buffer_release_v1.fenced_release event. - Support release fences in the GL renderer. - Assert that pending state buffer_release is always NULL after a commit. - Simplify weston_buffer_release_reference. - Move removal of destroy listener before resource destruction to avoid concerns about use-after-free in weston_buffer_release_reference - Rename weston_buffer_release_reference.busy_count to ref_count. - Add documentation for weston_buffer_release and ..._reference. Changes in v3: - Raise NO_BUFFER for get_release if no buffer has been committed, don't raise UNSUPPORTED_BUFFER for non-dmabuf buffers, so get_release works for all valid buffers. - Destroy the buffer_release object after sending an event. - Track lifetime of buffer_release objects per commit, independently of any buffers. - Use updated protocol interface names. - Use correct format specifier for resource ids. Changes in v2: - Raise UNSUPPORTED_BUFFER at commit if client has requested a buffer_release, but the committed buffer is not a valid linux_dmabuf. - Remove tests that are not viable anymore due to our inability to create dmabuf buffers and fences in a unit-test environment. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
6 years ago
assert(surface->pending.buffer_release_ref.buffer_release == 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>
12 years ago
sub->cached.sx += surface->pending.sx;
sub->cached.sy += surface->pending.sy;
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>
12 years ago
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>
12 years ago
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);
wl_list_insert_list(&sub->cached.feedback_list,
&surface->pending.feedback_list);
wl_list_init(&surface->pending.feedback_list);
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>
12 years ago
}
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>
12 years ago
weston_subsurface_is_synchronized(struct weston_subsurface *sub)
{
while (sub) {
if (sub->synchronized)
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>
12 years ago
if (!sub->parent)
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>
12 years ago
sub = weston_surface_to_subsurface(sub->parent);
}
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>
12 years ago
}
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 {
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>
12 years ago
/* 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
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>
12 years ago
{
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.
*/
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>
12 years ago
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);
}
}
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>
11 years ago
struct weston_view *view;
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>
11 years ago
wl_list_for_each(view, &sub->surface->views, surface_link)
weston_view_set_position(view,
sub->position.x,
sub->position.y);
sub->position.set = 0;
}
if (parent_is_synchronized || sub->synchronized)
weston_subsurface_synchronized_commit(sub);
}
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>
12 years ago
static void
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>
12 years ago
{
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>
11 years ago
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>
12 years ago
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>
11 years ago
wl_list_for_each(view, &surface->views, surface_link)
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>
12 years ago
/* 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.
*/
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>
12 years ago
if (!weston_surface_is_mapped(surface)) {
surface->is_mapped = surface->buffer_ref.buffer != NULL;
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>
11 years ago
/* 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>
12 years ago
* 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.
*
* 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>
12 years ago
* 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>
11 years ago
* 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>
12 years ago
*/
}
}
static struct weston_subsurface *
weston_surface_to_subsurface(struct weston_surface *surface)
{
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>
12 years ago
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>
12 years ago
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;
}
10 years ago
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;
}
WL_EXPORT const char *
weston_surface_get_role(struct weston_surface *surface)
{
return surface->role_name;
}
WL_EXPORT void
weston_surface_set_label_func(struct weston_surface *surface,
int (*desc)(struct weston_surface *,
char *, size_t))
{
surface->get_label = desc;
weston_timeline_refresh_subscription_objects(surface->compositor,
surface);
}
/** 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, 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_buffer *buffer = surface->buffer_ref.buffer;
if (buffer) {
*width = buffer->width;
*height = buffer->height;
} else {
*width = 0;
*height = 0;
}
}
/** 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(&region,
0, 0,
surface->width, surface->height);
wl_list_for_each(subsurface, &surface->subsurface_list, parent_link)
pixman_region32_union_rect(&region, &region,
subsurface->position.x,
subsurface->position.y,
subsurface->surface->width,
subsurface->surface->height);
box = pixman_region32_extents(&region);
struct weston_geometry geometry = {
.x = box->x1,
.y = box->y1,
.width = box->x2 - box->x1,
.height = box->y2 - box->y1,
};
pixman_region32_fini(&region);
return geometry;
}
/** 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 weston_surface_get_content_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>
12 years ago
static void
subsurface_set_position(struct wl_client *client,
struct wl_resource *resource, int32_t x, int32_t y)
{
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>
12 years ago
if (!sub)
return;
sub->position.x = x;
sub->position.y = y;
sub->position.set = 1;
}
static struct weston_subsurface *
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>
12 years ago
{
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>
12 years ago
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>
12 years ago
return NULL;
}
static struct weston_subsurface *
subsurface_sibling_check(struct weston_subsurface *sub,
struct weston_surface *surface,
const char *request)
{
struct weston_subsurface *sibling;
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>
12 years ago
if (!sibling) {
wl_resource_post_error(sub->resource,
WL_SUBSURFACE_ERROR_BAD_SURFACE,
"%s: wl_surface@%d is not a parent or sibling",
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>
12 years ago
return NULL;
}
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>
12 years ago
return sibling;
}
static void
subsurface_place_above(struct wl_client *client,
struct wl_resource *resource,
struct wl_resource *sibling_resource)
{
struct weston_subsurface *sub = wl_resource_get_user_data(resource);
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>
12 years ago
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);
sub->reordered = 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>
12 years ago
}
static void
subsurface_place_below(struct wl_client *client,
struct wl_resource *resource,
struct wl_resource *sibling_resource)
{
struct weston_subsurface *sub = wl_resource_get_user_data(resource);
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>
12 years ago
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);
sub->reordered = 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>
12 years ago
}
static void
subsurface_set_sync(struct wl_client *client, struct wl_resource *resource)
{
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>
12 years ago
if (sub)
sub->synchronized = 1;
}
static void
subsurface_set_desync(struct wl_client *client, struct wl_resource *resource)
{
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>
12 years ago
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>
12 years ago
sub->synchronized = 0;
/* 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>
12 years ago
}
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);
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>
12 years ago
/* The protocol object (wl_resource) is left inert. */
if (sub->resource)
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>
12 years ago
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);
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>
12 years ago
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)
{
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>
12 years ago
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;
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>
12 years ago
&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;
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>
12 years ago
&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>
11 years ago
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>
12 years ago
assert(sub->surface);
if (sub->resource) {
assert(weston_surface_to_subsurface(sub->surface) == sub);
assert(sub->parent_destroy_listener.notify ==
subsurface_handle_parent_destroy);
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>
11 years ago
weston_view_destroy(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>
11 years ago
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>
12 years ago
if (sub->parent)
weston_subsurface_unlink_parent(sub);
weston_surface_state_fini(&sub->cached);
weston_buffer_reference(&sub->cached_buffer_ref, NULL,
BUFFER_WILL_NOT_BE_ACCESSED);
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>
12 years ago
sub->surface->committed = NULL;
sub->surface->committed_private = NULL;
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>
12 years ago
} 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;
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>
12 years ago
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>
12 years ago
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>
11 years ago
wl_list_init(&sub->unused_views);
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>
12 years ago
if (!sub->resource) {
free(sub);
return NULL;
}
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>
12 years ago
weston_subsurface_link_surface(sub, surface);
weston_subsurface_link_parent(sub, parent);
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>
12 years ago
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;
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>
12 years ago
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)
{
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>
12 years ago
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",
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>
12 years ago
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",
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>
12 years ago
return;
}
10 years ago
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>
12 years ago
return;
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",
where, id, wl_resource_get_id(surface_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>
12 years ago
/* 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;
}
surface->committed = subsurface_committed;
surface->committed_private = sub;
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>
12 years ago
}
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;
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>
12 years ago
resource =
wl_resource_create(client, &wl_subcompositor_interface, 1, id);
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>
12 years ago
}
/** Set a DPMS mode on all of the compositor's outputs
*
* \param compositor The compositor instance
* \param state The DPMS state the outputs will be set to
*/
static void
weston_compositor_dpms(struct weston_compositor *compositor,
enum dpms_enum state)
{
struct weston_output *output;
wl_list_for_each(output, &compositor->output_list, link)
if (output->set_dpms)
output->set_dpms(output, state);
}
/** 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.
* \ingroup compositor
*/
WL_EXPORT void
weston_compositor_wake(struct weston_compositor *compositor)
{
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) {
case WESTON_COMPOSITOR_SLEEPING:
case WESTON_COMPOSITOR_IDLE:
case WESTON_COMPOSITOR_OFFSCREEN:
weston_compositor_dpms(compositor, WESTON_DPMS_ON);
wl_signal_emit(&compositor->wake_signal, compositor);
/* fall through */
default:
wl_event_source_timer_update(compositor->idle_source,
compositor->idle_time * 1000);
}
}
/** 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.
*
* \ingroup compositor
*/
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);
}
}
/** 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.
*
* \ingroup compositor
*/
WL_EXPORT void
weston_compositor_sleep(struct weston_compositor *compositor)
{
if (compositor->state == WESTON_COMPOSITOR_SLEEPING)
return;
wl_event_source_timer_update(compositor->idle_source, 0);
compositor->state = WESTON_COMPOSITOR_SLEEPING;
weston_compositor_dpms(compositor, WESTON_DPMS_OFF);
}
/** 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.
*/
static int
idle_handler(void *data)
{
struct weston_compositor *compositor = data;
if (compositor->idle_inhibit)
return 1;
compositor->state = WESTON_COMPOSITOR_IDLE;
wl_signal_emit(&compositor->idle_signal, compositor);
return 1;
}
WL_EXPORT void
weston_plane_init(struct weston_plane *plane,
struct weston_compositor *ec,
int32_t x, int32_t y)
{
pixman_region32_init(&plane->damage);
pixman_region32_init(&plane->clip);
plane->x = x;
plane->y = y;
plane->compositor = ec;
/* 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);
}
WL_EXPORT void
weston_plane_release(struct weston_plane *plane)
{
struct weston_view *view;
pixman_region32_fini(&plane->damage);
pixman_region32_fini(&plane->clip);
/*
* Can't use paint node list here, weston_plane is not specific to an
* output.
*/
wl_list_for_each(view, &plane->compositor->view_list, link) {
if (view->plane == plane)
view->plane = NULL;
}
wl_list_remove(&plane->link);
}
/** weston_compositor_stack_plane
* \ingroup compositor
*/
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);
}
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,
};
static void unbind_resource(struct wl_resource *resource)
{
wl_list_remove(wl_resource_get_link(resource));
}
static void
bind_output(struct wl_client *client,
void *data, uint32_t version, uint32_t id)
{
struct weston_head *head = data;
struct weston_output *output = head->output;
struct weston_mode *mode;
struct wl_resource *resource;
resource = wl_resource_create(client, &wl_output_interface,
version, id);
if (resource == NULL) {
wl_client_post_no_memory(client);
return;
}
wl_list_insert(&head->resource_list, wl_resource_get_link(resource));
wl_resource_set_implementation(resource, &output_interface, head,
unbind_resource);
assert(output);
wl_output_send_geometry(resource,
output->x,
output->y,
head->mm_width,
head->mm_height,
head->subpixel,
head->make, head->model,
output->transform);
if (version >= WL_OUTPUT_SCALE_SINCE_VERSION)
wl_output_send_scale(resource,
output->current_scale);
wl_list_for_each (mode, &output->mode_list, link) {
wl_output_send_mode(resource,
mode->flags,
mode->width,
mode->height,
mode->refresh);
}
if (version >= WL_OUTPUT_DONE_SINCE_VERSION)
wl_output_send_done(resource);
}
static void
weston_head_add_global(struct weston_head *head)
{
head->global = wl_global_create(head->compositor->wl_display,
&wl_output_interface, 3,
head, bind_output);
}
/** Remove the global wl_output protocol object
*
* \param head The head whose global to remove.
*
* Also orphans the wl_resources for this head (wl_output).
*/
static void
weston_head_remove_global(struct weston_head *head)
{
struct wl_resource *resource, *tmp;
if (head->global)
wl_global_destroy(head->global);
head->global = NULL;
wl_resource_for_each_safe(resource, tmp, &head->resource_list) {
unbind_resource(resource);
wl_resource_set_destructor(resource, NULL);
wl_resource_set_user_data(resource, NULL);
}
wl_resource_for_each(resource, &head->xdg_output_resource_list) {
/* It's sufficient to unset the destructor, then the list elements
* won't be accessed.
*/
wl_resource_set_destructor(resource, NULL);
}
wl_list_init(&head->xdg_output_resource_list);
}
/** Get the backing object of wl_output
*
* \param resource A wl_output protocol object.
* \return The backing object (user data) of a wl_resource representing a
* wl_output protocol object.
*
* \ingroup head
*/
WL_EXPORT struct weston_head *
weston_head_from_resource(struct wl_resource *resource)
{
assert(wl_resource_instance_of(resource, &wl_output_interface,
&output_interface));
return wl_resource_get_user_data(resource);
}
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
/** Initialize a pre-allocated weston_head
*
* \param head The head to initialize.
* \param name The head name, e.g. the connector name or equivalent.
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
*
* The head will be safe to attach, detach and release.
*
* The name is used in logs, and can be used by compositors as a configuration
* identifier.
*
* \ingroup head
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
* \internal
*/
WL_EXPORT void
weston_head_init(struct weston_head *head, const char *name)
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
{
/* Add some (in)sane defaults which can be used
* for checking if an output was properly configured
*/
memset(head, 0, sizeof *head);
wl_list_init(&head->compositor_link);
wl_signal_init(&head->destroy_signal);
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
wl_list_init(&head->output_link);
wl_list_init(&head->resource_list);
wl_list_init(&head->xdg_output_resource_list);
head->name = strdup(name);
head->supported_eotf_mask = WESTON_EOTF_MODE_SDR;
head->current_protection = WESTON_HDCP_DISABLE;
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
}
/** Send output heads changed signal
*
* \param output The output that changed.
*
* Notify that the enabled output gained and/or lost heads, or that the
* associated heads may have changed their connection status. This does not
* include cases where the output becomes enabled or disabled. The registered
* callbacks are called after the change has successfully happened.
*
* If connection status change causes the compositor to attach or detach a head
* to an enabled output, the registered callbacks may be called multiple times.
*
* \ingroup output
*/
static void
weston_output_emit_heads_changed(struct weston_output *output)
{
wl_signal_emit(&output->compositor->output_heads_changed_signal,
output);
}
/** Idle task for emitting heads_changed_signal */
static void
weston_compositor_call_heads_changed(void *data)
{
struct weston_compositor *compositor = data;
struct weston_head *head;
compositor->heads_changed_source = NULL;
wl_signal_emit(&compositor->heads_changed_signal, compositor);
wl_list_for_each(head, &compositor->head_list, compositor_link) {
if (head->output && head->output->enabled)
weston_output_emit_heads_changed(head->output);
}
}
/** Schedule a call on idle to heads_changed callback
*
* \param compositor The Compositor.
*
* \ingroup compositor
* \internal
*/
static void
weston_compositor_schedule_heads_changed(struct weston_compositor *compositor)
{
struct wl_event_loop *loop;
if (compositor->heads_changed_source)
return;
loop = wl_display_get_event_loop(compositor->wl_display);
compositor->heads_changed_source = wl_event_loop_add_idle(loop,
weston_compositor_call_heads_changed, compositor);
}
/** Register a new head
*
* \param compositor The compositor.
* \param head The head to register, must not be already registered.
*
* This signals the core that a new head has become available, leading to
* heads_changed hook being called later.
*
* \ingroup compositor
* \internal
*/
WL_EXPORT void
weston_compositor_add_head(struct weston_compositor *compositor,
struct weston_head *head)
{
assert(wl_list_empty(&head->compositor_link));
assert(head->name);
wl_list_insert(compositor->head_list.prev, &head->compositor_link);
head->compositor = compositor;
weston_compositor_schedule_heads_changed(compositor);
}
/** Adds a listener to be called when heads change
*
* \param compositor The compositor.
* \param listener The listener to add.
*
* The listener notify function argument is weston_compositor.
*
* The listener function will be called after heads are added or their
* connection status has changed. Several changes may be accumulated into a
* single call. The user is expected to iterate over the existing heads and
* check their statuses to find out what changed.
*
* \sa weston_compositor_iterate_heads, weston_head_is_connected,
* weston_head_is_enabled
* \ingroup compositor
*/
WL_EXPORT void
weston_compositor_add_heads_changed_listener(struct weston_compositor *compositor,
struct wl_listener *listener)
{
wl_signal_add(&compositor->heads_changed_signal, listener);
}
/** Iterate over available heads
*
* \param compositor The compositor.
* \param iter The iterator, or NULL for start.
* \return The next available head in the list.
*
* Returns all available heads, regardless of being connected or enabled.
*
* You can iterate over all heads as follows:
* \code
* struct weston_head *head = NULL;
*
* while ((head = weston_compositor_iterate_heads(compositor, head))) {
* ...
* }
* \endcode
*
* If you cause \c iter to be removed from the list, you cannot use it to
* continue iterating. Removing any other item is safe.
*
* \ingroup compositor
*/
WL_EXPORT struct weston_head *
weston_compositor_iterate_heads(struct weston_compositor *compositor,
struct weston_head *iter)
{
struct wl_list *list = &compositor->head_list;
struct wl_list *node;
assert(compositor);
assert(!iter || iter->compositor == compositor);
if (iter)
node = iter->compositor_link.next;
else
node = list->next;
assert(node);
assert(!iter || node != &iter->compositor_link);
if (node == list)
return NULL;
return container_of(node, struct weston_head, compositor_link);
}
/** Iterate over attached heads
*
* \param output The output whose heads to iterate.
* \param iter The iterator, or NULL for start.
* \return The next attached head in the list.
*
* Returns all heads currently attached to the output.
*
* You can iterate over all heads as follows:
* \code
* struct weston_head *head = NULL;
*
* while ((head = weston_output_iterate_heads(output, head))) {
* ...
* }
* \endcode
*
* If you cause \c iter to be removed from the list, you cannot use it to
* continue iterating. Removing any other item is safe.
*
* \ingroup output
*/
WL_EXPORT struct weston_head *
weston_output_iterate_heads(struct weston_output *output,
struct weston_head *iter)
{
struct wl_list *list = &output->head_list;
struct wl_list *node;
assert(output);
assert(!iter || iter->output == output);
if (iter)
node = iter->output_link.next;
else
node = list->next;
assert(node);
assert(!iter || node != &iter->output_link);
if (node == list)
return NULL;
return container_of(node, struct weston_head, output_link);
}
/** Attach a head to an output
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
*
* \param output The output to attach to.
* \param head The head that is not yet attached.
* \return 0 on success, -1 on failure.
*
* Attaches the given head to the output. All heads of an output are clones
* and share the resolution and timings.
*
* Cloning heads this way uses less resources than creating an output for
* each head, but is not always possible due to environment, driver and hardware
* limitations.
*
* On failure, the head remains unattached. Success of this function does not
* guarantee the output configuration is actually valid. The final checks are
* made on weston_output_enable() unless the output was already enabled.
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
*
* \ingroup output
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
*/
WL_EXPORT int
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
weston_output_attach_head(struct weston_output *output,
struct weston_head *head)
{
char *head_names;
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
if (!wl_list_empty(&head->output_link))
return -1;
if (output->attach_head) {
if (output->attach_head(output, head) < 0)
return -1;
} else if (!wl_list_empty(&output->head_list)) {
/* No support for clones in the legacy path. */
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
return -1;
}
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
head->output = output;
wl_list_insert(output->head_list.prev, &head->output_link);
if (output->enabled) {
weston_head_add_global(head);
head_names = weston_output_create_heads_string(output);
weston_log("Output '%s' updated to have head(s) %s\n",
output->name, head_names);
free(head_names);
weston_output_emit_heads_changed(output);
}
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
return 0;
}
/** Detach a head from its output
*
* \param head The head to detach.
*
* It is safe to detach a non-attached head.
*
* If the head is attached to an enabled output and the output will be left
* with no heads, the output will be disabled.
*
* \ingroup head
* \sa weston_output_disable
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
*/
WL_EXPORT void
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
weston_head_detach(struct weston_head *head)
{
struct weston_output *output = head->output;
char *head_names;
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
wl_list_remove(&head->output_link);
wl_list_init(&head->output_link);
head->output = NULL;
if (!output)
return;
if (output->detach_head)
output->detach_head(output, head);
if (output->enabled) {
weston_head_remove_global(head);
if (wl_list_empty(&output->head_list)) {
weston_log("Output '%s' no heads left, disabling.\n",
output->name);
weston_output_disable(output);
} else {
head_names = weston_output_create_heads_string(output);
weston_log("Output '%s' updated to have head(s) %s\n",
output->name, head_names);
free(head_names);
weston_output_emit_heads_changed(output);
}
}
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
}
/** Destroy a head
*
* \param head The head to be released.
*
* Destroys the head. The caller is responsible for freeing the memory pointed
* to by \c head.
*
* \ingroup head
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
* \internal
*/
WL_EXPORT void
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
weston_head_release(struct weston_head *head)
{
weston_signal_emit_mutable(&head->destroy_signal, head);
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
weston_head_detach(head);
free(head->make);
free(head->model);
free(head->serial_number);
free(head->name);
wl_list_remove(&head->compositor_link);
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
}
static void
weston_head_set_device_changed(struct weston_head *head)
{
head->device_changed = true;
if (head->compositor)
weston_compositor_schedule_heads_changed(head->compositor);
}
/** String equal comparison with NULLs being equal */
static bool
str_null_eq(const char *a, const char *b)
{
if (!a && !b)
return true;
if (!!a != !!b)
return false;
return strcmp(a, b) == 0;
}
/** Store monitor make, model and serial number
*
* \param head The head to modify.
* \param make The monitor make. If EDID is available, the PNP ID. Otherwise
* any string, or NULL for none.
* \param model The monitor model or name, or a made-up string, or NULL for
* none.
* \param serialno The monitor serial number, a made-up string, or NULL for
* none.
*
* This may set the device_changed flag.
*
* \ingroup head
* \internal
*/
WL_EXPORT void
weston_head_set_monitor_strings(struct weston_head *head,
const char *make,
const char *model,
const char *serialno)
{
if (str_null_eq(head->make, make) &&
str_null_eq(head->model, model) &&
str_null_eq(head->serial_number, serialno))
return;
free(head->make);
free(head->model);
free(head->serial_number);
head->make = make ? strdup(make) : NULL;
head->model = model ? strdup(model) : NULL;
head->serial_number = serialno ? strdup(serialno) : NULL;
weston_head_set_device_changed(head);
}
/** Store display non-desktop status
*
* \param head The head to modify.
* \param non_desktop Whether the head connects to a non-desktop display.
*
* \ingroup head
* \internal
*/
WL_EXPORT void
weston_head_set_non_desktop(struct weston_head *head, bool non_desktop)
{
if (head->non_desktop == non_desktop)
return;
head->non_desktop = non_desktop;
weston_head_set_device_changed(head);
}
/** Store display transformation
*
* \param head The head to modify.
* \param transform The transformation to apply for this head
*
* This may set the device_changed flag.
*
* \ingroup head
* \internal
*/
WL_EXPORT void
weston_head_set_transform(struct weston_head *head, uint32_t transform)
{
if (head->transform == transform)
return;
head->transform = transform;
weston_head_set_device_changed(head);
}
/** Store physical image size
*
* \param head The head to modify.
* \param mm_width Image area width in millimeters.
* \param mm_height Image area height in millimeters.
*
* This may set the device_changed flag.
*
* \ingroup head
* \internal
*/
WL_EXPORT void
weston_head_set_physical_size(struct weston_head *head,
int32_t mm_width, int32_t mm_height)
{
if (head->mm_width == mm_width &&
head->mm_height == mm_height)
return;
head->mm_width = mm_width;
head->mm_height = mm_height;
weston_head_set_device_changed(head);
}
/** Store monitor sub-pixel layout
*
* \param head The head to modify.
* \param sp Sub-pixel layout. The possible values are:
* - WL_OUTPUT_SUBPIXEL_UNKNOWN,
* - WL_OUTPUT_SUBPIXEL_NONE,
* - WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB,
* - WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR,
* - WL_OUTPUT_SUBPIXEL_VERTICAL_RGB,
* - WL_OUTPUT_SUBPIXEL_VERTICAL_BGR
*
* This may set the device_changed flag.
*
* \ingroup head
* \internal
*/
WL_EXPORT void
weston_head_set_subpixel(struct weston_head *head,
enum wl_output_subpixel sp)
{
if (head->subpixel == sp)
return;
head->subpixel = sp;
weston_head_set_device_changed(head);
}
/** Mark the monitor as internal
*
* This is used for embedded screens, like laptop panels.
*
* \param head The head to mark as internal.
*
* By default a head is external. The type is often inferred from the physical
* connector type.
*
* \ingroup head
* \internal
*/
WL_EXPORT void
weston_head_set_internal(struct weston_head *head)
{
head->connection_internal = true;
}
/** Store connector status
*
* \param head The head to modify.
* \param connected Whether the head is connected.
*
* Connectors are created as disconnected. This function can be used to
* set the connector status.
*
* The status should be set to true when a physical connector is connected to
* a video sink device like a monitor and to false when the connector is
* disconnected. For nested backends, the connection status should reflect the
* connection to the parent display server.
*
* When the connection status changes, it schedules a call to the heads_changed
* hook and sets the device_changed flag.
*
* \sa weston_compositor_set_heads_changed_cb
* \ingroup head
* \internal
*/
WL_EXPORT void
weston_head_set_connection_status(struct weston_head *head, bool connected)
{
if (head->connected == connected)
return;
head->connected = connected;
weston_head_set_device_changed(head);
}
/** Store the set of supported EOTF modes
*
* \param head The head to modify.
* \param eotf_mask A bit mask with the possible bits or'ed together from
* enum weston_eotf_mode.
*
* This may set the device_changed flag.
*
* \ingroup head
* \internal
*/
WL_EXPORT void
weston_head_set_supported_eotf_mask(struct weston_head *head,
uint32_t eotf_mask)
{
assert((eotf_mask & ~WESTON_EOTF_MODE_ALL_MASK) == 0);
if (head->supported_eotf_mask == eotf_mask)
return;
head->supported_eotf_mask = eotf_mask;
weston_head_set_device_changed(head);
}
static void
weston_output_compute_protection(struct weston_output *output)
{
struct weston_head *head;
enum weston_hdcp_protection op_protection;
bool op_protection_valid = false;
struct weston_compositor *wc = output->compositor;
wl_list_for_each(head, &output->head_list, output_link) {
if (!op_protection_valid) {
op_protection = head->current_protection;
op_protection_valid = true;
}
if (head->current_protection < op_protection)
op_protection = head->current_protection;
}
if (!op_protection_valid)
op_protection = WESTON_HDCP_DISABLE;
if (output->current_protection != op_protection) {
output->current_protection = op_protection;
weston_output_damage(output);
weston_schedule_surface_protection_update(wc);
}
}
WL_EXPORT void
weston_head_set_content_protection_status(struct weston_head *head,
enum weston_hdcp_protection status)
{
head->current_protection = status;
if (head->output)
weston_output_compute_protection(head->output);
}
/** Is the head currently connected?
*
* \param head The head to query.
* \return Connection status.
*
* Returns true if the head is physically connected to a monitor, or in
* case of a nested backend returns true when there is a connection to the
* parent display server.
*
* This is independent from the head being enabled.
*
* \sa weston_head_is_enabled
* \ingroup head
*/
WL_EXPORT bool
weston_head_is_connected(struct weston_head *head)
{
return head->connected;
}
/** Is the head currently enabled?
*
* \param head The head to query.
* \return Video status.
*
* Returns true if the head is currently transmitting a video stream.
*
* This is independent of the head being connected.
*
* \sa weston_head_is_connected
* \ingroup head
*/
WL_EXPORT bool
weston_head_is_enabled(struct weston_head *head)
{
if (!head->output)
return false;
return head->output->enabled;
}
/** Has the device information changed?
*
* \param head The head to query.
* \return True if the device information has changed since last reset.
*
* The information about the connected display device, e.g. a monitor, may
* change without being disconnected in between. Changing information
* causes a call to the heads_changed hook.
*
* The information includes make, model, serial number, physical size,
* and sub-pixel type. The connection status is also included.
*
* \sa weston_head_reset_device_changed, weston_compositor_set_heads_changed_cb
* \ingroup head
*/
WL_EXPORT bool
weston_head_is_device_changed(struct weston_head *head)
{
return head->device_changed;
}
/** Does the head represent a non-desktop display?
*
* \param head The head to query.
* \return True if the device is a non-desktop display.
*
* Non-desktop heads are not attached to outputs by default.
* This stops weston from extending the desktop onto head mounted displays.
*
* \ingroup head
*/
WL_EXPORT bool
weston_head_is_non_desktop(struct weston_head *head)
{
return head->non_desktop;
}
/** Acknowledge device information change
*
* \param head The head to acknowledge.
*
* Clears the device changed flag on this head. When a compositor has processed
* device information, it should call this to be able to notice further
* changes.
*
* \sa weston_head_is_device_changed
* \ingroup head
*/
WL_EXPORT void
weston_head_reset_device_changed(struct weston_head *head)
{
head->device_changed = false;
}
/** Get the name of a head
*
* \param head The head to query.
* \return The head's name, not NULL.
*
* The name depends on the backend. The DRM backend uses connector names,
* other backends may use hardcoded names or user-given names.
*
* \ingroup head
*/
WL_EXPORT const char *
weston_head_get_name(struct weston_head *head)
{
return head->name;
}
/** Get the output the head is attached to
*
* \param head The head to query.
* \return The output the head is attached to, or NULL if detached.
* \ingroup head
*/
WL_EXPORT struct weston_output *
weston_head_get_output(struct weston_head *head)
{
return head->output;
}
/** Get the head's native transformation
*
* \param head The head to query.
* \return The head's native transform, as a WL_OUTPUT_TRANSFORM_* value
*
* A weston_head may have a 'native' transform provided by the backend.
* Examples include panels which are physically rotated, where the rotation
* is recorded and described as part of the system configuration. This call
* will return any known native transform for the head.
*
* \ingroup head
*/
WL_EXPORT uint32_t
weston_head_get_transform(struct weston_head *head)
{
return head->transform;
}
/** Add destroy callback for a head
*
* \param head The head to watch for.
* \param listener The listener to add. The \c notify member must be set.
*
* Heads may get destroyed for various reasons by the backends. If a head is
* attached to an output, the compositor should listen for head destruction
* and reconfigure or destroy the output if necessary.
*
* The destroy callbacks will be called on weston_head destruction before any
* automatic detaching from an associated weston_output and before any
* weston_head information is lost.
*
* The \c data argument to the notify callback is the weston_head being
* destroyed.
*
* \ingroup head
*/
WL_EXPORT void
weston_head_add_destroy_listener(struct weston_head *head,
struct wl_listener *listener)
{
wl_signal_add(&head->destroy_signal, listener);
}
/** Look up destroy listener for a head
*
* \param head The head to query.
* \param notify The notify function used used for the added destroy listener.
* \return The listener, or NULL if not found.
*
* This looks up the previously added destroy listener struct based on the
* notify function it has. The listener can be used to access user data
* through \c container_of().
*
* \sa wl_signal_get()
* \ingroup head
*/
WL_EXPORT struct wl_listener *
weston_head_get_destroy_listener(struct weston_head *head,
wl_notify_func_t notify)
{
return wl_signal_get(&head->destroy_signal, notify);
}
/* Move other outputs when one is resized so the space remains contiguous. */
static void
weston_compositor_reflow_outputs(struct weston_compositor *compositor,
struct weston_output *resized_output, int delta_width)
{
struct weston_output *output;
bool start_resizing = false;
if (!delta_width)
return;
wl_list_for_each(output, &compositor->output_list, link) {
if (output == resized_output) {
start_resizing = true;
continue;
}
if (start_resizing) {
weston_output_move(output, output->x + delta_width, output->y);
output->dirty = 1;
}
}
}
/** Transform a region in-place from global to output coordinates
*
* \param output The output that defines the transformation.
* \param region The region to be transformed in-place.
*
* This takes a region in the global coordinate system, and takes into account
* output position, transform and scale, and converts the region into output
* pixel coordinates in the framebuffer.
*
* \internal
* \ingroup output
*/
WL_EXPORT void
weston_output_region_from_global(struct weston_output *output,
pixman_region32_t *region)
{
pixman_region32_translate(region, -output->x, -output->y);
weston_transformed_region(output->width, output->height,
output->transform,
output->current_scale,
region, region);
}
static void
weston_output_update_matrix(struct weston_output *output)
{
weston_matrix_init(&output->matrix);
weston_matrix_translate(&output->matrix, -output->x, -output->y, 0);
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, -output->width, 0, 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, 0, -output->height, 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);
output->dirty = 0;
weston_matrix_invert(&output->inverse_matrix, &output->matrix);
}
static void
weston_output_transform_scale_init(struct weston_output *output, uint32_t transform, uint32_t scale)
{
output->transform = transform;
output->native_scale = scale;
output->current_scale = scale;
convert_size_by_transform_scale(&output->width, &output->height,
output->current_mode->width,
output->current_mode->height,
transform, scale);
}
static void
weston_output_init_geometry(struct weston_output *output, int x, int y)
{
output->x = x;
output->y = y;
pixman_region32_fini(&output->region);
pixman_region32_init_rect(&output->region, x, y,
output->width,
output->height);
}
/**
* \ingroup output
*/
WL_EXPORT void
weston_output_move(struct weston_output *output, int x, int y)
{
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
struct weston_head *head;
struct wl_resource *resource;
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
int ver;
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. */
wl_signal_emit(&output->compositor->output_moved_signal, output);
/* Notify clients of the change for output position. */
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
wl_list_for_each(head, &output->head_list, output_link) {
wl_resource_for_each(resource, &head->resource_list) {
wl_output_send_geometry(resource,
output->x,
output->y,
head->mm_width,
head->mm_height,
head->subpixel,
head->make,
head->model,
output->transform);
ver = wl_resource_get_version(resource);
if (ver >= WL_OUTPUT_DONE_SINCE_VERSION)
wl_output_send_done(resource);
}
wl_resource_for_each(resource, &head->xdg_output_resource_list) {
zxdg_output_v1_send_logical_position(resource,
output->x,
output->y);
zxdg_output_v1_send_done(resource);
}
}
}
/** Signal that a pending output is taken into use.
*
* Removes the output from the pending list and adds it to the compositor's
* list of enabled outputs. The output created signal is emitted.
*
* The output gets an internal ID assigned, and the wl_output global is
* created.
*
* \param compositor The compositor instance.
* \param output The output to be added.
*
* \internal
* \ingroup compositor
*/
static void
weston_compositor_add_output(struct weston_compositor *compositor,
struct weston_output *output)
{
struct weston_view *view, *next;
struct weston_head *head;
assert(!output->enabled);
/* Verify we haven't reached the limit of 32 available output IDs */
assert(ffs(~compositor->output_id_pool) > 0);
/* 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(~compositor->output_id_pool) - 1;
compositor->output_id_pool |= 1u << output->id;
wl_list_remove(&output->link);
wl_list_insert(compositor->output_list.prev, &output->link);
output->enabled = true;
wl_list_for_each(head, &output->head_list, output_link)
weston_head_add_global(head);
wl_signal_emit(&compositor->output_created_signal, output);
/*
* Use view_list, as paint nodes have not been created for this
* output yet. Any existing view might touch this new output.
*/
wl_list_for_each_safe(view, next, &compositor->view_list, link)
weston_view_geometry_dirty(view);
}
/** Transform device coordinates into global coordinates
*
* \param output the weston_output object
* \param[in] device_x X coordinate in device units.
* \param[in] device_y Y coordinate in device units.
* \param[out] x X coordinate in the global space.
* \param[out] y Y coordinate in the global space.
*
* Transforms coordinates from the device coordinate space (physical pixel
* units) to the global coordinate space (logical pixel units). This takes
* into account output transform and scale.
*
* \ingroup output
* \internal
*/
WL_EXPORT void
weston_output_transform_coordinate(struct weston_output *output,
double device_x, double device_y,
double *x, double *y)
{
struct weston_vector p = { {
device_x,
device_y,
0.0,
1.0 } };
weston_matrix_transform(&output->inverse_matrix, &p);
*x = p.f[0] / p.f[3];
*y = p.f[1] / p.f[3];
}
static bool
validate_float_range(float val, float min, float max)
{
return val >= min && val <= max;
}
/* Based on CTA-861-G, HDR static metadata type 1 */
static bool
weston_hdr_metadata_type1_validate(const struct weston_hdr_metadata_type1 *md)
{
unsigned i;
if (md->group_mask & WESTON_HDR_METADATA_TYPE1_GROUP_PRIMARIES) {
for (i = 0; i < ARRAY_LENGTH(md->primary); i++) {
if (!validate_float_range(md->primary[i].x, 0.0, 1.0))
return false;
if (!validate_float_range(md->primary[i].y, 0.0, 1.0))
return false;
}
}
if (md->group_mask & WESTON_HDR_METADATA_TYPE1_GROUP_WHITE) {
if (!validate_float_range(md->white.x, 0.0, 1.0))
return false;
if (!validate_float_range(md->white.y, 0.0, 1.0))
return false;
}
if (md->group_mask & WESTON_HDR_METADATA_TYPE1_GROUP_MAXDML) {
if (!validate_float_range(md->maxDML, 1.0, 65535.0))
return false;
}
if (md->group_mask & WESTON_HDR_METADATA_TYPE1_GROUP_MINDML) {
if (!validate_float_range(md->minDML, 0.0001, 6.5535))
return false;
}
if (md->group_mask & WESTON_HDR_METADATA_TYPE1_GROUP_MAXCLL) {
if (!validate_float_range(md->maxCLL, 1.0, 65535.0))
return false;
}
if (md->group_mask & WESTON_HDR_METADATA_TYPE1_GROUP_MAXFALL) {
if (!validate_float_range(md->maxFALL, 1.0, 65535.0))
return false;
}
return true;
}
WL_EXPORT void
weston_output_color_outcome_destroy(struct weston_output_color_outcome **pco)
{
struct weston_output_color_outcome *co = *pco;
if (!co)
return;
weston_color_transform_unref(co->from_sRGB_to_output);
weston_color_transform_unref(co->from_sRGB_to_blend);
weston_color_transform_unref(co->from_blend_to_output);
free(co);
*pco = NULL;
}
WESTON_EXPORT_FOR_TESTS bool
weston_output_set_color_outcome(struct weston_output *output)
{
struct weston_color_manager *cm = output->compositor->color_manager;
struct weston_output_color_outcome *colorout;
colorout = cm->create_output_color_outcome(cm, output);
if (!colorout) {
weston_log("Creating color transformation for output \"%s\" failed.\n",
output->name);
return false;
}
if (!weston_hdr_metadata_type1_validate(&colorout->hdr_meta)) {
weston_log("Internal color manager error creating Metadata Type 1 for output \"%s\".\n",
output->name);
goto out_error;
}
weston_output_color_outcome_destroy(&output->color_outcome);
output->color_outcome = colorout;
output->color_outcome_serial++;
output->from_blend_to_output_by_backend = false;
weston_log("Output '%s' using color profile: %s\n", output->name,
weston_color_profile_get_description(output->color_profile));
return true;
out_error:
weston_output_color_outcome_destroy(&colorout);
return false;
}
/** Removes output from compositor's list of enabled outputs
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
*
* \param output The weston_output object that is being removed.
*
* The following happens:
*
* - Destroys all paint nodes related to the output.
*
* - The output assignments of all views in the current scenegraph are
* recomputed.
*
* - Destroys output's color transforms.
*
* - Presentation feedback is discarded.
*
* - Compositor is notified that outputs were changed and
* applies the necessary changes to re-layout outputs.
*
* - The output is put back in the pending outputs list.
*
* - Signal is emitted 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, and the wl_output global is removed.
*
* - The output's internal ID is released.
*
* \ingroup compositor
* \internal
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
*/
static void
weston_compositor_remove_output(struct weston_output *output)
{
struct weston_compositor *compositor = output->compositor;
struct weston_paint_node *pnode, *pntmp;
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
struct weston_view *view;
struct weston_head *head;
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
assert(output->destroying);
assert(output->enabled);
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
wl_list_for_each_safe(pnode, pntmp,
&output->paint_node_list, output_link) {
weston_paint_node_destroy(pnode);
}
assert(wl_list_empty(&output->paint_node_z_order_list));
/*
* Use view_list in case the output did not go through repaint
* after a view came on it, lacking a paint node. Just to be sure.
*/
wl_list_for_each(view, &compositor->view_list, link) {
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
if (view->output_mask & (1u << output->id))
weston_view_assign_output(view);
}
weston_output_color_outcome_destroy(&output->color_outcome);
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
weston_presentation_feedback_discard_list(&output->feedback_list);
weston_compositor_reflow_outputs(compositor, output, -output->width);
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
wl_list_remove(&output->link);
wl_list_insert(compositor->pending_output_list.prev, &output->link);
output->enabled = false;
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
weston_signal_emit_mutable(&compositor->output_destroyed_signal, output);
weston_signal_emit_mutable(&output->destroy_signal, output);
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
wl_list_for_each(head, &output->head_list, output_link)
weston_head_remove_global(head);
compositor->output_id_pool &= ~(1u << output->id);
output->id = 0xffffffff; /* invalid */
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
}
/** 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.
*
* \ingroup output
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
*/
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.
*
* 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.
*
* \ingroup output
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
*/
WL_EXPORT void
weston_output_set_transform(struct weston_output *output,
uint32_t transform)
{
struct weston_pointer_motion_event ev;
struct wl_resource *resource;
struct weston_seat *seat;
pixman_region32_t old_region;
int mid_x, mid_y;
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
struct weston_head *head;
int ver;
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
if (!output->enabled && output->transform == UINT32_MAX) {
output->transform = transform;
return;
}
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
weston_output_transform_scale_init(output, transform, output->scale);
pixman_region32_init(&old_region);
pixman_region32_copy(&old_region, &output->region);
weston_output_init_geometry(output, output->x, output->y);
output->dirty = 1;
/* Notify clients of the change for output transform. */
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
wl_list_for_each(head, &output->head_list, output_link) {
wl_resource_for_each(resource, &head->resource_list) {
wl_output_send_geometry(resource,
output->x,
output->y,
head->mm_width,
head->mm_height,
head->subpixel,
head->make,
head->model,
output->transform);
ver = wl_resource_get_version(resource);
if (ver >= WL_OUTPUT_DONE_SINCE_VERSION)
wl_output_send_done(resource);
}
wl_resource_for_each(resource, &head->xdg_output_resource_list) {
zxdg_output_v1_send_logical_position(resource,
output->x,
output->y);
zxdg_output_v1_send_logical_size(resource,
output->width,
output->height);
zxdg_output_v1_send_done(resource);
}
}
/* we must ensure that pointers are inside output, otherwise they disappear */
mid_x = output->x + output->width / 2;
mid_y = output->y + output->height / 2;
ev.mask = WESTON_POINTER_MOTION_ABS;
ev.x = wl_fixed_to_double(wl_fixed_from_int(mid_x));
ev.y = wl_fixed_to_double(wl_fixed_from_int(mid_y));
wl_list_for_each(seat, &output->compositor->seat_list, link) {
struct weston_pointer *pointer = weston_seat_get_pointer(seat);
if (pointer && pixman_region32_contains_point(&old_region,
wl_fixed_to_int(pointer->x),
wl_fixed_to_int(pointer->y),
NULL))
weston_pointer_move(pointer, &ev);
}
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
}
/** Set output's color profile
*
* \param output The output to change.
* \param cprof The color profile to set. Can be NULL for default sRGB profile.
* \return True on success, or false on failure.
*
* Calling this function changes the color profile of the output. This causes
* all existing weston_color_transform objects related to this output via
* paint nodes to be unreferenced and later re-created on demand.
*
* This function may not be called from within weston_output_repaint().
*
* On failure, nothing is changed.
*
* \ingroup output
*/
WL_EXPORT bool
weston_output_set_color_profile(struct weston_output *output,
struct weston_color_profile *cprof)
{
struct weston_color_profile *old;
struct weston_paint_node *pnode;
old = output->color_profile;
output->color_profile = weston_color_profile_ref(cprof);
if (output->enabled) {
if (!weston_output_set_color_outcome(output)) {
/* Failed, roll back */
weston_color_profile_unref(output->color_profile);
output->color_profile = old;
return false;
}
/* Remove outdated cached color transformations */
wl_list_for_each(pnode, &output->paint_node_list, output_link) {
weston_surface_color_transform_fini(&pnode->surf_xform);
pnode->surf_xform_valid = false;
}
}
weston_color_profile_unref(old);
return true;
}
/** Set EOTF mode on an output
*
* \param output The output to modify, must be in disabled state.
* \param eotf_mode The EOTF mode to set.
*
* Setting the output EOTF mode is used for turning HDR on/off. There are
* multiple modes for HDR on, see enum weston_eotf_mode. This is the high level
* choice on how to drive a video sink (monitor), either in the traditional
* SDR mode or in one of the HDR modes.
*
* After attaching heads to an output, you can find out the possibly supported
* EOTF modes with weston_output_get_supported_eotf_modes().
*
* This function does not check whether the given eotf_mode is actually
* supported on the output. Enabling an output with an unsupported EOTF mode
* has undefined visual results.
*
* The initial EOTF mode is SDR.
*
* \ingroup output
*/
WL_EXPORT void
weston_output_set_eotf_mode(struct weston_output *output,
enum weston_eotf_mode eotf_mode)
{
assert(!output->enabled);
output->eotf_mode = eotf_mode;
}
/** Get EOTF mode of an output
*
* \param output The output to query.
* \return The EOTF mode.
*
* \sa weston_output_set_eotf_mode
* \ingroup output
*/
WL_EXPORT enum weston_eotf_mode
weston_output_get_eotf_mode(const struct weston_output *output)
{
return output->eotf_mode;
}
/** Get HDR static metadata type 1
*
* \param output The output to query.
* \return Pointer to the metadata stored in weston_output.
*
* This function is meant to be used by libweston backends.
*
* \ingroup output
* \internal
*/
WL_EXPORT const struct weston_hdr_metadata_type1 *
weston_output_get_hdr_metadata_type1(const struct weston_output *output)
{
assert(output->color_outcome);
return &output->color_outcome->hdr_meta;
}
/** Set display or monitor basic color characteristics
*
* \param output The output to modify, must be in disabled state.
* \param cc The new characteristics to set, or NULL to unset everything.
*
* This sets the metadata that describes the color characteristics of the
* output in a very simple manner. If a non-NULL color profile is set for the
* output, that will always take precedence.
*
* The initial value has everything unset.
*
* This function is meant to be used by compositor frontends.
*
* \ingroup output
* \sa weston_output_set_color_profile
*/
WL_EXPORT void
weston_output_set_color_characteristics(struct weston_output *output,
const struct weston_color_characteristics *cc)
{
assert(!output->enabled);
if (cc)
output->color_characteristics = *cc;
else
output->color_characteristics.group_mask = 0;
}
/** Get display or monitor basic color characteristics
*
* \param output The output to query.
* \return Pointer to the metadata stored in weston_output.
*
* This function is meant to be used by color manager modules.
*
* \ingroup output
* \sa weston_output_set_color_characteristics
*/
WL_EXPORT const struct weston_color_characteristics *
weston_output_get_color_characteristics(struct weston_output *output)
{
return &output->color_characteristics;
}
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
/** 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.
* \param name Name for the output (the string is copied).
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
*
* Sets initial values for fields that are expected to be
* configured either by compositors or backends.
*
* The name is used in logs, and can be used by compositors as a configuration
* identifier.
*
* \ingroup output
* \internal
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
*/
WL_EXPORT void
weston_output_init(struct weston_output *output,
struct weston_compositor *compositor,
const char *name)
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
{
output->compositor = compositor;
output->destroying = 0;
output->name = strdup(name);
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
wl_list_init(&output->link);
wl_signal_init(&output->user_destroy_signal);
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
output->enabled = false;
output->eotf_mode = WESTON_EOTF_MODE_SDR;
output->desired_protection = WESTON_HDCP_DISABLE;
output->allow_protection = true;
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
wl_list_init(&output->head_list);
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
/* Add some (in)sane defaults which can be used
* for checking if an output was properly configured
*/
output->scale = 0;
/* Can't use -1 on uint32_t and 0 is valid enum value */
output->transform = UINT32_MAX;
pixman_region32_init(&output->region);
wl_list_init(&output->mode_list);
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
}
/** Adds weston_output object to pending output list.
*
* \param output The weston_output object to add
* \param compositor The compositor instance.
*
* The opposite of this operation is built into weston_output_release().
*
* \ingroup compositor
* \internal
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
*/
WL_EXPORT void
weston_compositor_add_pending_output(struct weston_output *output,
struct weston_compositor *compositor)
{
assert(output->disable);
assert(output->enable);
wl_list_remove(&output->link);
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
wl_list_insert(compositor->pending_output_list.prev, &output->link);
}
/** Create a string with the attached heads' names.
*
* The string must be free()'d.
*
* \ingroup output
*/
static char *
weston_output_create_heads_string(struct weston_output *output)
{
FILE *fp;
char *str = NULL;
size_t size = 0;
struct weston_head *head;
const char *sep = "";
fp = open_memstream(&str, &size);
if (!fp)
return NULL;
wl_list_for_each(head, &output->head_list, output_link) {
fprintf(fp, "%s%s", sep, head->name);
sep = ", ";
}
fclose(fp);
return str;
}
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
/** Constructs a weston_output object that can be used by the compositor.
*
* \param output The weston_output object that needs to be enabled. Must not
* be enabled already. Must have at least one head attached.
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
*
* Output coordinates are calculated and each new output is by default
* assigned to the right of previous one.
*
* Sets up the transformation, and geometry of the output using the
* properties that need to be configured by the compositor.
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
*
* 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.
*
* \ingroup output
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
*/
WL_EXPORT int
weston_output_enable(struct weston_output *output)
{
struct weston_compositor *c = output->compositor;
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
struct weston_output *iterator;
struct weston_head *head;
char *head_names;
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
int x = 0, y = 0;
if (output->enabled) {
weston_log("Error: attempt to enable an enabled output '%s'\n",
output->name);
return -1;
}
if (wl_list_empty(&output->head_list)) {
weston_log("Error: cannot enable output '%s' without heads.\n",
output->name);
return -1;
}
if (wl_list_empty(&output->mode_list) || !output->current_mode) {
weston_log("Error: no video mode for output '%s'.\n",
output->name);
return -1;
}
wl_list_for_each(head, &output->head_list, output_link) {
assert(head->make);
assert(head->model);
}
iterator = container_of(c->output_list.prev,
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
struct weston_output, link);
if (!wl_list_empty(&c->output_list))
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
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);
output->x = x;
output->y = y;
output->dirty = 1;
output->original_scale = output->scale;
wl_signal_init(&output->frame_signal);
wl_signal_init(&output->destroy_signal);
weston_output_transform_scale_init(output, output->transform, output->scale);
weston_output_init_geometry(output, x, y);
weston_output_damage(output);
wl_list_init(&output->animation_list);
wl_list_init(&output->feedback_list);
wl_list_init(&output->paint_node_list);
wl_list_init(&output->paint_node_z_order_list);
weston_log("Output '%s' attempts EOTF mode: %s\n", output->name,
weston_eotf_mode_to_str(output->eotf_mode));
if (!weston_output_set_color_outcome(output))
return -1;
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
/* 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_color_outcome_destroy(&output->color_outcome);
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
return -1;
}
weston_compositor_add_output(output->compositor, output);
head_names = weston_output_create_heads_string(output);
weston_log("Output '%s' enabled with head(s) %s\n",
output->name, head_names);
free(head_names);
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
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.
*
* Calls a backend specific function to disable an output, in case
* such function exists.
*
* The backend specific disable function may choose to postpone the disabling
* by returning a negative value, in which case this function returns early.
* In that case the backend will guarantee the output will be disabled soon
* by the backend calling this function again. One must not attempt to re-enable
* the output until that happens.
*
* Otherwise, if the output is being used by the compositor, it is removed
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
* 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()).
*
* See weston_output_init() for more information on the
* state output is returned to.
*
* If the output has never been enabled yet, this function can still be
* called to ensure that the output is actually turned off rather than left
* in the state it was discovered in.
*
* \ingroup output
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
*/
WL_EXPORT void
weston_output_disable(struct weston_output *output)
{
/* Should we rename this? */
output->destroying = 1;
/* Disable is called unconditionally also for not-enabled outputs,
* because at compositor start-up, if there is an output that is
* already on but the compositor wants to turn it off, we have to
* forward the turn-off to the backend so it knows to do it.
* The backend cannot initially turn off everything, because it
* would cause unnecessary mode-sets for all outputs the compositor
* wants to be on.
*/
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
if (output->disable(output) < 0)
return;
if (output->enabled) {
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
weston_compositor_remove_output(output);
assert(wl_list_empty(&output->paint_node_list));
}
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
output->destroying = 0;
}
/** Forces a synchronous call to heads_changed hook
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
*
* \param compositor The compositor instance
*
* If there are new or changed heads, calls the heads_changed hook and
* returns after the hook returns.
*
* \ingroup compositor
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
*/
WL_EXPORT void
weston_compositor_flush_heads_changed(struct weston_compositor *compositor)
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
{
if (compositor->heads_changed_source) {
wl_event_source_remove(compositor->heads_changed_source);
weston_compositor_call_heads_changed(compositor);
}
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
}
/** Add destroy callback for an output
*
* \param output The output to watch.
* \param listener The listener to add. The \c notify member must be set.
*
* The listener callback will be called when user destroys an output. This
* may be delayed by a backend in some cases. The main purpose of the
* listener is to allow hooking up custom data to the output. The custom data
* can be fetched via weston_output_get_destroy_listener() followed by
* container_of().
*
* The \c data argument to the notify callback is the weston_output being
* destroyed.
*
* @note This is for the final destruction of an output, not when it gets
* disabled. If you want to keep track of enabled outputs, this is not it.
*
* \ingroup output
*/
WL_EXPORT void
weston_output_add_destroy_listener(struct weston_output *output,
struct wl_listener *listener)
{
wl_signal_add(&output->user_destroy_signal, listener);
}
/** Look up destroy listener for an output
*
* \param output The output to query.
* \param notify The notify function used used for the added destroy listener.
* \return The listener, or NULL if not found.
*
* This looks up the previously added destroy listener struct based on the
* notify function it has. The listener can be used to access user data
* through \c container_of().
*
* \sa wl_signal_get() weston_output_add_destroy_listener()
* \ingroup output
*/
WL_EXPORT struct wl_listener *
weston_output_get_destroy_listener(struct weston_output *output,
wl_notify_func_t notify)
{
return wl_signal_get(&output->user_destroy_signal, notify);
}
/** Uninitialize an output
*
* Removes the output from the list of enabled outputs if necessary, but
* does not call the backend's output disable function. The output will no
* longer be in the list of pending outputs either.
*
* All fields of weston_output become uninitialized, i.e. should not be used
* anymore. The caller can free the memory after this.
*
* \ingroup output
* \internal
*/
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
WL_EXPORT void
weston_output_release(struct weston_output *output)
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
{
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
struct weston_head *head, *tmp;
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
output->destroying = 1;
weston_signal_emit_mutable(&output->user_destroy_signal, output);
if (output->idle_repaint_source)
wl_event_source_remove(output->idle_repaint_source);
if (output->enabled)
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
weston_compositor_remove_output(output);
weston_color_profile_unref(output->color_profile);
assert(output->color_outcome == NULL);
pixman_region32_fini(&output->region);
wl_list_remove(&output->link);
libweston: introduce weston_output::head_list The intention is that in the future backends will dynamically allocate weston_heads based on the resources they have. The lifetime of a weston_head will be independent of the lifetime of a weston_output it may be attached to. Backends allocate objects derived from weston_head, like they currently do for weston_output. Backend will choose when to destroy a weston_head. For clone mode, struct weston_output gains head_list member, which is the list of attached heads that will all show the same framebuffer. Since heads are growing out of weston_output, management functions are added. Detaching a head from an enabled output is allowed to accommodate disappearing heads. Attaching a head to an enabled output is disallowed because it may need hardware reconfiguration and testing, and so requires a weston_output_enable() call. As a temporary measure, we have one weston_head embedded in weston_output, so that backends can be migrated individually to the new allocation scheme. v8: - Do not send wp_presentation_feedback.sync_output events for multiple wl_output globals in weston_presentation_feedback_present(). v6: - adapt to upstream changes in weston_output_set_transform() - use wl_list_for_each_safe in weston_output_release() - removed weston_output_get_first_head() as it's not needed yet Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v5 Reviewed-by: Derek Foreman <derekf@osg.samsung.com> v7 Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
8 years ago
wl_list_for_each_safe(head, tmp, &output->head_list, output_link)
weston_head_detach(head);
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
free(output->name);
}
/** Find an output by its given name
*
* \param compositor The compositor to search in.
* \param name The output name to search for.
* \return An existing output with the given name, or NULL if not found.
*
* \ingroup compositor
*/
WL_EXPORT struct weston_output *
weston_compositor_find_output_by_name(struct weston_compositor *compositor,
const char *name)
{
struct weston_output *output;
wl_list_for_each(output, &compositor->output_list, link)
if (strcmp(output->name, name) == 0)
return output;
wl_list_for_each(output, &compositor->pending_output_list, link)
if (strcmp(output->name, name) == 0)
return output;
return NULL;
}
/** Create a named output for an unused head
*
* \param compositor The compositor.
* \param head The head to attach to the output.
* \param name The name for the output.
* \return A new \c weston_output, or NULL on failure.
*
* This creates a new weston_output that starts with the given head attached.
* The head must not be already attached to another output.
*
* An output must be configured and it must have at least one head before
* it can be enabled.
*
* \ingroup compositor
*/
WL_EXPORT struct weston_output *
weston_compositor_create_output(struct weston_compositor *compositor,
struct weston_head *head,
const char *name)
{
struct weston_output *output;
assert(compositor->backend->create_output);
if (weston_compositor_find_output_by_name(compositor, name)) {
weston_log("Warning: attempted to create an output with a "
"duplicate name '%s'.\n", name);
return NULL;
}
output = compositor->backend->create_output(compositor, name);
if (!output)
return NULL;
if (head && weston_output_attach_head(output, head) < 0) {
weston_output_destroy(output);
return NULL;
}
return output;
}
/** Destroy an output
*
* \param output The output to destroy.
*
* The heads attached to the given output are detached and become unused again.
*
* It is not necessary to explicitly destroy all outputs at compositor exit.
* weston_compositor_destroy() will automatically destroy any remaining
* outputs.
*
* \ingroup output
*/
WL_EXPORT void
weston_output_destroy(struct weston_output *output)
{
output->destroy(output);
}
/** When you need a head...
*
* This function is a hack, used until all code has been converted to become
* multi-head aware.
*
* \param output The weston_output whose head to get.
* \return The first head in the output's list.
*
* \ingroup output
*/
WL_EXPORT struct weston_head *
weston_output_get_first_head(struct weston_output *output)
{
if (wl_list_empty(&output->head_list))
return NULL;
return container_of(output->head_list.next,
struct weston_head, output_link);
}
/** Allow/Disallow content-protection support for an output
*
* This function sets the allow_protection member for an output. Setting of
* this field will allow the compositor to attempt content-protection for this
* output, for a backend that supports the content-protection protocol.
*
* \param output The weston_output for whom the content-protection is to be
* allowed.
* \param allow_protection The bool value which is to be set.
*/
WL_EXPORT void
weston_output_allow_protection(struct weston_output *output,
bool allow_protection)
{
output->allow_protection = allow_protection;
}
/** Get supported EOTF modes as a bit mask
*
* \param output The output to query.
* \return A bit mask with values from enum weston_eotf_mode or'ed together.
*
* Returns the bit mask of the EOTF modes that all the currently attached
* heads claim to support. Adding or removing heads may change the result.
* An output can be queried regrdless of whether it is enabled or disabled.
*
* If no heads are attached, no EOTF modes are deemed supported.
*
* \ingroup output
*/
WL_EXPORT uint32_t
weston_output_get_supported_eotf_modes(struct weston_output *output)
{
uint32_t eotf_modes = WESTON_EOTF_MODE_ALL_MASK;
struct weston_head *head;
if (wl_list_empty(&output->head_list))
return WESTON_EOTF_MODE_NONE;
wl_list_for_each(head, &output->head_list, output_link)
eotf_modes = eotf_modes & head->supported_eotf_mask;
return eotf_modes;
}
static void
xdg_output_unlist(struct wl_resource *resource)
{
wl_list_remove(wl_resource_get_link(resource));
}
static void
xdg_output_destroy(struct wl_client *client, struct wl_resource *resource)
{
wl_resource_destroy(resource);
}
static const struct zxdg_output_v1_interface xdg_output_interface = {
xdg_output_destroy
};
static void
xdg_output_manager_destroy(struct wl_client *client,
struct wl_resource *resource)
{
wl_resource_destroy(resource);
}
static void
xdg_output_manager_get_xdg_output(struct wl_client *client,
struct wl_resource *manager,
uint32_t id,
struct wl_resource *output_resource)
{
int version = wl_resource_get_version(manager);
struct weston_head *head = wl_resource_get_user_data(output_resource);
struct weston_output *output = head->output;
struct wl_resource *resource;
resource = wl_resource_create(client, &zxdg_output_v1_interface,
version, id);
if (resource == NULL) {
wl_client_post_no_memory(client);
return;
}
wl_list_insert(&head->xdg_output_resource_list,
wl_resource_get_link(resource));
wl_resource_set_implementation(resource, &xdg_output_interface,
NULL, xdg_output_unlist);
zxdg_output_v1_send_logical_position(resource, output->x, output->y);
zxdg_output_v1_send_logical_size(resource,
output->width,
output->height);
if (version >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION)
zxdg_output_v1_send_name(resource, head->name);
zxdg_output_v1_send_done(resource);
}
static const struct zxdg_output_manager_v1_interface xdg_output_manager_interface = {
xdg_output_manager_destroy,
xdg_output_manager_get_xdg_output
};
static void
bind_xdg_output_manager(struct wl_client *client,
void *data, uint32_t version, uint32_t id)
{
struct wl_resource *resource;
resource = wl_resource_create(client, &zxdg_output_manager_v1_interface,
version, id);
if (resource == NULL) {
wl_client_post_no_memory(client);
return;
}
wl_resource_set_implementation(resource, &xdg_output_manager_interface,
NULL, NULL);
}
static void
destroy_viewport(struct wl_resource *resource)
{
struct weston_surface *surface =
wl_resource_get_user_data(resource);
if (!surface)
return;
surface->viewport_resource = NULL;
surface->pending.buffer_viewport.buffer.src_width =
wl_fixed_from_int(-1);
surface->pending.buffer_viewport.surface.width = -1;
surface->pending.buffer_viewport.changed = 1;
}
static void
viewport_destroy(struct wl_client *client,
struct wl_resource *resource)
{
wl_resource_destroy(resource);
}
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);
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);
assert(surface->resource);
if (src_width == wl_fixed_from_int(-1) &&
src_height == wl_fixed_from_int(-1) &&
src_x == wl_fixed_from_int(-1) &&
src_y == wl_fixed_from_int(-1)) {
/* unset source rect */
surface->pending.buffer_viewport.buffer.src_width =
wl_fixed_from_int(-1);
surface->pending.buffer_viewport.changed = 1;
return;
}
if (src_width <= 0 || src_height <= 0 || src_x < 0 || src_y < 0) {
wl_resource_post_error(resource,
WP_VIEWPORT_ERROR_BAD_VALUE,
"wl_surface@%d viewport source "
"w=%f <= 0, h=%f <= 0, x=%f < 0, or y=%f < 0",
wl_resource_get_id(surface->resource),
wl_fixed_to_double(src_width),
wl_fixed_to_double(src_height),
wl_fixed_to_double(src_x),
wl_fixed_to_double(src_y));
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;
surface->pending.buffer_viewport.changed = 1;
}
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);
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);
if (dst_width == -1 && dst_height == -1) {
/* unset destination size */
surface->pending.buffer_viewport.surface.width = -1;
surface->pending.buffer_viewport.changed = 1;
return;
}
if (dst_width <= 0 || dst_height <= 0) {
wl_resource_post_error(resource,
WP_VIEWPORT_ERROR_BAD_VALUE,
"destination size must be positive (%dx%d)",
dst_width, dst_height);
return;
}
surface->pending.buffer_viewport.surface.width = dst_width;
surface->pending.buffer_viewport.surface.height = dst_height;
surface->pending.buffer_viewport.changed = 1;
}
static const struct wp_viewport_interface viewport_interface = {
viewport_destroy,
viewport_set_source,
viewport_set_destination
};
static void
viewporter_destroy(struct wl_client *client,
struct wl_resource *resource)
{
wl_resource_destroy(resource);
}
static void
viewporter_get_viewport(struct wl_client *client,
struct wl_resource *viewporter,
uint32_t id,
struct wl_resource *surface_resource)
{
int version = wl_resource_get_version(viewporter);
struct weston_surface *surface =
wl_resource_get_user_data(surface_resource);
struct wl_resource *resource;
if (surface->viewport_resource) {
wl_resource_post_error(viewporter,
WP_VIEWPORTER_ERROR_VIEWPORT_EXISTS,
"a viewport for that surface already exists");
return;
}
resource = wl_resource_create(client, &wp_viewport_interface,
version, id);
if (resource == NULL) {
wl_client_post_no_memory(client);
return;
}
wl_resource_set_implementation(resource, &viewport_interface,
surface, destroy_viewport);
surface->viewport_resource = resource;
}
static const struct wp_viewporter_interface viewporter_interface = {
viewporter_destroy,
viewporter_get_viewport
};
static void
bind_viewporter(struct wl_client *client,
void *data, uint32_t version, uint32_t id)
{
struct wl_resource *resource;
resource = wl_resource_create(client, &wp_viewporter_interface,
version, id);
if (resource == NULL) {
wl_client_post_no_memory(client);
return;
}
wl_resource_set_implementation(resource, &viewporter_interface,
NULL, NULL);
}
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);
}
static void
presentation_destroy(struct wl_client *client, struct wl_resource *resource)
{
wl_resource_destroy(resource);
}
static void
presentation_feedback(struct wl_client *client,
struct wl_resource *presentation_resource,
struct wl_resource *surface_resource,
uint32_t callback)
{
struct weston_surface *surface;
struct weston_presentation_feedback *feedback;
surface = wl_resource_get_user_data(surface_resource);
feedback = zalloc(sizeof *feedback);
if (feedback == NULL)
goto err_calloc;
feedback->resource = wl_resource_create(client,
&wp_presentation_feedback_interface,
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);
}
static const struct wp_presentation_interface presentation_implementation = {
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;
resource = wl_resource_create(client, &wp_presentation_interface,
version, id);
if (resource == NULL) {
wl_client_post_no_memory(client);
return;
}
wl_resource_set_implementation(resource, &presentation_implementation,
compositor, NULL);
wp_presentation_send_clock_id(resource, compositor->presentation_clock);
}
static void
compositor_bind(struct wl_client *client,
void *data, uint32_t version, uint32_t id)
{
struct weston_compositor *compositor = data;
struct wl_resource *resource;
resource = wl_resource_create(client, &wl_compositor_interface,
version, id);
if (resource == NULL) {
wl_client_post_no_memory(client);
return;
}
wl_resource_set_implementation(resource, &compositor_interface,
compositor, NULL);
}
static const char *
output_repaint_status_text(struct weston_output *output)
{
switch (output->repaint_status) {
case REPAINT_NOT_SCHEDULED:
return "no repaint";
case REPAINT_BEGIN_FROM_IDLE:
return "start_repaint_loop scheduled";
case REPAINT_SCHEDULED:
return "repaint scheduled";
case REPAINT_AWAITING_COMPLETION:
return "awaiting completion";
}
assert(!"output_repaint_status_text missing enum");
return NULL;
}
static void
debug_scene_view_print_buffer(FILE *fp, struct weston_view *view)
{
struct weston_buffer *buffer = view->surface->buffer_ref.buffer;
char *modifier_name;
if (!buffer) {
fprintf(fp, "\t\t[buffer not available]\n");
return;
}
switch (buffer->type) {
case WESTON_BUFFER_SHM:
fprintf(fp, "\t\tSHM buffer\n");
break;
case WESTON_BUFFER_DMABUF:
fprintf(fp, "\t\tdmabuf buffer\n");
break;
case WESTON_BUFFER_SOLID:
fprintf(fp, "\t\tsolid-colour buffer\n");
fprintf(fp, "\t\t\t[R %f, G %f, B %f, A %f]\n",
buffer->solid.r, buffer->solid.g, buffer->solid.b,
buffer->solid.a);
break;
case WESTON_BUFFER_RENDERER_OPAQUE:
fprintf(fp, "\t\tEGL buffer:\n");
fprintf(fp, "\t\t\t[format may be inaccurate]\n");
break;
}
if (buffer->busy_count > 0) {
fprintf(fp, "\t\t\t[%d references may use buffer content]\n",
buffer->busy_count);
} else {
fprintf(fp, "\t\t\t[buffer has been released to client]\n");
}
if (buffer->pixel_format) {
fprintf(fp, "\t\t\tformat: 0x%lx %s\n",
(unsigned long) buffer->pixel_format->format,
buffer->pixel_format->drm_format_name);
} else {
fprintf(fp, "\t\t\t[unknown format]\n");
}
modifier_name = pixel_format_get_modifier(buffer->format_modifier);
fprintf(fp, "\t\t\tmodifier: %s\n",
modifier_name ?
modifier_name : "Failed to convert to a modifier name");
free(modifier_name);
fprintf(fp, "\t\t\twidth: %d, height: %d\n",
buffer->width, buffer->height);
if (buffer->buffer_origin == ORIGIN_BOTTOM_LEFT)
fprintf(fp, "\t\t\tbottom-left origin\n");
if (buffer->direct_display)
fprintf(fp, "\t\t\tdirect-display buffer (no renderer access)\n");
}
static void
debug_scene_view_print(FILE *fp, struct weston_view *view, int view_idx)
{
struct weston_compositor *ec = view->surface->compositor;
struct weston_output *output;
char desc[512];
pixman_box32_t *box;
uint32_t surface_id = 0;
pid_t pid = 0;
if (view->surface->resource) {
struct wl_resource *resource = view->surface->resource;
wl_client_get_credentials(wl_resource_get_client(resource),
&pid, NULL, NULL);
surface_id = wl_resource_get_id(view->surface->resource);
}
if (!view->surface->get_label ||
view->surface->get_label(view->surface, desc, sizeof(desc)) < 0) {
strcpy(desc, "[no description available]");
}
fprintf(fp, "\tView %d (role %s, PID %d, surface ID %u, %s, %p):\n",
view_idx, view->surface->role_name, pid, surface_id,
desc, view);
box = pixman_region32_extents(&view->transform.boundingbox);
fprintf(fp, "\t\tposition: (%d, %d) -> (%d, %d)\n",
box->x1, box->y1, box->x2, box->y2);
box = pixman_region32_extents(&view->transform.opaque);
if (weston_view_is_opaque(view, &view->transform.boundingbox)) {
fprintf(fp, "\t\t[fully opaque]\n");
} else if (!pixman_region32_not_empty(&view->transform.opaque)) {
fprintf(fp, "\t\t[not opaque]\n");
} else {
fprintf(fp, "\t\t[opaque: (%d, %d) -> (%d, %d)]\n",
box->x1, box->y1, box->x2, box->y2);
}
if (view->alpha < 1.0)
fprintf(fp, "\t\talpha: %f\n", view->alpha);
if (view->output_mask != 0) {
bool first_output = true;
fprintf(fp, "\t\toutputs: ");
wl_list_for_each(output, &ec->output_list, link) {
if (!(view->output_mask & (1 << output->id)))
continue;
fprintf(fp, "%s%d (%s)%s",
(first_output) ? "" : ", ",
output->id, output->name,
(view->output == output) ? " (primary)" : "");
first_output = false;
}
} else {
fprintf(fp, "\t\t[no outputs]");
}
fprintf(fp, "\n");
debug_scene_view_print_buffer(fp, view);
}
static void
debug_scene_view_print_tree(struct weston_view *view,
FILE *fp, int *view_idx)
{
struct weston_subsurface *sub;
struct weston_view *ev;
/*
* print the view first, then we recursively go on printing
* sub-surfaces. We bail out once no more sub-surfaces are available.
*/
debug_scene_view_print(fp, view, *view_idx);
/* no more sub-surfaces */
if (wl_list_empty(&view->surface->subsurface_list))
return;
wl_list_for_each(sub, &view->surface->subsurface_list, parent_link) {
wl_list_for_each(ev, &sub->surface->views, surface_link) {
/* only print the child views of the current view */
if (ev->parent_view != view)
continue;
(*view_idx)++;
debug_scene_view_print_tree(ev, fp, view_idx);
}
}
}
/**
* Output information on how libweston is currently composing the scene
* graph.
*
* \ingroup compositor
*/
WL_EXPORT char *
weston_compositor_print_scene_graph(struct weston_compositor *ec)
{
struct weston_output *output;
struct weston_layer *layer;
struct timespec now;
int layer_idx = 0;
FILE *fp;
char *ret;
size_t len;
int err;
fp = open_memstream(&ret, &len);
assert(fp);
weston_compositor_read_presentation_clock(ec, &now);
fprintf(fp, "Weston scene graph at %ld.%09ld:\n\n",
now.tv_sec, now.tv_nsec);
wl_list_for_each(output, &ec->output_list, link) {
struct weston_head *head;
int head_idx = 0;
fprintf(fp, "Output %d (%s):\n", output->id, output->name);
assert(output->enabled);
fprintf(fp, "\tposition: (%d, %d) -> (%d, %d)\n",
output->x, output->y,
output->x + output->width,
output->y + output->height);
fprintf(fp, "\tmode: %dx%d@%.3fHz\n",
output->current_mode->width,
output->current_mode->height,
output->current_mode->refresh / 1000.0);
fprintf(fp, "\tscale: %d\n", output->scale);
fprintf(fp, "\trepaint status: %s\n",
output_repaint_status_text(output));
if (output->repaint_status == REPAINT_SCHEDULED)
fprintf(fp, "\tnext repaint: %ld.%09ld\n",
output->next_repaint.tv_sec,
output->next_repaint.tv_nsec);
wl_list_for_each(head, &output->head_list, output_link) {
fprintf(fp, "\tHead %d (%s): %sconnected\n",
head_idx++, head->name,
(head->connected) ? "" : "not ");
}
}
fprintf(fp, "\n");
wl_list_for_each(layer, &ec->layer_list, link) {
struct weston_view *view;
int view_idx = 0;
fprintf(fp, "Layer %d (pos 0x%lx):\n", layer_idx++,
(unsigned long) layer->position);
if (!weston_layer_mask_is_infinite(layer)) {
fprintf(fp, "\t[mask: (%d, %d) -> (%d,%d)]\n\n",
layer->mask.x1, layer->mask.y1,
layer->mask.x2, layer->mask.y2);
}
wl_list_for_each(view, &layer->view_list.link, layer_link.link) {
debug_scene_view_print_tree(view, fp, &view_idx);
view_idx++;
}
if (wl_list_empty(&layer->view_list.link))
fprintf(fp, "\t[no views]\n");
fprintf(fp, "\n");
}
err = fclose(fp);
assert(err == 0);
return ret;
}
/**
* Called when the 'scene-graph' debug scope is bound by a client. This
* one-shot weston-debug scope prints the current scene graph when bound,
* and then terminates the stream.
*/
static void
debug_scene_graph_cb(struct weston_log_subscription *sub, void *data)
{
struct weston_compositor *ec = data;
char *str = weston_compositor_print_scene_graph(ec);
weston_log_subscription_printf(sub, "%s", str);
free(str);
weston_log_subscription_complete(sub);
}
/** Retrieve testsuite data from compositor
*
* The testsuite data can be defined by the test suite of projects that uses
* libweston and given to the compositor at the moment of its creation. This
* function should be used when we need to retrieve the testsuite private data
* from the compositor.
*
* \param ec The weston compositor.
* \return The testsuite data.
*
* \ingroup compositor
* \sa weston_compositor_test_data_init
*/
WL_EXPORT void *
weston_compositor_get_test_data(struct weston_compositor *ec)
{
return ec->test_data.test_private_data;
}
/** 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
* \param log_ctx A pointer to weston_debug_compositor
* \param test_data Optional testsuite data, or NULL.
* using the \ref weston_compositor_get_user_data function.
* \return The compositor instance on success or NULL on failure.
*
* \ingroup compositor
*/
WL_EXPORT struct weston_compositor *
weston_compositor_create(struct wl_display *display,
struct weston_log_context *log_ctx, void *user_data,
const struct weston_testsuite_data *test_data)
{
struct weston_compositor *ec;
struct wl_event_loop *loop;
if (!log_ctx)
return NULL;
ec = zalloc(sizeof *ec);
if (!ec)
return NULL;
if (test_data)
ec->test_data = *test_data;
ec->weston_log_ctx = log_ctx;
ec->wl_display = display;
ec->user_data = user_data;
wl_signal_init(&ec->destroy_signal);
wl_signal_init(&ec->create_surface_signal);
wl_signal_init(&ec->activate_signal);
wl_signal_init(&ec->transform_signal);
wl_signal_init(&ec->kill_signal);
wl_signal_init(&ec->idle_signal);
wl_signal_init(&ec->wake_signal);
wl_signal_init(&ec->show_input_panel_signal);
wl_signal_init(&ec->hide_input_panel_signal);
wl_signal_init(&ec->update_input_panel_signal);
wl_signal_init(&ec->seat_created_signal);
wl_signal_init(&ec->output_created_signal);
wl_signal_init(&ec->output_destroyed_signal);
wl_signal_init(&ec->output_moved_signal);
wl_signal_init(&ec->output_resized_signal);
wl_signal_init(&ec->heads_changed_signal);
wl_signal_init(&ec->output_heads_changed_signal);
wl_signal_init(&ec->session_signal);
ec->session_active = true;
ec->output_id_pool = 0;
ec->repaint_msec = DEFAULT_REPAINT_WINDOW;
ec->activate_serial = 1;
input: introduce touch event mode for calibrator In addition to the normal touch event processing mode, introduce a new mode for calibrating a touchscreen input device. In the calibration mode, normal touch event processing is skipped, and the raw events are forwarded to the calibrator instead. The calibrator is not yet implemented, so the calls will be added in a following patch. To switch between modes, two functions are added, one for entering each mode. The mode switch happens only when no touches are down on any touch device, to avoid confusing touch grabs and clients. To realise this, the state machine has four states: prepare and actual state for both normal and calibrator modes. At this point nothing will attempt to change the touch event mode. The new calibrator mode is necessary, because when calibrating a touchscreen, the touch events must be routed to the calibration client directly. The touch coordinates are expected to be wrong, so they cannot go through the normal focus surface picking. The calibrator code also cannot use the normal touch grab interface, because it needs to be able to distinguish between different physical touch input devices, even if they are part of the same weston_seat. This requirement makes calibration special enough to warrant the new mode, a sort of "super grab". Co-developed by Louis-Francis and Pekka. Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb@collabora.com> Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v1 Tested-by: Matt Hoosier <matt.hoosier@gmail.com> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
7 years ago
ec->touch_mode = WESTON_TOUCH_MODE_NORMAL;
ec->content_protection = NULL;
if (!wl_global_create(ec->wl_display, &wl_compositor_interface, 4,
ec, compositor_bind))
goto fail;
if (!wl_global_create(ec->wl_display, &wl_subcompositor_interface, 1,
ec, bind_subcompositor))
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>
12 years ago
if (!wl_global_create(ec->wl_display, &wp_viewporter_interface, 1,
ec, bind_viewporter))
goto fail;
if (!wl_global_create(ec->wl_display, &zxdg_output_manager_v1_interface, 2,
ec, bind_xdg_output_manager))
goto fail;
if (!wl_global_create(ec->wl_display, &wp_presentation_interface, 1,
ec, bind_presentation))
goto fail;
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>
11 years ago
wl_list_init(&ec->view_list);
wl_list_init(&ec->plane_list);
wl_list_init(&ec->layer_list);
wl_list_init(&ec->seat_list);
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
wl_list_init(&ec->pending_output_list);
wl_list_init(&ec->output_list);
wl_list_init(&ec->head_list);
wl_list_init(&ec->key_binding_list);
wl_list_init(&ec->modifier_binding_list);
wl_list_init(&ec->button_binding_list);
wl_list_init(&ec->touch_binding_list);
wl_list_init(&ec->axis_binding_list);
wl_list_init(&ec->debug_binding_list);
wl_list_init(&ec->plugin_api_list);
weston_plane_init(&ec->primary_plane, ec, 0, 0);
weston_compositor_stack_plane(ec, &ec->primary_plane, NULL);
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);
ec->repaint_timer =
wl_event_loop_add_timer(loop, output_repaint_timer_handler,
ec);
weston_layer_init(&ec->fade_layer, ec);
weston_layer_init(&ec->cursor_layer, ec);
weston_layer_set_position(&ec->fade_layer, WESTON_LAYER_POSITION_FADE);
weston_layer_set_position(&ec->cursor_layer,
WESTON_LAYER_POSITION_CURSOR);
ec->debug_scene =
weston_compositor_add_log_scope(ec, "scene-graph",
"Scene graph details\n",
debug_scene_graph_cb, NULL,
ec);
ec->timeline =
weston_compositor_add_log_scope(ec, "timeline",
"Timeline event points\n",
weston_timeline_create_subscription,
weston_timeline_destroy_subscription,
ec);
ec->libseat_debug =
weston_compositor_add_log_scope(ec, "libseat-debug",
"libseat debug messages\n",
NULL, NULL, NULL);
return ec;
fail:
free(ec);
return NULL;
}
/** weston_compositor_shutdown
* \ingroup compositor
*/
WL_EXPORT void
weston_compositor_shutdown(struct weston_compositor *ec)
{
struct weston_output *output, *next;
wl_event_source_remove(ec->idle_source);
wl_event_source_remove(ec->repaint_timer);
if (ec->touch_calibration)
weston_compositor_destroy_touch_calibrator(ec);
/* Destroy all outputs associated with this compositor */
wl_list_for_each_safe(output, next, &ec->output_list, link)
output->destroy(output);
libweston: Add more functionality for handling weston_output objects This patch implements additional functionality that will be used for configuring, enabling and disabling weston's outputs. Its indended use is by the compositors or user programs that want to be able to configure, enable or disable an output at any time. An output can only be configured while it's disabled. The compositor and backend specific functionality is required for these functions to be useful, and those will come later in this series. All the new functions have been documented, so I'll avoid describing them here. v2: - Minor documentation improvements. - Rename output-initialized to output->enabled. - Split weston_output_disable() further into weston_compositor_remove_output(). - Rename weston_output_deinit() to weston_output_enable_undo(). - Make weston_output_disable() call two functions mentioned above instead of calling weston_output_disable() directly. This means that backend needs to take care of doing backend specific disable in backend specific destroy function. v3: - Require output->name to be set before calling weston_output_init_pending(). - Require output->destroying to be set before calling weston_compositor_remove_output(). - Split weston_output_init_pending() into weston_compositor_add_pending_output() so pending outputs can be announced separately. - Require output->disable() to be set in order for weston_output_disable() to be usable. - Fix output removing regression that happened when weston_output_disable() was split. - Minor documentation fix. v4: - Bump libweston version to 2 as this patch breaks the ABI. Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Armin Krezović <krezovic.armin@gmail.com>
8 years ago
/* Destroy all pending outputs associated with this compositor */
wl_list_for_each_safe(output, next, &ec->pending_output_list, link)
output->destroy(output);
libweston: introduce CMS component architecture See: https://gitlab.freedesktop.org/wayland/weston/-/issues/467#note_814985 This starts building the framework required for implementing color management. The main new interface is struct weston_color_manager. This commit also adds a no-op color manager implementation, which is used if no other color manager is loaded. This no-op color manager simply provides identity color transforms for everything, so that Weston keeps running exactly like before. weston_color_manager interface is incomplete and will be extended later. Colorspace objects are not introduced in this commit. However, when client content colorspace and output colorspace definitions are combined, they will produce color transformations from client content to output blending space and from output blending space to output space. This commit introduces a placeholder struct for color transforms, weston_color_transform. Objects of this type are expected to be heavy to create and store, which is why they are designed to be shared as much as possible, ideally making their instances unique. As color transform description is intended to be generic in libweston core, renderers and backends are expected to derive their own state for each transform object as necessary. Creating and storing the derived state maybe be expensive as well, more the reason to re-use these objects as much as possible. E.g. GL-renderer might upload a 3D LUT into a texture and keep the texture around. DRM-backend might create a KMS blob for a LUT and keep that around. As a color transform depends on both the surface and the output, a transform object may need to be created for each unique pair of them. Therefore color transforms are referenced from weston_paint_node. As paint nodes exist for not just surface+output but surface+view+output triplets, the code ensures that all paint nodes (having different view) for the same surface+output have the same color transform state. As a special case, if weston_color_transform is NULL, it means identity transform. This short-circuits some checks and memory allocations, but it does mean we use a separate member on weston_paint_node to know if the color transform has been initialized or not. Color transformations are pre-created at the weston_output paint_node_z_order_list creation step. Currently the z order lists contain all views globally, which means we populate color transforms we may never need, e.g. a view is never shown on a particular output. This problem should get fixed naturally when z order lists are constructed "pruned" in the future: to contain only those paint nodes that actually contribute to the output's image. As nothing actually supports color transforms yet, both renderers and the DRM-backend assert that they only get identity transforms. This check has the side-effect that all surface-output pairs actually get a weston_surface_color_transform_ref even though it points to NULL weston_color_transform. This design is inspired by Sebastian Wick's Weston color management work. Co-authored-by: Sebastian Wick <sebastian@sebastianwick.net> Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
4 years ago
/* Color manager objects may have renderer hooks */
if (ec->color_manager) {
ec->color_manager->destroy(ec->color_manager);
ec->color_manager = NULL;
}
if (ec->renderer)
ec->renderer->destroy(ec);
weston_binding_list_destroy_all(&ec->key_binding_list);
weston_binding_list_destroy_all(&ec->modifier_binding_list);
weston_binding_list_destroy_all(&ec->button_binding_list);
weston_binding_list_destroy_all(&ec->touch_binding_list);
weston_binding_list_destroy_all(&ec->axis_binding_list);
weston_binding_list_destroy_all(&ec->debug_binding_list);
weston_plane_release(&ec->primary_plane);
weston_layer_fini(&ec->fade_layer);
weston_layer_fini(&ec->cursor_layer);
if (!wl_list_empty(&ec->layer_list))
weston_log("BUG: layer_list is not empty after shutdown. Calls to weston_layer_fini() are missing somwhere.\n");
}
/** weston_compositor_exit_with_code
* \ingroup compositor
*/
WL_EXPORT void
weston_compositor_exit_with_code(struct weston_compositor *compositor,
int exit_code)
{
if (compositor->exit_code == EXIT_SUCCESS)
compositor->exit_code = exit_code;
weston_compositor_exit(compositor);
}
/** weston_compositor_set_default_pointer_grab
* \ingroup compositor
*/
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) {
struct weston_pointer *pointer = weston_seat_get_pointer(seat);
if (pointer)
weston_pointer_set_default_grab(pointer, interface);
}
}
/** weston_compositor_set_presentation_clock
* \ingroup compositor
*/
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.
*
* \ingroup compositor
*/
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 */
};
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;
}
/** Read the current time from the Presentation clock
*
* \param compositor
* \param[out] ts 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.
*
* \ingroup compositor
*/
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: '%s' (%d)\n",
compositor->presentation_clock,
strerror(errno), errno);
warned = true;
}
}
/** 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.
*
* \ingroup compositor
*/
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);
}
WL_EXPORT bool
weston_compositor_dmabuf_can_scanout(struct weston_compositor *compositor,
struct linux_dmabuf_buffer *buffer)
{
struct weston_backend *backend = compositor->backend;
if (backend->can_scanout_dmabuf == NULL)
return false;
return backend->can_scanout_dmabuf(compositor, buffer);
}
WL_EXPORT void
weston_version(int *major, int *minor, int *micro)
{
*major = WESTON_VERSION_MAJOR;
*minor = WESTON_VERSION_MINOR;
*micro = WESTON_VERSION_MICRO;
}
/**
* Attempts to find a module path from the module map specified in the
* environment. If found, writes the full path into the path variable.
*
* The module map is a string in environment variable WESTON_MODULE_MAP, where
* each entry is of the form "name=path" and entries are separated by
* semicolons. Whitespace is significant.
*
* \param name The name to search for.
* \param path Where the path is written to if found.
* \param path_len Allocated bytes at \c path .
* \returns The length of the string written to path on success, or 0 if the
* module was not specified in the environment map or path_len was too small.
*/
WL_EXPORT size_t
weston_module_path_from_env(const char *name, char *path, size_t path_len)
{
const char *mapping = getenv("WESTON_MODULE_MAP");
const char *end;
const int name_len = strlen(name);
if (!mapping)
return 0;
end = mapping + strlen(mapping);
while (mapping < end && *mapping) {
const char *filename, *next;
/* early out: impossibly short string */
if (end - mapping < name_len + 1)
return 0;
filename = &mapping[name_len + 1];
next = strchrnul(mapping, ';');
if (strncmp(mapping, name, name_len) == 0 &&
mapping[name_len] == '=') {
size_t file_len = next - filename; /* no trailing NUL */
if (file_len >= path_len)
return 0;
strncpy(path, filename, file_len);
path[file_len] = '\0';
return file_len;
}
mapping = next + 1;
}
return 0;
}
WL_EXPORT void *
weston_load_module(const char *name, const char *entrypoint)
{
char path[PATH_MAX];
void *module, *init;
size_t len;
if (name == NULL)
return NULL;
if (name[0] != '/') {
len = weston_module_path_from_env(name, path, sizeof path);
if (len == 0)
len = snprintf(path, sizeof path, "%s/%s",
LIBWESTON_MODULEDIR, name);
} else {
len = snprintf(path, sizeof path, "%s", name);
}
/* 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;
module = dlopen(path, RTLD_NOW | RTLD_NOLOAD);
if (module) {
weston_log("Module '%s' already loaded\n", path);
} else {
weston_log("Loading module '%s'\n", path);
module = dlopen(path, RTLD_NOW);
if (!module) {
weston_log("Failed to load module: %s\n", dlerror());
return NULL;
}
}
init = dlsym(module, entrypoint);
if (!init) {
weston_log("Failed to lookup init function: %s\n", dlerror());
dlclose(module);
return NULL;
}
return init;
}
/** Add a compositor destroy listener only once
*
* \param compositor The compositor whose destroy to watch for.
* \param listener The listener struct to initialize.
* \param destroy_handler The callback when compositor is destroyed.
* \return True if listener is added, or false if there already is a listener
* with the given \c destroy_handler.
*
* This function does nothing and returns false if the given callback function
* is already present in the weston_compositor destroy callbacks list.
* Otherwise, this function initializes the given listener with the given
* callback pointer and adds it to the compositor's destroy callbacks list.
*
* This can be used to ensure that plugin initialization is done only once
* in case the same plugin is loaded multiple times. If this function returns
* false, the plugin should be already initialized successfully.
*
* All plugins should register a destroy listener for cleaning up. Note, that
* the plugin destruction order is not guaranteed: plugins that depend on other
* plugins must be able to be torn down in arbitrary order.
*
* \sa weston_compositor_destroy
*/
WL_EXPORT bool
weston_compositor_add_destroy_listener_once(struct weston_compositor *compositor,
struct wl_listener *listener,
wl_notify_func_t destroy_handler)
{
if (wl_signal_get(&compositor->destroy_signal, destroy_handler))
return false;
listener->notify = destroy_handler;
wl_signal_add(&compositor->destroy_signal, listener);
return true;
}
/** Destroys the compositor.
*
* This function cleans up the compositor state and then destroys it.
*
* @param compositor The compositor to be destroyed.
*
* @ingroup compositor
*/
WL_EXPORT void
weston_compositor_destroy(struct weston_compositor *compositor)
{
/* prevent further rendering while shutting down */
compositor->state = WESTON_COMPOSITOR_OFFSCREEN;
weston_signal_emit_mutable(&compositor->destroy_signal, compositor);
weston_compositor_xkb_destroy(compositor);
if (compositor->backend)
compositor->backend->destroy(compositor);
/* The backend is responsible for destroying the heads. */
assert(wl_list_empty(&compositor->head_list));
weston_plugin_api_destroy_list(compositor);
if (compositor->heads_changed_source)
wl_event_source_remove(compositor->heads_changed_source);
weston_log_scope_destroy(compositor->debug_scene);
compositor->debug_scene = NULL;
weston_log_scope_destroy(compositor->timeline);
compositor->timeline = NULL;
weston_log_scope_destroy(compositor->libseat_debug);
compositor->libseat_debug = NULL;
if (compositor->default_dmabuf_feedback) {
weston_dmabuf_feedback_destroy(compositor->default_dmabuf_feedback);
weston_dmabuf_feedback_format_table_destroy(compositor->dmabuf_feedback_format_table);
}
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.
*
* \ingroup compositor
*/
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.
*
* \ingroup compositor
*/
WL_EXPORT void *
weston_compositor_get_user_data(struct weston_compositor *compositor)
{
return compositor->user_data;
}
static const char * const backend_map[] = {
[WESTON_BACKEND_DRM] = "drm-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",
};
/** 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.
*
* \ingroup compositor
*/
WL_EXPORT int
weston_compositor_load_backend(struct weston_compositor *compositor,
enum weston_compositor_backend backend,
struct weston_backend_config *config_base)
{
int (*backend_init)(struct weston_compositor *c,
struct weston_backend_config *config_base);
if (compositor->backend) {
weston_log("Error: attempt to load a backend when one is already loaded\n");
return -1;
}
if (backend >= ARRAY_LENGTH(backend_map))
return -1;
backend_init = weston_load_module(backend_map[backend], "weston_backend_init");
if (!backend_init)
return -1;
if (backend_init(compositor, config_base) < 0) {
compositor->backend = NULL;
return -1;
}
libweston: introduce CMS component architecture See: https://gitlab.freedesktop.org/wayland/weston/-/issues/467#note_814985 This starts building the framework required for implementing color management. The main new interface is struct weston_color_manager. This commit also adds a no-op color manager implementation, which is used if no other color manager is loaded. This no-op color manager simply provides identity color transforms for everything, so that Weston keeps running exactly like before. weston_color_manager interface is incomplete and will be extended later. Colorspace objects are not introduced in this commit. However, when client content colorspace and output colorspace definitions are combined, they will produce color transformations from client content to output blending space and from output blending space to output space. This commit introduces a placeholder struct for color transforms, weston_color_transform. Objects of this type are expected to be heavy to create and store, which is why they are designed to be shared as much as possible, ideally making their instances unique. As color transform description is intended to be generic in libweston core, renderers and backends are expected to derive their own state for each transform object as necessary. Creating and storing the derived state maybe be expensive as well, more the reason to re-use these objects as much as possible. E.g. GL-renderer might upload a 3D LUT into a texture and keep the texture around. DRM-backend might create a KMS blob for a LUT and keep that around. As a color transform depends on both the surface and the output, a transform object may need to be created for each unique pair of them. Therefore color transforms are referenced from weston_paint_node. As paint nodes exist for not just surface+output but surface+view+output triplets, the code ensures that all paint nodes (having different view) for the same surface+output have the same color transform state. As a special case, if weston_color_transform is NULL, it means identity transform. This short-circuits some checks and memory allocations, but it does mean we use a separate member on weston_paint_node to know if the color transform has been initialized or not. Color transformations are pre-created at the weston_output paint_node_z_order_list creation step. Currently the z order lists contain all views globally, which means we populate color transforms we may never need, e.g. a view is never shown on a particular output. This problem should get fixed naturally when z order lists are constructed "pruned" in the future: to contain only those paint nodes that actually contribute to the output's image. As nothing actually supports color transforms yet, both renderers and the DRM-backend assert that they only get identity transforms. This check has the side-effect that all surface-output pairs actually get a weston_surface_color_transform_ref even though it points to NULL weston_color_transform. This design is inspired by Sebastian Wick's Weston color management work. Co-authored-by: Sebastian Wick <sebastian@sebastianwick.net> Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
4 years ago
if (!compositor->color_manager) {
compositor->color_manager =
weston_color_manager_noop_create(compositor);
}
if (!compositor->color_manager)
return -1;
if (!compositor->color_manager->init(compositor->color_manager))
return -1;
weston_log("Color manager: %s\n", compositor->color_manager->name);
return 0;
}
/** weston_compositor_load_xwayland
* \ingroup compositor
*/
WL_EXPORT int
weston_compositor_load_xwayland(struct weston_compositor *compositor)
{
int (*module_init)(struct weston_compositor *ec);
module_init = weston_load_module("xwayland.so", "weston_module_init");
if (!module_init)
return -1;
if (module_init(compositor) < 0)
return -1;
return 0;
}
/** Load Little CMS color manager plugin
*
* Calling this function before loading any backend sets Little CMS
* as the active color matching module (CMM) instead of the default no-op
* color manager.
*
* \ingroup compositor
*/
WL_EXPORT int
weston_compositor_load_color_manager(struct weston_compositor *compositor)
{
struct weston_color_manager *
(*cm_create)(struct weston_compositor *compositor);
if (compositor->color_manager) {
weston_log("Error: Color manager '%s' is loaded, cannot load another.\n",
compositor->color_manager->name);
return -1;
}
cm_create = weston_load_module("color-lcms.so", "weston_color_manager_create");
if (!cm_create) {
weston_log("Error: Could not load color-lcms.so.\n");
return -1;
}
compositor->color_manager = cm_create(compositor);
if (!compositor->color_manager) {
weston_log("Error: loading color-lcms.so failed.\n");
return -1;
}
return 0;
}
/** Resolve an internal compositor error by disconnecting the client.
*
* This function is used in cases when the wl_buffer turns out
* unusable and there is no fallback path.
*
* It is possible the fault is caused by a compositor bug, the underlying
* graphics stack bug or normal behaviour, or perhaps a client mistake.
* In any case, the options are to either composite garbage or nothing,
* or disconnect the client. This is a helper function for the latter.
*
* The error is sent as an INVALID_OBJECT error on the client's wl_display.
*
* \param buffer The weston buffer that is unusable.
* \param msg A custom error message attached to the protocol error.
*/
WL_EXPORT void
weston_buffer_send_server_error(struct weston_buffer *buffer,
const char *msg)
{
struct wl_client *client;
struct wl_resource *display_resource;
uint32_t id;
assert(buffer->resource);
id = wl_resource_get_id(buffer->resource);
client = wl_resource_get_client(buffer->resource);
display_resource = wl_client_get_object(client, 1);
assert(display_resource);
wl_resource_post_error(display_resource,
WL_DISPLAY_ERROR_INVALID_OBJECT,
"server error with "
"wl_buffer@%u: %s", id, msg);
}
WL_EXPORT void
weston_output_disable_planes_incr(struct weston_output *output)
{
output->disable_planes++;
/*
* If disable_planes changes from 0 to non-zero, it means some type of
* recording of content has started, and therefore protection level of
* the protected surfaces must be updated to avoid the recording of
* the protected content.
*/
if (output->disable_planes == 1)
weston_schedule_surface_protection_update(output->compositor);
}
WL_EXPORT void
weston_output_disable_planes_decr(struct weston_output *output)
{
output->disable_planes--;
/*
* If disable_planes changes from non-zero to 0, it means no content
* recording is going on any more, and the protected and surfaces can be
* shown without any apprehensions about content being recorded.
*/
if (output->disable_planes == 0)
weston_schedule_surface_protection_update(output->compositor);
}