summaryrefslogtreecommitdiffstats
path: root/bsp/meta-synopsys/recipes-graphics/wayland
diff options
context:
space:
mode:
authorToshikazuOhiwa <toshikazu_ohiwa@mail.toyota.co.jp>2020-03-30 09:24:26 +0900
committerToshikazuOhiwa <toshikazu_ohiwa@mail.toyota.co.jp>2020-03-30 09:24:26 +0900
commit5b80bfd7bffd4c20d80b7c70a7130529e9a755dd (patch)
treeb4bb18dcd1487dbf1ea8127e5671b7bb2eded033 /bsp/meta-synopsys/recipes-graphics/wayland
parent706ad73eb02caf8532deaf5d38995bd258725cb8 (diff)
agl-basesystem
Diffstat (limited to 'bsp/meta-synopsys/recipes-graphics/wayland')
-rw-r--r--bsp/meta-synopsys/recipes-graphics/wayland/files/dvi-i-1-270.cfg7
-rw-r--r--bsp/meta-synopsys/recipes-graphics/wayland/weston-ini-conf.bbappend5
-rw-r--r--bsp/meta-synopsys/recipes-graphics/wayland/weston/1001-os-compatibility-define-CLOCK_BOOTTIME-when-not-avai.patch41
-rw-r--r--bsp/meta-synopsys/recipes-graphics/wayland/weston/1005-protocol-add-weston-debug.xml.patch242
-rw-r--r--bsp/meta-synopsys/recipes-graphics/wayland/weston/1006-libweston-add-weston_debug-API-and-implementation.patch958
-rw-r--r--bsp/meta-synopsys/recipes-graphics/wayland/weston/1007-compositor-add-option-to-enable-weston_debug.patch87
-rw-r--r--bsp/meta-synopsys/recipes-graphics/wayland/weston/1010-xwm-dump_property-to-use-FILE-internally.patch141
-rw-r--r--bsp/meta-synopsys/recipes-graphics/wayland/weston/1011-xwm-move-FILE-to-the-callers-of-dump_property.patch267
-rw-r--r--bsp/meta-synopsys/recipes-graphics/wayland/weston/1012-xwm-convert-WM_DEBUG-into-a-weston-debug-scope.patch423
-rw-r--r--bsp/meta-synopsys/recipes-graphics/wayland/weston/1014-compositor-Add-weston_layer_mask_is_infinite.patch52
-rw-r--r--bsp/meta-synopsys/recipes-graphics/wayland/weston/1015-compositor-Add-scene-graph-debug-scope.patch297
-rw-r--r--bsp/meta-synopsys/recipes-graphics/wayland/weston/1017-compositor-drm-Add-backend-pointer-to-drm_output.patch37
-rw-r--r--bsp/meta-synopsys/recipes-graphics/wayland/weston/1018-compositor-drm-Add-drm-backend-log-debug-scope.patch632
-rw-r--r--bsp/meta-synopsys/recipes-graphics/wayland/weston/1046-compositor-drm-Read-FB2_MODIFIERS-capability.patch89
-rw-r--r--bsp/meta-synopsys/recipes-graphics/wayland/weston_5.0.0.bbappend16
15 files changed, 3294 insertions, 0 deletions
diff --git a/bsp/meta-synopsys/recipes-graphics/wayland/files/dvi-i-1-270.cfg b/bsp/meta-synopsys/recipes-graphics/wayland/files/dvi-i-1-270.cfg
new file mode 100644
index 00000000..fafa41a4
--- /dev/null
+++ b/bsp/meta-synopsys/recipes-graphics/wayland/files/dvi-i-1-270.cfg
@@ -0,0 +1,7 @@
+# A display is connected to DVI-I-1 and needs to be rotated 270 degrees
+# to have a proper orientation of the homescreen. For example the various sizes
+# of the GeChic display or the Dell display.
+[output]
+name=DVI-I-1
+transform=270
+mode=preferred
diff --git a/bsp/meta-synopsys/recipes-graphics/wayland/weston-ini-conf.bbappend b/bsp/meta-synopsys/recipes-graphics/wayland/weston-ini-conf.bbappend
new file mode 100644
index 00000000..b44b6095
--- /dev/null
+++ b/bsp/meta-synopsys/recipes-graphics/wayland/weston-ini-conf.bbappend
@@ -0,0 +1,5 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+SRC_URI_append += "\
+ file://dvi-i-1-270.cfg \
+"
+
diff --git a/bsp/meta-synopsys/recipes-graphics/wayland/weston/1001-os-compatibility-define-CLOCK_BOOTTIME-when-not-avai.patch b/bsp/meta-synopsys/recipes-graphics/wayland/weston/1001-os-compatibility-define-CLOCK_BOOTTIME-when-not-avai.patch
new file mode 100644
index 00000000..a7f2a34a
--- /dev/null
+++ b/bsp/meta-synopsys/recipes-graphics/wayland/weston/1001-os-compatibility-define-CLOCK_BOOTTIME-when-not-avai.patch
@@ -0,0 +1,41 @@
+From 66b71951f8ce66f02040f8814e1d89db34c34a87 Mon Sep 17 00:00:00 2001
+From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Date: Sun, 22 Feb 2015 12:36:00 +0100
+Subject: [PATCH] os-compatibility: define CLOCK_BOOTTIME when not available
+
+CLOCK_BOOTTIME is supposed to be provided by the C library headers,
+but uClibc 0.9.33.2 does not provide it. Instead of depending on an
+uClibc patch, let's make Weston define it to the right value when not
+already defined by the C library.
+
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+---
+ shared/os-compatibility.h | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/shared/os-compatibility.h b/shared/os-compatibility.h
+index 172bb7e..e369899 100644
+--- a/shared/os-compatibility.h
++++ b/shared/os-compatibility.h
+@@ -26,6 +26,7 @@
+ #include "config.h"
+
+ #include <sys/types.h>
++#include <time.h>
+
+ #ifdef HAVE_EXECINFO_H
+ #include <execinfo.h>
+@@ -37,6 +38,10 @@ backtrace(void **buffer, int size)
+ }
+ #endif
+
++#ifndef CLOCK_BOOTTIME
++#define CLOCK_BOOTTIME 7
++#endif
++
+ int
+ os_socketpair_cloexec(int domain, int type, int protocol, int *sv);
+
+--
+2.1.0
+
diff --git a/bsp/meta-synopsys/recipes-graphics/wayland/weston/1005-protocol-add-weston-debug.xml.patch b/bsp/meta-synopsys/recipes-graphics/wayland/weston/1005-protocol-add-weston-debug.xml.patch
new file mode 100644
index 00000000..4ca79b72
--- /dev/null
+++ b/bsp/meta-synopsys/recipes-graphics/wayland/weston/1005-protocol-add-weston-debug.xml.patch
@@ -0,0 +1,242 @@
+From 4fc1ee8d5b5c2a66fcc1a5bafad3eb95c3759bac Mon Sep 17 00:00:00 2001
+From: Pekka Paalanen <pq@iki.fi>
+Date: Thu, 12 Oct 2017 13:13:41 +0200
+Subject: [PATCH 05/46] protocol: add weston-debug.xml
+
+This is a new debugging extension for non-production environments. The
+aim is to replace all build-time choosable debug prints in the
+compositor with runtime subscribable debug streams.
+
+Signed-off-by: Pekka Paalanen <pq@iki.fi>
+
+Added new libweston-$MAJOR-protocols.pc file and install that
+for external projects to find the XML files installed by libweston.
+
+Signed-off-by: Maniraj Devadoss <Maniraj.Devadoss@in.bosch.com>
+
+Use noarch_pkgconfig_DATA instead, add ${pc_sysrootdir}, drop
+unnecessary EXTRA_DIST of weston-debug.xml.
+
+Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
+
+Add explicit advertisement of available debug interfaces.
+
+Signed-off-by: Daniel Stone <daniels@collabora.com>
+Reviewed-by: Emre Ucan <eucan@de.adit-jv.com>
+---
+ Makefile.am | 10 +++
+ configure.ac | 1 +
+ libweston/libweston-protocols.pc.in | 7 ++
+ protocol/weston-debug.xml | 139 ++++++++++++++++++++++++++++++++++++
+ 4 files changed, 157 insertions(+)
+ create mode 100644 libweston/libweston-protocols.pc.in
+ create mode 100644 protocol/weston-debug.xml
+
+diff --git a/Makefile.am b/Makefile.am
+index 83546b7c..e38ac009 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -104,6 +104,10 @@ libweston_@LIBWESTON_MAJOR@_la_SOURCES = \
+ shared/platform.h \
+ shared/weston-egl-ext.h
+
++libweston_@LIBWESTON_MAJOR@_datadir = $(datadir)/weston/protocols
++dist_libweston_@LIBWESTON_MAJOR@_data_DATA = \
++ protocol/weston-debug.xml
++
+ lib_LTLIBRARIES += libweston-desktop-@LIBWESTON_MAJOR@.la
+ libweston_desktop_@LIBWESTON_MAJOR@_la_CPPFLAGS = $(AM_CPPFLAGS) -DIN_WESTON
+ libweston_desktop_@LIBWESTON_MAJOR@_la_CFLAGS = $(AM_CFLAGS) $(COMPOSITOR_CFLAGS)
+@@ -150,6 +154,8 @@ endif
+ nodist_libweston_@LIBWESTON_MAJOR@_la_SOURCES = \
+ protocol/weston-screenshooter-protocol.c \
+ protocol/weston-screenshooter-server-protocol.h \
++ protocol/weston-debug-protocol.c \
++ protocol/weston-debug-server-protocol.h \
+ protocol/text-cursor-position-protocol.c \
+ protocol/text-cursor-position-server-protocol.h \
+ protocol/text-input-unstable-v1-protocol.c \
+@@ -274,6 +280,10 @@ pkgconfig_DATA = \
+ libweston-desktop/libweston-desktop-${LIBWESTON_MAJOR}.pc \
+ compositor/weston.pc
+
++noarch_pkgconfigdir = $(datadir)/pkgconfig
++noarch_pkgconfig_DATA = \
++ libweston/libweston-${LIBWESTON_MAJOR}-protocols.pc
++
+ wayland_sessiondir = $(datadir)/wayland-sessions
+ dist_wayland_session_DATA = compositor/weston.desktop
+
+diff --git a/configure.ac b/configure.ac
+index ab9ff7c7..cb62a386 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -695,6 +695,7 @@ AC_CONFIG_FILES([Makefile libweston/version.h compositor/weston.pc])
+ # libweston_abi_version here, and outside [] because of m4 quoting rules
+ AC_CONFIG_FILES([libweston/libweston-]libweston_major_version[.pc:libweston/libweston.pc.in])
+ AC_CONFIG_FILES([libweston/libweston-]libweston_major_version[-uninstalled.pc:libweston/libweston-uninstalled.pc.in])
++AC_CONFIG_FILES([libweston/libweston-]libweston_major_version[-protocols.pc:libweston/libweston-protocols.pc.in])
+ AC_CONFIG_FILES([libweston-desktop/libweston-desktop-]libweston_major_version[.pc:libweston-desktop/libweston-desktop.pc.in])
+ AC_CONFIG_FILES([libweston-desktop/libweston-desktop-]libweston_major_version[-uninstalled.pc:libweston-desktop/libweston-desktop-uninstalled.pc.in])
+
+diff --git a/libweston/libweston-protocols.pc.in b/libweston/libweston-protocols.pc.in
+new file mode 100644
+index 00000000..6547a0d5
+--- /dev/null
++++ b/libweston/libweston-protocols.pc.in
+@@ -0,0 +1,7 @@
++prefix=@prefix@
++datarootdir=@datarootdir@
++pkgdatadir=${pc_sysrootdir}@datadir@/@PACKAGE@/protocols
++
++Name: libWeston Protocols
++Description: libWeston protocol files
++Version: @WESTON_VERSION@
+diff --git a/protocol/weston-debug.xml b/protocol/weston-debug.xml
+new file mode 100644
+index 00000000..effa1a19
+--- /dev/null
++++ b/protocol/weston-debug.xml
+@@ -0,0 +1,139 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<protocol name="weston_debug">
++
++ <copyright>
++ Copyright © 2017 Pekka Paalanen pq@iki.fi
++ Copyright © 2018 Zodiac Inflight Innovations
++
++ 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.
++ </copyright>
++
++ <interface name="weston_debug_v1" version="1">
++ <description summary="weston internal debugging">
++ This is a generic debugging interface for Weston internals, the global
++ object advertized through wl_registry.
++
++ WARNING: This interface by design allows a denial-of-service attack. It
++ should not be offered in production, or proper authorization mechnisms
++ must be enforced.
++
++ The idea is for a client to provide a file descriptor that the server
++ uses for printing debug information. The server uses the file
++ descriptor in blocking writes mode, which exposes the denial-of-service
++ risk. The blocking mode is necessary to ensure all debug messages can
++ be easily printed in place. It also ensures message ordering if a
++ client subcribes to more than one debug stream.
++
++ The available debugging features depend on the server.
++
++ A debug stream can be one-shot where the server prints the requested
++ information and then closes it, or continuous where server keeps on
++ printing until the client stops it. Or anything in between.
++ </description>
++
++ <request name="destroy" type="destructor">
++ <description summary="destroy factory object">
++ Destroys the factory object, but does not affect any other objects.
++ </description>
++ </request>
++
++ <event name="available">
++ <description summary="advertise available debug scope">
++ Advertises an available debug scope which the client may be able to
++ bind to. No information is provided by the server about the content
++ contained within the debug streams provided by the scope, once a
++ client has subscribed.
++ </description>
++
++ <arg name="name" type="string" allow-null="false"
++ summary="debug stream name"/>
++ <arg name="description" type="string" allow-null="true"
++ summary="human-readable description of the debug scope"/>
++ </event>
++
++ <request name="subscribe">
++ <description summary="subscribe to a debug stream">
++ Subscribe to a named debug stream. The server will start printing
++ to the given file descriptor.
++
++ If the named debug stream is a one-shot dump, the server will send
++ weston_debug_stream_v1.complete event once all requested data has
++ been printed. Otherwise, the server will continue streaming debug
++ prints until the subscription object is destroyed.
++
++ If the debug stream name is unknown to the server, the server will
++ immediately respond with weston_debug_stream_v1.failure event.
++ </description>
++
++ <arg name="name" type="string" allow-null="false"
++ summary="debug stream name"/>
++ <arg name="streamfd" type="fd" summary="write stream file descriptor"/>
++ <arg name="stream" type="new_id" interface="weston_debug_stream_v1"
++ summary="created debug stream object"/>
++ </request>
++ </interface>
++
++ <interface name="weston_debug_stream_v1" version="1">
++ <description summary="A subscribed debug stream">
++ Represents one subscribed debug stream, created with
++ weston_debug_v1.subscribe. When the object is created, it is associated
++ with a given file descriptor. The server will continue writing to the
++ file descriptor until the object is destroyed or the server sends an
++ event through the object.
++ </description>
++
++ <request name="destroy" type="destructor">
++ <description summary="close a debug stream">
++ Destroys the object, which causes the server to stop writing into
++ and closes the associated file descriptor if it was not closed
++ already.
++
++ Use a wl_display.sync if the clients needs to guarantee the file
++ descriptor is closed before continuing.
++ </description>
++ </request>
++
++ <event name="complete">
++ <description summary="server completed the debug stream">
++ The server has successfully finished writing to and has closed the
++ associated file descriptor.
++
++ This event is delivered only for one-shot debug streams where the
++ server dumps some data and stop. This is never delivered for
++ continuous debbug streams because they by definition never complete.
++ </description>
++ </event>
++
++ <event name="failure">
++ <description summary="server cannot continue the debug stream">
++ The server has stopped writing to and has closed the
++ associated file descriptor. The data already written to the file
++ descriptor is correct, but it may be truncated.
++
++ This event may be delivered at any time and for any kind of debug
++ stream. It may be due to a failure in or shutdown of the server.
++ The message argument may provide a hint of the reason.
++ </description>
++
++ <arg name="message" type="string" allow-null="true"
++ summary="human readable reason"/>
++ </event>
++ </interface>
++</protocol>
+--
+2.16.2
+
diff --git a/bsp/meta-synopsys/recipes-graphics/wayland/weston/1006-libweston-add-weston_debug-API-and-implementation.patch b/bsp/meta-synopsys/recipes-graphics/wayland/weston/1006-libweston-add-weston_debug-API-and-implementation.patch
new file mode 100644
index 00000000..83887c66
--- /dev/null
+++ b/bsp/meta-synopsys/recipes-graphics/wayland/weston/1006-libweston-add-weston_debug-API-and-implementation.patch
@@ -0,0 +1,958 @@
+From a5630eafec4f139adf1da4a5ba54894715d7b50f Mon Sep 17 00:00:00 2001
+From: Pekka Paalanen <pq@iki.fi>
+Date: Thu, 12 Oct 2017 13:13:42 +0200
+Subject: [PATCH 06/46] libweston: add weston_debug API and implementation
+
+weston_debug is both a libweston API for relaying debugging messages,
+and the compositor-debug wayland protocol implementation for accessing those
+debug messages from a Wayland client.
+
+weston_debug_compositor_{create,destroy}() are private API, hence not
+exported.
+
+Signed-off-by: Pekka Paalanen <pq@iki.fi>
+
+append the debug scope name along with the timestamp in
+weston_debug_scope_timestamp API
+
+Signed-off-by: Maniraj Devadoss <Maniraj.Devadoss@in.bosch.com>
+Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
+
+Add explicit advertisement of debug scope names.
+
+Signed-off-by: Daniel Stone <daniels@collabora.com>
+Reviewed-by: Emre Ucan <eucan@de.adit-jv.com>
+---
+ Makefile.am | 2 +
+ libweston/compositor.c | 5 +
+ libweston/compositor.h | 9 +
+ libweston/weston-debug.c | 732 +++++++++++++++++++++++++++++++++++++++++++++++
+ libweston/weston-debug.h | 107 +++++++
+ 5 files changed, 855 insertions(+)
+ create mode 100644 libweston/weston-debug.c
+ create mode 100644 libweston/weston-debug.h
+
+diff --git a/Makefile.am b/Makefile.am
+index e38ac009..d5ed3e58 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -96,6 +96,8 @@ libweston_@LIBWESTON_MAJOR@_la_SOURCES = \
+ libweston/linux-dmabuf.h \
+ libweston/pixel-formats.c \
+ libweston/pixel-formats.h \
++ libweston/weston-debug.c \
++ libweston/weston-debug.h \
+ shared/helpers.h \
+ shared/matrix.c \
+ shared/matrix.h \
+diff --git a/libweston/compositor.c b/libweston/compositor.c
+index 9deb7817..01616550 100644
+--- a/libweston/compositor.c
++++ b/libweston/compositor.c
+@@ -6361,6 +6361,9 @@ weston_compositor_create(struct wl_display *display, void *user_data)
+ ec, bind_presentation))
+ goto fail;
+
++ if (weston_debug_compositor_create(ec) < 0)
++ goto fail;
++
+ if (weston_input_init(ec) != 0)
+ goto fail;
+
+@@ -6702,6 +6705,8 @@ weston_compositor_destroy(struct weston_compositor *compositor)
+ if (compositor->heads_changed_source)
+ wl_event_source_remove(compositor->heads_changed_source);
+
++ weston_debug_compositor_destroy(compositor);
++
+ free(compositor);
+ }
+
+diff --git a/libweston/compositor.h b/libweston/compositor.h
+index 8b7a1020..33f02b18 100644
+--- a/libweston/compositor.h
++++ b/libweston/compositor.h
+@@ -1048,6 +1048,7 @@ struct weston_touch_calibrator;
+
+ struct weston_desktop_xwayland;
+ struct weston_desktop_xwayland_interface;
++struct weston_debug_compositor;
+
+ struct weston_compositor {
+ struct wl_signal destroy_signal;
+@@ -1160,6 +1161,8 @@ struct weston_compositor {
+ weston_touch_calibration_save_func touch_calibration_save;
+ struct weston_layer calibrator_layer;
+ struct weston_touch_calibrator *touch_calibrator;
++
++ struct weston_debug_compositor *weston_debug;
+ };
+
+ struct weston_buffer {
+@@ -2318,6 +2321,12 @@ int
+ weston_compositor_enable_touch_calibrator(struct weston_compositor *compositor,
+ weston_touch_calibration_save_func save);
+
++int
++weston_debug_compositor_create(struct weston_compositor *compositor);
++
++void
++weston_debug_compositor_destroy(struct weston_compositor *compositor);
++
+ #ifdef __cplusplus
+ }
+ #endif
+diff --git a/libweston/weston-debug.c b/libweston/weston-debug.c
+new file mode 100644
+index 00000000..04895ad5
+--- /dev/null
++++ b/libweston/weston-debug.c
+@@ -0,0 +1,732 @@
++/*
++ * Copyright © 2017 Pekka Paalanen <pq@iki.fi>
++ * Copyright © 2018 Zodiac Inflight Innovations
++ *
++ * 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 "weston-debug.h"
++#include "helpers.h"
++#include "compositor.h"
++
++#include "weston-debug-server-protocol.h"
++
++#include <assert.h>
++#include <unistd.h>
++#include <stdarg.h>
++#include <string.h>
++#include <errno.h>
++#include <sys/time.h>
++
++/** Main weston-debug context
++ *
++ * One per weston_compositor.
++ *
++ * \internal
++ */
++struct weston_debug_compositor {
++ struct weston_compositor *compositor;
++ struct wl_listener compositor_destroy_listener;
++ struct wl_global *global;
++ struct wl_list scope_list; /**< weston_debug_scope::compositor_link */
++};
++
++/** weston-debug message scope
++ *
++ * This is used for scoping debugging messages. Clients can subscribe to
++ * only the scopes they are interested in. A scope is identified by its name
++ * (also referred to as debug stream name).
++ */
++struct weston_debug_scope {
++ char *name;
++ char *desc;
++ weston_debug_scope_cb begin_cb;
++ void *user_data;
++ struct wl_list stream_list; /**< weston_debug_stream::scope_link */
++ struct wl_list compositor_link;
++};
++
++/** A debug stream created by a client
++ *
++ * A client provides a file descriptor for the server to write debug
++ * messages into. A weston_debug_stream is associated to one
++ * weston_debug_scope via the scope name, and the scope provides the messages.
++ * There can be several streams for the same scope, all streams getting the
++ * same messages.
++ */
++struct weston_debug_stream {
++ int fd; /**< client provided fd */
++ struct wl_resource *resource; /**< weston_debug_stream_v1 object */
++ struct wl_list scope_link;
++};
++
++static struct weston_debug_scope *
++get_scope(struct weston_debug_compositor *wdc, const char *name)
++{
++ struct weston_debug_scope *scope;
++
++ wl_list_for_each(scope, &wdc->scope_list, compositor_link)
++ if (strcmp(name, scope->name) == 0)
++ return scope;
++
++ return NULL;
++}
++
++static void
++stream_close_unlink(struct weston_debug_stream *stream)
++{
++ if (stream->fd != -1)
++ close(stream->fd);
++ stream->fd = -1;
++
++ wl_list_remove(&stream->scope_link);
++ wl_list_init(&stream->scope_link);
++}
++
++static void WL_PRINTF(2, 3)
++stream_close_on_failure(struct weston_debug_stream *stream,
++ const char *fmt, ...)
++{
++ char *msg;
++ va_list ap;
++ int ret;
++
++ stream_close_unlink(stream);
++
++ va_start(ap, fmt);
++ ret = vasprintf(&msg, fmt, ap);
++ va_end(ap);
++
++ if (ret > 0) {
++ weston_debug_stream_v1_send_failure(stream->resource, msg);
++ free(msg);
++ } else {
++ weston_debug_stream_v1_send_failure(stream->resource,
++ "MEMFAIL");
++ }
++}
++
++static struct weston_debug_stream *
++stream_create(struct weston_debug_compositor *wdc, const char *name,
++ int32_t streamfd, struct wl_resource *stream_resource)
++{
++ struct weston_debug_stream *stream;
++ struct weston_debug_scope *scope;
++
++ stream = zalloc(sizeof *stream);
++ if (!stream)
++ return NULL;
++
++ stream->fd = streamfd;
++ stream->resource = stream_resource;
++
++ scope = get_scope(wdc, name);
++ if (scope) {
++ wl_list_insert(&scope->stream_list, &stream->scope_link);
++
++ if (scope->begin_cb)
++ scope->begin_cb(stream, scope->user_data);
++ } else {
++ wl_list_init(&stream->scope_link);
++ stream_close_on_failure(stream,
++ "Debug stream name '%s' is unknown.",
++ name);
++ }
++
++ return stream;
++}
++
++static void
++stream_destroy(struct wl_resource *stream_resource)
++{
++ struct weston_debug_stream *stream;
++
++ stream = wl_resource_get_user_data(stream_resource);
++
++ if (stream->fd != -1)
++ close(stream->fd);
++ wl_list_remove(&stream->scope_link);
++ free(stream);
++}
++
++static void
++weston_debug_stream_destroy(struct wl_client *client,
++ struct wl_resource *stream_resource)
++{
++ wl_resource_destroy(stream_resource);
++}
++
++static const struct weston_debug_stream_v1_interface
++ weston_debug_stream_impl = {
++ weston_debug_stream_destroy
++};
++
++static void
++weston_debug_destroy(struct wl_client *client,
++ struct wl_resource *global_resource)
++{
++ wl_resource_destroy(global_resource);
++}
++
++static void
++weston_debug_subscribe(struct wl_client *client,
++ struct wl_resource *global_resource,
++ const char *name,
++ int32_t streamfd,
++ uint32_t new_stream_id)
++{
++ struct weston_debug_compositor *wdc;
++ struct wl_resource *stream_resource;
++ uint32_t version;
++ struct weston_debug_stream *stream;
++
++ wdc = wl_resource_get_user_data(global_resource);
++ version = wl_resource_get_version(global_resource);
++
++ stream_resource = wl_resource_create(client,
++ &weston_debug_stream_v1_interface,
++ version, new_stream_id);
++ if (!stream_resource)
++ goto fail;
++
++ stream = stream_create(wdc, name, streamfd, stream_resource);
++ if (!stream)
++ goto fail;
++
++ wl_resource_set_implementation(stream_resource,
++ &weston_debug_stream_impl,
++ stream, stream_destroy);
++ return;
++
++fail:
++ close(streamfd);
++ wl_client_post_no_memory(client);
++}
++
++static const struct weston_debug_v1_interface weston_debug_impl = {
++ weston_debug_destroy,
++ weston_debug_subscribe
++};
++
++static void
++bind_weston_debug(struct wl_client *client,
++ void *data, uint32_t version, uint32_t id)
++{
++ struct weston_debug_compositor *wdc = data;
++ struct weston_debug_scope *scope;
++ struct wl_resource *resource;
++
++ resource = wl_resource_create(client,
++ &weston_debug_v1_interface,
++ version, id);
++ if (!resource) {
++ wl_client_post_no_memory(client);
++ return;
++ }
++ wl_resource_set_implementation(resource, &weston_debug_impl,
++ wdc, NULL);
++
++ wl_list_for_each(scope, &wdc->scope_list, compositor_link) {
++ weston_debug_v1_send_available(resource, scope->name,
++ scope->desc);
++ }
++}
++
++/** Initialize weston-debug structure
++ *
++ * \param compositor The libweston compositor.
++ * \return 0 on success, -1 on failure.
++ *
++ * weston_debug_compositor is a singleton for each weston_compositor.
++ *
++ * Sets weston_compositor::weston_debug.
++ *
++ * \internal
++ */
++int
++weston_debug_compositor_create(struct weston_compositor *compositor)
++{
++ struct weston_debug_compositor *wdc;
++
++ if (compositor->weston_debug)
++ return -1;
++
++ wdc = zalloc(sizeof *wdc);
++ if (!wdc)
++ return -1;
++
++ wdc->compositor = compositor;
++ wl_list_init(&wdc->scope_list);
++
++ compositor->weston_debug = wdc;
++
++ return 0;
++}
++
++/** Destroy weston_debug_compositor structure
++ *
++ * \param compositor The libweston compositor whose weston-debug to tear down.
++ *
++ * Clears weston_compositor::weston_debug.
++ *
++ * \internal
++ */
++void
++weston_debug_compositor_destroy(struct weston_compositor *compositor)
++{
++ struct weston_debug_compositor *wdc = compositor->weston_debug;
++ struct weston_debug_scope *scope;
++
++ if (wdc->global)
++ wl_global_destroy(wdc->global);
++
++ wl_list_for_each(scope, &wdc->scope_list, compositor_link)
++ weston_log("Internal warning: debug scope '%s' has not been destroyed.\n",
++ scope->name);
++
++ /* Remove head to not crash if scope removed later. */
++ wl_list_remove(&wdc->scope_list);
++
++ free(wdc);
++
++ compositor->weston_debug = NULL;
++}
++
++/** Enable weston-debug protocol extension
++ *
++ * \param compositor The libweston compositor where to enable.
++ *
++ * This enables the weston_debug_v1 Wayland protocol extension which any client
++ * can use to get debug messsages from the compositor.
++ *
++ * WARNING: This feature should not be used in production. If a client
++ * provides a file descriptor that blocks writes, it will block the whole
++ * compositor indefinitely.
++ *
++ * There is no control on which client is allowed to subscribe to debug
++ * messages. Any and all clients are allowed.
++ *
++ * The debug extension is disabled by default, and once enabled, cannot be
++ * disabled again.
++ */
++WL_EXPORT void
++weston_compositor_enable_debug_protocol(struct weston_compositor *compositor)
++{
++ struct weston_debug_compositor *wdc = compositor->weston_debug;
++
++ assert(wdc);
++ if (wdc->global)
++ return;
++
++ wdc->global = wl_global_create(compositor->wl_display,
++ &weston_debug_v1_interface, 1,
++ wdc, bind_weston_debug);
++ if (!wdc->global)
++ return;
++
++ weston_log("WARNING: debug protocol has been enabled. "
++ "This is a potential denial-of-service attack vector and "
++ "information leak.\n");
++}
++
++/** Register a new debug stream name, creating a debug scope
++ *
++ * \param compositor The libweston compositor where to add.
++ * \param name The debug stream/scope name; must not be NULL.
++ * \param desc The debug scope description for humans; must not be NULL.
++ * \param begin_cb Optional callback when a client subscribes to this scope.
++ * \param user_data Optional user data pointer for the callback.
++ * \return A valid pointer on success, NULL on failure.
++ *
++ * This function is used to create a debug scope. All debug message printing
++ * happens for a scope, which allows clients to subscribe to the kind of
++ * debug messages they want by \c name.
++ *
++ * \c name must be unique in the \c weston_compositor instance. \c name and
++ * \c description must both be provided. The description is printed when a
++ * client asks for a list of supported debug scopes.
++ *
++ * \c begin_cb, if not NULL, is called when a client subscribes to the
++ * debug scope creating a debug stream. This is for debug scopes that need
++ * to print messages as a response to a client appearing, e.g. printing a
++ * list of windows on demand or a static preamble. The argument \c user_data
++ * is passed in to the callback and is otherwise unused.
++ *
++ * For one-shot debug streams, \c begin_cb should finally call
++ * weston_debug_stream_complete() to close the stream and tell the client
++ * the printing is complete. Otherwise the client expects more to be written
++ * to its file descriptor.
++ *
++ * The debug scope must be destroyed before destroying the
++ * \c weston_compositor.
++ *
++ * \memberof weston_debug_scope
++ * \sa weston_debug_stream, weston_debug_scope_cb
++ */
++WL_EXPORT struct weston_debug_scope *
++weston_compositor_add_debug_scope(struct weston_compositor *compositor,
++ const char *name,
++ const char *description,
++ weston_debug_scope_cb begin_cb,
++ void *user_data)
++{
++ struct weston_debug_compositor *wdc;
++ struct weston_debug_scope *scope;
++
++ if (!compositor || !name || !description) {
++ weston_log("Error: cannot add a debug scope without name or description.\n");
++ return NULL;
++ }
++
++ wdc = compositor->weston_debug;
++ if (!wdc) {
++ weston_log("Error: cannot add debug scope '%s', infra not initialized.\n",
++ name);
++ return NULL;
++ }
++
++ if (get_scope(wdc, name)){
++ weston_log("Error: debug scope named '%s' is already registered.\n",
++ name);
++ return NULL;
++ }
++
++ scope = zalloc(sizeof *scope);
++ if (!scope) {
++ weston_log("Error adding debug scope '%s': out of memory.\n",
++ name);
++ return NULL;
++ }
++
++ scope->name = strdup(name);
++ scope->desc = strdup(description);
++ scope->begin_cb = begin_cb;
++ scope->user_data = user_data;
++ wl_list_init(&scope->stream_list);
++
++ if (!scope->name || !scope->desc) {
++ weston_log("Error adding debug scope '%s': out of memory.\n",
++ name);
++ free(scope->name);
++ free(scope->desc);
++ free(scope);
++ return NULL;
++ }
++
++ wl_list_insert(wdc->scope_list.prev, &scope->compositor_link);
++
++ return scope;
++}
++
++/** Destroy a debug scope
++ *
++ * \param scope The debug scope to destroy; may be NULL.
++ *
++ * Destroys the debug scope, closing all open streams subscribed to it and
++ * sending them each a \c weston_debug_stream_v1.failure event.
++ *
++ * \memberof weston_debug_scope
++ */
++WL_EXPORT void
++weston_debug_scope_destroy(struct weston_debug_scope *scope)
++{
++ struct weston_debug_stream *stream;
++
++ if (!scope)
++ return;
++
++ while (!wl_list_empty(&scope->stream_list)) {
++ stream = wl_container_of(scope->stream_list.prev,
++ stream, scope_link);
++
++ stream_close_on_failure(stream, "debug name removed");
++ }
++
++ wl_list_remove(&scope->compositor_link);
++ free(scope->name);
++ free(scope->desc);
++ free(scope);
++}
++
++/** Are there any active subscriptions to the scope?
++ *
++ * \param scope The debug scope to check; may be NULL.
++ * \return True if any streams are open for this scope, false otherwise.
++ *
++ * As printing some debugging messages may be relatively expensive, one
++ * can use this function to determine if there is a need to gather the
++ * debugging information at all. If this function returns false, all
++ * printing for this scope is dropped, so gathering the information is
++ * pointless.
++ *
++ * The return value of this function should not be stored, as new clients
++ * may subscribe to the debug scope later.
++ *
++ * If the given scope is NULL, this function will always return false,
++ * making it safe to use in teardown or destroy code, provided the
++ * scope is initialized to NULL before creation and set to NULL after
++ * destruction.
++ *
++ * \memberof weston_debug_scope
++ */
++WL_EXPORT bool
++weston_debug_scope_is_enabled(struct weston_debug_scope *scope)
++{
++ if (!scope)
++ return false;
++
++ return !wl_list_empty(&scope->stream_list);
++}
++
++/** Write data into a specific debug stream
++ *
++ * \param stream The debug stream to write into; must not be NULL.
++ * \param data[in] Pointer to the data to write.
++ * \param len Number of bytes to write.
++ *
++ * Writes the given data (binary verbatim) into the debug stream.
++ * If \c len is zero or negative, the write is silently dropped.
++ *
++ * Writing is continued until all data has been written or
++ * a write fails. If the write fails due to a signal, it is re-tried.
++ * Otherwise on failure, the stream is closed and
++ * \c weston_debug_stream_v1.failure event is sent to the client.
++ *
++ * \memberof weston_debug_stream
++ */
++WL_EXPORT void
++weston_debug_stream_write(struct weston_debug_stream *stream,
++ const char *data, size_t len)
++{
++ ssize_t len_ = len;
++ ssize_t ret;
++ int e;
++
++ if (stream->fd == -1)
++ return;
++
++ while (len_ > 0) {
++ ret = write(stream->fd, data, len_);
++ e = errno;
++ if (ret < 0) {
++ if (e == EINTR)
++ continue;
++
++ stream_close_on_failure(stream,
++ "Error writing %zd bytes: %s (%d)",
++ len_, strerror(e), e);
++ break;
++ }
++
++ len_ -= ret;
++ data += ret;
++ }
++}
++
++/** Write a formatted string into a specific debug stream (varargs)
++ *
++ * \param stream The debug stream to write into.
++ * \param fmt Printf-style format string.
++ * \param ap Formatting arguments.
++ *
++ * The behavioral details are the same as for weston_debug_stream_write().
++ *
++ * \memberof weston_debug_stream
++ */
++WL_EXPORT void
++weston_debug_stream_vprintf(struct weston_debug_stream *stream,
++ const char *fmt, va_list ap)
++{
++ char *str;
++ int len;
++
++ len = vasprintf(&str, fmt, ap);
++ if (len >= 0) {
++ weston_debug_stream_write(stream, str, len);
++ free(str);
++ } else {
++ stream_close_on_failure(stream, "Out of memory");
++ }
++}
++
++/** Write a formatted string into a specific debug stream
++ *
++ * \param stream The debug stream to write into.
++ * \param fmt Printf-style format string and arguments.
++ *
++ * The behavioral details are the same as for weston_debug_stream_write().
++ *
++ * \memberof weston_debug_stream
++ */
++WL_EXPORT void
++weston_debug_stream_printf(struct weston_debug_stream *stream,
++ const char *fmt, ...)
++{
++ va_list ap;
++
++ va_start(ap, fmt);
++ weston_debug_stream_vprintf(stream, fmt, ap);
++ va_end(ap);
++}
++
++/** Close the debug stream and send success event
++ *
++ * \param stream The debug stream to close.
++ *
++ * Closes the debug stream and sends \c weston_debug_stream_v1.complete
++ * event to the client. This tells the client the debug information dump
++ * is complete.
++ *
++ * \memberof weston_debug_stream
++ */
++WL_EXPORT void
++weston_debug_stream_complete(struct weston_debug_stream *stream)
++{
++ stream_close_unlink(stream);
++ weston_debug_stream_v1_send_complete(stream->resource);
++}
++
++/** Write debug data for a scope
++ *
++ * \param scope The debug scope to write for; may be NULL, in which case
++ * nothing will be written.
++ * \param data[in] Pointer to the data to write.
++ * \param len Number of bytes to write.
++ *
++ * Writes the given data to all subscribed clients' streams.
++ *
++ * The behavioral details for each stream are the same as for
++ * weston_debug_stream_write().
++ *
++ * \memberof weston_debug_scope
++ */
++WL_EXPORT void
++weston_debug_scope_write(struct weston_debug_scope *scope,
++ const char *data, size_t len)
++{
++ struct weston_debug_stream *stream;
++
++ if (!scope)
++ return;
++
++ wl_list_for_each(stream, &scope->stream_list, scope_link)
++ weston_debug_stream_write(stream, data, len);
++}
++
++/** Write a formatted string for a scope (varargs)
++ *
++ * \param scope The debug scope to write for; may be NULL, in which case
++ * nothing will be written.
++ * \param fmt Printf-style format string.
++ * \param ap Formatting arguments.
++ *
++ * Writes to formatted string to all subscribed clients' streams.
++ *
++ * The behavioral details for each stream are the same as for
++ * weston_debug_stream_write().
++ *
++ * \memberof weston_debug_scope
++ */
++WL_EXPORT void
++weston_debug_scope_vprintf(struct weston_debug_scope *scope,
++ const char *fmt, va_list ap)
++{
++ static const char oom[] = "Out of memory";
++ char *str;
++ int len;
++
++ if (!weston_debug_scope_is_enabled(scope))
++ return;
++
++ len = vasprintf(&str, fmt, ap);
++ if (len >= 0) {
++ weston_debug_scope_write(scope, str, len);
++ free(str);
++ } else {
++ weston_debug_scope_write(scope, oom, sizeof oom - 1);
++ }
++}
++
++/** Write a formatted string for a scope
++ *
++ * \param scope The debug scope to write for; may be NULL, in which case
++ * nothing will be written.
++ * \param fmt Printf-style format string and arguments.
++ *
++ * Writes to formatted string to all subscribed clients' streams.
++ *
++ * The behavioral details for each stream are the same as for
++ * weston_debug_stream_write().
++ *
++ * \memberof weston_debug_scope
++ */
++WL_EXPORT void
++weston_debug_scope_printf(struct weston_debug_scope *scope,
++ const char *fmt, ...)
++{
++ va_list ap;
++
++ va_start(ap, fmt);
++ weston_debug_scope_vprintf(scope, fmt, ap);
++ va_end(ap);
++}
++
++/** Write debug scope name and current time into string
++ *
++ * \param scope[in] debug scope; may be NULL
++ * \param buf[out] Buffer to store the string.
++ * \param len Available size in the buffer in bytes.
++ * \return \c buf
++ *
++ * Reads the current local wall-clock time and formats it into a string.
++ * and append the debug scope name to it, if a scope is available.
++ * The string is NUL-terminated, even if truncated.
++ */
++WL_EXPORT char *
++weston_debug_scope_timestamp(struct weston_debug_scope *scope,
++ char *buf, size_t len)
++{
++ struct timeval tv;
++ struct tm *bdt;
++ char string[128];
++ size_t ret = 0;
++
++ gettimeofday(&tv, NULL);
++
++ bdt = localtime(&tv.tv_sec);
++ if (bdt)
++ ret = strftime(string, sizeof string,
++ "%Y-%m-%d %H:%M:%S", bdt);
++
++ if (ret > 0) {
++ snprintf(buf, len, "[%s.%03ld][%s]", string,
++ tv.tv_usec / 1000,
++ (scope) ? scope->name : "no scope");
++ } else {
++ snprintf(buf, len, "[?][%s]",
++ (scope) ? scope->name : "no scope");
++ }
++
++ return buf;
++}
+diff --git a/libweston/weston-debug.h b/libweston/weston-debug.h
+new file mode 100644
+index 00000000..c76cec85
+--- /dev/null
++++ b/libweston/weston-debug.h
+@@ -0,0 +1,107 @@
++/*
++ * Copyright © 2017 Pekka Paalanen <pq@iki.fi>
++ *
++ * 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.
++ */
++
++#ifndef WESTON_DEBUG_H
++#define WESTON_DEBUG_H
++
++#include <stdbool.h>
++#include <stdlib.h>
++#include <stdarg.h>
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++struct weston_compositor;
++
++void
++weston_compositor_enable_debug_protocol(struct weston_compositor *);
++
++struct weston_debug_scope;
++struct weston_debug_stream;
++
++/** weston_debug_scope callback
++ *
++ * \param stream The debug stream.
++ * \param user_data The \c user_data argument given to
++ * weston_compositor_add_debug_scope()
++ *
++ * \memberof weston_debug_scope
++ * \sa weston_debug_stream
++ */
++typedef void (*weston_debug_scope_cb)(struct weston_debug_stream *stream,
++ void *user_data);
++
++struct weston_debug_scope *
++weston_compositor_add_debug_scope(struct weston_compositor *compositor,
++ const char *name,
++ const char *description,
++ weston_debug_scope_cb begin_cb,
++ void *user_data);
++
++void
++weston_debug_scope_destroy(struct weston_debug_scope *scope);
++
++bool
++weston_debug_scope_is_enabled(struct weston_debug_scope *scope);
++
++void
++weston_debug_scope_write(struct weston_debug_scope *scope,
++ const char *data, size_t len);
++
++void
++weston_debug_scope_vprintf(struct weston_debug_scope *scope,
++ const char *fmt, va_list ap);
++
++void
++weston_debug_scope_printf(struct weston_debug_scope *scope,
++ const char *fmt, ...)
++ __attribute__ ((format (printf, 2, 3)));
++
++void
++weston_debug_stream_write(struct weston_debug_stream *stream,
++ const char *data, size_t len);
++
++void
++weston_debug_stream_vprintf(struct weston_debug_stream *stream,
++ const char *fmt, va_list ap);
++
++void
++weston_debug_stream_printf(struct weston_debug_stream *stream,
++ const char *fmt, ...)
++ __attribute__ ((format (printf, 2, 3)));
++
++void
++weston_debug_stream_complete(struct weston_debug_stream *stream);
++
++char *
++weston_debug_scope_timestamp(struct weston_debug_scope *scope,
++ char *buf, size_t len);
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* WESTON_DEBUG_H */
+--
+2.16.2
+
diff --git a/bsp/meta-synopsys/recipes-graphics/wayland/weston/1007-compositor-add-option-to-enable-weston_debug.patch b/bsp/meta-synopsys/recipes-graphics/wayland/weston/1007-compositor-add-option-to-enable-weston_debug.patch
new file mode 100644
index 00000000..34422850
--- /dev/null
+++ b/bsp/meta-synopsys/recipes-graphics/wayland/weston/1007-compositor-add-option-to-enable-weston_debug.patch
@@ -0,0 +1,87 @@
+From 771b7cfc11cec3638b0a4f47edeeaabe2ba46cb6 Mon Sep 17 00:00:00 2001
+From: Pekka Paalanen <pq@iki.fi>
+Date: Thu, 12 Oct 2017 13:13:43 +0200
+Subject: [PATCH 07/46] compositor: add option to enable weston_debug
+
+Let users enable the compositor debug protocol on the compositor command
+line. This allows weston-debug tool to work.
+
+Signed-off-by: Pekka Paalanen <pq@iki.fi>
+Signed-off-by: Maniraj Devadoss <Maniraj.Devadoss@in.bosch.com>
+Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
+---
+ compositor/main.c | 7 +++++++
+ man/weston.man | 11 +++++++++++
+ 2 files changed, 18 insertions(+)
+
+diff --git a/compositor/main.c b/compositor/main.c
+index b5b4fc59..2f34e111 100644
+--- a/compositor/main.c
++++ b/compositor/main.c
+@@ -60,6 +60,7 @@
+ #include "compositor-x11.h"
+ #include "compositor-wayland.h"
+ #include "windowed-output-api.h"
++#include "weston-debug.h"
+
+ #define WINDOW_TITLE "Weston Compositor"
+
+@@ -508,6 +509,7 @@ usage(int error_code)
+ " -c, --config=FILE\tConfig file to load, defaults to weston.ini\n"
+ " --no-config\t\tDo not read weston.ini\n"
+ " --wait-for-debugger\tRaise SIGSTOP on start-up\n"
++ " --debug\t\tEnable debug extension\n"
+ " -h, --help\t\tThis help message\n\n");
+
+ #if defined(BUILD_DRM_COMPOSITOR)
+@@ -2375,6 +2377,7 @@ int main(int argc, char *argv[])
+ char *socket_name = NULL;
+ int32_t version = 0;
+ int32_t noconfig = 0;
++ int32_t debug_protocol = 0;
+ int32_t numlock_on;
+ char *config_file = NULL;
+ struct weston_config *config = NULL;
+@@ -2399,6 +2402,7 @@ int main(int argc, char *argv[])
+ { WESTON_OPTION_BOOLEAN, "no-config", 0, &noconfig },
+ { WESTON_OPTION_STRING, "config", 'c', &config_file },
+ { WESTON_OPTION_BOOLEAN, "wait-for-debugger", 0, &wait_for_debugger },
++ { WESTON_OPTION_BOOLEAN, "debug", 0, &debug_protocol },
+ };
+
+ wl_list_init(&wet.layoutput_list);
+@@ -2486,6 +2490,9 @@ int main(int argc, char *argv[])
+ }
+ segv_compositor = wet.compositor;
+
++ if (debug_protocol)
++ weston_compositor_enable_debug_protocol(wet.compositor);
++
+ if (weston_compositor_init_config(wet.compositor, config) < 0)
+ goto out;
+
+diff --git a/man/weston.man b/man/weston.man
+index 44a73fa0..c09d4c2d 100644
+--- a/man/weston.man
++++ b/man/weston.man
+@@ -133,6 +133,17 @@ If also
+ .B --no-config
+ is given, no configuration file will be read.
+ .TP
++.BR \-\-debug
++Enable debug protocol extension
++.I weston_debug_v1
++which any client can use to receive debugging messages from the compositor.
++
++.B WARNING:
++This is risky for two reasons. First, a client may cause a denial-of-service
++blocking the compositor by providing an unsuitable file descriptor, and
++second, the debug messages may expose sensitive information. This option
++should not be used in production.
++.TP
+ .BR \-\-version
+ Print the program version.
+ .TP
+--
+2.16.2
+
diff --git a/bsp/meta-synopsys/recipes-graphics/wayland/weston/1010-xwm-dump_property-to-use-FILE-internally.patch b/bsp/meta-synopsys/recipes-graphics/wayland/weston/1010-xwm-dump_property-to-use-FILE-internally.patch
new file mode 100644
index 00000000..e9e46002
--- /dev/null
+++ b/bsp/meta-synopsys/recipes-graphics/wayland/weston/1010-xwm-dump_property-to-use-FILE-internally.patch
@@ -0,0 +1,141 @@
+From 0a3ef9902a210ab1fa0e4ed317ad7782f0399b51 Mon Sep 17 00:00:00 2001
+From: Pekka Paalanen <pq@iki.fi>
+Date: Thu, 12 Oct 2017 13:18:12 +0200
+Subject: [PATCH 10/46] xwm: dump_property() to use FILE internally
+
+Write the output of dump_property() out in one log call. When multiple
+processes (weston and Xwayland) are writing to the same file, this will
+keep the property dump uninterrupted by Xwayland debug prints.
+
+This is also preparation for more development in the same direction.
+
+Signed-off-by: Pekka Paalanen <pq@iki.fi>
+Signed-off-by: Maniraj Devadoss <Maniraj.Devadoss@in.bosch.com>
+Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
+Reviewed-by: Daniel Stone <daniels@collabora.com>
+---
+ xwayland/window-manager.c | 58 ++++++++++++++++++++++++-----------------------
+ 1 file changed, 30 insertions(+), 28 deletions(-)
+
+diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
+index 2b3defb7..3bf323a4 100644
+--- a/xwayland/window-manager.c
++++ b/xwayland/window-manager.c
+@@ -410,20 +410,14 @@ dump_cardinal_array_elem(FILE *fp, unsigned format,
+ }
+
+ static void
+-dump_cardinal_array(xcb_get_property_reply_t *reply)
++dump_cardinal_array(FILE *fp, xcb_get_property_reply_t *reply)
+ {
+ unsigned i = 0;
+- FILE *fp;
+ void *arr;
+ char *str = NULL;
+- size_t size = 0;
+
+ assert(reply->type == XCB_ATOM_CARDINAL);
+
+- fp = open_memstream(&str, &size);
+- if (!fp)
+- return;
+-
+ arr = xcb_get_property_value(reply);
+
+ fprintf(fp, "[");
+@@ -432,10 +426,6 @@ dump_cardinal_array(xcb_get_property_reply_t *reply)
+ arr, reply->value_len, i);
+ fprintf(fp, "]");
+
+- if (fclose(fp) != 0)
+- return;
+-
+- wm_log_continue("%s\n", str);
+ free(str);
+ }
+
+@@ -449,22 +439,29 @@ dump_property(struct weston_wm *wm,
+ xcb_window_t *window_value;
+ int width, len;
+ uint32_t i;
++ FILE *fp;
++ char *logstr;
++ size_t logsize;
+
+- width = wm_log_continue("%s: ", get_atom_name(wm->conn, property));
+- if (reply == NULL) {
+- wm_log_continue("(no reply)\n");
++ fp = open_memstream(&logstr, &logsize);
++ if (!fp)
+ return;
++
++ width = fprintf(fp, "%s: ", get_atom_name(wm->conn, property));
++ if (reply == NULL) {
++ fprintf(fp, "(no reply)\n");
++ goto out;
+ }
+
+- width += wm_log_continue("%s/%d, length %d (value_len %d): ",
+- get_atom_name(wm->conn, reply->type),
+- reply->format,
+- xcb_get_property_value_length(reply),
+- reply->value_len);
++ width += fprintf(fp, "%s/%d, length %d (value_len %d): ",
++ get_atom_name(wm->conn, reply->type),
++ reply->format,
++ xcb_get_property_value_length(reply),
++ reply->value_len);
+
+ if (reply->type == wm->atom.incr) {
+ incr_value = xcb_get_property_value(reply);
+- wm_log_continue("%d\n", *incr_value);
++ fprintf(fp, "%d\n", *incr_value);
+ } else if (reply->type == wm->atom.utf8_string ||
+ reply->type == wm->atom.string) {
+ text_value = xcb_get_property_value(reply);
+@@ -472,29 +469,34 @@ dump_property(struct weston_wm *wm,
+ len = 40;
+ else
+ len = reply->value_len;
+- wm_log_continue("\"%.*s\"\n", len, text_value);
++ fprintf(fp, "\"%.*s\"\n", len, text_value);
+ } else if (reply->type == XCB_ATOM_ATOM) {
+ atom_value = xcb_get_property_value(reply);
+ for (i = 0; i < reply->value_len; i++) {
+ name = get_atom_name(wm->conn, atom_value[i]);
+ if (width + strlen(name) + 2 > 78) {
+- wm_log_continue("\n ");
++ fprintf(fp, "\n ");
+ width = 4;
+ } else if (i > 0) {
+- width += wm_log_continue(", ");
++ width += fprintf(fp, ", ");
+ }
+
+- width += wm_log_continue("%s", name);
++ width += fprintf(fp, "%s", name);
+ }
+- wm_log_continue("\n");
++ fprintf(fp, "\n");
+ } else if (reply->type == XCB_ATOM_CARDINAL) {
+- dump_cardinal_array(reply);
++ dump_cardinal_array(fp, reply);
+ } else if (reply->type == XCB_ATOM_WINDOW && reply->format == 32) {
+ window_value = xcb_get_property_value(reply);
+- wm_log_continue("win %u\n", *window_value);
++ fprintf(fp, "win %u\n", *window_value);
+ } else {
+- wm_log_continue("huh?\n");
++ fprintf(fp, "huh?\n");
+ }
++
++out:
++ if (fclose(fp) == 0)
++ wm_log_continue("%s", logstr);
++ free(logstr);
+ }
+
+ static void
+--
+2.16.2
+
diff --git a/bsp/meta-synopsys/recipes-graphics/wayland/weston/1011-xwm-move-FILE-to-the-callers-of-dump_property.patch b/bsp/meta-synopsys/recipes-graphics/wayland/weston/1011-xwm-move-FILE-to-the-callers-of-dump_property.patch
new file mode 100644
index 00000000..693bff29
--- /dev/null
+++ b/bsp/meta-synopsys/recipes-graphics/wayland/weston/1011-xwm-move-FILE-to-the-callers-of-dump_property.patch
@@ -0,0 +1,267 @@
+From b3b006559856037ab97200b93641640b88ec7db8 Mon Sep 17 00:00:00 2001
+From: Pekka Paalanen <pq@iki.fi>
+Date: Thu, 12 Oct 2017 13:18:13 +0200
+Subject: [PATCH 11/46] xwm: move FILE to the callers of dump_property()
+
+This is preparation for using the weston-debug infrastructure for
+WM_DEBUG. dump_property() may be called from different debugging
+contexts and often needs to be prefixed with more information.
+
+An alternative to this patch would be to pass in the weston_debug_scope
+as an argument to dump_property(), but then all callers would need to be
+converted to weston-debug infra in a single commit.
+
+Therefore require the callers to provide the FILE* to print to.
+
+Signed-off-by: Pekka Paalanen <pq@iki.fi>
+Signed-off-by: Maniraj Devadoss <Maniraj.Devadoss@in.bosch.com>
+Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
+Reviewed-by: Daniel Stone <daniels@collabora.com>
+---
+ xwayland/selection.c | 39 ++++++++++++++++++++++++---
+ xwayland/window-manager.c | 67 +++++++++++++++++++----------------------------
+ xwayland/xwayland.h | 3 ++-
+ 3 files changed, 65 insertions(+), 44 deletions(-)
+
+diff --git a/xwayland/selection.c b/xwayland/selection.c
+index 59702246..e0eb3ffc 100644
+--- a/xwayland/selection.c
++++ b/xwayland/selection.c
+@@ -34,6 +34,12 @@
+ #include "xwayland.h"
+ #include "shared/helpers.h"
+
++#ifdef WM_DEBUG
++#define wm_log(...) weston_log(__VA_ARGS__)
++#else
++#define wm_log(...) do {} while (0)
++#endif
++
+ static int
+ writable_callback(int fd, uint32_t mask, void *data)
+ {
+@@ -102,6 +108,9 @@ weston_wm_get_incr_chunk(struct weston_wm *wm)
+ {
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
++ FILE *fp;
++ char *logstr;
++ size_t logsize;
+
+ cookie = xcb_get_property(wm->conn,
+ 0, /* delete */
+@@ -115,7 +124,13 @@ weston_wm_get_incr_chunk(struct weston_wm *wm)
+ if (reply == NULL)
+ return;
+
+- dump_property(wm, wm->atom.wl_selection, reply);
++ fp = open_memstream(&logstr, &logsize);
++ if (fp) {
++ dump_property(fp, wm, wm->atom.wl_selection, reply);
++ if (fclose(fp) == 0)
++ wm_log("%s", logstr);
++ free(logstr);
++ }
+
+ if (xcb_get_property_value_length(reply) > 0) {
+ /* reply's ownership is transferred to wm, which is responsible
+@@ -178,6 +193,9 @@ weston_wm_get_selection_targets(struct weston_wm *wm)
+ xcb_atom_t *value;
+ char **p;
+ uint32_t i;
++ FILE *fp;
++ char *logstr;
++ size_t logsize;
+
+ cookie = xcb_get_property(wm->conn,
+ 1, /* delete */
+@@ -191,7 +209,13 @@ weston_wm_get_selection_targets(struct weston_wm *wm)
+ if (reply == NULL)
+ return;
+
+- dump_property(wm, wm->atom.wl_selection, reply);
++ fp = open_memstream(&logstr, &logsize);
++ if (fp) {
++ dump_property(fp, wm, wm->atom.wl_selection, reply);
++ if (fclose(fp) == 0)
++ wm_log("%s", logstr);
++ free(logstr);
++ }
+
+ if (reply->type != XCB_ATOM_ATOM) {
+ free(reply);
+@@ -232,6 +256,9 @@ weston_wm_get_selection_data(struct weston_wm *wm)
+ {
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
++ FILE *fp;
++ char *logstr;
++ size_t logsize;
+
+ cookie = xcb_get_property(wm->conn,
+ 1, /* delete */
+@@ -243,7 +270,13 @@ weston_wm_get_selection_data(struct weston_wm *wm)
+
+ reply = xcb_get_property_reply(wm->conn, cookie, NULL);
+
+- dump_property(wm, wm->atom.wl_selection, reply);
++ fp = open_memstream(&logstr, &logsize);
++ if (fp) {
++ dump_property(fp, wm, wm->atom.wl_selection, reply);
++ if (fclose(fp) == 0)
++ wm_log("%s", logstr);
++ free(logstr);
++ }
+
+ if (reply == NULL) {
+ return;
+diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
+index 3bf323a4..4a26f6e7 100644
+--- a/xwayland/window-manager.c
++++ b/xwayland/window-manager.c
+@@ -210,23 +210,6 @@ wm_log(const char *fmt, ...)
+ #endif
+ }
+
+-static int __attribute__ ((format (printf, 1, 2)))
+-wm_log_continue(const char *fmt, ...)
+-{
+-#ifdef WM_DEBUG
+- int l;
+- va_list argp;
+-
+- va_start(argp, fmt);
+- l = weston_vlog_continue(fmt, argp);
+- va_end(argp);
+-
+- return l;
+-#else
+- return 0;
+-#endif
+-}
+-
+ static void
+ weston_output_weak_ref_init(struct weston_output_weak_ref *ref)
+ {
+@@ -430,7 +413,7 @@ dump_cardinal_array(FILE *fp, xcb_get_property_reply_t *reply)
+ }
+
+ void
+-dump_property(struct weston_wm *wm,
++dump_property(FILE *fp, struct weston_wm *wm,
+ xcb_atom_t property, xcb_get_property_reply_t *reply)
+ {
+ int32_t *incr_value;
+@@ -439,18 +422,11 @@ dump_property(struct weston_wm *wm,
+ xcb_window_t *window_value;
+ int width, len;
+ uint32_t i;
+- FILE *fp;
+- char *logstr;
+- size_t logsize;
+-
+- fp = open_memstream(&logstr, &logsize);
+- if (!fp)
+- return;
+
+ width = fprintf(fp, "%s: ", get_atom_name(wm->conn, property));
+ if (reply == NULL) {
+ fprintf(fp, "(no reply)\n");
+- goto out;
++ return;
+ }
+
+ width += fprintf(fp, "%s/%d, length %d (value_len %d): ",
+@@ -492,15 +468,10 @@ dump_property(struct weston_wm *wm,
+ } else {
+ fprintf(fp, "huh?\n");
+ }
+-
+-out:
+- if (fclose(fp) == 0)
+- wm_log_continue("%s", logstr);
+- free(logstr);
+ }
+
+ static void
+-read_and_dump_property(struct weston_wm *wm,
++read_and_dump_property(FILE *fp, struct weston_wm *wm,
+ xcb_window_t window, xcb_atom_t property)
+ {
+ xcb_get_property_reply_t *reply;
+@@ -510,7 +481,7 @@ read_and_dump_property(struct weston_wm *wm,
+ property, XCB_ATOM_ANY, 0, 2048);
+ reply = xcb_get_property_reply(wm->conn, cookie, NULL);
+
+- dump_property(wm, property, reply);
++ dump_property(fp, wm, property, reply);
+
+ free(reply);
+ }
+@@ -1389,19 +1360,35 @@ weston_wm_handle_property_notify(struct weston_wm *wm, xcb_generic_event_t *even
+ xcb_property_notify_event_t *property_notify =
+ (xcb_property_notify_event_t *) event;
+ struct weston_wm_window *window;
++ FILE *fp;
++ char *logstr;
++ size_t logsize;
+
+ if (!wm_lookup_window(wm, property_notify->window, &window))
+ return;
+
+ window->properties_dirty = 1;
+
+- wm_log("XCB_PROPERTY_NOTIFY: window %d, ", property_notify->window);
+- if (property_notify->state == XCB_PROPERTY_DELETE)
+- wm_log_continue("deleted %s\n",
+- get_atom_name(wm->conn, property_notify->atom));
+- else
+- read_and_dump_property(wm, property_notify->window,
+- property_notify->atom);
++ fp = open_memstream(&logstr, &logsize);
++ if (fp) {
++ fprintf(fp, "XCB_PROPERTY_NOTIFY: window %d, ", property_notify->window);
++ if (property_notify->state == XCB_PROPERTY_DELETE)
++ fprintf(fp, "deleted %s\n",
++ get_atom_name(wm->conn, property_notify->atom));
++ else
++ read_and_dump_property(fp, wm, property_notify->window,
++ property_notify->atom);
++
++ if (fclose(fp) == 0)
++ wm_log("%s", logstr);
++ free(logstr);
++ } else {
++ /* read_and_dump_property() is a X11 roundtrip.
++ * Mimic it to maintain ordering semantics between debug
++ * and non-debug paths.
++ */
++ get_atom_name(wm->conn, property_notify->atom);
++ }
+
+ if (property_notify->atom == wm->atom.net_wm_name ||
+ property_notify->atom == XCB_ATOM_WM_NAME)
+diff --git a/xwayland/xwayland.h b/xwayland/xwayland.h
+index ca75f5b7..52da6786 100644
+--- a/xwayland/xwayland.h
++++ b/xwayland/xwayland.h
+@@ -23,6 +23,7 @@
+ * SOFTWARE.
+ */
+
++#include <stdio.h>
+ #include <wayland-server.h>
+ #include <xcb/xcb.h>
+ #include <xcb/xfixes.h>
+@@ -159,7 +160,7 @@ struct weston_wm {
+ };
+
+ void
+-dump_property(struct weston_wm *wm, xcb_atom_t property,
++dump_property(FILE *fp, struct weston_wm *wm, xcb_atom_t property,
+ xcb_get_property_reply_t *reply);
+
+ const char *
+--
+2.16.2
+
diff --git a/bsp/meta-synopsys/recipes-graphics/wayland/weston/1012-xwm-convert-WM_DEBUG-into-a-weston-debug-scope.patch b/bsp/meta-synopsys/recipes-graphics/wayland/weston/1012-xwm-convert-WM_DEBUG-into-a-weston-debug-scope.patch
new file mode 100644
index 00000000..cc171a58
--- /dev/null
+++ b/bsp/meta-synopsys/recipes-graphics/wayland/weston/1012-xwm-convert-WM_DEBUG-into-a-weston-debug-scope.patch
@@ -0,0 +1,423 @@
+From 9b72eb7930ef60aa44ab49c53b2aec9e7242cf1c Mon Sep 17 00:00:00 2001
+From: Pekka Paalanen <pq@iki.fi>
+Date: Thu, 12 Oct 2017 13:18:14 +0200
+Subject: [PATCH 12/46] xwm: convert WM_DEBUG into a weston-debug scope
+
+Instead of a compile time choice, offer the XWM debugging messages
+through the weston-debug protocol and tool on demand. Users will not
+need to recompile weston to get XWM debugging, and it won't flood the
+weston log.
+
+The debug scope needs to be initialized in launcher.c for it be
+available from start, before the first X11 client tries to connect and
+initializes XWM.
+
+Signed-off-by: Pekka Paalanen <pq@iki.fi>
+
+pass the wm_debug scope to weston_debug_scope_printf API to append
+the scopename to the timestr
+
+Signed-off-by: Maniraj Devadoss <Maniraj.Devadoss@in.bosch.com>
+Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
+Reviewed-by: Daniel Stone <daniels@collabora.com>
+---
+ xwayland/launcher.c | 7 ++
+ xwayland/window-manager.c | 166 +++++++++++++++++++++++++---------------------
+ xwayland/xwayland.h | 3 +
+ 3 files changed, 99 insertions(+), 77 deletions(-)
+
+diff --git a/xwayland/launcher.c b/xwayland/launcher.c
+index 0ecdb205..c5b99385 100644
+--- a/xwayland/launcher.c
++++ b/xwayland/launcher.c
+@@ -229,6 +229,8 @@ weston_xserver_destroy(struct wl_listener *l, void *data)
+ if (wxs->loop)
+ weston_xserver_shutdown(wxs);
+
++ weston_debug_scope_destroy(wxs->wm_debug);
++
+ free(wxs);
+ }
+
+@@ -391,5 +393,10 @@ weston_module_init(struct weston_compositor *compositor)
+ wxs->destroy_listener.notify = weston_xserver_destroy;
+ wl_signal_add(&compositor->destroy_signal, &wxs->destroy_listener);
+
++ wxs->wm_debug = weston_compositor_add_debug_scope(wxs->compositor,
++ "xwm-wm-x11",
++ "XWM's window management X11 events\n",
++ NULL, NULL);
++
+ return 0;
+ }
+diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
+index 4a26f6e7..ccdae57f 100644
+--- a/xwayland/window-manager.c
++++ b/xwayland/window-manager.c
+@@ -193,23 +193,27 @@ static void
+ xserver_map_shell_surface(struct weston_wm_window *window,
+ struct weston_surface *surface);
+
+-static int __attribute__ ((format (printf, 1, 2)))
+-wm_log(const char *fmt, ...)
++static bool
++wm_debug_is_enabled(struct weston_wm *wm)
+ {
+-#ifdef WM_DEBUG
+- int l;
+- va_list argp;
++ return weston_debug_scope_is_enabled(wm->server->wm_debug);
++}
+
+- va_start(argp, fmt);
+- l = weston_vlog(fmt, argp);
+- va_end(argp);
++static void __attribute__ ((format (printf, 2, 3)))
++wm_printf(struct weston_wm *wm, const char *fmt, ...)
++{
++ va_list ap;
++ char timestr[128];
+
+- return l;
+-#else
+- return 0;
+-#endif
+-}
++ if (wm_debug_is_enabled(wm))
++ weston_debug_scope_printf(wm->server->wm_debug, "%s ",
++ weston_debug_scope_timestamp(wm->server->wm_debug,
++ timestr, sizeof timestr));
+
++ va_start(ap, fmt);
++ weston_debug_scope_vprintf(wm->server->wm_debug, fmt, ap);
++ va_end(ap);
++}
+ static void
+ weston_output_weak_ref_init(struct weston_output_weak_ref *ref)
+ {
+@@ -717,10 +721,10 @@ weston_wm_handle_configure_request(struct weston_wm *wm, xcb_generic_event_t *ev
+ uint32_t mask, values[16];
+ int x, y, width, height, i = 0;
+
+- wm_log("XCB_CONFIGURE_REQUEST (window %d) %d,%d @ %dx%d\n",
+- configure_request->window,
+- configure_request->x, configure_request->y,
+- configure_request->width, configure_request->height);
++ wm_printf(wm, "XCB_CONFIGURE_REQUEST (window %d) %d,%d @ %dx%d\n",
++ configure_request->window,
++ configure_request->x, configure_request->y,
++ configure_request->width, configure_request->height);
+
+ if (!wm_lookup_window(wm, configure_request->window, &window))
+ return;
+@@ -786,11 +790,11 @@ weston_wm_handle_configure_notify(struct weston_wm *wm, xcb_generic_event_t *eve
+ wm->server->compositor->xwayland_interface;
+ struct weston_wm_window *window;
+
+- wm_log("XCB_CONFIGURE_NOTIFY (window %d) %d,%d @ %dx%d%s\n",
+- configure_notify->window,
+- configure_notify->x, configure_notify->y,
+- configure_notify->width, configure_notify->height,
+- configure_notify->override_redirect ? ", override" : "");
++ wm_printf(wm, "XCB_CONFIGURE_NOTIFY (window %d) %d,%d @ %dx%d%s\n",
++ configure_notify->window,
++ configure_notify->x, configure_notify->y,
++ configure_notify->width, configure_notify->height,
++ configure_notify->override_redirect ? ", override" : "");
+
+ if (!wm_lookup_window(wm, configure_notify->window, &window))
+ return;
+@@ -839,7 +843,7 @@ weston_wm_create_surface(struct wl_listener *listener, void *data)
+ if (wl_resource_get_client(surface->resource) != wm->server->client)
+ return;
+
+- wm_log("XWM: create weston_surface %p\n", surface);
++ wm_printf(wm, "XWM: create weston_surface %p\n", surface);
+
+ wl_list_for_each(window, &wm->unpaired_window_list, link)
+ if (window->surface_id ==
+@@ -1096,8 +1100,8 @@ weston_wm_handle_map_request(struct weston_wm *wm, xcb_generic_event_t *event)
+ struct weston_output *output;
+
+ if (our_resource(wm, map_request->window)) {
+- wm_log("XCB_MAP_REQUEST (window %d, ours)\n",
+- map_request->window);
++ wm_printf(wm, "XCB_MAP_REQUEST (window %d, ours)\n",
++ map_request->window);
+ return;
+ }
+
+@@ -1126,10 +1130,10 @@ weston_wm_handle_map_request(struct weston_wm *wm, xcb_generic_event_t *event)
+ weston_wm_window_create_frame(window); /* sets frame_id */
+ assert(window->frame_id != XCB_WINDOW_NONE);
+
+- wm_log("XCB_MAP_REQUEST (window %d, %p, frame %d, %dx%d @ %d,%d)\n",
+- window->id, window, window->frame_id,
+- window->width, window->height,
+- window->map_request_x, window->map_request_y);
++ wm_printf(wm, "XCB_MAP_REQUEST (window %d, %p, frame %d, %dx%d @ %d,%d)\n",
++ window->id, window, window->frame_id,
++ window->width, window->height,
++ window->map_request_x, window->map_request_y);
+
+ weston_wm_window_set_allow_commits(window, false);
+ weston_wm_window_set_wm_state(window, ICCCM_NORMAL_STATE);
+@@ -1157,13 +1161,13 @@ weston_wm_handle_map_notify(struct weston_wm *wm, xcb_generic_event_t *event)
+ xcb_map_notify_event_t *map_notify = (xcb_map_notify_event_t *) event;
+
+ if (our_resource(wm, map_notify->window)) {
+- wm_log("XCB_MAP_NOTIFY (window %d, ours)\n",
+- map_notify->window);
++ wm_printf(wm, "XCB_MAP_NOTIFY (window %d, ours)\n",
++ map_notify->window);
+ return;
+ }
+
+- wm_log("XCB_MAP_NOTIFY (window %d%s)\n", map_notify->window,
+- map_notify->override_redirect ? ", override" : "");
++ wm_printf(wm, "XCB_MAP_NOTIFY (window %d%s)\n", map_notify->window,
++ map_notify->override_redirect ? ", override" : "");
+ }
+
+ static void
+@@ -1173,10 +1177,10 @@ weston_wm_handle_unmap_notify(struct weston_wm *wm, xcb_generic_event_t *event)
+ (xcb_unmap_notify_event_t *) event;
+ struct weston_wm_window *window;
+
+- wm_log("XCB_UNMAP_NOTIFY (window %d, event %d%s)\n",
+- unmap_notify->window,
+- unmap_notify->event,
+- our_resource(wm, unmap_notify->window) ? ", ours" : "");
++ wm_printf(wm, "XCB_UNMAP_NOTIFY (window %d, event %d%s)\n",
++ unmap_notify->window,
++ unmap_notify->event,
++ our_resource(wm, unmap_notify->window) ? ", ours" : "");
+
+ if (our_resource(wm, unmap_notify->window))
+ return;
+@@ -1216,7 +1220,7 @@ weston_wm_window_draw_decoration(struct weston_wm_window *window)
+ cairo_t *cr;
+ int width, height;
+
+- wm_log("XWM: draw decoration, win %d\n", window->id);
++ wm_printf(window->wm, "XWM: draw decoration, win %d\n", window->id);
+
+ weston_wm_window_get_frame_size(window, &width, &height);
+
+@@ -1279,8 +1283,8 @@ weston_wm_window_set_pending_state(struct weston_wm_window *window)
+ input_h = height;
+ }
+
+- wm_log("XWM: win %d geometry: %d,%d %dx%d\n",
+- window->id, input_x, input_y, input_w, input_h);
++ wm_printf(window->wm, "XWM: win %d geometry: %d,%d %dx%d\n",
++ window->id, input_x, input_y, input_w, input_h);
+
+ pixman_region32_fini(&window->surface->pending.input);
+ pixman_region32_init_rect(&window->surface->pending.input,
+@@ -1347,7 +1351,7 @@ weston_wm_window_schedule_repaint(struct weston_wm_window *window)
+ if (window->repaint_source)
+ return;
+
+- wm_log("XWM: schedule repaint, win %d\n", window->id);
++ wm_printf(wm, "XWM: schedule repaint, win %d\n", window->id);
+
+ window->repaint_source =
+ wl_event_loop_add_idle(wm->server->loop,
+@@ -1360,18 +1364,24 @@ weston_wm_handle_property_notify(struct weston_wm *wm, xcb_generic_event_t *even
+ xcb_property_notify_event_t *property_notify =
+ (xcb_property_notify_event_t *) event;
+ struct weston_wm_window *window;
+- FILE *fp;
++ FILE *fp = NULL;
+ char *logstr;
+ size_t logsize;
++ char timestr[128];
+
+ if (!wm_lookup_window(wm, property_notify->window, &window))
+ return;
+
+ window->properties_dirty = 1;
+
+- fp = open_memstream(&logstr, &logsize);
++ if (wm_debug_is_enabled(wm))
++ fp = open_memstream(&logstr, &logsize);
++
+ if (fp) {
+- fprintf(fp, "XCB_PROPERTY_NOTIFY: window %d, ", property_notify->window);
++ fprintf(fp, "%s XCB_PROPERTY_NOTIFY: window %d, ",
++ weston_debug_scope_timestamp(wm->server->wm_debug,
++ timestr, sizeof timestr),
++ property_notify->window);
+ if (property_notify->state == XCB_PROPERTY_DELETE)
+ fprintf(fp, "deleted %s\n",
+ get_atom_name(wm->conn, property_notify->atom));
+@@ -1380,7 +1390,8 @@ weston_wm_handle_property_notify(struct weston_wm *wm, xcb_generic_event_t *even
+ property_notify->atom);
+
+ if (fclose(fp) == 0)
+- wm_log("%s", logstr);
++ weston_debug_scope_write(wm->server->wm_debug,
++ logstr, logsize);
+ free(logstr);
+ } else {
+ /* read_and_dump_property() is a X11 roundtrip.
+@@ -1406,7 +1417,7 @@ weston_wm_window_create(struct weston_wm *wm,
+
+ window = zalloc(sizeof *window);
+ if (window == NULL) {
+- wm_log("failed to allocate window\n");
++ wm_printf(wm, "failed to allocate window\n");
+ return;
+ }
+
+@@ -1479,12 +1490,12 @@ weston_wm_handle_create_notify(struct weston_wm *wm, xcb_generic_event_t *event)
+ xcb_create_notify_event_t *create_notify =
+ (xcb_create_notify_event_t *) event;
+
+- wm_log("XCB_CREATE_NOTIFY (window %d, at (%d, %d), width %d, height %d%s%s)\n",
+- create_notify->window,
+- create_notify->x, create_notify->y,
+- create_notify->width, create_notify->height,
+- create_notify->override_redirect ? ", override" : "",
+- our_resource(wm, create_notify->window) ? ", ours" : "");
++ wm_printf(wm, "XCB_CREATE_NOTIFY (window %d, at (%d, %d), width %d, height %d%s%s)\n",
++ create_notify->window,
++ create_notify->x, create_notify->y,
++ create_notify->width, create_notify->height,
++ create_notify->override_redirect ? ", override" : "",
++ our_resource(wm, create_notify->window) ? ", ours" : "");
+
+ if (our_resource(wm, create_notify->window))
+ return;
+@@ -1502,10 +1513,10 @@ weston_wm_handle_destroy_notify(struct weston_wm *wm, xcb_generic_event_t *event
+ (xcb_destroy_notify_event_t *) event;
+ struct weston_wm_window *window;
+
+- wm_log("XCB_DESTROY_NOTIFY, win %d, event %d%s\n",
+- destroy_notify->window,
+- destroy_notify->event,
+- our_resource(wm, destroy_notify->window) ? ", ours" : "");
++ wm_printf(wm, "XCB_DESTROY_NOTIFY, win %d, event %d%s\n",
++ destroy_notify->window,
++ destroy_notify->event,
++ our_resource(wm, destroy_notify->window) ? ", ours" : "");
+
+ if (our_resource(wm, destroy_notify->window))
+ return;
+@@ -1523,11 +1534,11 @@ weston_wm_handle_reparent_notify(struct weston_wm *wm, xcb_generic_event_t *even
+ (xcb_reparent_notify_event_t *) event;
+ struct weston_wm_window *window;
+
+- wm_log("XCB_REPARENT_NOTIFY (window %d, parent %d, event %d%s)\n",
+- reparent_notify->window,
+- reparent_notify->parent,
+- reparent_notify->event,
+- reparent_notify->override_redirect ? ", override" : "");
++ wm_printf(wm, "XCB_REPARENT_NOTIFY (window %d, parent %d, event %d%s)\n",
++ reparent_notify->window,
++ reparent_notify->parent,
++ reparent_notify->event,
++ reparent_notify->override_redirect ? ", override" : "");
+
+ if (reparent_notify->parent == wm->screen->root) {
+ weston_wm_window_create(wm, reparent_notify->window, 10, 10,
+@@ -1734,7 +1745,7 @@ surface_destroy(struct wl_listener *listener, void *data)
+ container_of(listener,
+ struct weston_wm_window, surface_destroy_listener);
+
+- wm_log("surface for xid %d destroyed\n", window->id);
++ wm_printf(window->wm, "surface for xid %d destroyed\n", window->id);
+
+ /* This should have been freed by the shell.
+ * Don't try to use it later. */
+@@ -1750,7 +1761,8 @@ weston_wm_window_handle_surface_id(struct weston_wm_window *window,
+ struct wl_resource *resource;
+
+ if (window->surface_id != 0) {
+- wm_log("already have surface id for window %d\n", window->id);
++ wm_printf(wm, "already have surface id for window %d\n",
++ window->id);
+ return;
+ }
+
+@@ -1782,14 +1794,14 @@ weston_wm_handle_client_message(struct weston_wm *wm,
+ (xcb_client_message_event_t *) event;
+ struct weston_wm_window *window;
+
+- wm_log("XCB_CLIENT_MESSAGE (%s %d %d %d %d %d win %d)\n",
+- get_atom_name(wm->conn, client_message->type),
+- client_message->data.data32[0],
+- client_message->data.data32[1],
+- client_message->data.data32[2],
+- client_message->data.data32[3],
+- client_message->data.data32[4],
+- client_message->window);
++ wm_printf(wm, "XCB_CLIENT_MESSAGE (%s %d %d %d %d %d win %d)\n",
++ get_atom_name(wm->conn, client_message->type),
++ client_message->data.data32[0],
++ client_message->data.data32[1],
++ client_message->data.data32[2],
++ client_message->data.data32[3],
++ client_message->data.data32[4],
++ client_message->window);
+
+ /* The window may get created and destroyed before we actually
+ * handle the message. If it doesn't exist, bail.
+@@ -2007,9 +2019,9 @@ weston_wm_handle_button(struct weston_wm *wm, xcb_generic_event_t *event)
+ uint32_t button_id;
+ uint32_t double_click = 0;
+
+- wm_log("XCB_BUTTON_%s (detail %d)\n",
+- button->response_type == XCB_BUTTON_PRESS ?
+- "PRESS" : "RELEASE", button->detail);
++ wm_printf(wm, "XCB_BUTTON_%s (detail %d)\n",
++ button->response_type == XCB_BUTTON_PRESS ?
++ "PRESS" : "RELEASE", button->detail);
+
+ if (!wm_lookup_window(wm, button->event, &window) ||
+ !window->decorate)
+@@ -2221,7 +2233,7 @@ weston_wm_handle_event(int fd, uint32_t mask, void *data)
+ weston_wm_handle_destroy_notify(wm, event);
+ break;
+ case XCB_MAPPING_NOTIFY:
+- wm_log("XCB_MAPPING_NOTIFY\n");
++ wm_printf(wm, "XCB_MAPPING_NOTIFY\n");
+ break;
+ case XCB_PROPERTY_NOTIFY:
+ weston_wm_handle_property_notify(wm, event);
+@@ -2837,8 +2849,8 @@ xserver_map_shell_surface(struct weston_wm_window *window,
+ window->surface,
+ &shell_client);
+
+- wm_log("XWM: map shell surface, win %d, weston_surface %p, xwayland surface %p\n",
+- window->id, window->surface, window->shsurf);
++ wm_printf(wm, "XWM: map shell surface, win %d, weston_surface %p, xwayland surface %p\n",
++ window->id, window->surface, window->shsurf);
+
+ if (window->name)
+ xwayland_interface->set_title(window->shsurf, window->name);
+diff --git a/xwayland/xwayland.h b/xwayland/xwayland.h
+index 52da6786..507d534d 100644
+--- a/xwayland/xwayland.h
++++ b/xwayland/xwayland.h
+@@ -33,6 +33,7 @@
+ #include "compositor.h"
+ #include "compositor/weston.h"
+ #include "xwayland-api.h"
++#include "weston-debug.h"
+
+ #define SEND_EVENT_MASK (0x80)
+ #define EVENT_TYPE(event) ((event)->response_type & ~SEND_EVENT_MASK)
+@@ -52,6 +53,8 @@ struct weston_xserver {
+ struct wl_listener destroy_listener;
+ weston_xwayland_spawn_xserver_func_t spawn_func;
+ void *user_data;
++
++ struct weston_debug_scope *wm_debug;
+ };
+
+ struct weston_wm {
+--
+2.16.2
+
diff --git a/bsp/meta-synopsys/recipes-graphics/wayland/weston/1014-compositor-Add-weston_layer_mask_is_infinite.patch b/bsp/meta-synopsys/recipes-graphics/wayland/weston/1014-compositor-Add-weston_layer_mask_is_infinite.patch
new file mode 100644
index 00000000..ee4ab191
--- /dev/null
+++ b/bsp/meta-synopsys/recipes-graphics/wayland/weston/1014-compositor-Add-weston_layer_mask_is_infinite.patch
@@ -0,0 +1,52 @@
+From 3b7756351d31a72da11ff09c56efa17960db1b20 Mon Sep 17 00:00:00 2001
+From: Daniel Stone <daniels@collabora.com>
+Date: Fri, 20 Jul 2018 08:38:25 +0100
+Subject: [PATCH 14/46] compositor: Add weston_layer_mask_is_infinite
+
+As a counterpart to weston_layer_set_mask_infinite(), returning if the
+mask is the same as what is set.
+
+Signed-off-by: Daniel Stone <daniels@collabora.com>
+Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
+---
+ libweston/compositor.c | 9 +++++++++
+ libweston/compositor.h | 3 +++
+ 2 files changed, 12 insertions(+)
+
+diff --git a/libweston/compositor.c b/libweston/compositor.c
+index 01616550..a38c4c1b 100644
+--- a/libweston/compositor.c
++++ b/libweston/compositor.c
+@@ -2746,6 +2746,15 @@ weston_layer_set_mask_infinite(struct weston_layer *layer)
+ UINT32_MAX, UINT32_MAX);
+ }
+
++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_MIN + UINT32_MAX &&
++ layer->mask.y2 == INT32_MIN + UINT32_MAX;
++}
++
+ WL_EXPORT void
+ weston_output_schedule_repaint(struct weston_output *output)
+ {
+diff --git a/libweston/compositor.h b/libweston/compositor.h
+index 33f02b18..069fb03d 100644
+--- a/libweston/compositor.h
++++ b/libweston/compositor.h
+@@ -1685,6 +1685,9 @@ weston_layer_set_mask(struct weston_layer *layer, int x, int y, int width, int h
+ void
+ weston_layer_set_mask_infinite(struct weston_layer *layer);
+
++bool
++weston_layer_mask_is_infinite(struct weston_layer *layer);
++
+ void
+ weston_plane_init(struct weston_plane *plane,
+ struct weston_compositor *ec,
+--
+2.16.2
+
diff --git a/bsp/meta-synopsys/recipes-graphics/wayland/weston/1015-compositor-Add-scene-graph-debug-scope.patch b/bsp/meta-synopsys/recipes-graphics/wayland/weston/1015-compositor-Add-scene-graph-debug-scope.patch
new file mode 100644
index 00000000..13ba4c81
--- /dev/null
+++ b/bsp/meta-synopsys/recipes-graphics/wayland/weston/1015-compositor-Add-scene-graph-debug-scope.patch
@@ -0,0 +1,297 @@
+From ce62cb3d05505777893ccdfacbf2a013c82e4ce2 Mon Sep 17 00:00:00 2001
+From: Daniel Stone <daniels@collabora.com>
+Date: Fri, 20 Jul 2018 09:46:24 +0100
+Subject: [PATCH 15/46] compositor: Add scene-graph debug scope
+
+Add a 'scene-graph' debug scope which will dump out the current set of
+outputs, layers, and views and as much information as possible about how
+they are rendered and composited.
+
+Signed-off-by: Daniel Stone <daniels@collabora.com>
+---
+ libweston/compositor.c | 225 +++++++++++++++++++++++++++++++++++++++++++++++++
+ libweston/compositor.h | 4 +
+ 2 files changed, 229 insertions(+)
+
+diff --git a/libweston/compositor.c b/libweston/compositor.c
+index a38c4c1b..2ca3da3b 100644
+--- a/libweston/compositor.c
++++ b/libweston/compositor.c
+@@ -55,6 +55,8 @@
+ #include "timeline.h"
+
+ #include "compositor.h"
++#include "weston-debug.h"
++#include "linux-dmabuf.h"
+ #include "viewporter-server-protocol.h"
+ #include "presentation-time-server-protocol.h"
+ #include "shared/helpers.h"
+@@ -6306,6 +6308,221 @@ timeline_key_binding_handler(struct weston_keyboard *keyboard,
+ weston_timeline_open(compositor);
+ }
+
++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;
++ struct wl_shm_buffer *shm;
++ struct linux_dmabuf_buffer *dmabuf;
++
++ if (!buffer) {
++ fprintf(fp, "\t\t[buffer not available]\n");
++ return;
++ }
++
++ shm = wl_shm_buffer_get(buffer->resource);
++ if (shm) {
++ fprintf(fp, "\t\tSHM buffer\n");
++ fprintf(fp, "\t\t\tformat: 0x%lx\n",
++ (unsigned long) wl_shm_buffer_get_format(shm));
++ return;
++ }
++
++ dmabuf = linux_dmabuf_buffer_get(buffer->resource);
++ if (dmabuf) {
++ fprintf(fp, "\t\tdmabuf buffer\n");
++ fprintf(fp, "\t\t\tformat: 0x%lx\n",
++ (unsigned long) dmabuf->attributes.format);
++ fprintf(fp, "\t\t\tmodifier: 0x%llx\n",
++ (unsigned long long) dmabuf->attributes.modifier[0]);
++ return;
++ }
++
++ fprintf(fp, "\t\tEGL buffer");
++}
++
++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 (pixman_region32_equal(&view->transform.opaque,
++ &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);
++}
++
++/**
++ * Output information on how libweston is currently composing the scene
++ * graph.
++ */
++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(fp, view, 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_debug_stream *stream, void *data)
++{
++ struct weston_compositor *ec = data;
++ char *str = weston_compositor_print_scene_graph(ec);
++
++ weston_debug_stream_printf(stream, "%s", str);
++ free(str);
++ weston_debug_stream_complete(stream);
++}
++
+ /** Create the compositor.
+ *
+ * This functions creates and initializes a compositor instance.
+@@ -6415,6 +6632,12 @@ weston_compositor_create(struct wl_display *display, void *user_data)
+ weston_compositor_add_debug_binding(ec, KEY_T,
+ timeline_key_binding_handler, ec);
+
++ ec->debug_scene =
++ weston_compositor_add_debug_scope(ec, "scene-graph",
++ "Scene graph details\n",
++ debug_scene_graph_cb,
++ ec);
++
+ return ec;
+
+ fail:
+@@ -6714,6 +6937,8 @@ weston_compositor_destroy(struct weston_compositor *compositor)
+ if (compositor->heads_changed_source)
+ wl_event_source_remove(compositor->heads_changed_source);
+
++ weston_debug_scope_destroy(compositor->debug_scene);
++ compositor->debug_scene = NULL;
+ weston_debug_compositor_destroy(compositor);
+
+ free(compositor);
+diff --git a/libweston/compositor.h b/libweston/compositor.h
+index 069fb03d..49013e14 100644
+--- a/libweston/compositor.h
++++ b/libweston/compositor.h
+@@ -1163,6 +1163,7 @@ struct weston_compositor {
+ struct weston_touch_calibrator *touch_calibrator;
+
+ struct weston_debug_compositor *weston_debug;
++ struct weston_debug_scope *debug_scene;
+ };
+
+ struct weston_buffer {
+@@ -1933,6 +1934,9 @@ weston_buffer_reference(struct weston_buffer_reference *ref,
+ void
+ weston_compositor_get_time(struct timespec *time);
+
++char *
++weston_compositor_print_scene_graph(struct weston_compositor *ec);
++
+ void
+ weston_compositor_destroy(struct weston_compositor *ec);
+ struct weston_compositor *
+--
+2.16.2
+
diff --git a/bsp/meta-synopsys/recipes-graphics/wayland/weston/1017-compositor-drm-Add-backend-pointer-to-drm_output.patch b/bsp/meta-synopsys/recipes-graphics/wayland/weston/1017-compositor-drm-Add-backend-pointer-to-drm_output.patch
new file mode 100644
index 00000000..2dff3bd3
--- /dev/null
+++ b/bsp/meta-synopsys/recipes-graphics/wayland/weston/1017-compositor-drm-Add-backend-pointer-to-drm_output.patch
@@ -0,0 +1,37 @@
+From 64dbbee7f6570949edc8bca30e6cd026a9e70a59 Mon Sep 17 00:00:00 2001
+From: Daniel Stone <daniels@collabora.com>
+Date: Fri, 20 Jul 2018 19:00:06 +0100
+Subject: [PATCH 17/46] compositor-drm: Add backend pointer to drm_output
+
+Add this for convenience, so it's easier to access when we add the DRM
+backend debug scope.
+
+Signed-off-by: Daniel Stone <daniels@collabora.com>
+---
+ libweston/compositor-drm.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
+index 94d78752..612e6a8f 100644
+--- a/libweston/compositor-drm.c
++++ b/libweston/compositor-drm.c
+@@ -463,6 +463,7 @@ struct drm_head {
+
+ struct drm_output {
+ struct weston_output base;
++ struct drm_backend *backend;
+
+ uint32_t crtc_id; /* object ID to pass to DRM functions */
+ int pipe; /* index of CRTC in resource array / bitmasks */
+@@ -6104,6 +6105,8 @@ drm_output_create(struct weston_compositor *compositor, const char *name)
+ if (output == NULL)
+ return NULL;
+
++ output->backend = b;
++
+ weston_output_init(&output->base, compositor, name);
+
+ output->base.enable = drm_output_enable;
+--
+2.16.2
+
diff --git a/bsp/meta-synopsys/recipes-graphics/wayland/weston/1018-compositor-drm-Add-drm-backend-log-debug-scope.patch b/bsp/meta-synopsys/recipes-graphics/wayland/weston/1018-compositor-drm-Add-drm-backend-log-debug-scope.patch
new file mode 100644
index 00000000..932859ca
--- /dev/null
+++ b/bsp/meta-synopsys/recipes-graphics/wayland/weston/1018-compositor-drm-Add-drm-backend-log-debug-scope.patch
@@ -0,0 +1,632 @@
+From 1cbe1f952de2b22539e163c0055fa3dcbb2e2d54 Mon Sep 17 00:00:00 2001
+From: Daniel Stone <daniels@collabora.com>
+Date: Fri, 20 Jul 2018 10:21:28 +0100
+Subject: [PATCH 18/46] compositor-drm: Add drm-backend log debug scope
+
+Add a 'drm-debug' scope which prints verbose information about the DRM
+backend's repaint cycle, including the decision tree on how views are
+assigned (or not) to planes.
+
+Signed-off-by: Daniel Stone <daniels@collabora.com>
+---
+ libweston/compositor-drm.c | 285 ++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 258 insertions(+), 27 deletions(-)
+
+diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
+index 612e6a8f..b21793e5 100644
+--- a/libweston/compositor-drm.c
++++ b/libweston/compositor-drm.c
+@@ -51,6 +51,7 @@
+
+ #include "compositor.h"
+ #include "compositor-drm.h"
++#include "weston-debug.h"
+ #include "shared/helpers.h"
+ #include "shared/timespec-util.h"
+ #include "gl-renderer.h"
+@@ -73,6 +74,42 @@
+ #define GBM_BO_USE_CURSOR GBM_BO_USE_CURSOR_64X64
+ #endif
+
++/**
++ * A small wrapper to print information into the 'drm-backend' debug scope.
++ *
++ * The following conventions are used to print variables:
++ *
++ * - fixed uint32_t values, including Weston object IDs such as weston_output
++ * IDs, DRM object IDs such as CRTCs or properties, and GBM/DRM formats:
++ * "%lu (0x%lx)" (unsigned long) value, (unsigned long) value
++ *
++ * - fixed uint64_t values, such as DRM property values (including object IDs
++ * when used as a value):
++ * "%llu (0x%llx)" (unsigned long long) value, (unsigned long long) value
++ *
++ * - non-fixed-width signed int:
++ * "%d" value
++ *
++ * - non-fixed-width unsigned int:
++ * "%u (0x%x)" value, value
++ *
++ * - non-fixed-width unsigned long:
++ * "%lu (0x%lx)" value, value
++ *
++ * Either the integer or hexadecimal forms may be omitted if it is known that
++ * one representation is not useful (e.g. width/height in hex are rarely what
++ * you want).
++ *
++ * This is to avoid implicit widening or narrowing when we use fixed-size
++ * types: uint32_t can be resolved by either unsigned int or unsigned long
++ * on a 32-bit system but only unsigned int on a 64-bit system, with uint64_t
++ * being unsigned long long on a 32-bit system and unsigned long on a 64-bit
++ * system. To avoid confusing side effects, we explicitly cast to the widest
++ * possible type and use a matching format specifier.
++ */
++#define drm_debug(b, ...) \
++ weston_debug_scope_printf((b)->debug, __VA_ARGS__)
++
+ #define MAX_CLONED_CONNECTORS 4
+
+ /**
+@@ -302,6 +339,8 @@ struct drm_backend {
+ bool shutting_down;
+
+ bool aspect_ratio_supported;
++
++ struct weston_debug_scope *debug;
+ };
+
+ struct drm_mode {
+@@ -2357,6 +2396,10 @@ crtc_add_prop(drmModeAtomicReq *req, struct drm_output *output,
+
+ ret = drmModeAtomicAddProperty(req, output->crtc_id, info->prop_id,
+ val);
++ drm_debug(output->backend, "\t\t\t[CRTC:%lu] %lu (%s) -> %llu (0x%llx)\n",
++ (unsigned long) output->crtc_id,
++ (unsigned long) info->prop_id, info->name,
++ (unsigned long long) val, (unsigned long long) val);
+ return (ret <= 0) ? -1 : 0;
+ }
+
+@@ -2372,6 +2415,10 @@ connector_add_prop(drmModeAtomicReq *req, struct drm_head *head,
+
+ ret = drmModeAtomicAddProperty(req, head->connector_id,
+ info->prop_id, val);
++ drm_debug(head->backend, "\t\t\t[CONN:%lu] %lu (%s) -> %llu (0x%llx)\n",
++ (unsigned long) head->connector_id,
++ (unsigned long) info->prop_id, info->name,
++ (unsigned long long) val, (unsigned long long) val);
+ return (ret <= 0) ? -1 : 0;
+ }
+
+@@ -2387,6 +2434,10 @@ plane_add_prop(drmModeAtomicReq *req, struct drm_plane *plane,
+
+ ret = drmModeAtomicAddProperty(req, plane->plane_id, info->prop_id,
+ val);
++ drm_debug(plane->backend, "\t\t\t[PLANE:%lu] %lu (%s) -> %llu (0x%llx)\n",
++ (unsigned long) plane->plane_id,
++ (unsigned long) info->prop_id, info->name,
++ (unsigned long long) val, (unsigned long long) val);
+ return (ret <= 0) ? -1 : 0;
+ }
+
+@@ -2405,6 +2456,9 @@ drm_mode_ensure_blob(struct drm_backend *backend, struct drm_mode *mode)
+ if (ret != 0)
+ weston_log("failed to create mode property blob: %m\n");
+
++ drm_debug(backend, "\t\t\t[atomic] created new mode blob %lu for %s",
++ (unsigned long) mode->blob_id, mode->mode_info.name);
++
+ return ret;
+ }
+
+@@ -2414,17 +2468,23 @@ drm_output_apply_state_atomic(struct drm_output_state *state,
+ uint32_t *flags)
+ {
+ struct drm_output *output = state->output;
+- struct drm_backend *backend = to_drm_backend(output->base.compositor);
++ struct drm_backend *b = to_drm_backend(output->base.compositor);
+ struct drm_plane_state *plane_state;
+ struct drm_mode *current_mode = to_drm_mode(output->base.current_mode);
+ struct drm_head *head;
+ int ret = 0;
+
+- if (state->dpms != output->state_cur->dpms)
++ drm_debug(b, "\t\t[atomic] %s output %lu (%s) state\n",
++ (*flags & DRM_MODE_ATOMIC_TEST_ONLY) ? "testing" : "applying",
++ (unsigned long) output->base.id, output->base.name);
++
++ if (state->dpms != output->state_cur->dpms) {
++ drm_debug(b, "\t\t\t[atomic] DPMS state differs, modeset OK\n");
+ *flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
++ }
+
+ if (state->dpms == WESTON_DPMS_ON) {
+- ret = drm_mode_ensure_blob(backend, current_mode);
++ ret = drm_mode_ensure_blob(b, current_mode);
+ if (ret != 0)
+ return ret;
+
+@@ -2522,6 +2582,9 @@ drm_pending_state_apply_atomic(struct drm_pending_state *pending_state,
+ uint32_t *unused;
+ int err;
+
++ drm_debug(b, "\t\t[atomic] previous state invalid; "
++ "starting with fresh state\n");
++
+ /* If we need to reset all our state (e.g. because we've
+ * just started, or just been VT-switched in), explicitly
+ * disable all the CRTCs and connectors we aren't using. */
+@@ -2534,9 +2597,16 @@ drm_pending_state_apply_atomic(struct drm_pending_state *pending_state,
+
+ head = to_drm_head(head_base);
+
++ drm_debug(b, "\t\t[atomic] disabling inactive head %s\n",
++ head_base->name);
++
+ info = &head->props_conn[WDRM_CONNECTOR_CRTC_ID];
+ err = drmModeAtomicAddProperty(req, head->connector_id,
+ info->prop_id, 0);
++ drm_debug(b, "\t\t\t[CONN:%lu] %lu (%s) -> 0\n",
++ (unsigned long) head->connector_id,
++ (unsigned long) info->prop_id,
++ info->name);
+ if (err <= 0)
+ ret = -1;
+ }
+@@ -2573,12 +2643,21 @@ drm_pending_state_apply_atomic(struct drm_pending_state *pending_state,
+ continue;
+ }
+
++ drm_debug(b, "\t\t[atomic] disabling unused CRTC %lu\n",
++ (unsigned long) *unused);
++
++ drm_debug(b, "\t\t\t[CRTC:%lu] %lu (%s) -> 0\n",
++ (unsigned long) *unused,
++ (unsigned long) info->prop_id, info->name);
+ err = drmModeAtomicAddProperty(req, *unused,
+ info->prop_id, 0);
+ if (err <= 0)
+ ret = -1;
+
+ info = &infos[WDRM_CRTC_MODE_ID];
++ drm_debug(b, "\t\t\t[CRTC:%lu] %lu (%s) -> 0\n",
++ (unsigned long) *unused,
++ (unsigned long) info->prop_id, info->name);
+ err = drmModeAtomicAddProperty(req, *unused,
+ info->prop_id, 0);
+ if (err <= 0)
+@@ -2590,6 +2669,8 @@ drm_pending_state_apply_atomic(struct drm_pending_state *pending_state,
+ /* Disable all the planes; planes which are being used will
+ * override this state in the output-state application. */
+ wl_list_for_each(plane, &b->plane_list, link) {
++ drm_debug(b, "\t\t[atomic] starting with plane %lu disabled\n",
++ (unsigned long) plane->plane_id);
+ plane_add_prop(req, plane, WDRM_PLANE_CRTC_ID, 0);
+ plane_add_prop(req, plane, WDRM_PLANE_FB_ID, 0);
+ }
+@@ -2972,6 +3053,14 @@ drm_repaint_begin(struct weston_compositor *compositor)
+ ret = drm_pending_state_alloc(b);
+ b->repaint_data = ret;
+
++ if (weston_debug_scope_is_enabled(b->debug)) {
++ char *dbg = weston_compositor_print_scene_graph(compositor);
++ drm_debug(b, "[repaint] Beginning repaint; pending_state %p\n",
++ ret);
++ drm_debug(b, "%s", dbg);
++ free(dbg);
++ }
++
+ return ret;
+ }
+
+@@ -2991,6 +3080,7 @@ drm_repaint_flush(struct weston_compositor *compositor, void *repaint_data)
+ struct drm_pending_state *pending_state = repaint_data;
+
+ drm_pending_state_apply(pending_state);
++ drm_debug(b, "[repaint] flushed pending_state %p\n", pending_state);
+ b->repaint_data = NULL;
+ }
+
+@@ -3007,6 +3097,7 @@ drm_repaint_cancel(struct weston_compositor *compositor, void *repaint_data)
+ struct drm_pending_state *pending_state = repaint_data;
+
+ drm_pending_state_free(pending_state);
++ drm_debug(b, "[repaint] cancel pending_state %p\n", pending_state);
+ b->repaint_data = NULL;
+ }
+
+@@ -3050,12 +3141,21 @@ drm_output_prepare_overlay_view(struct drm_output_state *output_state,
+ struct drm_fb *fb;
+ unsigned int i;
+ int ret;
++ enum {
++ NO_PLANES,
++ NO_PLANES_WITH_FORMAT,
++ NO_PLANES_ACCEPTED,
++ PLACED_ON_PLANE,
++ } availability = NO_PLANES;
+
+ assert(!b->sprites_are_broken);
+
+ fb = drm_fb_get_from_view(output_state, ev);
+- if (!fb)
++ if (!fb) {
++ drm_debug(b, "\t\t\t\t[overlay] not placing view %p on overlay: "
++ " couldn't get fb\n", ev);
+ return NULL;
++ }
+
+ wl_list_for_each(p, &b->plane_list, link) {
+ if (p->type != WDRM_PLANE_TYPE_OVERLAY)
+@@ -3064,6 +3164,15 @@ drm_output_prepare_overlay_view(struct drm_output_state *output_state,
+ if (!drm_plane_is_available(p, output))
+ continue;
+
++ state = drm_output_state_get_plane(output_state, p);
++ if (state->fb) {
++ state = NULL;
++ continue;
++ }
++
++ if (availability == NO_PLANES)
++ availability = NO_PLANES_WITH_FORMAT;
++
+ /* Check whether the format is supported */
+ for (i = 0; i < p->count_formats; i++) {
+ unsigned int j;
+@@ -3084,15 +3193,14 @@ drm_output_prepare_overlay_view(struct drm_output_state *output_state,
+ if (i == p->count_formats)
+ continue;
+
+- state = drm_output_state_get_plane(output_state, p);
+- if (state->fb) {
+- state = NULL;
+- continue;
+- }
++ if (availability == NO_PLANES_WITH_FORMAT)
++ availability = NO_PLANES_ACCEPTED;
+
+ state->ev = ev;
+ state->output = output;
+ if (!drm_plane_state_coords_for_view(state, ev)) {
++ drm_debug(b, "\t\t\t\t[overlay] not placing view %p on overlay: "
++ "unsuitable transform\n", ev);
+ drm_plane_state_put_back(state);
+ state = NULL;
+ continue;
+@@ -3100,6 +3208,8 @@ drm_output_prepare_overlay_view(struct drm_output_state *output_state,
+ if (!b->atomic_modeset &&
+ (state->src_w != state->dest_w << 16 ||
+ state->src_h != state->dest_h << 16)) {
++ drm_debug(b, "\t\t\t\t[overlay] not placing view %p on overlay: "
++ "no scaling without atomic\n", ev);
+ drm_plane_state_put_back(state);
+ state = NULL;
+ continue;
+@@ -3113,17 +3223,48 @@ drm_output_prepare_overlay_view(struct drm_output_state *output_state,
+
+ /* In planes-only mode, we don't have an incremental state to
+ * test against, so we just hope it'll work. */
+- if (mode == DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY)
++ if (mode == DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY) {
++ drm_debug(b, "\t\t\t\t[overlay] provisionally placing "
++ "view %p on overlay %lu in planes-only mode\n",
++ ev, (unsigned long) p->plane_id);
++ availability = PLACED_ON_PLANE;
+ goto out;
++ }
+
+ ret = drm_pending_state_test(output_state->pending_state);
+- if (ret == 0)
++ if (ret == 0) {
++ drm_debug(b, "\t\t\t\t[overlay] provisionally placing "
++ "view %p on overlay %d in mixed mode\n",
++ ev, p->plane_id);
++ availability = PLACED_ON_PLANE;
+ goto out;
++ }
++
++ drm_debug(b, "\t\t\t\t[overlay] not placing view %p on overlay %lu "
++ "in mixed mode: kernel test failed\n",
++ ev, (unsigned long) p->plane_id);
+
+ drm_plane_state_put_back(state);
+ state = NULL;
+ }
+
++ switch (availability) {
++ case NO_PLANES:
++ drm_debug(b, "\t\t\t\t[overlay] not placing view %p on overlay: "
++ "no free overlay planes\n", ev);
++ break;
++ case NO_PLANES_WITH_FORMAT:
++ drm_debug(b, "\t\t\t\t[overlay] not placing view %p on overlay: "
++ "no free overlay planes matching format 0x%lx, "
++ "modifier 0x%llx\n",
++ ev, (unsigned long) fb->format,
++ (unsigned long long) fb->modifier);
++ break;
++ case NO_PLANES_ACCEPTED:
++ case PLACED_ON_PLANE:
++ break;
++ }
++
+ out:
+ drm_fb_unref(fb);
+ return state;
+@@ -3192,13 +3333,23 @@ drm_output_prepare_cursor_view(struct drm_output_state *output_state,
+ if (b->gbm == NULL)
+ return NULL;
+
+- if (ev->surface->buffer_ref.buffer == NULL)
++ if (ev->surface->buffer_ref.buffer == NULL) {
++ drm_debug(b, "\t\t\t\t[cursor] not assigning view %p to cursor plane "
++ "(no buffer available)\n", ev);
+ return NULL;
++ }
+ shmbuf = wl_shm_buffer_get(ev->surface->buffer_ref.buffer->resource);
+- if (!shmbuf)
++ if (!shmbuf) {
++ drm_debug(b, "\t\t\t\t[cursor] not assigning view %p to cursor plane "
++ "(buffer isn't SHM)\n", ev);
+ return NULL;
+- if (wl_shm_buffer_get_format(shmbuf) != WL_SHM_FORMAT_ARGB8888)
++ }
++ if (wl_shm_buffer_get_format(shmbuf) != WL_SHM_FORMAT_ARGB8888) {
++ drm_debug(b, "\t\t\t\t[cursor] not assigning view %p to cursor plane "
++ "(format 0x%lx unsuitable)\n",
++ ev, (unsigned long) wl_shm_buffer_get_format(shmbuf));
+ return NULL;
++ }
+
+ plane_state =
+ drm_output_state_get_plane(output_state, output->cursor_plane);
+@@ -3216,8 +3367,11 @@ drm_output_prepare_cursor_view(struct drm_output_state *output_state,
+ plane_state->src_w > (unsigned) b->cursor_width << 16 ||
+ plane_state->src_h > (unsigned) b->cursor_height << 16 ||
+ plane_state->src_w != plane_state->dest_w << 16 ||
+- plane_state->src_h != plane_state->dest_h << 16)
++ plane_state->src_h != plane_state->dest_h << 16) {
++ drm_debug(b, "\t\t\t\t[cursor] not assigning view %p to cursor plane "
++ "(positioning requires cropping or scaling)\n", ev);
+ goto err;
++ }
+
+ /* Since we're setting plane state up front, we need to work out
+ * whether or not we need to upload a new cursor. We can't use the
+@@ -3240,8 +3394,10 @@ drm_output_prepare_cursor_view(struct drm_output_state *output_state,
+ plane_state->fb =
+ drm_fb_ref(output->gbm_cursor_fb[output->current_cursor]);
+
+- if (needs_update)
++ if (needs_update) {
++ drm_debug(b, "\t\t\t\t[cursor] copying new content to cursor BO\n");
+ cursor_bo_update(plane_state, ev);
++ }
+
+ /* The cursor API is somewhat special: in cursor_bo_update(), we upload
+ * a buffer which is always cursor_width x cursor_height, even if the
+@@ -3252,6 +3408,9 @@ drm_output_prepare_cursor_view(struct drm_output_state *output_state,
+ plane_state->dest_w = b->cursor_width;
+ plane_state->dest_h = b->cursor_height;
+
++ drm_debug(b, "\t\t\t\t[cursor] provisionally assigned view %p to cursor\n",
++ ev);
++
+ return plane_state;
+
+ err:
+@@ -3347,18 +3506,32 @@ drm_output_propose_state(struct weston_output *output_base,
+ if (!scanout_fb ||
+ (scanout_fb->type != BUFFER_GBM_SURFACE &&
+ scanout_fb->type != BUFFER_PIXMAN_DUMB)) {
++ drm_debug(b, "\t\t[state] cannot propose mixed mode: "
++ "for output %s (%lu): no previous renderer "
++ "fb\n",
++ output->base.name,
++ (unsigned long) output->base.id);
+ drm_output_state_free(state);
+ return NULL;
+ }
+
+ if (scanout_fb->width != output_base->current_mode->width ||
+ scanout_fb->height != output_base->current_mode->height) {
++ drm_debug(b, "\t\t[state] cannot propose mixed mode "
++ "for output %s (%lu): previous fb has "
++ "different size\n",
++ output->base.name,
++ (unsigned long) output->base.id);
+ drm_output_state_free(state);
+ return NULL;
+ }
+
+ scanout_state = drm_plane_state_duplicate(state,
+ plane->state_cur);
++ drm_debug(b, "\t\t[state] using renderer FB ID %lu for mixed "
++ "mode for output %s (%lu)\n",
++ (unsigned long) scanout_fb->fb_id, output->base.name,
++ (unsigned long) output->base.id);
+ }
+
+ /*
+@@ -3384,18 +3557,32 @@ drm_output_propose_state(struct weston_output *output_base,
+ bool totally_occluded = false;
+ bool overlay_occluded = false;
+
++ drm_debug(b, "\t\t\t[view] evaluating view %p for "
++ "output %s (%lu)\n",
++ ev, output->base.name,
++ (unsigned long) output->base.id);
++
+ /* If this view doesn't touch our output at all, there's no
+ * reason to do anything with it. */
+- if (!(ev->output_mask & (1u << output->base.id)))
++ if (!(ev->output_mask & (1u << output->base.id))) {
++ drm_debug(b, "\t\t\t\t[view] ignoring view %p "
++ "(not on our output)\n", ev);
+ continue;
++ }
+
+ /* We only assign planes to views which are exclusively present
+ * on our output. */
+- if (ev->output_mask != (1u << output->base.id))
++ if (ev->output_mask != (1u << output->base.id)) {
++ drm_debug(b, "\t\t\t\t[view] not assigning view %p to plane "
++ "(on multiple outputs)\n", ev);
+ force_renderer = true;
++ }
+
+- if (!ev->surface->buffer_ref.buffer)
++ if (!ev->surface->buffer_ref.buffer) {
++ drm_debug(b, "\t\t\t\t[view] not assigning view %p to plane "
++ "(no buffer available)\n", ev);
+ force_renderer = true;
++ }
+
+ /* Ignore views we know to be totally occluded. */
+ pixman_region32_init(&clipped_view);
+@@ -3408,6 +3595,8 @@ drm_output_propose_state(struct weston_output *output_base,
+ &occluded_region);
+ totally_occluded = !pixman_region32_not_empty(&surface_overlap);
+ if (totally_occluded) {
++ drm_debug(b, "\t\t\t\t[view] ignoring view %p "
++ "(occluded on our output)\n", ev);
+ pixman_region32_fini(&surface_overlap);
+ pixman_region32_fini(&clipped_view);
+ continue;
+@@ -3418,8 +3607,11 @@ drm_output_propose_state(struct weston_output *output_base,
+ * be part of, or occluded by, it, and cannot go on a plane. */
+ pixman_region32_intersect(&surface_overlap, &renderer_region,
+ &clipped_view);
+- if (pixman_region32_not_empty(&surface_overlap))
++ if (pixman_region32_not_empty(&surface_overlap)) {
++ drm_debug(b, "\t\t\t\t[view] not assigning view %p to plane "
++ "(occluded by renderer views)\n", ev);
+ force_renderer = true;
++ }
+
+ /* We do not control the stacking order of overlay planes;
+ * the scanout plane is strictly stacked bottom and the cursor
+@@ -3428,8 +3620,11 @@ drm_output_propose_state(struct weston_output *output_base,
+ * planes overlapping each other. */
+ pixman_region32_intersect(&surface_overlap, &occluded_region,
+ &clipped_view);
+- if (pixman_region32_not_empty(&surface_overlap))
++ if (pixman_region32_not_empty(&surface_overlap)) {
++ drm_debug(b, "\t\t\t\t[view] not assigning view %p to plane "
++ "(occluded by other overlay planes)\n", ev);
+ overlay_occluded = true;
++ }
+ pixman_region32_fini(&surface_overlap);
+
+ /* The cursor plane is 'special' in the sense that we can still
+@@ -3441,10 +3636,16 @@ drm_output_propose_state(struct weston_output *output_base,
+ /* If sprites are disabled or the view is not fully opaque, we
+ * must put the view into the renderer - unless it has already
+ * been placed in the cursor plane, which can handle alpha. */
+- if (!ps && !planes_ok)
++ if (!ps && !planes_ok) {
++ drm_debug(b, "\t\t\t\t[view] not assigning view %p to plane "
++ "(precluded by mode)\n", ev);
+ force_renderer = true;
+- if (!ps && !drm_view_is_opaque(ev))
++ }
++ if (!ps && !drm_view_is_opaque(ev)) {
++ drm_debug(b, "\t\t\t\t[view] not assigning view %p to plane "
++ "(view not fully opaque)\n", ev);
+ force_renderer = true;
++ }
+
+ /* Only try to place scanout surfaces in planes-only mode; in
+ * mixed mode, we have already failed to place a view on the
+@@ -3477,6 +3678,9 @@ drm_output_propose_state(struct weston_output *output_base,
+ * check if this is OK, and add ourselves to the renderer
+ * region if so. */
+ if (!renderer_ok) {
++ drm_debug(b, "\t\t[view] failing state generation: "
++ "placing view %p to renderer not allowed\n",
++ ev);
+ pixman_region32_fini(&clipped_view);
+ goto err_region;
+ }
+@@ -3496,8 +3700,11 @@ drm_output_propose_state(struct weston_output *output_base,
+
+ /* Check to see if this state will actually work. */
+ ret = drm_pending_state_test(state->pending_state);
+- if (ret != 0)
++ if (ret != 0) {
++ drm_debug(b, "\t\t[view] failing state generation: "
++ "atomic test not OK\n");
+ goto err;
++ }
+
+ /* Counterpart to duplicating scanout state at the top of this
+ * function: if we have taken a renderer framebuffer and placed it in
+@@ -3530,12 +3737,24 @@ drm_assign_planes(struct weston_output *output_base, void *repaint_data)
+ struct weston_view *ev;
+ struct weston_plane *primary = &output_base->compositor->primary_plane;
+
++ drm_debug(b, "\t[repaint] preparing state for output %s (%lu)\n",
++ output_base->name, (unsigned long) output_base->id);
++
+ if (!b->sprites_are_broken) {
+ state = drm_output_propose_state(output_base, pending_state,
+ DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY);
+- if (!state)
++ if (!state) {
++ drm_debug(b, "\t[repaint] could not build planes-only "
++ "state, trying mixed\n");
+ state = drm_output_propose_state(output_base, pending_state,
+ DRM_OUTPUT_PROPOSE_STATE_MIXED);
++ }
++ if (!state) {
++ drm_debug(b, "\t[repaint] could not build mixed-mode "
++ "state, trying renderer-only\n");
++ }
++ } else {
++ drm_debug(b, "\t[state] no overlay plane support\n");
+ }
+
+ if (!state)
+@@ -3582,10 +3801,16 @@ drm_assign_planes(struct weston_output *output_base, void *repaint_data)
+ }
+ }
+
+- if (target_plane)
++ if (target_plane) {
++ drm_debug(b, "\t[repaint] view %p on %s plane %lu\n",
++ ev, plane_type_enums[target_plane->type].name,
++ (unsigned long) target_plane->plane_id);
+ weston_view_move_to_plane(ev, &target_plane->base);
+- else
++ } else {
++ drm_debug(b, "\t[repaint] view %p using renderer "
++ "composition\n", ev);
+ weston_view_move_to_plane(ev, primary);
++ }
+
+ if (!target_plane ||
+ target_plane->type == WDRM_PLANE_TYPE_CURSOR) {
+@@ -6264,6 +6489,8 @@ drm_destroy(struct weston_compositor *ec)
+
+ destroy_sprites(b);
+
++ weston_debug_scope_destroy(b->debug);
++ b->debug = NULL;
+ weston_compositor_shutdown(ec);
+
+ wl_list_for_each_safe(base, next, &ec->head_list, compositor_link)
+@@ -6725,6 +6952,10 @@ drm_backend_create(struct weston_compositor *compositor,
+ b->pageflip_timeout = config->pageflip_timeout;
+ b->use_pixman_shadow = config->use_pixman_shadow;
+
++ b->debug = weston_compositor_add_debug_scope(compositor, "drm-backend",
++ "Debug messages from DRM/KMS backend\n",
++ NULL, NULL);
++
+ compositor->backend = &b->base;
+
+ if (parse_gbm_format(config->gbm_format, GBM_FORMAT_XRGB8888, &b->gbm_format) < 0)
+--
+2.16.2
+
diff --git a/bsp/meta-synopsys/recipes-graphics/wayland/weston/1046-compositor-drm-Read-FB2_MODIFIERS-capability.patch b/bsp/meta-synopsys/recipes-graphics/wayland/weston/1046-compositor-drm-Read-FB2_MODIFIERS-capability.patch
new file mode 100644
index 00000000..f3a46b1a
--- /dev/null
+++ b/bsp/meta-synopsys/recipes-graphics/wayland/weston/1046-compositor-drm-Read-FB2_MODIFIERS-capability.patch
@@ -0,0 +1,89 @@
+From a864f58f44d701164dbb32bfcdde8c6d761f28ee Mon Sep 17 00:00:00 2001
+From: Deepak Rawat <drawat@vmware.com>
+Date: Fri, 24 Aug 2018 13:16:03 -0700
+Subject: [PATCH 46/46] compositor-drm: Read FB2_MODIFIERS capability
+
+Not all drivers support fb2 modifiers so read the capability before
+using drmModeAddFB2WithModifiers.
+
+Signed-off-by: Deepak Rawat <drawat@vmware.com>
+---
+ libweston/compositor-drm.c | 20 +++++++++++++++-----
+ 1 file changed, 15 insertions(+), 5 deletions(-)
+
+diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
+index e024e66f..4cf0d31f 100644
+--- a/libweston/compositor-drm.c
++++ b/libweston/compositor-drm.c
+@@ -346,6 +346,8 @@ struct drm_backend {
+
+ bool aspect_ratio_supported;
+
++ bool fb_modifiers;
++
+ struct weston_debug_scope *debug;
+ };
+
+@@ -961,7 +963,7 @@ drm_fb_destroy_gbm(struct gbm_bo *bo, void *data)
+ }
+
+ static int
+-drm_fb_addfb(struct drm_fb *fb)
++drm_fb_addfb(struct drm_backend *b, struct drm_fb *fb)
+ {
+ int ret = -EINVAL;
+ #ifdef HAVE_DRM_ADDFB2_MODIFIERS
+@@ -971,7 +973,7 @@ drm_fb_addfb(struct drm_fb *fb)
+
+ /* If we have a modifier set, we must only use the WithModifiers
+ * entrypoint; we cannot import it through legacy ioctls. */
+- if (fb->modifier != DRM_FORMAT_MOD_INVALID) {
++ if (b->fb_modifiers && fb->modifier != DRM_FORMAT_MOD_INVALID) {
+ /* KMS demands that if a modifier is set, it must be the same
+ * for all planes. */
+ #ifdef HAVE_DRM_ADDFB2_MODIFIERS
+@@ -1055,7 +1057,7 @@ drm_fb_create_dumb(struct drm_backend *b, int width, int height,
+ fb->height = height;
+ fb->fd = b->drm.fd;
+
+- if (drm_fb_addfb(fb) != 0) {
++ if (drm_fb_addfb(b, fb) != 0) {
+ weston_log("failed to create kms fb: %m\n");
+ goto err_bo;
+ }
+@@ -1228,7 +1230,7 @@ drm_fb_get_from_dmabuf(struct linux_dmabuf_buffer *dmabuf,
+ goto err_free;
+ }
+
+- if (drm_fb_addfb(fb) != 0)
++ if (drm_fb_addfb(backend, fb) != 0)
+ goto err_free;
+
+ return fb;
+@@ -1301,7 +1303,7 @@ drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend *backend,
+ goto err_free;
+ }
+
+- if (drm_fb_addfb(fb) != 0) {
++ if (drm_fb_addfb(backend, fb) != 0) {
+ if (type == BUFFER_GBM_SURFACE)
+ weston_log("failed to create kms fb: %m\n");
+ goto err_free;
+@@ -4062,6 +4064,14 @@ init_kms_caps(struct drm_backend *b)
+ weston_log("DRM: %s atomic modesetting\n",
+ b->atomic_modeset ? "supports" : "does not support");
+
++#ifdef HAVE_DRM_ADDFB2_MODIFIERS
++ ret = drmGetCap(b->drm.fd, DRM_CAP_ADDFB2_MODIFIERS, &cap);
++ if (ret == 0)
++ b->fb_modifiers = cap;
++ else
++#endif
++ b->fb_modifiers = 0;
++
+ /*
+ * KMS support for hardware planes cannot properly synchronize
+ * without nuclear page flip. Without nuclear/atomic, hw plane
+--
+2.16.2
+
diff --git a/bsp/meta-synopsys/recipes-graphics/wayland/weston_5.0.0.bbappend b/bsp/meta-synopsys/recipes-graphics/wayland/weston_5.0.0.bbappend
new file mode 100644
index 00000000..ac339435
--- /dev/null
+++ b/bsp/meta-synopsys/recipes-graphics/wayland/weston_5.0.0.bbappend
@@ -0,0 +1,16 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/weston:"
+SRC_URI_append += "\
+ file://1001-os-compatibility-define-CLOCK_BOOTTIME-when-not-avai.patch; \
+ file://1005-protocol-add-weston-debug.xml.patch; \
+ file://1006-libweston-add-weston_debug-API-and-implementation.patch; \
+ file://1007-compositor-add-option-to-enable-weston_debug.patch; \
+ file://1010-xwm-dump_property-to-use-FILE-internally.patch; \
+ file://1011-xwm-move-FILE-to-the-callers-of-dump_property.patch; \
+ file://1012-xwm-convert-WM_DEBUG-into-a-weston-debug-scope.patch; \
+ file://1014-compositor-Add-weston_layer_mask_is_infinite.patch; \
+ file://1015-compositor-Add-scene-graph-debug-scope.patch; \
+ file://1017-compositor-drm-Add-backend-pointer-to-drm_output.patch; \
+ file://1018-compositor-drm-Add-drm-backend-log-debug-scope.patch; \
+ file://1046-compositor-drm-Read-FB2_MODIFIERS-capability.patch; \
+"
+