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 27 #include <array> 28 #include <memory> 29 30 namespace android { 31 namespace uirenderer { 32 33 enum class JankTrackerType { 34 // The default, means there's no description set 35 Generic, 36 // The profile data represents a package 37 Package, 38 // The profile data is for a specific window 39 Window, 40 }; 41 42 // Metadata about the ProfileData being collected 43 struct ProfileDataDescription { 44 JankTrackerType type; 45 std::string name; 46 }; 47 48 // TODO: Replace DrawProfiler with this 49 class JankTracker { 50 public: 51 explicit JankTracker(ProfileDataContainer* globalData); 52 setDescription(JankTrackerType type,const std::string && name)53 void setDescription(JankTrackerType type, const std::string&& name) { 54 mDescription.type = type; 55 mDescription.name = name; 56 } 57 startFrame()58 FrameInfo* startFrame() { return &mFrames.next(); } 59 void finishFrame(const FrameInfo& frame); 60 void finishGpuDraw(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