diff options
| -rw-r--r-- | include/gui/DisplayEventReceiver.h | 2 | ||||
| -rw-r--r-- | libs/gui/DisplayEventReceiver.cpp | 8 | ||||
| -rw-r--r-- | services/surfaceflinger/Android.mk | 1 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.cpp | 39 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.h | 4 | ||||
| -rw-r--r-- | services/surfaceflinger/LayerBase.cpp | 19 | ||||
| -rw-r--r-- | services/surfaceflinger/LayerBase.h | 17 | ||||
| -rw-r--r-- | services/surfaceflinger/MessageQueue.cpp | 80 | ||||
| -rw-r--r-- | services/surfaceflinger/MessageQueue.h | 32 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 219 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 8 | 
11 files changed, 257 insertions, 172 deletions
| diff --git a/include/gui/DisplayEventReceiver.h b/include/gui/DisplayEventReceiver.h index a28137785e..7bca8d6ea8 100644 --- a/include/gui/DisplayEventReceiver.h +++ b/include/gui/DisplayEventReceiver.h @@ -95,6 +95,8 @@ public:       * should be destroyed and getEvents() shouldn't be called again.       */      ssize_t getEvents(Event* events, size_t count); +    static ssize_t getEvents(const sp<BitTube>& dataChannel, +            Event* events, size_t count);      /*       * setVsyncRate() sets the Event::VSync delivery rate. A value of diff --git a/libs/gui/DisplayEventReceiver.cpp b/libs/gui/DisplayEventReceiver.cpp index 3b3ccaaf74..6a4763d5a7 100644 --- a/libs/gui/DisplayEventReceiver.cpp +++ b/libs/gui/DisplayEventReceiver.cpp @@ -80,7 +80,13 @@ status_t DisplayEventReceiver::requestNextVsync() {  ssize_t DisplayEventReceiver::getEvents(DisplayEventReceiver::Event* events,          size_t count) { -    ssize_t size = mDataChannel->read(events, sizeof(events[0])*count); +    return DisplayEventReceiver::getEvents(mDataChannel, events, count); +} + +ssize_t DisplayEventReceiver::getEvents(const sp<BitTube>& dataChannel, +        Event* events, size_t count) +{ +    ssize_t size = dataChannel->read(events, sizeof(events[0])*count);      ALOGE_IF(size<0,              "DisplayEventReceiver::getEvents error (%s)",              strerror(-size)); diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk index fc211e56b9..8b4c0744b7 100644 --- a/services/surfaceflinger/Android.mk +++ b/services/surfaceflinger/Android.mk @@ -32,7 +32,6 @@ ifeq ($(TARGET_BOARD_PLATFORM), omap3)  endif  ifeq ($(TARGET_BOARD_PLATFORM), omap4)  	LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY -	LOCAL_CFLAGS += -DUSE_TRIPLE_BUFFERING=1  endif  ifeq ($(TARGET_BOARD_PLATFORM), s5pc110)  	LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY -DNEVER_DEFAULT_TO_ASYNC_MODE diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 9c04d59720..64f72d5c87 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -55,6 +55,7 @@ Layer::Layer(SurfaceFlinger* flinger,          mCurrentTransform(0),          mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),          mCurrentOpacity(true), +        mRefreshPending(0),          mFrameLatencyNeeded(false),          mFrameLatencyOffset(0),          mFormat(PIXEL_FORMAT_NONE), @@ -97,12 +98,7 @@ void Layer::onFirstRef()      mSurfaceTexture = new SurfaceTextureLayer(mTextureName, this);      mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));      mSurfaceTexture->setSynchronousMode(true); -#ifdef USE_TRIPLE_BUFFERING -#warning "using triple buffering" -    mSurfaceTexture->setBufferCountServer(3); -#else      mSurfaceTexture->setBufferCountServer(2); -#endif  }  Layer::~Layer() @@ -113,7 +109,7 @@ Layer::~Layer()  void Layer::onFrameQueued() {      android_atomic_inc(&mQueuedFrames); -    mFlinger->signalEvent(); +    mFlinger->signalLayerUpdate();  }  // called with SurfaceFlinger::mStateLock as soon as the layer is entered @@ -407,16 +403,37 @@ bool Layer::isCropped() const {  // pageflip handling...  // ---------------------------------------------------------------------------- +bool Layer::onPreComposition() +{ +    // if there was more than one pending update, request a refresh +    if (mRefreshPending >= 2) { +        mRefreshPending = 0; +        return true; +    } +    mRefreshPending = 0; +    return false; +} +  void Layer::lockPageFlip(bool& recomputeVisibleRegions)  {      if (mQueuedFrames > 0) { + +        // if we've already called updateTexImage() without going through +        // a composition step, we have to skip this layer at this point +        // because we cannot call updateTeximage() without a corresponding +        // compositionComplete() call. +        // we'll trigger an update in onPreComposition(). +        if (mRefreshPending++) { +            return; +        } +          // Capture the old state of the layer for comparisons later          const bool oldOpacity = isOpaque();          sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;          // signal another event if we have more frames pending          if (android_atomic_dec(&mQueuedFrames) > 1) { -            mFlinger->signalEvent(); +            mFlinger->signalLayerUpdate();          }          if (mSurfaceTexture->updateTexImage() < NO_ERROR) { @@ -519,6 +536,10 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)  void Layer::unlockPageFlip(          const Transform& planeTransform, Region& outDirtyRegion)  { +    if (mRefreshPending >= 2) { +        return; +    } +      Region dirtyRegion(mPostedDirtyRegion);      if (!dirtyRegion.isEmpty()) {          mPostedDirtyRegion.clear(); @@ -552,9 +573,9 @@ void Layer::dump(String8& result, char* buffer, size_t SIZE) const      snprintf(buffer, SIZE,              "      "              "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X]," -            " transform-hint=0x%02x, queued-frames=%d\n", +            " transform-hint=0x%02x, queued-frames=%d, mRefreshPending=%d\n",              mFormat, w0, h0, s0,f0, -            getTransformHint(), mQueuedFrames); +            getTransformHint(), mQueuedFrames, mRefreshPending);      result.append(buffer); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 2dd4da130d..bf30608c97 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -80,6 +80,7 @@ public:      virtual wp<IBinder> getSurfaceTextureBinder() const;      virtual void onLayerDisplayed(); +    virtual bool onPreComposition();      // only for debugging      inline const sp<GraphicBuffer>& getActiveBuffer() const { return mActiveBuffer; } @@ -115,14 +116,17 @@ private:      uint32_t mCurrentTransform;      uint32_t mCurrentScalingMode;      bool mCurrentOpacity; +    size_t mRefreshPending;      bool mFrameLatencyNeeded;      int mFrameLatencyOffset; +      struct Statistics {          Statistics() : timestamp(0), set(0), vsync(0) { }          nsecs_t timestamp;  // buffer timestamp          nsecs_t set;        // buffer displayed timestamp          nsecs_t vsync;      // vsync immediately before set      }; +      // protected by mLock      Statistics mFrameStats[128]; diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp index d32fcdd625..44aafdf8c8 100644 --- a/services/surfaceflinger/LayerBase.cpp +++ b/services/surfaceflinger/LayerBase.cpp @@ -47,8 +47,7 @@ LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display)        mOrientation(0),        mPlaneOrientation(0),        mTransactionFlags(0), -      mPremultipliedAlpha(true), mName("unnamed"), mDebug(false), -      mInvalidate(0) +      mPremultipliedAlpha(true), mName("unnamed"), mDebug(false)  {      const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware());      mFlags = hw.getFlags(); @@ -262,23 +261,11 @@ void LayerBase::validateVisibility(const Transform& planeTransform)      mTransformedBounds = tr.makeBounds(w, h);  } -void LayerBase::lockPageFlip(bool& recomputeVisibleRegions) -{ +void LayerBase::lockPageFlip(bool& recomputeVisibleRegions) {  }  void LayerBase::unlockPageFlip( -        const Transform& planeTransform, Region& outDirtyRegion) -{ -    if ((android_atomic_and(~1, &mInvalidate)&1) == 1) { -        outDirtyRegion.orSelf(visibleRegionScreen); -    } -} - -void LayerBase::invalidate() -{ -    if ((android_atomic_or(1, &mInvalidate)&1) == 0) { -        mFlinger->signalEvent(); -    } +        const Transform& planeTransform, Region& outDirtyRegion) {  }  void LayerBase::drawRegion(const Region& reg) const diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h index 6b62c9db78..b8f7680b2b 100644 --- a/services/surfaceflinger/LayerBase.h +++ b/services/surfaceflinger/LayerBase.h @@ -103,8 +103,6 @@ public:              Rect visibleBounds() const;              void drawRegion(const Region& reg) const; -            void invalidate(); -      virtual sp<LayerBaseClient> getLayerBaseClient() const { return 0; }      virtual sp<Layer> getLayer() const { return 0; } @@ -204,9 +202,16 @@ public:      /** called with the state lock when the surface is removed from the       *  current list */ -    virtual void onRemoved() { }; +    virtual void onRemoved() { } -    virtual void onLayerDisplayed() { }; +    /** called after page-flip +     */ +    virtual void onLayerDisplayed() { } + +    /** called before composition. +     * returns true if the layer has pending updates. +     */ +    virtual bool onPreComposition() { return false; }      /** always call base class first */      virtual void dump(String8& result, char* scratch, size_t size) const; @@ -275,10 +280,6 @@ protected:      mutable     bool            mDebug; -                // atomic -    volatile    int32_t         mInvalidate; -                 -  public:      // called from class SurfaceFlinger      virtual ~LayerBase(); diff --git a/services/surfaceflinger/MessageQueue.cpp b/services/surfaceflinger/MessageQueue.cpp index 70711e73ee..1ff3567f4d 100644 --- a/services/surfaceflinger/MessageQueue.cpp +++ b/services/surfaceflinger/MessageQueue.cpp @@ -29,6 +29,7 @@  #include "MessageQueue.h"  #include "EventThread.h" +#include "SurfaceFlinger.h"  namespace android { @@ -48,14 +49,47 @@ void MessageBase::handleMessage(const Message&) {  // --------------------------------------------------------------------------- +void MessageQueue::Handler::signalRefresh() { +    if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) { +        mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH)); +    } +} + +void MessageQueue::Handler::signalInvalidate() { +    if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) { +        mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE)); +    } +} + +void MessageQueue::Handler::handleMessage(const Message& message) { +    switch (message.what) { +        case INVALIDATE: +            android_atomic_and(~eventMaskInvalidate, &mEventMask); +            mQueue.mFlinger->onMessageReceived(message.what); +            break; +        case REFRESH: +            android_atomic_and(~eventMaskRefresh, &mEventMask); +            mQueue.mFlinger->onMessageReceived(message.what); +            break; +    } +} + +// --------------------------------------------------------------------------- +  MessageQueue::MessageQueue() -    : mLooper(new Looper(true)), mWorkPending(0)  {  }  MessageQueue::~MessageQueue() {  } +void MessageQueue::init(const sp<SurfaceFlinger>& flinger) +{ +    mFlinger = flinger; +    mLooper = new Looper(true); +    mHandler = new Handler(*this); +} +  void MessageQueue::setEventThread(const sp<EventThread>& eventThread)  {      mEventThread = eventThread; @@ -68,25 +102,16 @@ void MessageQueue::setEventThread(const sp<EventThread>& eventThread)  void MessageQueue::waitMessage() {      do {          IPCThreadState::self()->flushCommands(); -          int32_t ret = mLooper->pollOnce(-1);          switch (ret) {              case ALOOPER_POLL_WAKE:              case ALOOPER_POLL_CALLBACK: -                // callback and/or wake -                if (android_atomic_and(0, &mWorkPending)) { -                    return; -                }                  continue; - -            case ALOOPER_POLL_TIMEOUT: -                // timeout (should not happen) -                continue; -              case ALOOPER_POLL_ERROR:                  ALOGE("ALOOPER_POLL_ERROR"); +            case ALOOPER_POLL_TIMEOUT: +                // timeout (should not happen)                  continue; -              default:                  // should not happen                  ALOGE("Looper::pollOnce() returned unknown status %d", ret); @@ -107,15 +132,12 @@ status_t MessageQueue::postMessage(      return NO_ERROR;  } -void MessageQueue::scheduleWorkASAP() { -    if (android_atomic_or(1, &mWorkPending) == 0) { -        mLooper->wake(); -   } +void MessageQueue::invalidate() { +    mHandler->signalInvalidate();  } -status_t MessageQueue::invalidate() { +void MessageQueue::refresh() {      mEvents->requestNextVsync(); -    return NO_ERROR;  }  int MessageQueue::cb_eventReceiver(int fd, int events, void* data) { @@ -126,10 +148,10 @@ int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {  int MessageQueue::eventReceiver(int fd, int events) {      ssize_t n;      DisplayEventReceiver::Event buffer[8]; -    while ((n = getEvents(buffer, 8)) > 0) { +    while ((n = DisplayEventReceiver::getEvents(mEventTube, buffer, 8)) > 0) {          for (int i=0 ; i<n ; i++) {              if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) { -                scheduleWorkASAP(); +                mHandler->signalRefresh();                  break;              }          } @@ -137,24 +159,6 @@ int MessageQueue::eventReceiver(int fd, int events) {      return 1;  } -ssize_t MessageQueue::getEvents( -        DisplayEventReceiver::Event* events, size_t count) -{ -    ssize_t size = mEventTube->read(events, sizeof(events[0])*count); -    ALOGE_IF(size<0, "MessageQueue::getEvents error (%s)", strerror(-size)); -    if (size >= 0) { -        // Note: if (size % sizeof(events[0])) != 0, we've got a -        // partial read. This can happen if the queue filed up (ie: if we -        // didn't pull from it fast enough). -        // We discard the partial event and rely on the sender to -        // re-send the event if appropriate (some events, like VSYNC -        // can be lost forever). -        // returns number of events read -        size /= sizeof(events[0]); -    } -    return size; -} -  // ---------------------------------------------------------------------------  }; // namespace android diff --git a/services/surfaceflinger/MessageQueue.h b/services/surfaceflinger/MessageQueue.h index 5ea197dc70..ea29e7ef72 100644 --- a/services/surfaceflinger/MessageQueue.h +++ b/services/surfaceflinger/MessageQueue.h @@ -33,6 +33,7 @@ namespace android {  class IDisplayEventConnection;  class EventThread; +class SurfaceFlinger;  // --------------------------------------------------------------------------- @@ -59,25 +60,48 @@ private:  // ---------------------------------------------------------------------------  class MessageQueue { +    class Handler : public MessageHandler { +        enum { +            eventMaskInvalidate = 0x1, +            eventMaskRefresh    = 0x2 +        }; +        MessageQueue& mQueue; +        int32_t mEventMask; +    public: +        Handler(MessageQueue& queue) : mQueue(queue), mEventMask(0) { } +        virtual void handleMessage(const Message& message); +        void signalRefresh(); +        void signalInvalidate(); +    }; + +    friend class Handler; + +    sp<SurfaceFlinger> mFlinger;      sp<Looper> mLooper;      sp<EventThread> mEventThread;      sp<IDisplayEventConnection> mEvents;      sp<BitTube> mEventTube; -    int32_t mWorkPending; +    sp<Handler> mHandler; +      static int cb_eventReceiver(int fd, int events, void* data);      int eventReceiver(int fd, int events); -    ssize_t getEvents(DisplayEventReceiver::Event* events, size_t count); -    void scheduleWorkASAP();  public: +    enum { +        INVALIDATE = 0, +        REFRESH    = 1, +    }; +      MessageQueue();      ~MessageQueue(); +    void init(const sp<SurfaceFlinger>& flinger);      void setEventThread(const sp<EventThread>& events);      void waitMessage();      status_t postMessage(const sp<MessageBase>& message, nsecs_t reltime=0); -    status_t invalidate(); +    void invalidate(); +    void refresh();  };  // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index ff70ec327e..870235bffa 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -125,11 +125,34 @@ void SurfaceFlinger::init()      ALOGI_IF(mDebugDDMS,         "DDMS debugging enabled");  } +void SurfaceFlinger::onFirstRef() +{ +    mEventQueue.init(this); + +    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY); + +    // Wait for the main thread to be done with its initialization +    mReadyToRunBarrier.wait(); +} + +  SurfaceFlinger::~SurfaceFlinger()  {      glDeleteTextures(1, &mWormholeTexName);  } +void SurfaceFlinger::binderDied(const wp<IBinder>& who) +{ +    // the window manager died on us. prepare its eulogy. + +    // reset screen orientation +    Vector<ComposerState> state; +    setTransactionState(state, eOrientationDefault, 0); + +    // restart the boot-animation +    property_set("ctl.start", "bootanim"); +} +  sp<IMemoryHeap> SurfaceFlinger::getCblk() const  {      return mServerHeap; @@ -183,26 +206,6 @@ void SurfaceFlinger::bootFinished()      property_set("ctl.stop", "bootanim");  } -void SurfaceFlinger::binderDied(const wp<IBinder>& who) -{ -    // the window manager died on us. prepare its eulogy. - -    // reset screen orientation -    Vector<ComposerState> state; -    setTransactionState(state, eOrientationDefault, 0); - -    // restart the boot-animation -    property_set("ctl.start", "bootanim"); -} - -void SurfaceFlinger::onFirstRef() -{ -    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY); - -    // Wait for the main thread to be done with its initialization -    mReadyToRunBarrier.wait(); -} -  static inline uint16_t pack565(int r, int g, int b) {      return (r<<11)|(g<<5)|b;  } @@ -311,34 +314,6 @@ status_t SurfaceFlinger::readyToRun()  }  // ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#pragma mark Events Handler -#endif - -void SurfaceFlinger::waitForEvent() { -    mEventQueue.waitMessage(); -} - -void SurfaceFlinger::signalEvent() { -    mEventQueue.invalidate(); -} - -status_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, -        nsecs_t reltime, uint32_t flags) { -    return mEventQueue.postMessage(msg, reltime); -} - -status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, -        nsecs_t reltime, uint32_t flags) { -    status_t res = mEventQueue.postMessage(msg, reltime); -    if (res == NO_ERROR) { -        msg->wait(); -    } -    return res; -} - -// ----------------------------------------------------------------------------  bool SurfaceFlinger::authenticateSurfaceTexture(          const sp<ISurfaceTexture>& surfaceTexture) const { @@ -388,52 +363,91 @@ sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {  }  // ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#pragma mark Main loop -#endif + +void SurfaceFlinger::waitForEvent() { +    mEventQueue.waitMessage(); +} + +void SurfaceFlinger::signalTransaction() { +    mEventQueue.invalidate(); +} + +void SurfaceFlinger::signalLayerUpdate() { +    mEventQueue.invalidate(); +} + +void SurfaceFlinger::signalRefresh() { +    mEventQueue.refresh(); +} + +status_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, +        nsecs_t reltime, uint32_t flags) { +    return mEventQueue.postMessage(msg, reltime); +} + +status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, +        nsecs_t reltime, uint32_t flags) { +    status_t res = mEventQueue.postMessage(msg, reltime); +    if (res == NO_ERROR) { +        msg->wait(); +    } +    return res; +}  bool SurfaceFlinger::threadLoop()  {      waitForEvent(); +    return true; +} -    // check for transactions -    if (CC_UNLIKELY(mConsoleSignals)) { -        handleConsoleEvents(); -    } +void SurfaceFlinger::onMessageReceived(int32_t what) +{ +    switch (what) { +        case MessageQueue::INVALIDATE: { +            // check for transactions +            if (CC_UNLIKELY(mConsoleSignals)) { +                handleConsoleEvents(); +            } -    // if we're in a global transaction, don't do anything. -    const uint32_t mask = eTransactionNeeded | eTraversalNeeded; -    uint32_t transactionFlags = peekTransactionFlags(mask); -    if (CC_UNLIKELY(transactionFlags)) { -        handleTransaction(transactionFlags); -    } +            // if we're in a global transaction, don't do anything. +            const uint32_t mask = eTransactionNeeded | eTraversalNeeded; +            uint32_t transactionFlags = peekTransactionFlags(mask); +            if (CC_UNLIKELY(transactionFlags)) { +                handleTransaction(transactionFlags); +            } -    // post surfaces (if needed) -    handlePageFlip(); +            // post surfaces (if needed) +            handlePageFlip(); -    if (mDirtyRegion.isEmpty()) { -        // nothing new to do. -        return true; -    } +            if (!mDirtyRegion.isEmpty()) { +                signalRefresh(); +            } +        } break; -    if (CC_UNLIKELY(mHwWorkListDirty)) { -        // build the h/w work list -        handleWorkList(); -    } +        case MessageQueue::REFRESH: { +            if (!mDirtyRegion.isEmpty()) { +                // NOTE: it is mandatory to call hw.compositionComplete() +                // after handleRefresh() +                handleRefresh(); -    const DisplayHardware& hw(graphicPlane(0).displayHardware()); -    if (CC_LIKELY(hw.canDraw())) { -        // repaint the framebuffer (if needed) -        handleRepaint(); -        // inform the h/w that we're done compositing -        hw.compositionComplete(); -        postFramebuffer(); -    } else { -        // pretend we did the post -        hw.compositionComplete(); +                const DisplayHardware& hw(graphicPlane(0).displayHardware()); +                if (CC_UNLIKELY(mHwWorkListDirty)) { +                    // build the h/w work list +                    handleWorkList(); +                } +                if (CC_LIKELY(hw.canDraw())) { +                    // repaint the framebuffer (if needed) +                    handleRepaint(); +                    // inform the h/w that we're done compositing +                    hw.compositionComplete(); +                    postFramebuffer(); +                } else { +                    // pretend we did the post +                    hw.compositionComplete(); +                } +            } +        } break;      } -    return true;  }  void SurfaceFlinger::postFramebuffer() @@ -717,13 +731,13 @@ void SurfaceFlinger::commitTransaction()  void SurfaceFlinger::handlePageFlip()  { -    bool visibleRegions = mVisibleRegionsDirty; +    const DisplayHardware& hw = graphicPlane(0).displayHardware(); +    const Region screenRegion(hw.bounds()); +      const LayerVector& currentLayers(mDrawingState.layersSortedByZ); -    visibleRegions |= lockPageFlip(currentLayers); +    const bool visibleRegions = lockPageFlip(currentLayers); -        const DisplayHardware& hw = graphicPlane(0).displayHardware(); -        const Region screenRegion(hw.bounds()); -        if (visibleRegions) { +        if (visibleRegions || mVisibleRegionsDirty) {              Region opaqueRegion;              computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion); @@ -770,7 +784,7 @@ void SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)  {      const GraphicPlane& plane(graphicPlane(0));      const Transform& planeTransform(plane.transform()); -    size_t count = currentLayers.size(); +    const size_t count = currentLayers.size();      sp<LayerBase> const* layers = currentLayers.array();      for (size_t i=0 ; i<count ; i++) {          const sp<LayerBase>& layer(layers[i]); @@ -778,6 +792,23 @@ void SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)      }  } +void SurfaceFlinger::handleRefresh() +{ +    bool needInvalidate = false; +    const LayerVector& currentLayers(mDrawingState.layersSortedByZ); +    const size_t count = currentLayers.size(); +    for (size_t i=0 ; i<count ; i++) { +        const sp<LayerBase>& layer(currentLayers[i]); +        if (layer->onPreComposition()) { +            needInvalidate = true; +        } +    } +    if (needInvalidate) { +        signalLayerUpdate(); +    } +} + +  void SurfaceFlinger::handleWorkList()  {      mHwWorkListDirty = false; @@ -1175,7 +1206,7 @@ uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)  {      uint32_t old = android_atomic_or(flags, &mTransactionFlags);      if ((old & flags)==0) { // wake the server up -        signalEvent(); +        signalTransaction();      }      return old;  } @@ -1426,14 +1457,14 @@ void SurfaceFlinger::screenReleased(int dpy)  {      // this may be called by a signal handler, we can't do too much in here      android_atomic_or(eConsoleReleased, &mConsoleSignals); -    signalEvent(); +    signalTransaction();  }  void SurfaceFlinger::screenAcquired(int dpy)  {      // this may be called by a signal handler, we can't do too much in here      android_atomic_or(eConsoleAcquired, &mConsoleSignals); -    signalEvent(); +    signalTransaction();  }  status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) @@ -1769,7 +1800,7 @@ void SurfaceFlinger::repaintEverything() {      const DisplayHardware& hw(graphicPlane(0).displayHardware());      const Rect bounds(hw.getBounds());      setInvalidateRegion(Region(bounds)); -    signalEvent(); +    signalTransaction();  }  void SurfaceFlinger::setInvalidateRegion(const Region& reg) { @@ -2245,7 +2276,7 @@ status_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode)      // make sure to redraw the whole screen when the animation is done      mDirtyRegion.set(hw.bounds()); -    signalEvent(); +    signalTransaction();      return NO_ERROR;  } diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index c24a9de45a..fcd93615ff 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -190,6 +190,8 @@ public:              status_t renderScreenToTextureLocked(DisplayID dpy,                      GLuint* textureName, GLfloat* uOut, GLfloat* vOut); +            void onMessageReceived(int32_t what); +              status_t postMessageAsync(const sp<MessageBase>& msg,                      nsecs_t reltime=0, uint32_t flags = 0); @@ -283,7 +285,10 @@ private:  public:     // hack to work around gcc 4.0.3 bug      const GraphicPlane&     graphicPlane(int dpy) const;            GraphicPlane&     graphicPlane(int dpy); -          void              signalEvent(); + +          void              signalTransaction(); +          void              signalLayerUpdate(); +          void              signalRefresh();            void              repaintEverything();  private: @@ -300,6 +305,7 @@ private:              void        handlePageFlip();              bool        lockPageFlip(const LayerVector& currentLayers);              void        unlockPageFlip(const LayerVector& currentLayers); +            void        handleRefresh();              void        handleWorkList();              void        handleRepaint();              void        postFramebuffer(); |