1 /*
2  * Copyright 2017 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 #pragma once
18 
19 #include <android-base/thread_annotations.h>
20 #include <layerproto/LayerProtoHeader.h>
21 #include <utils/Errors.h>
22 #include <utils/StrongPointer.h>
23 
24 #include <condition_variable>
25 #include <memory>
26 #include <mutex>
27 #include <queue>
28 #include <thread>
29 
30 using namespace android::surfaceflinger;
31 
32 namespace android {
33 
34 class SurfaceFlinger;
35 
36 constexpr auto operator""_MB(unsigned long long const num) {
37     return num * 1024 * 1024;
38 }
39 /*
40  * SurfaceTracing records layer states during surface flinging.
41  */
42 class SurfaceTracing {
43 public:
44     explicit SurfaceTracing(SurfaceFlinger& flinger);
45     bool enable();
46     bool disable();
47     status_t writeToFile();
48     bool isEnabled() const;
49     void notify(const char* where);
50     void notifyLocked(const char* where) NO_THREAD_SAFETY_ANALYSIS /* REQUIRES(mSfLock) */;
51 
52     void setBufferSize(size_t bufferSizeInByte);
53     void writeToFileAsync();
54     void dump(std::string& result) const;
55 
56     enum : uint32_t {
57         TRACE_CRITICAL = 1 << 0,
58         TRACE_INPUT = 1 << 1,
59         TRACE_COMPOSITION = 1 << 2,
60         TRACE_EXTRA = 1 << 3,
61         TRACE_HWC = 1 << 4,
62         TRACE_ALL = 0xffffffff
63     };
64     void setTraceFlags(uint32_t flags);
flagIsSetLocked(uint32_t flags)65     bool flagIsSetLocked(uint32_t flags) NO_THREAD_SAFETY_ANALYSIS /* REQUIRES(mSfLock) */ {
66         return (mTraceFlags & flags) == flags;
67     }
68 
69 private:
70     static constexpr auto kDefaultBufferCapInByte = 5_MB;
71     static constexpr auto kDefaultFileName = "/data/misc/wmtrace/layers_trace.pb";
72 
73     class LayersTraceBuffer { // ring buffer
74     public:
size()75         size_t size() const { return mSizeInBytes; }
used()76         size_t used() const { return mUsedInBytes; }
frameCount()77         size_t frameCount() const { return mStorage.size(); }
78 
setSize(size_t newSize)79         void setSize(size_t newSize) { mSizeInBytes = newSize; }
80         void reset(size_t newSize);
81         void emplace(LayersTraceProto&& proto);
82         void flush(LayersTraceFileProto* fileProto);
83 
84     private:
85         size_t mUsedInBytes = 0U;
86         size_t mSizeInBytes = 0U;
87         std::queue<LayersTraceProto> mStorage;
88     };
89 
90     void mainLoop();
91     bool addFirstEntry();
92     LayersTraceProto traceWhenNotified();
93     LayersTraceProto traceLayersLocked(const char* where) REQUIRES(mSfLock);
94 
95     // Returns true if trace is enabled.
96     bool addTraceToBuffer(LayersTraceProto& entry);
97     void writeProtoFileLocked() REQUIRES(mTraceLock);
98 
99     SurfaceFlinger& mFlinger;
100     status_t mLastErr = NO_ERROR;
101     std::thread mThread;
102     std::condition_variable mCanStartTrace;
103 
104     std::mutex& mSfLock;
105     uint32_t mTraceFlags GUARDED_BY(mSfLock) = TRACE_CRITICAL | TRACE_INPUT;
106     const char* mWhere GUARDED_BY(mSfLock) = "";
107     uint32_t mMissedTraceEntries GUARDED_BY(mSfLock) = 0;
108     bool mTracingInProgress GUARDED_BY(mSfLock) = false;
109 
110     mutable std::mutex mTraceLock;
111     LayersTraceBuffer mBuffer GUARDED_BY(mTraceLock);
112     size_t mBufferSize GUARDED_BY(mTraceLock) = kDefaultBufferCapInByte;
113     bool mEnabled GUARDED_BY(mTraceLock) = false;
114     bool mWriteToFile GUARDED_BY(mTraceLock) = false;
115 };
116 
117 } // namespace android
118