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     // Must be the last value!
     52     NumIndexes
     53 };
     54 
     55 extern const std::string FrameInfoNames[];
     56 
     57 namespace FrameInfoFlags {
     58     enum {
     59         WindowLayoutChanged = 1 << 0,
     60         RTAnimation = 1 << 1,
     61         SurfaceCanvas = 1 << 2,
     62         SkippedFrame = 1 << 3,
     63     };
     64 };
     65 
     66 class ANDROID_API UiFrameInfoBuilder {
     67 public:
     68     UiFrameInfoBuilder(int64_t* buffer) : mBuffer(buffer) {
     69         memset(mBuffer, 0, UI_THREAD_FRAME_INFO_SIZE * sizeof(int64_t));
     70     }
     71 
     72     UiFrameInfoBuilder& setVsync(nsecs_t vsyncTime, nsecs_t intendedVsync) {
     73         set(FrameInfoIndex::Vsync) = vsyncTime;
     74         set(FrameInfoIndex::IntendedVsync) = intendedVsync;
     75         // Pretend the other fields are all at vsync, too, so that naive
     76         // duration calculations end up being 0 instead of very large
     77         set(FrameInfoIndex::HandleInputStart) = vsyncTime;
     78         set(FrameInfoIndex::AnimationStart) = vsyncTime;
     79         set(FrameInfoIndex::PerformTraversalsStart) = vsyncTime;
     80         set(FrameInfoIndex::DrawStart) = vsyncTime;
     81         return *this;
     82     }
     83 
     84     UiFrameInfoBuilder& addFlag(int frameInfoFlag) {
     85         set(FrameInfoIndex::Flags) |= static_cast<uint64_t>(frameInfoFlag);
     86         return *this;
     87     }
     88 
     89 private:
     90     inline int64_t& set(FrameInfoIndex index) {
     91         return mBuffer[static_cast<int>(index)];
     92     }
     93 
     94     int64_t* mBuffer;
     95 };
     96 
     97 class FrameInfo {
     98 public:
     99     void importUiThreadInfo(int64_t* info);
    100 
    101     void markSyncStart() {
    102         set(FrameInfoIndex::SyncStart) = systemTime(CLOCK_MONOTONIC);
    103     }
    104 
    105     void markIssueDrawCommandsStart() {
    106         set(FrameInfoIndex::IssueDrawCommandsStart) = systemTime(CLOCK_MONOTONIC);
    107     }
    108 
    109     void markSwapBuffers() {
    110         set(FrameInfoIndex::SwapBuffers) = systemTime(CLOCK_MONOTONIC);
    111     }
    112 
    113     void markFrameCompleted() {
    114         set(FrameInfoIndex::FrameCompleted) = systemTime(CLOCK_MONOTONIC);
    115     }
    116 
    117     void addFlag(int frameInfoFlag) {
    118         set(FrameInfoIndex::Flags) |= static_cast<uint64_t>(frameInfoFlag);
    119     }
    120 
    121     inline int64_t operator[](FrameInfoIndex index) const {
    122         return get(index);
    123     }
    124 
    125     inline int64_t operator[](int index) const {
    126         if (index < 0 || index >= static_cast<int>(FrameInfoIndex::NumIndexes)) return 0;
    127         return mFrameInfo[index];
    128     }
    129 
    130     inline int64_t duration(FrameInfoIndex start, FrameInfoIndex end) const {
    131         int64_t endtime = get(end);
    132         int64_t starttime = get(start);
    133         int64_t gap = endtime - starttime;
    134         gap = starttime > 0 ? gap : 0;
    135         if (end > FrameInfoIndex::SyncQueued &&
    136                 start < FrameInfoIndex::SyncQueued) {
    137             // Need to subtract out the time spent in a stalled state
    138             // as this will be captured by the previous frame's info
    139             int64_t offset = get(FrameInfoIndex::SyncStart)
    140                     - get(FrameInfoIndex::SyncQueued);
    141             if (offset > 0) {
    142                 gap -= offset;
    143             }
    144         }
    145         return gap > 0 ? gap : 0;
    146     }
    147 
    148     inline int64_t totalDuration() const {
    149         return duration(FrameInfoIndex::IntendedVsync, FrameInfoIndex::FrameCompleted);
    150     }
    151 
    152     inline int64_t& set(FrameInfoIndex index) {
    153         return mFrameInfo[static_cast<int>(index)];
    154     }
    155 
    156     inline int64_t get(FrameInfoIndex index) const {
    157         if (index == FrameInfoIndex::NumIndexes) return 0;
    158         return mFrameInfo[static_cast<int>(index)];
    159     }
    160 
    161 private:
    162     int64_t mFrameInfo[static_cast<int>(FrameInfoIndex::NumIndexes)];
    163 };
    164 
    165 } /* namespace uirenderer */
    166 } /* namespace android */
    167 
    168 #endif /* FRAMEINFO_H_ */
    169