Home | History | Annotate | Download | only in surfaceflinger
      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 <stdint.h>
     18 #include <errno.h>
     19 #include <sys/types.h>
     20 
     21 #include <binder/IPCThreadState.h>
     22 
     23 #include <utils/threads.h>
     24 #include <utils/Timers.h>
     25 #include <utils/Log.h>
     26 
     27 #include <gui/IDisplayEventConnection.h>
     28 
     29 #include "MessageQueue.h"
     30 #include "EventThread.h"
     31 #include "SurfaceFlinger.h"
     32 
     33 namespace android {
     34 
     35 // ---------------------------------------------------------------------------
     36 
     37 MessageBase::MessageBase()
     38     : MessageHandler() {
     39 }
     40 
     41 MessageBase::~MessageBase() {
     42 }
     43 
     44 void MessageBase::handleMessage(const Message&) {
     45     this->handler();
     46     barrier.open();
     47 };
     48 
     49 // ---------------------------------------------------------------------------
     50 
     51 void MessageQueue::Handler::dispatchRefresh() {
     52     if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) {
     53         mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));
     54     }
     55 }
     56 
     57 void MessageQueue::Handler::dispatchInvalidate() {
     58     if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) {
     59         mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));
     60     }
     61 }
     62 
     63 void MessageQueue::Handler::handleMessage(const Message& message) {
     64     switch (message.what) {
     65         case INVALIDATE:
     66             android_atomic_and(~eventMaskInvalidate, &mEventMask);
     67             mQueue.mFlinger->onMessageReceived(message.what);
     68             break;
     69         case REFRESH:
     70             android_atomic_and(~eventMaskRefresh, &mEventMask);
     71             mQueue.mFlinger->onMessageReceived(message.what);
     72             break;
     73     }
     74 }
     75 
     76 // ---------------------------------------------------------------------------
     77 
     78 MessageQueue::MessageQueue()
     79 {
     80 }
     81 
     82 MessageQueue::~MessageQueue() {
     83 }
     84 
     85 void MessageQueue::init(const sp<SurfaceFlinger>& flinger)
     86 {
     87     mFlinger = flinger;
     88     mLooper = new Looper(true);
     89     mHandler = new Handler(*this);
     90 }
     91 
     92 void MessageQueue::setEventThread(const sp<EventThread>& eventThread)
     93 {
     94     mEventThread = eventThread;
     95     mEvents = eventThread->createEventConnection();
     96     mEvents->stealReceiveChannel(&mEventTube);
     97     mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT,
     98             MessageQueue::cb_eventReceiver, this);
     99 }
    100 
    101 void MessageQueue::waitMessage() {
    102     do {
    103         IPCThreadState::self()->flushCommands();
    104         int32_t ret = mLooper->pollOnce(-1);
    105         switch (ret) {
    106             case Looper::POLL_WAKE:
    107             case Looper::POLL_CALLBACK:
    108                 continue;
    109             case Looper::POLL_ERROR:
    110                 ALOGE("Looper::POLL_ERROR");
    111                 continue;
    112             case Looper::POLL_TIMEOUT:
    113                 // timeout (should not happen)
    114                 continue;
    115             default:
    116                 // should not happen
    117                 ALOGE("Looper::pollOnce() returned unknown status %d", ret);
    118                 continue;
    119         }
    120     } while (true);
    121 }
    122 
    123 status_t MessageQueue::postMessage(
    124         const sp<MessageBase>& messageHandler, nsecs_t relTime)
    125 {
    126     const Message dummyMessage;
    127     if (relTime > 0) {
    128         mLooper->sendMessageDelayed(relTime, messageHandler, dummyMessage);
    129     } else {
    130         mLooper->sendMessage(messageHandler, dummyMessage);
    131     }
    132     return NO_ERROR;
    133 }
    134 
    135 
    136 void MessageQueue::invalidate() {
    137     mEvents->requestNextVsync();
    138 }
    139 
    140 void MessageQueue::refresh() {
    141     mHandler->dispatchRefresh();
    142 }
    143 
    144 int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
    145     MessageQueue* queue = reinterpret_cast<MessageQueue *>(data);
    146     return queue->eventReceiver(fd, events);
    147 }
    148 
    149 int MessageQueue::eventReceiver(int /*fd*/, int /*events*/) {
    150     ssize_t n;
    151     DisplayEventReceiver::Event buffer[8];
    152     while ((n = DisplayEventReceiver::getEvents(&mEventTube, buffer, 8)) > 0) {
    153         for (int i=0 ; i<n ; i++) {
    154             if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
    155                 mHandler->dispatchInvalidate();
    156                 break;
    157             }
    158         }
    159     }
    160     return 1;
    161 }
    162 
    163 // ---------------------------------------------------------------------------
    164 
    165 }; // namespace android
    166