Loading services/surfaceflinger/Layer.cpp +31 −1 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ #include <ui/GraphicBuffer.h> #include <ui/PixelFormat.h> #include <gui/BufferItem.h> #include <gui/Surface.h> #include "clz.h" Loading Loading @@ -158,11 +159,26 @@ void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */, } } void Layer::onFrameAvailable(const BufferItem& /* item */) { void Layer::onFrameAvailable(const BufferItem& item) { // Add this buffer from our internal queue tracker { // Autolock scope Mutex::Autolock lock(mQueueItemLock); mQueueItems.push_back(item); } android_atomic_inc(&mQueuedFrames); mFlinger->signalLayerUpdate(); } void Layer::onFrameReplaced(const BufferItem& item) { Mutex::Autolock lock(mQueueItemLock); if (mQueueItems.empty()) { ALOGE("Can't replace a frame on an empty queue"); return; } mQueueItems.editItemAt(0) = item; } void Layer::onSidebandStreamChanged() { if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) { // mSidebandStreamChanged was false Loading Loading @@ -1012,6 +1028,14 @@ bool Layer::setLayerStack(uint32_t layerStack) { // pageflip handling... // ---------------------------------------------------------------------------- bool Layer::shouldPresentNow(const DispSync& dispSync) const { Mutex::Autolock lock(mQueueItemLock); nsecs_t expectedPresent = mSurfaceFlingerConsumer->computeExpectedPresent(dispSync); return mQueueItems.empty() ? false : mQueueItems[0].mTimestamp < expectedPresent; } bool Layer::onPreComposition() { mRefreshPending = false; return mQueuedFrames > 0 || mSidebandStreamChanged; Loading Loading @@ -1201,6 +1225,12 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) return outDirtyRegion; } // Remove this buffer from our internal queue tracker { // Autolock scope Mutex::Autolock lock(mQueueItemLock); mQueueItems.removeAt(0); } // Decrement the queued-frames count. Signal another event if we // have more frames pending. if (android_atomic_dec(&mQueuedFrames) > 1) { Loading services/surfaceflinger/Layer.h +7 −0 Original line number Diff line number Diff line Loading @@ -210,6 +210,8 @@ public: void onLayerDisplayed(const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface* layer); bool shouldPresentNow(const DispSync& dispSync) const; /* * called before composition. * returns true if the layer has pending updates. Loading Loading @@ -331,6 +333,7 @@ protected: private: // Interface implementation for SurfaceFlingerConsumer::ContentsChangedListener virtual void onFrameAvailable(const BufferItem& item); virtual void onFrameReplaced(const BufferItem& item); virtual void onSidebandStreamChanged(); void commitTransaction(); Loading Loading @@ -403,6 +406,10 @@ private: // This layer can be a cursor on some displays. bool mPotentialCursor; // Local copy of the queued contents of the incoming BufferQueue mutable Mutex mQueueItemLock; Vector<BufferItem> mQueueItems; }; // --------------------------------------------------------------------------- Loading services/surfaceflinger/SurfaceFlinger.cpp +41 −17 Original line number Diff line number Diff line Loading @@ -828,30 +828,39 @@ void SurfaceFlinger::eventControl(int disp, int event, int enabled) { void SurfaceFlinger::onMessageReceived(int32_t what) { ATRACE_CALL(); switch (what) { case MessageQueue::TRANSACTION: case MessageQueue::TRANSACTION: { handleMessageTransaction(); break; case MessageQueue::INVALIDATE: handleMessageTransaction(); handleMessageInvalidate(); } case MessageQueue::INVALIDATE: { bool refreshNeeded = handleMessageTransaction(); refreshNeeded |= handleMessageInvalidate(); if (refreshNeeded) { // Signal a refresh if a transaction modified the window state or if // a new buffer was latched signalRefresh(); } break; case MessageQueue::REFRESH: } case MessageQueue::REFRESH: { handleMessageRefresh(); break; } } } void SurfaceFlinger::handleMessageTransaction() { bool SurfaceFlinger::handleMessageTransaction() { uint32_t transactionFlags = peekTransactionFlags(eTransactionMask); if (transactionFlags) { handleTransaction(transactionFlags); return true; } return false; } void SurfaceFlinger::handleMessageInvalidate() { bool SurfaceFlinger::handleMessageInvalidate() { ATRACE_CALL(); handlePageFlip(); return handlePageFlip(); } void SurfaceFlinger::handleMessageRefresh() { Loading Loading @@ -1686,12 +1695,13 @@ void SurfaceFlinger::invalidateLayerStack(uint32_t layerStack, } } void SurfaceFlinger::handlePageFlip() bool SurfaceFlinger::handlePageFlip() { Region dirtyRegion; bool visibleRegions = false; const LayerVector& layers(mDrawingState.layersSortedByZ); bool frameQueued = false; // Store the set of layers that need updates. This set must not change as // buffers are being latched, as this could result in a deadlock. Loading @@ -1705,9 +1715,13 @@ void SurfaceFlinger::handlePageFlip() Vector<Layer*> layersWithQueuedFrames; for (size_t i = 0, count = layers.size(); i<count ; i++) { const sp<Layer>& layer(layers[i]); if (layer->hasQueuedFrame()) if (layer->hasQueuedFrame()) { frameQueued = true; if (layer->shouldPresentNow(mPrimaryDispSync)) { layersWithQueuedFrames.push_back(layer.get()); } } } for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) { Layer* layer = layersWithQueuedFrames[i]; const Region dirty(layer->latchBuffer(visibleRegions)); Loading @@ -1716,6 +1730,16 @@ void SurfaceFlinger::handlePageFlip() } mVisibleRegionsDirty |= visibleRegions; // If we will need to wake up at some time in the future to deal with a // queued frame that shouldn't be displayed during this vsync period, wake // up during the next vsync period to check again. if (frameQueued && layersWithQueuedFrames.empty()) { signalLayerUpdate(); } // Only continue with the refresh if there is actually new work to do return !layersWithQueuedFrames.empty(); } void SurfaceFlinger::invalidateHwcGeometry() Loading services/surfaceflinger/SurfaceFlinger.h +10 −5 Original line number Diff line number Diff line Loading @@ -247,8 +247,12 @@ private: // called on the main thread in response to setPowerMode() void setPowerModeInternal(const sp<DisplayDevice>& hw, int mode); void handleMessageTransaction(); void handleMessageInvalidate(); // Returns whether the transaction actually modified any state bool handleMessageTransaction(); // Returns whether a new buffer has been latched (see handlePageFlip()) bool handleMessageInvalidate(); void handleMessageRefresh(); void handleTransaction(uint32_t transactionFlags); Loading @@ -256,10 +260,11 @@ private: void updateCursorAsync(); /* handlePageFilp: this is were we latch a new buffer * if available and compute the dirty region. /* handlePageFlip - latch a new buffer if available and compute the dirty * region. Returns whether a new buffer has been latched, i.e., whether it * is necessary to perform a refresh during this vsync. */ void handlePageFlip(); bool handlePageFlip(); /* ------------------------------------------------------------------------ * Transactions Loading services/surfaceflinger/SurfaceFlingerConsumer.h +1 −1 Original line number Diff line number Diff line Loading @@ -67,9 +67,9 @@ public: sp<NativeHandle> getSidebandStream() const; private: nsecs_t computeExpectedPresent(const DispSync& dispSync); private: virtual void onSidebandStreamChanged(); wp<ContentsChangedListener> mContentsChangedListener; Loading Loading
services/surfaceflinger/Layer.cpp +31 −1 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ #include <ui/GraphicBuffer.h> #include <ui/PixelFormat.h> #include <gui/BufferItem.h> #include <gui/Surface.h> #include "clz.h" Loading Loading @@ -158,11 +159,26 @@ void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */, } } void Layer::onFrameAvailable(const BufferItem& /* item */) { void Layer::onFrameAvailable(const BufferItem& item) { // Add this buffer from our internal queue tracker { // Autolock scope Mutex::Autolock lock(mQueueItemLock); mQueueItems.push_back(item); } android_atomic_inc(&mQueuedFrames); mFlinger->signalLayerUpdate(); } void Layer::onFrameReplaced(const BufferItem& item) { Mutex::Autolock lock(mQueueItemLock); if (mQueueItems.empty()) { ALOGE("Can't replace a frame on an empty queue"); return; } mQueueItems.editItemAt(0) = item; } void Layer::onSidebandStreamChanged() { if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) { // mSidebandStreamChanged was false Loading Loading @@ -1012,6 +1028,14 @@ bool Layer::setLayerStack(uint32_t layerStack) { // pageflip handling... // ---------------------------------------------------------------------------- bool Layer::shouldPresentNow(const DispSync& dispSync) const { Mutex::Autolock lock(mQueueItemLock); nsecs_t expectedPresent = mSurfaceFlingerConsumer->computeExpectedPresent(dispSync); return mQueueItems.empty() ? false : mQueueItems[0].mTimestamp < expectedPresent; } bool Layer::onPreComposition() { mRefreshPending = false; return mQueuedFrames > 0 || mSidebandStreamChanged; Loading Loading @@ -1201,6 +1225,12 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) return outDirtyRegion; } // Remove this buffer from our internal queue tracker { // Autolock scope Mutex::Autolock lock(mQueueItemLock); mQueueItems.removeAt(0); } // Decrement the queued-frames count. Signal another event if we // have more frames pending. if (android_atomic_dec(&mQueuedFrames) > 1) { Loading
services/surfaceflinger/Layer.h +7 −0 Original line number Diff line number Diff line Loading @@ -210,6 +210,8 @@ public: void onLayerDisplayed(const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface* layer); bool shouldPresentNow(const DispSync& dispSync) const; /* * called before composition. * returns true if the layer has pending updates. Loading Loading @@ -331,6 +333,7 @@ protected: private: // Interface implementation for SurfaceFlingerConsumer::ContentsChangedListener virtual void onFrameAvailable(const BufferItem& item); virtual void onFrameReplaced(const BufferItem& item); virtual void onSidebandStreamChanged(); void commitTransaction(); Loading Loading @@ -403,6 +406,10 @@ private: // This layer can be a cursor on some displays. bool mPotentialCursor; // Local copy of the queued contents of the incoming BufferQueue mutable Mutex mQueueItemLock; Vector<BufferItem> mQueueItems; }; // --------------------------------------------------------------------------- Loading
services/surfaceflinger/SurfaceFlinger.cpp +41 −17 Original line number Diff line number Diff line Loading @@ -828,30 +828,39 @@ void SurfaceFlinger::eventControl(int disp, int event, int enabled) { void SurfaceFlinger::onMessageReceived(int32_t what) { ATRACE_CALL(); switch (what) { case MessageQueue::TRANSACTION: case MessageQueue::TRANSACTION: { handleMessageTransaction(); break; case MessageQueue::INVALIDATE: handleMessageTransaction(); handleMessageInvalidate(); } case MessageQueue::INVALIDATE: { bool refreshNeeded = handleMessageTransaction(); refreshNeeded |= handleMessageInvalidate(); if (refreshNeeded) { // Signal a refresh if a transaction modified the window state or if // a new buffer was latched signalRefresh(); } break; case MessageQueue::REFRESH: } case MessageQueue::REFRESH: { handleMessageRefresh(); break; } } } void SurfaceFlinger::handleMessageTransaction() { bool SurfaceFlinger::handleMessageTransaction() { uint32_t transactionFlags = peekTransactionFlags(eTransactionMask); if (transactionFlags) { handleTransaction(transactionFlags); return true; } return false; } void SurfaceFlinger::handleMessageInvalidate() { bool SurfaceFlinger::handleMessageInvalidate() { ATRACE_CALL(); handlePageFlip(); return handlePageFlip(); } void SurfaceFlinger::handleMessageRefresh() { Loading Loading @@ -1686,12 +1695,13 @@ void SurfaceFlinger::invalidateLayerStack(uint32_t layerStack, } } void SurfaceFlinger::handlePageFlip() bool SurfaceFlinger::handlePageFlip() { Region dirtyRegion; bool visibleRegions = false; const LayerVector& layers(mDrawingState.layersSortedByZ); bool frameQueued = false; // Store the set of layers that need updates. This set must not change as // buffers are being latched, as this could result in a deadlock. Loading @@ -1705,9 +1715,13 @@ void SurfaceFlinger::handlePageFlip() Vector<Layer*> layersWithQueuedFrames; for (size_t i = 0, count = layers.size(); i<count ; i++) { const sp<Layer>& layer(layers[i]); if (layer->hasQueuedFrame()) if (layer->hasQueuedFrame()) { frameQueued = true; if (layer->shouldPresentNow(mPrimaryDispSync)) { layersWithQueuedFrames.push_back(layer.get()); } } } for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) { Layer* layer = layersWithQueuedFrames[i]; const Region dirty(layer->latchBuffer(visibleRegions)); Loading @@ -1716,6 +1730,16 @@ void SurfaceFlinger::handlePageFlip() } mVisibleRegionsDirty |= visibleRegions; // If we will need to wake up at some time in the future to deal with a // queued frame that shouldn't be displayed during this vsync period, wake // up during the next vsync period to check again. if (frameQueued && layersWithQueuedFrames.empty()) { signalLayerUpdate(); } // Only continue with the refresh if there is actually new work to do return !layersWithQueuedFrames.empty(); } void SurfaceFlinger::invalidateHwcGeometry() Loading
services/surfaceflinger/SurfaceFlinger.h +10 −5 Original line number Diff line number Diff line Loading @@ -247,8 +247,12 @@ private: // called on the main thread in response to setPowerMode() void setPowerModeInternal(const sp<DisplayDevice>& hw, int mode); void handleMessageTransaction(); void handleMessageInvalidate(); // Returns whether the transaction actually modified any state bool handleMessageTransaction(); // Returns whether a new buffer has been latched (see handlePageFlip()) bool handleMessageInvalidate(); void handleMessageRefresh(); void handleTransaction(uint32_t transactionFlags); Loading @@ -256,10 +260,11 @@ private: void updateCursorAsync(); /* handlePageFilp: this is were we latch a new buffer * if available and compute the dirty region. /* handlePageFlip - latch a new buffer if available and compute the dirty * region. Returns whether a new buffer has been latched, i.e., whether it * is necessary to perform a refresh during this vsync. */ void handlePageFlip(); bool handlePageFlip(); /* ------------------------------------------------------------------------ * Transactions Loading
services/surfaceflinger/SurfaceFlingerConsumer.h +1 −1 Original line number Diff line number Diff line Loading @@ -67,9 +67,9 @@ public: sp<NativeHandle> getSidebandStream() const; private: nsecs_t computeExpectedPresent(const DispSync& dispSync); private: virtual void onSidebandStreamChanged(); wp<ContentsChangedListener> mContentsChangedListener; Loading