1 /* 2 * Copyright (C) 2015 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 #ifndef JANKTRACKER_H_ 17 #define JANKTRACKER_H_ 18 19 #include "FrameInfo.h" 20 #include "ProfileData.h" 21 #include "ProfileDataContainer.h" 22 #include "renderthread/TimeLord.h" 23 #include "utils/RingBuffer.h" 24 25 #include <cutils/compiler.h> 26 #include <ui/DisplayInfo.h> 27 28 #include <array> 29 #include <memory> 30 31 namespace android { 32 namespace uirenderer { 33 34 enum class JankTrackerType { 35 // The default, means there's no description set 36 Generic, 37 // The profile data represents a package 38 Package, 39 // The profile data is for a specific window 40 Window, 41 }; 42 43 // Metadata about the ProfileData being collected 44 struct ProfileDataDescription { 45 JankTrackerType type; 46 std::string name; 47 }; 48 49 // TODO: Replace DrawProfiler with this 50 class JankTracker { 51 public: 52 explicit JankTracker(ProfileDataContainer* globalData, const DisplayInfo& displayInfo); 53 setDescription(JankTrackerType type,const std::string && name)54 void setDescription(JankTrackerType type, const std::string&& name) { 55 mDescription.type = type; 56 mDescription.name = name; 57 } 58 startFrame()59 FrameInfo* startFrame() { return &mFrames.next(); } 60 void finishFrame(const FrameInfo& frame); 61 dumpStats(int fd)62 void dumpStats(int fd) { dumpData(fd, &mDescription, mData.get()); } 63 void dumpFrames(int fd); 64 void reset(); 65 66 // Exposed for FrameInfoVisualizer 67 // TODO: Figure out a better way to handle this frames()68 RingBuffer<FrameInfo, 120>& frames() { return mFrames; } 69 70 private: 71 void setFrameInterval(nsecs_t frameIntervalNanos); 72 73 static void dumpData(int fd, const ProfileDataDescription* description, 74 const ProfileData* data); 75 76 std::array<int64_t, NUM_BUCKETS> mThresholds; 77 int64_t mFrameInterval; 78 nsecs_t mSwapDeadline; 79 // The amount of time we will erase from the total duration to account 80 // for SF vsync offsets with HWC2 blocking dequeueBuffers. 81 // (Vsync + mDequeueBlockTolerance) is the point at which we expect 82 // SF to have released the buffer normally, so we will forgive up to that 83 // point in time by comparing to (IssueDrawCommandsStart + DequeueDuration) 84 // This is only used if we are in pipelined mode and are using HWC2, 85 // otherwise it's 0. 86 nsecs_t mDequeueTimeForgiveness = 0; 87 ProfileDataContainer mData; 88 ProfileDataContainer* mGlobalData; 89 ProfileDataDescription mDescription; 90 91 // Ring buffer large enough for 2 seconds worth of frames 92 RingBuffer<FrameInfo, 120> mFrames; 93 }; 94 95 } /* namespace uirenderer */ 96 } /* namespace android */ 97 98 #endif /* JANKTRACKER_H_ */ 99