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

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

Merge "[HWUI] use AChoreographer in place of DisplayEventReceiver."

parents a2030eb2 4a818f18
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -52,8 +52,8 @@ void DeviceInfo::setMaxTextureSize(int maxTextureSize) {
    DeviceInfo::get()->mMaxTextureSize = maxTextureSize;
}

void DeviceInfo::onDisplayConfigChanged() {
    updateDisplayInfo();
void DeviceInfo::onRefreshRateChanged(int64_t vsyncPeriod) {
    mVsyncPeriod = vsyncPeriod;
}

void DeviceInfo::updateDisplayInfo() {
@@ -113,10 +113,11 @@ void DeviceInfo::updateDisplayInfo() {
    ADisplay* primaryDisplay = mDisplays[mPhysicalDisplayIndex];
    status_t status = ADisplay_getCurrentConfig(primaryDisplay, &mCurrentConfig);
    LOG_ALWAYS_FATAL_IF(status, "Failed to get display config, error %d", status);

    mWidth = ADisplayConfig_getWidth(mCurrentConfig);
    mHeight = ADisplayConfig_getHeight(mCurrentConfig);
    mDensity = ADisplayConfig_getDensity(mCurrentConfig);
    mRefreshRate = ADisplayConfig_getFps(mCurrentConfig);
    mVsyncPeriod = static_cast<int64_t>(1000000000 / ADisplayConfig_getFps(mCurrentConfig));
    mCompositorOffset = ADisplayConfig_getCompositorOffsetNanos(mCurrentConfig);
    mAppOffset = ADisplayConfig_getAppVsyncOffsetNanos(mCurrentConfig);
}
+4 −3
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ public:
    static int32_t getWidth() { return get()->mWidth; }
    static int32_t getHeight() { return get()->mHeight; }
    static float getDensity() { return get()->mDensity; }
    static float getRefreshRate() { return get()->mRefreshRate; }
    static int64_t getVsyncPeriod() { return get()->mVsyncPeriod; }
    static int64_t getCompositorOffset() { return get()->mCompositorOffset; }
    static int64_t getAppOffset() { return get()->mAppOffset; }

@@ -47,7 +47,8 @@ public:
    sk_sp<SkColorSpace> getWideColorSpace() const { return mWideColorSpace; }
    SkColorType getWideColorType() const { return mWideColorType; }

    void onDisplayConfigChanged();
    // This method should be called whenever the display refresh rate changes.
    void onRefreshRateChanged(int64_t vsyncPeriod);

private:
    friend class renderthread::RenderThread;
@@ -68,7 +69,7 @@ private:
    int32_t mWidth = 1080;
    int32_t mHeight = 1920;
    float mDensity = 2.0;
    float mRefreshRate = 60.0;
    int64_t mVsyncPeriod = 16666666;
    int64_t mCompositorOffset = 0;
    int64_t mAppOffset = 0;
};
+1 −1
Original line number Diff line number Diff line
@@ -81,7 +81,7 @@ static FrameInfoIndex sFrameStart = FrameInfoIndex::IntendedVsync;

JankTracker::JankTracker(ProfileDataContainer* globalData) {
    mGlobalData = globalData;
    nsecs_t frameIntervalNanos = static_cast<nsecs_t>(1_s / DeviceInfo::getRefreshRate());
    nsecs_t frameIntervalNanos = DeviceInfo::getVsyncPeriod();
    nsecs_t sfOffset = DeviceInfo::getCompositorOffset();
    nsecs_t offsetDelta = sfOffset - DeviceInfo::getAppOffset();
    // There are two different offset cases. If the offsetDelta is positive
+49 −76
Original line number Diff line number Diff line
@@ -34,7 +34,6 @@
#include <GrContextOptions.h>
#include <gl/GrGLInterface.h>

#include <gui/DisplayEventReceiver.h>
#include <sys/resource.h>
#include <utils/Condition.h>
#include <utils/Log.h>
@@ -45,53 +44,43 @@ namespace android {
namespace uirenderer {
namespace renderthread {

// Number of events to read at a time from the DisplayEventReceiver pipe.
// The value should be large enough that we can quickly drain the pipe
// using just a few large reads.
static const size_t EVENT_BUFFER_SIZE = 100;

static bool gHasRenderThreadInstance = false;

static JVMAttachHook gOnStartHook = nullptr;

class DisplayEventReceiverWrapper : public VsyncSource {
public:
    DisplayEventReceiverWrapper(std::unique_ptr<DisplayEventReceiver>&& receiver,
            const std::function<void()>& onDisplayConfigChanged)
            : mDisplayEventReceiver(std::move(receiver))
            , mOnDisplayConfigChanged(onDisplayConfigChanged) {}

    virtual void requestNextVsync() override {
        status_t status = mDisplayEventReceiver->requestNextVsync();
        LOG_ALWAYS_FATAL_IF(status != NO_ERROR, "requestNextVsync failed with status: %d", status);
    }

    virtual nsecs_t latestVsyncEvent() override {
        DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE];
        nsecs_t latest = 0;
        ssize_t n;
        while ((n = mDisplayEventReceiver->getEvents(buf, EVENT_BUFFER_SIZE)) > 0) {
            for (ssize_t i = 0; i < n; i++) {
                const DisplayEventReceiver::Event& ev = buf[i];
                switch (ev.header.type) {
                    case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
                        latest = ev.header.timestamp;
                        break;
                    case DisplayEventReceiver::DISPLAY_EVENT_CONFIG_CHANGED:
                        mOnDisplayConfigChanged();
                        break;
void RenderThread::frameCallback(int64_t frameTimeNanos, void* data) {
    RenderThread* rt = reinterpret_cast<RenderThread*>(data);
    rt->mVsyncRequested = false;
    if (rt->timeLord().vsyncReceived(frameTimeNanos) && !rt->mFrameCallbackTaskPending) {
        ATRACE_NAME("queue mFrameCallbackTask");
        rt->mFrameCallbackTaskPending = true;
        nsecs_t runAt = (frameTimeNanos + rt->mDispatchFrameDelay);
        rt->queue().postAt(runAt, [=]() { rt->dispatchFrameCallbacks(); });
    }
}

void RenderThread::refreshRateCallback(int64_t vsyncPeriod, void* data) {
    ATRACE_NAME("refreshRateCallback");
    RenderThread* rt = reinterpret_cast<RenderThread*>(data);
    DeviceInfo::get()->onRefreshRateChanged(vsyncPeriod);
    rt->setupFrameInterval();
}
        if (n < 0) {
            ALOGW("Failed to get events from display event receiver, status=%d", status_t(n));

class ChoreographerSource : public VsyncSource {
public:
    ChoreographerSource(RenderThread* renderThread) : mRenderThread(renderThread) {}

    virtual void requestNextVsync() override {
        AChoreographer_postFrameCallback64(mRenderThread->mChoreographer,
                                           RenderThread::frameCallback, mRenderThread);
    }
        return latest;

    virtual void drainPendingEvents() override {
        AChoreographer_handlePendingEvents(mRenderThread->mChoreographer, mRenderThread);
    }

private:
    std::unique_ptr<DisplayEventReceiver> mDisplayEventReceiver;
    std::function<void()> mOnDisplayConfigChanged;
    RenderThread* mRenderThread;
};

class DummyVsyncSource : public VsyncSource {
@@ -99,11 +88,14 @@ public:
    DummyVsyncSource(RenderThread* renderThread) : mRenderThread(renderThread) {}

    virtual void requestNextVsync() override {
        mRenderThread->queue().postDelayed(16_ms,
                                           [this]() { mRenderThread->drainDisplayEventQueue(); });
        mRenderThread->queue().postDelayed(16_ms, [this]() {
            RenderThread::frameCallback(systemTime(SYSTEM_TIME_MONOTONIC), mRenderThread);
        });
    }

    virtual nsecs_t latestVsyncEvent() override { return systemTime(SYSTEM_TIME_MONOTONIC); }
    virtual void drainPendingEvents() override {
        RenderThread::frameCallback(systemTime(SYSTEM_TIME_MONOTONIC), mRenderThread);
    }

private:
    RenderThread* mRenderThread;
@@ -145,29 +137,24 @@ RenderThread::RenderThread()
}

RenderThread::~RenderThread() {
    // Note that if this fatal assertion is removed then member variables must
    // be properly destroyed.
    LOG_ALWAYS_FATAL("Can't destroy the render thread");
}

void RenderThread::initializeDisplayEventReceiver() {
    LOG_ALWAYS_FATAL_IF(mVsyncSource, "Initializing a second DisplayEventReceiver?");
void RenderThread::initializeChoreographer() {
    LOG_ALWAYS_FATAL_IF(mVsyncSource, "Initializing a second Choreographer?");

    if (!Properties::isolatedProcess) {
        auto receiver = std::make_unique<DisplayEventReceiver>(
            ISurfaceComposer::eVsyncSourceApp,
            ISurfaceComposer::eConfigChangedDispatch);
        status_t status = receiver->initCheck();
        LOG_ALWAYS_FATAL_IF(status != NO_ERROR,
                            "Initialization of DisplayEventReceiver "
                            "failed with status: %d",
                            status);
        mChoreographer = AChoreographer_create();
        LOG_ALWAYS_FATAL_IF(mChoreographer == nullptr, "Initialization of Choreographer failed");
        AChoreographer_registerRefreshRateCallback(mChoreographer,
                                                   RenderThread::refreshRateCallback, this);

        // Register the FD
        mLooper->addFd(receiver->getFd(), 0, Looper::EVENT_INPUT,
                       RenderThread::displayEventReceiverCallback, this);
        mVsyncSource = new DisplayEventReceiverWrapper(std::move(receiver), [this] {
            DeviceInfo::get()->onDisplayConfigChanged();
            setupFrameInterval();
        });
        mLooper->addFd(AChoreographer_getFd(mChoreographer), 0, Looper::EVENT_INPUT,
                       RenderThread::choreographerCallback, this);
        mVsyncSource = new ChoreographerSource(this);
    } else {
        mVsyncSource = new DummyVsyncSource(this);
    }
@@ -175,7 +162,7 @@ void RenderThread::initializeDisplayEventReceiver() {

void RenderThread::initThreadLocals() {
    setupFrameInterval();
    initializeDisplayEventReceiver();
    initializeChoreographer();
    mEglManager = new EglManager();
    mRenderState = new RenderState(*this);
    mVkManager = new VulkanManager();
@@ -183,7 +170,7 @@ void RenderThread::initThreadLocals() {
}

void RenderThread::setupFrameInterval() {
    nsecs_t frameIntervalNanos = static_cast<nsecs_t>(1000000000 / DeviceInfo::getRefreshRate());
    nsecs_t frameIntervalNanos = DeviceInfo::getVsyncPeriod();
    mTimeLord.setFrameInterval(frameIntervalNanos);
    mDispatchFrameDelay = static_cast<nsecs_t>(frameIntervalNanos * .25f);
}
@@ -288,7 +275,7 @@ void RenderThread::setGrContext(sk_sp<GrContext> context) {
    }
}

int RenderThread::displayEventReceiverCallback(int fd, int events, void* data) {
int RenderThread::choreographerCallback(int fd, int events, void* data) {
    if (events & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP)) {
        ALOGE("Display event receiver pipe was closed or an error occurred.  "
              "events=0x%x",
@@ -302,24 +289,10 @@ int RenderThread::displayEventReceiverCallback(int fd, int events, void* data) {
              events);
        return 1;  // keep the callback
    }
    RenderThread* rt = reinterpret_cast<RenderThread*>(data);
    AChoreographer_handlePendingEvents(rt->mChoreographer, data);

    reinterpret_cast<RenderThread*>(data)->drainDisplayEventQueue();

    return 1;  // keep the callback
}

void RenderThread::drainDisplayEventQueue() {
    ATRACE_CALL();
    nsecs_t vsyncEvent = mVsyncSource->latestVsyncEvent();
    if (vsyncEvent > 0) {
        mVsyncRequested = false;
        if (mTimeLord.vsyncReceived(vsyncEvent) && !mFrameCallbackTaskPending) {
            ATRACE_NAME("queue mFrameCallbackTask");
            mFrameCallbackTaskPending = true;
            nsecs_t runAt = (vsyncEvent + mDispatchFrameDelay);
            queue().postAt(runAt, [this]() { dispatchFrameCallbacks(); });
        }
    }
    return 1;
}

void RenderThread::dispatchFrameCallbacks() {
@@ -360,7 +333,7 @@ bool RenderThread::threadLoop() {
        processQueue();

        if (mPendingRegistrationFrameCallbacks.size() && !mFrameCallbackTaskPending) {
            drainDisplayEventQueue();
            mVsyncSource->drainPendingEvents();
            mFrameCallbacks.insert(mPendingRegistrationFrameCallbacks.begin(),
                                   mPendingRegistrationFrameCallbacks.end());
            mPendingRegistrationFrameCallbacks.clear();
+14 −3
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

#include <GrContext.h>
#include <SkBitmap.h>
#include <apex/choreographer.h>
#include <cutils/compiler.h>
#include <thread/ThreadBase.h>
#include <utils/Looper.h>
@@ -73,10 +74,11 @@ protected:

struct VsyncSource {
    virtual void requestNextVsync() = 0;
    virtual nsecs_t latestVsyncEvent() = 0;
    virtual void drainPendingEvents() = 0;
    virtual ~VsyncSource() {}
};

class ChoreographerSource;
class DummyVsyncSource;

typedef void (*JVMAttachHook)(const char* name);
@@ -136,6 +138,7 @@ private:
    friend class DispatchFrameCallbacks;
    friend class RenderProxy;
    friend class DummyVsyncSource;
    friend class ChoreographerSource;
    friend class android::uirenderer::AutoBackendTextureRelease;
    friend class android::uirenderer::TestUtils;
    friend class android::uirenderer::WebViewFunctor;
@@ -149,13 +152,21 @@ private:
    static RenderThread& getInstance();

    void initThreadLocals();
    void initializeDisplayEventReceiver();
    void initializeChoreographer();
    void setupFrameInterval();
    static int displayEventReceiverCallback(int fd, int events, void* data);
    // Callbacks for choreographer events:
    // choreographerCallback will call AChoreograper_handleEvent to call the
    // corresponding callbacks for each display event type
    static int choreographerCallback(int fd, int events, void* data);
    // Callback that will be run on vsync ticks.
    static void frameCallback(int64_t frameTimeNanos, void* data);
    // Callback that will be run whenver there is a refresh rate change.
    static void refreshRateCallback(int64_t vsyncPeriod, void* data);
    void drainDisplayEventQueue();
    void dispatchFrameCallbacks();
    void requestVsync();

    AChoreographer* mChoreographer;
    VsyncSource* mVsyncSource;
    bool mVsyncRequested;
    std::set<IFrameCallback*> mFrameCallbacks;