Revert "Revert "Bind to FBO when using GPU composition""

Hold for now while I propose a fix on top of this change.

This reverts commit 8d4f90aaadf9f3be77d258d2acd67b6186352811.

Reason for revert: Forward fixing

Bug: 117680609
Change-Id: I68a26ced146fa057de3aeb144cbfe2fa3c9842fe
Test: See If639ce2c6cd600eabb957d278815f80b413d92b3
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 35ba391..7150660 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -45,6 +45,7 @@
 #include <gui/BufferQueue.h>
 #include <gui/GuiConfig.h>
 #include <gui/IDisplayEventConnection.h>
+#include <gui/IProducerListener.h>
 #include <gui/LayerDebugInfo.h>
 #include <gui/Surface.h>
 #include <renderengine/RenderEngine.h>
@@ -676,10 +677,6 @@
     LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(*display->getId()),
                         "Internal display is disconnected.");
 
-    // make the default display GLContext current so that we can create textures
-    // when creating Layers (which may happens before we render something)
-    display->makeCurrent();
-
     if (useVrFlinger) {
         auto vrFlingerRequestDisplayCallback = [this](bool requestDisplay) {
             // This callback is called from the vr flinger dispatch thread. We
@@ -1409,7 +1406,6 @@
     // mCurrentState and mDrawingState and re-apply all changes when we make the
     // transition.
     mDrawingState.displays.clear();
-    getRenderEngine().resetCurrentSurface();
     mDisplays.clear();
 }
 
@@ -1719,7 +1715,7 @@
             auto& engine(getRenderEngine());
             engine.fillRegionWithColor(dirtyRegion, 1, 0, 1, 1);
 
-            display->swapBuffers(getHwComposer());
+            display->queueBuffer(getHwComposer());
         }
     }
 
@@ -2194,8 +2190,7 @@
         if (displayId) {
             getHwComposer().presentAndGetReleaseFences(*displayId);
         }
-        display->onSwapBuffersCompleted();
-        display->makeCurrent();
+        display->onPresentDisplayCompleted();
         for (auto& layer : display->getVisibleLayersSortedByZ()) {
             sp<Fence> releaseFence = Fence::NO_FENCE;
 
@@ -2348,16 +2343,11 @@
     std::unique_ptr<renderengine::Surface> renderSurface = getRenderEngine().createSurface();
     renderSurface->setCritical(isInternalDisplay);
     renderSurface->setAsync(state.isVirtual());
-    renderSurface->setNativeWindow(nativeWindow.get());
     creationArgs.renderSurface = std::move(renderSurface);
 
     // Make sure that composition can never be stalled by a virtual display
     // consumer that isn't processing buffers fast enough. We have to do this
-    // in two places:
-    // * Here, in case the display is composed entirely by HWC.
-    // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the
-    //   window's swap interval in eglMakeCurrent, so they'll override the
-    //   interval we set here.
+    // here, in case the display is composed entirely by HWC.
     if (state.isVirtual()) {
         nativeWindow->setSwapInterval(nativeWindow.get(), 0);
     }
@@ -2417,12 +2407,6 @@
                 const auto externalDisplayId = getExternalDisplayId();
 
                 // in drawing state but not in current state
-                // Call makeCurrent() on the primary display so we can
-                // be sure that nothing associated with this display
-                // is current.
-                if (const auto defaultDisplay = getDefaultDisplayDeviceLocked()) {
-                    defaultDisplay->makeCurrent();
-                }
                 if (const auto display = getDisplayDeviceLocked(draw.keyAt(i))) {
                     display->disconnect(getHwComposer());
                 }
@@ -2973,7 +2957,7 @@
     mGeometryInvalid = true;
 }
 
-void SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& display,
+void SurfaceFlinger::doDisplayComposition(const sp<DisplayDevice>& display,
                                           const Region& inDirtyRegion) {
     // We only need to actually compose the display if:
     // 1) It is being handled by hardware composer, which may need this to
@@ -2988,10 +2972,10 @@
     if (!doComposeSurfaces(display)) return;
 
     // swap buffers (presentation)
-    display->swapBuffers(getHwComposer());
+    display->queueBuffer(getHwComposer());
 }
 
-bool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& display) {
+bool SurfaceFlinger::doComposeSurfaces(const sp<DisplayDevice>& display) {
     ALOGV("doComposeSurfaces");
 
     const Region bounds(display->bounds());
@@ -3004,9 +2988,31 @@
     bool applyColorMatrix = false;
     bool needsEnhancedColorMatrix = false;
 
+    // Framebuffer will live in this scope for GPU composition.
+    std::unique_ptr<renderengine::BindNativeBufferAsFramebuffer> fbo;
+
     if (hasClientComposition) {
         ALOGV("hasClientComposition");
 
+        sp<GraphicBuffer> buf = display->dequeueBuffer();
+
+        if (buf == nullptr) {
+            ALOGW("Dequeuing buffer for display [%s] failed, bailing out of "
+                  "client composition for this frame",
+                  display->getDisplayName().c_str());
+            return false;
+        }
+
+        // Bind the framebuffer in this scope.
+        fbo = std::make_unique<renderengine::BindNativeBufferAsFramebuffer>(getRenderEngine(),
+                                                                            buf->getNativeBuffer());
+
+        if (fbo->getStatus() != NO_ERROR) {
+            ALOGW("Binding buffer for display [%s] failed with status: %d",
+                  display->getDisplayName().c_str(), fbo->getStatus());
+            return false;
+        }
+
         Dataspace outputDataspace = Dataspace::UNKNOWN;
         if (display->hasWideColorGamut()) {
             outputDataspace = display->getCompositionDataSpace();
@@ -3035,18 +3041,7 @@
             colorMatrix *= mEnhancedSaturationMatrix;
         }
 
-        if (!display->makeCurrent()) {
-            ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
-                  display->getDisplayName().c_str());
-            getRenderEngine().resetCurrentSurface();
-
-            // |mStateLock| not needed as we are on the main thread
-            const auto defaultDisplay = getDefaultDisplayDeviceLocked();
-            if (!defaultDisplay || !defaultDisplay->makeCurrent()) {
-                ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting.");
-            }
-            return false;
-        }
+        display->setViewportAndProjection();
 
         // Never touch the framebuffer if we don't have any framebuffer layers
         if (hasDeviceComposition) {
@@ -3139,11 +3134,15 @@
         firstLayer = false;
     }
 
-    // Clear color transform matrix at the end of the frame.
-    getRenderEngine().setColorTransform(mat4());
-
-    // disable scissor at the end of the frame
-    getBE().mRenderEngine->disableScissor();
+    // Perform some cleanup steps if we used client composition.
+    if (hasClientComposition) {
+        getRenderEngine().setColorTransform(mat4());
+        getBE().mRenderEngine->disableScissor();
+        display->finishBuffer();
+        // Clear out error flags here so that we don't wait until next
+        // composition to log.
+        getRenderEngine().checkErrors();
+    }
     return true;
 }