diff --git a/include/gui/DisplayEventReceiver.h b/include/gui/DisplayEventReceiver.h index a28137785..7bca8d6ea 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& 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 3b3ccaaf7..6a4763d5a 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& 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 fc211e56b..8b4c0744b 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 9c04d5972..64f72d5c8 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 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 2dd4da130..bf30608c9 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -80,6 +80,7 @@ public: virtual wp getSurfaceTextureBinder() const; virtual void onLayerDisplayed(); + virtual bool onPreComposition(); // only for debugging inline const sp& 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 d32fcdd62..44aafdf8c 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 6b62c9db7..b8f7680b2 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 getLayerBaseClient() const { return 0; } virtual sp 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 70711e73e..1ff3567f4 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& flinger) +{ + mFlinger = flinger; + mLooper = new Looper(true); + mHandler = new Handler(*this); +} + void MessageQueue::setEventThread(const sp& eventThread) { mEventThread = eventThread; @@ -68,25 +102,16 @@ void MessageQueue::setEventThread(const sp& 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_ERROR: + ALOGE("ALOOPER_POLL_ERROR"); case ALOOPER_POLL_TIMEOUT: // timeout (should not happen) continue; - - case ALOOPER_POLL_ERROR: - ALOGE("ALOOPER_POLL_ERROR"); - 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 ; isignalRefresh(); 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 5ea197dc7..ea29e7ef7 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 mFlinger; sp mLooper; sp mEventThread; sp mEvents; sp mEventTube; - int32_t mWorkPending; + sp 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& flinger); void setEventThread(const sp& events); void waitMessage(); status_t postMessage(const sp& 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 ff70ec327..870235bff 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& who) +{ + // the window manager died on us. prepare its eulogy. + + // reset screen orientation + Vector state; + setTransactionState(state, eOrientationDefault, 0); + + // restart the boot-animation + property_set("ctl.start", "bootanim"); +} + sp SurfaceFlinger::getCblk() const { return mServerHeap; @@ -183,26 +206,6 @@ void SurfaceFlinger::bootFinished() property_set("ctl.stop", "bootanim"); } -void SurfaceFlinger::binderDied(const wp& who) -{ - // the window manager died on us. prepare its eulogy. - - // reset screen orientation - Vector 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; } @@ -310,34 +313,6 @@ status_t SurfaceFlinger::readyToRun() return NO_ERROR; } -// ---------------------------------------------------------------------------- -#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& msg, - nsecs_t reltime, uint32_t flags) { - return mEventQueue.postMessage(msg, reltime); -} - -status_t SurfaceFlinger::postMessageSync(const sp& 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( @@ -388,54 +363,93 @@ sp 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& msg, + nsecs_t reltime, uint32_t flags) { + return mEventQueue.postMessage(msg, reltime); +} + +status_t SurfaceFlinger::postMessageSync(const sp& 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(); - - // 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); - } - - // post surfaces (if needed) - handlePageFlip(); - - if (mDirtyRegion.isEmpty()) { - // nothing new to do. - return true; - } - - if (CC_UNLIKELY(mHwWorkListDirty)) { - // build the h/w work list - handleWorkList(); - } - - 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(); - } return true; } +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); + } + + // post surfaces (if needed) + handlePageFlip(); + + if (!mDirtyRegion.isEmpty()) { + signalRefresh(); + } + } break; + + 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_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; + } +} + void SurfaceFlinger::postFramebuffer() { // this should never happen. we do the flip anyways so we don't @@ -717,13 +731,13 @@ void SurfaceFlinger::commitTransaction() void SurfaceFlinger::handlePageFlip() { - bool visibleRegions = mVisibleRegionsDirty; - const LayerVector& currentLayers(mDrawingState.layersSortedByZ); - visibleRegions |= lockPageFlip(currentLayers); + const DisplayHardware& hw = graphicPlane(0).displayHardware(); + const Region screenRegion(hw.bounds()); - const DisplayHardware& hw = graphicPlane(0).displayHardware(); - const Region screenRegion(hw.bounds()); - if (visibleRegions) { + const LayerVector& currentLayers(mDrawingState.layersSortedByZ); + const bool visibleRegions = lockPageFlip(currentLayers); + + 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 const* layers = currentLayers.array(); for (size_t i=0 ; i& 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& 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& 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 c24a9de45..fcd93615f 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& 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();