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

Commit 433ba6df authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "In Vk DeferredLayerUpdater make sure we releause buffers to foreign queue." into sc-dev

parents 6addf585 27e1fa25
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -89,5 +89,27 @@ void AutoBackendTextureRelease::newBufferContent(GrDirectContext* context) {
    }
}

void AutoBackendTextureRelease::releaseQueueOwnership(GrDirectContext* context) {
    if (!context) {
        return;
    }

    LOG_ALWAYS_FATAL_IF(Properties::getRenderPipelineType() != RenderPipelineType::SkiaVulkan);
    if (mBackendTexture.isValid()) {
        // Passing in VK_IMAGE_LAYOUT_UNDEFINED means we keep the old layout.
        GrBackendSurfaceMutableState newState(VK_IMAGE_LAYOUT_UNDEFINED,
                                              VK_QUEUE_FAMILY_FOREIGN_EXT);

        // The unref for this ref happens in the releaseProc passed into setBackendTextureState. The
        // releaseProc callback will be made when the work to set the new state has finished on the
        // gpu.
        ref();
        // Note that we don't have an explicit call to set the backend texture back onto the
        // graphics queue when we use the VkImage again. Internally, Skia will notice that the image
        // is not on the graphics queue and will do the transition automatically.
        context->setBackendTextureState(mBackendTexture, newState, nullptr, releaseProc, this);
    }
}

} /* namespace uirenderer */
} /* namespace android */
+2 −0
Original line number Diff line number Diff line
@@ -49,6 +49,8 @@ public:

    void newBufferContent(GrDirectContext* context);

    void releaseQueueOwnership(GrDirectContext* context);

private:
    // The only way to invoke dtor is with unref, when mUsageCount is 0.
    ~AutoBackendTextureRelease() {}
+36 −14
Original line number Diff line number Diff line
@@ -76,6 +76,9 @@ void DeferredLayerUpdater::destroyLayer() {

    mLayer = nullptr;

    for (auto& [index, slot] : mImageSlots) {
        slot.clear(mRenderState.getRenderThread().getGrContext());
    }
    mImageSlots.clear();
}

@@ -89,31 +92,39 @@ void DeferredLayerUpdater::setPaint(const SkPaint* paint) {
    }
}

static status_t createReleaseFence(bool useFenceSync, EGLSyncKHR* eglFence, EGLDisplay* display,
                                   int* releaseFence, void* handle) {
status_t DeferredLayerUpdater::createReleaseFence(bool useFenceSync, EGLSyncKHR* eglFence,
                                                  EGLDisplay* display, int* releaseFence,
                                                  void* handle) {
    *display = EGL_NO_DISPLAY;
    RenderState* renderState = (RenderState*)handle;
    DeferredLayerUpdater* dlu = (DeferredLayerUpdater*)handle;
    RenderState& renderState = dlu->mRenderState;
    status_t err;
    if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
        EglManager& eglManager = renderState->getRenderThread().eglManager();
        EglManager& eglManager = renderState.getRenderThread().eglManager();
        *display = eglManager.eglDisplay();
        err = eglManager.createReleaseFence(useFenceSync, eglFence, releaseFence);
    } else {
        err = renderState->getRenderThread().vulkanManager().createReleaseFence(
                releaseFence, renderState->getRenderThread().getGrContext());
        int previousSlot = dlu->mCurrentSlot;
        if (previousSlot != -1) {
            dlu->mImageSlots[previousSlot].releaseQueueOwnership(
                    renderState.getRenderThread().getGrContext());
        }
        err = renderState.getRenderThread().vulkanManager().createReleaseFence(
                releaseFence, renderState.getRenderThread().getGrContext());
    }
    return err;
}

static status_t fenceWait(int fence, void* handle) {
status_t DeferredLayerUpdater::fenceWait(int fence, void* handle) {
    // Wait on the producer fence for the buffer to be ready.
    status_t err;
    RenderState* renderState = (RenderState*)handle;
    DeferredLayerUpdater* dlu = (DeferredLayerUpdater*)handle;
    RenderState& renderState = dlu->mRenderState;
    if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
        err = renderState->getRenderThread().eglManager().fenceWait(fence);
        err = renderState.getRenderThread().eglManager().fenceWait(fence);
    } else {
        err = renderState->getRenderThread().vulkanManager().fenceWait(
                fence, renderState->getRenderThread().getGrContext());
        err = renderState.getRenderThread().vulkanManager().fenceWait(
                fence, renderState.getRenderThread().getGrContext());
    }
    return err;
}
@@ -143,9 +154,10 @@ void DeferredLayerUpdater::apply() {
            // cannot tell which mode it is in.
            AHardwareBuffer* hardwareBuffer = ASurfaceTexture_dequeueBuffer(
                    mSurfaceTexture.get(), &slot, &dataspace, transformMatrix, &newContent,
                    createReleaseFence, fenceWait, &mRenderState);
                    createReleaseFence, fenceWait, this);

            if (hardwareBuffer) {
                mCurrentSlot = slot;
                sk_sp<SkImage> layerImage = mImageSlots[slot].createIfNeeded(
                        hardwareBuffer, dataspace, newContent,
                        mRenderState.getRenderThread().getGrContext());
@@ -193,7 +205,7 @@ sk_sp<SkImage> DeferredLayerUpdater::ImageSlot::createIfNeeded(AHardwareBuffer*
    if (!mTextureRelease || !mTextureRelease->getImage().get() || dataspace != mDataspace ||
        forceCreate || mBuffer != buffer) {
        if (buffer != mBuffer) {
            clear();
            clear(context);
        }

        if (!buffer) {
@@ -213,8 +225,11 @@ sk_sp<SkImage> DeferredLayerUpdater::ImageSlot::createIfNeeded(AHardwareBuffer*
    return mTextureRelease ? mTextureRelease->getImage() : nullptr;
}

void DeferredLayerUpdater::ImageSlot::clear() {
void DeferredLayerUpdater::ImageSlot::clear(GrDirectContext* context) {
    if (mTextureRelease) {
        if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
            this->releaseQueueOwnership(context);
        }
        // The following unref counteracts the initial mUsageCount of 1, set by default initializer.
        mTextureRelease->unref(true);
        mTextureRelease = nullptr;
@@ -223,5 +238,12 @@ void DeferredLayerUpdater::ImageSlot::clear() {
    mBuffer = nullptr;
}

void DeferredLayerUpdater::ImageSlot::releaseQueueOwnership(GrDirectContext* context) {
    LOG_ALWAYS_FATAL_IF(Properties::getRenderPipelineType() != RenderPipelineType::SkiaVulkan);
    if (mTextureRelease) {
        mTextureRelease->releaseQueueOwnership(context);
    }
}

} /* namespace uirenderer */
} /* namespace android */
+14 −3
Original line number Diff line number Diff line
@@ -20,9 +20,12 @@
#include <SkImage.h>
#include <SkMatrix.h>
#include <android/hardware_buffer.h>
#include <cutils/compiler.h>
#include <android/surface_texture.h>
#include <cutils/compiler.h>
#include <utils/Errors.h>

#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <map>
#include <memory>

@@ -103,13 +106,16 @@ private:
     */
    class ImageSlot {
    public:
        ~ImageSlot() { clear(); }
        ~ImageSlot() {}

        sk_sp<SkImage> createIfNeeded(AHardwareBuffer* buffer, android_dataspace dataspace,
                                      bool forceCreate, GrDirectContext* context);

        void releaseQueueOwnership(GrDirectContext* context);

        void clear(GrDirectContext* context);

    private:
        void clear();

        // the dataspace associated with the current image
        android_dataspace mDataspace = HAL_DATASPACE_UNKNOWN;
@@ -123,6 +129,10 @@ private:
        AutoBackendTextureRelease* mTextureRelease = nullptr;
    };

    static status_t createReleaseFence(bool useFenceSync, EGLSyncKHR* eglFence, EGLDisplay* display,
                                       int* releaseFence, void* handle);
    static status_t fenceWait(int fence, void* handle);

    /**
     * DeferredLayerUpdater stores the SkImages that have been allocated by the BufferQueue
     * for each buffer slot.
@@ -142,6 +152,7 @@ private:
    SkMatrix* mTransform;
    bool mGLContextAttached;
    bool mUpdateTexImage;
    int mCurrentSlot = -1;

    Layer* mLayer;
};