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 #include "EmulatorFeatureInfo.h" 20 #include "IOStream.h" 21 #include "renderControl_enc.h" 22 #include "ChecksumCalculator.h" 23 #include "goldfish_dma.h" 24 25 #include <cutils/native_handle.h> 26 27 #ifdef GOLDFISH_VULKAN 28 #include <mutex> 29 #else 30 #include <utils/threads.h> 31 #endif 32 33 #include <string> 34 35 class GLEncoder; 36 struct gl_client_context_t; 37 class GL2Encoder; 38 struct gl2_client_context_t; 39 40 namespace goldfish_vk { 41 class VkEncoder; 42 } 43 44 // ExtendedRCEncoderContext is an extended version of renderControl_encoder_context_t 45 // that will be used to track available emulator features. 46 class ExtendedRCEncoderContext : public renderControl_encoder_context_t { 47 public: ExtendedRCEncoderContext(IOStream * stream,ChecksumCalculator * checksumCalculator)48 ExtendedRCEncoderContext(IOStream *stream, ChecksumCalculator *checksumCalculator) 49 : renderControl_encoder_context_t(stream, checksumCalculator), 50 m_dmaCxt(NULL), m_dmaPtr(NULL), m_dmaPhysAddr(0) { } setSyncImpl(SyncImpl syncImpl)51 void setSyncImpl(SyncImpl syncImpl) { m_featureInfo.syncImpl = syncImpl; } setDmaImpl(DmaImpl dmaImpl)52 void setDmaImpl(DmaImpl dmaImpl) { m_featureInfo.dmaImpl = dmaImpl; } setHostComposition(HostComposition hostComposition)53 void setHostComposition(HostComposition hostComposition) { 54 m_featureInfo.hostComposition = hostComposition; } hasNativeSync()55 bool hasNativeSync() const { return m_featureInfo.syncImpl >= SYNC_IMPL_NATIVE_SYNC_V2; } hasNativeSyncV3()56 bool hasNativeSyncV3() const { return m_featureInfo.syncImpl >= SYNC_IMPL_NATIVE_SYNC_V3; } hasNativeSyncV4()57 bool hasNativeSyncV4() const { return m_featureInfo.syncImpl >= SYNC_IMPL_NATIVE_SYNC_V4; } hasHostCompositionV1()58 bool hasHostCompositionV1() const { 59 return m_featureInfo.hostComposition == HOST_COMPOSITION_V1; } hasHostCompositionV2()60 bool hasHostCompositionV2() const { 61 return m_featureInfo.hostComposition == HOST_COMPOSITION_V2; } hasYUVCache()62 bool hasYUVCache() const { 63 return m_featureInfo.hasYUVCache; } hasAsyncUnmapBuffer()64 bool hasAsyncUnmapBuffer() const { 65 return m_featureInfo.hasAsyncUnmapBuffer; } getDmaVersion()66 DmaImpl getDmaVersion() const { return m_featureInfo.dmaImpl; } bindDmaContext(struct goldfish_dma_context * cxt)67 void bindDmaContext(struct goldfish_dma_context* cxt) { m_dmaCxt = cxt; } bindDmaDirectly(void * dmaPtr,uint64_t dmaPhysAddr)68 void bindDmaDirectly(void* dmaPtr, uint64_t dmaPhysAddr) { 69 m_dmaPtr = dmaPtr; 70 m_dmaPhysAddr = dmaPhysAddr; 71 } lockAndWriteDma(void * data,uint32_t size)72 virtual uint64_t lockAndWriteDma(void* data, uint32_t size) { 73 if (m_dmaPtr && m_dmaPhysAddr) { 74 memcpy(m_dmaPtr, data, size); 75 return m_dmaPhysAddr; 76 } else if (m_dmaCxt) { 77 return writeGoldfishDma(data, size, m_dmaCxt); 78 } else { 79 ALOGE("%s: ERROR: No DMA context bound!", __func__); 80 return 0; 81 } 82 } setGLESMaxVersion(GLESMaxVersion ver)83 void setGLESMaxVersion(GLESMaxVersion ver) { m_featureInfo.glesMaxVersion = ver; } getGLESMaxVersion()84 GLESMaxVersion getGLESMaxVersion() const { return m_featureInfo.glesMaxVersion; } hasDirectMem()85 bool hasDirectMem() const { 86 #ifdef HOST_BUILD 87 // unit tests do not support restoring "guest" ram because there is no VM 88 return false; 89 #else 90 return m_featureInfo.hasDirectMem; 91 #endif 92 } 93 featureInfo_const()94 const EmulatorFeatureInfo* featureInfo_const() const { return &m_featureInfo; } featureInfo()95 EmulatorFeatureInfo* featureInfo() { return &m_featureInfo; } 96 private: writeGoldfishDma(void * data,uint32_t size,struct goldfish_dma_context * dmaCxt)97 static uint64_t writeGoldfishDma(void* data, uint32_t size, 98 struct goldfish_dma_context* dmaCxt) { 99 ALOGV("%s(data=%p, size=%u): call", __func__, data, size); 100 101 goldfish_dma_write(dmaCxt, data, size); 102 uint64_t paddr = goldfish_dma_guest_paddr(dmaCxt); 103 104 ALOGV("%s: paddr=0x%llx", __func__, (unsigned long long)paddr); 105 return paddr; 106 } 107 108 EmulatorFeatureInfo m_featureInfo; 109 struct goldfish_dma_context* m_dmaCxt; 110 void* m_dmaPtr; 111 uint64_t m_dmaPhysAddr; 112 }; 113 114 // Abstraction for gralloc handle conversion 115 class Gralloc { 116 public: 117 virtual uint32_t createColorBuffer( 118 ExtendedRCEncoderContext* rcEnc, int width, int height, uint32_t glformat); 119 virtual uint32_t getHostHandle(native_handle_t const* handle) = 0; 120 virtual int getFormat(native_handle_t const* handle) = 0; 121 virtual size_t getAllocatedSize(native_handle_t const* handle) = 0; ~Gralloc()122 virtual ~Gralloc() {} 123 }; 124 125 // Abstraction for process pipe helper 126 class ProcessPipe { 127 public: 128 virtual bool processPipeInit(HostConnectionType connType, renderControl_encoder_context_t *rcEnc) = 0; ~ProcessPipe()129 virtual ~ProcessPipe() {} 130 }; 131 132 struct EGLThreadInfo; 133 134 135 class HostConnection 136 { 137 public: 138 static HostConnection *get(); 139 static HostConnection *getWithThreadInfo(EGLThreadInfo* tInfo); 140 static void exit(); 141 142 static HostConnection *createUnique(); 143 static void teardownUnique(HostConnection* con); 144 145 ~HostConnection(); 146 connectionType()147 HostConnectionType connectionType() const { 148 return m_connectionType; 149 } 150 151 GLEncoder *glEncoder(); 152 GL2Encoder *gl2Encoder(); 153 goldfish_vk::VkEncoder *vkEncoder(); 154 ExtendedRCEncoderContext *rcEncoder(); checksumHelper()155 ChecksumCalculator *checksumHelper() { return &m_checksumHelper; } grallocHelper()156 Gralloc *grallocHelper() { return m_grallocHelper; } 157 flush()158 void flush() { 159 if (m_stream) { 160 m_stream->flush(); 161 } 162 } 163 setGrallocOnly(bool gralloc_only)164 void setGrallocOnly(bool gralloc_only) { 165 m_grallocOnly = gralloc_only; 166 } 167 isGrallocOnly()168 bool isGrallocOnly() const { return m_grallocOnly; } 169 170 #ifdef __clang__ 171 #pragma clang diagnostic push 172 #pragma clang diagnostic ignored "-Wthread-safety-analysis" 173 #endif lock()174 void lock() const { m_lock.lock(); } unlock()175 void unlock() const { m_lock.unlock(); } 176 #ifdef __clang__ 177 #pragma clang diagnostic pop 178 #endif 179 180 private: 181 // If the connection failed, |conn| is deleted. 182 // Returns NULL if connection failed. 183 static HostConnection* connect(HostConnection* con); 184 185 HostConnection(); 186 static gl_client_context_t *s_getGLContext(); 187 static gl2_client_context_t *s_getGL2Context(); 188 189 const std::string& queryGLExtensions(ExtendedRCEncoderContext *rcEnc); 190 // setProtocol initilizes GL communication protocol for checksums 191 // should be called when m_rcEnc is created 192 void setChecksumHelper(ExtendedRCEncoderContext *rcEnc); 193 void queryAndSetSyncImpl(ExtendedRCEncoderContext *rcEnc); 194 void queryAndSetDmaImpl(ExtendedRCEncoderContext *rcEnc); 195 void queryAndSetGLESMaxVersion(ExtendedRCEncoderContext *rcEnc); 196 void queryAndSetNoErrorState(ExtendedRCEncoderContext *rcEnc); 197 void queryAndSetHostCompositionImpl(ExtendedRCEncoderContext *rcEnc); 198 void queryAndSetDirectMemSupport(ExtendedRCEncoderContext *rcEnc); 199 void queryAndSetVulkanSupport(ExtendedRCEncoderContext *rcEnc); 200 void queryAndSetDeferredVulkanCommandsSupport(ExtendedRCEncoderContext *rcEnc); 201 void queryAndSetVulkanNullOptionalStringsSupport(ExtendedRCEncoderContext *rcEnc); 202 void queryAndSetVulkanCreateResourcesWithRequirementsSupport(ExtendedRCEncoderContext *rcEnc); 203 void queryAndSetVulkanIgnoredHandles(ExtendedRCEncoderContext *rcEnc); 204 void queryAndSetYUVCache(ExtendedRCEncoderContext *mrcEnc); 205 void queryAndSetAsyncUnmapBuffer(ExtendedRCEncoderContext *rcEnc); 206 void queryAndSetVirtioGpuNext(ExtendedRCEncoderContext *rcEnc); 207 void queryHasSharedSlotsHostMemoryAllocator(ExtendedRCEncoderContext *rcEnc); 208 void queryAndSetVulkanFreeMemorySync(ExtendedRCEncoderContext *rcEnc); 209 210 private: 211 HostConnectionType m_connectionType; 212 GrallocType m_grallocType; 213 IOStream *m_stream; 214 GLEncoder *m_glEnc; 215 GL2Encoder *m_gl2Enc; 216 goldfish_vk::VkEncoder *m_vkEnc; 217 ExtendedRCEncoderContext *m_rcEnc; 218 ChecksumCalculator m_checksumHelper; 219 Gralloc *m_grallocHelper; 220 ProcessPipe *m_processPipe; 221 std::string m_glExtensions; 222 bool m_grallocOnly; 223 bool m_noHostError; 224 #ifdef GOLDFISH_VULKAN 225 mutable std::mutex m_lock; 226 #else 227 mutable android::Mutex m_lock; 228 #endif 229 }; 230 231 #endif 232