diff options
author | Jesse Hall <jessehall@google.com> | 2014-03-13 20:28:16 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-03-13 20:28:17 +0000 |
commit | 73ed82f809a40560fd3a6d53d18e5c846362d764 (patch) | |
tree | cbf5d50d6c3b7cd49b69c1d95b4f294f64cae8a7 /services | |
parent | a3f519fe6ffb6ac358a3a8015beb94ef1b596ae5 (diff) | |
parent | 399184a4cd728ea1421fb0bc1722274a29e38f4a (diff) | |
download | frameworks_native-73ed82f809a40560fd3a6d53d18e5c846362d764.zip frameworks_native-73ed82f809a40560fd3a6d53d18e5c846362d764.tar.gz frameworks_native-73ed82f809a40560fd3a6d53d18e5c846362d764.tar.bz2 |
Merge "Add sideband streams to BufferQueue and related classes"
Diffstat (limited to 'services')
-rw-r--r-- | services/surfaceflinger/DisplayHardware/HWComposer.cpp | 11 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayHardware/HWComposer.h | 4 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp | 4 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h | 1 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 28 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 7 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlingerConsumer.cpp | 27 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlingerConsumer.h | 14 |
8 files changed, 87 insertions, 9 deletions
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 474f633..0ca93c8 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -25,6 +25,7 @@ #include <utils/Errors.h> #include <utils/misc.h> +#include <utils/NativeHandle.h> #include <utils/String8.h> #include <utils/Thread.h> #include <utils/Trace.h> @@ -942,12 +943,22 @@ public: SharedBuffer const* sb = reg.getSharedBuffer(&visibleRegion.numRects); visibleRegion.rects = reinterpret_cast<hwc_rect_t const *>(sb->data()); } + virtual void setSidebandStream(const sp<NativeHandle>& stream) { + ALOG_ASSERT(stream->handle() != NULL); + getLayer()->compositionType = HWC_SIDEBAND; + getLayer()->sidebandStream = stream->handle(); + } virtual void setBuffer(const sp<GraphicBuffer>& buffer) { if (buffer == 0 || buffer->handle == 0) { getLayer()->compositionType = HWC_FRAMEBUFFER; getLayer()->flags |= HWC_SKIP_LAYER; getLayer()->handle = 0; } else { + if (getLayer()->compositionType == HWC_SIDEBAND) { + // If this was a sideband layer but the stream was removed, reset + // it to FRAMEBUFFER. The HWC can change it to OVERLAY in prepare. + getLayer()->compositionType = HWC_FRAMEBUFFER; + } getLayer()->handle = buffer->handle; } } diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index 9f96113..9218bf6 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -45,9 +45,10 @@ struct framebuffer_device_t; namespace android { // --------------------------------------------------------------------------- -class GraphicBuffer; class Fence; class FloatRect; +class GraphicBuffer; +class NativeHandle; class Region; class String8; class SurfaceFlinger; @@ -164,6 +165,7 @@ public: virtual void setFrame(const Rect& frame) = 0; virtual void setCrop(const FloatRect& crop) = 0; virtual void setVisibleRegionScreen(const Region& reg) = 0; + virtual void setSidebandStream(const sp<NativeHandle>& stream) = 0; virtual void setBuffer(const sp<GraphicBuffer>& buffer) = 0; virtual void setAcquireFenceFd(int fenceFd) = 0; virtual void setPlaneAlpha(uint8_t alpha) = 0; diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp index 91be439..11c42e0 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp @@ -469,6 +469,10 @@ status_t VirtualDisplaySurface::disconnect(int api) { return mSource[SOURCE_SINK]->disconnect(api); } +status_t VirtualDisplaySurface::setSidebandStream(const sp<NativeHandle>& /*stream*/) { + return INVALID_OPERATION; +} + void VirtualDisplaySurface::updateQueueBufferOutput( const QueueBufferOutput& qbo) { uint32_t w, h, transformHint, numPendingBuffers; diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h index cd9a5b0..0d30a1b 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h @@ -107,6 +107,7 @@ private: virtual status_t connect(const sp<IBinder>& token, int api, bool producerControlledByApp, QueueBufferOutput* output); virtual status_t disconnect(int api); + virtual status_t setSidebandStream(const sp<NativeHandle>& stream); // // Utility methods diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 465d376..019d892 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -27,6 +27,7 @@ #include <utils/Errors.h> #include <utils/Log.h> +#include <utils/NativeHandle.h> #include <utils/StopWatch.h> #include <utils/Trace.h> @@ -66,6 +67,7 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client, mFormat(PIXEL_FORMAT_NONE), mTransactionFlags(0), mQueuedFrames(0), + mSidebandStreamChanged(false), mCurrentTransform(0), mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), mCurrentOpacity(true), @@ -118,7 +120,7 @@ void Layer::onFirstRef() { mBufferQueue = new SurfaceTextureLayer(mFlinger); mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName); mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); - mSurfaceFlingerConsumer->setFrameAvailableListener(this); + mSurfaceFlingerConsumer->setContentsChangedListener(this); mSurfaceFlingerConsumer->setName(mName); #ifdef TARGET_DISABLE_TRIPLE_BUFFERING @@ -158,6 +160,13 @@ void Layer::onFrameAvailable() { mFlinger->signalLayerUpdate(); } +void Layer::onSidebandStreamChanged() { + if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) { + // mSidebandStreamChanged was false + mFlinger->signalLayerUpdate(); + } +} + // called with SurfaceFlinger::mStateLock from the drawing thread after // the layer has been remove from the current state list (and just before // it's removed from the drawing state list) @@ -413,9 +422,13 @@ void Layer::setPerFrameData(const sp<const DisplayDevice>& hw, Region visible = tr.transform(visibleRegion.intersect(hw->getViewport())); layer.setVisibleRegionScreen(visible); - // NOTE: buffer can be NULL if the client never drew into this - // layer yet, or if we ran out of memory - layer.setBuffer(mActiveBuffer); + if (mSidebandStream.get()) { + layer.setSidebandStream(mSidebandStream); + } else { + // NOTE: buffer can be NULL if the client never drew into this + // layer yet, or if we ran out of memory + layer.setBuffer(mActiveBuffer); + } } void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */, @@ -907,7 +920,7 @@ bool Layer::setLayerStack(uint32_t layerStack) { bool Layer::onPreComposition() { mRefreshPending = false; - return mQueuedFrames > 0; + return mQueuedFrames > 0 || mSidebandStreamChanged; } void Layer::onPostComposition() { @@ -950,6 +963,11 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) { ATRACE_CALL(); + if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) { + // mSidebandStreamChanged was true + mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream(); + } + Region outDirtyRegion; if (mQueuedFrames > 0) { diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 9283eaa..43de999 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -66,7 +66,7 @@ class SurfaceFlinger; * This also implements onFrameAvailable(), which notifies SurfaceFlinger * that new data has arrived. */ -class Layer : public SurfaceFlingerConsumer::FrameAvailableListener { +class Layer : public SurfaceFlingerConsumer::ContentsChangedListener { static int32_t sSequence; public: @@ -313,8 +313,9 @@ protected: private: - // Interface implementation for SurfaceFlingerConsumer::FrameAvailableListener + // Interface implementation for SurfaceFlingerConsumer::ContentsChangedListener virtual void onFrameAvailable(); + virtual void onSidebandStreamChanged(); void commitTransaction(); @@ -351,10 +352,12 @@ private: // thread-safe volatile int32_t mQueuedFrames; + volatile int32_t mSidebandStreamChanged; // used like an atomic boolean FrameTracker mFrameTracker; // main thread sp<GraphicBuffer> mActiveBuffer; + sp<NativeHandle> mSidebandStream; Rect mCurrentCrop; uint32_t mCurrentTransform; uint32_t mCurrentScalingMode; diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp index 6dc093e..a412543 100644 --- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp +++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp @@ -21,8 +21,9 @@ #include <private/gui/SyncFeatures.h> -#include <utils/Trace.h> #include <utils/Errors.h> +#include <utils/NativeHandle.h> +#include <utils/Trace.h> namespace android { @@ -112,6 +113,10 @@ bool SurfaceFlingerConsumer::getTransformToDisplayInverse() const { return mTransformToDisplayInverse; } +sp<NativeHandle> SurfaceFlingerConsumer::getSidebandStream() const { + return mConsumer->getSidebandStream(); +} + // We need to determine the time when a buffer acquired now will be // displayed. This can be calculated: // time when previous buffer's actual-present fence was signaled @@ -154,6 +159,26 @@ nsecs_t SurfaceFlingerConsumer::computeExpectedPresent() return prevVsync + hwcLatency * vsyncPeriod + extraPadding; } +void SurfaceFlingerConsumer::setContentsChangedListener( + const wp<ContentsChangedListener>& listener) { + setFrameAvailableListener(listener); + Mutex::Autolock lock(mMutex); + mContentsChangedListener = listener; +} + +void SurfaceFlingerConsumer::onSidebandStreamChanged() { + sp<ContentsChangedListener> listener; + { // scope for the lock + Mutex::Autolock lock(mMutex); + ALOG_ASSERT(mFrameAvailableListener.unsafe_get() == mContentsChangedListener.unsafe_get()); + listener = mContentsChangedListener.promote(); + } + + if (listener != NULL) { + listener->onSidebandStreamChanged(); + } +} + // --------------------------------------------------------------------------- }; // namespace android diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.h b/services/surfaceflinger/SurfaceFlingerConsumer.h index 688ad32..becd5d3 100644 --- a/services/surfaceflinger/SurfaceFlingerConsumer.h +++ b/services/surfaceflinger/SurfaceFlingerConsumer.h @@ -27,6 +27,10 @@ namespace android { */ class SurfaceFlingerConsumer : public GLConsumer { public: + struct ContentsChangedListener: public FrameAvailableListener { + virtual void onSidebandStreamChanged() = 0; + }; + SurfaceFlingerConsumer(const sp<BufferQueue>& bq, uint32_t tex) : GLConsumer(bq, tex, GLConsumer::TEXTURE_EXTERNAL, false) {} @@ -54,9 +58,19 @@ public: // must be called from SF main thread bool getTransformToDisplayInverse() const; + // Sets the contents changed listener. This should be used instead of + // ConsumerBase::setFrameAvailableListener(). + void setContentsChangedListener(const wp<ContentsChangedListener>& listener); + + sp<NativeHandle> getSidebandStream() const; + private: nsecs_t computeExpectedPresent(); + virtual void onSidebandStreamChanged(); + + wp<ContentsChangedListener> mContentsChangedListener; + // Indicates this buffer must be transformed by the inverse transform of the screen // it is displayed onto. This is applied after GLConsumer::mCurrentTransform. // This must be set/read from SurfaceFlinger's main thread. |