Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 41280697 authored by Ben Widawsky's avatar Ben Widawsky Committed by Android (Google) Code Review
Browse files

Merge "SF: Remove EventLog frame duration" into main

parents 90efc8a9 31135466
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -173,7 +173,6 @@ filegroup {
        "DisplayHardware/VirtualDisplaySurface.cpp",
        "DisplayRenderArea.cpp",
        "Effects/Daltonizer.cpp",
        "EventLog/EventLog.cpp",
        "FrontEnd/LayerCreationArgs.cpp",
        "FrontEnd/LayerHandle.cpp",
        "FrontEnd/LayerSnapshot.cpp",
+0 −133
Original line number Diff line number Diff line
/*
 * Copyright 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"

#include <stdio.h>
#include <stdlib.h>
#include <log/log.h>

#include "EventLog.h"

namespace android {

ANDROID_SINGLETON_STATIC_INSTANCE(EventLog)


EventLog::EventLog() {
}

void EventLog::doLogFrameDurations(const std::string_view& name, const int32_t* durations,
                                   size_t numDurations) {
    EventLog::TagBuffer buffer(LOGTAG_SF_FRAME_DUR);
    buffer.startList(1 + numDurations);
    buffer.writeString(name);
    for (size_t i = 0; i < numDurations; i++) {
        buffer.writeInt32(durations[i]);
    }
    buffer.endList();
    buffer.log();
}

void EventLog::logFrameDurations(const std::string_view& name, const int32_t* durations,
                                 size_t numDurations) {
    EventLog::getInstance().doLogFrameDurations(name, durations, numDurations);
}

// ---------------------------------------------------------------------------

EventLog::TagBuffer::TagBuffer(int32_t tag)
    : mPos(0), mTag(tag), mOverflow(false) {
}

void EventLog::TagBuffer::log() {
    if (mOverflow) {
        ALOGW("couldn't log to binary event log: overflow.");
    } else if (android_bWriteLog(mTag, mStorage, mPos) < 0) {
        ALOGE("couldn't log to EventLog: %s", strerror(errno));
    }
    // purge the buffer
    mPos = 0;
    mOverflow = false;
}

void EventLog::TagBuffer::startList(int8_t count) {
    if (mOverflow) return;
    const size_t needed = 1 + sizeof(count);
    if (mPos + needed > STORAGE_MAX_SIZE) {
        mOverflow = true;
        return;
    }
    mStorage[mPos + 0] = EVENT_TYPE_LIST;
    mStorage[mPos + 1] = count;
    mPos += needed;
}

void EventLog::TagBuffer::endList() {
    if (mOverflow) return;
    const size_t needed = 1;
    if (mPos + needed > STORAGE_MAX_SIZE) {
        mOverflow = true;
        return;
    }
    mStorage[mPos + 0] = '\n';
    mPos += needed;
}

void EventLog::TagBuffer::writeInt32(int32_t value) {
    if (mOverflow) return;
    const size_t needed = 1 + sizeof(value);
    if (mPos + needed > STORAGE_MAX_SIZE) {
        mOverflow = true;
        return;
    }
    mStorage[mPos + 0] = EVENT_TYPE_INT;
    memcpy(&mStorage[mPos + 1], &value, sizeof(value));
    mPos += needed;
}

void EventLog::TagBuffer::writeInt64(int64_t value) {
    if (mOverflow) return;
    const size_t needed = 1 + sizeof(value);
    if (mPos + needed > STORAGE_MAX_SIZE) {
        mOverflow = true;
        return;
    }
    mStorage[mPos + 0] = EVENT_TYPE_LONG;
    memcpy(&mStorage[mPos + 1], &value, sizeof(value));
    mPos += needed;
}

void EventLog::TagBuffer::writeString(const std::string_view& value) {
    if (mOverflow) return;
    const size_t stringLen = value.length();
    const size_t needed = 1 + sizeof(int32_t) + stringLen;
    if (mPos + needed > STORAGE_MAX_SIZE) {
        mOverflow = true;
        return;
    }
    mStorage[mPos + 0] = EVENT_TYPE_STRING;
    memcpy(&mStorage[mPos + 1], &stringLen, sizeof(int32_t));
    memcpy(&mStorage[mPos + 5], value.data(), stringLen);
    mPos += needed;
}

} // namespace android

// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic pop // ignored "-Wconversion"
+0 −73
Original line number Diff line number Diff line
/*
 * Copyright 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <utils/Errors.h>
#include <utils/Singleton.h>

#include <cstdint>
#include <string_view>

namespace android {

class EventLog : public Singleton<EventLog> {

public:
    static void logFrameDurations(const std::string_view& name, const int32_t* durations,
                                  size_t numDurations);

protected:
    EventLog();

private:
    /*
     * EventLogBuffer is a helper class to construct an in-memory event log
     * tag. In this version the buffer is not dynamic, so write operation can
     * fail if there is not enough space in the temporary buffer.
     * Once constructed, the buffer can be logger by calling the log()
     * method.
     */

    class TagBuffer {
        enum { STORAGE_MAX_SIZE = 128 };
        int32_t mPos;
        int32_t mTag;
        bool mOverflow;
        char mStorage[STORAGE_MAX_SIZE];
    public:
        explicit TagBuffer(int32_t tag);

        void startList(int8_t count);
        void endList();

        void writeInt32(int32_t);
        void writeInt64(int64_t);
        void writeString(const std::string_view&);

        void log();
    };

    friend class Singleton<EventLog>;
    EventLog(const EventLog&);
    EventLog& operator =(const EventLog&);

    enum { LOGTAG_SF_FRAME_DUR = 60100 };
    void doLogFrameDurations(const std::string_view& name, const int32_t* durations,
                             size_t numDurations);
};

} // namespace android
+0 −1
Original line number Diff line number Diff line
@@ -35,7 +35,6 @@

# 60100 - 60199 reserved for surfaceflinger

60100 sf_frame_dur (window|3),(dur0|1),(dur1|1),(dur2|1),(dur3|1),(dur4|1),(dur5|1),(dur6|1)
60110 sf_stop_bootanim (time|2|3)

# NOTE - the range 1000000-2000000 is reserved for partners and others who
+2 −70
Original line number Diff line number Diff line
@@ -26,16 +26,10 @@
#include <ui/FrameStats.h>

#include "FrameTracker.h"
#include "EventLog/EventLog.h"

namespace android {

FrameTracker::FrameTracker() :
        mOffset(0),
        mNumFences(0),
        mDisplayPeriod(0) {
    resetFrameCountersLocked();
}
FrameTracker::FrameTracker() : mOffset(0), mNumFences(0), mDisplayPeriod(0) {}

void FrameTracker::setDesiredPresentTime(nsecs_t presentTime) {
    Mutex::Autolock lock(mMutex);
@@ -73,9 +67,6 @@ void FrameTracker::setDisplayRefreshPeriod(nsecs_t displayPeriod) {
void FrameTracker::advanceFrame() {
    Mutex::Autolock lock(mMutex);

    // Update the statistic to include the frame we just finished.
    updateStatsLocked(mOffset);

    // Advance to the next frame.
    mOffset = (mOffset+1) % NUM_FRAME_RECORDS;
    mFrameRecords[mOffset].desiredPresentTime = INT64_MAX;
@@ -138,19 +129,12 @@ void FrameTracker::getStats(FrameStats* outStats) const {
    }
}

void FrameTracker::logAndResetStats(const std::string_view& name) {
    Mutex::Autolock lock(mMutex);
    logStatsLocked(name);
    resetFrameCountersLocked();
}

void FrameTracker::processFencesLocked() const {
    FrameRecord* records = const_cast<FrameRecord*>(mFrameRecords);
    int& numFences = const_cast<int&>(mNumFences);

    for (int i = 1; i < NUM_FRAME_RECORDS && numFences > 0; i++) {
        size_t idx = (mOffset + NUM_FRAME_RECORDS - i) % NUM_FRAME_RECORDS;
        bool updated = false;

        const std::shared_ptr<FenceTime>& rfence = records[idx].frameReadyFence;
        if (rfence != nullptr) {
@@ -158,7 +142,6 @@ void FrameTracker::processFencesLocked() const {
            if (records[idx].frameReadyTime < INT64_MAX) {
                records[idx].frameReadyFence = nullptr;
                numFences--;
                updated = true;
            }
        }

@@ -169,58 +152,7 @@ void FrameTracker::processFencesLocked() const {
            if (records[idx].actualPresentTime < INT64_MAX) {
                records[idx].actualPresentFence = nullptr;
                numFences--;
                updated = true;
            }
            }

        if (updated) {
            updateStatsLocked(idx);
        }
    }
}

void FrameTracker::updateStatsLocked(size_t newFrameIdx) const {
    int* numFrames = const_cast<int*>(mNumFrames);

    if (mDisplayPeriod > 0 && isFrameValidLocked(newFrameIdx)) {
        size_t prevFrameIdx = (newFrameIdx+NUM_FRAME_RECORDS-1) %
                NUM_FRAME_RECORDS;

        if (isFrameValidLocked(prevFrameIdx)) {
            nsecs_t newPresentTime =
                    mFrameRecords[newFrameIdx].actualPresentTime;
            nsecs_t prevPresentTime =
                    mFrameRecords[prevFrameIdx].actualPresentTime;

            nsecs_t duration = newPresentTime - prevPresentTime;
            int numPeriods = int((duration + mDisplayPeriod/2) /
                    mDisplayPeriod);

            for (int i = 0; i < NUM_FRAME_BUCKETS-1; i++) {
                int nextBucket = 1 << (i+1);
                if (numPeriods < nextBucket) {
                    numFrames[i]++;
                    return;
                }
            }

            // The last duration bucket is a catch-all.
            numFrames[NUM_FRAME_BUCKETS-1]++;
        }
    }
}

void FrameTracker::resetFrameCountersLocked() {
    for (int i = 0; i < NUM_FRAME_BUCKETS; i++) {
        mNumFrames[i] = 0;
    }
}

void FrameTracker::logStatsLocked(const std::string_view& name) const {
    for (int i = 0; i < NUM_FRAME_BUCKETS; i++) {
        if (mNumFrames[i] > 0) {
            EventLog::logFrameDurations(name, mNumFrames, NUM_FRAME_BUCKETS);
            return;
        }
    }
}
Loading