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