Loading libs/hwui/AutoBackendTextureRelease.cpp +22 −0 Original line number Diff line number Diff line Loading @@ -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 */ libs/hwui/AutoBackendTextureRelease.h +2 −0 Original line number Diff line number Diff line Loading @@ -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() {} Loading libs/hwui/DeferredLayerUpdater.cpp +36 −14 Original line number Diff line number Diff line Loading @@ -76,6 +76,9 @@ void DeferredLayerUpdater::destroyLayer() { mLayer = nullptr; for (auto& [index, slot] : mImageSlots) { slot.clear(mRenderState.getRenderThread().getGrContext()); } mImageSlots.clear(); } Loading @@ -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; } Loading Loading @@ -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()); Loading Loading @@ -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) { Loading @@ -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; Loading @@ -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 */ libs/hwui/DeferredLayerUpdater.h +14 −3 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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; Loading @@ -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. Loading @@ -142,6 +152,7 @@ private: SkMatrix* mTransform; bool mGLContextAttached; bool mUpdateTexImage; int mCurrentSlot = -1; Layer* mLayer; }; Loading Loading
libs/hwui/AutoBackendTextureRelease.cpp +22 −0 Original line number Diff line number Diff line Loading @@ -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 */
libs/hwui/AutoBackendTextureRelease.h +2 −0 Original line number Diff line number Diff line Loading @@ -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() {} Loading
libs/hwui/DeferredLayerUpdater.cpp +36 −14 Original line number Diff line number Diff line Loading @@ -76,6 +76,9 @@ void DeferredLayerUpdater::destroyLayer() { mLayer = nullptr; for (auto& [index, slot] : mImageSlots) { slot.clear(mRenderState.getRenderThread().getGrContext()); } mImageSlots.clear(); } Loading @@ -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; } Loading Loading @@ -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()); Loading Loading @@ -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) { Loading @@ -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; Loading @@ -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 */
libs/hwui/DeferredLayerUpdater.h +14 −3 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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; Loading @@ -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. Loading @@ -142,6 +152,7 @@ private: SkMatrix* mTransform; bool mGLContextAttached; bool mUpdateTexImage; int mCurrentSlot = -1; Layer* mLayer; }; Loading