Add sideband streams to BufferQueue and related classes

Sideband streams are essentially a device-specific buffer queue that
bypasses the BufferQueue system. They can be used for situations with
hard real-time requirements like high-quality TV and video playback
with A/V sync. A handle to the stream is provided by the source HAL,
and attached to a BufferQueue. The sink HAL can read buffers via the
stream handle rather than acquiring individual buffers from the
BufferQueue.

Change-Id: Ib3f262eddfc520f4bbe3d9b91753ed7dd09d3a9b
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 @@
         mFormat(PIXEL_FORMAT_NONE),
         mTransactionFlags(0),
         mQueuedFrames(0),
+        mSidebandStreamChanged(false),
         mCurrentTransform(0),
         mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
         mCurrentOpacity(true),
@@ -118,7 +120,7 @@
     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 @@
     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 @@
     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::onPreComposition() {
     mRefreshPending = false;
-    return mQueuedFrames > 0;
+    return mQueuedFrames > 0 || mSidebandStreamChanged;
 }
 
 void Layer::onPostComposition() {
@@ -950,6 +963,11 @@
 {
     ATRACE_CALL();
 
+    if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
+        // mSidebandStreamChanged was true
+        mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
+    }
+
     Region outDirtyRegion;
     if (mQueuedFrames > 0) {