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

Commit b0c041b6 authored by Chia-I Wu's avatar Chia-I Wu
Browse files

surfaceflinger: return fence fd from RenderEngine::flush

The caller does not need to work with EGLSync after this chnage.

Test: SurfaceFlinger_test
Change-Id: I1cf7d11d3023d09be8a73001493c39b4309e7542
parent 7f40290b
Loading
Loading
Loading
Loading
+45 −2
Original line number Diff line number Diff line
@@ -247,8 +247,51 @@ void RenderEngine::fillRegionWithColor(const Region& region, uint32_t height,
    drawMesh(mesh);
}

void RenderEngine::flush() {
int RenderEngine::flush(bool wait) {
    // Attempt to create a sync khr object that can produce a sync point. If that
    // isn't available, create a non-dupable sync object in the fallback path and
    // wait on it directly.
    EGLSyncKHR sync;
    if (!wait) {
        EGLint syncFd = EGL_NO_NATIVE_FENCE_FD_ANDROID;

        sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
        if (sync != EGL_NO_SYNC_KHR) {
            // native fence fd will not be populated until flush() is done.
            glFlush();

            // get the sync fd
            syncFd = eglDupNativeFenceFDANDROID(mEGLDisplay, sync);
            if (syncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
                ALOGW("failed to dup sync khr object");
            }

            eglDestroySyncKHR(mEGLDisplay, sync);
        }

        if (syncFd != EGL_NO_NATIVE_FENCE_FD_ANDROID) {
            return syncFd;
        }
    }

    // fallback or explicit wait
    sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL);
    if (sync != EGL_NO_SYNC_KHR) {
        EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync,
                EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/);
        EGLint eglErr = eglGetError();
        if (result == EGL_TIMEOUT_EXPIRED_KHR) {
            ALOGW("fence wait timed out");
        } else {
            ALOGW_IF(eglErr != EGL_SUCCESS,
                    "error waiting on EGL fence: %#x", eglErr);
        }
        eglDestroySyncKHR(mEGLDisplay, sync);
    } else {
        ALOGW("error creating EGL fence: %#x", eglGetError());
    }

    return -1;
}

void RenderEngine::clearWithColor(float red, float green, float blue, float alpha) {
+2 −1
Original line number Diff line number Diff line
@@ -77,7 +77,8 @@ public:
    virtual void dump(String8& result);

    // helpers
    void flush();
    // flush returns -1 or a valid native fence fd owned by the caller
    int flush(bool wait);
    void clearWithColor(float red, float green, float blue, float alpha);
    void fillRegionWithColor(const Region& region, uint32_t height,
            float red, float green, float blue, float alpha);
+1 −38
Original line number Diff line number Diff line
@@ -4584,7 +4584,6 @@ status_t SurfaceFlinger::captureScreenImplLocked(const RenderArea& renderArea,
        return PERMISSION_DENIED;
    }

    int syncFd = -1;
    // create an EGLImage from the buffer so we can later
    // turn it into a texture
    EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT,
@@ -4610,43 +4609,7 @@ status_t SurfaceFlinger::captureScreenImplLocked(const RenderArea& renderArea,
    // dependent on the context's EGLConfig.
    renderScreenImplLocked(renderArea, traverseLayers, true, useIdentityTransform);

    // Attempt to create a sync khr object that can produce a sync point. If that
    // isn't available, create a non-dupable sync object in the fallback path and
    // wait on it directly.
    EGLSyncKHR sync = EGL_NO_SYNC_KHR;
    if (!DEBUG_SCREENSHOTS) {
       sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
       // native fence fd will not be populated until flush() is done.
       getRenderEngine().flush();
    }

    if (sync != EGL_NO_SYNC_KHR) {
        // get the sync fd
        syncFd = eglDupNativeFenceFDANDROID(mEGLDisplay, sync);
        if (syncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
            ALOGW("captureScreen: failed to dup sync khr object");
            syncFd = -1;
        }
        eglDestroySyncKHR(mEGLDisplay, sync);
    } else {
        // fallback path
        sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL);
        if (sync != EGL_NO_SYNC_KHR) {
            EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync,
                EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/);
            EGLint eglErr = eglGetError();
            if (result == EGL_TIMEOUT_EXPIRED_KHR) {
                ALOGW("captureScreen: fence wait timed out");
            } else {
                ALOGW_IF(eglErr != EGL_SUCCESS,
                        "captureScreen: error waiting on EGL fence: %#x", eglErr);
            }
            eglDestroySyncKHR(mEGLDisplay, sync);
        } else {
            ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError());
        }
    }
    *outSyncFd = syncFd;
    *outSyncFd = getRenderEngine().flush(DEBUG_SCREENSHOTS);

    if (DEBUG_SCREENSHOTS) {
        const auto reqWidth = renderArea.getReqWidth();