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" 15afb0118a8be2a3fd271b2af51ccc13a2429a5078Andrew Hsieh#include <assert.h> 16183e927350a14945e13ab217e16ab5dce20349f3Jesse Hall 17183e927350a14945e13ab217e16ab5dce20349f3Jesse Hall/* Declared in "android/globals.h" */ 18183e927350a14945e13ab217e16ab5dce20349f3Jesse Hallint android_gles_fast_pipes = 1; 19183e927350a14945e13ab217e16ab5dce20349f3Jesse Hall 207b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner#include "android/globals.h" 21cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#include <android/utils/debug.h> 22cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#include <android/utils/path.h> 23cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#include <android/utils/bufprint.h> 24cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#include <android/utils/dll.h> 25183e927350a14945e13ab217e16ab5dce20349f3Jesse Hall 266aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner// NOTE: The declarations below should be equivalent to those in 276aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner// <libOpenglRender/render_api_platform_types.h> 286aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner#ifdef _WIN32 296aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner#include <windows.h> 306aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turnertypedef HDC FBNativeDisplayType; 316aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turnertypedef HWND FBNativeWindowType; 326aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner#elif defined(__linux__) 336aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner// Really a Window, which is defined as 32-bit unsigned long on all platforms 346aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner// but we don't want to include the X11 headers here. 356aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turnertypedef uint32_t FBNativeWindowType; 366aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner#elif defined(__APPLE__) 376aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turnertypedef void* FBNativeWindowType; 386aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner#else 396aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner#warning "unsupported platform" 406aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner#endif 416aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner 426aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner// NOTE: The declarations below should be equivalent to those in 436aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner// <libOpenglRender/render_api.h> 446aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner 456aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner/* list of constants to be passed to setStreamMode */ 466aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner#define STREAM_MODE_DEFAULT 0 476aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner#define STREAM_MODE_TCP 1 486aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner#define STREAM_MODE_UNIX 2 496aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner#define STREAM_MODE_PIPE 3 506aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner 516aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner#define RENDERER_FUNCTIONS_LIST \ 526aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner FUNCTION_(int, initLibrary, (void), ()) \ 536aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner FUNCTION_(int, setStreamMode, (int mode), (mode)) \ 546aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner FUNCTION_(int, initOpenGLRenderer, (int width, int height, char* addr, size_t addrLen), (width, height, addr, addrLen)) \ 556aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner FUNCTION_VOID_(getHardwareStrings, (const char** vendors, const char** renderer, const char** version), (vendors, renderer, version)) \ 566aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner FUNCTION_VOID_(setPostCallback, (OnPostFunc onPost, void* onPostContext), (onPost, onPostContext)) \ 576aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner FUNCTION_(int, createOpenGLSubwindow, (FBNativeWindowType window, int x, int y, int width, int height, float zRot), (window, x, y, width, height, zRot)) \ 586aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner FUNCTION_(int, destroyOpenGLSubwindow, (void), ()) \ 596aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner FUNCTION_VOID_(setOpenGLDisplayRotation, (float zRot), (zRot)) \ 606aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner FUNCTION_VOID_(repaintOpenGLDisplay, (void), ()) \ 616aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner FUNCTION_(int, stopOpenGLRenderer, (void), ()) \ 62183e927350a14945e13ab217e16ab5dce20349f3Jesse Hall 63cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#include <stdio.h> 64cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#include <stdlib.h> 65cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 66cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#define D(...) VERBOSE_PRINT(init,__VA_ARGS__) 67cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#define DD(...) VERBOSE_PRINT(gles,__VA_ARGS__) 68cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 69cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner/* Name of the GLES rendering library we're going to use */ 7048fbbc097293db01bdfb3be6511a8a40451b4db0David 'Digit' Turner#if UINTPTR_MAX == UINT32_MAX 71cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#define RENDERER_LIB_NAME "libOpenglRender" 7248fbbc097293db01bdfb3be6511a8a40451b4db0David 'Digit' Turner#elif UINTPTR_MAX == UINT64_MAX 73c7389bd69e570a2c8432b37399aff1976b021f0fAndrew Hsieh#define RENDERER_LIB_NAME "lib64OpenglRender" 74c7389bd69e570a2c8432b37399aff1976b021f0fAndrew Hsieh#else 7548fbbc097293db01bdfb3be6511a8a40451b4db0David 'Digit' Turner#error Unknown UINTPTR_MAX 76c7389bd69e570a2c8432b37399aff1976b021f0fAndrew Hsieh#endif 77cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 786aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner// Define the corresponding function pointers. 796aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner#define FUNCTION_(ret, name, sig, params) \ 806aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner static ret (*name) sig = NULL; 816aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner#define FUNCTION_VOID_(name, sig, params) \ 826aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner static void (*name) sig = NULL; 836aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' TurnerRENDERER_FUNCTIONS_LIST 846aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner#undef FUNCTION_ 856aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner#undef FUNCTION_VOID_ 866aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner 876aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner// Define a function that initializes the function pointers by looking up 886aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner// the symbols from the shared library. 89cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnerstatic int 90cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' TurnerinitOpenglesEmulationFuncs(ADynamicLibrary* rendererLib) 91cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner{ 92cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner void* symbol; 93cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner char* error; 946699b688d7dbd7ad4a07ca1c1f77db864012010aJesse Hall 956aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner#define FUNCTION_(ret, name, sig, params) \ 966699b688d7dbd7ad4a07ca1c1f77db864012010aJesse Hall symbol = adynamicLibrary_findSymbol(rendererLib, #name, &error); \ 97cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner if (symbol != NULL) { \ 986699b688d7dbd7ad4a07ca1c1f77db864012010aJesse Hall name = symbol; \ 99cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } else { \ 100cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner derror("GLES emulation: Could not find required symbol (%s): %s", #name, error); \ 101cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner free(error); \ 102cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner return -1; \ 103cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } 1046aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner#define FUNCTION_VOID_(name, sig, params) FUNCTION_(void, name, sig, params) 1056aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' TurnerRENDERER_FUNCTIONS_LIST 1066aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner#undef FUNCTION_VOID_ 1076aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner#undef FUNCTION_ 1086699b688d7dbd7ad4a07ca1c1f77db864012010aJesse Hall 109cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner return 0; 110cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner} 111cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 1126aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner 1136aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner/* Defined in android/hw-pipe-net.c */ 1146aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turnerextern int android_init_opengles_pipes(void); 1156aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner 1166aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turnerstatic ADynamicLibrary* rendererLib; 1176aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turnerstatic int rendererStarted; 1186aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turnerstatic char rendererAddress[256]; 1196aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner 120cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnerint 121cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnerandroid_initOpenglesEmulation(void) 122cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner{ 123cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner char* error = NULL; 124cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 125cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner if (rendererLib != NULL) 126cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner return 0; 127cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 128cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner D("Initializing hardware OpenGLES emulation support"); 129cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 130cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner rendererLib = adynamicLibrary_open(RENDERER_LIB_NAME, &error); 131cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner if (rendererLib == NULL) { 132cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner derror("Could not load OpenGLES emulation library: %s", error); 133cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner return -1; 134cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } 135cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 136cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner android_init_opengles_pipes(); 137cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 138cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner /* Resolve the functions */ 139cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner if (initOpenglesEmulationFuncs(rendererLib) < 0) { 140cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner derror("OpenGLES emulation library mismatch. Be sure to use the correct version!"); 141cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner goto BAD_EXIT; 142cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } 143cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 144cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner if (!initLibrary()) { 145cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner derror("OpenGLES initialization failed!"); 146cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner goto BAD_EXIT; 147cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } 148cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 1497b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner if (android_gles_fast_pipes) { 1507b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner#ifdef _WIN32 1517b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner /* XXX: NEED Win32 pipe implementation */ 1527b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner setStreamMode(STREAM_MODE_TCP); 1537b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner#else 1546699b688d7dbd7ad4a07ca1c1f77db864012010aJesse Hall setStreamMode(STREAM_MODE_UNIX); 1557b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner#endif 1567b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner } else { 1576699b688d7dbd7ad4a07ca1c1f77db864012010aJesse Hall setStreamMode(STREAM_MODE_TCP); 1587b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner } 159cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner return 0; 160cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 161cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' TurnerBAD_EXIT: 162cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner derror("OpenGLES emulation library could not be initialized!"); 163cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner adynamicLibrary_close(rendererLib); 164cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner rendererLib = NULL; 165cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner return -1; 166cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner} 167cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 168cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnerint 169ba5c1f674511aff458dae69927a1c61d60e66aa1Jesse Hallandroid_startOpenglesRenderer(int width, int height) 170cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner{ 171cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner if (!rendererLib) { 172cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner D("Can't start OpenGLES renderer without support libraries"); 173cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner return -1; 174cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } 175cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 17623a322d55622b2045eaeb94ebcf5b26e8ef51369Jesse Hall if (rendererStarted) { 17723a322d55622b2045eaeb94ebcf5b26e8ef51369Jesse Hall return 0; 17823a322d55622b2045eaeb94ebcf5b26e8ef51369Jesse Hall } 17923a322d55622b2045eaeb94ebcf5b26e8ef51369Jesse Hall 180055adab0b70c70890634649a27c12b2c25afcacaJesse Hall if (!initOpenGLRenderer(width, height, rendererAddress, sizeof(rendererAddress))) { 181cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner D("Can't start OpenGLES renderer?"); 182cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner return -1; 183cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } 18423a322d55622b2045eaeb94ebcf5b26e8ef51369Jesse Hall 18523a322d55622b2045eaeb94ebcf5b26e8ef51369Jesse Hall rendererStarted = 1; 186cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner return 0; 187cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner} 188cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 189ba5c1f674511aff458dae69927a1c61d60e66aa1Jesse Hallvoid 190ba5c1f674511aff458dae69927a1c61d60e66aa1Jesse Hallandroid_setPostCallback(OnPostFunc onPost, void* onPostContext) 191ba5c1f674511aff458dae69927a1c61d60e66aa1Jesse Hall{ 192ba5c1f674511aff458dae69927a1c61d60e66aa1Jesse Hall if (rendererLib) { 193ba5c1f674511aff458dae69927a1c61d60e66aa1Jesse Hall setPostCallback(onPost, onPostContext); 194ba5c1f674511aff458dae69927a1c61d60e66aa1Jesse Hall } 195ba5c1f674511aff458dae69927a1c61d60e66aa1Jesse Hall} 196ba5c1f674511aff458dae69927a1c61d60e66aa1Jesse Hall 197733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hallstatic void strncpy_safe(char* dst, const char* src, size_t n) 198733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall{ 199733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall strncpy(dst, src, n); 200733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall dst[n-1] = '\0'; 201733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall} 202733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall 203733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hallstatic void extractBaseString(char* dst, const char* src, size_t dstSize) 204733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall{ 205733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall const char* begin = strchr(src, '('); 206733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall const char* end = strrchr(src, ')'); 207733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall 208733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall if (!begin || !end) { 209733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall strncpy_safe(dst, src, dstSize); 210733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall return; 211733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall } 212733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall begin += 1; 213733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall 214733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall // "foo (bar)" 215733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall // ^ ^ 216733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall // b e 217733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall // = 5 8 218733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall // substring with NUL-terminator is end-begin+1 bytes 219733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall if (end - begin + 1 > dstSize) { 220733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall end = begin + dstSize - 1; 221733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall } 222733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall 223733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall strncpy_safe(dst, begin, end - begin + 1); 224733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall} 225733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall 226733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hallvoid 227733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hallandroid_getOpenglesHardwareStrings(char* vendor, size_t vendorBufSize, 228733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall char* renderer, size_t rendererBufSize, 229733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall char* version, size_t versionBufSize) 230733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall{ 231733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall const char *vendorSrc, *rendererSrc, *versionSrc; 232733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall 23323a322d55622b2045eaeb94ebcf5b26e8ef51369Jesse Hall assert(vendorBufSize > 0 && rendererBufSize > 0 && versionBufSize > 0); 23423a322d55622b2045eaeb94ebcf5b26e8ef51369Jesse Hall assert(vendor != NULL && renderer != NULL && version != NULL); 23523a322d55622b2045eaeb94ebcf5b26e8ef51369Jesse Hall 23623a322d55622b2045eaeb94ebcf5b26e8ef51369Jesse Hall if (!rendererStarted) { 23723a322d55622b2045eaeb94ebcf5b26e8ef51369Jesse Hall D("Can't get OpenGL ES hardware strings when renderer not started"); 238055adab0b70c70890634649a27c12b2c25afcacaJesse Hall vendor[0] = renderer[0] = version[0] = '\0'; 23923a322d55622b2045eaeb94ebcf5b26e8ef51369Jesse Hall return; 24023a322d55622b2045eaeb94ebcf5b26e8ef51369Jesse Hall } 24123a322d55622b2045eaeb94ebcf5b26e8ef51369Jesse Hall 242733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall getHardwareStrings(&vendorSrc, &rendererSrc, &versionSrc); 243733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall if (!vendorSrc) vendorSrc = ""; 244733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall if (!rendererSrc) rendererSrc = ""; 245733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall if (!versionSrc) versionSrc = ""; 246733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall 247733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall /* Special case for the default ES to GL translators: extract the strings 248733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall * of the underlying OpenGL implementation. */ 249733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall if (strncmp(vendorSrc, "Google", 6) == 0 && 250733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall strncmp(rendererSrc, "Android Emulator OpenGL ES Translator", 37) == 0) { 251733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall extractBaseString(vendor, vendorSrc, vendorBufSize); 252733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall extractBaseString(renderer, rendererSrc, rendererBufSize); 253733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall extractBaseString(version, versionSrc, versionBufSize); 254733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall } else { 255733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall strncpy_safe(vendor, vendorSrc, vendorBufSize); 256733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall strncpy_safe(renderer, rendererSrc, rendererBufSize); 257733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall strncpy_safe(version, versionSrc, versionBufSize); 258733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall } 259733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall} 260733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall 261cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnervoid 262cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnerandroid_stopOpenglesRenderer(void) 263cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner{ 26423a322d55622b2045eaeb94ebcf5b26e8ef51369Jesse Hall if (rendererStarted) { 265cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner stopOpenGLRenderer(); 26623a322d55622b2045eaeb94ebcf5b26e8ef51369Jesse Hall rendererStarted = 0; 267cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } 268cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner} 269cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 270cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnerint 271cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnerandroid_showOpenglesWindow(void* window, int x, int y, int width, int height, float rotation) 272cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner{ 27323a322d55622b2045eaeb94ebcf5b26e8ef51369Jesse Hall if (rendererStarted) { 2746aff02b9b67f734329c58db3c2da6304aeb770bfDavid 'Digit' Turner int success = createOpenGLSubwindow((FBNativeWindowType)(uintptr_t)window, x, y, width, height, rotation); 2756699b688d7dbd7ad4a07ca1c1f77db864012010aJesse Hall return success ? 0 : -1; 276cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } else { 277cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner return -1; 278cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } 279cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner} 280cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 281cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnerint 282cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnerandroid_hideOpenglesWindow(void) 283cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner{ 28423a322d55622b2045eaeb94ebcf5b26e8ef51369Jesse Hall if (rendererStarted) { 2856699b688d7dbd7ad4a07ca1c1f77db864012010aJesse Hall int success = destroyOpenGLSubwindow(); 2866699b688d7dbd7ad4a07ca1c1f77db864012010aJesse Hall return success ? 0 : -1; 287cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } else { 288cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner return -1; 289cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } 290cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner} 291cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner 292cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnervoid 293cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turnerandroid_redrawOpenglesWindow(void) 294cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner{ 29523a322d55622b2045eaeb94ebcf5b26e8ef51369Jesse Hall if (rendererStarted) { 296cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner repaintOpenGLDisplay(); 297cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner } 298cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner} 2997b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner 3007b56a4a9a250573d5bdb8d04a2d8a64937432832David Turnervoid 301055adab0b70c70890634649a27c12b2c25afcacaJesse Hallandroid_gles_server_path(char* buff, size_t buffsize) 3027b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner{ 303055adab0b70c70890634649a27c12b2c25afcacaJesse Hall strncpy_safe(buff, rendererAddress, buffsize); 3047b56a4a9a250573d5bdb8d04a2d8a64937432832David Turner} 305