Home | History | Annotate | Download | only in Scheduler
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <errno.h>
     18 #include <stdint.h>
     19 #include <sys/types.h>
     20 
     21 #include <binder/IPCThreadState.h>
     22 
     23 #include <utils/Log.h>
     24 #include <utils/Timers.h>
     25 #include <utils/threads.h>
     26 
     27 #include <gui/DisplayEventReceiver.h>
     28 #include <gui/IDisplayEventConnection.h>
     29 
     30 #include "EventThread.h"
     31 #include "MessageQueue.h"
     32 #include "SurfaceFlinger.h"
     33 
     34 namespace android {
     35 
     36 // ---------------------------------------------------------------------------
     37 
     38 MessageBase::MessageBase() : MessageHandler() {}
     39 
     40 MessageBase::~MessageBase() {}
     41 
     42 void MessageBase::handleMessage(const Message&) {
     43     this->handler();
     44     barrier.open();
     45 };
     46 
     47 // ---------------------------------------------------------------------------
     48 
     49 MessageQueue::~MessageQueue() = default;
     50 
     51 // ---------------------------------------------------------------------------
     52 
     53 namespace impl {
     54 
     55 void MessageQueue::Handler::dispatchRefresh() {
     56     if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) {
     57         mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));
     58     }
     59 }
     60 
     61 void MessageQueue::Handler::dispatchInvalidate() {
     62     if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) {
     63         mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));
     64     }
     65 }
     66 
     67 void MessageQueue::Handler::handleMessage(const Message& message) {
     68     switch (message.what) {
     69         case INVALIDATE:
     70             android_atomic_and(~eventMaskInvalidate, &mEventMask);
     71             mQueue.mFlinger->onMessageReceived(message.what);
     72             break;
     73         case REFRESH:
     74             android_atomic_and(~eventMaskRefresh, &mEventMask);
     75             mQueue.mFlinger->onMessageReceived(message.what);
     76             break;
     77     }
     78 }
     79 
     80 // ---------------------------------------------------------------------------
     81 
     82 void MessageQueue::init(const sp<SurfaceFlinger>& flinger) {
     83     mFlinger = flinger;
     84     mLooper = new Looper(true);
     85     mHandler = new Handler(*this);
     86 }
     87 
     88 void MessageQueue::setEventThread(android::EventThread* eventThread,
     89                                   ResyncCallback resyncCallback) {
     90     if (mEventThread == eventThread) {
     91         return;
     92     }
     93 
     94     if (mEventTube.getFd() >= 0) {
     95         mLooper->removeFd(mEventTube.getFd());
     96     }
     97 
     98     mEventThread = eventThread;
     99     mEvents = eventThread->createEventConnection(std::move(resyncCallback));
    100     mEvents->stealReceiveChannel(&mEventTube);
    101     mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver,
    102                    this);
    103 }
    104 
    105 void MessageQueue::setEventConnection(const sp<EventThreadConnection>& connection) {
    106     if (mEventTube.getFd() >= 0) {
    107         mLooper->removeFd(mEventTube.getFd());
    108     }
    109 
    110     mEvents = connection;
    111     mEvents->stealReceiveChannel(&mEventTube);
    112     mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver,
    113                    this);
    114 }
    115 
    116 void MessageQueue::waitMessage() {
    117     do {
    118         IPCThreadState::self()->flushCommands();
    119         int32_t ret = mLooper->pollOnce(-1);
    120         switch (ret) {
    121             case Looper::POLL_WAKE:
    122             case Looper::POLL_CALLBACK:
    123                 continue;
    124             case Looper::POLL_ERROR:
    125                 ALOGE("Looper::POLL_ERROR");
    126                 continue;
    127             case Looper::POLL_TIMEOUT:
    128                 // timeout (should not happen)
    129                 continue;
    130             default:
    131                 // should not happen
    132                 ALOGE("Looper::pollOnce() returned unknown status %d", ret);
    133                 continue;
    134         }
    135     } while (true);
    136 }
    137 
    138 status_t MessageQueue::postMessage(const sp<MessageBase>& messageHandler, nsecs_t relTime) {
    139     const Message dummyMessage;
    140     if (relTime > 0) {
    141         mLooper->sendMessageDelayed(relTime, messageHandler, dummyMessage);
    142     } else {
    143         mLooper->sendMessage(messageHandler, dummyMessage);
    144     }
    145     return NO_ERROR;
    146 }
    147 
    148 void MessageQueue::invalidate() {
    149     mEvents->requestNextVsync();
    150 }
    151 
    152 void MessageQueue::refresh() {
    153     mHandler->dispatchRefresh();
    154 }
    155 
    156 int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
    157     MessageQueue* queue = reinterpret_cast<MessageQueue*>(data);
    158     return queue->eventReceiver(fd, events);
    159 }
    160 
    161 int MessageQueue::eventReceiver(int /*fd*/, int /*events*/) {
    162     ssize_t n;
    163     DisplayEventReceiver::Event buffer[8];
    164     while ((n = DisplayEventReceiver::getEvents(&mEventTube, buffer, 8)) > 0) {
    165         for (int i = 0; i < n; i++) {
    166             if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
    167                 mHandler->dispatchInvalidate();
    168                 break;
    169             }
    170         }
    171     }
    172     return 1;
    173 }
    174 
    175 // ---------------------------------------------------------------------------
    176 
    177 } // namespace impl
    178 } // namespace android
    179