libgui: Add generation numbers to BufferQueue

This change allows producers to set a generation number on a
BufferQueue. This number will be embedded in any new GraphicBuffers
created in that BufferQueue, and attempts to attach buffers which have
a different generation number will fail.

It also plumbs the setGenerationNumber method through Surface, with the
additional effect that any buffers attached to the Surface after
setting a new generation number will automatically be updated with the
new number (as opposed to failing, as would happen on through IGBP).

Bug: 20923096
Change-Id: I32bf726b035f99c3e5834beaf76afb9f01adcbc2
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 04ac0f4..aeb56e0 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -42,7 +42,8 @@
 Surface::Surface(
         const sp<IGraphicBufferProducer>& bufferProducer,
         bool controlledByApp)
-    : mGraphicBufferProducer(bufferProducer)
+    : mGraphicBufferProducer(bufferProducer),
+      mGenerationNumber(0)
 {
     // Initialize the ANativeWindow function pointers.
     ANativeWindow::setSwapInterval  = hook_setSwapInterval;
@@ -102,6 +103,14 @@
             reqHeight, mReqFormat, mReqUsage);
 }
 
+status_t Surface::setGenerationNumber(uint32_t generation) {
+    status_t result = mGraphicBufferProducer->setGenerationNumber(generation);
+    if (result == NO_ERROR) {
+        mGenerationNumber = generation;
+    }
+    return result;
+}
+
 int Surface::hook_setSwapInterval(ANativeWindow* window, int interval) {
     Surface* c = getSelf(window);
     return c->setSwapInterval(interval);
@@ -698,11 +707,14 @@
     Mutex::Autolock lock(mMutex);
 
     sp<GraphicBuffer> graphicBuffer(static_cast<GraphicBuffer*>(buffer));
+    uint32_t priorGeneration = graphicBuffer->mGenerationNumber;
+    graphicBuffer->mGenerationNumber = mGenerationNumber;
     int32_t attachedSlot = -1;
     status_t result = mGraphicBufferProducer->attachBuffer(
             &attachedSlot, graphicBuffer);
     if (result != NO_ERROR) {
         ALOGE("attachBuffer: IGraphicBufferProducer call failed (%d)", result);
+        graphicBuffer->mGenerationNumber = priorGeneration;
         return result;
     }
     mSlots[attachedSlot].buffer = graphicBuffer;