- **xwm-wm-x11** - a scope for the X11 window manager in Weston for supporting
Xwayland, printing some X11 protocol actions.
- **content-protection-debug** - scope for debugging HDCP issues.
+- **timeline** - see more at :ref:`timeline points`
.. note::
subscription will be created. Enabling the debug-protocol happens using the
:samp:`--debug` command line.
+Timeline points
+---------------
+
+A special log scope is the 'timeline' scope which, together with
+`wesgr <https://github.com/ppaalanen/wesgr>`_ tool, helps diagnose latency issues.
+Timeline points write to this 'timeline' scope in different parts of the
+compositor, including the GL renderer.
+
+As with all other scopes this scope is available over the debug protocol, or by
+using the others :ref:`subscribers`. By far the easiest way to get data out
+of this scope would be to use the debug protocol.
+Then use `wesgr <https://github.com/ppaalanen/wesgr>`_ to process the data which
+will transform it into a SVG that can be rendered by any web browser.
+
+The following illustrates how to use it:
+
+.. code-block:: console
+
+ ./weston-debug timeline > log.json
+ ./wesgr -i log.json -o log.svg
+
+Inserting timeline points
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Timline points can be inserted using :c:macro:`TL_POINT` macro. The macro will
+take the :type:`weston_compositor` instance, followed by the name of the
+timeline point. What follows next is a variable number of arguments, which
+**must** end with the macro :c:macro:`TLP_END`.
+
+Debug protocol API
+------------------
+
.. doxygengroup:: debug-protocol
:content-only:
#include "timeline.h"
#include "weston-log-internal.h"
+/**
+ * Timeline itself is not a subscriber but a scope (a producer of data), and it
+ * re-routes the data it produces to all the subscriptions (and implicitly
+ * to the subscribers) using a subscription iteration to go through all of them.
+ *
+ * Public API:
+ * * weston_timeline_refresh_subscription_objects() - allows outside parts of
+ * libweston notify/signal timeline code about the fact that underlying object
+ * has suffered some modifications and needs to re-emit the object ID.
+ * * weston_log_timeline_point() - which will disseminate data to all
+ * subscriptions
+ *
+ * Do note that only weston_timeline_refresh_subscription_objects()
+ * is exported in libweston.
+ *
+ * Destruction of the objects assigned to each underlying objects happens in
+ * two places: one in the logging framework callback of the log scope
+ * ('destroy_subscription'), and secondly, when the object itself gets
+ * destroyed.
+ *
+ * timeline_emit_context - For each subscription this object will be created to
+ * store a buffer when the object itself will be written and a subscription,
+ * which will be used to force the object ID if there is a need to do so (the
+ * underlying object has been refreshed, or better said has suffered some
+ * modification). Data written to a subscription will be flushed before the
+ * data written to the FILE *.
+ *
+ * @param cur a FILE *
+ * @param subscription a pointer to an already created subscription
+ *
+ * @ingroup internal-log
+ * @sa weston_timeline_point
+ */
struct timeline_emit_context {
FILE *cur;
struct weston_log_subscription *subscription;
return weston_timeline_subscription_search(tl_sub, object);
}
+/** Sets (on) the timeline subscription object refresh status.
+ *
+ * This function 'notifies' timeline to print the object ID. The timeline code
+ * will reset it back, so there's no need for users to do anything about it.
+ *
+ * Can be used from outside libweston.
+ *
+ * @param wc a weston_compositor instance
+ * @param object the underyling object
+ *
+ * @ingroup log
+ */
WL_EXPORT void
weston_timeline_refresh_subscription_objects(struct weston_compositor *wc,
void *object)
[TLT_GPU] = emit_gpu_timestamp,
};
+/** Disseminates the message to all subscriptions of the scope \c
+ * timeline_scope
+ *
+ * The TL_POINT() is a wrapper over this function, but it uses the weston_compositor
+ * instance to pass the timeline scope.
+ *
+ * @param timeline_scope the timeline scope
+ * @param name the name of the timeline point. Interpretable by the tool reading
+ * the output (wesgr).
+ *
+ * @ingroup log
+ */
WL_EXPORT void
weston_timeline_point(struct weston_log_scope *timeline_scope,
const char *name, ...)
TLT_GPU,
};
+/** Timeline subscription created for each subscription
+ *
+ * Created automatically by weston_log_scope::new_subscription and
+ * destroyed by weston_log_scope::destroy_subscription.
+ *
+ * @ingroup internal-log
+ */
struct weston_timeline_subscription {
unsigned int next_id;
struct wl_list objects; /**< weston_timeline_subscription_object::subscription_link */
/**
* Created when object is first seen for a particular timeline subscription
* Destroyed when the subscription got destroyed or object was destroyed
+ *
+ * @ingroup internal-log
*/
struct weston_timeline_subscription_object {
void *object; /**< points to the object */
(void)((type)0 == tmp___); \
tmp___; })
+/**
+ * Should be used as the last argument when using TL_POINT macro
+ *
+ * @ingroup log
+ */
#define TLP_END TLT_END, NULL
+
#define TLP_OUTPUT(o) TLT_OUTPUT, TYPEVERIFY(struct weston_output *, (o))
#define TLP_SURFACE(s) TLT_SURFACE, TYPEVERIFY(struct weston_surface *, (s))
#define TLP_VBLANK(t) TLT_VBLANK, TYPEVERIFY(const struct timespec *, (t))
#define TLP_GPU(t) TLT_GPU, TYPEVERIFY(const struct timespec *, (t))
+/** This macro is used to add timeline points.
+ *
+ * Use TLP_END when done for the vargs.
+ *
+ * @param ec weston_compositor instance
+ *
+ * @ingroup log
+ */
#define TL_POINT(ec, ...) do { \
weston_timeline_point(ec->timeline, __VA_ARGS__); \
} while (0)