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 #include <gui/BitTube.h>
     29 
     30 #include "MessageQueue.h"
     31 #include "EventThread.h"
     32 #include "SurfaceFlinger.h"
     33 
     34 namespace android {
     35 
     36 // ---------------------------------------------------------------------------
     37 
     38 MessageBase::MessageBase()
     39     : MessageHandler() {
     40 }
     41 
     42 MessageBase::~MessageBase() {
     43 }
     44 
     45 void MessageBase::handleMessage(const Message&) {
     46     this->handler();
     47     barrier.open();
     48 };
     49 
     50 // ---------------------------------------------------------------------------
     51 
     52 void MessageQueue::Handler::dispatchRefresh() {
     53     if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) {
     54         mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));
     55     }
     56 }
     57 
     58 void MessageQueue::Handler::dispatchInvalidate() {
     59     if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) {
     60         mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));
     61     }
     62 }
     63 
     64 void MessageQueue::Handler::dispatchTransaction() {
     65     if ((android_atomic_or(eventMaskTransaction, &mEventMask) & eventMaskTransaction) == 0) {
     66         mQueue.mLooper->sendMessage(this, Message(MessageQueue::TRANSACTION));
     67     }
     68 }
     69 
     70 void MessageQueue::Handler::handleMessage(const Message& message) {
     71     switch (message.what) {
     72         case INVALIDATE:
     73             android_atomic_and(~eventMaskInvalidate, &mEventMask);
     74             mQueue.mFlinger->onMessageReceived(message.what);
     75             break;
     76         case REFRESH:
     77             android_atomic_and(~eventMaskRefresh, &mEventMask);
     78             mQueue.mFlinger->onMessageReceived(message.what);
     79             break;
     80         case TRANSACTION:
     81             android_atomic_and(~eventMaskTransaction, &mEventMask);
     82             mQueue.mFlinger->onMessageReceived(message.what);
     83             break;
     84     }
     85 }
     86 
     87 // ---------------------------------------------------------------------------
     88 
     89 MessageQueue::MessageQueue()
     90 {
     91 }
     92 
     93 MessageQueue::~MessageQueue() {
     94 }
     95 
     96 void MessageQueue::init(const sp<SurfaceFlinger>& flinger)
     97 {
     98     mFlinger = flinger;
     99     mLooper = new Looper(true);
    100     mHandler = new Handler(*this);
    101 }
    102 
    103 void MessageQueue::setEventThread(const sp<EventThread>& eventThread)
    104 {
    105     mEventThread = eventThread;
    106     mEvents = eventThread->createEventConnection();
    107     mEventTube = mEvents->getDataChannel();
    108     mLooper->addFd(mEventTube->getFd(), 0, Looper::EVENT_INPUT,
    109             MessageQueue::cb_eventReceiver, this);
    110 }
    111 
    112 void MessageQueue::waitMessage() {
    113     do {
    114         IPCThreadState::self()->flushCommands();
    115         int32_t ret = mLooper->pollOnce(-1);
    116         switch (ret) {
    117             case Looper::POLL_WAKE:
    118             case Looper::POLL_CALLBACK:
    119                 continue;
    120             case Looper::POLL_ERROR:
    121                 ALOGE("Looper::POLL_ERROR");
    122             case Looper::POLL_TIMEOUT:
    123                 // timeout (should not happen)
    124                 continue;
    125             default:
    126                 // should not happen
    127                 ALOGE("Looper::pollOnce() returned unknown status %d", ret);
    128                 continue;
    129         }
    130     } while (true);
    131 }
    132 
    133 status_t MessageQueue::postMessage(
    134         const sp<MessageBase>& messageHandler, nsecs_t relTime)
    135 {
    136     const Message dummyMessage;
    137     if (relTime > 0) {
    138         mLooper->sendMessageDelayed(relTime, messageHandler, dummyMessage);
    139     } else {
    140         mLooper->sendMessage(messageHandler, dummyMessage);
    141     }
    142     return NO_ERROR;
    143 }
    144 
    145 
    146 /* when INVALIDATE_ON_VSYNC is set SF only processes
    147  * buffer updates on VSYNC and performs a refresh immediately
    148  * after.
    149  *
    150  * when INVALIDATE_ON_VSYNC is set to false, SF will instead
    151  * perform the buffer updates immediately, but the refresh only
    152  * at the next VSYNC.
    153  * THIS MODE IS BUGGY ON GALAXY NEXUS AND WILL CAUSE HANGS
    154  */
    155 #define INVALIDATE_ON_VSYNC 1
    156 
    157 void MessageQueue::invalidateTransactionNow() {
    158     mHandler->dispatchTransaction();
    159 }
    160 
    161 void MessageQueue::invalidate() {
    162 #if INVALIDATE_ON_VSYNC
    163     mEvents->requestNextVsync();
    164 #else
    165     mHandler->dispatchInvalidate();
    166 #endif
    167 }
    168 
    169 void MessageQueue::refresh() {
    170 #if INVALIDATE_ON_VSYNC
    171     mHandler->dispatchRefresh();
    172 #else
    173     mEvents->requestNextVsync();
    174 #endif
    175 }
    176 
    177 int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
    178     MessageQueue* queue = reinterpret_cast<MessageQueue *>(data);
    179     return queue->eventReceiver(fd, events);
    180 }
    181 
    182 int MessageQueue::eventReceiver(int /*fd*/, int /*events*/) {
    183     ssize_t n;
    184     DisplayEventReceiver::Event buffer[8];
    185     while ((n = DisplayEventReceiver::getEvents(mEventTube, buffer, 8)) > 0) {
    186         for (int i=0 ; i<n ; i++) {
    187             if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
    188 #if INVALIDATE_ON_VSYNC
    189                 mHandler->dispatchInvalidate();
    190 #else
    191                 mHandler->dispatchRefresh();
    192 #endif
    193                 break;
    194             }
    195         }
    196     }
    197     return 1;
    198 }
    199 
    200 // ---------------------------------------------------------------------------
    201 
    202 }; // namespace android
    203