{"id":22543291,"url":"https://github.com/sudara/melatonin_perfetto","last_synced_at":"2025-06-14T02:04:52.771Z","repository":{"id":48137409,"uuid":"516563017","full_name":"sudara/melatonin_perfetto","owner":"sudara","description":"Use google's perfetto performance tracing in JUCE plugins and apps","archived":false,"fork":false,"pushed_at":"2025-04-22T15:45:26.000Z","size":146,"stargazers_count":54,"open_issues_count":14,"forks_count":8,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-14T02:03:56.089Z","etag":null,"topics":["cplusplus","juce-framework","juce-modules"],"latest_commit_sha":null,"homepage":"","language":"CMake","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sudara.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"sudara"}},"created_at":"2022-07-22T00:45:45.000Z","updated_at":"2025-06-11T20:19:58.000Z","dependencies_parsed_at":"2024-11-17T14:34:28.004Z","dependency_job_id":"15aa531d-de83-40ea-b18f-cd4f243aaa85","html_url":"https://github.com/sudara/melatonin_perfetto","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sudara/melatonin_perfetto","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudara%2Fmelatonin_perfetto","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudara%2Fmelatonin_perfetto/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudara%2Fmelatonin_perfetto/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudara%2Fmelatonin_perfetto/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sudara","download_url":"https://codeload.github.com/sudara/melatonin_perfetto/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudara%2Fmelatonin_perfetto/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259747214,"owners_count":22905310,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cplusplus","juce-framework","juce-modules"],"created_at":"2024-12-07T13:16:51.485Z","updated_at":"2025-06-14T02:04:52.764Z","avatar_url":"https://github.com/sudara.png","language":"CMake","funding_links":["https://github.com/sponsors/sudara"],"categories":[],"sub_categories":[],"readme":"# Melatonin Perfetto\n\n[![](https://github.com/sudara/melatonin_perfetto/workflows/CI/badge.svg)](https://github.com/sudara/melatonin_perfetto/actions)\n\nSounds like an ice cream flavor (albeit a sleepy one).\n\nHowever, it's just a way to use the amazing [Perfetto](http://perfetto.dev) performance tracing in JUCE.\n\n[Perfetto](https://perfetto.dev) lets you accurately measure different parts of your code and visualize it over time. It's the successor to [`chrome://tracing`](https://slack.engineering/chrome-tracing-for-fun-and-profit/). \n\n![image-1024x396](https://user-images.githubusercontent.com/472/180338251-ce3c5814-ff9c-4fbb-a8c0-9caefc2f34dc.png)\n\n## Why would I use Perfetto instead of the profiler?\n\n✨  \n✨✨  \n✨✨✨  \n### [Read the blog post!](https://melatonin.dev/blog/using-perfetto-with-juce-for-dsp-and-ui-performance-tuning)\n✨✨✨  \n✨✨  \n✨  \n\n## Requirements\n\n* JUCE, any version after JUCE 5 should be happy\n* C++17 (a Perfetto requirement since v31.0) \n\n## Installing with CMake\n\nWe worked hard so you don't have to. \n\nNot only do we handle building Perfetto (which is fairly annoying on Windows), but we've made it very easy to add this module into your CMake projects.\n\nYou have several options. In all cases, the exported target you should link against is: `Melatonin::Perfetto`.\n\n### Option #1: `FetchContent`\n\nExample usage:\n```cmake\ninclude (FetchContent)\n\nFetchContent_Declare (melatonin_perfetto\n  GIT_REPOSITORY https://github.com/sudara/melatonin_perfetto.git\n  GIT_TAG origin/main)\n\nFetchContent_MakeAvailable (melatonin_perfetto)\n\ntarget_link_libraries (yourTarget PRIVATE Melatonin::Perfetto)\n```\n\n### Option #2: submodules and `add_subdirectory`\n\nIf you are a git submodule aficionado, add this repository as a git submodule to your project:\n```sh\ngit submodule add -b main https://github.com/sudara/melatonin_perfetto.git modules/melatonin_perfetto\n```\nand then simply call `add_subdirectory` in your CMakeLists.txt:\n```cmake\nadd_subdirectory (modules/melatonin_perfetto)\n\ntarget_link_libraries (yourTarget PRIVATE Melatonin::Perfetto)\n```\n\n### Option #3: Installing and using `find_package`\n\nInstall the module to your system by cloning the code and then running the following commands:\n```sh\ncmake -B Builds\ncmake --build Builds\ncmake --install Builds\n```\n\nThe `--install` command will write to system directories, so it may require `sudo`.\n\nOnce this module is installed to your system, you can simply add to your CMake project:\n```cmake\nfind_package (MelatoninPerfetto)\n\ntarget_link_libraries (yourTarget PRIVATE Melatonin::Perfetto)\n```\n\n## Installing with Projucer\n\n### Step 1: Download the Perfetto SDK\n\nIt can go anywhere. You'll actually need to use git to grab it though, there's no way to download it otherwise. Paste this into your macOS terminal (or download git on windows and use git bash):\n\n```\ngit clone https://android.googlesource.com/platform/external/perfetto -b v31.0\n```\n\n### Step 2: Download this module and add to your project\n\nUse git to add it as a submodule if you'd like stay up to date with any changes:\n\n```\ngit submodule add -b main https://github.com/sudara/melatonin_perfetto.git modules/melatonin_perfetto\n```\n\nOr just download it and stick it somewhere.\n\nBe sure to add it in Projucer under \"Modules\".\n\n\n### Step 3: Add the perfetto headers in File Explorer\n\nThis is necessary to actually compile the perfetto tracing sdk from source.\n\nIn the File Explorer, hit the `+`, `Add Existing Files` and make sure the following two are added:\n\n```\nsdk/perfetto.h\nsdk/perfetto.cc\n```\n\n### Step 4: Add to your project's Header Search Paths\n\nIn the Project Settings (gear at the top right of the sidebar), tell the Projucer where to find `perfetto/sdk` folder.\n\nFor example, if you downloaded it as a sibling folder to the project, you would add the following to `Header Search Paths`:\n\n```\n../perfetto/sdk\n```\n\n### Step 5: Add read/write permissions where necessary (macOS)\n\nIf you have `App Sandbox` enabled, you'll have to enable the following:\n\n```\n`File Access: Read/Write: Download Folder (Read/Write)` \n```\n\nThis lets perfetto write out the trace files.\n\n\n\u003cimg src=\"https://user-images.githubusercontent.com/472/213724719-be39512e-cda2-43cb-a589-0c3478625228.jpg\" width=\"400\"/\u003e\n\n\n### Step 5: Add compile flags and preprocessor definitions (Windows)\n\nWindows Projucer builds [require some extra love](https://forum.juce.com/t/new-module-profile-your-juce-ui-dsp-performance-with-perfetto/54589/43?u=sudara).\n\nGo to the Settings page for the Visual Studio Exporter and add these to \"Extra Compile Flags\":\n\n```\n/bigobj\n/Zc:__cplusplus\n/permissive-\n/Zc:externC-\n```\n\nIn addition, you'll need the following \"Extra Preprocessor Definitions\" set on that same page:\n\n```\nNOMINMAX=1 \nWIN32_LEAN_AND_MEAN=1\n```\n\n### Step 6: Enable/Disable via the Projucer\n\nAs you'll see in \"How to use\", you can toggle perfetto traces on/off by adding the following in the exporter's preprocessor definitions:\n\n```\nPERFETTO=1\n```\n\nIf that's too clunky, you can also just toggle in the source (read more below).\n\n## How to use\n\n### Step 1: Add a few pieces of guarded code to your plugin\n\nInclude library:\n```cpp\n#include \u003cmelatonin_perfetto/melatonin_perfetto.h\u003e\n```\n\nAdd a member of the plugin processor, guarded by a preprocessor definition:\n```cpp\n#if PERFETTO\n    MelatoninPerfetto tracingSession;\n#endif\n```\n\nThat's it! Earlier versions (1.2 and before) had MelatoninPerfetto as a singleton that you'd have to setup in the constructor, but now it's just a regular class. \n\n### Step 2: Pepper around some sweet sweet trace macros\n\nPerfetto will *only* measure functions you specifically tell it to.\n\nPepper around `TRACE_DSP()` or `TRACE_COMPONENT()` macros at the start of the functions you want to measure.\n\nFor example, in your `PluginProcessor::processBlock`:\n\n```cpp\nvoid SineMachineAudioProcessor::processBlock (juce::AudioBuffer\u003cfloat\u003e\u0026 buffer, juce::MidiBuffer\u0026 midiMessages)\n{\n    TRACE_DSP();\n    \n    // your dsp code here\n}\n```\n\nor a component's `paint` method:\n\n```cpp\nvoid paint (juce::Graphics\u0026 g) override\n{\n    TRACE_COMPONENT();\n    \n    // your paint code here\n}\n```\n\nBy default, perfetto is disabled (`PERFETTO=0`) and the macros will evaporate on compile, so feel free to leave them in your code, especially if you plan on profiling again in the future.\n\n### Step 3: Enable profiling\n\nWhen you are ready to profile, you'll need to set `PERFETTO=1` \n\nThis module offers a CMake option, `PERFETTO`, that when `ON`, adds the `PERFETTO` symbol to the module's exported\ncompile definitions. This CMake option \nis an easy way for you to turn tracing on and off from the command line when building your project:\n\n```sh\ncmake -B build -D PERFETTO=ON\n```\nThe value of `PERFETTO` will be saved in the CMake cache, so you don't need to re-specify this every time you re-run\nCMake configure. \n\nTo turn it off again, you can do:\n```sh\ncmake -B build -D PERFETTO=OFF\n```\n\nYou can add this as a CMake option in your IDE build settings, for example in CLion:\n\n\u003cimg width=\"254\" alt=\"CLion - 2023-01-07 06@2x\" src=\"https://user-images.githubusercontent.com/472/211118287-0a3cd6bb-84e3-430b-a7d4-34474e51e42d.png\"\u003e\n\n\nAaaaand if you are lazy like Sudara sometimes is, you can just edit melatonin_perfetto and change the default to `PERFETTO=1`...\n\nThat'll actually include the google lib and will profile the code.\n\n### Step 4: Run your app \n\nReminder: do you want to profile Release? Probably! I love profiling Debug builds too, but if you are looking for real-world numbers, you'll want to use Release.\n\nStart your app and perform the actions you want traced.\n\nWhen you quit your app, a trace file will be dumped \n\n**(Note: don't just terminate it via your IDE, the file will be only dumped on a graceful quit)**.\n\n### Step 5: Drag the trace into Perfetto\n\nFind the trace file and drag it into https://ui.perfetto.dev\n\nYou can keep the macros peppered around in your app during normal dev/release. \n\nJust remember to set `PERFETTO` back to `0` or `OFF` so everything gets turned into a no-op. \n\n## Customizing\n\nBy default, there are two perfetto \"categories\" defined, `dsp` and `components`. \n\nThe current function name is passed as the name. \n\n\nYou can also add custom parameters that will show up in perfetto's UI:\n\n```cpp\nTRACE_DSP(\"startSample\", startSample, \"numSamples\", numSamples);\n```\n\n### TRACE_EVENT\n\nYou can also use the built in `TRACE_EVENT` which takes a name if you don't want it to derive a name based on the function.\n\nThis is also if you want to do things like have multiple traces in a function, for example in a loop.\n\n```cpp\n    TRACE_DSP(); // start the trace, use the function name\n    \n    if (someCondition)\n    {\n        TRACE_EVENT(\"dsp\", \"someCondition\");\n        // do something expensive,  traced separately\n    }\n\n    moreFuctionCode(); // included in the main trace\n```\n\n\n### TRACE_EVENT_BEGIN and TRACE_EVENT_END\n\nSometimes you want to go full granular and not just depend on scoping.\n\nTo do this, use `TRACE_EVENT_BEGIN` and `TRACE_EVENT_END`:\n\n```cpp\nTRACE_EVENT_BEGIN (\"dsp\", \"memset\");\n// CLEAR the temp buffer\ntemp.clear();\nTRACE_EVENT_END (\"dsp\");\n\n```\n\n### Dynamic Names\n\nPerfetto is optimized to be low overhead, shipping in RELEASE production builds. By default usage is via compile-time strings. \n\nWorking with strings dynamically introduces runtime overhead — but hey, sometimes you just want to look at something real quick. For those cases, Perfetto provides a helper:\n\n```\nTRACE_EVENT (\"dsp\", perfetto::DynamicString{my_dynamic_string});\n```\n\n\n### \"Solo\" the message or audio thread\n\nIf you are focusing on UI and want to temporarily rid of the audio thread in the trace, set `PERFETTO_ENABLE_TRACE_DSP=0` in your preprocessor definitions (or just modify the header like I do) and it will be a no-op.\n\nYou can do the reverse and disable all UI component tracing on the message thread with `PERFETTO_ENABLE_TRACE_COMPONENT=0`.\n\nGo wild! \n\n\n## Assumptions / Caveats\n\n* On Mac, the trace is dumped to your Downloads folder. On Windows, it's dumped to your Desktop (sorry not sorry).\n* Traces are set to in memory, 80MB by default.\n\n## Troubleshooting\n\n### Perfetto gives me an error about C++17 on Windows\n\nMake sure you are passing the `/Zc:__cplusplus` flag so MSVC's version detection actually works, see [this link](https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/)\n\nIn CMake:\n\n```\ntarget_compile_options(\"${PROJECT_NAME}\" PUBLIC /Zc:__cplusplus)\n\n```\n\n### I don't see a trace file\n\nDid you quit your app gracefully, such as with cmd-Q? If you instead just hit STOP on your IDE, you won't get a trace file.\n\n### My traces appear empty\n\nYou probably went over the memory size that Perfetto is set to use by default (80MB). \n\nIf you are doing intensive profiling with lots of functions being called many times, you'll probably want to increase this limit. You can do this by passing the number of `kb` you want to `beginSession`:\n\n```\nMelatoninPerfetto::get().beginSession(300000); # 300MB\n```\n\n### I keep forgetting to turn perfetto off!\n\nGet warned by your tests if someone left `PERFETTO=1` on with a test like this (this example is Catch2):\n\n```c++\nTEST_CASE (\"Perfetto not accidentally left enabled\", \"[perfetto]\")\n{\n#if defined(PERFETTO) \u0026\u0026 PERFETTO\n    FAIL_CHECK (\"PERFETTO IS ENABLED\");\n#else\n    SUCCEED (\"PERFETTO DISABLED\");\n#endif\n}\n```\n\nIf you use perfetto regularly, you can also do what I do and check for `PERFETTO` in your plugin editor and display something in the UI:\n\n\u003cimg width=\"384\" alt=\"AudioPluginHost - 2023-01-06 44@2x\" src=\"https://user-images.githubusercontent.com/472/211118327-e984f359-4e2f-4aec-8b4d-991093b36e67.png\"\u003e\n\n## Running Perfetto in your tests\n\nIt can be really nice to run a few test cases through perfetto. \n\nTo do so with Catch2, for example, you'll need to first link against `Catch2::Catch2` instead of `Catch2::Catch2WithMain`:\n\n```\ntarget_link_libraries(Tests PRIVATE SharedCode Catch2::Catch2WithMain)\n```\n\nAnd then define your own `main` function. \n\n```cpp\n#include \"melatonin_perfetto/melatonin_perfetto.h\"\nint main (int argc, char* argv[])\n{\n#if PERFETTO\n    MelatoninPerfetto perfetto;\n#endif\n\n    const int result = Catch::Session().run (argc, argv);\n\n    return result;\n}\n```\n\n## Running Melatonin::Perfetto's tests\n\n`melatonin_perfetto` includes a test suite using CTest. To run the tests, clone the code and run these commands:\n```sh\ncmake -B Builds\ncmake --build Builds --config Debug\ncd Builds\nctest -C Debug\n```\n\nThe tests attempt to build two minimal CMake projects that depend on the `melatonin_perfetto` module; one tests\nfinding an install tree using `find_package()` and one tests calling `add_subdirectory()`. These tests serve to\nverify that this module's packaging and installation scripts are correct, and that it can be successfully imported\nto other projects using the methods advertised above. Another test case verifies that attempting to configure a \nproject that adds `melatonin_perfetto` before JUCE will fail with the proper error message.\n\n## Acknowledgements\n\n* Thanks to [@benthevining](https://github.com/benthevining) for extra CMake love and tests!\n* Thanks to [@dikadk](https://github.com/dikadk) for getting a Projucer version running on MacOS \n* Thanks to stephenk for putting in the effort to [getting the Projucer version working on Windows](https://forum.juce.com/t/new-module-profile-your-juce-ui-dsp-performance-with-perfetto/54589/43?u=sudara).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsudara%2Fmelatonin_perfetto","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsudara%2Fmelatonin_perfetto","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsudara%2Fmelatonin_perfetto/lists"}