diff options
author | 2021-05-26 09:24:15 -0400 | |
---|---|---|
committer | 2021-05-26 13:38:33 -0400 | |
commit | 27e1fa257b9c538c53bcfbf30f6fc1833342b055 (patch) | |
tree | ae6edc7988ac53b50f696860fe88217811166241 | |
parent | 2869d5a8c8def75ed6287cbf8b1514499fd2adc8 (diff) |
In Vk DeferredLayerUpdater make sure we releause buffers to foreign queue.
For Vulkan we need to make sure that when we draw AHBs we must
transition them to and from the foreign queue so that the producer is
able to write new data to them and we are able to see the new writes.
Test: Manual running of Lens app
Bug: 178773035
Change-Id: I807709d2b671bf5a01a82237f3b5838734f0d978
-rw-r--r-- | libs/hwui/AutoBackendTextureRelease.cpp | 22 | ||||
-rw-r--r-- | libs/hwui/AutoBackendTextureRelease.h | 2 | ||||
-rw-r--r-- | libs/hwui/DeferredLayerUpdater.cpp | 50 | ||||
-rw-r--r-- | libs/hwui/DeferredLayerUpdater.h | 17 |
4 files changed, 74 insertions, 17 deletions
diff --git a/libs/hwui/AutoBackendTextureRelease.cpp b/libs/hwui/AutoBackendTextureRelease.cpp index 33264d5d5c86..ef5eacbdb4ad 100644 --- a/libs/hwui/AutoBackendTextureRelease.cpp +++ b/libs/hwui/AutoBackendTextureRelease.cpp @@ -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 */ diff --git a/libs/hwui/AutoBackendTextureRelease.h b/libs/hwui/AutoBackendTextureRelease.h index 06f51fcd1105..c9bb767a3185 100644 --- a/libs/hwui/AutoBackendTextureRelease.h +++ b/libs/hwui/AutoBackendTextureRelease.h @@ -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() {} diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp index 6589dbd50cf7..8d112d1c64bf 100644 --- a/libs/hwui/DeferredLayerUpdater.cpp +++ b/libs/hwui/DeferredLayerUpdater.cpp @@ -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 */ diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h index 6731e9c428d6..8f79c4ec97b8 100644 --- a/libs/hwui/DeferredLayerUpdater.h +++ b/libs/hwui/DeferredLayerUpdater.h @@ -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; }; |