1 // Copyright 2019 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 express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 #pragma once 15 16 #include <inttypes.h> 17 18 #include <atomic> 19 #include <mutex> 20 #include <optional> 21 #include <unordered_map> 22 #include <utility> 23 24 #include "aemu/base/Compiler.h" 25 #include "aemu/base/ManagedDescriptor.hpp" 26 #include "aemu/base/ThreadAnnotations.h" 27 28 // A global mapping from opaque host memory IDs to host virtual 29 // addresses/sizes. This is so that the guest doesn't have to know the host 30 // virtual address to be able to map them. However, we do also provide a 31 // mechanism for obtaining the offsets into page for such buffers (as the guest 32 // does need to know those). 33 // 34 // This is currently used only in conjunction with virtio-gpu-next and Vulkan / 35 // address space device, though there are possible other consumers of this, so 36 // it becomes a global object. It exports methods into VmOperations. 37 38 using android::base::DescriptorType; 39 using android::base::ManagedDescriptor; 40 41 namespace gfxstream { 42 43 // Caching types 44 #define MAP_CACHE_MASK 0x0f 45 #define MAP_CACHE_NONE 0x00 46 #define MAP_CACHE_CACHED 0x01 47 #define MAP_CACHE_UNCACHED 0x02 48 #define MAP_CACHE_WC 0x03 49 50 #define STREAM_HANDLE_TYPE_MEM_OPAQUE_FD 0x1 51 #define STREAM_HANDLE_TYPE_MEM_DMABUF 0x2 52 #define STREAM_HANDLE_TYPE_MEM_OPAQUE_WIN32 0x3 53 #define STREAM_HANDLE_TYPE_MEM_SHM 0x4 54 #define STREAM_HANDLE_TYPE_MEM_ZIRCON 0x5 55 56 #define STREAM_HANDLE_TYPE_SIGNAL_OPAQUE_FD 0x10 57 #define STREAM_HANDLE_TYPE_SIGNAL_SYNC_FD 0x20 58 #define STREAM_HANDLE_TYPE_SIGNAL_OPAQUE_WIN32 0x30 59 #define STREAM_HANDLE_TYPE_SIGNAL_ZIRCON 0x40 60 #define STREAM_HANDLE_TYPE_SIGNAL_EVENT_FD 0x50 61 62 #define STREAM_HANDLE_TYPE_PLATFORM_SCREEN_BUFFER_QNX 0x01000000 63 #define STREAM_HANDLE_TYPE_PLATFORM_EGL_NATIVE_PIXMAP 0x02000000 64 65 typedef int64_t ExternalHandleType; 66 67 struct ExternalHandleInfo { 68 ExternalHandleType handle; 69 uint32_t streamHandleType; 70 }; 71 72 // A struct describing the information about host memory associated 73 // with a host memory id. Used with virtio-gpu-next. 74 struct HostMemInfo { 75 void* addr; 76 uint32_t caching; 77 }; 78 79 struct GenericDescriptorInfo { 80 ManagedDescriptor descriptor; 81 uint32_t streamHandleType; 82 }; 83 84 struct VulkanInfo { 85 uint32_t memoryIndex; 86 uint8_t deviceUUID[16]; 87 uint8_t driverUUID[16]; 88 }; 89 90 struct BlobDescriptorInfo { 91 GenericDescriptorInfo descriptorInfo; 92 uint32_t caching; 93 std::optional<VulkanInfo> vulkanInfoOpt; 94 }; 95 96 using SyncDescriptorInfo = GenericDescriptorInfo; 97 98 class ExternalObjectManager { 99 public: 100 ExternalObjectManager() = default; 101 102 static ExternalObjectManager* get(); 103 104 void addMapping(uint32_t ctx_id, uint64_t blobId, void* addr, uint32_t caching); 105 std::optional<HostMemInfo> removeMapping(uint32_t ctx_id, uint64_t blobId); 106 107 void addBlobDescriptorInfo(uint32_t ctx_id, uint64_t blobId, ManagedDescriptor descriptor, 108 uint32_t streamHandleType, uint32_t caching, 109 std::optional<VulkanInfo> vulkanInfoOpt); 110 std::optional<BlobDescriptorInfo> removeBlobDescriptorInfo(uint32_t ctx_id, uint64_t blobId); 111 112 void addSyncDescriptorInfo(uint32_t ctx_id, uint64_t syncId, ManagedDescriptor descriptor, 113 uint32_t streamHandleType); 114 std::optional<SyncDescriptorInfo> removeSyncDescriptorInfo(uint32_t ctx_id, uint64_t syncId); 115 116 void addResourceExternalHandleInfo(uint32_t resHandle, 117 const ExternalHandleInfo& externalHandleInfo); 118 std::optional<ExternalHandleInfo> removeResourceExternalHandleInfo(uint32_t resHandle); 119 120 private: 121 // Only for pairs of std::hash-able types for simplicity. 122 // You can of course template this struct to allow other hash functions 123 struct pair_hash { 124 template <class T1, class T2> operatorpair_hash125 std::size_t operator()(const std::pair<T1, T2>& p) const { 126 auto h1 = std::hash<T1>{}(p.first); 127 auto h2 = std::hash<T2>{}(p.second); 128 129 // Mainly for demonstration purposes, i.e. works but is overly simple 130 // In the real world, use sth. like boost.hash_combine 131 return h1 ^ h2; 132 } 133 }; 134 135 std::mutex mMutex; 136 std::unordered_map<std::pair<uint32_t, uint64_t>, HostMemInfo, pair_hash> mHostMemInfos 137 GUARDED_BY(mMutex); 138 std::unordered_map<std::pair<uint32_t, uint64_t>, BlobDescriptorInfo, pair_hash> 139 mBlobDescriptorInfos GUARDED_BY(mMutex); 140 std::unordered_map<std::pair<uint32_t, uint64_t>, SyncDescriptorInfo, pair_hash> 141 mSyncDescriptorInfos GUARDED_BY(mMutex); 142 std::unordered_map<uint32_t, ExternalHandleInfo> mResourceExternalHandleInfos 143 GUARDED_BY(mMutex); 144 145 DISALLOW_COPY_ASSIGN_AND_MOVE(ExternalObjectManager); 146 }; 147 148 } // namespace gfxstream 149