Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package weston for openSUSE:Factory checked 
in at 2022-08-10 17:14:32
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/weston (Old)
 and      /work/SRC/openSUSE:Factory/.weston.new.1521 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "weston"

Wed Aug 10 17:14:32 2022 rev:27 rq:994204 version:10.0.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/weston/weston.changes    2022-02-02 
22:45:01.942060204 +0100
+++ /work/SRC/openSUSE:Factory/.weston.new.1521/weston.changes  2022-08-10 
17:15:41.898083585 +0200
@@ -1,0 +2,34 @@
+Tue Aug  9 20:21:35 UTC 2022 - Dirk M??ller <[email protected]>
+
+- update to 10.0.2:
+  This is a bugfix release for 10.0.0.
+  * clients/simple-dmabuf-feedback: do not use buffer before compositor's 
response
+  * kiosk-shell: Check if app_ids have been set after initial commit
+  * kiosk-shell: Don't occlude shsurf on other outputs
+  * kiosk-shell: Favor out views on same output
+  * libweston: Assert if ref-count balance is wrong
+  * libweston, desktop-shell: Add a wrapper for weston_surface reference
+  * desktop-shell: Create a distinct view for the fade-out close anim
+  * desktop-shell: Rename destroy_layer functions
+  * desktop-shell: Migrate surface_unlink_view
+  * desktop-shell: Check for a valid desktop_surface
+  * desktop-shell: Clarify weston_view destruction at tear down
+  * desktop-shell: Add missing weston_view_destroy()
+  * simple-egl: Add start as maximized
+  * libweston-desktop: Replace buffer with geometry
+  * simple-egl: Remove uneeded check
+  * simple-egl: Defer EGL surface/window creation
+  * simple-egl: Move set_fullscreen/set_maximized before initial commit
+  * gl-renderer: fix performance regression in frag
+  * libweston/compositor: Cache buffer damage for synced subsurfaces
+  * tests: Add test for synced subsurfaces and buffer damage
+  * libweston/compositor: Do not map subsurfaces without buffer
+  * tests: Add test for subsurfaces mapping hierachies
+  * clients/simple-dmabuf-feedback: Support multi-tranche feedbacks
+  * clients/simple-dmabuf-*: Increase buffer limit to four
+  * clients/simple-dmabuf-feedback: Add fallback print method for unknown 
formats
+  * backend-drm: Add failure reasons for failing gbm_bo_import
+  * clients/simple-dmabuf-feedback: use time instead of redraws
+  * libweston/linux-dmabuf: create surface feedback on demand 
+
+-------------------------------------------------------------------

Old:
----
  weston-10.0.0.tar.xz
  weston-10.0.0.tar.xz.sig

New:
----
  weston-10.0.2.tar.xz
  weston-10.0.2.tar.xz.sig

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ weston.spec ++++++
--- /var/tmp/diff_new_pack.5xoVj8/_old  2022-08-10 17:15:42.614085454 +0200
+++ /var/tmp/diff_new_pack.5xoVj8/_new  2022-08-10 17:15:42.622085475 +0200
@@ -19,18 +19,17 @@
 Name:           weston
 %define lname  libweston0
 %define major   10
-%define realver        10.0.0
-Version:        10
+%define realver        10.0.2
+Version:        10.0.2
 Release:        0
 Summary:        Wayland Reference Compositor
 License:        CC-BY-SA-3.0 AND MIT
 Group:          System/X11/Servers
 URL:            https://wayland.freedesktop.org/
-
 #Git-Clone:    git://anongit.freedesktop.org/wayland/weston
 #Git-Web:      https://cgit.freedesktop.org/wayland/weston/
-Source:         https://wayland.freedesktop.org/releases/weston-%realver.tar.xz
-Source2:        
https://wayland.freedesktop.org/releases/weston-%realver.tar.xz.sig
+Source:         
https://gitlab.freedesktop.org/wayland/weston/-/releases/%realver/downloads/weston-%realver.tar.xz
+Source2:        
https://gitlab.freedesktop.org/wayland/weston/-/releases/%realver/downloads/weston-%realver.tar.xz.sig
 Source3:        %name.keyring
 BuildRequires:  Mesa-libGLESv3-devel
 BuildRequires:  autoconf >= 2.64

++++++ weston-10.0.0.tar.xz -> weston-10.0.2.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weston-10.0.0/.gitlab-ci.yml 
new/weston-10.0.2/.gitlab-ci.yml
--- old/weston-10.0.0/.gitlab-ci.yml    2022-02-01 22:59:57.000000000 +0100
+++ new/weston-10.0.2/.gitlab-ci.yml    2022-07-26 12:22:25.000000000 +0200
@@ -296,7 +296,9 @@
     - .build-options-full
   artifacts:
     reports:
-      cobertura: $BUILDDIR/meson-logs/coverage.xml
+      coverage_report:
+        coverage_format: cobertura
+        path: $BUILDDIR/meson-logs/coverage.xml
 
 aarch64-debian-full-build:
   extends:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weston-10.0.0/clients/simple-dmabuf-egl.c 
new/weston-10.0.2/clients/simple-dmabuf-egl.c
--- old/weston-10.0.0/clients/simple-dmabuf-egl.c       2022-02-01 
22:59:57.000000000 +0100
+++ new/weston-10.0.2/clients/simple-dmabuf-egl.c       2022-07-26 
12:22:25.000000000 +0200
@@ -131,7 +131,7 @@
        int release_fence_fd;
 };
 
-#define NUM_BUFFERS 3
+#define NUM_BUFFERS 4
 
 struct window {
        struct display *display;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weston-10.0.0/clients/simple-dmabuf-feedback.c 
new/weston-10.0.2/clients/simple-dmabuf-feedback.c
--- old/weston-10.0.0/clients/simple-dmabuf-feedback.c  2022-02-01 
22:59:57.000000000 +0100
+++ new/weston-10.0.2/clients/simple-dmabuf-feedback.c  2022-07-26 
12:22:25.000000000 +0200
@@ -26,11 +26,13 @@
 #include "config.h"
 
 #include <assert.h>
+#include <ctype.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <stdio.h>
 #include <libudev.h>
 #include <sys/mman.h>
+#include <time.h>
 
 #include "shared/helpers.h"
 #include "shared/platform.h"
@@ -47,7 +49,7 @@
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 
-#define NUM_BUFFERS 3
+#define NUM_BUFFERS 4
 
 /* We have to hack the DRM-backend to pretend that planes of the underlying
  * hardware don't support this format. If you change the value of this 
constant,
@@ -140,7 +142,11 @@
 struct buffer {
        struct window *window;
        struct wl_buffer *buffer;
-       bool busy;
+       enum {
+               NOT_CREATED,
+               IN_USE,
+               AVAILABLE
+       } status;
        bool recreate;
        int dmabuf_fds[4];
        struct gbm_bo *bo;
@@ -469,7 +475,7 @@
 {
        struct buffer *buf = data;
 
-       buf->busy = false;
+       buf->status = AVAILABLE;
 
        if (buf->recreate)
                buffer_recreate(buf);
@@ -485,6 +491,7 @@
 {
        struct buffer *buf = data;
 
+       buf->status = AVAILABLE;
        buf->buffer = new_buffer;
        wl_buffer_add_listener(buf->buffer, &buffer_listener, buf);
        zwp_linux_buffer_params_v1_destroy(params);
@@ -516,6 +523,7 @@
        struct zwp_linux_buffer_params_v1 *params;
        int i;
 
+       buf->status = NOT_CREATED;
        buf->window = window;
        buf->width = width;
        buf->height = height;
@@ -573,8 +581,22 @@
        unsigned int i;
 
        for (i = 0; i < NUM_BUFFERS; i++)
-               if (!window->buffers[i].busy)
+               if (window->buffers[i].status == AVAILABLE)
                        return &window->buffers[i];
+
+       /* In this client, we sometimes have to recreate the buffers. As we are
+       * not using the create_immed request from zwp_linux_dmabuf_v1, we need
+       * to wait an event from the server (what leads to create_succeeded()
+       * being called in this client). So if all buffers are busy, it may be
+       * the case in which all the buffers were recreated but the server still
+       * didn't send the events. This is very unlikely to happen, but a
+       * roundtrip() guarantees that we receive and process the events. */
+       wl_display_roundtrip(window->display->display);
+
+       for (i = 0; i < NUM_BUFFERS; i++)
+               if (window->buffers[i].status == AVAILABLE)
+                       return &window->buffers[i];
+
        return NULL;
 }
 
@@ -639,15 +661,13 @@
        window->callback = wl_surface_frame(window->surface);
        wl_callback_add_listener(window->callback, &frame_listener, window);
        wl_surface_commit(window->surface);
-       buf->busy = true;
+       buf->status = IN_USE;
 
        region = wl_compositor_create_region(window->display->compositor);
        wl_region_add(region, 0, 0, window->display->output.width,
                      window->display->output.height);
        wl_surface_set_opaque_region(window->surface, region);
        wl_region_destroy(region);
-
-       window->n_redraws++;
 }
 
 static const struct wl_callback_listener frame_listener = {
@@ -1050,18 +1070,54 @@
        }
 }
 
+static char
+bits2graph(uint32_t value, unsigned bitoffset)
+{
+       int c = (value >> bitoffset) & 0xff;
+
+       if (isgraph(c) || isspace(c))
+               return c;
+
+       return '?';
+}
+
+static void
+fourcc2str(uint32_t format, char *str, int len)
+{
+       int i;
+
+       assert(len >= 5);
+
+       for (i = 0; i < 4; i++)
+               str[i] = bits2graph(format, i * 8);
+       str[i] = '\0';
+}
+
 static void
 print_tranche_format_modifier(uint32_t format, uint64_t modifier)
 {
        const struct pixel_format_info *fmt_info;
+       char *format_str;
        char *mod_name;
+       int len;
 
-       fmt_info = pixel_format_get_info(format);
        mod_name = pixel_format_get_modifier(modifier);
+       fmt_info = pixel_format_get_info(format);
+
+       if (fmt_info) {
+               len = asprintf(&format_str, "%s", fmt_info->drm_format_name);
+       } else {
+               char fourcc_str[5];
+
+               fourcc2str(format, fourcc_str, sizeof(fourcc_str));
+               len = asprintf(&format_str, "0x%08x (%s)", format, fourcc_str);
+       }
+       assert(len > 0);
 
        fprintf(stderr, "???    ???????????????????????????tranche 
format/modifier pair - format %s, modifier %s\n",
-                       fmt_info ? fmt_info->drm_format_name : "UNKNOWN", 
mod_name);
+                       format_str, mod_name);
 
+       free(format_str);
        free(mod_name);
 }
 
@@ -1103,7 +1159,7 @@
        dmabuf_feedback_tranche_init(&feedback->pending_tranche);
 }
 
-static void
+static bool
 pick_initial_format_from_renderer_tranche(struct window *window,
                                          struct dmabuf_feedback_tranche 
*tranche)
 {
@@ -1117,13 +1173,12 @@
                window->format.format = fmt->format;
                wl_array_copy(&window->format.modifiers, &fmt->modifiers);
 
-               return;
+               return true;
        }
-
-       assert(0 && "error: INITIAL_BUFFER_FORMAT not supported by the 
hardware");
+       return false;
 }
 
-static void
+static bool
 pick_format_from_scanout_tranche(struct window *window,
                                 struct dmabuf_feedback_tranche *tranche)
 {
@@ -1132,8 +1187,9 @@
 
        wl_array_for_each(fmt, &tranche->formats.arr) {
 
-               /* Ignore format that we're already using. */
-               if (fmt->format == window->format.format)
+               /* Ignore the format that we want to pick from the render
+                * tranche. */
+               if (fmt->format == INITIAL_BUFFER_FORMAT)
                        continue;
 
                /* Format should be supported by the compositor. */
@@ -1147,10 +1203,9 @@
                window->format.format = fmt->format;
                wl_array_copy(&window->format.modifiers, &fmt->modifiers);
 
-               return;
+               return true;
        }
-
-       assert(0 && "error: no valid pair of format/modifier in the scanout 
tranche");
+       return false;
 }
 
 static void
@@ -1158,25 +1213,37 @@
 {
        struct window *window = data;
        struct dmabuf_feedback_tranche *tranche;
+       bool got_scanout_tranche = false;
        unsigned int i;
 
        fprintf(stderr, "???end of dma-buf feedback\n\n");
 
        /* The first time that we receive dma-buf feedback for a surface it
-        * contains only the renderer tranche. We pick the INITIAL_BUFFER_FORMAT
+        * contains only the renderer tranches. We pick the 
INITIAL_BUFFER_FORMAT
         * from there. Then the compositor should detect that the format is
         * unsupported by the underlying hardware (not actually, but you should
-        * have faked this in the DRM-backend) and send the scanout tranche. We
-        * use the formats/modifiers of the scanout tranche to reallocate our
+        * have faked this in the DRM-backend) and send the scanout tranches. We
+        * use the formats/modifiers of the scanout tranches to reallocate our
         * buffers. */
        wl_array_for_each(tranche, &window->pending_dmabuf_feedback.tranches) {
                if (tranche->is_scanout_tranche) {
-                       pick_format_from_scanout_tranche(window, tranche);
-                       for (i = 0; i < NUM_BUFFERS; i++)
-                               window->buffers[i].recreate = true;
-                       break;
+                       got_scanout_tranche = true;
+                       if (pick_format_from_scanout_tranche(window, tranche)) {
+                               for (i = 0; i < NUM_BUFFERS; i++)
+                                       window->buffers[i].recreate = true;
+                               break;
+                       }
                }
-               pick_initial_format_from_renderer_tranche(window, tranche);
+               if (pick_initial_format_from_renderer_tranche(window, tranche))
+                       break;
+       }
+
+       if (got_scanout_tranche) {
+               assert(window->format.format != INITIAL_BUFFER_FORMAT &&
+                      "error: no valid pair of format/modifier in the scanout 
tranches");
+       } else {
+               assert(window->format.format == INITIAL_BUFFER_FORMAT &&
+                      "error: INITIAL_BUFFER_FORMAT not supported by the 
hardware");
        }
 
        dmabuf_feedback_fini(&window->dmabuf_feedback);
@@ -1383,6 +1450,9 @@
        struct display *display;
        struct window *window;
        int ret = 0;
+       struct timespec start_time, current_time;
+       const time_t MAX_TIME_SECONDS = 3;
+       time_t delta_time = 0;
 
        fprintf(stderr, "This client was written with the purpose of manually 
test " \
                        "Weston's dma-buf feedback implementation. See main() " 
\
@@ -1391,9 +1461,14 @@
        display = create_display();
        window = create_window(display);
 
+       clock_gettime(CLOCK_MONOTONIC, &start_time);
+
        redraw(window, NULL, 0);
-       while (ret != -1 && window->n_redraws < 200)
+       while (ret != -1 && delta_time < MAX_TIME_SECONDS) {
                ret = wl_display_dispatch(display->display);
+               clock_gettime(CLOCK_MONOTONIC, &current_time);
+               delta_time = current_time.tv_sec - start_time.tv_sec;
+       }
 
        destroy_window(window);
        destroy_display(display);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weston-10.0.0/clients/simple-dmabuf-v4l.c 
new/weston-10.0.2/clients/simple-dmabuf-v4l.c
--- old/weston-10.0.0/clients/simple-dmabuf-v4l.c       2022-02-01 
22:59:57.000000000 +0100
+++ new/weston-10.0.2/clients/simple-dmabuf-v4l.c       2022-07-26 
12:22:25.000000000 +0200
@@ -127,7 +127,7 @@
        int data_offsets[VIDEO_MAX_PLANES];
 };
 
-#define NUM_BUFFERS 3
+#define NUM_BUFFERS 4
 
 struct window {
        struct display *display;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weston-10.0.0/clients/simple-egl.c 
new/weston-10.0.2/clients/simple-egl.c
--- old/weston-10.0.0/clients/simple-egl.c      2022-02-01 22:59:57.000000000 
+0100
+++ new/weston-10.0.2/clients/simple-egl.c      2022-07-26 12:22:25.000000000 
+0200
@@ -262,6 +262,19 @@
        GLuint frag, vert;
        GLuint program;
        GLint status;
+       EGLBoolean ret;
+
+       window->native = wl_egl_window_create(window->surface,
+                                             window->geometry.width,
+                                             window->geometry.height);
+       window->egl_surface =
+               weston_platform_create_egl_surface(window->display->egl.dpy,
+                                                  window->display->egl.conf,
+                                                  window->native, NULL);
+
+       ret = eglMakeCurrent(window->display->egl.dpy, window->egl_surface,
+                            window->egl_surface, window->display->egl.ctx);
+       assert(ret == EGL_TRUE);
 
        frag = create_shader(window, frag_shader_text, GL_FRAGMENT_SHADER);
        vert = create_shader(window, vert_shader_text, GL_VERTEX_SHADER);
@@ -362,19 +375,9 @@
 create_surface(struct window *window)
 {
        struct display *display = window->display;
-       EGLBoolean ret;
 
        window->surface = wl_compositor_create_surface(display->compositor);
 
-       window->native =
-               wl_egl_window_create(window->surface,
-                                    window->geometry.width,
-                                    window->geometry.height);
-       window->egl_surface =
-               weston_platform_create_egl_surface(display->egl.dpy,
-                                                  display->egl.conf,
-                                                  window->native, NULL);
-
        window->xdg_surface = xdg_wm_base_get_xdg_surface(display->wm_base,
                                                          window->surface);
        xdg_surface_add_listener(window->xdg_surface,
@@ -389,21 +392,16 @@
        xdg_toplevel_set_app_id(window->xdg_toplevel,
                        "org.freedesktop.weston.simple-egl");
 
+       if (window->fullscreen)
+               xdg_toplevel_set_fullscreen(window->xdg_toplevel, NULL);
+       else if (window->maximized)
+               xdg_toplevel_set_maximized(window->xdg_toplevel);
+
        window->wait_for_configure = true;
        wl_surface_commit(window->surface);
 
-       ret = eglMakeCurrent(window->display->egl.dpy, window->egl_surface,
-                            window->egl_surface, window->display->egl.ctx);
-       assert(ret == EGL_TRUE);
-
        if (!window->frame_sync)
                eglSwapInterval(display->egl.dpy, 0);
-
-       if (!display->wm_base)
-               return;
-
-       if (window->fullscreen)
-               xdg_toplevel_set_fullscreen(window->xdg_toplevel, NULL);
 }
 
 static void
@@ -806,6 +804,7 @@
        fprintf(stderr, "Usage: simple-egl [OPTIONS]\n\n"
                "  -d <us>\tBuffer swap delay in microseconds\n"
                "  -f\tRun in fullscreen mode\n"
+               "  -m\tRun in maximized mode\n"
                "  -o\tCreate an opaque surface\n"
                "  -s\tUse a 16 bpp EGL config\n"
                "  -b\tDon't sync to compositor redraw (eglSwapInterval 0)\n"
@@ -836,6 +835,8 @@
                        window.delay = atoi(argv[++i]);
                else if (strcmp("-f", argv[i]) == 0)
                        window.fullscreen = 1;
+               else if (strcmp("-m", argv[i]) == 0)
+                       window.maximized = 1;
                else if (strcmp("-o", argv[i]) == 0)
                        window.opaque = 1;
                else if (strcmp("-s", argv[i]) == 0)
@@ -864,7 +865,17 @@
 
        init_egl(&display, &window);
        create_surface(&window);
-       init_gl(&window);
+
+       /* we already have wait_for_configure set after create_surface() */
+       while (running && ret != -1 && window.wait_for_configure) {
+               ret = wl_display_dispatch(display.display);
+
+               /* wait until xdg_surface::configure acks the new dimensions */
+               if (window.wait_for_configure)
+                       continue;
+
+               init_gl(&window);
+       }
 
        display.cursor_surface =
                wl_compositor_create_surface(display.compositor);
@@ -874,17 +885,9 @@
        sigint.sa_flags = SA_RESETHAND;
        sigaction(SIGINT, &sigint, NULL);
 
-       /* The mainloop here is a little subtle.  Redrawing will cause
-        * EGL to read events so we can just call
-        * wl_display_dispatch_pending() to handle any events that got
-        * queued up as a side effect. */
        while (running && ret != -1) {
-               if (window.wait_for_configure) {
-                       ret = wl_display_dispatch(display.display);
-               } else {
-                       ret = wl_display_dispatch_pending(display.display);
-                       redraw(&window, NULL, 0);
-               }
+               ret = wl_display_dispatch_pending(display.display);
+               redraw(&window, NULL, 0);
        }
 
        fprintf(stderr, "simple-egl exiting\n");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weston-10.0.0/desktop-shell/shell.c 
new/weston-10.0.2/desktop-shell/shell.c
--- old/weston-10.0.0/desktop-shell/shell.c     2022-02-01 22:59:57.000000000 
+0100
+++ new/weston-10.0.2/desktop-shell/shell.c     2022-07-26 12:22:25.000000000 
+0200
@@ -101,6 +101,8 @@
 
        struct weston_desktop_surface *desktop_surface;
        struct weston_view *view;
+       struct weston_surface *wsurface_anim_fade;
+       struct weston_view *wview_anim_fade;
        int32_t last_width, last_height;
 
        struct desktop_shell *shell;
@@ -194,6 +196,10 @@
 };
 
 
+static struct weston_view *
+shell_fade_create_fade_out_view(struct shell_surface *shsurf,
+                               struct weston_surface *surface);
+
 static struct desktop_shell *
 shell_surface_get_shell(struct shell_surface *shsurf);
 
@@ -261,10 +267,12 @@
                wl_list_init(&shsurf_child->children_link);
        }
        wl_list_remove(&shsurf->children_link);
+       weston_desktop_surface_unlink_view(shsurf->view);
+       weston_view_destroy(shsurf->view);
 
        wl_signal_emit(&shsurf->destroy_signal, shsurf);
+       weston_surface_destroy(shsurf->wsurface_anim_fade);
 
-       weston_view_destroy(shsurf->view);
        if (shsurf->output_destroy_listener.notify) {
                wl_list_remove(&shsurf->output_destroy_listener.link);
                shsurf->output_destroy_listener.notify = NULL;
@@ -877,7 +885,7 @@
 }
 
 static void
-desktop_shell_destroy_views_on_layer(struct weston_layer *layer);
+desktop_shell_destroy_layer(struct weston_layer *layer);
 
 static void
 workspace_destroy(struct workspace *ws)
@@ -892,7 +900,7 @@
        if (ws->fsurf_back)
                focus_surface_destroy(ws->fsurf_back);
 
-       desktop_shell_destroy_views_on_layer(&ws->layer);
+       desktop_shell_destroy_layer(&ws->layer);
        free(ws);
 }
 
@@ -1381,7 +1389,7 @@
        int dx = wl_fixed_to_int(grab->touch->grab_x + move->dx);
        int dy = wl_fixed_to_int(grab->touch->grab_y + move->dy);
 
-       if (!shsurf || !move->active)
+       if (!shsurf || !shsurf->desktop_surface || !move->active)
                return;
 
        es = weston_desktop_surface_get_surface(shsurf->desktop_surface);
@@ -1513,7 +1521,7 @@
        int cx, cy;
 
        weston_pointer_move(pointer, event);
-       if (!shsurf)
+       if (!shsurf || !shsurf->desktop_surface)
                return;
 
        surface = weston_desktop_surface_get_surface(shsurf->desktop_surface);
@@ -2253,8 +2261,8 @@
 
        loop = wl_display_get_event_loop(shsurf->shell->compositor->wl_display);
 
-       if (weston_view_is_mapped(shsurf->view)) {
-               weston_view_unmap(shsurf->view);
+       if (weston_view_is_mapped(shsurf->wview_anim_fade)) {
+               weston_view_unmap(shsurf->wview_anim_fade);
                wl_event_loop_add_idle(loop, fade_out_done_idle_cb, shsurf);
        }
 }
@@ -2364,7 +2372,6 @@
        weston_desktop_surface_set_user_data(shsurf->desktop_surface, NULL);
        shsurf->desktop_surface = NULL;
 
-       weston_desktop_surface_unlink_view(shsurf->view);
        if (weston_surface_is_mapped(surface) &&
            shsurf->shell->win_close_animation_type == ANIMATION_FADE) {
 
@@ -2373,11 +2380,26 @@
                        pixman_region32_init(&surface->pending.input);
                        pixman_region32_fini(&surface->input);
                        pixman_region32_init(&surface->input);
-                       weston_fade_run(shsurf->view, 1.0, 0.0, 300.0,
+
+                       /* its location might have changed, but also might've
+                        * migrated to a different output, so re-compute  this
+                        * as the animation requires having the same output as
+                        * the view */
+                       weston_view_set_output(shsurf->wview_anim_fade,
+                                              shsurf->view->output);
+                       weston_view_set_position(shsurf->wview_anim_fade,
+                                                shsurf->view->geometry.x,
+                                                shsurf->view->geometry.y);
+
+                       weston_layer_entry_insert(&shsurf->view->layer_link,
+                                                 
&shsurf->wview_anim_fade->layer_link);
+
+                       /* unmap the "original" view */
+                       weston_view_unmap(shsurf->view);
+                       weston_fade_run(shsurf->wview_anim_fade, 1.0, 0.0, 
300.0,
                                        fade_out_done, shsurf);
+
                        return;
-               } else {
-                       weston_surface_destroy(surface);
                }
        }
 
@@ -2500,8 +2522,14 @@
        if (!weston_surface_is_mapped(surface)) {
                map(shell, shsurf, sx, sy);
                surface->is_mapped = true;
-               if (shsurf->shell->win_close_animation_type == ANIMATION_FADE)
-                       ++surface->ref_count;
+               /* as we need to survive the weston_surface destruction we'll
+                * need to take another reference */
+               if (shsurf->shell->win_close_animation_type == ANIMATION_FADE) {
+                       surface->ref_count++;
+                       shsurf->wsurface_anim_fade = surface;
+                       shsurf->wview_anim_fade =
+                               shell_fade_create_fade_out_view(shsurf, 
surface);
+               }
                return;
        }
 
@@ -3992,6 +4020,29 @@
        return view;
 }
 
+static struct weston_view *
+shell_fade_create_fade_out_view(struct shell_surface *shsurf,
+                               struct weston_surface *surface)
+{
+       struct weston_view *view;
+       struct weston_output *woutput;
+
+       view = weston_view_create(surface);
+       if (!view)
+               return NULL;
+
+       woutput = get_focused_output(surface->compositor);
+       /* set the initial position and output just in case we happen to not
+        * move it around and just destroy it */
+       weston_view_set_output(view, woutput);
+       weston_view_set_position(view,
+                                shsurf->view->geometry.x,
+                                shsurf->view->geometry.y);
+       view->is_mapped = true;
+
+       return view;
+}
+
 static void
 shell_fade(struct desktop_shell *shell, enum fade_type type)
 {
@@ -4905,7 +4956,7 @@
 }
 
 static void
-desktop_shell_destroy_views_on_layer(struct weston_layer *layer)
+desktop_shell_destroy_layer(struct weston_layer *layer)
 {
        struct weston_view *view, *view_next;
 
@@ -4916,9 +4967,17 @@
                 * additional black_view created and added to its layer_link
                 * fullscreen view. See shell_ensure_fullscreen_black_view()
                 *
-                * As that black_view it is not a weston_desktop_surface
-                * we can't have a shsurf for it so we just destroy it like
-                * we do it in desktop_surface_removed() */
+                * Note that we do not choose to destroy all other potential
+                * views we find in the layer, but instead we explicitly verify
+                * if the view in question was explicitly created by
+                * desktop-shell, rather than libweston-desktop (in
+                * desktop_surface_added()).
+                *
+                * This is particularly important because libweston-desktop
+                * could create additional views, which are managed implicitly,
+                * but which are still being added to the layer list.
+                *
+                */
                if (shsurf)
                        desktop_shell_destroy_surface(shsurf);
                else
@@ -4970,12 +5029,12 @@
                workspace_destroy(*ws);
        wl_array_release(&shell->workspaces.array);
 
-       desktop_shell_destroy_views_on_layer(&shell->panel_layer);
-       desktop_shell_destroy_views_on_layer(&shell->background_layer);
-       desktop_shell_destroy_views_on_layer(&shell->lock_layer);
-       desktop_shell_destroy_views_on_layer(&shell->input_panel_layer);
-       desktop_shell_destroy_views_on_layer(&shell->minimized_layer);
-       desktop_shell_destroy_views_on_layer(&shell->fullscreen_layer);
+       desktop_shell_destroy_layer(&shell->panel_layer);
+       desktop_shell_destroy_layer(&shell->background_layer);
+       desktop_shell_destroy_layer(&shell->lock_layer);
+       desktop_shell_destroy_layer(&shell->input_panel_layer);
+       desktop_shell_destroy_layer(&shell->minimized_layer);
+       desktop_shell_destroy_layer(&shell->fullscreen_layer);
 
        free(shell->client);
        free(shell);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weston-10.0.0/kiosk-shell/kiosk-shell.c 
new/weston-10.0.2/kiosk-shell/kiosk-shell.c
--- old/weston-10.0.0/kiosk-shell/kiosk-shell.c 2022-02-01 22:59:57.000000000 
+0100
+++ new/weston-10.0.2/kiosk-shell/kiosk-shell.c 2022-07-26 12:22:25.000000000 
+0200
@@ -173,8 +173,10 @@
        app_id = weston_desktop_surface_get_app_id(shsurf->desktop_surface);
        if (app_id) {
                wl_list_for_each(shoutput, &shsurf->shell->output_list, link) {
-                       if (kiosk_shell_output_has_app_id(shoutput, app_id))
+                       if (kiosk_shell_output_has_app_id(shoutput, app_id)) {
+                               shsurf->appid_output_assigned = true;
                                return shoutput->output;
+                       }
                }
        }
 
@@ -354,6 +356,7 @@
        shsurf->desktop_surface = desktop_surface;
        shsurf->view = view;
        shsurf->shell = shell;
+       shsurf->appid_output_assigned = false;
 
        weston_desktop_surface_set_user_data(desktop_surface, shsurf);
 
@@ -387,8 +390,10 @@
 
                /* removes it from the normal_layer and move it to inactive
                 * one, without occluding the top-level window if the new one
-                * is a child to that */
-               if (!shsurf->parent) {
+                * is a child to that. Also, do not occlude another view
+                * (currently focused one) on a different output when activating
+                * a new one. */
+               if (!shsurf->parent && (shsurf->output == 
current_focus->output)) {
                        
weston_layer_entry_remove(&current_focus->view->layer_link);
                        
weston_layer_entry_insert(&shsurf->shell->inactive_layer.view_list,
                                                  
&current_focus->view->layer_link);
@@ -645,12 +650,18 @@
        struct weston_view *top_view = NULL;
        struct weston_view *view;
 
+
        /* we need to take into account that the surface being destroyed it not
         * always the same as the focus_surface, which could result in picking
         * and *activating* the wrong window, so avoid returning a view for
         * that case. A particular case is when a top-level child window, would
-        * pick a parent window below the focused_surface. */
-       if (focused_surface != shsurf->view->surface)
+        * pick a parent window below the focused_surface.
+        *
+        * Apply that only on the same output to avoid incorrectly returning an
+        * invalid/empty view, which could happen if the view being destroyed
+        * is on a output different than the focused_surface output */
+       if (focused_surface && focused_surface != shsurf->view->surface &&
+           shsurf->output == focused_surface->output)
                return top_view;
 
        wl_list_for_each(view, &layer->view_list.link, layer_link.link) {
@@ -660,6 +671,10 @@
                if (!view->is_mapped || view == shsurf->view)
                        continue;
 
+               /* pick views only on the same output */
+               if (view->output != shsurf->output)
+                       continue;
+
                view_shsurf = get_kiosk_shell_surface(view->surface);
                if (!view_shsurf)
                        continue;
@@ -721,6 +736,8 @@
                weston_desktop_surface_get_user_data(desktop_surface);
        struct weston_surface *surface =
                weston_desktop_surface_get_surface(desktop_surface);
+       const char *app_id =
+               weston_desktop_surface_get_app_id(desktop_surface);
        bool is_resized;
        bool is_fullscreen;
 
@@ -729,6 +746,24 @@
        if (surface->width == 0)
                return;
 
+       if (!shsurf->appid_output_assigned && app_id) {
+               struct weston_output *output = NULL;
+
+               /* reset previous output being set in _added() as the output is
+                * being cached */
+               shsurf->output = NULL;
+               output = kiosk_shell_surface_find_best_output(shsurf);
+
+               kiosk_shell_surface_set_output(shsurf, output);
+               weston_desktop_surface_set_size(shsurf->desktop_surface,
+                                               shsurf->output->width,
+                                               shsurf->output->height);
+               /* even if we couldn't find an appid set for a particular
+                * output still flag the shsurf as to a avoid changing the
+                * output every time */
+               shsurf->appid_output_assigned = true;
+       }
+
        /* TODO: When the top-level surface is committed with a new size after 
an
         * output resize, sometimes the view appears scaled. What state are we 
not
         * updating?
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weston-10.0.0/kiosk-shell/kiosk-shell.h 
new/weston-10.0.2/kiosk-shell/kiosk-shell.h
--- old/weston-10.0.0/kiosk-shell/kiosk-shell.h 2022-02-01 22:59:57.000000000 
+0100
+++ new/weston-10.0.2/kiosk-shell/kiosk-shell.h 2022-07-26 12:22:25.000000000 
+0200
@@ -73,6 +73,8 @@
                int32_t x;
                int32_t y;
        } xwayland;
+
+       bool appid_output_assigned;
 };
 
 struct kiosk_shell_seat {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weston-10.0.0/libweston/backend-drm/drm-internal.h 
new/weston-10.0.2/libweston/backend-drm/drm-internal.h
--- old/weston-10.0.0/libweston/backend-drm/drm-internal.h      2022-02-01 
22:59:57.000000000 +0100
+++ new/weston-10.0.2/libweston/backend-drm/drm-internal.h      2022-07-26 
12:22:25.000000000 +0200
@@ -236,6 +236,7 @@
        FAILURE_REASONS_FB_FORMAT_INCOMPATIBLE = (1 << 1),
        FAILURE_REASONS_DMABUF_MODIFIER_INVALID = (1 << 2),
        FAILURE_REASONS_ADD_FB_FAILED = (1 << 3),
+       FAILURE_REASONS_GBM_BO_IMPORT_FAILED = (1 << 4)
 };
 
 /**
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weston-10.0.0/libweston/backend-drm/fb.c 
new/weston-10.0.2/libweston/backend-drm/fb.c
--- old/weston-10.0.0/libweston/backend-drm/fb.c        2022-02-01 
22:59:57.000000000 +0100
+++ new/weston-10.0.2/libweston/backend-drm/fb.c        2022-07-26 
12:22:25.000000000 +0200
@@ -276,8 +276,12 @@
 
        fb->bo = gbm_bo_import(backend->gbm, GBM_BO_IMPORT_FD_MODIFIER,
                               &import_mod, GBM_BO_USE_SCANOUT);
-       if (!fb->bo)
+       if (!fb->bo) {
+               if (try_view_on_plane_failure_reasons)
+                       *try_view_on_plane_failure_reasons |=
+                               FAILURE_REASONS_GBM_BO_IMPORT_FAILED;
                goto err_free;
+       }
 
        fb->width = dmabuf->attributes.width;
        fb->height = dmabuf->attributes.height;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weston-10.0.0/libweston/backend-drm/state-propose.c 
new/weston-10.0.2/libweston/backend-drm/state-propose.c
--- old/weston-10.0.0/libweston/backend-drm/state-propose.c     2022-02-01 
22:59:57.000000000 +0100
+++ new/weston-10.0.2/libweston/backend-drm/state-propose.c     2022-07-26 
12:22:25.000000000 +0200
@@ -602,7 +602,8 @@
        if (try_view_on_plane_failure_reasons &
                (FAILURE_REASONS_ADD_FB_FAILED |
                 FAILURE_REASONS_FB_FORMAT_INCOMPATIBLE |
-                FAILURE_REASONS_DMABUF_MODIFIER_INVALID))
+                FAILURE_REASONS_DMABUF_MODIFIER_INVALID |
+                FAILURE_REASONS_GBM_BO_IMPORT_FAILED))
                action_needed |= ACTION_NEEDED_ADD_SCANOUT_TRANCHE;
 
        assert(action_needed != (ACTION_NEEDED_REMOVE_SCANOUT_TRANCHE |
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weston-10.0.0/libweston/compositor.c 
new/weston-10.0.2/libweston/compositor.c
--- old/weston-10.0.0/libweston/compositor.c    2022-02-01 22:59:57.000000000 
+0100
+++ new/weston-10.0.2/libweston/compositor.c    2022-07-26 12:22:25.000000000 
+0200
@@ -2306,6 +2306,10 @@
        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;
 
@@ -4044,54 +4048,22 @@
        surface_damage_buffer
 };
 
-static int
-create_surface_dmabuf_feedback(struct weston_compositor *ec,
-                              struct weston_surface *surface)
-{
-       struct weston_dmabuf_feedback_tranche *tranche;
-       dev_t main_device = ec->default_dmabuf_feedback->main_device;
-       uint32_t flags = 0;
-
-       surface->dmabuf_feedback = weston_dmabuf_feedback_create(main_device);
-       if (!surface->dmabuf_feedback)
-               return -1;
-
-       tranche = 
weston_dmabuf_feedback_tranche_create(surface->dmabuf_feedback,
-                                                       
ec->dmabuf_feedback_format_table,
-                                                       main_device, flags,
-                                                       RENDERER_PREF);
-       if (!tranche) {
-               weston_dmabuf_feedback_destroy(surface->dmabuf_feedback);
-               surface->dmabuf_feedback = NULL;
-               return -1;
-       }
-
-       return 0;
-}
-
 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;
-       int ret;
 
        surface = weston_surface_create(ec);
        if (surface == NULL)
                goto err;
 
-       if (ec->default_dmabuf_feedback) {
-               ret = create_surface_dmabuf_feedback(ec, surface);
-               if (ret < 0)
-                       goto err_dmabuf_feedback;
-       }
-
        surface->resource =
                wl_resource_create(client, &wl_surface_interface,
                                   wl_resource_get_version(resource), id);
        if (surface->resource == NULL)
-               goto err_dmabuf_feedback;
+               goto err_res;
        wl_resource_set_implementation(surface->resource, &surface_interface,
                                       surface, destroy_surface);
 
@@ -4099,7 +4071,7 @@
 
        return;
 
-err_dmabuf_feedback:
+err_res:
        weston_surface_destroy(surface);
 err:
        wl_resource_post_no_memory(resource);
@@ -4211,6 +4183,11 @@
                              &surface->pending.damage_surface);
        pixman_region32_clear(&surface->pending.damage_surface);
 
+       pixman_region32_union(&sub->cached.damage_buffer,
+                             &sub->cached.damage_buffer,
+                             &surface->pending.damage_buffer);
+       pixman_region32_clear(&surface->pending.damage_buffer);
+
        if (surface->pending.newly_attached) {
                sub->cached.newly_attached = 1;
                weston_surface_state_set_buffer(&sub->cached,
@@ -4233,8 +4210,6 @@
        sub->cached.sx += surface->pending.sx;
        sub->cached.sy += surface->pending.sy;
 
-       apply_damage_buffer(&sub->cached.damage_surface, surface, 
&surface->pending);
-
        sub->cached.buffer_viewport.changed |=
                surface->pending.buffer_viewport.changed;
        sub->cached.buffer_viewport.buffer =
@@ -4361,7 +4336,7 @@
         */
 
        if (!weston_surface_is_mapped(surface)) {
-               surface->is_mapped = true;
+               surface->is_mapped = surface->buffer_ref.buffer != NULL;
 
                /* Cannot call weston_view_update_transform(),
                 * because that would call it also for the parent surface,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weston-10.0.0/libweston/linux-dmabuf.c 
new/weston-10.0.2/libweston/linux-dmabuf.c
--- old/weston-10.0.0/libweston/linux-dmabuf.c  2022-02-01 22:59:57.000000000 
+0100
+++ new/weston-10.0.2/libweston/linux-dmabuf.c  2022-07-26 12:22:25.000000000 
+0200
@@ -684,6 +684,7 @@
        wl_resource_for_each_safe(res, res_tmp, 
&dmabuf_feedback->resource_list) {
                wl_list_remove(wl_resource_get_link(res));
                wl_list_init(wl_resource_get_link(res));
+               wl_resource_set_user_data(res, NULL);
        }
 
        free(dmabuf_feedback);
@@ -786,6 +787,7 @@
 {
        struct wl_resource *res;
 
+       assert(!wl_list_empty(&dmabuf_feedback->resource_list));
        wl_resource_for_each(res, &dmabuf_feedback->resource_list)
                weston_dmabuf_feedback_send(dmabuf_feedback,
                                            format_table, res, false);
@@ -794,7 +796,16 @@
 static void
 dmabuf_feedback_resource_destroy(struct wl_resource *resource)
 {
+       struct weston_surface *surface =
+               wl_resource_get_user_data(resource);
+
        wl_list_remove(wl_resource_get_link(resource));
+
+       if (surface &&
+           wl_list_empty(&surface->dmabuf_feedback->resource_list)) {
+               weston_dmabuf_feedback_destroy(surface->dmabuf_feedback);
+               surface->dmabuf_feedback = NULL;
+       }
 }
 
 static void
@@ -810,7 +821,8 @@
 
 static struct wl_resource *
 dmabuf_feedback_resource_create(struct wl_resource *dmabuf_resource,
-                               struct wl_client *client, uint32_t 
dmabuf_feedback_id)
+                               struct wl_client *client, uint32_t 
dmabuf_feedback_id,
+                               struct weston_surface *surface)
 {
        struct wl_resource *dmabuf_feedback_res;
        uint32_t version;
@@ -826,7 +838,7 @@
        wl_list_init(wl_resource_get_link(dmabuf_feedback_res));
        wl_resource_set_implementation(dmabuf_feedback_res,
                                       
&zwp_linux_dmabuf_feedback_implementation,
-                                      NULL, dmabuf_feedback_resource_destroy);
+                                      surface, 
dmabuf_feedback_resource_destroy);
 
        return dmabuf_feedback_res;
 }
@@ -842,7 +854,8 @@
 
        dmabuf_feedback_resource =
                dmabuf_feedback_resource_create(dmabuf_resource,
-                                               client, dmabuf_feedback_id);
+                                               client, dmabuf_feedback_id,
+                                               NULL);
        if (!dmabuf_feedback_resource) {
                wl_resource_post_no_memory(dmabuf_resource);
                return;
@@ -853,22 +866,55 @@
                                    dmabuf_feedback_resource, true);
 }
 
+static int
+create_surface_dmabuf_feedback(struct weston_compositor *ec,
+                              struct weston_surface *surface)
+{
+       struct weston_dmabuf_feedback_tranche *tranche;
+       dev_t main_device = ec->default_dmabuf_feedback->main_device;
+       uint32_t flags = 0;
+
+       surface->dmabuf_feedback = weston_dmabuf_feedback_create(main_device);
+       if (!surface->dmabuf_feedback)
+               return -1;
+
+       tranche = 
weston_dmabuf_feedback_tranche_create(surface->dmabuf_feedback,
+                                                       
ec->dmabuf_feedback_format_table,
+                                                       main_device, flags,
+                                                       RENDERER_PREF);
+       if (!tranche) {
+               weston_dmabuf_feedback_destroy(surface->dmabuf_feedback);
+               surface->dmabuf_feedback = NULL;
+               return -1;
+       }
+
+       return 0;
+}
+
 static void
 linux_dmabuf_get_per_surface_feedback(struct wl_client *client,
                                      struct wl_resource *dmabuf_resource,
                                      uint32_t dmabuf_feedback_id,
                                      struct wl_resource *surface_resource)
 {
+       struct weston_compositor *compositor =
+               wl_resource_get_user_data(dmabuf_resource);
        struct weston_surface *surface =
                wl_resource_get_user_data(surface_resource);
        struct wl_resource *dmabuf_feedback_resource;
+       int ret;
 
        dmabuf_feedback_resource =
                dmabuf_feedback_resource_create(dmabuf_resource,
-                                               client, dmabuf_feedback_id);
-       if (!dmabuf_feedback_resource) {
-               wl_resource_post_no_memory(dmabuf_resource);
-               return;
+                                               client, dmabuf_feedback_id,
+                                               surface);
+       if (!dmabuf_feedback_resource)
+               goto err;
+
+       if (!surface->dmabuf_feedback) {
+               ret = create_surface_dmabuf_feedback(compositor, surface);
+               if (ret < 0)
+                       goto err_feedback;
        }
 
        /* Surface dma-buf feedback is dynamic and may need to be resent to
@@ -879,6 +925,13 @@
        weston_dmabuf_feedback_send(surface->dmabuf_feedback,
                                    
surface->compositor->dmabuf_feedback_format_table,
                                    dmabuf_feedback_resource, true);
+       return;
+
+err_feedback:
+       wl_resource_set_user_data(dmabuf_feedback_resource, NULL);
+       wl_resource_destroy(dmabuf_feedback_resource);
+err:
+       wl_resource_post_no_memory(dmabuf_resource);
 }
 
 /** Get the linux_dmabuf_buffer from a wl_buffer resource
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weston-10.0.0/libweston/renderer-gl/fragment.glsl 
new/weston-10.0.2/libweston/renderer-gl/fragment.glsl
--- old/weston-10.0.0/libweston/renderer-gl/fragment.glsl       2022-02-01 
22:59:57.000000000 +0100
+++ new/weston-10.0.2/libweston/renderer-gl/fragment.glsl       2022-07-26 
12:22:25.000000000 +0200
@@ -67,6 +67,9 @@
 compile_const bool c_green_tint = DEF_GREEN_TINT;
 compile_const int c_color_pre_curve = DEF_COLOR_PRE_CURVE;
 
+compile_const bool c_need_color_pipeline =
+       c_color_pre_curve != SHADER_COLOR_CURVE_IDENTITY;
+
 vec4
 yuva2rgba(vec4 yuva)
 {
@@ -202,9 +205,6 @@
 vec4
 color_pipeline(vec4 color)
 {
-       /* View alpha (opacity) */
-       color.a *= alpha;
-
        color.rgb = color_pre_curve(color.rgb);
 
        return color;
@@ -218,18 +218,35 @@
        /* Electrical (non-linear) RGBA values, may be premult or not */
        color = sample_input_texture();
 
-       /* Ensure straight alpha */
-       if (c_input_is_premult) {
-               if (color.a == 0.0)
-                       color.rgb = vec3(0, 0, 0);
-               else
-                       color.rgb *= 1.0 / color.a;
-       }
+       if (c_need_color_pipeline) {
+               /* Ensure straight alpha */
+               if (c_input_is_premult) {
+                       if (color.a == 0.0)
+                               color.rgb = vec3(0, 0, 0);
+                       else
+                               color.rgb *= 1.0 / color.a;
+               }
+
+               color = color_pipeline(color);
 
-       color = color_pipeline(color);
+               /* View alpha (opacity) */
+               color.a *= alpha;
 
-       /* pre-multiply for blending */
-       color.rgb *= color.a;
+               /* pre-multiply for blending */
+               color.rgb *= color.a;
+       } else {
+               /* Fast path for disabled color management */
+
+               if (c_input_is_premult) {
+                       /* View alpha (opacity) */
+                       color *= alpha;
+               } else {
+                       /* View alpha (opacity) */
+                       color.a *= alpha;
+                       /* pre-multiply for blending */
+                       color.rgb *= color.a;
+               }
+       }
 
        if (c_green_tint)
                color = vec4(0.0, 0.3, 0.0, 0.2) + color * 0.8;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weston-10.0.0/libweston-desktop/xdg-shell.c 
new/weston-10.0.2/libweston-desktop/xdg-shell.c
--- old/weston-10.0.0/libweston-desktop/xdg-shell.c     2022-02-01 
22:59:57.000000000 +0100
+++ new/weston-10.0.2/libweston-desktop/xdg-shell.c     2022-07-26 
12:22:25.000000000 +0200
@@ -713,7 +713,7 @@
 
                wl_resource_post_error(client_resource,
                                       XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE,
-                                      "xdg_surface buffer (%" PRIi32 " x %" 
PRIi32 ") "
+                                      "xdg_surface geometry (%" PRIi32 " x %" 
PRIi32 ") "
                                       "does not match the configured maximized 
state (%" PRIi32 " x %" PRIi32 ")",
                                       geometry.width, geometry.height,
                                       toplevel->next.size.width,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weston-10.0.0/meson.build 
new/weston-10.0.2/meson.build
--- old/weston-10.0.0/meson.build       2022-02-01 22:59:57.000000000 +0100
+++ new/weston-10.0.2/meson.build       2022-07-26 12:22:25.000000000 +0200
@@ -1,6 +1,6 @@
 project('weston',
        'c',
-       version: '10.0.0',
+       version: '10.0.2',
        default_options: [
                'warning_level=3',
                'c_std=gnu99',
@@ -121,7 +121,7 @@
 
 backend_default = get_option('backend-default')
 if backend_default == 'auto'
-       foreach b : [ 'headless', 'fbdev', 'x11', 'wayland', 'drm' ]
+       foreach b : [ 'headless', 'x11', 'wayland', 'drm' ]
                if get_option('backend-' + b)
                        backend_default = b
                endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weston-10.0.0/tests/devices-test.c 
new/weston-10.0.2/tests/devices-test.c
--- old/weston-10.0.0/tests/devices-test.c      2022-02-01 22:59:57.000000000 
+0100
+++ new/weston-10.0.2/tests/devices-test.c      2022-07-26 12:22:25.000000000 
+0200
@@ -36,6 +36,8 @@
 
        compositor_setup_defaults(&setup);
 
+       setup.shell = SHELL_TEST_DESKTOP;
+
        return weston_test_harness_execute_as_client(harness, &setup);
 }
 DECLARE_FIXTURE_SETUP(fixture_setup);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weston-10.0.0/tests/ivi-layout-test-plugin.c 
new/weston-10.0.2/tests/ivi-layout-test-plugin.c
--- old/weston-10.0.0/tests/ivi-layout-test-plugin.c    2022-02-01 
22:59:57.000000000 +0100
+++ new/weston-10.0.2/tests/ivi-layout-test-plugin.c    2022-07-26 
12:22:25.000000000 +0200
@@ -53,7 +53,7 @@
        static void runner_func_##name(struct test_context *);  \
                                                                \
        const struct runner_test runner_test_##name             \
-               __attribute__ ((section ("plugin_test_section"))) =     \
+               __attribute__ ((used, section ("plugin_test_section"))) = \
        {                                                       \
                #name, runner_func_##name                       \
        };                                                      \
Binary files old/weston-10.0.0/tests/reference/subsurface_empty_mapping-00.png 
and new/weston-10.0.2/tests/reference/subsurface_empty_mapping-00.png differ
Binary files old/weston-10.0.0/tests/reference/subsurface_empty_mapping-01.png 
and new/weston-10.0.2/tests/reference/subsurface_empty_mapping-01.png differ
Binary files 
old/weston-10.0.0/tests/reference/subsurface_sync_damage_buffer-00.png and 
new/weston-10.0.2/tests/reference/subsurface_sync_damage_buffer-00.png differ
Binary files 
old/weston-10.0.0/tests/reference/subsurface_sync_damage_buffer-01.png and 
new/weston-10.0.2/tests/reference/subsurface_sync_damage_buffer-01.png differ
Binary files 
old/weston-10.0.0/tests/reference/subsurface_sync_damage_buffer-02.png and 
new/weston-10.0.2/tests/reference/subsurface_sync_damage_buffer-02.png differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weston-10.0.0/tests/subsurface-shot-test.c 
new/weston-10.0.2/tests/subsurface-shot-test.c
--- old/weston-10.0.0/tests/subsurface-shot-test.c      2022-02-01 
22:59:57.000000000 +0100
+++ new/weston-10.0.2/tests/subsurface-shot-test.c      2022-07-26 
12:22:25.000000000 +0200
@@ -117,7 +117,7 @@
        buf = create_shm_buffer_a8r8g8b8(client, width, height);
        fill_image_with_color(buf->image, color);
        wl_surface_attach(surface, buf->proxy, 0, 0);
-       wl_surface_damage(surface, 0, 0, width, height);
+       wl_surface_damage_buffer(surface, 0, 0, width, height);
        wl_surface_commit(surface);
 
        return buf;
@@ -213,3 +213,199 @@
        wl_subcompositor_destroy(subco);
        client_destroy(client);
 }
+
+TEST(subsurface_sync_damage_buffer)
+{
+       struct client *client;
+       struct wl_subcompositor *subco;
+       struct buffer *bufs[2] = { 0 };
+       struct wl_surface *surf[2] = { 0 };
+       struct wl_subsurface *sub[2] = { 0 };
+       struct rectangle clip = { 40, 40, 280, 200 };
+       int fail = 0;
+       unsigned i;
+       pixman_color_t red;
+       pixman_color_t blue;
+       pixman_color_t green;
+
+       color_rgb888(&red, 255, 0, 0);
+       color_rgb888(&blue, 0, 0, 255);
+       color_rgb888(&green, 0, 255, 0);
+
+       client = create_client_and_test_surface(100, 50, 100, 100);
+       assert(client);
+       subco = get_subcompositor(client);
+
+       /* move the pointer clearly away from our screenshooting area */
+       weston_test_move_pointer(client->test->weston_test, 0, 1, 0, 2, 30);
+
+       /* make the parent surface red */
+       surf[0] = client->surface->wl_surface;
+       client->surface->wl_surface = NULL; /* we stole it and destroy it */
+       bufs[0] = surface_commit_color(client, surf[0], &red, 100, 100);
+       /* sub[0] is not used */
+
+       fail += check_screen(client, "subsurface_sync_damage_buffer", 0, &clip, 
0);
+
+       /* create a blue sub-surface above red */
+       surf[1] = wl_compositor_create_surface(client->wl_compositor);
+       sub[1] = wl_subcompositor_get_subsurface(subco, surf[1], surf[0]);
+       bufs[1] = surface_commit_color(client, surf[1], &blue, 100, 100);
+
+       wl_subsurface_set_position(sub[1], 20, 20);
+       wl_surface_commit(surf[0]);
+
+       fail += check_screen(client, "subsurface_sync_damage_buffer", 1, &clip, 
1);
+
+       buffer_destroy(bufs[1]);
+       bufs[1] = surface_commit_color(client, surf[1], &green, 100, 100);
+       wl_surface_commit(surf[0]);
+
+       fail += check_screen(client, "subsurface_sync_damage_buffer", 2, &clip, 
2);
+
+       assert(fail == 0);
+
+       for (i = 0; i < ARRAY_LENGTH(sub); i++)
+               if (sub[i])
+                       wl_subsurface_destroy(sub[i]);
+
+       for (i = 0; i < ARRAY_LENGTH(surf); i++)
+               if (surf[i])
+                       wl_surface_destroy(surf[i]);
+
+       for (i = 0; i < ARRAY_LENGTH(bufs); i++)
+               if (bufs[i])
+                       buffer_destroy(bufs[i]);
+
+       wl_subcompositor_destroy(subco);
+       client_destroy(client);
+}
+
+TEST(subsurface_empty_mapping)
+{
+       struct client *client;
+       struct wl_subcompositor *subco;
+       struct wp_viewporter *viewporter;
+       struct buffer *bufs[3] = { 0 };
+       struct wl_surface *surf[3] = { 0 };
+       struct wl_subsurface *sub[3] = { 0 };
+       struct wp_viewport *viewport;
+       struct rectangle clip = { 40, 40, 280, 200 };
+       int fail = 0;
+       unsigned i;
+       pixman_color_t red;
+       pixman_color_t blue;
+       pixman_color_t green;
+
+       color_rgb888(&red, 255, 0, 0);
+       color_rgb888(&blue, 0, 0, 255);
+       color_rgb888(&green, 0, 255, 0);
+
+       client = create_client_and_test_surface(100, 50, 100, 100);
+       assert(client);
+       subco = get_subcompositor(client);
+       viewporter = bind_to_singleton_global(client,
+                                             &wp_viewporter_interface, 1);
+
+       /* move the pointer clearly away from our screenshooting area */
+       weston_test_move_pointer(client->test->weston_test, 0, 1, 0, 2, 30);
+
+       /* make the parent surface red */
+       surf[0] = client->surface->wl_surface;
+       client->surface->wl_surface = NULL; /* we stole it and destroy it */
+       bufs[0] = surface_commit_color(client, surf[0], &red, 100, 100);
+       /* sub[0] is not used */
+
+       fail += check_screen(client, "subsurface_empty_mapping", 0, &clip, 0);
+
+       /* create an empty subsurface on top */
+       surf[1] = wl_compositor_create_surface(client->wl_compositor);
+       sub[1] = wl_subcompositor_get_subsurface(subco, surf[1], surf[0]);
+       wl_subsurface_set_desync (sub[1]);
+
+       wl_subsurface_set_position(sub[1], 20, 20);
+       wl_surface_commit(surf[0]);
+
+       fail += check_screen(client, "subsurface_empty_mapping", 0, &clip, 1);
+
+       /* create a green subsurface on top */
+       surf[2] = wl_compositor_create_surface(client->wl_compositor);
+       sub[2] = wl_subcompositor_get_subsurface(subco, surf[2], surf[1]);
+       wl_subsurface_set_desync (sub[2]);
+       bufs[2] = surface_commit_color(client, surf[2], &green, 100, 100);
+
+       wl_subsurface_set_position(sub[2], 20, 20);
+       wl_surface_commit(surf[1]);
+
+       fail += check_screen(client, "subsurface_empty_mapping", 0, &clip, 2);
+
+       wl_surface_attach(surf[1], NULL, 0, 0);
+       wl_surface_commit(surf[1]);
+
+       fail += check_screen(client, "subsurface_empty_mapping", 0, &clip, 3);
+
+       wl_surface_set_buffer_scale (surf[1], 1);
+       wl_surface_commit(surf[1]);
+
+       fail += check_screen(client, "subsurface_empty_mapping", 0, &clip, 4);
+
+       viewport = wp_viewporter_get_viewport(viewporter, surf[1]);
+       wp_viewport_set_destination(viewport, 5, 5);
+       wl_surface_commit(surf[1]);
+
+       fail += check_screen(client, "subsurface_empty_mapping", 0, &clip, 5);
+
+       wp_viewport_set_destination(viewport, -1, -1);
+       wl_surface_commit(surf[1]);
+
+       fail += check_screen(client, "subsurface_empty_mapping", 0, &clip, 6);
+
+       /* map the previously empty middle surface with a blue buffer */
+       bufs[1] = surface_commit_color(client, surf[1], &blue, 100, 100);
+
+       fail += check_screen(client, "subsurface_empty_mapping", 1, &clip, 7);
+
+       /* try to trigger a recomputation of the buffer size with the
+        * shm-buffer potentially being released already */
+       wl_surface_set_buffer_scale (surf[1], 1);
+       wl_surface_commit(surf[1]);
+
+       fail += check_screen(client, "subsurface_empty_mapping", 1, &clip, 8);
+
+       /* try more */
+       wp_viewport_set_destination(viewport, 100, 100);
+       wl_surface_commit(surf[1]);
+
+       fail += check_screen(client, "subsurface_empty_mapping", 1, &clip, 9);
+
+       /* unmap the middle surface again to ensure recursive unmapping */
+       wl_surface_attach(surf[1], NULL, 0, 0);
+       wl_surface_commit(surf[1]);
+
+       fail += check_screen(client, "subsurface_empty_mapping", 0, &clip, 10);
+
+       /* remap middle surface to ensure recursive mapping */
+       bufs[1] = surface_commit_color(client, surf[1], &blue, 100, 100);
+
+       fail += check_screen(client, "subsurface_empty_mapping", 1, &clip, 11);
+
+       assert(fail == 0);
+
+       wp_viewport_destroy(viewport);
+
+       for (i = 0; i < ARRAY_LENGTH(sub); i++)
+               if (sub[i])
+                       wl_subsurface_destroy(sub[i]);
+
+       for (i = 0; i < ARRAY_LENGTH(surf); i++)
+               if (surf[i])
+                       wl_surface_destroy(surf[i]);
+
+       for (i = 0; i < ARRAY_LENGTH(bufs); i++)
+               if (bufs[i])
+                       buffer_destroy(bufs[i]);
+
+       wp_viewporter_destroy(viewporter);
+       wl_subcompositor_destroy(subco);
+       client_destroy(client);
+}

Reply via email to