| Vishnu Nair | 00b9013 | 2021-11-05 14:03:40 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright 2021 The Android Open Source Project | 
 | 3 |  * | 
 | 4 |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
 | 5 |  * you may not use this file except in compliance with the License. | 
 | 6 |  * You may obtain a copy of the License at | 
 | 7 |  * | 
 | 8 |  *      http://www.apache.org/licenses/LICENSE-2.0 | 
 | 9 |  * | 
 | 10 |  * Unless required by applicable law or agreed to in writing, software | 
 | 11 |  * distributed under the License is distributed on an "AS IS" BASIS, | 
 | 12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | 13 |  * See the License for the specific language governing permissions and | 
 | 14 |  * limitations under the License. | 
 | 15 |  */ | 
 | 16 |  | 
 | 17 | #undef LOG_TAG | 
 | 18 | #define LOG_TAG "LayerTracing" | 
 | 19 | #define ATRACE_TAG ATRACE_TAG_GRAPHICS | 
 | 20 |  | 
 | 21 | #include <SurfaceFlinger.h> | 
 | 22 | #include <android-base/stringprintf.h> | 
 | 23 | #include <log/log.h> | 
 | 24 | #include <utils/SystemClock.h> | 
 | 25 | #include <utils/Trace.h> | 
 | 26 |  | 
 | 27 | #include "LayerTracing.h" | 
 | 28 | #include "RingBuffer.h" | 
 | 29 |  | 
 | 30 | namespace android { | 
 | 31 |  | 
 | 32 | LayerTracing::LayerTracing(SurfaceFlinger& flinger) : mFlinger(flinger) { | 
 | 33 |     mBuffer = std::make_unique<RingBuffer<LayersTraceFileProto, LayersTraceProto>>(); | 
 | 34 | } | 
 | 35 |  | 
 | 36 | LayerTracing::~LayerTracing() = default; | 
 | 37 |  | 
 | 38 | bool LayerTracing::enable() { | 
 | 39 |     std::scoped_lock lock(mTraceLock); | 
 | 40 |     if (mEnabled) { | 
 | 41 |         return false; | 
 | 42 |     } | 
 | 43 |     mBuffer->setSize(mBufferSizeInBytes); | 
 | 44 |     mEnabled = true; | 
 | 45 |     return true; | 
 | 46 | } | 
 | 47 |  | 
| Vishnu Nair | d8f5e9f | 2022-02-03 10:23:28 -0800 | [diff] [blame] | 48 | bool LayerTracing::disable(std::string filename) { | 
| Vishnu Nair | 00b9013 | 2021-11-05 14:03:40 -0700 | [diff] [blame] | 49 |     std::scoped_lock lock(mTraceLock); | 
 | 50 |     if (!mEnabled) { | 
 | 51 |         return false; | 
 | 52 |     } | 
 | 53 |     mEnabled = false; | 
 | 54 |     LayersTraceFileProto fileProto = createTraceFileProto(); | 
| Vishnu Nair | d8f5e9f | 2022-02-03 10:23:28 -0800 | [diff] [blame] | 55 |     mBuffer->writeToFile(fileProto, filename); | 
| Vishnu Nair | 0cc69e1 | 2021-11-18 09:05:49 -0800 | [diff] [blame] | 56 |     mBuffer->reset(); | 
| Vishnu Nair | 00b9013 | 2021-11-05 14:03:40 -0700 | [diff] [blame] | 57 |     return true; | 
 | 58 | } | 
 | 59 |  | 
 | 60 | bool LayerTracing::isEnabled() const { | 
 | 61 |     std::scoped_lock lock(mTraceLock); | 
 | 62 |     return mEnabled; | 
 | 63 | } | 
 | 64 |  | 
 | 65 | status_t LayerTracing::writeToFile() { | 
 | 66 |     std::scoped_lock lock(mTraceLock); | 
 | 67 |     if (!mEnabled) { | 
 | 68 |         return STATUS_OK; | 
 | 69 |     } | 
 | 70 |     LayersTraceFileProto fileProto = createTraceFileProto(); | 
 | 71 |     return mBuffer->writeToFile(fileProto, FILE_NAME); | 
 | 72 | } | 
 | 73 |  | 
 | 74 | void LayerTracing::setTraceFlags(uint32_t flags) { | 
 | 75 |     std::scoped_lock lock(mTraceLock); | 
 | 76 |     mFlags = flags; | 
 | 77 | } | 
 | 78 |  | 
 | 79 | void LayerTracing::setBufferSize(size_t bufferSizeInBytes) { | 
 | 80 |     std::scoped_lock lock(mTraceLock); | 
 | 81 |     mBufferSizeInBytes = bufferSizeInBytes; | 
 | 82 | } | 
 | 83 |  | 
 | 84 | bool LayerTracing::flagIsSet(uint32_t flags) const { | 
 | 85 |     return (mFlags & flags) == flags; | 
 | 86 | } | 
 | 87 |  | 
 | 88 | LayersTraceFileProto LayerTracing::createTraceFileProto() const { | 
 | 89 |     LayersTraceFileProto fileProto; | 
 | 90 |     fileProto.set_magic_number(uint64_t(LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_H) << 32 | | 
 | 91 |                                LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_L); | 
| Kean Mariotti | c44fdaf | 2022-07-29 14:20:39 +0000 | [diff] [blame] | 92 |     auto timeOffsetNs = static_cast<std::uint64_t>(systemTime(SYSTEM_TIME_REALTIME) - | 
 | 93 |                                                    systemTime(SYSTEM_TIME_MONOTONIC)); | 
 | 94 |     fileProto.set_real_to_elapsed_time_offset_nanos(timeOffsetNs); | 
| Vishnu Nair | 00b9013 | 2021-11-05 14:03:40 -0700 | [diff] [blame] | 95 |     return fileProto; | 
 | 96 | } | 
 | 97 |  | 
 | 98 | void LayerTracing::dump(std::string& result) const { | 
 | 99 |     std::scoped_lock lock(mTraceLock); | 
 | 100 |     base::StringAppendF(&result, "Tracing state: %s\n", mEnabled ? "enabled" : "disabled"); | 
 | 101 |     mBuffer->dump(result); | 
 | 102 | } | 
 | 103 |  | 
| Pablo Gamito | b877579 | 2022-06-10 15:02:42 +0000 | [diff] [blame] | 104 | void LayerTracing::notify(bool visibleRegionDirty, int64_t time, int64_t vsyncId) { | 
| Vishnu Nair | 00b9013 | 2021-11-05 14:03:40 -0700 | [diff] [blame] | 105 |     std::scoped_lock lock(mTraceLock); | 
 | 106 |     if (!mEnabled) { | 
 | 107 |         return; | 
 | 108 |     } | 
 | 109 |  | 
| Vishnu Nair | b64a3b4 | 2022-01-13 15:29:32 -0800 | [diff] [blame] | 110 |     if (!visibleRegionDirty && !flagIsSet(LayerTracing::TRACE_BUFFERS)) { | 
 | 111 |         return; | 
 | 112 |     } | 
 | 113 |  | 
| Vishnu Nair | 00b9013 | 2021-11-05 14:03:40 -0700 | [diff] [blame] | 114 |     ATRACE_CALL(); | 
 | 115 |     LayersTraceProto entry; | 
| Vishnu Nair | b64a3b4 | 2022-01-13 15:29:32 -0800 | [diff] [blame] | 116 |     entry.set_elapsed_realtime_nanos(time); | 
 | 117 |     const char* where = visibleRegionDirty ? "visibleRegionsDirty" : "bufferLatched"; | 
| Vishnu Nair | 00b9013 | 2021-11-05 14:03:40 -0700 | [diff] [blame] | 118 |     entry.set_where(where); | 
 | 119 |     LayersProto layers(mFlinger.dumpDrawingStateProto(mFlags)); | 
 | 120 |  | 
 | 121 |     if (flagIsSet(LayerTracing::TRACE_EXTRA)) { | 
 | 122 |         mFlinger.dumpOffscreenLayersProto(layers); | 
 | 123 |     } | 
 | 124 |     entry.mutable_layers()->Swap(&layers); | 
 | 125 |  | 
 | 126 |     if (flagIsSet(LayerTracing::TRACE_HWC)) { | 
 | 127 |         std::string hwcDump; | 
 | 128 |         mFlinger.dumpHwc(hwcDump); | 
 | 129 |         entry.set_hwc_blob(hwcDump); | 
 | 130 |     } | 
 | 131 |     if (!flagIsSet(LayerTracing::TRACE_COMPOSITION)) { | 
 | 132 |         entry.set_excludes_composition_state(true); | 
 | 133 |     } | 
 | 134 |     mFlinger.dumpDisplayProto(entry); | 
| Pablo Gamito | b877579 | 2022-06-10 15:02:42 +0000 | [diff] [blame] | 135 |     entry.set_vsync_id(vsyncId); | 
| Greg Kaiser | ddefa7b | 2022-06-13 06:19:26 -0700 | [diff] [blame] | 136 |     mBuffer->emplace(std::move(entry)); | 
| Vishnu Nair | 00b9013 | 2021-11-05 14:03:40 -0700 | [diff] [blame] | 137 | } | 
 | 138 |  | 
 | 139 | } // namespace android |