1f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian/*
2f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian * Copyright (C) 2009 The Android Open Source Project
3f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian *
4f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License");
5f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian * you may not use this file except in compliance with the License.
6f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian * You may obtain a copy of the License at
7f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian *
8f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian *      http://www.apache.org/licenses/LICENSE-2.0
9f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian *
10f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian * Unless required by applicable law or agreed to in writing, software
11f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS,
12f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian * See the License for the specific language governing permissions and
14f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian * limitations under the License.
15f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian */
16f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
17f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian#include <stdint.h>
18f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian#include <errno.h>
19f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian#include <sys/types.h>
20f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
218aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian#include <binder/IPCThreadState.h>
228aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian
23f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian#include <utils/threads.h>
24f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian#include <utils/Timers.h>
25f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian#include <utils/Log.h>
268aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian
278aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian#include <gui/IDisplayEventConnection.h>
288aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian#include <gui/BitTube.h>
29f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
30f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian#include "MessageQueue.h"
318aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian#include "EventThread.h"
3299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian#include "SurfaceFlinger.h"
33f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
34f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopiannamespace android {
35f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
36f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian// ---------------------------------------------------------------------------
37f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
38f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias AgopianMessageBase::MessageBase()
39f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian    : MessageHandler() {
40b6683b58a8cd97e6d527a355bee7ffe9cf8fd6e7Mathias Agopian}
41b6683b58a8cd97e6d527a355bee7ffe9cf8fd6e7Mathias Agopian
42f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias AgopianMessageBase::~MessageBase() {
43b6683b58a8cd97e6d527a355bee7ffe9cf8fd6e7Mathias Agopian}
44b6683b58a8cd97e6d527a355bee7ffe9cf8fd6e7Mathias Agopian
45f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopianvoid MessageBase::handleMessage(const Message&) {
46f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian    this->handler();
47f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian    barrier.open();
48f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian};
49f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian
50b6683b58a8cd97e6d527a355bee7ffe9cf8fd6e7Mathias Agopian// ---------------------------------------------------------------------------
51b6683b58a8cd97e6d527a355bee7ffe9cf8fd6e7Mathias Agopian
524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid MessageQueue::Handler::dispatchRefresh() {
5399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) {
5499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));
5599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
5699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
5799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid MessageQueue::Handler::dispatchInvalidate() {
5999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) {
6099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));
6199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
6299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
6399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
649eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopianvoid MessageQueue::Handler::dispatchTransaction() {
659eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    if ((android_atomic_or(eventMaskTransaction, &mEventMask) & eventMaskTransaction) == 0) {
669eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian        mQueue.mLooper->sendMessage(this, Message(MessageQueue::TRANSACTION));
679eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    }
689eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian}
699eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian
7099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid MessageQueue::Handler::handleMessage(const Message& message) {
7199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (message.what) {
7299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        case INVALIDATE:
7399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            android_atomic_and(~eventMaskInvalidate, &mEventMask);
7499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            mQueue.mFlinger->onMessageReceived(message.what);
7599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            break;
7699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        case REFRESH:
7799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            android_atomic_and(~eventMaskRefresh, &mEventMask);
7899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            mQueue.mFlinger->onMessageReceived(message.what);
7999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            break;
809eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian        case TRANSACTION:
819eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian            android_atomic_and(~eventMaskTransaction, &mEventMask);
829eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian            mQueue.mFlinger->onMessageReceived(message.what);
839eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian            break;
8499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
8599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
8699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
8799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian// ---------------------------------------------------------------------------
8899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
89f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias AgopianMessageQueue::MessageQueue()
90f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian{
91f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian}
92f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
93f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias AgopianMessageQueue::~MessageQueue() {
94f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian}
95f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
9699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid MessageQueue::init(const sp<SurfaceFlinger>& flinger)
9799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
9899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mFlinger = flinger;
9999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mLooper = new Looper(true);
10099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mHandler = new Handler(*this);
10199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
10299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1038aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopianvoid MessageQueue::setEventThread(const sp<EventThread>& eventThread)
1048aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian{
1058aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    mEventThread = eventThread;
1068aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    mEvents = eventThread->createEventConnection();
1078aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    mEventTube = mEvents->getDataChannel();
1088aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    mLooper->addFd(mEventTube->getFd(), 0, ALOOPER_EVENT_INPUT,
1098aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian            MessageQueue::cb_eventReceiver, this);
1108aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian}
1118aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian
112f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopianvoid MessageQueue::waitMessage() {
113f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    do {
114f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian        IPCThreadState::self()->flushCommands();
115f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian        int32_t ret = mLooper->pollOnce(-1);
116f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian        switch (ret) {
117f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian            case ALOOPER_POLL_WAKE:
118f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian            case ALOOPER_POLL_CALLBACK:
119f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian                continue;
120f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian            case ALOOPER_POLL_ERROR:
121e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("ALOOPER_POLL_ERROR");
12299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            case ALOOPER_POLL_TIMEOUT:
12399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian                // timeout (should not happen)
124f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian                continue;
125f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian            default:
126f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian                // should not happen
127e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Looper::pollOnce() returned unknown status %d", ret);
128f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian                continue;
129f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian        }
130f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian    } while (true);
131f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian}
132f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
133f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopianstatus_t MessageQueue::postMessage(
134f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian        const sp<MessageBase>& messageHandler, nsecs_t relTime)
135f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian{
136f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian    const Message dummyMessage;
137f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian    if (relTime > 0) {
138f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian        mLooper->sendMessageDelayed(relTime, messageHandler, dummyMessage);
139f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian    } else {
140f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian        mLooper->sendMessage(messageHandler, dummyMessage);
141f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    }
142f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian    return NO_ERROR;
143f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian}
144f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian
1459eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian
1464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian/* when INVALIDATE_ON_VSYNC is set SF only processes
1474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian * buffer updates on VSYNC and performs a refresh immediately
1484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian * after.
1494fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian *
1504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian * when INVALIDATE_ON_VSYNC is set to false, SF will instead
1514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian * perform the buffer updates immediately, but the refresh only
1524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian * at the next VSYNC.
1534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian * THIS MODE IS BUGGY ON GALAXY NEXUS AND WILL CAUSE HANGS
1544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian */
1554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian#define INVALIDATE_ON_VSYNC 1
1564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
1579eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopianvoid MessageQueue::invalidateTransactionNow() {
1589eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    mHandler->dispatchTransaction();
1599eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian}
1609eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian
16199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid MessageQueue::invalidate() {
1624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian#if INVALIDATE_ON_VSYNC
16369a655caef30663403802281210363f643ceb946Mathias Agopian    mEvents->requestNextVsync();
1644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian#else
1654fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mHandler->dispatchInvalidate();
1664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian#endif
1678aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian}
1688aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian
16999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid MessageQueue::refresh() {
1704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian#if INVALIDATE_ON_VSYNC
1714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mHandler->dispatchRefresh();
1724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian#else
1738aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    mEvents->requestNextVsync();
1744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian#endif
175f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian}
176f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
1778aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopianint MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
1788aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    MessageQueue* queue = reinterpret_cast<MessageQueue *>(data);
1798aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return queue->eventReceiver(fd, events);
1808aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian}
1818aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian
1828aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopianint MessageQueue::eventReceiver(int fd, int events) {
1838aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    ssize_t n;
1848aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    DisplayEventReceiver::Event buffer[8];
18599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    while ((n = DisplayEventReceiver::getEvents(mEventTube, buffer, 8)) > 0) {
1868aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian        for (int i=0 ; i<n ; i++) {
1878aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian            if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
1884fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian#if INVALIDATE_ON_VSYNC
1894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                mHandler->dispatchInvalidate();
1904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian#else
1914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                mHandler->dispatchRefresh();
1924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian#endif
1938aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian                break;
1948aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian            }
1958aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian        }
1968aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    }
1978aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return 1;
1988aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian}
1998aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian
200f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian// ---------------------------------------------------------------------------
201f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
202f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian}; // namespace android
203