opengles.c revision c7389bd69e570a2c8432b37399aff1976b021f0f
1cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner/* Copyright (C) 2011 The Android Open Source Project 2cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner** 3cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner** This software is licensed under the terms of the GNU General Public 4cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner** License version 2, as published by the Free Software Foundation, and 5cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner** may be copied, distributed, and modified under those terms. 6cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner** 7cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner** This program is distributed in the hope that it will be useful, 8cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner** but WITHOUT ANY WARRANTY; without even the implied warranty of 9cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner** GNU General Public License for more details. 11cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner*/ 12cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 13cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#include "config-host.h" 14cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#include "android/opengles.h" 157b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner#include "android/globals.h" 16cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#include <android/utils/debug.h> 17cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#include <android/utils/path.h> 18cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#include <android/utils/bufprint.h> 19cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#include <android/utils/dll.h> 20cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#include <stdio.h> 21cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#include <stdlib.h> 22cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 23cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#define D(...) VERBOSE_PRINT(init,__VA_ARGS__) 24cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#define DD(...) VERBOSE_PRINT(gles,__VA_ARGS__) 25cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 267b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner/* Declared in "android/globals.h" */ 277b56a4a9a250573d5bdb8d04a2d8a64937432832David Turnerint android_gles_fast_pipes = 1; 287b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner 29cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner/* Name of the GLES rendering library we're going to use */ 30c7389bd69e570a2c8432b37399aff1976b021f0fAndrew Hsieh#if HOST_LONG_BITS == 32 31cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#define RENDERER_LIB_NAME "libOpenglRender" 32c7389bd69e570a2c8432b37399aff1976b021f0fAndrew Hsieh#elif HOST_LONG_BITS == 64 33c7389bd69e570a2c8432b37399aff1976b021f0fAndrew Hsieh#define RENDERER_LIB_NAME "lib64OpenglRender" 34c7389bd69e570a2c8432b37399aff1976b021f0fAndrew Hsieh#else 35c7389bd69e570a2c8432b37399aff1976b021f0fAndrew Hsieh#error Unknown HOST_LONG_BITS 36c7389bd69e570a2c8432b37399aff1976b021f0fAndrew Hsieh#endif 37cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 38cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner/* These definitions *must* match those under: 39cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner * development/tools/emulator/opengl/host/include/libOpenglRender/render_api.h 40cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner */ 41cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#define DYNLINK_FUNCTIONS \ 42cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner DYNLINK_FUNC(int,initLibrary,(void),(),return) \ 437b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner DYNLINK_FUNC(int,setStreamMode,(int a),(a),return) \ 44cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner DYNLINK_FUNC(int,initOpenGLRenderer,(int width, int height, int port),(width,height,port),return) \ 45cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner DYNLINK_FUNC(int,createOpenGLSubwindow,(void* window, int x, int y, int width, int height, float zRot),(window,x,y,width,height,zRot),return)\ 46cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner DYNLINK_FUNC(int,destroyOpenGLSubwindow,(void),(),return)\ 47cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner DYNLINK_FUNC(void,repaintOpenGLDisplay,(void),(),)\ 48cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner DYNLINK_FUNC(void,stopOpenGLRenderer,(void),(),) 49cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 507b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner#define STREAM_MODE_DEFAULT 0 517b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner#define STREAM_MODE_TCP 1 527b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner#define STREAM_MODE_UNIX 2 537b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner#define STREAM_MODE_PIPE 3 54cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 55cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#ifndef CONFIG_STANDALONE_UI 56cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner/* Defined in android/hw-pipe-net.c */ 57cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnerextern int android_init_opengles_pipes(void); 58cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#endif 59cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 60cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnerstatic ADynamicLibrary* rendererLib; 61cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 62cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner/* Define the pointers and the wrapper functions to call them */ 63cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#define DYNLINK_FUNC(result,name,sig,params,ret) \ 64cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner static result (*_ptr_##name) sig; \ 65cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner static result name sig { \ 66cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner ret (*_ptr_##name) params ; \ 67cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } 68cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 69cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' TurnerDYNLINK_FUNCTIONS 70cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 71cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#undef DYNLINK_FUNC 72cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 73cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnerstatic int 74cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' TurnerinitOpenglesEmulationFuncs(ADynamicLibrary* rendererLib) 75cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner{ 76cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner void* symbol; 77cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner char* error; 78cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#define DYNLINK_FUNC(result,name,sig,params,ret) \ 79cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner symbol = adynamicLibrary_findSymbol( rendererLib, #name, &error ); \ 80cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner if (symbol != NULL) { \ 81cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner _ptr_##name = symbol; \ 82cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } else { \ 83cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner derror("GLES emulation: Could not find required symbol (%s): %s", #name, error); \ 84cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner free(error); \ 85cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner return -1; \ 86cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } 87cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' TurnerDYNLINK_FUNCTIONS 88cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#undef DYNLINK_FUNC 89cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner return 0; 90cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner} 91cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 92cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnerint 93cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnerandroid_initOpenglesEmulation(void) 94cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner{ 95cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner char* error = NULL; 96cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 97cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner if (rendererLib != NULL) 98cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner return 0; 99cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 100cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner D("Initializing hardware OpenGLES emulation support"); 101cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 102cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner rendererLib = adynamicLibrary_open(RENDERER_LIB_NAME, &error); 103cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner if (rendererLib == NULL) { 104cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner derror("Could not load OpenGLES emulation library: %s", error); 105cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner return -1; 106cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } 107cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 108cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#ifndef CONFIG_STANDALONE_UI 109cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner android_init_opengles_pipes(); 110cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#endif 111cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 112cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 113cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner /* Resolve the functions */ 114cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner if (initOpenglesEmulationFuncs(rendererLib) < 0) { 115cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner derror("OpenGLES emulation library mismatch. Be sure to use the correct version!"); 116cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner goto BAD_EXIT; 117cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } 118cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 119cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner if (!initLibrary()) { 120cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner derror("OpenGLES initialization failed!"); 121cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner goto BAD_EXIT; 122cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } 123cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 1247b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner if (android_gles_fast_pipes) { 1257b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner#ifdef _WIN32 1267b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner /* XXX: NEED Win32 pipe implementation */ 1277b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner setStreamMode(STREAM_MODE_TCP); 1287b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner#else 1297b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner setStreamMode(STREAM_MODE_UNIX); 1307b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner#endif 1317b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner } else { 1327b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner setStreamMode(STREAM_MODE_TCP); 1337b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner } 134cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner return 0; 135cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 136cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' TurnerBAD_EXIT: 137cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner derror("OpenGLES emulation library could not be initialized!"); 138cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner adynamicLibrary_close(rendererLib); 139cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner rendererLib = NULL; 140cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner return -1; 141cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner} 142cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 143cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnerint 144cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnerandroid_startOpenglesRenderer(int width, int height) 145cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner{ 146cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner if (!rendererLib) { 147cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner D("Can't start OpenGLES renderer without support libraries"); 148cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner return -1; 149cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } 150cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 151cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner if (initOpenGLRenderer(width, height,ANDROID_OPENGLES_BASE_PORT) != 0) { 152cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner D("Can't start OpenGLES renderer?"); 153cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner return -1; 154cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } 155cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner return 0; 156cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner} 157cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 158cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnervoid 159cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnerandroid_stopOpenglesRenderer(void) 160cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner{ 161cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner if (rendererLib) { 162cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner stopOpenGLRenderer(); 163cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } 164cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner} 165cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 166cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnerint 167cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnerandroid_showOpenglesWindow(void* window, int x, int y, int width, int height, float rotation) 168cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner{ 169cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner if (rendererLib) { 170cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner return createOpenGLSubwindow(window, x, y, width, height, rotation); 171cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } else { 172cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner return -1; 173cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } 174cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner} 175cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 176cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnerint 177cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnerandroid_hideOpenglesWindow(void) 178cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner{ 179cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner if (rendererLib) { 180cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner return destroyOpenGLSubwindow(); 181cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } else { 182cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner return -1; 183cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } 184cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner} 185cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 186cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnervoid 187cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnerandroid_redrawOpenglesWindow(void) 188cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner{ 189cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner if (rendererLib) { 190cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner repaintOpenGLDisplay(); 191cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } 192cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner} 1937b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner 1947b56a4a9a250573d5bdb8d04a2d8a64937432832David Turnervoid 1957b56a4a9a250573d5bdb8d04a2d8a64937432832David Turnerandroid_gles_unix_path(char* buff, size_t buffsize, int port) 1967b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner{ 1977b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner const char* user = getenv("USER"); 1987b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner char *p = buff, *end = buff + buffsize; 1997b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner 2007b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner /* The logic here must correspond to the one inside 2017b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner * development/tools/emulator/opengl/shared/libOpenglCodecCommon/UnixStream.cpp */ 2027b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner p = bufprint(p, end, "/tmp/"); 2037b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner if (user && user[0]) { 2047b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner p = bufprint(p, end, "android-%s/", user); 2057b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner } 2067b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner p = bufprint(p, end, "qemu-gles-%d", port); 2077b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner} 208