1 // Copyright (C) 2024 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 15 #pragma once 16 17 #include <stdint.h> 18 19 #include <memory> 20 #include <optional> 21 #include <unordered_set> 22 23 extern "C" { 24 #include "host-common/goldfish_pipe.h" 25 } // extern "C" 26 27 #include "ExternalObjectManager.h" 28 #include "VirtioGpu.h" 29 #ifdef GFXSTREAM_BUILD_WITH_SNAPSHOT_FRONTEND_SUPPORT 30 #include "VirtioGpuResourceSnapshot.pb.h" 31 #endif // GFXSTREAM_BUILD_WITH_SNAPSHOT_FRONTEND_SUPPORT 32 #include "VirtioGpuRingBlob.h" 33 #include "gfxstream/host/Features.h" 34 #include "gfxstream/virtio-gpu-gfxstream-renderer-unstable.h" 35 #include "gfxstream/virtio-gpu-gfxstream-renderer.h" 36 37 namespace gfxstream { 38 namespace host { 39 40 // LINT.IfChange(virtio_gpu_resource_type) 41 enum class VirtioGpuResourceType { 42 UNKNOWN = 0, 43 // Used as a communication channel between the guest and the host 44 // which does not need an allocation on the host GPU. 45 PIPE = 1, 46 // Used as a GPU data buffer. 47 BUFFER = 2, 48 // Used as a GPU texture. 49 COLOR_BUFFER = 3, 50 // Used as a blob and not known to FrameBuffer. 51 BLOB = 4, 52 }; 53 // LINT.ThenChange(VirtioGpuResourceSnapshot.proto:virtio_gpu_resource_type) 54 55 class VirtioGpuResource { 56 public: VirtioGpuResource()57 VirtioGpuResource() {} 58 59 static std::optional<VirtioGpuResource> Create( 60 const struct stream_renderer_resource_create_args* args, struct iovec* iov, 61 uint32_t num_iovs); 62 63 static std::optional<VirtioGpuResource> Create( 64 const gfxstream::host::FeatureSet& features, uint32_t pageSize, uint32_t contextId, 65 uint32_t resourceId, const struct stream_renderer_resource_create_args* createArgs, 66 const struct stream_renderer_create_blob* createBlobArgs, 67 const struct stream_renderer_handle* handle); 68 69 int Destroy(); 70 GetId()71 VirtioGpuResourceId GetId() const { return mId; } 72 73 void AttachIov(struct iovec* iov, uint32_t num_iovs); 74 void DetachIov(); 75 76 void AttachToContext(VirtioGpuContextId contextId); 77 void DetachFromContext(VirtioGpuContextId contextId); 78 std::unordered_set<VirtioGpuContextId> GetAttachedContexts() const; 79 80 int Map(void** outAddress, uint64_t* outSize); 81 82 int GetInfo(struct stream_renderer_resource_info* outInfo) const; 83 84 int GetVulkanInfo(struct stream_renderer_vulkan_info* outInfo) const; 85 86 int GetCaching(uint32_t* outHvaCaching) const; 87 SetHostPipe(GoldfishHostPipe * pipe)88 void SetHostPipe(GoldfishHostPipe* pipe) { mHostPipe = pipe; } 89 90 int WaitSyncResource(); 91 92 // Corresponds to Virtio GPU "TransferFromHost" commands and VMM requests to 93 // copy into display buffers. 94 int TransferRead(const GoldfishPipeServiceOps* ops, uint64_t offset, stream_renderer_box* box, 95 std::optional<std::vector<struct iovec>> iovs = std::nullopt); 96 97 struct TransferWriteResult { 98 int status = 0; 99 100 // If, while processing the first guest to host transfer for a PIPE resource 101 // which contains the pipe service name, the returned pipe service to replace 102 // the generic pipe. 103 VirtioGpuContextId contextId = -1; 104 GoldfishHostPipe* contextPipe = nullptr; 105 }; 106 // Corresponds to Virtio GPU "TransferToHost" commands. 107 TransferWriteResult TransferWrite(const GoldfishPipeServiceOps* ops, uint64_t offset, 108 stream_renderer_box* box, 109 std::optional<std::vector<struct iovec>> iovs = std::nullopt); 110 111 int ExportBlob(struct stream_renderer_handle* outHandle); 112 113 std::shared_ptr<RingBlob> ShareRingBlob(); 114 115 #ifdef GFXSTREAM_BUILD_WITH_SNAPSHOT_FRONTEND_SUPPORT 116 std::optional<gfxstream::host::snapshot::VirtioGpuResourceSnapshot> Snapshot() const; 117 118 static std::optional<VirtioGpuResource> Restore( 119 const gfxstream::host::snapshot::VirtioGpuResourceSnapshot& snapshot); 120 #endif 121 122 private: 123 int ReadFromPipeToLinear(const GoldfishPipeServiceOps* ops, uint64_t offset, 124 stream_renderer_box* box); 125 TransferWriteResult WriteToPipeFromLinear(const GoldfishPipeServiceOps* ops, uint64_t offset, 126 stream_renderer_box* box); 127 128 int ReadFromBufferToLinear(uint64_t offset, stream_renderer_box* box); 129 int WriteToBufferFromLinear(uint64_t offset, stream_renderer_box* box); 130 131 int ReadFromColorBufferToLinear(uint64_t offset, stream_renderer_box* box); 132 int WriteToColorBufferFromLinear(uint64_t offset, stream_renderer_box* box); 133 134 // If `iovs` provided, copy from this resource's linear buffer to the given `iovs`. 135 // Otherwise, copy from this resource's linear buffer into its previously attached 136 // iovs. 137 int TransferToIov(uint64_t offset, const stream_renderer_box* box, 138 std::optional<std::vector<struct iovec>> iovs = std::nullopt); 139 140 // If `iovs` provided, copy from the given `iovs` to this resources linear buffer. 141 // Otherwise, copy from this resource's previously attached iovs into its linear 142 // buffer. 143 int TransferFromIov(uint64_t offset, const stream_renderer_box* box, 144 std::optional<std::vector<struct iovec>> iovs = std::nullopt); 145 146 enum TransferDirection { 147 IOV_TO_LINEAR = 0, 148 LINEAR_TO_IOV = 1, 149 }; 150 int TransferWithIov(uint64_t offset, const stream_renderer_box* box, 151 const std::vector<struct iovec>& iovs, TransferDirection direction); 152 153 // LINT.IfChange(virtio_gpu_resource) 154 VirtioGpuResourceId mId = -1; 155 VirtioGpuResourceType mResourceType = VirtioGpuResourceType::UNKNOWN; 156 std::optional<struct stream_renderer_resource_create_args> mCreateArgs; 157 std::optional<struct stream_renderer_create_blob> mCreateBlobArgs; 158 std::vector<struct iovec> mIovs; 159 std::vector<char> mLinear; 160 GoldfishHostPipe* mHostPipe = nullptr; 161 std::optional<VirtioGpuContextId> mLatestAttachedContext; 162 std::unordered_set<VirtioGpuContextId> mAttachedToContexts; 163 164 // If this resource is a blob resource, the source of the external memory. 165 // 166 // * For ring blobs, blobs that are used soley for guest and host 167 // communication, the external memory is allocated by this resource 168 // in the frontend. 169 // 170 // * For non ring blobs, the memory from the backend as either an external 171 // memory handle (`BlobDescriptorInfo`) or a raw mapping. 172 using RingBlobMemory = std::shared_ptr<RingBlob>; 173 using ExternalMemoryDescriptor = std::shared_ptr<BlobDescriptorInfo>; 174 using ExternalMemoryMapping = HostMemInfo; 175 176 using BlobMemory = 177 std::variant<RingBlobMemory, ExternalMemoryDescriptor, ExternalMemoryMapping>; 178 std::optional<BlobMemory> mBlobMemory; 179 // LINT.ThenChange(VirtioGpuResourceSnapshot.proto:virtio_gpu_resource) 180 }; 181 182 } // namespace host 183 } // namespace gfxstream