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

Commit 71c5b0c4 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes I91b38c51,Ic62bfb68

* changes:
  [SurfaceFlinger] Allow DispSync to be GMock'd
  [SurfaceFlinger] Hide SyncFeatures behind RenderEngine
parents ee109fcc 41be5d28
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -40,7 +40,6 @@
#include <gui/SurfaceComposerClient.h>

#include <private/gui/ComposerService.h>
#include <private/gui/SyncFeatures.h>

#include <utils/Log.h>
#include <utils/String8.h>
@@ -206,7 +205,7 @@ status_t BufferLayerConsumer::updateTexImage(BufferRejecter* rejecter, const Dis
        return err;
    }

    if (!SyncFeatures::getInstance().useNativeFenceSync()) {
    if (mRE.useNativeFenceSync()) {
        // Bind the new buffer to the GL texture.
        //
        // Older devices require the "implicit" synchronization provided
@@ -374,7 +373,7 @@ status_t BufferLayerConsumer::syncForReleaseLocked() {
    BLC_LOGV("syncForReleaseLocked");

    if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
        if (SyncFeatures::getInstance().useNativeFenceSync()) {
        if (mRE.useNativeFenceSync()) {
            base::unique_fd fenceFd = mRE.flush();
            if (fenceFd == -1) {
                BLC_LOGE("syncForReleaseLocked: failed to flush RenderEngine");
@@ -512,7 +511,7 @@ status_t BufferLayerConsumer::doFenceWaitLocked() const {
    }

    if (mCurrentFence->isValid()) {
        if (SyncFeatures::getInstance().useWaitSync()) {
        if (mRE.useWaitSync()) {
            base::unique_fd fenceFd(mCurrentFence->dup());
            if (fenceFd == -1) {
                BLC_LOGE("doFenceWait: error dup'ing fence fd: %d", errno);
+3 −2
Original line number Diff line number Diff line
@@ -245,8 +245,9 @@ status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t
    LayerRejecter r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
                    getProducerStickyTransform() != 0, mName.string(), mOverrideScalingMode,
                    getTransformToDisplayInverse(), mFreezeGeometryUpdates);
    status_t updateResult = mConsumer->updateTexImage(&r, mFlinger->mPrimaryDispSync, &mAutoRefresh,
                                                      &queuedBuffer, mLastFrameNumberReceived);
    status_t updateResult =
            mConsumer->updateTexImage(&r, *mFlinger->mPrimaryDispSync, &mAutoRefresh, &queuedBuffer,
                                      mLastFrameNumberReceived);
    if (updateResult == BufferQueue::PRESENT_LATER) {
        // Producer doesn't want buffer to be displayed yet.  Signal a
        // layer update so we check again at the next opportunity.
+6 −0
Original line number Diff line number Diff line
@@ -40,6 +40,10 @@ using std::min;

namespace android {

DispSync::~DispSync() = default;

namespace impl {

// Setting this to true enables verbose tracing that can be used to debug
// vsync event model or phase issues.
static const bool kTraceDetailedInfo = false;
@@ -707,4 +711,6 @@ void DispSync::dump(String8& result) const {
    result.appendFormat("current monotonic time: %" PRId64 "\n", now);
}

} // namespace impl

} // namespace android
+48 −22
Original line number Diff line number Diff line
@@ -31,6 +31,36 @@ namespace android {

class String8;
class FenceTime;

class DispSync {
public:
    class Callback {
    public:
        virtual ~Callback() = default;
        virtual void onDispSyncEvent(nsecs_t when) = 0;
    };

    virtual ~DispSync();

    virtual void reset() = 0;
    virtual bool addPresentFence(const std::shared_ptr<FenceTime>&) = 0;
    virtual void beginResync() = 0;
    virtual bool addResyncSample(nsecs_t timestamp) = 0;
    virtual void endResync() = 0;
    virtual void setPeriod(nsecs_t period) = 0;
    virtual nsecs_t getPeriod() = 0;
    virtual void setRefreshSkipCount(int count) = 0;
    virtual status_t addEventListener(const char* name, nsecs_t phase, Callback* callback) = 0;
    virtual status_t removeEventListener(Callback* callback) = 0;
    virtual status_t changePhaseOffset(Callback* callback, nsecs_t phase) = 0;
    virtual nsecs_t computeNextRefresh(int periodOffset) const = 0;
    virtual void setIgnorePresentFences(bool ignore) = 0;

    virtual void dump(String8& result) const = 0;
};

namespace impl {

class DispSyncThread;

// DispSync maintains a model of the periodic hardware-based vsync events of a
@@ -46,21 +76,15 @@ class DispSyncThread;
// current model accurately represents the hardware event times it will return
// false to indicate that a resynchronization (via addResyncSample) is not
// needed.
class DispSync {
public:
    class Callback {
class DispSync : public android::DispSync {
public:
        virtual ~Callback(){};
        virtual void onDispSyncEvent(nsecs_t when) = 0;
    };

    explicit DispSync(const char* name);
    ~DispSync();
    ~DispSync() override;

    void init(bool hasSyncFramework, int64_t dispSyncPresentTimeOffset);

    // reset clears the resync samples and error value.
    void reset();
    void reset() override;

    // addPresentFence adds a fence for use in validating the current vsync
    // event model.  The fence need not be signaled at the time
@@ -71,7 +95,7 @@ public:
    //
    // This method should be called with the retire fence from each HWComposer
    // set call that affects the display.
    bool addPresentFence(const std::shared_ptr<FenceTime>& fenceTime);
    bool addPresentFence(const std::shared_ptr<FenceTime>& fenceTime) override;

    // The beginResync, addResyncSample, and endResync methods are used to re-
    // synchronize the DispSync's model to the hardware vsync events.  The re-
@@ -84,45 +108,45 @@ public:
    // is turned on (i.e. once immediately after it's turned on) and whenever
    // addPresentFence returns true indicating that the model has drifted away
    // from the hardware vsync events.
    void beginResync();
    bool addResyncSample(nsecs_t timestamp);
    void endResync();
    void beginResync() override;
    bool addResyncSample(nsecs_t timestamp) override;
    void endResync() override;

    // The setPeriod method sets the vsync event model's period to a specific
    // value.  This should be used to prime the model when a display is first
    // turned on.  It should NOT be used after that.
    void setPeriod(nsecs_t period);
    void setPeriod(nsecs_t period) override;

    // The getPeriod method returns the current vsync period.
    nsecs_t getPeriod();
    nsecs_t getPeriod() override;

    // setRefreshSkipCount specifies an additional number of refresh
    // cycles to skip.  For example, on a 60Hz display, a skip count of 1
    // will result in events happening at 30Hz.  Default is zero.  The idea
    // is to sacrifice smoothness for battery life.
    void setRefreshSkipCount(int count);
    void setRefreshSkipCount(int count) override;

    // addEventListener registers a callback to be called repeatedly at the
    // given phase offset from the hardware vsync events.  The callback is
    // called from a separate thread and it should return reasonably quickly
    // (i.e. within a few hundred microseconds).
    status_t addEventListener(const char* name, nsecs_t phase, Callback* callback);
    status_t addEventListener(const char* name, nsecs_t phase, Callback* callback) override;

    // removeEventListener removes an already-registered event callback.  Once
    // this method returns that callback will no longer be called by the
    // DispSync object.
    status_t removeEventListener(Callback* callback);
    status_t removeEventListener(Callback* callback) override;

    // changePhaseOffset changes the phase offset of an already-registered event callback. The
    // method will make sure that there is no skipping or double-firing on the listener per frame,
    // even when changing the offsets multiple times.
    status_t changePhaseOffset(Callback* callback, nsecs_t phase);
    status_t changePhaseOffset(Callback* callback, nsecs_t phase) override;

    // computeNextRefresh computes when the next refresh is expected to begin.
    // The periodOffset value can be used to move forward or backward; an
    // offset of zero is the next refresh, -1 is the previous refresh, 1 is
    // the refresh after next. etc.
    nsecs_t computeNextRefresh(int periodOffset) const;
    nsecs_t computeNextRefresh(int periodOffset) const override;

    // In certain situations the present fences aren't a good indicator of vsync
    // time, e.g. when vr flinger is active, or simply aren't available,
@@ -130,10 +154,10 @@ public:
    // whether or not DispSync ignores present fences. If present fences are
    // ignored, DispSync will always ask for hardware vsync events by returning
    // true from addPresentFence() and addResyncSample().
    void setIgnorePresentFences(bool ignore);
    void setIgnorePresentFences(bool ignore) override;

    // dump appends human-readable debug info to the result string.
    void dump(String8& result) const;
    void dump(String8& result) const override;

private:
    void updateModelLocked();
@@ -206,6 +230,8 @@ private:
    std::unique_ptr<Callback> mZeroPhaseTracer;
};

} // namespace impl

} // namespace android

#endif // ANDROID_DISPSYNC_H
+9 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@

#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
#include <configstore/Utils.h>
#include <private/gui/SyncFeatures.h>

using namespace android::hardware::configstore;
using namespace android::hardware::configstore::V1_0;
@@ -175,6 +176,14 @@ EGLConfig RenderEngine::getEGLConfig() const {
    return mEGLConfig;
}

bool RenderEngine::useNativeFenceSync() const {
    return SyncFeatures::getInstance().useNativeFenceSync();
}

bool RenderEngine::useWaitSync() const {
    return SyncFeatures::getInstance().useWaitSync();
}

bool RenderEngine::isCurrent() const {
    return mEGLDisplay == eglGetCurrentDisplay() && mEGLContext == eglGetCurrentContext();
}
Loading