blob: ed1e2ec89cf95bab6dfd5bbe57c8d881e945fb3e [file] [log] [blame]
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#undef LOG_TAG
#define LOG_TAG "LayerTracing"
#include "LayerDataSource.h"
#include <log/log.h>
#include <perfetto/config/android/surfaceflinger_layers_config.pbzero.h>
namespace android {
void LayerDataSource::Initialize(LayerTracing& layerTracing) {
mLayerTracing.store(&layerTracing);
auto args = perfetto::TracingInitArgs{};
args.backends = perfetto::kSystemBackend;
// We are tracing ~50kb/entry and the default shmem buffer size (256kb) could be overrun.
// A shmem buffer overrun typically just stalls layer tracing, however when the stall
// lasts for too long perfetto assumes there is a deadlock and aborts surfaceflinger.
args.shmem_size_hint_kb = 1024;
perfetto::Tracing::Initialize(args);
perfetto::DataSourceDescriptor descriptor;
descriptor.set_name(android::LayerDataSource::kName);
LayerDataSource::Register(descriptor);
}
void LayerDataSource::UnregisterLayerTracing() {
mLayerTracing.store(nullptr);
}
void LayerDataSource::OnSetup(const LayerDataSource::SetupArgs& args) {
const auto configRaw = args.config->surfaceflinger_layers_config_raw();
const auto config = perfetto::protos::pbzero::SurfaceFlingerLayersConfig::Decoder{configRaw};
if (config.has_mode() && config.mode() != LayerTracing::Mode::MODE_UNSPECIFIED) {
mMode = static_cast<LayerTracing::Mode>(config.mode());
} else {
mMode = LayerTracing::Mode::MODE_GENERATED_BUGREPORT_ONLY;
ALOGD("Received config with unspecified 'mode'."
" Using 'MODE_GENERATED_BUGREPORT_ONLY' as default");
}
mFlags = 0;
for (auto it = config.trace_flags(); it; ++it) {
mFlags |= static_cast<uint32_t>(*it);
}
}
void LayerDataSource::OnStart(const LayerDataSource::StartArgs&) {
ALOGD("Received OnStart event (mode = 0x%02x, flags = 0x%02x)", mMode, mFlags);
if (auto* p = mLayerTracing.load()) {
p->onStart(mMode, mFlags);
}
}
void LayerDataSource::OnFlush(const LayerDataSource::FlushArgs& args) {
ALOGD("Received OnFlush event"
" (mode = 0x%02x, flags = 0x%02x, reason = 0x%" PRIx64 ", clone_target = 0x%0" PRIx64 ")",
mMode, mFlags, args.flush_flags.reason(), args.flush_flags.clone_target());
bool isBugreport = args.flush_flags.reason() == perfetto::FlushFlags::Reason::kTraceClone &&
args.flush_flags.clone_target() == perfetto::FlushFlags::CloneTarget::kBugreport;
if (auto* p = mLayerTracing.load()) {
p->onFlush(mMode, mFlags, isBugreport);
}
}
void LayerDataSource::OnStop(const LayerDataSource::StopArgs&) {
ALOGD("Received OnStop event (mode = 0x%02x, flags = 0x%02x)", mMode, mFlags);
if (auto* p = mLayerTracing.load()) {
p->onStop(mMode);
}
}
LayerTracing::Mode LayerDataSource::GetMode() const {
return mMode;
}
std::atomic<LayerTracing*> LayerDataSource::mLayerTracing = nullptr;
} // namespace android
PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(android::LayerDataSource);