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

Commit d6927fb1 authored by Brian Anderson's avatar Brian Anderson
Browse files

Track frame events incrementally and per layer.

* Replaces FenceTracker, which was owned by SurfaceFlinger,
    with FrameEventHistory, which is owned by Layer.
* Updates FrameEventHistory as events occur.
* Changes SurfaceFlinger flag "--fences" to
    "--frame-events".

Test: adb shell /data/nativetest/libgui_test/libgui_test
--gtest_filter=*GetFrameTimestamps*

Change-Id: I868c2ef93964656d7e41848243433499e7f45fe7
parent eae58191
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -66,8 +66,9 @@ public:
        virtual void onFrameReplaced(const BufferItem& item) override;
        virtual void onBuffersReleased() override;
        virtual void onSidebandStreamChanged() override;
        virtual bool getFrameTimestamps(uint64_t frameNumber,
                FrameTimestamps* outTimestamps) const override;
        virtual bool addAndGetFrameTimestamps(
                const NewFrameEventsEntry* newTimestamps,
                uint64_t frameNumber, FrameTimestamps* outTimestamps) override;
    private:
        // mConsumerListener is a weak reference to the IConsumerListener.  This is
        // the raison d'etre of ProxyConsumerListener.
+5 −1
Original line number Diff line number Diff line
@@ -178,7 +178,7 @@ public:

    // See IGraphicBufferProducer::getFrameTimestamps
    virtual bool getFrameTimestamps(uint64_t frameNumber,
            FrameTimestamps* outTimestamps) const override;
            FrameTimestamps* outTimestamps) override;

    // See IGraphicBufferProducer::getUniqueId
    virtual status_t getUniqueId(uint64_t* outId) const override;
@@ -195,6 +195,10 @@ private:
    // BufferQueueCore::INVALID_BUFFER_SLOT otherwise
    int getFreeSlotLocked() const;

    bool addAndGetFrameTimestamps(
            const NewFrameEventsEntry* newTimestamps,
            uint64_t frameNumber, FrameTimestamps* outTimestamps);

    // waitForFreeSlotThenRelock finds the oldest slot in the FREE state. It may
    // block if there are no available slots and we are not in non-blocking
    // mode (producer and consumer controlled by the application). If it blocks,
+83 −1
Original line number Diff line number Diff line
@@ -17,11 +17,20 @@
#ifndef ANDROID_GUI_FRAMETIMESTAMPS_H
#define ANDROID_GUI_FRAMETIMESTAMPS_H

#include <utils/Timers.h>
#include <ui/Fence.h>
#include <utils/Flattenable.h>
#include <utils/StrongPointer.h>
#include <utils/Timers.h>

#include <array>

namespace android {


struct FrameEvents;
class String8;


enum class SupportableFrameTimestamps {
    REQUESTED_PRESENT,
    ACQUIRE,
@@ -32,8 +41,14 @@ enum class SupportableFrameTimestamps {
    RELEASE_TIME,
};


// The timestamps the consumer sends to the producer over binder.
struct FrameTimestamps : public LightFlattenablePod<FrameTimestamps> {
    FrameTimestamps() = default;
    explicit FrameTimestamps(const FrameEvents& fences);

    uint64_t frameNumber{0};
    nsecs_t postedTime{0};
    nsecs_t requestedPresentTime{0};
    nsecs_t acquireTime{0};
    nsecs_t refreshStartTime{0};
@@ -43,5 +58,72 @@ struct FrameTimestamps : public LightFlattenablePod<FrameTimestamps> {
    nsecs_t releaseTime{0};
};


// A collection of timestamps corresponding to a single frame.
struct FrameEvents {
    void checkFencesForCompletion();
    void dump(String8& outString) const;

    bool valid{false};
    uint64_t frameNumber{0};

    // Whether or not certain points in the frame's life cycle have been
    // encountered help us determine if timestamps aren't available because
    // a) we'll just never get them or b) they're not ready yet.
    bool addPostCompositeCalled{false};
    bool addRetireCalled{false};

    nsecs_t postedTime{0};
    nsecs_t requestedPresentTime{0};
    nsecs_t latchTime{0};
    nsecs_t firstRefreshStartTime{0};
    nsecs_t lastRefreshStartTime{0};

    nsecs_t acquireTime{0};
    nsecs_t gpuCompositionDoneTime{0};
    nsecs_t displayPresentTime{0};
    nsecs_t displayRetireTime{0};
    nsecs_t releaseTime{0};

    sp<Fence> acquireFence{Fence::NO_FENCE};
    sp<Fence> gpuCompositionDoneFence{Fence::NO_FENCE};
    sp<Fence> displayPresentFence{Fence::NO_FENCE};
    sp<Fence> displayRetireFence{Fence::NO_FENCE};
    sp<Fence> releaseFence{Fence::NO_FENCE};
};


struct NewFrameEventsEntry {
    uint64_t frameNumber{0};
    nsecs_t postedTime{0};
    nsecs_t requestedPresentTime{0};
    sp<Fence> acquireFence{Fence::NO_FENCE};
};


class FrameEventHistory {
public:
    FrameEvents* getFrame(uint64_t frameNumber);
    FrameEvents* getFrame(uint64_t frameNumber, size_t* iHint);
    void checkFencesForCompletion();
    void dump(String8& outString) const;

    void addQueue(const NewFrameEventsEntry& newFrameEntry);
    void addLatch(uint64_t frameNumber, nsecs_t latchTime);
    void addPreComposition(uint64_t frameNumber, nsecs_t refreshStartTime);
    void addPostComposition(uint64_t frameNumber,
            sp<Fence> gpuCompositionDone, sp<Fence> displayPresent);
    void addRetire(uint64_t frameNumber, sp<Fence> displayRetire);
    void addRelease(uint64_t frameNumber, sp<Fence> release);

private:
    static constexpr size_t MAX_FRAME_HISTORY = 8;
    std::array<FrameEvents, MAX_FRAME_HISTORY> mFrames;
    size_t mQueueOffset{0};
    size_t mCompositionOffset{0};
    size_t mRetireOffset{0};
    size_t mReleaseOffset{0};
};

} // namespace android
#endif
+7 −4
Original line number Diff line number Diff line
@@ -82,10 +82,13 @@ public:
    // different stream.
    virtual void onSidebandStreamChanged() = 0; /* Asynchronous */

    // See IGraphicBufferProducer::getFrameTimestamps
    // This queries the consumer for the timestamps
    virtual bool getFrameTimestamps(uint64_t /*frameNumber*/,
            FrameTimestamps* /*outTimestamps*/) const { return false; }
    // Notifies the consumer of any new producer-side events and then queries
    // the consumer timestamps
    virtual bool addAndGetFrameTimestamps(
            const NewFrameEventsEntry* /*newTimestamps*/,
            uint64_t /*frameNumber*/, FrameTimestamps* /*outTimestamps*/) {
        return false;
    }
};


+1 −1
Original line number Diff line number Diff line
@@ -594,7 +594,7 @@ public:
    //
    // If a fence has not yet signaled the timestamp returned will be 0;
    virtual bool getFrameTimestamps(uint64_t /*frameNumber*/,
            FrameTimestamps* /*outTimestamps*/) const { return false; }
            FrameTimestamps* /*outTimestamps*/) { return false; }

    // Returns a unique id for this BufferQueue
    virtual status_t getUniqueId(uint64_t* outId) const = 0;
Loading