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/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 @@
         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 @@
 namespace android {
 // ---------------------------------------------------------------------------
 
-class GraphicBuffer;
 class Fence;
 class FloatRect;
+class GraphicBuffer;
+class NativeHandle;
 class Region;
 class String8;
 class SurfaceFlinger;
@@ -164,6 +165,7 @@
         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 a1820ab..0f87066 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -458,6 +458,10 @@
     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 6899904..c2cd779 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -105,6 +105,7 @@
     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