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 "IOStream.h" 20#include "renderControl_enc.h" 21#include "ChecksumCalculator.h" 22#include "goldfish_dma.h" 23 24#include <string> 25 26class GLEncoder; 27struct gl_client_context_t; 28class GL2Encoder; 29struct gl2_client_context_t; 30 31// SyncImpl determines the presence of host/guest OpenGL fence sync 32// capabilities. It corresponds exactly to EGL_ANDROID_native_fence_sync 33// capability, but for the emulator, we need to make sure that 34// OpenGL pipe protocols match, so we use a special extension name 35// here. 36// SYNC_IMPL_NONE means that the native fence sync capability is 37// not present, and we will end up using the equivalent of glFinish 38// in order to preserve buffer swapping order. 39// SYNC_IMPL_NATIVE_SYNC means that we do have native fence sync 40// capability, and we will use a fence fd to synchronize buffer swaps. 41enum SyncImpl { 42 SYNC_IMPL_NONE = 0, 43 SYNC_IMPL_NATIVE_SYNC_V2 = 1, 44 SYNC_IMPL_NATIVE_SYNC_V3 = 2, 45}; 46 47// Interface: 48// Use the highest of v2 or v3 that show up, making us 49// SYNC_IMPL_NATIVE_SYNC_V2 or SYNC_IMPL_NATIVE_SYNC_V3. 50static const char kRCNativeSyncV2[] = "ANDROID_EMU_native_sync_v2"; 51static const char kRCNativeSyncV3[] = "ANDROID_EMU_native_sync_v3"; 52 53// DMA for OpenGL 54enum DmaImpl { 55 DMA_IMPL_NONE = 0, 56 DMA_IMPL_v1 = 1, 57}; 58 59static const char kDmaExtStr_v1[] = "ANDROID_EMU_dma_v1"; 60 61// OpenGL ES max supported version 62enum GLESMaxVersion { 63 GLES_MAX_VERSION_2 = 0, 64 GLES_MAX_VERSION_3_0 = 1, 65 GLES_MAX_VERSION_3_1 = 2, 66 GLES_MAX_VERSION_3_2 = 3, 67}; 68 69static const char kGLESMaxVersion_2[] = "ANDROID_EMU_gles_max_version_2"; 70static const char kGLESMaxVersion_3_0[] = "ANDROID_EMU_gles_max_version_3_0"; 71static const char kGLESMaxVersion_3_1[] = "ANDROID_EMU_gles_max_version_3_1"; 72static const char kGLESMaxVersion_3_2[] = "ANDROID_EMU_gles_max_version_3_2"; 73 74// No querying errors from host extension 75static const char kGLESNoHostError[] = "ANDROID_EMU_gles_no_host_error"; 76 77// ExtendedRCEncoderContext is an extended version of renderControl_encoder_context_t 78// that will be used to track SyncImpl. 79class ExtendedRCEncoderContext : public renderControl_encoder_context_t { 80public: 81 ExtendedRCEncoderContext(IOStream *stream, ChecksumCalculator *checksumCalculator) 82 : renderControl_encoder_context_t(stream, checksumCalculator) { 83 m_dmaCxt = NULL; 84 } 85 void setSyncImpl(SyncImpl syncImpl) { m_syncImpl = syncImpl; } 86 void setDmaImpl(DmaImpl dmaImpl) { m_dmaImpl = dmaImpl; } 87 bool hasNativeSync() const { return m_syncImpl >= SYNC_IMPL_NATIVE_SYNC_V2; } 88 bool hasNativeSyncV3() const { return m_syncImpl >= SYNC_IMPL_NATIVE_SYNC_V3; } 89 DmaImpl getDmaVersion() const { return m_dmaImpl; } 90 void bindDmaContext(struct goldfish_dma_context* cxt) { m_dmaCxt = cxt; } 91 virtual uint64_t lockAndWriteDma(void* data, uint32_t size) { 92 ALOGV("%s: call", __FUNCTION__); 93 if (!m_dmaCxt) { 94 ALOGE("%s: ERROR: No DMA context bound!", 95 __FUNCTION__); 96 return 0; 97 } 98 goldfish_dma_lock(m_dmaCxt); 99 goldfish_dma_write(m_dmaCxt, data, size); 100 uint64_t paddr = goldfish_dma_guest_paddr(m_dmaCxt); 101 ALOGV("%s: paddr=0x%llx", __FUNCTION__, paddr); 102 return paddr; 103 } 104 void setGLESMaxVersion(GLESMaxVersion ver) { m_glesMaxVersion = ver; } 105 GLESMaxVersion getGLESMaxVersion() const { return m_glesMaxVersion; } 106private: 107 SyncImpl m_syncImpl; 108 DmaImpl m_dmaImpl; 109 struct goldfish_dma_context* m_dmaCxt; 110 GLESMaxVersion m_glesMaxVersion; 111}; 112 113struct EGLThreadInfo; 114 115class HostConnection 116{ 117public: 118 static HostConnection *get(); 119 static HostConnection *getWithThreadInfo(EGLThreadInfo* tInfo); 120 static void exit(); 121 ~HostConnection(); 122 123 GLEncoder *glEncoder(); 124 GL2Encoder *gl2Encoder(); 125 ExtendedRCEncoderContext *rcEncoder(); 126 ChecksumCalculator *checksumHelper() { return &m_checksumHelper; } 127 128 void flush() { 129 if (m_stream) { 130 m_stream->flush(); 131 } 132 } 133 134 void setGrallocOnly(bool gralloc_only) { 135 m_grallocOnly = gralloc_only; 136 } 137 138 bool isGrallocOnly() const { return m_grallocOnly; } 139 140 int getPipeFd() const { return m_pipeFd; } 141 142private: 143 HostConnection(); 144 static gl_client_context_t *s_getGLContext(); 145 static gl2_client_context_t *s_getGL2Context(); 146 147 const std::string& queryGLExtensions(ExtendedRCEncoderContext *rcEnc); 148 // setProtocol initilizes GL communication protocol for checksums 149 // should be called when m_rcEnc is created 150 void setChecksumHelper(ExtendedRCEncoderContext *rcEnc); 151 void queryAndSetSyncImpl(ExtendedRCEncoderContext *rcEnc); 152 void queryAndSetDmaImpl(ExtendedRCEncoderContext *rcEnc); 153 void queryAndSetGLESMaxVersion(ExtendedRCEncoderContext *rcEnc); 154 void queryAndSetNoErrorState(ExtendedRCEncoderContext *rcEnc); 155 156private: 157 IOStream *m_stream; 158 GLEncoder *m_glEnc; 159 GL2Encoder *m_gl2Enc; 160 ExtendedRCEncoderContext *m_rcEnc; 161 ChecksumCalculator m_checksumHelper; 162 std::string m_glExtensions; 163 bool m_grallocOnly; 164 int m_pipeFd; 165 bool m_noHostError; 166}; 167 168#endif 169