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>
28f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
29f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian#include "MessageQueue.h"
308aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian#include "EventThread.h"
3199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian#include "SurfaceFlinger.h"
32f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
33f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopiannamespace android {
34f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
35f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian// ---------------------------------------------------------------------------
36f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
37f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias AgopianMessageBase::MessageBase()
38f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian    : MessageHandler() {
39b6683b58a8cd97e6d527a355bee7ffe9cf8fd6e7Mathias Agopian}
40b6683b58a8cd97e6d527a355bee7ffe9cf8fd6e7Mathias Agopian
41f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias AgopianMessageBase::~MessageBase() {
42b6683b58a8cd97e6d527a355bee7ffe9cf8fd6e7Mathias Agopian}
43b6683b58a8cd97e6d527a355bee7ffe9cf8fd6e7Mathias Agopian
44f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopianvoid MessageBase::handleMessage(const Message&) {
45f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian    this->handler();
46f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian    barrier.open();
47f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian};
48f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian
49b6683b58a8cd97e6d527a355bee7ffe9cf8fd6e7Mathias Agopian// ---------------------------------------------------------------------------
50b6683b58a8cd97e6d527a355bee7ffe9cf8fd6e7Mathias Agopian
514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid MessageQueue::Handler::dispatchRefresh() {
5299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) {
5399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));
5499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
5599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
5699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid MessageQueue::Handler::dispatchInvalidate() {
5899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) {
5999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));
6099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
6199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
6299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
6399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid MessageQueue::Handler::handleMessage(const Message& message) {
6499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (message.what) {
6599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        case INVALIDATE:
6699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            android_atomic_and(~eventMaskInvalidate, &mEventMask);
6799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            mQueue.mFlinger->onMessageReceived(message.what);
6899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            break;
6999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        case REFRESH:
7099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            android_atomic_and(~eventMaskRefresh, &mEventMask);
7199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            mQueue.mFlinger->onMessageReceived(message.what);
7299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            break;
7399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
7499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
7599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
7699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian// ---------------------------------------------------------------------------
7799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
78f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias AgopianMessageQueue::MessageQueue()
79f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian{
80f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian}
81f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
82f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias AgopianMessageQueue::~MessageQueue() {
83f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian}
84f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
8599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid MessageQueue::init(const sp<SurfaceFlinger>& flinger)
8699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
8799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mFlinger = flinger;
8899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mLooper = new Looper(true);
8999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mHandler = new Handler(*this);
9099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
9199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
928aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopianvoid MessageQueue::setEventThread(const sp<EventThread>& eventThread)
938aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian{
948aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    mEventThread = eventThread;
958aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    mEvents = eventThread->createEventConnection();
966b698e4fe4ff50dcef818452283637f9870ae770Dan Stoza    mEvents->stealReceiveChannel(&mEventTube);
976b698e4fe4ff50dcef818452283637f9870ae770Dan Stoza    mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT,
988aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian            MessageQueue::cb_eventReceiver, this);
998aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian}
1008aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian
101f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopianvoid MessageQueue::waitMessage() {
102f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    do {
103f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian        IPCThreadState::self()->flushCommands();
104f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian        int32_t ret = mLooper->pollOnce(-1);
105f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian        switch (ret) {
106fe761ab6c72bdcdb8a2cf0df1524f526d8609feeBrian Carlstrom            case Looper::POLL_WAKE:
107fe761ab6c72bdcdb8a2cf0df1524f526d8609feeBrian Carlstrom            case Looper::POLL_CALLBACK:
108f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian                continue;
109fe761ab6c72bdcdb8a2cf0df1524f526d8609feeBrian Carlstrom            case Looper::POLL_ERROR:
110fe761ab6c72bdcdb8a2cf0df1524f526d8609feeBrian Carlstrom                ALOGE("Looper::POLL_ERROR");
11153390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos                continue;
112fe761ab6c72bdcdb8a2cf0df1524f526d8609feeBrian Carlstrom            case Looper::POLL_TIMEOUT:
11399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian                // timeout (should not happen)
114f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian                continue;
115f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian            default:
116f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian                // should not happen
117e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Looper::pollOnce() returned unknown status %d", ret);
118f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian                continue;
119f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian        }
120f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian    } while (true);
121f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian}
122f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
123f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopianstatus_t MessageQueue::postMessage(
124f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian        const sp<MessageBase>& messageHandler, nsecs_t relTime)
125f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian{
126f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian    const Message dummyMessage;
127f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian    if (relTime > 0) {
128f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian        mLooper->sendMessageDelayed(relTime, messageHandler, dummyMessage);
129f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian    } else {
130f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian        mLooper->sendMessage(messageHandler, dummyMessage);
131f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian    }
132f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian    return NO_ERROR;
133f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian}
134f61c57fe2e955e1c195bb0ca2dd7bcdaa922d5a9Mathias Agopian
1359eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian
13699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid MessageQueue::invalidate() {
13769a655caef30663403802281210363f643ceb946Mathias Agopian    mEvents->requestNextVsync();
1388aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian}
1398aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian
14099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid MessageQueue::refresh() {
1414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mHandler->dispatchRefresh();
142f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian}
143f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
1448aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopianint MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
1458aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    MessageQueue* queue = reinterpret_cast<MessageQueue *>(data);
1468aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return queue->eventReceiver(fd, events);
1478aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian}
1488aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian
14992dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzynint MessageQueue::eventReceiver(int /*fd*/, int /*events*/) {
1508aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    ssize_t n;
1518aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    DisplayEventReceiver::Event buffer[8];
1526b698e4fe4ff50dcef818452283637f9870ae770Dan Stoza    while ((n = DisplayEventReceiver::getEvents(&mEventTube, buffer, 8)) > 0) {
1538aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian        for (int i=0 ; i<n ; i++) {
1548aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian            if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
1554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                mHandler->dispatchInvalidate();
1568aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian                break;
1578aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian            }
1588aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian        }
1598aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    }
1608aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return 1;
1618aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian}
1628aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian
163f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian// ---------------------------------------------------------------------------
164f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
165f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian}; // namespace android
166