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