Simplify frame callback pipeline.

The gRPC streamScreenshot api works roughly as follows:

1. Register for frame change events.
2. Take a screenshot when event is received.
3. Send screenshot to client

Previously we used the callback infrastructure used by screen recording.
This callback mechanism provides the frame that was produced as well,
and introduced a significant amount of overhead that could result in
screen flicker when there is a consistent high FPS. Note that the
returned frame was never used by the gRPC api.

We now introduce a lightweight callback that only notifies that a new
frame is available, and no longer copy around frames.

Bug: b/179310324
Test: No more flickering in fuchsia when streaming screenshots.
Change-Id: Ibd63f7fcaa4228466dd6d13877b5793d8f6f8444
diff --git a/stream-servers/FrameBuffer.h b/stream-servers/FrameBuffer.h
index fe5f331..ceb785b 100644
--- a/stream-servers/FrameBuffer.h
+++ b/stream-servers/FrameBuffer.h
@@ -16,6 +16,11 @@
 #ifndef _LIBRENDER_FRAMEBUFFER_H
 #define _LIBRENDER_FRAMEBUFFER_H
 
+#include <EGL/egl.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <stdint.h>
+
 #include <array>
 #include <functional>
 #include <map>
@@ -24,11 +29,6 @@
 #include <unordered_map>
 #include <unordered_set>
 
-#include <EGL/egl.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#include <stdint.h>
-
 #include "Compositor.h"
 #include "Display.h"
 #include "DisplaySurface.h"
@@ -37,12 +37,13 @@
 #include "PostWorker.h"
 #include "ReadbackWorker.h"
 #include "aemu/base/AsyncResult.h"
+#include "aemu/base/EventNotificationSupport.h"
 #include "aemu/base/HealthMonitor.h"
-#include "aemu/base/synchronization/Lock.h"
 #include "aemu/base/ManagedDescriptor.hpp"
-#include "aemu/base/synchronization/MessageChannel.h"
 #include "aemu/base/Metrics.h"
 #include "aemu/base/files/Stream.h"
+#include "aemu/base/synchronization/Lock.h"
+#include "aemu/base/synchronization/MessageChannel.h"
 #include "aemu/base/threads/Thread.h"
 #include "aemu/base/threads/WorkerThread.h"
 #include "gl/BufferGl.h"
@@ -51,14 +52,14 @@
 #include "gl/DisplaySurfaceGl.h"
 #include "gl/EmulatedEglConfig.h"
 #include "gl/EmulatedEglContext.h"
-#include "gl/EmulatedEglWindowSurface.h"
 #include "gl/EmulatedEglImage.h"
+#include "gl/EmulatedEglWindowSurface.h"
 #include "gl/EmulationGl.h"
 #include "gl/GLESVersionDetector.h"
 #include "gl/TextureDraw.h"
-#include "render_api.h"
 #include "render-utils/Renderer.h"
 #include "render-utils/virtio_gpu_ops.h"
+#include "render_api.h"
 #include "snapshot/common.h"
 #include "utils/RenderDoc.h"
 #include "vulkan/vk_util.h"
@@ -115,7 +116,7 @@
 // There is only one global instance, that can be retrieved with getFB(),
 // and which must be previously setup by calling initialize().
 //
-class FrameBuffer {
+class FrameBuffer : public android::base::EventNotificationSupport<emugl::FrameBufferChangeEvent> {
    public:
     // Initialize the global instance.
     // |width| and |height| are the dimensions of the emulator GPU display
@@ -673,7 +674,10 @@
     AsyncResult postImpl(HandleType p_colorbuffer, Post::CompletionCallback callback,
                   bool needLockAndBind = true, bool repaint = false);
     bool postImplSync(HandleType p_colorbuffer, bool needLockAndBind = true, bool repaint = false);
-    void setGuestPostedAFrame() { m_guestPostedAFrame = true; }
+    void setGuestPostedAFrame() {
+        m_guestPostedAFrame = true;
+        fireEvent({emugl::FrameBufferChange::FrameReady, mFrameNumber++});
+    }
     HandleType createColorBufferWithHandleLocked(int p_width, int p_height, GLenum p_internalFormat,
                                                  FrameworkFormat p_frameworkFormat,
                                                  HandleType handle);
@@ -708,6 +712,7 @@
     android::base::Lock m_lock;
     android::base::ReadWriteLock m_contextStructureLock;
     android::base::Lock m_colorBufferMapLock;
+    uint64_t mFrameNumber;
     FBNativeWindowType m_nativeWindow = 0;
     gfxstream::EmulatedEglContextMap m_contexts;
     gfxstream::EmulatedEglImageMap m_images;
diff --git a/stream-servers/RenderWindow.cpp b/stream-servers/RenderWindow.cpp
index 6fc4f77..7f86f0b 100644
--- a/stream-servers/RenderWindow.cpp
+++ b/stream-servers/RenderWindow.cpp
@@ -474,6 +474,14 @@
     return FrameBuffer::getFB()->getReadPixelsCallback();
 }
 
+void RenderWindow::addListener(emugl::Renderer::FrameBufferChangeEventListener* listener) {
+    FrameBuffer::getFB()->addListener(listener);
+}
+
+void RenderWindow::removeListener(emugl::Renderer::FrameBufferChangeEventListener* listener) {
+    FrameBuffer::getFB()->removeListener(listener);
+}
+
 emugl::Renderer::FlushReadPixelPipeline
 RenderWindow::getFlushReadPixelPipeline() {
     return FrameBuffer::getFB()->getFlushReadPixelPipeline();
diff --git a/stream-servers/RenderWindow.h b/stream-servers/RenderWindow.h
index a67513c..cfc0dad 100644
--- a/stream-servers/RenderWindow.h
+++ b/stream-servers/RenderWindow.h
@@ -144,6 +144,9 @@
 
     void setPaused(bool paused);
 
+    void addListener(emugl::Renderer::FrameBufferChangeEventListener* listener);
+    void removeListener(emugl::Renderer::FrameBufferChangeEventListener* listener);
+
 private:
     bool processMessage(const RenderWindowMessage& msg);
     bool useThread() const { return mThread != nullptr; }
diff --git a/stream-servers/RendererImpl.cpp b/stream-servers/RendererImpl.cpp
index 9d8e121..592fb02 100644
--- a/stream-servers/RendererImpl.cpp
+++ b/stream-servers/RendererImpl.cpp
@@ -255,13 +255,11 @@
 }
 
 void RendererImpl::addListener(FrameBufferChangeEventListener* listener) {
-    // TODO: need CP
-    (void)listener;
+    mRenderWindow->addListener(listener);
 }
 
 void RendererImpl::removeListener(FrameBufferChangeEventListener* listener) {
-    // TODO: need CP
-    (void)listener;
+    mRenderWindow->removeListener(listener);
 }
 
 void* RendererImpl::addressSpaceGraphicsConsumerCreate(