From 8270b2873eecfcd18d1f851fe799fb4689de8bf5 Mon Sep 17 00:00:00 2001 From: Lingfeng Yang Date: Fri, 23 Apr 2021 14:49:25 -0700 Subject: Native VK Swapchain: rcCompose support (basic) Basic support for rcCompose. Change-Id: Ib1396654311d97b3bb02620785cf9d2ba958bb40 --- stream-servers/ColorBuffer.cpp | 2 + stream-servers/CompositorVk.cpp | 251 ++++++++++++++++++------ stream-servers/CompositorVk.h | 32 ++- stream-servers/DisplayVk.cpp | 104 +++++++++- stream-servers/DisplayVk.h | 7 +- stream-servers/FrameBuffer.cpp | 55 +++++- stream-servers/FrameBuffer.h | 36 +--- stream-servers/PostCommands.h | 40 ++++ stream-servers/vulkan/Compositor.vert | 9 +- stream-servers/vulkan/CompositorVertexShader.h | 101 ++++++---- stream-servers/vulkan/VkAndroidNativeBuffer.cpp | 5 +- 11 files changed, 474 insertions(+), 168 deletions(-) create mode 100644 stream-servers/PostCommands.h diff --git a/stream-servers/ColorBuffer.cpp b/stream-servers/ColorBuffer.cpp index b36c8710..a01002f6 100644 --- a/stream-servers/ColorBuffer.cpp +++ b/stream-servers/ColorBuffer.cpp @@ -21,6 +21,8 @@ #include "TextureDraw.h" #include "TextureResize.h" #include "YUVConverter.h" +#include "vulkan/VulkanDispatch.h" +#include "vulkan/VkCommonOperations.h" #include "OpenGLESDispatch/DispatchTables.h" #include "OpenGLESDispatch/EGLDispatch.h" diff --git a/stream-servers/CompositorVk.cpp b/stream-servers/CompositorVk.cpp index 7be39256..385e62a3 100644 --- a/stream-servers/CompositorVk.cpp +++ b/stream-servers/CompositorVk.cpp @@ -2,7 +2,7 @@ #include -#include +#include #include #include "vulkan/vk_util.h" @@ -24,13 +24,123 @@ static VkShaderModule createShaderModule(const goldfish_vk::VulkanDispatch &vk, return res; } -Composition::Composition(VkImageView vkImageView, VkSampler vkSampler, - uint32_t width, uint32_t height) - : m_vkImageView(vkImageView), - m_vkSampler(vkSampler), +Composition::Composition(VkSampler vkSampler, uint32_t width, uint32_t height, + const std::vector& composeLayers) + : m_vkSampler(vkSampler), m_width(width), m_height(height), - m_transform(1.0f) {} + m_composeLayers(composeLayers) { + setTransforms(); +} + +Composition::Composition(VkImageView vkImageView, VkSampler vkSampler, uint32_t width, uint32_t height) + : m_vkSampler(vkSampler), + m_width(width), + m_height(height) { + + ComposeLayerVk composeLayer; + composeLayer.imageView = vkImageView; + composeLayer.layerInfo = + (ComposeLayer){ + 0, + HWC2_COMPOSITION_DEVICE, + { 0, 0, static_cast(width), static_cast(height) }, + { 0.0f, 0.0f, (float)width, (float)height }, + HWC2_BLEND_MODE_PREMULTIPLIED, + 1.0f, + { 0, 0, 0, 0}, + (hwc_transform_t)0 /* transform */ + }; + std::vector composeLayers = { + composeLayer, + }; + + m_composeLayers = composeLayers; + setTransforms(); +} + +void Composition::setTransforms() { + float pos_scaleX; + float pos_scaleY; + float pos_trX; + float pos_trY; + + float texcoord_scaleX; + float texcoord_scaleY; + float texcoord_trX; + float texcoord_trY; + + float dst_width = (float)m_width; + float dst_height = (float)m_height; + + uint32_t i = 0; + + for (const auto& info : m_composeLayers) { + uint32_t cbWidth = info.cbWidth; + uint32_t cbHeight = info.cbHeight; + const auto& li = info.layerInfo; + const auto& pos_rect = li.displayFrame; + const auto& texcoord_rect = li.crop; + + int pos_width = pos_rect.right - pos_rect.left; + int pos_height = pos_rect.bottom - pos_rect.top; + + pos_scaleX = float(pos_width) / dst_width; + pos_scaleY = float(pos_height) / dst_height; + + pos_trX = -1.0f + pos_scaleX + 2.0f * float(pos_rect.left) / dst_width; + pos_trY = -1.0f + pos_scaleY + 2.0f * float(pos_rect.top) / dst_height; + + texcoord_scaleX = (texcoord_rect.right - texcoord_rect.left) / float(cbWidth); + texcoord_scaleY = (texcoord_rect.bottom - texcoord_rect.top) / float(cbHeight); + + texcoord_trX = texcoord_rect.left / float(cbWidth); + texcoord_trY = texcoord_rect.top / float(cbHeight); + + float texcoord_rot = 0.0f; + + const float pi = 3.14159265358979324f; + + switch (li.transform) { + case HWC_TRANSFORM_ROT_90: + texcoord_rot = pi * 0.5f; + break; + case HWC_TRANSFORM_ROT_180: + texcoord_rot = pi; + break; + case HWC_TRANSFORM_ROT_270: + texcoord_rot = pi * 1.5f; + break; + case HWC_TRANSFORM_FLIP_H: + texcoord_scaleX *= -1.0f; + break; + case HWC_TRANSFORM_FLIP_V: + texcoord_scaleY *= -1.0f; + break; + case HWC_TRANSFORM_FLIP_H_ROT_90: + texcoord_rot = pi * 0.5f; + texcoord_scaleX *= -1.0f; + break; + case HWC_TRANSFORM_FLIP_V_ROT_90: + texcoord_rot = pi * 0.5f; + texcoord_scaleY *= -1.0f; + break; + default: + break; + + } + + m_transformsPerLayer.push_back({ + glm::translate(glm::mat4(1.0f), glm::vec3(pos_trX, pos_trY, 0.0f)) * + glm::scale(glm::mat4(1.0f), glm::vec3(pos_scaleX, pos_scaleY, 1.0f)), + glm::translate(glm::mat4(1.0f), glm::vec3(texcoord_trX, texcoord_trY, 0.0f)) * + glm::scale(glm::mat4(1.0f), glm::vec3(texcoord_scaleX, texcoord_scaleY, 1.0f)) * + glm::rotate(glm::mat4(1.0f), texcoord_rot, glm::vec3(0.0f, 0.0f, 1.0f)), + }); + + ++i; + } +} const std::vector CompositorVk::k_vertices = { {{-1.0f, -1.0f}, {0.0f, 0.0f}}, @@ -84,6 +194,10 @@ CompositorVk::CompositorVk(const goldfish_vk::VulkanDispatch &vk, m_emptyCompositionVkSampler(VK_NULL_HANDLE), m_currentCompositions(0), m_uniformStorage({VK_NULL_HANDLE, VK_NULL_HANDLE, nullptr, 0}) { + + (void)m_renderTargetWidth; + (void)m_renderTargetHeight; + VkPhysicalDeviceProperties physicalDeviceProperties; m_vk.vkGetPhysicalDeviceProperties(m_vkPhysicalDevice, &physicalDeviceProperties); @@ -203,12 +317,12 @@ void CompositorVk::setUpGraphicsPipeline(uint32_t width, uint32_t height, VkPipelineColorBlendAttachmentState colorBlendAttachment = { .blendEnable = VK_TRUE, - .srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA, + .srcColorBlendFactor = VK_BLEND_FACTOR_ONE, .dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, .colorBlendOp = VK_BLEND_OP_ADD, - .srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO, - .dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE, - .alphaBlendOp = VK_BLEND_OP_MAX, + .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE, + .dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + .alphaBlendOp = VK_BLEND_OP_ADD, .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT}; @@ -433,35 +547,39 @@ void CompositorVk::setUpFramebuffers( } } +static const uint32_t kMaxLayersPerFrame = 10; + void CompositorVk::setUpDescriptorSets() { uint32_t numOfFrames = static_cast(m_renderTargetVkFrameBuffers.size()); + uint32_t setsPerDescriptorType = numOfFrames * kMaxLayersPerFrame; + VkDescriptorPoolSize descriptorPoolSizes[2] = { {.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .descriptorCount = numOfFrames}, + .descriptorCount = setsPerDescriptorType}, {.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .descriptorCount = numOfFrames}}; + .descriptorCount = setsPerDescriptorType}}; VkDescriptorPoolCreateInfo descriptorPoolCi = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, .flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT, - .maxSets = static_cast(numOfFrames), + .maxSets = static_cast(setsPerDescriptorType), .poolSizeCount = static_cast(std::size(descriptorPoolSizes)), .pPoolSizes = descriptorPoolSizes}; VK_CHECK(m_vk.vkCreateDescriptorPool(m_vkDevice, &descriptorPoolCi, nullptr, &m_vkDescriptorPool)); - std::vector layouts(numOfFrames, + std::vector layouts(setsPerDescriptorType, m_vkDescriptorSetLayout); VkDescriptorSetAllocateInfo descriptorSetAllocInfo = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, .descriptorPool = m_vkDescriptorPool, - .descriptorSetCount = numOfFrames, + .descriptorSetCount = setsPerDescriptorType, .pSetLayouts = layouts.data()}; - m_vkDescriptorSets.resize(numOfFrames); + m_vkDescriptorSets.resize(setsPerDescriptorType); VK_CHECK(m_vk.vkAllocateDescriptorSets(m_vkDevice, &descriptorSetAllocInfo, m_vkDescriptorSets.data())); - for (size_t i = 0; i < numOfFrames; i++) { + for (size_t i = 0; i < setsPerDescriptorType; i++) { VkDescriptorBufferInfo bufferInfo = { .buffer = m_uniformStorage.m_vkBuffer, .offset = i * m_uniformStorage.m_stride, @@ -514,11 +632,13 @@ void CompositorVk::setUpCommandBuffers(uint32_t width, uint32_t height) { offsets); m_vk.vkCmdBindIndexBuffer(cmdBuffer, m_indexVkBuffer, 0, VK_INDEX_TYPE_UINT16); - m_vk.vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - m_vkPipelineLayout, 0, 1, - &m_vkDescriptorSets[i], 0, nullptr); - m_vk.vkCmdDrawIndexed( - cmdBuffer, static_cast(k_indices.size()), 1, 0, 0, 0); + for (uint32_t j = 0; j < kMaxLayersPerFrame; ++j) { + m_vk.vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + m_vkPipelineLayout, 0, 1, + &m_vkDescriptorSets[i * kMaxLayersPerFrame + j], 0, nullptr); + m_vk.vkCmdDrawIndexed( + cmdBuffer, static_cast(k_indices.size()), 1, 0, 0, 0); + } m_vk.vkCmdEndRenderPass(cmdBuffer); VK_CHECK(m_vk.vkEndCommandBuffer(cmdBuffer)); @@ -617,7 +737,7 @@ void CompositorVk::setUpEmptyComposition(VkFormat format) { void CompositorVk::setUpUniformBuffers() { auto numOfFrames = m_renderTargetVkFrameBuffers.size(); - VkDeviceSize size = m_uniformStorage.m_stride * numOfFrames; + VkDeviceSize size = m_uniformStorage.m_stride * numOfFrames * kMaxLayersPerFrame; auto maybeBuffer = createBuffer(size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | @@ -677,46 +797,51 @@ VkCommandBuffer CompositorVk::getCommandBuffer(uint32_t i) const { return m_vkCommandBuffers[i]; } -void CompositorVk::setComposition(uint32_t i, +void CompositorVk::setComposition(uint32_t rtIndex, std::unique_ptr &&composition) { - m_currentCompositions[i] = std::move(composition); - const auto ¤tComposition = *m_currentCompositions[i]; - VkDescriptorImageInfo imageInfo = { - .sampler = currentComposition.m_vkSampler, - .imageView = currentComposition.m_vkImageView, - .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL}; - VkWriteDescriptorSet descriptorSetWrite = { - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = m_vkDescriptorSets[i], - .dstBinding = 0, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .pImageInfo = &imageInfo}; - m_vk.vkUpdateDescriptorSets(m_vkDevice, 1, &descriptorSetWrite, 0, nullptr); - - auto local2screen = glm::translate(glm::mat3(1.0f), glm::vec2(1.0f, 1.0f)); - local2screen = - glm::scale( - glm::mat3(1.0f), - glm::vec2(static_cast(currentComposition.m_width) / 2.0f, - static_cast(currentComposition.m_height) / 2.0f)) * - local2screen; - auto screen2ndc = - glm::scale(glm::mat3(1.0f), - glm::vec2(2.0f / static_cast(m_renderTargetWidth), - 2.0f / static_cast(m_renderTargetHeight))); - screen2ndc = - glm::translate(glm::mat3(1.0f), glm::vec2(-1.0f, -1.0f)) * screen2ndc; - auto t = screen2ndc * currentComposition.m_transform * local2screen; - UniformBufferObject ubo{}; - ubo.transform = glm::mat4(glm::vec4(t[0][0], t[0][1], 0.0f, t[0][2]), - glm::vec4(t[1][0], t[1][1], 0.0f, t[1][2]), - glm::vec4(0.0f, 0.0f, 0.0f, 0.0f), - glm::vec4(t[2][0], t[2][1], 0.0f, t[2][2])); - memcpy(reinterpret_cast(m_uniformStorage.m_data) + - i * m_uniformStorage.m_stride, - &ubo, sizeof(ubo)); + m_currentCompositions[rtIndex] = std::move(composition); + const auto ¤tComposition = *m_currentCompositions[rtIndex]; + + memset(reinterpret_cast(m_uniformStorage.m_data) + + (rtIndex * kMaxLayersPerFrame + 0) * m_uniformStorage.m_stride, + 0, + sizeof(Composition::LayerTransform) * kMaxLayersPerFrame); + + for (size_t i = 0; i < currentComposition.m_composeLayers.size(); ++i) { + VkDescriptorImageInfo imageInfo = { + .sampler = currentComposition.m_vkSampler, + .imageView = currentComposition.m_composeLayers[i].imageView, + .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL}; + VkWriteDescriptorSet descriptorSetWrite = { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = m_vkDescriptorSets[rtIndex * kMaxLayersPerFrame + i], + .dstBinding = 0, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .pImageInfo = &imageInfo}; + m_vk.vkUpdateDescriptorSets(m_vkDevice, 1, &descriptorSetWrite, 0, nullptr); + memcpy(reinterpret_cast(m_uniformStorage.m_data) + + (rtIndex * kMaxLayersPerFrame + i) * m_uniformStorage.m_stride, + currentComposition.m_transformsPerLayer.data() + i, + sizeof(Composition::LayerTransform)); + } + + for (size_t i = currentComposition.m_composeLayers.size(); i < kMaxLayersPerFrame; ++i) { + VkDescriptorImageInfo imageInfo = { + .sampler = m_emptyCompositionVkSampler, + .imageView = m_emptyCompositionVkImageView, + .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL}; + VkWriteDescriptorSet descriptorSetWrite = { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = m_vkDescriptorSets[rtIndex * kMaxLayersPerFrame + i], + .dstBinding = 0, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .pImageInfo = &imageInfo}; + m_vk.vkUpdateDescriptorSets(m_vkDevice, 1, &descriptorSetWrite, 0, nullptr); + } } VkVertexInputBindingDescription CompositorVk::Vertex::getBindingDescription() { @@ -737,4 +862,4 @@ CompositorVk::Vertex::getAttributeDescription() { .binding = 0, .format = VK_FORMAT_R32G32_SFLOAT, .offset = offsetof(struct Vertex, texPos)}}; -} \ No newline at end of file +} diff --git a/stream-servers/CompositorVk.h b/stream-servers/CompositorVk.h index 91551574..062c4881 100644 --- a/stream-servers/CompositorVk.h +++ b/stream-servers/CompositorVk.h @@ -12,19 +12,34 @@ #include "vulkan/cereal/common/goldfish_vk_dispatch.h" #include "vulkan/vk_util.h" +#include "Hwc2.h" + +class ComposeLayerVk { +public: + VkImageView imageView; + uint32_t cbWidth; + uint32_t cbHeight; + ComposeLayer layerInfo; +}; + class Composition { - public: - VkImageView m_vkImageView; +public: VkSampler m_vkSampler; uint32_t m_width; uint32_t m_height; - // transform matrix in screen coordinates - glm::mat3 m_transform; + std::vector m_composeLayers; + struct LayerTransform { + glm::mat4 pos; + glm::mat4 texcoord; + }; + std::vector m_transformsPerLayer; Composition() = delete; - explicit Composition(VkImageView, VkSampler, uint32_t width, - uint32_t height); + explicit Composition(VkSampler, uint32_t width, uint32_t height, const std::vector& composeLayers); + explicit Composition(VkImageView, VkSampler, uint32_t width, uint32_t height); +private: + void setTransforms(); }; struct CompositorVkBase @@ -117,7 +132,8 @@ class CompositorVk : protected CompositorVkBase { void copyBuffer(VkBuffer src, VkBuffer dst, VkDeviceSize) const; struct UniformBufferObject { - alignas(16) glm::mat4 transform; + alignas(16) glm::mat4 pos_transform; + alignas(16) glm::mat4 texcoord_transform; }; struct Vertex { @@ -149,4 +165,4 @@ class CompositorVk : protected CompositorVkBase { } m_uniformStorage; }; -#endif /* COMPOSITOR_VK_H */ \ No newline at end of file +#endif /* COMPOSITOR_VK_H */ diff --git a/stream-servers/DisplayVk.cpp b/stream-servers/DisplayVk.cpp index 62fc66c7..f49b5910 100644 --- a/stream-servers/DisplayVk.cpp +++ b/stream-servers/DisplayVk.cpp @@ -2,8 +2,8 @@ #include #include - #include "ErrorLog.h" +#include "Hwc2.h" DisplayVk::DisplayVk(const goldfish_vk::VulkanDispatch &vk, VkPhysicalDevice vkPhysicalDevice, @@ -121,6 +121,11 @@ void DisplayVk::post( __FUNCTION__, __FILE__, static_cast(__LINE__)); return; } + + if (!displayBufferPtr) { + return; + } + auto &surfaceState = *m_surfaceState; const auto &db = *displayBufferPtr; @@ -142,12 +147,6 @@ void DisplayVk::post( } auto composition = std::make_unique( db.m_vkImageView, m_compositionVkSampler, db.m_width, db.m_height); - composition->m_transform = - glm::scale(glm::mat3(1.0), - glm::vec2(static_cast(surfaceState.m_width) / - static_cast(db.m_width), - static_cast(surfaceState.m_height) / - static_cast(db.m_height))); m_compositorVk->setComposition(imageIndex, std::move(composition)); surfaceState.m_prevDisplayBuffer = displayBufferPtr; } @@ -180,6 +179,95 @@ void DisplayVk::post( VK_TRUE, UINT64_MAX)); } +void DisplayVk::compose( + const Post& postCmd, + const std::vector>& composeBuffers, + const std::shared_ptr& displayBufferPtr) { + ComposeDevice_v2* composeDevice = (ComposeDevice_v2*)(postCmd.composeBuffer.data()); + uint32_t bufferSize = (uint32_t)postCmd.composeBuffer.size(); + ComposeLayer* l = (ComposeLayer*)composeDevice->layer; + + std::vector composeLayers; + for (int i = 0; i < composeDevice->numLayers; ++i, ++l) { + ComposeLayerVk cl; + if (!composeBuffers[i]) { + fprintf(stderr, "%s: warning: null ptr passed to compose bufer\n", __func__); + continue; + } + cl.imageView = composeBuffers[i]->m_vkImageView; + cl.cbWidth = composeBuffers[i]->m_width; + cl.cbHeight = composeBuffers[i]->m_height; + cl.layerInfo = *l; + composeLayers.push_back(cl); + } + + if (composeLayers.empty()) { + return; + } + + if (m_swapChainStateVk == nullptr || m_compositorVk == nullptr) { + ERR("%s(%s:%d): Haven't bound to a surface, can't post color buffer.\n", + __FUNCTION__, __FILE__, static_cast(__LINE__)); + return; + } + + if (!displayBufferPtr) { + return; + } + + auto &surfaceState = *m_surfaceState; + const auto &db = *displayBufferPtr; + + VK_CHECK(m_vk.vkWaitForFences(m_vkDevice, 1, &m_frameDrawCompleteFence, + VK_TRUE, UINT64_MAX)); + uint32_t imageIndex; + VK_CHECK(m_vk.vkAcquireNextImageKHR( + m_vkDevice, m_swapChainStateVk->getSwapChain(), UINT64_MAX, + m_imageReadySem, VK_NULL_HANDLE, &imageIndex)); + auto maybePrevDisplayBuffer = surfaceState.m_prevDisplayBuffer.lock(); + + if (!canComposite(db.m_vkFormat)) { + ERR("%s(%s:%d): Can't composite the DisplayBuffer(0x%" PRIxPTR + "). The image(VkFormat = %" PRIu64 ") can be sampled from.\n", + __FUNCTION__, __FILE__, static_cast(__LINE__), + reinterpret_cast(displayBufferPtr.get()), + static_cast(db.m_vkFormat)); + return; + } + + auto composition = std::make_unique( + m_compositionVkSampler, db.m_width, db.m_height, composeLayers); + m_compositorVk->setComposition(imageIndex, std::move(composition)); + surfaceState.m_prevDisplayBuffer = displayBufferPtr; + + auto cmdBuff = m_compositorVk->getCommandBuffer(imageIndex); + + VK_CHECK(m_vk.vkResetFences(m_vkDevice, 1, &m_frameDrawCompleteFence)); + VkPipelineStageFlags waitStages[] = { + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; + VkSubmitInfo submitInfo = {.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, + .waitSemaphoreCount = 1, + .pWaitSemaphores = &m_imageReadySem, + .pWaitDstStageMask = waitStages, + .commandBufferCount = 1, + .pCommandBuffers = &cmdBuff, + .signalSemaphoreCount = 1, + .pSignalSemaphores = &m_frameDrawCompleteSem}; + VK_CHECK(m_vk.vkQueueSubmit(m_compositorVkQueue, 1, &submitInfo, + m_frameDrawCompleteFence)); + + auto swapChain = m_swapChainStateVk->getSwapChain(); + VkPresentInfoKHR presentInfo = {.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, + .waitSemaphoreCount = 1, + .pWaitSemaphores = &m_frameDrawCompleteSem, + .swapchainCount = 1, + .pSwapchains = &swapChain, + .pImageIndices = &imageIndex}; + VK_CHECK(m_vk.vkQueuePresentKHR(m_swapChainVkQueue, &presentInfo)); + VK_CHECK(m_vk.vkWaitForFences(m_vkDevice, 1, &m_frameDrawCompleteFence, + VK_TRUE, UINT64_MAX)); +} + bool DisplayVk::canComposite(VkFormat format) { auto it = m_canComposite.find(format); if (it != m_canComposite.end()) { @@ -223,4 +311,4 @@ DisplayVk::DisplayBufferInfo::DisplayBufferInfo( DisplayVk::DisplayBufferInfo::~DisplayBufferInfo() { m_vk.vkDestroyImageView(m_vkDevice, m_vkImageView, nullptr); -} \ No newline at end of file +} diff --git a/stream-servers/DisplayVk.h b/stream-servers/DisplayVk.h index 88e86c20..4d3d2666 100644 --- a/stream-servers/DisplayVk.h +++ b/stream-servers/DisplayVk.h @@ -8,6 +8,7 @@ #include "CompositorVk.h" #include "RenderContext.h" #include "SwapChainStateVk.h" +#include "PostCommands.h" #include "vulkan/cereal/common/goldfish_vk_dispatch.h" // The DisplayVk class holds the Vulkan and other states required to draw a @@ -49,6 +50,10 @@ class DisplayVk { uint32_t height); void post(const std::shared_ptr &); + void compose( + const Post& postCmd, const std::vector>& composeBuffers, + const std::shared_ptr& displayBuffer); + private: bool canComposite(VkFormat); @@ -77,4 +82,4 @@ class DisplayVk { std::unordered_map m_canComposite; }; -#endif \ No newline at end of file +#endif diff --git a/stream-servers/FrameBuffer.cpp b/stream-servers/FrameBuffer.cpp index efee4542..00d4c03f 100644 --- a/stream-servers/FrameBuffer.cpp +++ b/stream-servers/FrameBuffer.cpp @@ -757,7 +757,7 @@ FrameBuffer::FrameBuffer(int p_width, int p_height, bool useSubWindow) kFeature_RefCountPipe)), m_noDelayCloseColorBufferEnabled(feature_is_enabled( kFeature_NoDelayCloseColorBuffer)), - m_postThread([this](FrameBuffer::Post&& post) { + m_postThread([this](Post&& post) { return postWorkerFunc(post); }) { uint32_t displayId = 0; @@ -857,7 +857,7 @@ FrameBuffer::postWorkerFunc(const Post& post) { return WorkerProcessingResult::Continue; } -void FrameBuffer::sendPostWorkerCmd(FrameBuffer::Post post) { +void FrameBuffer::sendPostWorkerCmd(Post post) { #ifdef __APPLE__ bool postOnlyOnMainThread = m_subWin && (emugl::getRenderer() == SELECTED_RENDERER_HOST); #else @@ -2480,7 +2480,12 @@ bool FrameBuffer::postImpl(HandleType p_colorbuffer, // TODO(kaiyili, b/179481815): make DisplayVk::post asynchronous. if (m_displayVk != nullptr) { + if (m_justVkComposed) { + m_justVkComposed = false; + goto EXIT; + } m_displayVk->post(c->second.cb->getDisplayBufferVk()); + m_lastPostedColorBuffer = p_colorbuffer; goto EXIT; } @@ -2784,9 +2789,47 @@ bool FrameBuffer::compose(uint32_t bufferSize, void* buffer, bool needPost) { composeCmd.composeBuffer.resize(bufferSize); memcpy(composeCmd.composeBuffer.data(), buffer, bufferSize); composeCmd.cmd = PostCmd::Compose; - sendPostWorkerCmd(composeCmd); - if (p2->displayId == 0 && needPost) { - post(p2->targetHandle, false); + if (m_displayVk) { + ColorBufferMap::iterator c; + + std::vector cbs; // Keep ColorBuffers alive + std::vector> composeBuffers; + ComposeDevice_v2* composeDevice = (ComposeDevice_v2*)buffer; + ComposeLayer* l = (ComposeLayer*)composeDevice->layer; + for (int i = 0; i < composeDevice->numLayers; ++i, ++l) { + c = m_colorbuffers.find(l->cbHandle); + if (c == m_colorbuffers.end()) { + composeBuffers.push_back(nullptr); + continue; + } + cbs.push_back(c->second.cb); + auto db = c->second.cb->getDisplayBufferVk(); + if (!db) { + mutex.unlock(); + goldfish_vk::setupVkColorBuffer(l->cbHandle); + mutex.lock(); + db = c->second.cb->getDisplayBufferVk(); + } + composeBuffers.push_back(db); + } + + c = m_colorbuffers.find(p2->targetHandle); + auto db = c->second.cb->getDisplayBufferVk(); + + if (!db) { + mutex.unlock(); + goldfish_vk::setupVkColorBuffer(p2->targetHandle); + mutex.lock(); + db = c->second.cb->getDisplayBufferVk(); + } + + m_displayVk->compose(composeCmd, composeBuffers, db); + m_justVkComposed = true; + } else { + sendPostWorkerCmd(composeCmd); + if (p2->displayId == 0 && needPost) { + post(p2->targetHandle, false); + } } return true; } @@ -3222,4 +3265,4 @@ VkImageLayout FrameBuffer::getVkImageLayoutForPresent() const { return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; } return VK_IMAGE_LAYOUT_GENERAL; -} \ No newline at end of file +} diff --git a/stream-servers/FrameBuffer.h b/stream-servers/FrameBuffer.h index 71ce1ec0..08f4e4dc 100644 --- a/stream-servers/FrameBuffer.h +++ b/stream-servers/FrameBuffer.h @@ -30,6 +30,7 @@ #include "FbConfig.h" #include "GLESVersionDetector.h" #include "Hwc2.h" +#include "PostCommands.h" #include "PostWorker.h" #include "ReadbackWorker.h" #include "RenderContext.h" @@ -680,6 +681,9 @@ class FrameBuffer { TextureDraw* m_textureDraw = nullptr; EGLConfig m_eglConfig = nullptr; HandleType m_lastPostedColorBuffer = 0; + // With Vulkan swapchain, compose also means to post to the WSI surface. + // In this case, don't do anything in the subsequent resource flush. + bool m_justVkComposed = false; float m_zRot = 0; float m_px = 0; float m_py = 0; @@ -755,38 +759,6 @@ class FrameBuffer { // buffer is already tied to a file descriptor in the guest kernel. bool m_noDelayCloseColorBufferEnabled = false; - // Posting - enum class PostCmd { - Post = 0, - Viewport = 1, - Compose = 2, - Clear = 3, - Screenshot = 4, - Exit = 5, - }; - - struct Post { - PostCmd cmd; - int composeVersion; - std::vector composeBuffer; - union { - ColorBuffer* cb; - struct { - int width; - int height; - } viewport; - struct { - ColorBuffer* cb; - int screenwidth; - int screenheight; - GLenum format; - GLenum type; - int rotation; - void* pixels; - } screenshot; - }; - }; - std::unique_ptr m_postWorker = {}; android::base::WorkerThread m_postThread; android::base::WorkerProcessingResult postWorkerFunc(const Post& post); diff --git a/stream-servers/PostCommands.h b/stream-servers/PostCommands.h new file mode 100644 index 00000000..bcc2c759 --- /dev/null +++ b/stream-servers/PostCommands.h @@ -0,0 +1,40 @@ +#pragma once + +#include + +#include + +class ColorBuffer; + +// Posting +enum class PostCmd { + Post = 0, + Viewport = 1, + Compose = 2, + Clear = 3, + Screenshot = 4, + Exit = 5, +}; + +struct Post { + PostCmd cmd; + int composeVersion; + std::vector composeBuffer; + union { + ColorBuffer* cb; + struct { + int width; + int height; + } viewport; + struct { + ColorBuffer* cb; + int screenwidth; + int screenheight; + GLenum format; + GLenum type; + int rotation; + void* pixels; + } screenshot; + }; +}; + diff --git a/stream-servers/vulkan/Compositor.vert b/stream-servers/vulkan/Compositor.vert index 5dbefbd4..40702633 100644 --- a/stream-servers/vulkan/Compositor.vert +++ b/stream-servers/vulkan/Compositor.vert @@ -2,7 +2,8 @@ #extension GL_ARB_separate_shader_objects : enable layout(binding = 1) uniform UniformBufferObject { - mat4 transform; + mat4 posTransform; + mat4 texcoordTransform; } ubo; layout(location = 0) in vec2 inPosition; @@ -11,6 +12,6 @@ layout(location = 1) in vec2 texCoord; layout(location = 0) out vec2 fragTexCoord; void main() { - gl_Position = vec4((ubo.transform * vec4(inPosition, 0.0, 1.0)).xy, 0.0, 1.0); - fragTexCoord = texCoord; -} \ No newline at end of file + gl_Position = vec4((ubo.posTransform * vec4(inPosition, 0.0, 1.0)).xy, 0.0, 1.0); + fragTexCoord = (ubo.texcoordTransform * vec4(texCoord, 0.0, 1.0)).xy; +} diff --git a/stream-servers/vulkan/CompositorVertexShader.h b/stream-servers/vulkan/CompositorVertexShader.h index b1bbcfe2..d98b6daf 100644 --- a/stream-servers/vulkan/CompositorVertexShader.h +++ b/stream-servers/vulkan/CompositorVertexShader.h @@ -20,13 +20,13 @@ #include const uint32_t compositorVertexShader[] = { -0x07230203, 0x00010000, 0x000d000a, 0x0000002b, +0x07230203, 0x00010000, 0x000d000a, 0x00000033, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, 0x0009000f, 0x00000000, 0x00000004, 0x6e69616d, 0x00000000, 0x0000000d, 0x00000019, 0x00000028, -0x00000029, 0x00030003, 0x00000002, 0x000001c2, +0x0000002c, 0x00030003, 0x00000002, 0x000001c2, 0x00090004, 0x415f4c47, 0x735f4252, 0x72617065, 0x5f657461, 0x64616873, 0x6f5f7265, 0x63656a62, 0x00007374, 0x000a0004, 0x475f4c47, 0x4c474f4f, @@ -45,41 +45,47 @@ const uint32_t compositorVertexShader[] = { 0x435f6c67, 0x446c6c75, 0x61747369, 0x0065636e, 0x00030005, 0x0000000d, 0x00000000, 0x00070005, 0x00000011, 0x66696e55, 0x426d726f, 0x65666675, -0x6a624f72, 0x00746365, 0x00060006, 0x00000011, -0x00000000, 0x6e617274, 0x726f6673, 0x0000006d, -0x00030005, 0x00000013, 0x006f6275, 0x00050005, -0x00000019, 0x6f506e69, 0x69746973, 0x00006e6f, -0x00060005, 0x00000028, 0x67617266, 0x43786554, -0x64726f6f, 0x00000000, 0x00050005, 0x00000029, -0x43786574, 0x64726f6f, 0x00000000, 0x00050048, -0x0000000b, 0x00000000, 0x0000000b, 0x00000000, -0x00050048, 0x0000000b, 0x00000001, 0x0000000b, -0x00000001, 0x00050048, 0x0000000b, 0x00000002, -0x0000000b, 0x00000003, 0x00050048, 0x0000000b, -0x00000003, 0x0000000b, 0x00000004, 0x00030047, -0x0000000b, 0x00000002, 0x00040048, 0x00000011, -0x00000000, 0x00000005, 0x00050048, 0x00000011, -0x00000000, 0x00000023, 0x00000000, 0x00050048, -0x00000011, 0x00000000, 0x00000007, 0x00000010, -0x00030047, 0x00000011, 0x00000002, 0x00040047, -0x00000013, 0x00000022, 0x00000000, 0x00040047, -0x00000013, 0x00000021, 0x00000001, 0x00040047, -0x00000019, 0x0000001e, 0x00000000, 0x00040047, -0x00000028, 0x0000001e, 0x00000000, 0x00040047, -0x00000029, 0x0000001e, 0x00000001, 0x00020013, -0x00000002, 0x00030021, 0x00000003, 0x00000002, -0x00030016, 0x00000006, 0x00000020, 0x00040017, -0x00000007, 0x00000006, 0x00000004, 0x00040015, -0x00000008, 0x00000020, 0x00000000, 0x0004002b, -0x00000008, 0x00000009, 0x00000001, 0x0004001c, -0x0000000a, 0x00000006, 0x00000009, 0x0006001e, -0x0000000b, 0x00000007, 0x00000006, 0x0000000a, -0x0000000a, 0x00040020, 0x0000000c, 0x00000003, -0x0000000b, 0x0004003b, 0x0000000c, 0x0000000d, -0x00000003, 0x00040015, 0x0000000e, 0x00000020, -0x00000001, 0x0004002b, 0x0000000e, 0x0000000f, -0x00000000, 0x00040018, 0x00000010, 0x00000007, -0x00000004, 0x0003001e, 0x00000011, 0x00000010, +0x6a624f72, 0x00746365, 0x00070006, 0x00000011, +0x00000000, 0x54736f70, 0x736e6172, 0x6d726f66, +0x00000000, 0x00080006, 0x00000011, 0x00000001, +0x63786574, 0x64726f6f, 0x6e617254, 0x726f6673, +0x0000006d, 0x00030005, 0x00000013, 0x006f6275, +0x00050005, 0x00000019, 0x6f506e69, 0x69746973, +0x00006e6f, 0x00060005, 0x00000028, 0x67617266, +0x43786554, 0x64726f6f, 0x00000000, 0x00050005, +0x0000002c, 0x43786574, 0x64726f6f, 0x00000000, +0x00050048, 0x0000000b, 0x00000000, 0x0000000b, +0x00000000, 0x00050048, 0x0000000b, 0x00000001, +0x0000000b, 0x00000001, 0x00050048, 0x0000000b, +0x00000002, 0x0000000b, 0x00000003, 0x00050048, +0x0000000b, 0x00000003, 0x0000000b, 0x00000004, +0x00030047, 0x0000000b, 0x00000002, 0x00040048, +0x00000011, 0x00000000, 0x00000005, 0x00050048, +0x00000011, 0x00000000, 0x00000023, 0x00000000, +0x00050048, 0x00000011, 0x00000000, 0x00000007, +0x00000010, 0x00040048, 0x00000011, 0x00000001, +0x00000005, 0x00050048, 0x00000011, 0x00000001, +0x00000023, 0x00000040, 0x00050048, 0x00000011, +0x00000001, 0x00000007, 0x00000010, 0x00030047, +0x00000011, 0x00000002, 0x00040047, 0x00000013, +0x00000022, 0x00000000, 0x00040047, 0x00000013, +0x00000021, 0x00000001, 0x00040047, 0x00000019, +0x0000001e, 0x00000000, 0x00040047, 0x00000028, +0x0000001e, 0x00000000, 0x00040047, 0x0000002c, +0x0000001e, 0x00000001, 0x00020013, 0x00000002, +0x00030021, 0x00000003, 0x00000002, 0x00030016, +0x00000006, 0x00000020, 0x00040017, 0x00000007, +0x00000006, 0x00000004, 0x00040015, 0x00000008, +0x00000020, 0x00000000, 0x0004002b, 0x00000008, +0x00000009, 0x00000001, 0x0004001c, 0x0000000a, +0x00000006, 0x00000009, 0x0006001e, 0x0000000b, +0x00000007, 0x00000006, 0x0000000a, 0x0000000a, +0x00040020, 0x0000000c, 0x00000003, 0x0000000b, +0x0004003b, 0x0000000c, 0x0000000d, 0x00000003, +0x00040015, 0x0000000e, 0x00000020, 0x00000001, +0x0004002b, 0x0000000e, 0x0000000f, 0x00000000, +0x00040018, 0x00000010, 0x00000007, 0x00000004, +0x0004001e, 0x00000011, 0x00000010, 0x00000010, 0x00040020, 0x00000012, 0x00000002, 0x00000011, 0x0004003b, 0x00000012, 0x00000013, 0x00000002, 0x00040020, 0x00000014, 0x00000002, 0x00000010, @@ -91,7 +97,8 @@ const uint32_t compositorVertexShader[] = { 0x00040020, 0x00000025, 0x00000003, 0x00000007, 0x00040020, 0x00000027, 0x00000003, 0x00000017, 0x0004003b, 0x00000027, 0x00000028, 0x00000003, -0x0004003b, 0x00000018, 0x00000029, 0x00000001, +0x0004002b, 0x0000000e, 0x00000029, 0x00000001, +0x0004003b, 0x00000018, 0x0000002c, 0x00000001, 0x00050036, 0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x000200f8, 0x00000005, 0x00050041, 0x00000014, 0x00000015, 0x00000013, 0x0000000f, @@ -110,7 +117,17 @@ const uint32_t compositorVertexShader[] = { 0x00000007, 0x00000024, 0x00000022, 0x00000023, 0x0000001b, 0x0000001c, 0x00050041, 0x00000025, 0x00000026, 0x0000000d, 0x0000000f, 0x0003003e, -0x00000026, 0x00000024, 0x0004003d, 0x00000017, -0x0000002a, 0x00000029, 0x0003003e, 0x00000028, -0x0000002a, 0x000100fd, 0x00010038 -}; \ No newline at end of file +0x00000026, 0x00000024, 0x00050041, 0x00000014, +0x0000002a, 0x00000013, 0x00000029, 0x0004003d, +0x00000010, 0x0000002b, 0x0000002a, 0x0004003d, +0x00000017, 0x0000002d, 0x0000002c, 0x00050051, +0x00000006, 0x0000002e, 0x0000002d, 0x00000000, +0x00050051, 0x00000006, 0x0000002f, 0x0000002d, +0x00000001, 0x00070050, 0x00000007, 0x00000030, +0x0000002e, 0x0000002f, 0x0000001b, 0x0000001c, +0x00050091, 0x00000007, 0x00000031, 0x0000002b, +0x00000030, 0x0007004f, 0x00000017, 0x00000032, +0x00000031, 0x00000031, 0x00000000, 0x00000001, +0x0003003e, 0x00000028, 0x00000032, 0x000100fd, +0x00010038 +}; diff --git a/stream-servers/vulkan/VkAndroidNativeBuffer.cpp b/stream-servers/vulkan/VkAndroidNativeBuffer.cpp index 5bc4f24e..42ea6183 100644 --- a/stream-servers/vulkan/VkAndroidNativeBuffer.cpp +++ b/stream-servers/vulkan/VkAndroidNativeBuffer.cpp @@ -277,10 +277,6 @@ void teardownAndroidNativeBufferImage( anbInfo->acquireQueueState.teardown(vk, device); - if (anbInfo->externallyBacked) { - teardownVkColorBuffer(anbInfo->colorBufferHandle); - } - *anbInfo = {}; } @@ -399,6 +395,7 @@ void AndroidNativeBufferInfo::QueueState::setup( void AndroidNativeBufferInfo::QueueState::teardown( VulkanDispatch* vk, VkDevice device) { + if (queue) vk->vkQueueWaitIdle(queue); if (cb) vk->vkFreeCommandBuffers(device, pool, 1, &cb); if (pool) vk->vkDestroyCommandPool(device, pool, nullptr); if (fence) vk->vkDestroyFence(device, fence, nullptr); -- cgit v1.2.3