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

Commit e18703ad authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "In Vk DeferredLayerUpdater make sure we releause buffers to foreign...

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

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14735288

Change-Id: Iead74d38b9acbec8184f247cf7d6a5663186b450
parents f06c2d8e 433ba6df
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;
};