Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 99599940 authored by Ady Abraham's avatar Ady Abraham
Browse files

SurfaceFlinger: move sync_wait for screen capture to client

Free up time from the SF's main thread by moving the fence waiting
to the client.

Test: Observe systrace of region sample thread
Test: adb shell screencap
Test: Recents takes the screenshot
Test: Rotate device
Test: Volume + power down for screenshot
Bug: 178649983
Change-Id: I0a4991c013375b1f354e0728a06ca30a835b0422
parent 31999efb
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -25,6 +25,14 @@ status_t ScreenCaptureResults::writeToParcel(android::Parcel* parcel) const {
    } else {
        SAFE_PARCEL(parcel->writeBool, false);
    }

    if (fence != Fence::NO_FENCE) {
        SAFE_PARCEL(parcel->writeBool, true);
        SAFE_PARCEL(parcel->write, *fence);
    } else {
        SAFE_PARCEL(parcel->writeBool, false);
    }

    SAFE_PARCEL(parcel->writeBool, capturedSecureLayers);
    SAFE_PARCEL(parcel->writeUint32, static_cast<uint32_t>(capturedDataspace));
    SAFE_PARCEL(parcel->writeInt32, result);
@@ -39,6 +47,13 @@ status_t ScreenCaptureResults::readFromParcel(const android::Parcel* parcel) {
        SAFE_PARCEL(parcel->read, *buffer);
    }

    bool hasFence;
    SAFE_PARCEL(parcel->readBool, &hasFence);
    if (hasFence) {
        fence = new Fence();
        SAFE_PARCEL(parcel->read, *fence);
    }

    SAFE_PARCEL(parcel->readBool, &capturedSecureLayers);
    uint32_t dataspace = 0;
    SAFE_PARCEL(parcel->readUint32, &dataspace);
+1 −1
Original line number Diff line number Diff line
@@ -20,5 +20,5 @@ import android.gui.ScreenCaptureResults;

/** @hide */
oneway interface IScreenCaptureListener {
    void onScreenCaptureComplete(in ScreenCaptureResults captureResults);
    void onScreenCaptureCompleted(in ScreenCaptureResults captureResults);
}
 No newline at end of file
+2 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@

#include <binder/Parcel.h>
#include <binder/Parcelable.h>
#include <ui/Fence.h>
#include <ui/GraphicBuffer.h>

namespace android::gui {
@@ -39,6 +40,7 @@ public:
    status_t readFromParcel(const android::Parcel* parcel) override;

    sp<GraphicBuffer> buffer;
    sp<Fence> fence = Fence::NO_FENCE;
    bool capturedSecureLayers{false};
    ui::Dataspace capturedDataspace{ui::Dataspace::V0_SRGB};
    status_t result = OK;
+4 −2
Original line number Diff line number Diff line
@@ -26,14 +26,16 @@ using gui::ScreenCaptureResults;

struct SyncScreenCaptureListener : gui::BnScreenCaptureListener {
public:
    binder::Status onScreenCaptureComplete(const ScreenCaptureResults& captureResults) override {
    binder::Status onScreenCaptureCompleted(const ScreenCaptureResults& captureResults) override {
        resultsPromise.set_value(captureResults);
        return binder::Status::ok();
    }

    ScreenCaptureResults waitForResults() {
        std::future<ScreenCaptureResults> resultsFuture = resultsPromise.get_future();
        return resultsFuture.get();
        const auto screenCaptureResults = resultsFuture.get();
        screenCaptureResults.fence->waitForever("");
        return screenCaptureResults;
    }

private:
+8 −13
Original line number Diff line number Diff line
@@ -5851,23 +5851,18 @@ status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture,
        if (!renderArea) {
            ALOGW("Skipping screen capture because of invalid render area.");
            captureResults.result = NO_MEMORY;
            captureListener->onScreenCaptureComplete(captureResults);
            captureListener->onScreenCaptureCompleted(captureResults);
            return;
        }

        status_t result = NO_ERROR;
        int syncFd = -1;
        renderArea->render([&] {
            result = renderScreenImplLocked(*renderArea, traverseLayers, buffer, forSystem, &syncFd,
            result = renderScreenImplLocked(*renderArea, traverseLayers, buffer, forSystem,
                                            regionSampling, captureResults);
        });

        if (result == NO_ERROR) {
            sync_wait(syncFd, -1);
            close(syncFd);
        }
        captureResults.result = result;
        captureListener->onScreenCaptureComplete(captureResults);
        captureListener->onScreenCaptureCompleted(captureResults);
    }));

    return NO_ERROR;
@@ -5876,7 +5871,7 @@ status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture,
status_t SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
                                                TraverseLayersFunction traverseLayers,
                                                const sp<GraphicBuffer>& buffer, bool forSystem,
                                                int* outSyncFd, bool regionSampling,
                                                bool regionSampling,
                                                ScreenCaptureResults& captureResults) {
    ATRACE_CALL();

@@ -5985,14 +5980,14 @@ status_t SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
    getRenderEngine().drawLayers(clientCompositionDisplay, clientCompositionLayerPointers, buffer,
                                 /*useFramebufferCache=*/false, std::move(bufferFence), &drawFence);

    *outSyncFd = drawFence.release();

    if (*outSyncFd >= 0) {
        sp<Fence> releaseFence = new Fence(dup(*outSyncFd));
    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);

Loading