[libcamera-devel] [PATCH 1/1] Use tracing with perfetto in ChromeOS

Harvey Yang chenghaoyang at chromium.org
Wed Jun 15 16:20:51 CEST 2022


As ChromeOS is using perfetto (project named as CrOSetto). When ChromeOS
uses libcamera, it should use perfetto to collect traces instead of
lttng.

Signed-off-by: Harvey Yang <chenghaoyang at chromium.org>
---
 include/libcamera/internal/tracepoints.h.in   | 37 +++++++++--
 .../internal/tracepoints/meson.build          | 25 ++++---
 .../internal/tracepoints/pipeline.perfetto    | 10 +++
 .../internal/tracepoints/request.perfetto     | 30 +++++++++
 meson.build                                   |  1 +
 src/android/cros/camera3_hal.cpp              |  5 ++
 src/android/cros/meson.build                  |  1 +
 src/libcamera/meson.build                     | 18 ++++-
 src/libcamera/pipeline_perfetto.cpp           | 22 +++++++
 src/libcamera/request_perfetto.cpp            | 65 +++++++++++++++++++
 src/libcamera/tracepoints.cpp                 | 11 ++++
 11 files changed, 209 insertions(+), 16 deletions(-)
 create mode 100644 include/libcamera/internal/tracepoints/pipeline.perfetto
 create mode 100644 include/libcamera/internal/tracepoints/request.perfetto
 create mode 100644 src/libcamera/pipeline_perfetto.cpp
 create mode 100644 src/libcamera/request_perfetto.cpp

diff --git a/include/libcamera/internal/tracepoints.h.in b/include/libcamera/internal/tracepoints.h.in
index d0fc1365..d91fadd7 100644
--- a/include/libcamera/internal/tracepoints.h.in
+++ b/include/libcamera/internal/tracepoints.h.in
@@ -9,7 +9,24 @@
 #ifndef __LIBCAMERA_INTERNAL_TRACEPOINTS_H__
 #define __LIBCAMERA_INTERNAL_TRACEPOINTS_H__
 
-#if HAVE_TRACING
+#if HAVE_PERFETTO
+
+#include <perfetto/perfetto.h>
+
+PERFETTO_DEFINE_CATEGORIES(
+	perfetto::Category("libcamera")
+		.SetDescription("Events from libcamera"));
+
+#define LIBCAMERA_TRACEPOINT(t_name, ...) \
+LIBCAMERA_TRACE_EVENT_##t_name(__VA_ARGS__)
+
+#define LIBCAMERA_TRACEPOINT_IPA_BEGIN(pipe, func) \
+LIBCAMERA_TRACE_EVENT_ipa_call_begin(#pipe, #func)
+
+#define LIBCAMERA_TRACEPOINT_IPA_END(pipe, func) \
+LIBCAMERA_TRACE_EVENT_ipa_call_end(#pipe, #func)
+
+#elif HAVE_TRACING /* !HAVE_PERFETTO */
 #define LIBCAMERA_TRACEPOINT(...) tracepoint(libcamera, __VA_ARGS__)
 
 #define LIBCAMERA_TRACEPOINT_IPA_BEGIN(pipe, func) \
@@ -18,7 +35,7 @@ tracepoint(libcamera, ipa_call_begin, #pipe, #func)
 #define LIBCAMERA_TRACEPOINT_IPA_END(pipe, func) \
 tracepoint(libcamera, ipa_call_end, #pipe, #func)
 
-#else
+#else /* HAVE_PERFETTO */
 
 namespace {
 
@@ -34,12 +51,15 @@ inline void unused([[maybe_unused]] Args&& ...args)
 #define LIBCAMERA_TRACEPOINT_IPA_BEGIN(pipe, func)
 #define LIBCAMERA_TRACEPOINT_IPA_END(pipe, func)
 
-#endif /* HAVE_TRACING */
+#endif /* HAVE_PERFETTO */
 
 #endif /* __LIBCAMERA_INTERNAL_TRACEPOINTS_H__ */
 
+#if HAVE_PERFETTO
+
+#include <perfetto/perfetto.h>
 
-#if HAVE_TRACING
+#elif HAVE_TRACING
 
 #undef TRACEPOINT_PROVIDER
 #define TRACEPOINT_PROVIDER libcamera
@@ -52,10 +72,15 @@ inline void unused([[maybe_unused]] Args&& ...args)
 
 #include <lttng/tracepoint.h>
 
-{{source}}
 
 #endif /* INCLUDE_LIBCAMERA_INTERNAL_TRACEPOINTS_TP_H */
 
 #include <lttng/tracepoint-event.h>
 
-#endif /* HAVE_TRACING */
+#endif /* HAVE_PERFETTO */
+
+#if HAVE_PERFETTO || HAVE_TRACING
+
+{{source}}
+
+#endif /* HAVE_PERFETTO || HAVE_TRACING */
diff --git a/include/libcamera/internal/tracepoints/meson.build b/include/libcamera/internal/tracepoints/meson.build
index d9b2fca5..ff5aece6 100644
--- a/include/libcamera/internal/tracepoints/meson.build
+++ b/include/libcamera/internal/tracepoints/meson.build
@@ -1,12 +1,19 @@
 # SPDX-License-Identifier: CC0-1.0
 
-# enum files must go first
-tracepoint_files = files([
-    'buffer_enums.tp',
-    'request_enums.tp',
-])
+if get_option('android').enabled() and get_option('android_platform') == 'cros'
+  tracepoint_files = files([
+      'pipeline.perfetto',
+      'request.perfetto',
+  ])
+else
+  # enum files must go first
+  tracepoint_files = files([
+      'buffer_enums.tp',
+      'request_enums.tp',
+  ])
 
-tracepoint_files += files([
-    'pipeline.tp',
-    'request.tp',
-])
+  tracepoint_files += files([
+      'pipeline.tp',
+      'request.tp',
+  ])
+endif
diff --git a/include/libcamera/internal/tracepoints/pipeline.perfetto b/include/libcamera/internal/tracepoints/pipeline.perfetto
new file mode 100644
index 00000000..5f45295e
--- /dev/null
+++ b/include/libcamera/internal/tracepoints/pipeline.perfetto
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2022, Google Inc.
+ *
+ * pipeline.tp - Tracepoints for pipelines
+ */
+
+void LIBCAMERA_TRACE_EVENT_ipa_call_begin(const char *pipe, const char *func);
+
+void LIBCAMERA_TRACE_EVENT_ipa_call_end(const char *pipe, const char *func);
diff --git a/include/libcamera/internal/tracepoints/request.perfetto b/include/libcamera/internal/tracepoints/request.perfetto
new file mode 100644
index 00000000..fd6a42a4
--- /dev/null
+++ b/include/libcamera/internal/tracepoints/request.perfetto
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2022, Google Inc.
+ *
+ * request.tp - Tracepoints for the request object
+ */
+
+#include <libcamera/internal/request.h>
+
+#include <libcamera/framebuffer.h>
+
+void LIBCAMERA_TRACE_EVENT_request(libcamera::Request *req);
+
+void LIBCAMERA_TRACE_EVENT_request_construct(libcamera::Request *req);
+
+void LIBCAMERA_TRACE_EVENT_request_destroy(libcamera::Request *req);
+
+void LIBCAMERA_TRACE_EVENT_request_reuse(libcamera::Request *req);
+
+void LIBCAMERA_TRACE_EVENT_request_queue(libcamera::Request *req);
+
+void LIBCAMERA_TRACE_EVENT_request_device_queue(libcamera::Request *req);
+
+void LIBCAMERA_TRACE_EVENT_request_complete(libcamera::Request::Private *req);
+
+void LIBCAMERA_TRACE_EVENT_request_cancel(libcamera::Request::Private *req);
+
+void LIBCAMERA_TRACE_EVENT_request_complete_buffer(
+		libcamera::Request::Private *req,
+		libcamera::FrameBuffer * buf);
diff --git a/meson.build b/meson.build
index 29d8542d..053bb831 100644
--- a/meson.build
+++ b/meson.build
@@ -176,6 +176,7 @@ py_mod.find_installation('python3', modules: py_modules)
 summary({
             'Enabled pipelines': pipelines,
             'Enabled IPA modules': ipa_modules,
+            'Perfetto support': perfetto_enabled,
             'Tracing support': tracing_enabled,
             'Android support': android_enabled,
             'GStreamer support': gst_enabled,
diff --git a/src/android/cros/camera3_hal.cpp b/src/android/cros/camera3_hal.cpp
index fb863b5f..2fbd7f14 100644
--- a/src/android/cros/camera3_hal.cpp
+++ b/src/android/cros/camera3_hal.cpp
@@ -7,10 +7,15 @@
 
 #include <cros-camera/cros_camera_hal.h>
 
+#include "libcamera/internal/tracepoints.h"
 #include "../camera_hal_manager.h"
 
 static void set_up([[maybe_unused]] cros::CameraMojoChannelManagerToken *token)
 {
+	perfetto::TracingInitArgs args;
+	args.backends |= perfetto::kSystemBackend;
+	perfetto::Tracing::Initialize(args);
+	perfetto::TrackEvent::Register();
 }
 
 static void tear_down()
diff --git a/src/android/cros/meson.build b/src/android/cros/meson.build
index 35995dd8..68f2bd9e 100644
--- a/src/android/cros/meson.build
+++ b/src/android/cros/meson.build
@@ -9,5 +9,6 @@ android_hal_sources += files([
 ])
 
 android_deps += dependency('libcros_camera')
+android_deps += dependency('perfetto')
 
 android_cpp_args += ['-DOS_CHROMEOS']
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
index 26912ca1..3332cc05 100644
--- a/src/libcamera/meson.build
+++ b/src/libcamera/meson.build
@@ -71,11 +71,22 @@ if libgnutls.found()
     config_h.set('HAVE_GNUTLS', 1)
 endif
 
-if liblttng.found()
+if get_option('android').enabled() and get_option('android_platform') == 'cros'
+    perfetto_enabled = true
+    tracing_enabled = false
+    config_h.set('HAVE_PERFETTO', 1)
+    libcamera_sources += [
+        'pipeline_perfetto.cpp',
+        'request_perfetto.cpp',
+        'tracepoints.cpp',
+    ]
+elif liblttng.found()
+    perfetto_enabled = false
     tracing_enabled = true
     config_h.set('HAVE_TRACING', 1)
     libcamera_sources += files(['tracepoints.cpp'])
 else
+    perfetto_enabled = false
     tracing_enabled = false
 endif
 
@@ -128,6 +139,11 @@ libcamera_deps = [
     libudev,
 ]
 
+if perfetto_enabled
+  perfetto = dependency('perfetto', required : true)
+  libcamera_deps += [ perfetto ]
+endif
+
 # We add '/' to the build_rpath as a 'safe' path to act as a boolean flag.
 # The build_rpath is stripped at install time by meson, so we determine at
 # runtime if the library is running from an installed location by checking
diff --git a/src/libcamera/pipeline_perfetto.cpp b/src/libcamera/pipeline_perfetto.cpp
new file mode 100644
index 00000000..d0ddc17d
--- /dev/null
+++ b/src/libcamera/pipeline_perfetto.cpp
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2022, Google Inc.
+ *
+ * pipeline.tp - Tracepoints for pipelines
+ */
+
+#include "libcamera/internal/tracepoints.h"
+
+void LIBCAMERA_TRACE_EVENT_ipa_call_begin(const char *pipe, const char *func) {
+	// TODO: Consider TRACE_EVENT_BEGIN
+	TRACE_EVENT("libcamera", "ipa_call_begin",
+		    "pipeline_name", pipe,
+		    "function_name", func);
+}
+
+void LIBCAMERA_TRACE_EVENT_ipa_call_end(const char *pipe, const char *func) {
+	// TODO: Consider TRACE_EVENT_END
+	TRACE_EVENT("libcamera", "ipa_call_end",
+		    "pipeline_name", pipe,
+		    "function_name", func);
+}
diff --git a/src/libcamera/request_perfetto.cpp b/src/libcamera/request_perfetto.cpp
new file mode 100644
index 00000000..c82cce33
--- /dev/null
+++ b/src/libcamera/request_perfetto.cpp
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2022, Google Inc.
+ *
+ * request.tp - Tracepoints for the request object
+ */
+
+
+#include <libcamera/framebuffer.h>
+
+#include "libcamera/internal/request.h"
+#include "libcamera/internal/tracepoints.h"
+
+void LIBCAMERA_TRACE_EVENT_request(libcamera::Request *req) {
+	TRACE_EVENT("libcamera", "request",
+		    "request_ptr", reinterpret_cast<uintptr_t>(req),
+		    "cookie", req->cookie(),
+		    "status", req->status()); // TODO
+}
+
+void LIBCAMERA_TRACE_EVENT_request_construct(libcamera::Request *req) {
+	TRACE_EVENT("libcamera", "request_construct",
+		    "request_ptr", reinterpret_cast<uintptr_t>(req));
+}
+
+void LIBCAMERA_TRACE_EVENT_request_destroy(libcamera::Request *req) {
+	TRACE_EVENT("libcamera", "request_destroy",
+		    "request_ptr", reinterpret_cast<uintptr_t>(req));
+}
+
+void LIBCAMERA_TRACE_EVENT_request_reuse(libcamera::Request *req) {
+	TRACE_EVENT("libcamera", "request_reuse",
+		    "request_ptr", reinterpret_cast<uintptr_t>(req));
+}
+
+void LIBCAMERA_TRACE_EVENT_request_queue(libcamera::Request *req) {
+	TRACE_EVENT("libcamera", "request_queue",
+		    "request_ptr", reinterpret_cast<uintptr_t>(req));
+}
+
+void LIBCAMERA_TRACE_EVENT_request_device_queue(libcamera::Request *req) {
+	TRACE_EVENT("libcamera", "request_device_queue",
+		    "request_ptr", reinterpret_cast<uintptr_t>(req));
+}
+
+void LIBCAMERA_TRACE_EVENT_request_complete(libcamera::Request::Private *req) {
+	TRACE_EVENT("libcamera", "request_complete",
+		    "request_private_ptr", reinterpret_cast<uintptr_t>(req));
+}
+
+void LIBCAMERA_TRACE_EVENT_request_cancel(libcamera::Request::Private *req) {
+	TRACE_EVENT("libcamera", "request_cancel",
+		    "request_private_ptr", reinterpret_cast<uintptr_t>(req));
+}
+
+void LIBCAMERA_TRACE_EVENT_request_complete_buffer(
+		libcamera::Request::Private *req,
+		libcamera::FrameBuffer * buf) {
+	TRACE_EVENT("libcamera", "request_complete_buffer",
+		    "request_private_ptr", reinterpret_cast<uintptr_t>(req),
+		    "cookie", req->_o<libcamera::Request>()->cookie(),
+		    "status", req->_o<libcamera::Request>()->status(), // TODO
+		    "buffer_ptr", reinterpret_cast<uintptr_t>(buf),
+		    "buffer_status", buf->metadata().status); // TODO
+}
diff --git a/src/libcamera/tracepoints.cpp b/src/libcamera/tracepoints.cpp
index 0173b75a..a07ea531 100644
--- a/src/libcamera/tracepoints.cpp
+++ b/src/libcamera/tracepoints.cpp
@@ -4,7 +4,18 @@
  *
  * tracepoints.cpp - Tracepoints with lttng
  */
+
+#if HAVE_PERFETTO
+
+#include "libcamera/internal/tracepoints.h"
+
+PERFETTO_TRACK_EVENT_STATIC_STORAGE();
+
+#else
+
 #define TRACEPOINT_CREATE_PROBES
 #define TRACEPOINT_DEFINE
 
 #include "libcamera/internal/tracepoints.h"
+
+#endif /* HAVE_PERFETTO */
-- 
2.36.1.476.g0c4daa206d-goog



More information about the libcamera-devel mailing list