• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expresso or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #pragma once
15 
16 #include <vulkan/vulkan.h>
17 
18 #include <atomic>
19 #include <deque>
20 #include <memory>
21 #include <unordered_set>
22 #include <vector>
23 
24 #include "VkCommonOperations.h"
25 #include "VkQsriTimeline.h"
26 #include "base/ConditionVariable.h"
27 #include "base/Lock.h"
28 #include "cereal/common/goldfish_vk_private_defs.h"
29 
30 namespace goldfish_vk {
31 
32 struct AndroidNativeBufferInfo;
33 struct VulkanDispatch;
34 
35 // This class provides methods to create and query information about Android
36 // native buffers in the context of creating Android swapchain images that have
37 // Android native buffer backing.
38 
39 // This is to be refactored to move to external memory only once we get that
40 // working.
41 
42 void teardownAndroidNativeBufferImage(
43     VulkanDispatch* vk,
44     AndroidNativeBufferInfo* anbInfo);
45 
46 struct AndroidNativeBufferInfo {
~AndroidNativeBufferInfoAndroidNativeBufferInfo47     ~AndroidNativeBufferInfo() {
48         if (vk) {
49             teardownAndroidNativeBufferImage(vk, this);
50         }
51     }
52 
53     VulkanDispatch* vk = nullptr;
54     VkDevice device = VK_NULL_HANDLE;
55     VkFormat vkFormat;
56     VkExtent3D extent;
57     VkImageUsageFlags usage;
58     std::vector<uint32_t> queueFamilyIndices;
59 
60     int format;
61     int stride;
62     uint32_t colorBufferHandle;
63     bool externallyBacked = false;
64     bool useVulkanNativeImage = false;
65 
66     // We will be using separate allocations for image versus staging memory,
67     // because not all host Vulkan drivers will support directly rendering to
68     // host visible memory in a layout that glTexSubImage2D can consume.
69 
70     // If we are using external memory, these memories are imported
71     // to the current instance.
72     VkDeviceMemory imageMemory = VK_NULL_HANDLE;
73     VkDeviceMemory stagingMemory = VK_NULL_HANDLE;
74 
75     VkBuffer stagingBuffer = VK_NULL_HANDLE;
76 
77     uint32_t imageMemoryTypeIndex;
78     uint32_t stagingMemoryTypeIndex;
79 
80     uint8_t* mappedStagingPtr = nullptr;
81 
82     // To be populated later as we go.
83     VkImage image = VK_NULL_HANDLE;
84     VkMemoryRequirements memReqs;
85 
86     // The queue over which we send the buffer/image copy commands depends on
87     // the queue over which vkQueueSignalReleaseImageANDROID happens.
88     // It is assumed that the VkImage object has been created by Android swapchain layer
89     // with all the relevant queue family indices for sharing set properly.
90     struct QueueState {
91         VkQueue queue = VK_NULL_HANDLE;
92         VkCommandPool pool = VK_NULL_HANDLE;
93         VkCommandBuffer cb = VK_NULL_HANDLE;
94         VkCommandBuffer cb2 = VK_NULL_HANDLE;
95         VkFence fence = VK_NULL_HANDLE;
96         android::base::Lock* lock = nullptr;
97         uint32_t queueFamilyIndex = 0;
98         void setup(
99             VulkanDispatch* vk,
100             VkDevice device,
101             VkQueue queue,
102             uint32_t queueFamilyIndex,
103             android::base::Lock* queueLock);
104         void teardown(VulkanDispatch* vk, VkDevice device);
105     };
106     // We keep one QueueState for each queue family index used by the guest
107     // in vkQueuePresentKHR.
108     std::vector<QueueState> queueStates;
109 
110     // Did we ever sync the Vulkan image with a ColorBuffer?
111     // If so, set everSynced along with the queue family index
112     // used to do that.
113     // If the swapchain image was created with exclusive sharing
114     // mode (reflected in this struct's |sharingMode| field),
115     // this part doesn't really matter.
116     bool everSynced = false;
117     uint32_t lastUsedQueueFamilyIndex;
118 
119     // On first acquire, we might use a different queue family
120     // to initially set the semaphore/fence to be signaled.
121     // Track that here.
122     bool everAcquired = false;
123     QueueState acquireQueueState;
124 
125     // State that is of interest when interacting with sync fds and SyncThread.
126     // Protected by this lock and condition variable.
127     class QsriWaitFencePool {
128        public:
129         QsriWaitFencePool(VulkanDispatch*, VkDevice);
130         ~QsriWaitFencePool();
131         VkFence getFenceFromPool();
132         void returnFence(VkFence fence);
133 
134        private:
135         android::base::Lock mLock;
136 
137         VulkanDispatch* mVk;
138         VkDevice mDevice;
139 
140         // A pool of vkFences for waiting (optimization so we don't keep recreating them every
141         // time).
142         std::vector<VkFence> mAvailableFences;
143         std::unordered_set<VkFence> mUsedFences;
144     };
145 
146     std::unique_ptr<QsriWaitFencePool> qsriWaitFencePool = nullptr;
147     std::unique_ptr<VkQsriTimeline> qsriTimeline = nullptr;
148 };
149 
150 VkResult prepareAndroidNativeBufferImage(
151     VulkanDispatch* vk,
152     VkDevice device,
153     const VkImageCreateInfo* pCreateInfo,
154     const VkNativeBufferANDROID* nativeBufferANDROID,
155     const VkAllocationCallbacks* pAllocator,
156     const VkPhysicalDeviceMemoryProperties* memProps,
157     AndroidNativeBufferInfo* out);
158 
159 void getGralloc0Usage(VkFormat format, VkImageUsageFlags imageUsage,
160                       int* usage_out);
161 void getGralloc1Usage(VkFormat format, VkImageUsageFlags imageUsage,
162                       VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
163                       uint64_t* consumerUsage_out,
164                       uint64_t* producerUsage_out);
165 
166 VkResult setAndroidNativeImageSemaphoreSignaled(
167     VulkanDispatch* vk,
168     VkDevice device,
169     VkQueue defaultQueue,
170     uint32_t defaultQueueFamilyIndex,
171     android::base::Lock* defaultQueueLock,
172     VkSemaphore semaphore,
173     VkFence fence,
174     AndroidNativeBufferInfo* anbInfo);
175 
176 VkResult syncImageToColorBuffer(
177     VulkanDispatch* vk,
178     uint32_t queueFamilyIndex,
179     VkQueue queue,
180     android::base::Lock* queueLock,
181     uint32_t waitSemaphoreCount,
182     const VkSemaphore* pWaitSemaphores,
183     int* pNativeFenceFd,
184     std::shared_ptr<AndroidNativeBufferInfo> anbInfo);
185 
186 } // namespace goldfish_vk
187