Revert "Second Patch for async RenderEngine"

Revert "Fix vender implementation due to second patch of async R..."

Revert submission 15644535-asyncRenderEngineV2

Reason for revert: Broke multiple tests
Reverted Changes:
I772122750:Fix vts cases due to function change for async ren...
I615f2927d:Second Patch for async RenderEngine
I3f47b8b67:Fix vender implementation due to second patch of a...

Bug: 202803359
Bug: 202808760
Change-Id: Ib8ef68747621b7114cf2d1dfb856292674729744
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index 6c60e53..f98681e 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -48,9 +48,7 @@
 // Interface implementation for Layer
 // -----------------------------------------------------------------------
 
-void BufferQueueLayer::onLayerDisplayed(
-        std::shared_future<renderengine::RenderEngineResult> futureRenderEngineResult) {
-    sp<Fence> releaseFence = new Fence(dup(futureRenderEngineResult.get().drawFence));
+void BufferQueueLayer::onLayerDisplayed(const sp<Fence>& releaseFence) {
     mConsumer->setReleaseFence(releaseFence);
 
     // Prevent tracing the same release multiple times.
diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h
index dfdb5c0..a3bd725 100644
--- a/services/surfaceflinger/BufferQueueLayer.h
+++ b/services/surfaceflinger/BufferQueueLayer.h
@@ -42,8 +42,7 @@
     // Implements Layer.
     const char* getType() const override { return "BufferQueueLayer"; }
 
-    void onLayerDisplayed(
-            std::shared_future<renderengine::RenderEngineResult> futureRenderEngineResult) override;
+    void onLayerDisplayed(const sp<Fence>& releaseFence) override;
 
     // If a buffer was replaced this frame, release the former buffer
     void releasePendingBuffer(nsecs_t dequeueReadyTime) override;
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 454363a..132ee9d 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -70,11 +70,69 @@
     }
 }
 
+status_t BufferStateLayer::addReleaseFence(const sp<CallbackHandle>& ch,
+                                           const sp<Fence>& fence) {
+    if (ch == nullptr) {
+        return OK;
+    }
+    ch->previousReleaseCallbackId = mPreviousReleaseCallbackId;
+    if (!ch->previousReleaseFence.get()) {
+        ch->previousReleaseFence = fence;
+        return OK;
+    }
+
+    // Below logic is lifted from ConsumerBase.cpp:
+    // Check status of fences first because merging is expensive.
+    // Merging an invalid fence with any other fence results in an
+    // invalid fence.
+    auto currentStatus = ch->previousReleaseFence->getStatus();
+    if (currentStatus == Fence::Status::Invalid) {
+        ALOGE("Existing fence has invalid state, layer: %s", mName.c_str());
+        return BAD_VALUE;
+    }
+
+    auto incomingStatus = fence->getStatus();
+    if (incomingStatus == Fence::Status::Invalid) {
+        ALOGE("New fence has invalid state, layer: %s", mName.c_str());
+        ch->previousReleaseFence = fence;
+        return BAD_VALUE;
+    }
+
+    // If both fences are signaled or both are unsignaled, we need to merge
+    // them to get an accurate timestamp.
+    if (currentStatus == incomingStatus) {
+        char fenceName[32] = {};
+        snprintf(fenceName, 32, "%.28s", mName.c_str());
+        sp<Fence> mergedFence = Fence::merge(
+                fenceName, ch->previousReleaseFence, fence);
+        if (!mergedFence.get()) {
+            ALOGE("failed to merge release fences, layer: %s", mName.c_str());
+            // synchronization is broken, the best we can do is hope fences
+            // signal in order so the new fence will act like a union
+            ch->previousReleaseFence = fence;
+            return BAD_VALUE;
+        }
+        ch->previousReleaseFence = mergedFence;
+    } else if (incomingStatus == Fence::Status::Unsignaled) {
+        // If one fence has signaled and the other hasn't, the unsignaled
+        // fence will approximately correspond with the correct timestamp.
+        // There's a small race if both fences signal at about the same time
+        // and their statuses are retrieved with unfortunate timing. However,
+        // by this point, they will have both signaled and only the timestamp
+        // will be slightly off; any dependencies after this point will
+        // already have been met.
+        ch->previousReleaseFence = fence;
+    }
+    // else if (currentStatus == Fence::Status::Unsignaled) is a no-op.
+
+    return OK;
+}
+
 // -----------------------------------------------------------------------
 // Interface implementation for Layer
 // -----------------------------------------------------------------------
-void BufferStateLayer::onLayerDisplayed(
-        std::shared_future<renderengine::RenderEngineResult> futureRenderEngineResult) {
+void BufferStateLayer::onLayerDisplayed(const sp<Fence>& releaseFence) {
+
     // If a layer has been displayed again we may need to clear
     // the mLastClientComposition fence that we use for early release in setBuffer
     // (as we now have a new fence which won't pass through the client composition path in some cases
@@ -88,6 +146,9 @@
         mLastClientCompositionDisplayed = true;
     }
 
+    if (!releaseFence->isValid()) {
+        return;
+    }
     // The previous release fence notifies the client that SurfaceFlinger is done with the previous
     // buffer that was presented on this layer. The first transaction that came in this frame that
     // replaced the previous buffer on this layer needs this release fence, because the fence will
@@ -112,19 +173,17 @@
             break;
         }
     }
+    auto status = addReleaseFence(ch, releaseFence);
+    if (status != OK) {
+        ALOGE("Failed to add release fence for layer %s", getName().c_str());
+    }
 
-    mListPreviousReleaseFences.emplace_back(futureRenderEngineResult);
+    mPreviousReleaseFence = releaseFence;
 
     // Prevent tracing the same release multiple times.
     if (mPreviousFrameNumber != mPreviousReleasedFrameNumber) {
         mPreviousReleasedFrameNumber = mPreviousFrameNumber;
     }
-
-    if (ch != nullptr) {
-        ch->previousReleaseCallbackId = mPreviousReleaseCallbackId;
-        ch->previousReleaseFences.emplace_back(futureRenderEngineResult);
-        ch->name = mName;
-    }
 }
 
 void BufferStateLayer::onSurfaceFrameCreated(
@@ -172,18 +231,9 @@
     mFlinger->getTransactionCallbackInvoker().addCallbackHandles(
             mDrawingState.callbackHandles, jankData);
 
-    sp<Fence> releaseFence = Fence::NO_FENCE;
-    for (auto& handle : mDrawingState.callbackHandles) {
-        if (handle->releasePreviousBuffer &&
-            mDrawingState.releaseBufferEndpoint == handle->listener) {
-            releaseFence =
-                    handle->previousReleaseFence ? handle->previousReleaseFence : Fence::NO_FENCE;
-            break;
-        }
-    }
-
     mDrawingState.callbackHandles = {};
 
+    const sp<Fence>& releaseFence(mPreviousReleaseFence);
     std::shared_ptr<FenceTime> releaseFenceTime = std::make_shared<FenceTime>(releaseFence);
     {
         Mutex::Autolock lock(mFrameEventHistoryMutex);
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index 6cb9b35..87b68ea 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -39,9 +39,7 @@
     // Implements Layer.
     const char* getType() const override { return "BufferStateLayer"; }
 
-    void onLayerDisplayed(
-            std::shared_future<renderengine::RenderEngineResult> futureRenderEngineResult) override;
-
+    void onLayerDisplayed(const sp<Fence>& releaseFence) override;
     void releasePendingBuffer(nsecs_t dequeueReadyTime) override;
 
     void finalizeFrameEventHistory(const std::shared_ptr<FenceTime>& glDoneFence,
@@ -117,6 +115,8 @@
     bool updateFrameEventHistory(const sp<Fence>& acquireFence, nsecs_t postedTime,
                                  nsecs_t requestedPresentTime);
 
+    status_t addReleaseFence(const sp<CallbackHandle>& ch, const sp<Fence>& releaseFence);
+
     bool latchSidebandStream(bool& recomputeVisibleRegions) override;
 
     bool hasFrameUpdate() const override;
@@ -139,7 +139,7 @@
     std::shared_ptr<renderengine::ExternalTexture> getBufferFromBufferData(
             const BufferData& bufferData);
 
-    std::vector<std::shared_future<renderengine::RenderEngineResult>> mListPreviousReleaseFences;
+    sp<Fence> mPreviousReleaseFence;
     ReleaseCallbackId mPreviousReleaseCallbackId = ReleaseCallbackId::INVALID_ID;
     uint64_t mPreviousReleasedFrameNumber = 0;
 
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
index ac243c0..f7b71cf 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
@@ -16,7 +16,6 @@
 
 #pragma once
 
-#include <future>
 #include <optional>
 #include <ostream>
 #include <unordered_set>
@@ -27,7 +26,6 @@
 #pragma clang diagnostic ignored "-Wextra"
 
 #include <renderengine/LayerSettings.h>
-#include <renderengine/RenderEngine.h>
 
 // TODO(b/129481165): remove the #pragma below and fix conversion issues
 #pragma clang diagnostic pop // ignored "-Wconversion -Wextra"
@@ -153,7 +151,7 @@
             ClientCompositionTargetSettings&) = 0;
 
     // Called after the layer is displayed to update the presentation fence
-    virtual void onLayerDisplayed(std::shared_future<renderengine::RenderEngineResult>) = 0;
+    virtual void onLayerDisplayed(const sp<Fence>&) = 0;
 
     // Gets some kind of identifier for the layer for debug purposes.
     virtual const char* getDebugName() const = 0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
index 16aebef..d215bda 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
@@ -39,7 +39,7 @@
                  std::vector<compositionengine::LayerFE::LayerSettings>(
                          compositionengine::LayerFE::ClientCompositionTargetSettings&));
 
-    MOCK_METHOD1(onLayerDisplayed, void(std::shared_future<renderengine::RenderEngineResult>));
+    MOCK_METHOD1(onLayerDisplayed, void(const sp<Fence>&));
 
     MOCK_CONST_METHOD0(getDebugName, const char*());
     MOCK_CONST_METHOD0(getSequence, int32_t());
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 7ea1aa2..048d7c2 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -27,7 +27,6 @@
 #include <compositionengine/impl/OutputLayer.h>
 #include <compositionengine/impl/OutputLayerCompositionState.h>
 #include <compositionengine/impl/planner/Planner.h>
-#include <ftl/future.h>
 
 #include <thread>
 
@@ -1098,12 +1097,12 @@
         setExpensiveRenderingExpected(true);
     }
 
-    std::vector<renderengine::LayerSettings> clientRenderEngineLayers;
-    clientRenderEngineLayers.reserve(clientCompositionLayers.size());
+    std::vector<const renderengine::LayerSettings*> clientCompositionLayerPointers;
+    clientCompositionLayerPointers.reserve(clientCompositionLayers.size());
     std::transform(clientCompositionLayers.begin(), clientCompositionLayers.end(),
-                   std::back_inserter(clientRenderEngineLayers),
-                   [](LayerFE::LayerSettings& settings) -> renderengine::LayerSettings {
-                       return settings;
+                   std::back_inserter(clientCompositionLayerPointers),
+                   [](LayerFE::LayerSettings& settings) -> renderengine::LayerSettings* {
+                       return &settings;
                    });
 
     const nsecs_t renderEngineStart = systemTime();
@@ -1116,7 +1115,7 @@
     const bool useFramebufferCache = outputState.layerFilter.toInternalDisplay;
     auto [status, drawFence] =
             renderEngine
-                    .drawLayers(clientCompositionDisplay, clientRenderEngineLayers, tex,
+                    .drawLayers(clientCompositionDisplay, clientCompositionLayerPointers, tex,
                                 useFramebufferCache, std::move(fd))
                     .get();
 
@@ -1296,10 +1295,8 @@
             releaseFence =
                     Fence::merge("LayerRelease", releaseFence, frame.clientTargetAcquireFence);
         }
-        layer->getLayerFE().onLayerDisplayed(
-                ftl::yield<renderengine::RenderEngineResult>(
-                        {NO_ERROR, base::unique_fd(releaseFence->dup())})
-                        .share());
+
+        layer->getLayerFE().onLayerDisplayed(releaseFence);
     }
 
     // We've got a list of layers needing fences, that are disjoint with
@@ -1307,9 +1304,7 @@
     // supply them with the present fence.
     for (auto& weakLayer : mReleasedLayers) {
         if (auto layer = weakLayer.promote(); layer != nullptr) {
-            layer->onLayerDisplayed(ftl::yield<renderengine::RenderEngineResult>(
-                                            {NO_ERROR, base::unique_fd(frame.presentFence->dup())})
-                                            .share());
+            layer->onLayerDisplayed(frame.presentFence);
         }
     }
 
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
index ec52e59..e6b716e 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
@@ -193,6 +193,11 @@
                              clientCompositionList.cend());
     }
 
+    std::vector<const renderengine::LayerSettings*> layerSettingsPointers;
+    std::transform(layerSettings.cbegin(), layerSettings.cend(),
+                   std::back_inserter(layerSettingsPointers),
+                   [](const renderengine::LayerSettings& settings) { return &settings; });
+
     renderengine::LayerSettings blurLayerSettings;
     if (mBlurLayer) {
         auto blurSettings = targetSettings;
@@ -207,7 +212,7 @@
         blurLayerSettings.name = std::string("blur layer");
         // Clear out the shadow settings
         blurLayerSettings.shadow = {};
-        layerSettings.push_back(blurLayerSettings);
+        layerSettingsPointers.push_back(&blurLayerSettings);
     }
 
     renderengine::LayerSettings holePunchSettings;
@@ -225,7 +230,7 @@
         holePunchSettings.disableBlending = true;
         holePunchSettings.alpha = 0.0f;
         holePunchSettings.name = std::string("hole punch layer");
-        layerSettings.push_back(holePunchSettings);
+        layerSettingsPointers.push_back(&holePunchSettings);
 
         // Add a solid background as the first layer in case there is no opaque
         // buffer behind the punch hole
@@ -234,7 +239,7 @@
         holePunchBackgroundSettings.geometry.boundaries = holePunchSettings.geometry.boundaries;
         holePunchBackgroundSettings.geometry.positionTransform =
                 holePunchSettings.geometry.positionTransform;
-        layerSettings.emplace(layerSettings.begin(), holePunchBackgroundSettings);
+        layerSettingsPointers.insert(layerSettingsPointers.begin(), &holePunchBackgroundSettings);
     }
 
     if (sDebugHighlighLayers) {
@@ -252,7 +257,7 @@
                 .alpha = half(0.05f),
         };
 
-        layerSettings.emplace_back(highlight);
+        layerSettingsPointers.emplace_back(&highlight);
     }
 
     auto texture = texturePool.borrowTexture();
@@ -268,8 +273,8 @@
     }
 
     auto [status, drawFence] = renderEngine
-                                       .drawLayers(displaySettings, layerSettings, texture->get(),
-                                                   false, std::move(bufferFence))
+                                       .drawLayers(displaySettings, layerSettingsPointers,
+                                                   texture->get(), false, std::move(bufferFence))
                                        .get();
 
     if (status == NO_ERROR) {
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index cf63ef5..8f0028c 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -24,7 +24,6 @@
 #include <compositionengine/mock/LayerFE.h>
 #include <compositionengine/mock/OutputLayer.h>
 #include <compositionengine/mock/RenderSurface.h>
-#include <ftl/future.h>
 #include <gtest/gtest.h>
 #include <renderengine/mock/RenderEngine.h>
 #include <ui/Rect.h>
@@ -2885,24 +2884,12 @@
     // are passed. This happens to work with the current implementation, but
     // would not survive certain calls like Fence::merge() which would return a
     // new instance.
-    base::unique_fd layer1FD(layer1Fence->dup());
-    base::unique_fd layer2FD(layer2Fence->dup());
-    base::unique_fd layer3FD(layer3Fence->dup());
-    EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_))
-            .WillOnce([&layer1FD](std::shared_future<renderengine::RenderEngineResult>
-                                          futureRenderEngineResult) {
-                EXPECT_EQ(layer1FD, futureRenderEngineResult.get().drawFence);
-            });
-    EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_))
-            .WillOnce([&layer2FD](std::shared_future<renderengine::RenderEngineResult>
-                                          futureRenderEngineResult) {
-                EXPECT_EQ(layer2FD, futureRenderEngineResult.get().drawFence);
-            });
-    EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_))
-            .WillOnce([&layer3FD](std::shared_future<renderengine::RenderEngineResult>
-                                          futureRenderEngineResult) {
-                EXPECT_EQ(layer3FD, futureRenderEngineResult.get().drawFence);
-            });
+    EXPECT_CALL(*mLayer1.layerFE,
+                onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer1Fence.get()))));
+    EXPECT_CALL(*mLayer2.layerFE,
+                onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer2Fence.get()))));
+    EXPECT_CALL(*mLayer3.layerFE,
+                onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer3Fence.get()))));
 
     mOutput.postFramebuffer();
 }
@@ -2928,9 +2915,9 @@
     // Fence::merge is called, and since none of the fences are actually valid,
     // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
     // This is the best we can do without creating a real kernel fence object.
-    EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
-    EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
-    EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());
+    EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(Fence::NO_FENCE));
+    EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(Fence::NO_FENCE));
+    EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(Fence::NO_FENCE));
 
     mOutput.postFramebuffer();
 }
@@ -2962,22 +2949,12 @@
     EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
 
     // Each released layer should be given the presentFence.
-    base::unique_fd layerFD(presentFence.get()->dup());
-    EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_))
-            .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
-                                         futureRenderEngineResult) {
-                EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
-            });
-    EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_))
-            .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
-                                         futureRenderEngineResult) {
-                EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
-            });
-    EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_))
-            .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
-                                         futureRenderEngineResult) {
-                EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
-            });
+    EXPECT_CALL(*releasedLayer1,
+                onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
+    EXPECT_CALL(*releasedLayer2,
+                onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
+    EXPECT_CALL(*releasedLayer3,
+                onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
 
     mOutput.postFramebuffer();
 
@@ -3154,9 +3131,9 @@
     EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
     EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _))
             .WillRepeatedly([&](const renderengine::DisplaySettings&,
-                                const std::vector<renderengine::LayerSettings>&,
+                                const std::vector<const renderengine::LayerSettings*>&,
                                 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
-                                base::unique_fd&&)
+                                base::unique_fd &&)
                                     -> std::future<renderengine::RenderEngineResult> {
                 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
             });
@@ -3184,11 +3161,11 @@
                     }));
 
     EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
-    EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
+    EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _))
             .WillRepeatedly([&](const renderengine::DisplaySettings&,
-                                const std::vector<renderengine::LayerSettings>&,
+                                const std::vector<const renderengine::LayerSettings*>&,
                                 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
-                                base::unique_fd&&)
+                                base::unique_fd &&)
                                     -> std::future<renderengine::RenderEngineResult> {
                 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
             });
@@ -3219,11 +3196,11 @@
                     }));
 
     EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
-    EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, true, _))
+    EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _))
             .WillRepeatedly([&](const renderengine::DisplaySettings&,
-                                const std::vector<renderengine::LayerSettings>&,
+                                const std::vector<const renderengine::LayerSettings*>&,
                                 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
-                                base::unique_fd&&)
+                                base::unique_fd &&)
                                     -> std::future<renderengine::RenderEngineResult> {
                 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
             });
@@ -3249,7 +3226,7 @@
             .WillRepeatedly(Return());
 
     EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
-    EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
+    EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _))
             .Times(2)
             .WillOnce(Return(ByMove(
                     futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))))
@@ -3281,7 +3258,7 @@
             .WillRepeatedly(Return());
 
     EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
-    EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
+    EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _))
             .WillOnce(Return(ByMove(
                     futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
     EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
@@ -3317,11 +3294,11 @@
     EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
             .WillOnce(Return(mOutputBuffer))
             .WillOnce(Return(otherOutputBuffer));
-    EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
+    EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _))
             .WillRepeatedly([&](const renderengine::DisplaySettings&,
-                                const std::vector<renderengine::LayerSettings>&,
+                                const std::vector<const renderengine::LayerSettings*>&,
                                 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
-                                base::unique_fd&&)
+                                base::unique_fd &&)
                                     -> std::future<renderengine::RenderEngineResult> {
                 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
             });
@@ -3353,10 +3330,10 @@
             .WillRepeatedly(Return());
 
     EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
-    EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
+    EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _))
             .WillOnce(Return(ByMove(
                     futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
-    EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, false, _))
+    EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r3)), _, false, _))
             .WillOnce(Return(ByMove(
                     futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
 
@@ -3510,9 +3487,9 @@
         EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
                 .WillRepeatedly(
                         [&](const renderengine::DisplaySettings&,
-                            const std::vector<renderengine::LayerSettings>&,
+                            const std::vector<const renderengine::LayerSettings*>&,
                             const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
-                            base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
+                            base::unique_fd &&) -> std::future<renderengine::RenderEngineResult> {
                             return futureOf<renderengine::RenderEngineResult>(
                                     {NO_ERROR, base::unique_fd()});
                         });
diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
index 42b3d97..ecb05f8 100644
--- a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
@@ -346,15 +346,15 @@
 
     const auto drawLayers =
             [&](const renderengine::DisplaySettings& displaySettings,
-                const std::vector<renderengine::LayerSettings>& layers,
+                const std::vector<const renderengine::LayerSettings*>& layers,
                 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
-                base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
+                base::unique_fd &&) -> std::future<renderengine::RenderEngineResult> {
         EXPECT_EQ(mOutputState.framebufferSpace.getContent(), displaySettings.physicalDisplay);
         EXPECT_EQ(mOutputState.layerStackSpace.getContent(), displaySettings.clip);
         EXPECT_EQ(ui::Transform::toRotationFlags(mOutputState.framebufferSpace.getOrientation()),
                   displaySettings.orientation);
-        EXPECT_EQ(0.5f, layers[0].alpha);
-        EXPECT_EQ(0.75f, layers[1].alpha);
+        EXPECT_EQ(0.5f, layers[0]->alpha);
+        EXPECT_EQ(0.75f, layers[1]->alpha);
         EXPECT_EQ(ui::Dataspace::SRGB, displaySettings.outputDataspace);
         return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
     };
@@ -398,15 +398,15 @@
 
     const auto drawLayers =
             [&](const renderengine::DisplaySettings& displaySettings,
-                const std::vector<renderengine::LayerSettings>& layers,
+                const std::vector<const renderengine::LayerSettings*>& layers,
                 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
-                base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
+                base::unique_fd &&) -> std::future<renderengine::RenderEngineResult> {
         EXPECT_EQ(mOutputState.framebufferSpace.getContent(), displaySettings.physicalDisplay);
         EXPECT_EQ(mOutputState.layerStackSpace.getContent(), displaySettings.clip);
         EXPECT_EQ(ui::Transform::toRotationFlags(mOutputState.framebufferSpace.getOrientation()),
                   displaySettings.orientation);
-        EXPECT_EQ(0.5f, layers[0].alpha);
-        EXPECT_EQ(0.75f, layers[1].alpha);
+        EXPECT_EQ(0.5f, layers[0]->alpha);
+        EXPECT_EQ(0.75f, layers[1]->alpha);
         EXPECT_EQ(ui::Dataspace::SRGB, displaySettings.outputDataspace);
 
         return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
@@ -453,15 +453,15 @@
 
     const auto drawLayers =
             [&](const renderengine::DisplaySettings& displaySettings,
-                const std::vector<renderengine::LayerSettings>& layers,
+                const std::vector<const renderengine::LayerSettings*>& layers,
                 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
-                base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
+                base::unique_fd &&) -> std::future<renderengine::RenderEngineResult> {
         EXPECT_EQ(mOutputState.framebufferSpace.getContent(), displaySettings.physicalDisplay);
         EXPECT_EQ(mOutputState.layerStackSpace.getContent(), displaySettings.clip);
         EXPECT_EQ(ui::Transform::toRotationFlags(mOutputState.framebufferSpace.getOrientation()),
                   displaySettings.orientation);
-        EXPECT_EQ(0.5f, layers[0].alpha);
-        EXPECT_EQ(0.75f, layers[1].alpha);
+        EXPECT_EQ(0.5f, layers[0]->alpha);
+        EXPECT_EQ(0.75f, layers[1]->alpha);
         EXPECT_EQ(ui::Dataspace::SRGB, displaySettings.outputDataspace);
 
         return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
@@ -656,26 +656,26 @@
 
     const auto drawLayers =
             [&](const renderengine::DisplaySettings&,
-                const std::vector<renderengine::LayerSettings>& layers,
+                const std::vector<const renderengine::LayerSettings*>& layers,
                 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
-                base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
+                base::unique_fd &&) -> std::future<renderengine::RenderEngineResult> {
         // If the highlight layer is enabled, it will increase the size by 1.
         // We're interested in the third layer either way.
         EXPECT_GE(layers.size(), 4u);
         {
-            const auto holePunchSettings = layers[3];
-            EXPECT_EQ(nullptr, holePunchSettings.source.buffer.buffer);
-            EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchSettings.source.solidColor);
-            EXPECT_TRUE(holePunchSettings.disableBlending);
-            EXPECT_EQ(0.0f, holePunchSettings.alpha);
+            const auto* holePunchSettings = layers[3];
+            EXPECT_EQ(nullptr, holePunchSettings->source.buffer.buffer);
+            EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchSettings->source.solidColor);
+            EXPECT_TRUE(holePunchSettings->disableBlending);
+            EXPECT_EQ(0.0f, holePunchSettings->alpha);
         }
 
         {
-            const auto holePunchBackgroundSettings = layers[0];
-            EXPECT_EQ(nullptr, holePunchBackgroundSettings.source.buffer.buffer);
-            EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchBackgroundSettings.source.solidColor);
-            EXPECT_FALSE(holePunchBackgroundSettings.disableBlending);
-            EXPECT_EQ(1.0f, holePunchBackgroundSettings.alpha);
+            const auto* holePunchBackgroundSettings = layers[0];
+            EXPECT_EQ(nullptr, holePunchBackgroundSettings->source.buffer.buffer);
+            EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchBackgroundSettings->source.solidColor);
+            EXPECT_FALSE(holePunchBackgroundSettings->disableBlending);
+            EXPECT_EQ(1.0f, holePunchBackgroundSettings->alpha);
         }
 
         return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
@@ -717,27 +717,27 @@
 
     const auto drawLayers =
             [&](const renderengine::DisplaySettings&,
-                const std::vector<renderengine::LayerSettings>& layers,
+                const std::vector<const renderengine::LayerSettings*>& layers,
                 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
-                base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
+                base::unique_fd &&) -> std::future<renderengine::RenderEngineResult> {
         // If the highlight layer is enabled, it will increase the size by 1.
         // We're interested in the third layer either way.
         EXPECT_GE(layers.size(), 4u);
 
         {
-            const auto holePunchSettings = layers[3];
-            EXPECT_EQ(nullptr, holePunchSettings.source.buffer.buffer);
-            EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchSettings.source.solidColor);
-            EXPECT_TRUE(holePunchSettings.disableBlending);
-            EXPECT_EQ(0.0f, holePunchSettings.alpha);
+            const auto* holePunchSettings = layers[3];
+            EXPECT_EQ(nullptr, holePunchSettings->source.buffer.buffer);
+            EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchSettings->source.solidColor);
+            EXPECT_TRUE(holePunchSettings->disableBlending);
+            EXPECT_EQ(0.0f, holePunchSettings->alpha);
         }
 
         {
-            const auto holePunchBackgroundSettings = layers[0];
-            EXPECT_EQ(nullptr, holePunchBackgroundSettings.source.buffer.buffer);
-            EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchBackgroundSettings.source.solidColor);
-            EXPECT_FALSE(holePunchBackgroundSettings.disableBlending);
-            EXPECT_EQ(1.0f, holePunchBackgroundSettings.alpha);
+            const auto* holePunchBackgroundSettings = layers[0];
+            EXPECT_EQ(nullptr, holePunchBackgroundSettings->source.buffer.buffer);
+            EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchBackgroundSettings->source.solidColor);
+            EXPECT_FALSE(holePunchBackgroundSettings->disableBlending);
+            EXPECT_EQ(1.0f, holePunchBackgroundSettings->alpha);
         }
 
         return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
@@ -867,16 +867,16 @@
 
     const auto drawLayers =
             [&](const renderengine::DisplaySettings&,
-                const std::vector<renderengine::LayerSettings>& layers,
+                const std::vector<const renderengine::LayerSettings*>& layers,
                 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
-                base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
+                base::unique_fd &&) -> std::future<renderengine::RenderEngineResult> {
         // If the highlight layer is enabled, it will increase the size by 1.
         // We're interested in the third layer either way.
         EXPECT_GE(layers.size(), 3u);
-        const auto blurSettings = layers[2];
-        EXPECT_TRUE(blurSettings.skipContentDraw);
-        EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), blurSettings.source.solidColor);
-        EXPECT_EQ(0.0f, blurSettings.alpha);
+        const auto* blurSettings = layers[2];
+        EXPECT_TRUE(blurSettings->skipContentDraw);
+        EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), blurSettings->source.solidColor);
+        EXPECT_EQ(0.0f, blurSettings->alpha);
 
         return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
     };
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index d68cf97..5707c67 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -221,8 +221,7 @@
  * Layer.  So, the implementation is done in BufferLayer.  When called on a
  * EffectLayer object, it's essentially a NOP.
  */
-void Layer::onLayerDisplayed(
-        std::shared_future<renderengine::RenderEngineResult> /*futureRenderEngineResult*/) {}
+void Layer::onLayerDisplayed(const sp<Fence>& /*releaseFence*/) {}
 
 void Layer::removeRelativeZ(const std::vector<Layer*>& layersInTree) {
     if (mDrawingState.zOrderRelativeOf == nullptr) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 4569f9a..07b2eb5 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -616,8 +616,7 @@
     void prepareCompositionState(compositionengine::LayerFE::StateSubset subset) override;
     std::vector<compositionengine::LayerFE::LayerSettings> prepareClientCompositionList(
             compositionengine::LayerFE::ClientCompositionTargetSettings&) override;
-    void onLayerDisplayed(
-            std::shared_future<renderengine::RenderEngineResult> futureRenderEngineResult) override;
+    void onLayerDisplayed(const sp<Fence>& releaseFence) override;
 
     void setWasClientComposed(const sp<Fence>& fence) override {
         mLastClientCompositionFence = fence;
diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp
index d0f56b5..aa2fec5 100644
--- a/services/surfaceflinger/RegionSamplingThread.cpp
+++ b/services/surfaceflinger/RegionSamplingThread.cpp
@@ -356,13 +356,10 @@
                                                renderengine::ExternalTexture::Usage::WRITEABLE);
     }
 
-    auto captureScreenResultFuture =
-            mFlinger.captureScreenCommon(std::move(renderAreaFuture), traverseLayers, buffer,
-                                         true /* regionSampling */, false /* grayscale */, nullptr);
-    auto& captureScreenResult = captureScreenResultFuture.get();
-    if (captureScreenResult.drawFence.ok()) {
-        sync_wait(captureScreenResult.drawFence.get(), -1);
-    }
+    const sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
+    mFlinger.captureScreenCommon(std::move(renderAreaFuture), traverseLayers, buffer,
+                                 true /* regionSampling */, false /* grayscale */, captureListener);
+    ScreenCaptureResults captureResults = captureListener->waitForResults();
 
     std::vector<Descriptor> activeDescriptors;
     for (const auto& descriptor : descriptors) {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 638458c..acb81dc 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -5972,10 +5972,9 @@
         traverseLayersInLayerStack(layerStack, args.uid, visitor);
     };
 
-    auto captureResultFuture = captureScreenCommon(std::move(renderAreaFuture), traverseLayers,
-                                                   reqSize, args.pixelFormat, args.allowProtected,
-                                                   args.grayscale, captureListener);
-    return captureResultFuture.get().status;
+    return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, reqSize,
+                               args.pixelFormat, args.allowProtected, args.grayscale,
+                               captureListener);
 }
 
 status_t SurfaceFlinger::captureDisplay(DisplayId displayId,
@@ -6010,15 +6009,9 @@
         traverseLayersInLayerStack(layerStack, CaptureArgs::UNSET_UID, visitor);
     };
 
-    if (captureListener == nullptr) {
-        ALOGE("capture screen must provide a capture listener callback");
-        return BAD_VALUE;
-    }
-    auto captureResultFuture =
-            captureScreenCommon(std::move(renderAreaFuture), traverseLayers, size,
-                                ui::PixelFormat::RGBA_8888, false /* allowProtected */,
-                                false /* grayscale */, captureListener);
-    return captureResultFuture.get().status;
+    return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, size,
+                               ui::PixelFormat::RGBA_8888, false /* allowProtected */,
+                               false /* grayscale */, captureListener);
 }
 
 status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args,
@@ -6145,28 +6138,23 @@
         });
     };
 
-    if (captureListener == nullptr) {
-        ALOGE("capture screen must provide a capture listener callback");
-        return BAD_VALUE;
-    }
-
-    auto captureResultFuture = captureScreenCommon(std::move(renderAreaFuture), traverseLayers,
-                                                   reqSize, args.pixelFormat, args.allowProtected,
-                                                   args.grayscale, captureListener);
-    return captureResultFuture.get().status;
+    return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, reqSize,
+                               args.pixelFormat, args.allowProtected, args.grayscale,
+                               captureListener);
 }
 
-std::shared_future<renderengine::RenderEngineResult> SurfaceFlinger::captureScreenCommon(
-        RenderAreaFuture renderAreaFuture, TraverseLayersFunction traverseLayers,
-        ui::Size bufferSize, ui::PixelFormat reqPixelFormat, bool allowProtected, bool grayscale,
-        const sp<IScreenCaptureListener>& captureListener) {
+status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture,
+                                             TraverseLayersFunction traverseLayers,
+                                             ui::Size bufferSize, ui::PixelFormat reqPixelFormat,
+                                             bool allowProtected, bool grayscale,
+                                             const sp<IScreenCaptureListener>& captureListener) {
     ATRACE_CALL();
 
     if (exceedsMaxRenderTargetSize(bufferSize.getWidth(), bufferSize.getHeight())) {
         ALOGE("Attempted to capture screen with size (%" PRId32 ", %" PRId32
               ") that exceeds render target size limit.",
               bufferSize.getWidth(), bufferSize.getHeight());
-        return ftl::yield<renderengine::RenderEngineResult>({BAD_VALUE, base::unique_fd()}).share();
+        return BAD_VALUE;
     }
 
     // Loop over all visible layers to see whether there's any protected layer. A protected layer is
@@ -6206,23 +6194,25 @@
                                false /* regionSampling */, grayscale, captureListener);
 }
 
-std::shared_future<renderengine::RenderEngineResult> SurfaceFlinger::captureScreenCommon(
+status_t SurfaceFlinger::captureScreenCommon(
         RenderAreaFuture renderAreaFuture, TraverseLayersFunction traverseLayers,
         const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling,
         bool grayscale, const sp<IScreenCaptureListener>& captureListener) {
     ATRACE_CALL();
 
+    if (captureListener == nullptr) {
+        ALOGE("capture screen must provide a capture listener callback");
+        return BAD_VALUE;
+    }
+
     bool canCaptureBlackoutContent = hasCaptureBlackoutContentPermission();
 
-    auto scheduleResultFuture = schedule([=,
-                                          renderAreaFuture = std::move(renderAreaFuture)]() mutable
-                                         -> std::shared_future<renderengine::RenderEngineResult> {
+    static_cast<void>(schedule([=, renderAreaFuture = std::move(renderAreaFuture)]() mutable {
         if (mRefreshPending) {
             ALOGW("Skipping screenshot for now");
             captureScreenCommon(std::move(renderAreaFuture), traverseLayers, buffer, regionSampling,
                                 grayscale, captureListener);
-            return ftl::yield<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()})
-                    .share();
+            return;
         }
         ScreenCaptureResults captureResults;
         std::unique_ptr<RenderArea> renderArea = renderAreaFuture.get();
@@ -6230,44 +6220,24 @@
             ALOGW("Skipping screen capture because of invalid render area.");
             captureResults.result = NO_MEMORY;
             captureListener->onScreenCaptureCompleted(captureResults);
-            return ftl::yield<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()})
-                    .share();
+            return;
         }
 
-        std::shared_future<renderengine::RenderEngineResult> renderEngineResultFuture;
-
+        status_t result = NO_ERROR;
         renderArea->render([&] {
-            renderEngineResultFuture =
-                    renderScreenImplLocked(*renderArea, traverseLayers, buffer,
-                                           canCaptureBlackoutContent, regionSampling, grayscale,
-                                           captureResults);
+            result = renderScreenImplLocked(*renderArea, traverseLayers, buffer,
+                                            canCaptureBlackoutContent, regionSampling, grayscale,
+                                            captureResults);
         });
-        // spring up a thread to unblock SF main thread and wait for
-        // RenderEngineResult to be available
-        if (captureListener != nullptr) {
-            std::async([=]() mutable {
-                ATRACE_NAME("captureListener is nonnull!");
-                auto& [status, drawFence] = renderEngineResultFuture.get();
-                captureResults.result = status;
-                captureResults.fence = new Fence(dup(drawFence));
-                captureListener->onScreenCaptureCompleted(captureResults);
-            });
-        }
-        return renderEngineResultFuture;
-    });
 
-    // flatten scheduleResultFuture object to single shared_future object
-    std::future<renderengine::RenderEngineResult> captureScreenResultFuture =
-            ftl::chain(std::move(scheduleResultFuture))
-                    .then([=](std::shared_future<renderengine::RenderEngineResult> futureObject)
-                                  -> renderengine::RenderEngineResult {
-                        auto& [status, drawFence] = futureObject.get();
-                        return {status, base::unique_fd(dup(drawFence))};
-                    });
-    return captureScreenResultFuture.share();
+        captureResults.result = result;
+        captureListener->onScreenCaptureCompleted(captureResults);
+    }));
+
+    return NO_ERROR;
 }
 
-std::shared_future<renderengine::RenderEngineResult> SurfaceFlinger::renderScreenImplLocked(
+status_t SurfaceFlinger::renderScreenImplLocked(
         const RenderArea& renderArea, TraverseLayersFunction traverseLayers,
         const std::shared_ptr<renderengine::ExternalTexture>& buffer,
         bool canCaptureBlackoutContent, bool regionSampling, bool grayscale,
@@ -6286,8 +6256,7 @@
     // the impetus on WindowManager to not persist them.
     if (captureResults.capturedSecureLayers && !canCaptureBlackoutContent) {
         ALOGW("FB is protected: PERMISSION_DENIED");
-        return ftl::yield<renderengine::RenderEngineResult>({PERMISSION_DENIED, base::unique_fd()})
-                .share();
+        return PERMISSION_DENIED;
     }
 
     captureResults.buffer = buffer->getBuffer();
@@ -6369,12 +6338,11 @@
 
     });
 
-    std::vector<renderengine::LayerSettings> clientRenderEngineLayers;
-    clientRenderEngineLayers.reserve(clientCompositionLayers.size());
+    std::vector<const renderengine::LayerSettings*> clientCompositionLayerPointers(
+            clientCompositionLayers.size());
     std::transform(clientCompositionLayers.begin(), clientCompositionLayers.end(),
-                   std::back_inserter(clientRenderEngineLayers),
-                   [](compositionengine::LayerFE::LayerSettings& settings)
-                           -> renderengine::LayerSettings { return settings; });
+                   clientCompositionLayerPointers.begin(),
+                   std::pointer_traits<renderengine::LayerSettings*>::pointer_to);
 
     // Use an empty fence for the buffer fence, since we just created the buffer so
     // there is no need for synchronization with the GPU.
@@ -6382,22 +6350,24 @@
     getRenderEngine().useProtectedContext(useProtected);
 
     const constexpr bool kUseFramebufferCache = false;
-    std::future<renderengine::RenderEngineResult> drawLayersResult =
-            getRenderEngine().drawLayers(clientCompositionDisplay, clientRenderEngineLayers, buffer,
-                                         kUseFramebufferCache, std::move(bufferFence));
+    auto [status, drawFence] =
+            getRenderEngine()
+                    .drawLayers(clientCompositionDisplay, clientCompositionLayerPointers, buffer,
+                                kUseFramebufferCache, std::move(bufferFence))
+                    .get();
 
-    std::shared_future<renderengine::RenderEngineResult> drawLayersResultFuture =
-            drawLayersResult.share(); // drawLayersResult will be moved to shared one
-
-    for (auto* layer : renderedLayers) {
-        // make a copy of shared_future object for each layer
-        layer->onLayerDisplayed(drawLayersResultFuture);
+    if (drawFence >= 0) {
+        sp<Fence> releaseFence = new Fence(dup(drawFence));
+        for (auto* layer : renderedLayers) {
+            layer->onLayerDisplayed(releaseFence);
+        }
     }
 
+    captureResults.fence = new Fence(drawFence.release());
     // Always switch back to unprotected context.
     getRenderEngine().useProtectedContext(false);
 
-    return drawLayersResultFuture;
+    return status;
 }
 
 void SurfaceFlinger::windowInfosReported() {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 45fd94e..1f0e42d 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -906,17 +906,17 @@
     // Boot animation, on/off animations and screen capture
     void startBootAnim();
 
-    std::shared_future<renderengine::RenderEngineResult> captureScreenCommon(
-            RenderAreaFuture, TraverseLayersFunction, ui::Size bufferSize, ui::PixelFormat,
-            bool allowProtected, bool grayscale, const sp<IScreenCaptureListener>&);
-    std::shared_future<renderengine::RenderEngineResult> captureScreenCommon(
-            RenderAreaFuture, TraverseLayersFunction,
-            const std::shared_ptr<renderengine::ExternalTexture>&, bool regionSampling,
-            bool grayscale, const sp<IScreenCaptureListener>&);
-    std::shared_future<renderengine::RenderEngineResult> renderScreenImplLocked(
-            const RenderArea&, TraverseLayersFunction,
-            const std::shared_ptr<renderengine::ExternalTexture>&, bool canCaptureBlackoutContent,
-            bool regionSampling, bool grayscale, ScreenCaptureResults&);
+    status_t captureScreenCommon(RenderAreaFuture, TraverseLayersFunction, ui::Size bufferSize,
+                                 ui::PixelFormat, bool allowProtected, bool grayscale,
+                                 const sp<IScreenCaptureListener>&);
+    status_t captureScreenCommon(RenderAreaFuture, TraverseLayersFunction,
+                                 const std::shared_ptr<renderengine::ExternalTexture>&,
+                                 bool regionSampling, bool grayscale,
+                                 const sp<IScreenCaptureListener>&);
+    status_t renderScreenImplLocked(const RenderArea&, TraverseLayersFunction,
+                                    const std::shared_ptr<renderengine::ExternalTexture>&,
+                                    bool canCaptureBlackoutContent, bool regionSampling,
+                                    bool grayscale, ScreenCaptureResults&);
 
     // If the uid provided is not UNSET_UID, the traverse will skip any layers that don't have a
     // matching ownerUid
diff --git a/services/surfaceflinger/TransactionCallbackInvoker.cpp b/services/surfaceflinger/TransactionCallbackInvoker.cpp
index 8fbf0b4..c1eb896 100644
--- a/services/surfaceflinger/TransactionCallbackInvoker.cpp
+++ b/services/surfaceflinger/TransactionCallbackInvoker.cpp
@@ -154,38 +154,6 @@
     // destroyed the client side is dead and there won't be anyone to send the callback to.
     sp<IBinder> surfaceControl = handle->surfaceControl.promote();
     if (surfaceControl) {
-        sp<Fence> prevFence = nullptr;
-
-        for (const auto& futureStruct : handle->previousReleaseFences) {
-            sp<Fence> currentFence = sp<Fence>::make(dup(futureStruct.get().drawFence));
-            if (prevFence == nullptr && currentFence->getStatus() != Fence::Status::Invalid) {
-                prevFence = currentFence;
-                handle->previousReleaseFence = prevFence;
-            } else if (prevFence != nullptr) {
-                // If both fences are signaled or both are unsignaled, we need to merge
-                // them to get an accurate timestamp.
-                if (prevFence->getStatus() != Fence::Status::Invalid &&
-                    prevFence->getStatus() == currentFence->getStatus()) {
-                    char fenceName[32] = {};
-                    snprintf(fenceName, 32, "%.28s", handle->name.c_str());
-                    sp<Fence> mergedFence = Fence::merge(fenceName, prevFence, currentFence);
-                    if (mergedFence->isValid()) {
-                        handle->previousReleaseFence = mergedFence;
-                        prevFence = handle->previousReleaseFence;
-                    }
-                } else if (currentFence->getStatus() == Fence::Status::Unsignaled) {
-                    // If one fence has signaled and the other hasn't, the unsignaled
-                    // fence will approximately correspond with the correct timestamp.
-                    // There's a small race if both fences signal at about the same time
-                    // and their statuses are retrieved with unfortunate timing. However,
-                    // by this point, they will have both signaled and only the timestamp
-                    // will be slightly off; any dependencies after this point will
-                    // already have been met.
-                    handle->previousReleaseFence = currentFence;
-                }
-            }
-        }
-        handle->previousReleaseFences = {};
         FrameEventHistoryStats eventStats(handle->frameNumber,
                                           handle->gpuCompositionDoneFence->getSnapshot().fence,
                                           handle->compositorTiming, handle->refreshStartTime,
diff --git a/services/surfaceflinger/TransactionCallbackInvoker.h b/services/surfaceflinger/TransactionCallbackInvoker.h
index 100dbfa..7e879e1 100644
--- a/services/surfaceflinger/TransactionCallbackInvoker.h
+++ b/services/surfaceflinger/TransactionCallbackInvoker.h
@@ -18,9 +18,8 @@
 
 #include <condition_variable>
 #include <deque>
-#include <future>
-#include <mutex>
 #include <queue>
+#include <mutex>
 #include <thread>
 #include <unordered_map>
 #include <unordered_set>
@@ -29,7 +28,6 @@
 
 #include <binder/IBinder.h>
 #include <gui/ITransactionCompletedListener.h>
-#include <renderengine/RenderEngine.h>
 #include <ui/Fence.h>
 
 namespace android {
@@ -44,9 +42,7 @@
     wp<IBinder> surfaceControl;
 
     bool releasePreviousBuffer = false;
-    std::string name;
     sp<Fence> previousReleaseFence;
-    std::vector<std::shared_future<renderengine::RenderEngineResult>> previousReleaseFences;
     nsecs_t acquireTime = -1;
     nsecs_t latchTime = -1;
     uint32_t transformHint = 0;
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 61c7c39..5135ff9 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -247,16 +247,10 @@
                                                              "screenshot"),
                                            *mRenderEngine, true);
 
-    auto result = mFlinger.renderScreenImplLocked(*renderArea, traverseLayers, mCaptureScreenBuffer,
-                                                  forSystem, regionSampling);
-    EXPECT_TRUE(result.valid());
-
-    auto& [status, drawFence] = result.get();
-
-    EXPECT_EQ(NO_ERROR, status);
-    if (drawFence.ok()) {
-        sync_wait(drawFence.get(), -1);
-    }
+    status_t result =
+            mFlinger.renderScreenImplLocked(*renderArea, traverseLayers, mCaptureScreenBuffer,
+                                            forSystem, regionSampling);
+    EXPECT_EQ(NO_ERROR, result);
 
     LayerCase::cleanup(this);
 }
@@ -352,9 +346,9 @@
     static void setupCommonScreensCaptureCallExpectations(CompositionTest* test) {
         EXPECT_CALL(*test->mRenderEngine, drawLayers)
                 .WillRepeatedly([&](const renderengine::DisplaySettings& displaySettings,
-                                    const std::vector<renderengine::LayerSettings>&,
+                                    const std::vector<const renderengine::LayerSettings*>&,
                                     const std::shared_ptr<renderengine::ExternalTexture>&,
-                                    const bool, base::unique_fd&&)
+                                    const bool, base::unique_fd &&)
                                         -> std::future<renderengine::RenderEngineResult> {
                     EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance);
                     EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
@@ -403,9 +397,9 @@
                                 Return(0)));
         EXPECT_CALL(*test->mRenderEngine, drawLayers)
                 .WillRepeatedly([&](const renderengine::DisplaySettings& displaySettings,
-                                    const std::vector<renderengine::LayerSettings>&,
+                                    const std::vector<const renderengine::LayerSettings*>&,
                                     const std::shared_ptr<renderengine::ExternalTexture>&,
-                                    const bool, base::unique_fd&&)
+                                    const bool, base::unique_fd &&)
                                         -> std::future<renderengine::RenderEngineResult> {
                     EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance);
                     EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
@@ -639,9 +633,9 @@
     static void setupREBufferCompositionCommonCallExpectations(CompositionTest* test) {
         EXPECT_CALL(*test->mRenderEngine, drawLayers)
                 .WillOnce([&](const renderengine::DisplaySettings& displaySettings,
-                              const std::vector<renderengine::LayerSettings>& layerSettings,
+                              const std::vector<const renderengine::LayerSettings*>& layerSettings,
                               const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
-                              base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
+                              base::unique_fd &&) -> std::future<renderengine::RenderEngineResult> {
                     EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance);
                     EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
                               displaySettings.physicalDisplay);
@@ -658,16 +652,16 @@
                                          "verification lambda";
                         return resultFuture;
                     }
-                    const renderengine::LayerSettings layer = layerSettings.back();
-                    EXPECT_THAT(layer.source.buffer.buffer, Not(IsNull()));
-                    EXPECT_THAT(layer.source.buffer.fence, Not(IsNull()));
-                    EXPECT_EQ(DEFAULT_TEXTURE_ID, layer.source.buffer.textureName);
-                    EXPECT_EQ(false, layer.source.buffer.isY410BT2020);
-                    EXPECT_EQ(true, layer.source.buffer.usePremultipliedAlpha);
-                    EXPECT_EQ(false, layer.source.buffer.isOpaque);
-                    EXPECT_EQ(0.0, layer.geometry.roundedCornersRadius);
-                    EXPECT_EQ(ui::Dataspace::UNKNOWN, layer.sourceDataspace);
-                    EXPECT_EQ(LayerProperties::COLOR[3], layer.alpha);
+                    const renderengine::LayerSettings* layer = layerSettings.back();
+                    EXPECT_THAT(layer->source.buffer.buffer, Not(IsNull()));
+                    EXPECT_THAT(layer->source.buffer.fence, Not(IsNull()));
+                    EXPECT_EQ(DEFAULT_TEXTURE_ID, layer->source.buffer.textureName);
+                    EXPECT_EQ(false, layer->source.buffer.isY410BT2020);
+                    EXPECT_EQ(true, layer->source.buffer.usePremultipliedAlpha);
+                    EXPECT_EQ(false, layer->source.buffer.isOpaque);
+                    EXPECT_EQ(0.0, layer->geometry.roundedCornersRadius);
+                    EXPECT_EQ(ui::Dataspace::UNKNOWN, layer->sourceDataspace);
+                    EXPECT_EQ(LayerProperties::COLOR[3], layer->alpha);
                     return resultFuture;
                 });
     }
@@ -691,9 +685,9 @@
     static void setupREColorCompositionCallExpectations(CompositionTest* test) {
         EXPECT_CALL(*test->mRenderEngine, drawLayers)
                 .WillOnce([&](const renderengine::DisplaySettings& displaySettings,
-                              const std::vector<renderengine::LayerSettings>& layerSettings,
+                              const std::vector<const renderengine::LayerSettings*>& layerSettings,
                               const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
-                              base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
+                              base::unique_fd &&) -> std::future<renderengine::RenderEngineResult> {
                     EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance);
                     EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
                               displaySettings.physicalDisplay);
@@ -710,14 +704,14 @@
                                    "setupREColorCompositionCallExpectations verification lambda";
                         return resultFuture;
                     }
-                    const renderengine::LayerSettings layer = layerSettings.back();
-                    EXPECT_THAT(layer.source.buffer.buffer, IsNull());
+                    const renderengine::LayerSettings* layer = layerSettings.back();
+                    EXPECT_THAT(layer->source.buffer.buffer, IsNull());
                     EXPECT_EQ(half3(LayerProperties::COLOR[0], LayerProperties::COLOR[1],
                                     LayerProperties::COLOR[2]),
-                              layer.source.solidColor);
-                    EXPECT_EQ(0.0, layer.geometry.roundedCornersRadius);
-                    EXPECT_EQ(ui::Dataspace::UNKNOWN, layer.sourceDataspace);
-                    EXPECT_EQ(LayerProperties::COLOR[3], layer.alpha);
+                              layer->source.solidColor);
+                    EXPECT_EQ(0.0, layer->geometry.roundedCornersRadius);
+                    EXPECT_EQ(ui::Dataspace::UNKNOWN, layer->sourceDataspace);
+                    EXPECT_EQ(LayerProperties::COLOR[3], layer->alpha);
                     return resultFuture;
                 });
     }
@@ -771,9 +765,9 @@
     static void setupInsecureREBufferCompositionCommonCallExpectations(CompositionTest* test) {
         EXPECT_CALL(*test->mRenderEngine, drawLayers)
                 .WillOnce([&](const renderengine::DisplaySettings& displaySettings,
-                              const std::vector<renderengine::LayerSettings>& layerSettings,
+                              const std::vector<const renderengine::LayerSettings*>& layerSettings,
                               const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
-                              base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
+                              base::unique_fd &&) -> std::future<renderengine::RenderEngineResult> {
                     EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance);
                     EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
                               displaySettings.physicalDisplay);
@@ -790,12 +784,12 @@
                                          "verification lambda";
                         return resultFuture;
                     }
-                    const renderengine::LayerSettings layer = layerSettings.back();
-                    EXPECT_THAT(layer.source.buffer.buffer, IsNull());
-                    EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), layer.source.solidColor);
-                    EXPECT_EQ(0.0, layer.geometry.roundedCornersRadius);
-                    EXPECT_EQ(ui::Dataspace::UNKNOWN, layer.sourceDataspace);
-                    EXPECT_EQ(1.0f, layer.alpha);
+                    const renderengine::LayerSettings* layer = layerSettings.back();
+                    EXPECT_THAT(layer->source.buffer.buffer, IsNull());
+                    EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), layer->source.solidColor);
+                    EXPECT_EQ(0.0, layer->geometry.roundedCornersRadius);
+                    EXPECT_EQ(ui::Dataspace::UNKNOWN, layer->sourceDataspace);
+                    EXPECT_EQ(1.0f, layer->alpha);
                     return resultFuture;
                 });
     }