• 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 <mutex>
22 #include <optional>
23 #include <unordered_set>
24 #include <vector>
25 
26 #include "VkCommonOperations.h"
27 #include "VkQsriTimeline.h"
28 #include "aemu/base/AsyncResult.h"
29 #include "aemu/base/BumpPool.h"
30 #include "aemu/base/ThreadAnnotations.h"
31 #include "aemu/base/synchronization/ConditionVariable.h"
32 #include "aemu/base/synchronization/Lock.h"
33 #include "gfxstream/host/BackendCallbacks.h"
34 #include "goldfish_vk_private_defs.h"
35 
36 namespace gfxstream {
37 namespace vk {
38 
39 struct VulkanDispatch;
40 
41 // This class provides methods to create and query information about Android
42 // native buffers in the context of creating Android swapchain images that have
43 // Android native buffer backing.
44 
45 class AndroidNativeBufferInfo {
46    public:
47     static std::unique_ptr<AndroidNativeBufferInfo> create(
48         VkEmulation* emu, VulkanDispatch* vk, VkDevice device, android::base::BumpPool& allocator,
49         const VkImageCreateInfo* pCreateInfo, const VkNativeBufferANDROID* nativeBufferANDROID,
50         const VkAllocationCallbacks* pAllocator, const VkPhysicalDeviceMemoryProperties* memProps);
51 
52     AndroidNativeBufferInfo(const AndroidNativeBufferInfo&) = delete;
53     AndroidNativeBufferInfo& operator=(const AndroidNativeBufferInfo&) = delete;
54 
55     AndroidNativeBufferInfo(AndroidNativeBufferInfo&&) = delete;
56     AndroidNativeBufferInfo& operator=(AndroidNativeBufferInfo&&) = delete;
57 
58     ~AndroidNativeBufferInfo();
59 
getImage()60     VkImage getImage() const { return mImage; }
61 
isExternallyBacked()62     bool isExternallyBacked() const { return mExternallyBacked; }
63 
isUsingNativeImage()64     bool isUsingNativeImage() const { return mUseVulkanNativeImage; }
65 
getColorBufferHandle()66     uint32_t getColorBufferHandle() const { return mColorBufferHandle; }
67 
68     VkResult on_vkAcquireImageANDROID(VkEmulation* emu, VulkanDispatch* vk, VkDevice device, VkQueue defaultQueue,
69                                       uint32_t defaultQueueFamilyIndex,
70                                       std::mutex* defaultQueueMutex, VkSemaphore semaphore,
71                                       VkFence fence);
72 
73     VkResult on_vkQueueSignalReleaseImageANDROID(VkEmulation* emu,
74                                                  VulkanDispatch* vk, uint32_t queueFamilyIndex,
75                                                  VkQueue queue, std::mutex* queueMutex,
76                                                  uint32_t waitSemaphoreCount,
77                                                  const VkSemaphore* pWaitSemaphores,
78                                                  int* pNativeFenceFd);
79 
80     AsyncResult registerQsriCallback(VkImage image, VkQsriTimeline::Callback callback);
81 
82    private:
83     AndroidNativeBufferInfo() = default;
84 
85     VulkanDispatch* mDeviceDispatch = nullptr;
86     VkDevice mDevice = VK_NULL_HANDLE;
87     VkFormat mVkFormat;
88     VkExtent3D mExtent;
89     VkImageUsageFlags mUsage;
90     std::vector<uint32_t> mQueueFamilyIndices;
91 
92     int mAhbFormat = 0;
93     int mStride = 0;
94     uint32_t mColorBufferHandle = 0;
95     bool mExternallyBacked = false;
96     bool mUseVulkanNativeImage = false;
97 
98     // We will be using separate allocations for image versus staging memory,
99     // because not all host Vulkan drivers will support directly rendering to
100     // host visible memory in a layout that glTexSubImage2D can consume.
101 
102     // If we are using external memory, these memories are imported
103     // to the current instance.
104     VkDeviceMemory mImageMemory = VK_NULL_HANDLE;
105     uint32_t mImageMemoryTypeIndex = -1;
106 
107     VkDeviceMemory mStagingBufferMemory = VK_NULL_HANDLE;
108     VkBuffer mStagingBuffer = VK_NULL_HANDLE;
109     uint8_t* mMappedStagingPtr = nullptr;
110 
111     // To be populated later as we go.
112     VkImage mImage = VK_NULL_HANDLE;
113     VkMemoryRequirements mImageMemoryRequirements;
114 
115     // The queue over which we send the buffer/image copy commands depends on
116     // the queue over which vkQueueSignalReleaseImageANDROID happens.
117     // It is assumed that the VkImage object has been created by Android swapchain layer
118     // with all the relevant queue family indices for sharing set properly.
119     struct QueueState {
120         VkQueue queue = VK_NULL_HANDLE;
121         VkCommandPool pool = VK_NULL_HANDLE;
122         VkCommandBuffer cb = VK_NULL_HANDLE;
123         VkCommandBuffer cb2 = VK_NULL_HANDLE;
124         VkFence fence = VK_NULL_HANDLE;
125         std::mutex* queueMutex = nullptr;
126         uint32_t queueFamilyIndex = 0;
127         std::optional<CancelableFuture> latestUse;
128         void setup(VulkanDispatch* vk, VkDevice device, VkQueue queue, uint32_t queueFamilyIndex,
129                    std::mutex* queueMutex);
130         void teardown(VulkanDispatch* vk, VkDevice device);
131     };
132     // We keep one QueueState for each queue family index used by the guest
133     // in vkQueuePresentKHR.
134     std::vector<QueueState> mQueueStates;
135 
136     // Did we ever sync the Vulkan image with a ColorBuffer?
137     // If so, set everSynced along with the queue family index
138     // used to do that.
139     // If the swapchain image was created with exclusive sharing
140     // mode (reflected in this struct's |sharingMode| field),
141     // this part doesn't really matter.
142     bool mEverSynced = false;
143     static constexpr uint32_t INVALID_QUEUE_FAMILY_INDEX = std::numeric_limits<uint32_t>::max();
144     uint32_t mLastUsedQueueFamilyIndex = INVALID_QUEUE_FAMILY_INDEX;
145 
146     // On first acquire, we might use a different queue family
147     // to initially set the semaphore/fence to be signaled.
148     // Track that here.
149     bool mEverAcquired = false;
150     QueueState mAcquireQueueState;
151 
152     // State that is of interest when interacting with sync fds and SyncThread.
153     // Protected by this lock and condition variable.
154     class QsriWaitFencePool {
155        public:
156         QsriWaitFencePool(VulkanDispatch*, VkDevice);
157         ~QsriWaitFencePool();
158         VkFence getFenceFromPool();
159         void returnFence(VkFence fence);
160 
161        private:
162         std::mutex mMutex;
163 
164         VulkanDispatch* mVk;
165         VkDevice mDevice;
166 
167         // A pool of vkFences for waiting (optimization so we don't keep recreating them every
168         // time).
169         std::vector<VkFence> mAvailableFences GUARDED_BY(mMutex);
170         std::unordered_set<VkFence> mUsedFences GUARDED_BY(mMutex);
171     };
172 
173     std::unique_ptr<QsriWaitFencePool> mQsriWaitFencePool;
174     std::unique_ptr<VkQsriTimeline> mQsriTimeline;
175 };
176 
177 void getGralloc0Usage(VkFormat format, VkImageUsageFlags imageUsage, int* usage_out);
178 void getGralloc1Usage(VkFormat format, VkImageUsageFlags imageUsage,
179                       VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
180                       uint64_t* consumerUsage_out, uint64_t* producerUsage_out);
181 
182 }  // namespace vk
183 }  // namespace gfxstream
184