1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #ifndef __COMMON_HOST_CONNECTION_H 17 #define __COMMON_HOST_CONNECTION_H 18 19 #if defined(ANDROID) 20 #include "gfxstream/guest/ANativeWindow.h" 21 #include "gfxstream/guest/Gralloc.h" 22 #endif 23 24 #include <cstring> 25 #include <memory> 26 #include <mutex> 27 #include <optional> 28 #include <string> 29 30 #include "EmulatorFeatureInfo.h" 31 #include "Sync.h" 32 #include "VirtGpu.h" 33 #include "gfxstream/guest/ChecksumCalculator.h" 34 #include "gfxstream/guest/IOStream.h" 35 #include "renderControl_enc.h" 36 37 class GLEncoder; 38 struct gl_client_context_t; 39 class GL2Encoder; 40 struct gl2_client_context_t; 41 42 namespace gfxstream { 43 namespace vk { 44 class VkEncoder; 45 } // namespace vk 46 } // namespace gfxstream 47 48 // ExtendedRCEncoderContext is an extended version of renderControl_encoder_context_t 49 // that will be used to track available emulator features. 50 class ExtendedRCEncoderContext : public renderControl_encoder_context_t { 51 public: ExtendedRCEncoderContext(gfxstream::guest::IOStream * stream,gfxstream::guest::ChecksumCalculator * checksumCalculator)52 ExtendedRCEncoderContext(gfxstream::guest::IOStream *stream, 53 gfxstream::guest::ChecksumCalculator *checksumCalculator) 54 : renderControl_encoder_context_t(stream, checksumCalculator) {} setSyncImpl(SyncImpl syncImpl)55 void setSyncImpl(SyncImpl syncImpl) { m_featureInfo.syncImpl = syncImpl; } setDmaImpl(DmaImpl dmaImpl)56 void setDmaImpl(DmaImpl dmaImpl) { m_featureInfo.dmaImpl = dmaImpl; } setHostComposition(HostComposition hostComposition)57 void setHostComposition(HostComposition hostComposition) { 58 m_featureInfo.hostComposition = hostComposition; } hasNativeSync()59 bool hasNativeSync() const { return m_featureInfo.syncImpl >= SYNC_IMPL_NATIVE_SYNC_V2; } hasNativeSyncV3()60 bool hasNativeSyncV3() const { return m_featureInfo.syncImpl >= SYNC_IMPL_NATIVE_SYNC_V3; } hasNativeSyncV4()61 bool hasNativeSyncV4() const { return m_featureInfo.syncImpl >= SYNC_IMPL_NATIVE_SYNC_V4; } hasVirtioGpuNativeSync()62 bool hasVirtioGpuNativeSync() const { return m_featureInfo.hasVirtioGpuNativeSync; } hasHostCompositionV1()63 bool hasHostCompositionV1() const { 64 return m_featureInfo.hostComposition == HOST_COMPOSITION_V1; } hasHostCompositionV2()65 bool hasHostCompositionV2() const { 66 return m_featureInfo.hostComposition == HOST_COMPOSITION_V2; } hasYUVCache()67 bool hasYUVCache() const { 68 return m_featureInfo.hasYUVCache; } hasAsyncUnmapBuffer()69 bool hasAsyncUnmapBuffer() const { 70 return m_featureInfo.hasAsyncUnmapBuffer; } hasHostSideTracing()71 bool hasHostSideTracing() const { 72 return m_featureInfo.hasHostSideTracing; 73 } hasAsyncFrameCommands()74 bool hasAsyncFrameCommands() const { 75 return m_featureInfo.hasAsyncFrameCommands; 76 } hasSyncBufferData()77 bool hasSyncBufferData() const { 78 return m_featureInfo.hasSyncBufferData; } hasHWCMultiConfigs()79 bool hasHWCMultiConfigs() const { 80 return m_featureInfo.hasHWCMultiConfigs; 81 } bindDmaDirectly(void * dmaPtr,uint64_t dmaPhysAddr)82 void bindDmaDirectly(void* dmaPtr, uint64_t dmaPhysAddr) { 83 m_dmaPtr = dmaPtr; 84 m_dmaPhysAddr = dmaPhysAddr; 85 } lockAndWriteDma(void * data,uint32_t size)86 virtual uint64_t lockAndWriteDma(void* data, uint32_t size) { 87 if (m_dmaPtr && m_dmaPhysAddr) { 88 if (data != m_dmaPtr) { 89 memcpy(m_dmaPtr, data, size); 90 } 91 return m_dmaPhysAddr; 92 } else { 93 ALOGE("%s: ERROR: No DMA context bound!", __func__); 94 return 0; 95 } 96 } setGLESMaxVersion(GLESMaxVersion ver)97 void setGLESMaxVersion(GLESMaxVersion ver) { m_featureInfo.glesMaxVersion = ver; } getGLESMaxVersion()98 GLESMaxVersion getGLESMaxVersion() const { return m_featureInfo.glesMaxVersion; } hasDirectMem()99 bool hasDirectMem() const { 100 return m_featureInfo.hasDirectMem; 101 } 102 featureInfo_const()103 const EmulatorFeatureInfo* featureInfo_const() const { return &m_featureInfo; } featureInfo()104 EmulatorFeatureInfo* featureInfo() { return &m_featureInfo; } 105 106 private: 107 EmulatorFeatureInfo m_featureInfo; 108 void* m_dmaPtr = nullptr; 109 uint64_t m_dmaPhysAddr = 0; 110 }; 111 112 struct EGLThreadInfo; 113 114 class HostConnection 115 { 116 public: 117 static HostConnection *get(); 118 static HostConnection* getOrCreate(enum VirtGpuCapset capset = kCapsetNone); 119 120 static HostConnection* getWithThreadInfo(EGLThreadInfo* tInfo, 121 enum VirtGpuCapset capset = kCapsetNone); 122 static void exit(); 123 static void exitUnclean(); // for testing purposes 124 125 static std::unique_ptr<HostConnection> createUnique(enum VirtGpuCapset capset = kCapsetNone); 126 HostConnection(const HostConnection&) = delete; 127 128 ~HostConnection(); 129 130 GLEncoder *glEncoder(); 131 GL2Encoder *gl2Encoder(); 132 gfxstream::vk::VkEncoder *vkEncoder(); 133 ExtendedRCEncoderContext *rcEncoder(); 134 getRendernodeFd()135 int getRendernodeFd() { return m_rendernodeFd; } 136 checksumHelper()137 gfxstream::guest::ChecksumCalculator *checksumHelper() { return &m_checksumHelper; } 138 139 #if defined(ANDROID) anwHelper()140 gfxstream::ANativeWindowHelper* anwHelper() { return m_anwHelper.get(); } grallocHelper()141 gfxstream::Gralloc* grallocHelper() { return m_grallocHelper.get(); } 142 #endif syncHelper()143 gfxstream::SyncHelper* syncHelper() { return m_syncHelper.get(); } 144 flush()145 void flush() { 146 if (m_stream) { 147 m_stream->flush(); 148 } 149 } 150 151 #ifdef __clang__ 152 #pragma clang diagnostic push 153 #pragma clang diagnostic ignored "-Wthread-safety-analysis" 154 #endif lock()155 void lock() const { m_lock.lock(); } unlock()156 void unlock() const { m_lock.unlock(); } 157 #ifdef __clang__ 158 #pragma clang diagnostic pop 159 #endif 160 161 bool exitUncleanly; // for testing purposes 162 163 private: 164 // If the connection failed, |conn| is deleted. 165 // Returns NULL if connection failed. 166 static std::unique_ptr<HostConnection> connect(enum VirtGpuCapset capset); 167 168 HostConnection(); 169 static gl_client_context_t* s_getGLContext(); 170 static gl2_client_context_t* s_getGL2Context(); 171 172 const std::string& queryHostExtensions(ExtendedRCEncoderContext* rcEnc); 173 // setProtocol initializes GL communication protocol for checksums 174 // should be called when m_rcEnc is created 175 void setChecksumHelper(ExtendedRCEncoderContext* rcEnc); 176 void queryAndSetSyncImpl(ExtendedRCEncoderContext* rcEnc); 177 void queryAndSetDmaImpl(ExtendedRCEncoderContext* rcEnc); 178 void queryAndSetGLESMaxVersion(ExtendedRCEncoderContext* rcEnc); 179 void queryAndSetNoErrorState(ExtendedRCEncoderContext* rcEnc); 180 void queryAndSetHostCompositionImpl(ExtendedRCEncoderContext* rcEnc); 181 void queryAndSetDirectMemSupport(ExtendedRCEncoderContext* rcEnc); 182 void queryAndSetVulkanSupport(ExtendedRCEncoderContext* rcEnc); 183 void queryAndSetDeferredVulkanCommandsSupport(ExtendedRCEncoderContext* rcEnc); 184 void queryAndSetVulkanNullOptionalStringsSupport(ExtendedRCEncoderContext* rcEnc); 185 void queryAndSetVulkanCreateResourcesWithRequirementsSupport(ExtendedRCEncoderContext* rcEnc); 186 void queryAndSetVulkanIgnoredHandles(ExtendedRCEncoderContext* rcEnc); 187 void queryAndSetYUVCache(ExtendedRCEncoderContext* mrcEnc); 188 void queryAndSetAsyncUnmapBuffer(ExtendedRCEncoderContext* rcEnc); 189 void queryAndSetVirtioGpuNext(ExtendedRCEncoderContext* rcEnc); 190 void queryHasSharedSlotsHostMemoryAllocator(ExtendedRCEncoderContext* rcEnc); 191 void queryAndSetVulkanFreeMemorySync(ExtendedRCEncoderContext* rcEnc); 192 void queryAndSetVirtioGpuNativeSync(ExtendedRCEncoderContext* rcEnc); 193 void queryAndSetVulkanShaderFloat16Int8Support(ExtendedRCEncoderContext* rcEnc); 194 void queryAndSetVulkanAsyncQueueSubmitSupport(ExtendedRCEncoderContext* rcEnc); 195 void queryAndSetHostSideTracingSupport(ExtendedRCEncoderContext* rcEnc); 196 void queryAndSetAsyncFrameCommands(ExtendedRCEncoderContext* rcEnc); 197 void queryAndSetVulkanQueueSubmitWithCommandsSupport(ExtendedRCEncoderContext* rcEnc); 198 void queryAndSetVulkanBatchedDescriptorSetUpdateSupport(ExtendedRCEncoderContext* rcEnc); 199 void queryAndSetSyncBufferData(ExtendedRCEncoderContext* rcEnc); 200 void queryAndSetVulkanAsyncQsri(ExtendedRCEncoderContext* rcEnc); 201 void queryAndSetReadColorBufferDma(ExtendedRCEncoderContext* rcEnc); 202 void queryAndSetHWCMultiConfigs(ExtendedRCEncoderContext* rcEnc); 203 void queryAndSetVulkanAuxCommandBufferMemory(ExtendedRCEncoderContext* rcEnc); 204 GLint queryVersion(ExtendedRCEncoderContext* rcEnc); 205 206 private: 207 HostConnectionType m_connectionType; 208 209 // intrusively refcounted 210 gfxstream::guest::IOStream* m_stream = nullptr; 211 212 std::unique_ptr<GLEncoder> m_glEnc; 213 std::unique_ptr<GL2Encoder> m_gl2Enc; 214 215 // intrusively refcounted 216 gfxstream::vk::VkEncoder* m_vkEnc = nullptr; 217 std::unique_ptr<ExtendedRCEncoderContext> m_rcEnc; 218 219 gfxstream::guest::ChecksumCalculator m_checksumHelper; 220 #if defined(ANDROID) 221 std::unique_ptr<gfxstream::ANativeWindowHelper> m_anwHelper; 222 std::unique_ptr<gfxstream::Gralloc> m_grallocHelper; 223 #endif 224 std::unique_ptr<gfxstream::SyncHelper> m_syncHelper; 225 std::string m_hostExtensions; 226 bool m_noHostError; 227 mutable std::mutex m_lock; 228 int m_rendernodeFd; 229 }; 230 231 #endif 232