Merge "In Vk DeferredLayerUpdater make sure we releause buffers to foreign queue." into sc-dev
diff --git a/libs/hwui/AutoBackendTextureRelease.cpp b/libs/hwui/AutoBackendTextureRelease.cpp
index 33264d5..ef5eacb 100644
--- a/libs/hwui/AutoBackendTextureRelease.cpp
+++ b/libs/hwui/AutoBackendTextureRelease.cpp
@@ -89,5 +89,27 @@
}
}
+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 06f51fc..c9bb767 100644
--- a/libs/hwui/AutoBackendTextureRelease.h
+++ b/libs/hwui/AutoBackendTextureRelease.h
@@ -49,6 +49,8 @@
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 6589dbd..8d112d1 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -76,6 +76,9 @@
mLayer = nullptr;
+ for (auto& [index, slot] : mImageSlots) {
+ slot.clear(mRenderState.getRenderThread().getGrContext());
+ }
mImageSlots.clear();
}
@@ -89,31 +92,39 @@
}
}
-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 @@
// 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 @@
if (!mTextureRelease || !mTextureRelease->getImage().get() || dataspace != mDataspace ||
forceCreate || mBuffer != buffer) {
if (buffer != mBuffer) {
- clear();
+ clear(context);
}
if (!buffer) {
@@ -213,8 +225,11 @@
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 @@
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 6731e9c..8f79c4e 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 @@
*/
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 @@
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 @@
SkMatrix* mTransform;
bool mGLContextAttached;
bool mUpdateTexImage;
+ int mCurrentSlot = -1;
Layer* mLayer;
};