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

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

Merge "[AChoreographer] Add private api that decouples from ALooper."

parents dca5cd30 50a931da
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -50,17 +50,20 @@ status_t DisplayEventDispatcher::initialize() {
        return result;
    }

    if (mLooper != nullptr) {
        int rc = mLooper->addFd(mReceiver.getFd(), 0, Looper::EVENT_INPUT, this, NULL);
        if (rc < 0) {
            return UNKNOWN_ERROR;
        }
    }

    return OK;
}

void DisplayEventDispatcher::dispose() {
    ALOGV("dispatcher %p ~ Disposing display event dispatcher.", this);

    if (!mReceiver.initCheck()) {
    if (!mReceiver.initCheck() && mLooper != nullptr) {
        mLooper->removeFd(mReceiver.getFd());
    }
}
@@ -101,6 +104,10 @@ void DisplayEventDispatcher::toggleConfigEvents(ISurfaceComposer::ConfigChanged
    mConfigChangeFlag = configChangeFlag;
}

int DisplayEventDispatcher::getFd() {
    return mReceiver.getFd();
}

int DisplayEventDispatcher::handleEvent(int, int events, void*) {
    if (events & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP)) {
        ALOGE("Display event receiver pipe was closed or an error occurred.  "
+2 −1
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@ public:
    void dispose();
    status_t scheduleVsync();
    void toggleConfigEvents(ISurfaceComposer::ConfigChanged configChangeFlag);
    int getFd();
    virtual int handleEvent(int receiveFd, int events, void* data);

protected:
    virtual ~DisplayEventDispatcher() = default;
@@ -48,7 +50,6 @@ private:
    virtual void dispatchConfigChanged(nsecs_t timestamp, PhysicalDisplayId displayId,
                                       int32_t configId, nsecs_t vsyncPeriod) = 0;

    virtual int handleEvent(int receiveFd, int events, void* data);
    bool processPendingEvents(nsecs_t* outTimestamp, PhysicalDisplayId* outDisplayId,
                              uint32_t* outCount);
};
+43 −8
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ struct RefreshRateCallback {

class Choreographer : public DisplayEventDispatcher, public MessageHandler {
public:
    explicit Choreographer(const sp<Looper>& looper);
    void postFrameCallbackDelayed(AChoreographer_frameCallback cb,
                                  AChoreographer_frameCallback64 cb64, void* data, nsecs_t delay);
    void registerRefreshRateCallback(AChoreographer_refreshRateCallback cb, void* data);
@@ -68,12 +69,9 @@ public:
    virtual void handleMessage(const Message& message) override;

    static Choreographer* getForThread();

protected:
    virtual ~Choreographer() = default;

private:
    explicit Choreographer(const sp<Looper>& looper);
    Choreographer(const Choreographer&) = delete;

    void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count) override;
@@ -132,14 +130,22 @@ void Choreographer::postFrameCallbackDelayed(
    }
    if (callback.dueTime <= now) {
        if (std::this_thread::get_id() != mThreadId) {
            if (mLooper != nullptr) {
                Message m{MSG_SCHEDULE_VSYNC};
                mLooper->sendMessage(this, m);
            } else {
                scheduleVsync();
            }
        } else {
            scheduleVsync();
        }
    } else {
        if (mLooper != nullptr) {
            Message m{MSG_SCHEDULE_CALLBACKS};
            mLooper->sendMessageDelayed(delay, this, m);
        } else {
            scheduleCallbacks();
        }
    }
}

@@ -238,7 +244,7 @@ void Choreographer::handleMessage(const Message& message) {

/* Glue for the NDK interface */

using android::Choreographer;
using namespace android;

static inline Choreographer* AChoreographer_to_Choreographer(AChoreographer* choreographer) {
    return reinterpret_cast<Choreographer*>(choreographer);
@@ -281,3 +287,32 @@ void AChoreographer_unregisterRefreshRateCallback(AChoreographer* choreographer,
                                                  AChoreographer_refreshRateCallback callback) {
    AChoreographer_to_Choreographer(choreographer)->unregisterRefreshRateCallback(callback);
}

AChoreographer* AChoreographer_create() {
    Choreographer* choreographer = new Choreographer(nullptr);
    status_t result = choreographer->initialize();
    if (result != OK) {
        ALOGW("Failed to initialize");
        return nullptr;
    }
    return Choreographer_to_AChoreographer(choreographer);
}

void AChoreographer_destroy(AChoreographer* choreographer) {
    if (choreographer == nullptr) {
        return;
    }

    delete AChoreographer_to_Choreographer(choreographer);
}

int AChoreographer_getFd(AChoreographer* choreographer) {
    return AChoreographer_to_Choreographer(choreographer)->getFd();
}

void AChoreographer_handlePendingEvents(AChoreographer* choreographer, void* data) {
    // Pass dummy fd and events args to handleEvent, since the underlying
    // DisplayEventDispatcher doesn't need them outside of validating that a
    // Looper instance didn't break, but these args circumvent those checks.
    AChoreographer_to_Choreographer(choreographer)->handleEvent(-1, Looper::EVENT_INPUT, data);
}
+1 −1
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@
// limitations under the License.

ndk_headers {
    name: "libachoreographer_ndk_headers",
    name: "libnativedisplay_ndk_headers",
    from: "include/android",
    to: "android",
    srcs: ["include/android/*.h"],
+35 −0
Original line number Diff line number Diff line
@@ -40,4 +40,39 @@ void AChoreographer_registerRefreshRateCallback(AChoreographer* choreographer,
void AChoreographer_unregisterRefreshRateCallback(AChoreographer* choreographer,
                                                  AChoreographer_refreshRateCallback);

/**
 * Creates an instance of AChoreographer.
 *
 * The key differences between this method and AChoreographer_getInstance are:
 * 1. The returned AChoreographer instance is not a thread-local, and
 * 2. This method does not require an existing ALooper attached to the thread.
 */
AChoreographer* AChoreographer_create();

/**
 * Destroys a choreographer instance created from AChoreographer_create.
 */
void AChoreographer_destroy(AChoreographer* choreographer);

/**
 * Returns the underlying file descriptor associated with this choreographer
 * instance.
 *
 * The caller can listen to the file descriptor to respond to any AChoreographer
 * events. One such way is registering the file descriptor to a Looper instance,
 * although this is not a requirement.
 */
int AChoreographer_getFd(AChoreographer* choreographer);

/**
 * Provides a callback to handle all pending events emitted by this
 * choreographer instance. Specifically, this delegates to the callbacks
 * previously registered to choreographer.
 *
 * If the associated file descriptor is attached to a Looper instance, then the
 * callback attached to that Looper is expected to handle exceptional Looper
 * events.
 */
void AChoreographer_handlePendingEvents(AChoreographer* choreographer, void* data);

__END_DECLS