diff --git a/include/gui/BufferQueue.h b/include/gui/BufferQueue.h index 721b2189e..09300a20c 100644 --- a/include/gui/BufferQueue.h +++ b/include/gui/BufferQueue.h @@ -62,9 +62,10 @@ public: public: ProxyConsumerListener(const wp& consumerListener); virtual ~ProxyConsumerListener(); - virtual void onFrameAvailable(const BufferItem& item); - virtual void onBuffersReleased(); - virtual void onSidebandStreamChanged(); + virtual void onFrameAvailable(const BufferItem& item) override; + virtual void onFrameReplaced(const BufferItem& item) override; + virtual void onBuffersReleased() override; + virtual void onSidebandStreamChanged() override; private: // mConsumerListener is a weak reference to the IConsumerListener. This is // the raison d'etre of ProxyConsumerListener. diff --git a/include/gui/ConsumerBase.h b/include/gui/ConsumerBase.h index d56fa89b5..5be3ffb8d 100644 --- a/include/gui/ConsumerBase.h +++ b/include/gui/ConsumerBase.h @@ -38,15 +38,9 @@ class ConsumerBase : public virtual RefBase, protected ConsumerListener { public: struct FrameAvailableListener : public virtual RefBase { - // onFrameAvailable() is called each time an additional frame becomes - // available for consumption. This means that frames that are queued - // while in asynchronous mode only trigger the callback if no previous - // frames are pending. Frames queued while in synchronous mode always - // trigger the callback. - // - // This is called without any lock held and can be called concurrently - // by multiple threads. + // See IConsumerListener::onFrame{Available,Replaced} virtual void onFrameAvailable(const BufferItem& item) = 0; + virtual void onFrameReplaced(const BufferItem& /* item */) {} }; virtual ~ConsumerBase(); @@ -104,14 +98,16 @@ protected: // Implementation of the IConsumerListener interface. These // calls are used to notify the ConsumerBase of asynchronous events in the - // BufferQueue. The onFrameAvailable and onBuffersReleased methods should - // not need to be overridden by derived classes, but if they are overridden - // the ConsumerBase implementation must be called from the derived class. - // The ConsumerBase version of onSidebandStreamChanged does nothing and can - // be overriden by derived classes if they want the notification. - virtual void onFrameAvailable(const BufferItem& item); - virtual void onBuffersReleased(); - virtual void onSidebandStreamChanged(); + // BufferQueue. The onFrameAvailable, onFrameReplaced, and + // onBuffersReleased methods should not need to be overridden by derived + // classes, but if they are overridden the ConsumerBase implementation must + // be called from the derived class. The ConsumerBase version of + // onSidebandStreamChanged does nothing and can be overriden by derived + // classes if they want the notification. + virtual void onFrameAvailable(const BufferItem& item) override; + virtual void onFrameReplaced(const BufferItem& item) override; + virtual void onBuffersReleased() override; + virtual void onSidebandStreamChanged() override; // freeBufferLocked frees up the given buffer slot. If the slot has been // initialized this will release the reference to the GraphicBuffer in that diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp index 2fcbaf2f6..ccbb5a25f 100644 --- a/libs/gui/BufferQueue.cpp +++ b/libs/gui/BufferQueue.cpp @@ -39,6 +39,14 @@ void BufferQueue::ProxyConsumerListener::onFrameAvailable( } } +void BufferQueue::ProxyConsumerListener::onFrameReplaced( + const BufferItem& item) { + sp listener(mConsumerListener.promote()); + if (listener != NULL) { + listener->onFrameReplaced(item); + } +} + void BufferQueue::ProxyConsumerListener::onBuffersReleased() { sp listener(mConsumerListener.promote()); if (listener != NULL) { diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp index e576018bf..aa9443acf 100644 --- a/libs/gui/ConsumerBase.cpp +++ b/libs/gui/ConsumerBase.cpp @@ -114,6 +114,21 @@ void ConsumerBase::onFrameAvailable(const BufferItem& item) { } } +void ConsumerBase::onFrameReplaced(const BufferItem &item) { + CB_LOGV("onFrameReplaced"); + + sp listener; + { + Mutex::Autolock lock(mMutex); + listener = mFrameAvailableListener.promote(); + } + + if (listener != NULL) { + CB_LOGV("actually calling onFrameReplaced"); + listener->onFrameReplaced(item); + } +} + void ConsumerBase::onBuffersReleased() { Mutex::Autolock lock(mMutex); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 46c17e5d1..0b4c640c3 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -339,9 +339,9 @@ protected: private: // Interface implementation for SurfaceFlingerConsumer::ContentsChangedListener - virtual void onFrameAvailable(const BufferItem& item); - virtual void onFrameReplaced(const BufferItem& item); - virtual void onSidebandStreamChanged(); + virtual void onFrameAvailable(const BufferItem& item) override; + virtual void onFrameReplaced(const BufferItem& item) override; + virtual void onSidebandStreamChanged() override; void commitTransaction();