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

Commit 3a7e8441 authored by Derek Sollenberger's avatar Derek Sollenberger Committed by Android (Google) Code Review
Browse files

Merge "Add support for latching unsignaled buffers in Skia RenderEngine."

parents 27a08532 4ee7b493
Loading
Loading
Loading
Loading
+25 −10
Original line number Diff line number Diff line
@@ -424,14 +424,28 @@ base::unique_fd SkiaGLRenderEngine::flush() {
    return fenceFd;
}

bool SkiaGLRenderEngine::waitFence(base::unique_fd fenceFd) {
void SkiaGLRenderEngine::waitFence(base::borrowed_fd fenceFd) {
    if (fenceFd.get() >= 0 && !waitGpuFence(fenceFd)) {
        ATRACE_NAME("SkiaGLRenderEngine::waitFence");
        sync_wait(fenceFd.get(), -1);
    }
}

bool SkiaGLRenderEngine::waitGpuFence(base::borrowed_fd fenceFd) {
    if (!gl::GLExtensions::getInstance().hasNativeFenceSync() ||
        !gl::GLExtensions::getInstance().hasWaitSync()) {
        return false;
    }

    // Duplicate the fence for passing to eglCreateSyncKHR.
    base::unique_fd fenceDup(dup(fenceFd.get()));
    if (fenceDup.get() < 0) {
        ALOGE("failed to create duplicate fence fd: %d", fenceDup.get());
        return false;
    }

    // release the fd and transfer the ownership to EGLSync
    EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceFd.release(), EGL_NONE};
    EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceDup.release(), EGL_NONE};
    EGLSyncKHR sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
    if (sync == EGL_NO_SYNC_KHR) {
        ALOGE("failed to create EGL native fence sync: %#x", eglGetError());
@@ -727,14 +741,6 @@ void SkiaGLRenderEngine::drawLayersInternal(
        return;
    }

    if (bufferFence.get() >= 0) {
        // Duplicate the fence for passing to waitFence.
        base::unique_fd bufferFenceDup(dup(bufferFence.get()));
        if (bufferFenceDup < 0 || !waitFence(std::move(bufferFenceDup))) {
            ATRACE_NAME("Waiting before draw");
            sync_wait(bufferFence.get(), -1);
        }
    }
    if (buffer == nullptr) {
        ALOGE("No output buffer provided. Aborting GPU composition.");
        resultPromise->set_value({BAD_VALUE, base::unique_fd()});
@@ -760,6 +766,9 @@ void SkiaGLRenderEngine::drawLayersInternal(
                                                               true, mTextureCleanupMgr);
    }

    // wait on the buffer to be ready to use prior to using it
    waitFence(bufferFence);

    const ui::Dataspace dstDataspace =
            mUseColorManagement ? display.outputDataspace : ui::Dataspace::V0_SRGB_LINEAR;
    sk_sp<SkSurface> dstSurface = surfaceTextureRef->getOrCreateSurface(dstDataspace, grContext);
@@ -995,6 +1004,12 @@ void SkiaGLRenderEngine::drawLayersInternal(
                                                      false, mTextureCleanupMgr);
            }

            // if the layer's buffer has a fence, then we must must respect the fence prior to using
            // the buffer.
            if (layer->source.buffer.fence != nullptr) {
                waitFence(layer->source.buffer.fence->get());
            }

            // isOpaque means we need to ignore the alpha in the image,
            // replacing it with the alpha specified by the LayerSettings. See
            // https://developer.android.com/reference/android/view/SurfaceControl.Builder#setOpaque(boolean)
+4 −1
Original line number Diff line number Diff line
@@ -99,7 +99,10 @@ private:
    inline GrDirectContext* getActiveGrContext() const;

    base::unique_fd flush();
    bool waitFence(base::unique_fd fenceFd);
    // waitFence attempts to wait in the GPU, and if unable to waits on the CPU instead.
    void waitFence(base::borrowed_fd fenceFd);
    bool waitGpuFence(base::borrowed_fd fenceFd);

    void initCanvas(SkCanvas* canvas, const DisplaySettings& display);
    void drawShadow(SkCanvas* canvas, const SkRRect& casterRRect,
                    const ShadowSettings& shadowSettings);