Home | History | Annotate | Download | only in hwui
      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 FRAMEINFO_H_
     17 #define FRAMEINFO_H_
     18 
     19 #include "utils/Macros.h"
     20 
     21 #include <cutils/compiler.h>
     22 #include <utils/Timers.h>
     23 
     24 #include <memory.h>
     25 #include <string>
     26 
     27 namespace android {
     28 namespace uirenderer {
     29 
     30 #define UI_THREAD_FRAME_INFO_SIZE 9
     31 
     32 enum class FrameInfoIndex {
     33     Flags = 0,
     34     IntendedVsync,
     35     Vsync,
     36     OldestInputEvent,
     37     NewestInputEvent,
     38     HandleInputStart,
     39     AnimationStart,
     40     PerformTraversalsStart,
     41     DrawStart,
     42     // End of UI frame info
     43 
     44     SyncQueued,
     45 
     46     SyncStart,
     47     IssueDrawCommandsStart,
     48     SwapBuffers,
     49     FrameCompleted,
     50 
     51     DequeueBufferDuration,
     52     QueueBufferDuration,
     53 
     54     // Must be the last value!
     55     // Also must be kept in sync with FrameMetrics.java#FRAME_STATS_COUNT
     56     NumIndexes
     57 };
     58 
     59 extern const std::string FrameInfoNames[];
     60 
     61 namespace FrameInfoFlags {
     62 enum {
     63     WindowLayoutChanged = 1 << 0,
     64     RTAnimation = 1 << 1,
     65     SurfaceCanvas = 1 << 2,
     66     SkippedFrame = 1 << 3,
     67 };
     68 };
     69 
     70 class ANDROID_API UiFrameInfoBuilder {
     71 public:
     72     explicit UiFrameInfoBuilder(int64_t* buffer) : mBuffer(buffer) {
     73         memset(mBuffer, 0, UI_THREAD_FRAME_INFO_SIZE * sizeof(int64_t));
     74     }
     75 
     76     UiFrameInfoBuilder& setVsync(nsecs_t vsyncTime, nsecs_t intendedVsync) {
     77         set(FrameInfoIndex::Vsync) = vsyncTime;
     78         set(FrameInfoIndex::IntendedVsync) = intendedVsync;
     79         // Pretend the other fields are all at vsync, too, so that naive
     80         // duration calculations end up being 0 instead of very large
     81         set(FrameInfoIndex::HandleInputStart) = vsyncTime;
     82         set(FrameInfoIndex::AnimationStart) = vsyncTime;
     83         set(FrameInfoIndex::PerformTraversalsStart) = vsyncTime;
     84         set(FrameInfoIndex::DrawStart) = vsyncTime;
     85         return *this;
     86     }
     87 
     88     UiFrameInfoBuilder& addFlag(int frameInfoFlag) {
     89         set(FrameInfoIndex::Flags) |= static_cast<uint64_t>(frameInfoFlag);
     90         return *this;
     91     }
     92 
     93 private:
     94     inline int64_t& set(FrameInfoIndex index) { return mBuffer[static_cast<int>(index)]; }
     95 
     96     int64_t* mBuffer;
     97 };
     98 
     99 class FrameInfo {
    100 public:
    101     void importUiThreadInfo(int64_t* info);
    102 
    103     void markSyncStart() { set(FrameInfoIndex::SyncStart) = systemTime(CLOCK_MONOTONIC); }
    104 
    105     void markIssueDrawCommandsStart() {
    106         set(FrameInfoIndex::IssueDrawCommandsStart) = systemTime(CLOCK_MONOTONIC);
    107     }
    108 
    109     void markSwapBuffers() { set(FrameInfoIndex::SwapBuffers) = systemTime(CLOCK_MONOTONIC); }
    110 
    111     void markFrameCompleted() { set(FrameInfoIndex::FrameCompleted) = systemTime(CLOCK_MONOTONIC); }
    112 
    113     void addFlag(int frameInfoFlag) {
    114         set(FrameInfoIndex::Flags) |= static_cast<uint64_t>(frameInfoFlag);
    115     }
    116 
    117     const int64_t* data() const { return mFrameInfo; }
    118 
    119     inline int64_t operator[](FrameInfoIndex index) const { return get(index); }
    120 
    121     inline int64_t operator[](int index) const {
    122         if (index < 0 || index >= static_cast<int>(FrameInfoIndex::NumIndexes)) return 0;
    123         return mFrameInfo[index];
    124     }
    125 
    126     inline int64_t duration(FrameInfoIndex start, FrameInfoIndex end) const {
    127         int64_t endtime = get(end);
    128         int64_t starttime = get(start);
    129         int64_t gap = endtime - starttime;
    130         gap = starttime > 0 ? gap : 0;
    131         if (end > FrameInfoIndex::SyncQueued && start < FrameInfoIndex::SyncQueued) {
    132             // Need to subtract out the time spent in a stalled state
    133             // as this will be captured by the previous frame's info
    134             int64_t offset = get(FrameInfoIndex::SyncStart) - get(FrameInfoIndex::SyncQueued);
    135             if (offset > 0) {
    136                 gap -= offset;
    137             }
    138         }
    139         return gap > 0 ? gap : 0;
    140     }
    141 
    142     inline int64_t totalDuration() const {
    143         return duration(FrameInfoIndex::IntendedVsync, FrameInfoIndex::FrameCompleted);
    144     }
    145 
    146     inline int64_t& set(FrameInfoIndex index) { return mFrameInfo[static_cast<int>(index)]; }
    147 
    148     inline int64_t get(FrameInfoIndex index) const {
    149         if (index == FrameInfoIndex::NumIndexes) return 0;
    150         return mFrameInfo[static_cast<int>(index)];
    151     }
    152 
    153 private:
    154     int64_t mFrameInfo[static_cast<int>(FrameInfoIndex::NumIndexes)];
    155 };
    156 
    157 } /* namespace uirenderer */
    158 } /* namespace android */
    159 
    160 #endif /* FRAMEINFO_H_ */
    161