summaryrefslogtreecommitdiff
path: root/stream-servers/vulkan/VkAndroidNativeBuffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'stream-servers/vulkan/VkAndroidNativeBuffer.cpp')
-rw-r--r--stream-servers/vulkan/VkAndroidNativeBuffer.cpp120
1 files changed, 114 insertions, 6 deletions
diff --git a/stream-servers/vulkan/VkAndroidNativeBuffer.cpp b/stream-servers/vulkan/VkAndroidNativeBuffer.cpp
index 7cbfb5a2..a47bb4d0 100644
--- a/stream-servers/vulkan/VkAndroidNativeBuffer.cpp
+++ b/stream-servers/vulkan/VkAndroidNativeBuffer.cpp
@@ -19,13 +19,61 @@
#include "GrallocDefs.h"
#include "VkCommonOperations.h"
#include "VulkanDispatch.h"
+#include "SyncThread.h"
#include <string.h>
#define VK_ANB_ERR(fmt,...) fprintf(stderr, "%s:%d " fmt "\n", __func__, __LINE__, ##__VA_ARGS__);
+#define VK_ANB_DEBUG 0
+
+#if VK_ANB_DEBUG
+#define VK_ANB_DEBUG(fmt,...) fprintf(stderr, "vk-anb-debug: %s:%d " fmt "\n", __func__, __LINE__, ##__VA_ARGS__);
+#define VK_ANB_DEBUG_OBJ(obj, fmt,...) fprintf(stderr, "vk-anb-debug: %s:%d:%p " fmt "\n", __func__, __LINE__, obj, ##__VA_ARGS__);
+#else
+#define VK_ANB_DEBUG(fmt,...)
+#define VK_ANB_DEBUG_OBJ(obj, fmt,...)
+#endif
+
+using android::base::AutoLock;
+using android::base::Lock;
+
namespace goldfish_vk {
+VkFence AndroidNativeBufferInfo::QsriWaitInfo::getFenceFromPoolLocked() {
+ VK_ANB_DEBUG("enter");
+
+ if (!vk) return VK_NULL_HANDLE;
+
+ if (fencePool.empty()) {
+ VkFence fence;
+ VkFenceCreateInfo fenceCreateInfo = {
+ VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, 0, 0,
+ };
+ vk->vkCreateFence(device, &fenceCreateInfo, nullptr, &fence);
+ VK_ANB_DEBUG("no fences in pool, created %p", fence);
+ return fence;
+ } else {
+ VkFence res = fencePool.back();
+ fencePool.pop_back();
+ vk->vkResetFences(device, 1, &res);
+ VK_ANB_DEBUG("existing fence in pool: %p. also reset the fence", res);
+ return res;
+ }
+}
+
+AndroidNativeBufferInfo::QsriWaitInfo::~QsriWaitInfo() {
+ VK_ANB_DEBUG("enter");
+ if (!vk) return;
+ if (!device) return;
+ // Nothing in the fence pool is unsignaled
+ for (auto fence : fencePool) {
+ VK_ANB_DEBUG("destroy fence %p", fence);
+ vk->vkDestroyFence(device, fence, nullptr);
+ }
+ VK_ANB_DEBUG("exit");
+}
+
bool parseAndroidNativeBufferInfo(
const VkImageCreateInfo* pCreateInfo,
AndroidNativeBufferInfo* info_out) {
@@ -48,8 +96,7 @@ VkResult prepareAndroidNativeBufferImage(
const VkPhysicalDeviceMemoryProperties* memProps,
AndroidNativeBufferInfo* out) {
- *out = {};
-
+ out->vk = vk;
out->device = device;
out->vkFormat = pCreateInfo->format;
out->extent = pCreateInfo->extent;
@@ -273,11 +320,22 @@ void teardownAndroidNativeBufferImage(
for (auto queueState : anbInfo->queueStates) {
queueState.teardown(vk, device);
}
+
anbInfo->queueStates.clear();
anbInfo->acquireQueueState.teardown(vk, device);
- *anbInfo = {};
+ anbInfo->vk = nullptr;
+ anbInfo->device = VK_NULL_HANDLE;
+ anbInfo->image = VK_NULL_HANDLE;
+ anbInfo->imageMemory = VK_NULL_HANDLE;
+ anbInfo->stagingBuffer = VK_NULL_HANDLE;
+ anbInfo->mappedStagingPtr = nullptr;
+ anbInfo->stagingMemory = VK_NULL_HANDLE;
+
+ AutoLock lock(anbInfo->qsriWaitInfo.lock);
+ anbInfo->qsriWaitInfo.presentCount = 0;
+ anbInfo->qsriWaitInfo.requestedPresentCount = 0;
}
void getGralloc0Usage(VkFormat format, VkImageUsageFlags imageUsage,
@@ -505,6 +563,8 @@ VkResult setAndroidNativeImageSemaphoreSignaled(
return VK_SUCCESS;
}
+static constexpr uint64_t kTimeoutNs = 3ULL * 1000000000ULL;
+
VkResult syncImageToColorBuffer(
VulkanDispatch* vk,
uint32_t queueFamilyIndex,
@@ -512,7 +572,14 @@ VkResult syncImageToColorBuffer(
uint32_t waitSemaphoreCount,
const VkSemaphore* pWaitSemaphores,
int* pNativeFenceFd,
- AndroidNativeBufferInfo* anbInfo) {
+ std::shared_ptr<AndroidNativeBufferInfo> anbInfo) {
+
+ auto anbInfoPtr = anbInfo.get();
+ {
+ AutoLock lock(anbInfo->qsriWaitInfo.lock);
+ VK_ANB_DEBUG_OBJ(anbInfoPtr, "ensure dispatch %p device %p", vk, anbInfo->device);
+ anbInfo->qsriWaitInfo.ensureDispatchAndDevice(vk, anbInfo->device);
+ }
auto fb = FrameBuffer::getFB();
fb->lock();
@@ -662,13 +729,46 @@ VkResult syncImageToColorBuffer(
};
// TODO(kaiyili): initiate ownership transfer to DisplayVk here.
- vk->vkQueueSubmit(queueState.queue, 1, &submitInfo, VK_NULL_HANDLE);
-
+ VkFence qsriFence = VK_NULL_HANDLE;
+ {
+ VK_ANB_DEBUG_OBJ(anbInfoPtr, "trying to get qsri fence");
+ AutoLock lock(anbInfo->qsriWaitInfo.lock);
+ VK_ANB_DEBUG_OBJ(anbInfoPtr, "trying to get qsri fence (got lock)");
+ qsriFence = anbInfo->qsriWaitInfo.getFenceFromPoolLocked();
+ VK_ANB_DEBUG_OBJ(anbInfoPtr, "got qsri fence %p", qsriFence);
+ }
+ vk->vkQueueSubmit(queueState.queue, 1, &submitInfo, qsriFence);
fb->unlock();
if (anbInfo->useVulkanNativeImage) {
+ VK_ANB_DEBUG_OBJ(anbInfoPtr, "using native image, so use sync thread to wait");
fb->setColorBufferInUse(anbInfo->colorBufferHandle, false);
+ VkDevice device = anbInfo->device;
+ // Queue wait to sync thread with completion callback
+ // Pass anbInfo by value to get a ref
+ SyncThread::get()->triggerGeneral([anbInfoPtr, anbInfo, vk, device, qsriFence] {
+ VK_ANB_DEBUG_OBJ(anbInfoPtr, "wait callback: enter");
+ if (qsriFence) {
+ VK_ANB_DEBUG_OBJ(anbInfoPtr, "wait callback: wait for fence %p...", qsriFence);
+ vk->vkWaitForFences(device, 1, &qsriFence, VK_FALSE, kTimeoutNs);
+ VK_ANB_DEBUG_OBJ(anbInfoPtr, "wait callback: wait for fence %p...(done)", qsriFence);
+ }
+ AutoLock lock(anbInfo->qsriWaitInfo.lock);
+ VK_ANB_DEBUG_OBJ(anbInfoPtr, "wait callback: return fence and signal");
+ if (qsriFence) {
+ anbInfo->qsriWaitInfo.returnFenceLocked(qsriFence);
+ }
+ ++anbInfo->qsriWaitInfo.presentCount;
+ VK_ANB_DEBUG_OBJ(anbInfoPtr, "wait callback: done, present count is now %llu", (unsigned long long)anbInfo->qsriWaitInfo.presentCount);
+ anbInfo->qsriWaitInfo.cv.signal();
+ VK_ANB_DEBUG_OBJ(anbInfoPtr, "wait callback: exit");
+ });
} else {
+ VK_ANB_DEBUG_OBJ(anbInfoPtr, "not using native image, so wait right away");
+ if (qsriFence) {
+ vk->vkWaitForFences(anbInfo->device, 1, &qsriFence, VK_FALSE, kTimeoutNs);
+ }
+
VkMappedMemoryRange toInvalidate = {
VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0,
anbInfo->stagingMemory,
@@ -701,6 +801,14 @@ VkResult syncImageToColorBuffer(
colorBufferHandle,
anbInfo->mappedStagingPtr,
bpp * anbInfo->extent.width * anbInfo->extent.height);
+
+ AutoLock lock(anbInfo->qsriWaitInfo.lock);
+ ++anbInfo->qsriWaitInfo.presentCount;
+ VK_ANB_DEBUG_OBJ(anbInfoPtr, "done, present count is now %llu", (unsigned long long)anbInfo->qsriWaitInfo.presentCount);
+ anbInfo->qsriWaitInfo.cv.signal();
+ if (qsriFence) {
+ anbInfo->qsriWaitInfo.returnFenceLocked(qsriFence);
+ }
}
return VK_SUCCESS;