|
|
|
@ -9,11 +9,84 @@
@@ -9,11 +9,84 @@
|
|
|
|
|
#include <EGL/egl.h> |
|
|
|
|
#include <EGL/eglext.h> |
|
|
|
|
|
|
|
|
|
static int gl_attribs[REF_GL_ATTRIBUTES_COUNT] = { 0 }; |
|
|
|
|
static qboolean gl_attribs_set[REF_GL_ATTRIBUTES_COUNT] = { 0 }; |
|
|
|
|
static EGLint gl_api = EGL_OPENGL_ES_API; |
|
|
|
|
static void *libgles1, *libgles2; |
|
|
|
|
static qboolean gles1; |
|
|
|
|
static struct vid_android_s |
|
|
|
|
{ |
|
|
|
|
int gl_attribs[REF_GL_ATTRIBUTES_COUNT]; |
|
|
|
|
qboolean gl_attribs_set[REF_GL_ATTRIBUTES_COUNT]; |
|
|
|
|
EGLint gl_api; |
|
|
|
|
qboolean gles1; |
|
|
|
|
void *libgles1, *libgles2; |
|
|
|
|
qboolean has_context; |
|
|
|
|
ANativeWindow* window; |
|
|
|
|
} vid_android; |
|
|
|
|
|
|
|
|
|
static struct nw_s |
|
|
|
|
{ |
|
|
|
|
void (*release)(ANativeWindow* window); |
|
|
|
|
int32_t (*getWidth)(ANativeWindow* window); |
|
|
|
|
int32_t (*getHeight)(ANativeWindow* window); |
|
|
|
|
int32_t (*getFormat)(ANativeWindow* window); |
|
|
|
|
int32_t (*setBuffersGeometry)(ANativeWindow* window, int32_t width, int32_t height, int32_t format); |
|
|
|
|
int32_t (*lock)(ANativeWindow* window, ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds); |
|
|
|
|
int32_t (*unlockAndPost)(ANativeWindow* window); |
|
|
|
|
ANativeWindow* (*fromSurface)(JNIEnv* env, jobject surface); |
|
|
|
|
} nw; |
|
|
|
|
|
|
|
|
|
#define NW_FF(x) {"ANativeWindow_"#x, (void*)&nw.x} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static dllfunc_t android_funcs[] = |
|
|
|
|
{ |
|
|
|
|
NW_FF(release), |
|
|
|
|
NW_FF(getWidth), |
|
|
|
|
NW_FF(getHeight), |
|
|
|
|
NW_FF(getFormat), |
|
|
|
|
NW_FF(setBuffersGeometry), |
|
|
|
|
NW_FF(lock), |
|
|
|
|
NW_FF(unlockAndPost), |
|
|
|
|
NW_FF(fromSurface), |
|
|
|
|
{ NULL, NULL } |
|
|
|
|
}; |
|
|
|
|
#undef NW_FF |
|
|
|
|
dll_info_t android_info = { "libandroid.so", android_funcs, false }; |
|
|
|
|
|
|
|
|
|
static struct egl_s |
|
|
|
|
{ |
|
|
|
|
EGLSurface (*GetCurrentSurface)(EGLint readdraw); |
|
|
|
|
EGLDisplay (*GetCurrentDisplay)(void); |
|
|
|
|
EGLint (*GetError)(void); |
|
|
|
|
EGLBoolean (*SwapBuffers)(EGLDisplay dpy, EGLSurface surface); |
|
|
|
|
EGLBoolean (*SwapInterval)(EGLDisplay dpy, EGLint interval); |
|
|
|
|
void *(*GetProcAddress)(const char *procname); |
|
|
|
|
} egl; |
|
|
|
|
#undef GetProcAddress |
|
|
|
|
#define EGL_FF(x) {"egl"#x, (void*)&egl.x} |
|
|
|
|
static dllfunc_t egl_funcs[] = |
|
|
|
|
{ |
|
|
|
|
EGL_FF(SwapInterval), |
|
|
|
|
EGL_FF(SwapBuffers), |
|
|
|
|
EGL_FF(GetError), |
|
|
|
|
EGL_FF(GetCurrentDisplay), |
|
|
|
|
EGL_FF(GetCurrentSurface), |
|
|
|
|
EGL_FF(GetProcAddress), |
|
|
|
|
{ NULL, NULL } |
|
|
|
|
}; |
|
|
|
|
#undef EGL_FF |
|
|
|
|
dll_info_t egl_info = { "libEGL.so", egl_funcs, false }; |
|
|
|
|
|
|
|
|
|
static struct nativeegl_s |
|
|
|
|
{ |
|
|
|
|
qboolean valid; |
|
|
|
|
void *window; |
|
|
|
|
EGLDisplay dpy; |
|
|
|
|
EGLSurface surface; |
|
|
|
|
EGLContext context; |
|
|
|
|
EGLConfig cfg; |
|
|
|
|
EGLint numCfg; |
|
|
|
|
|
|
|
|
|
const char *extensions; |
|
|
|
|
} negl; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
======================== |
|
|
|
|
Android_SwapInterval |
|
|
|
@ -22,7 +95,7 @@ Android_SwapInterval
@@ -22,7 +95,7 @@ Android_SwapInterval
|
|
|
|
|
static void Android_SwapInterval( int interval ) |
|
|
|
|
{ |
|
|
|
|
if( negl.valid ) |
|
|
|
|
eglSwapInterval( negl.dpy, interval ); |
|
|
|
|
egl.SwapInterval( negl.dpy, interval ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -68,7 +141,7 @@ void GL_SwapBuffers( void )
@@ -68,7 +141,7 @@ void GL_SwapBuffers( void )
|
|
|
|
|
{ |
|
|
|
|
if( negl.valid ) |
|
|
|
|
{ |
|
|
|
|
eglSwapBuffers( negl.dpy, negl.surface ); |
|
|
|
|
egl.SwapBuffers( negl.dpy, negl.surface ); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
@ -83,29 +156,64 @@ Android_UpdateSurface
@@ -83,29 +156,64 @@ Android_UpdateSurface
|
|
|
|
|
Check if we may use native EGL without jni calls |
|
|
|
|
======================== |
|
|
|
|
*/ |
|
|
|
|
void Android_UpdateSurface( void ) |
|
|
|
|
void Android_UpdateSurface( qboolean active ) |
|
|
|
|
{ |
|
|
|
|
negl.valid = false; |
|
|
|
|
|
|
|
|
|
if( !Sys_CheckParm("-nativeegl") ) |
|
|
|
|
if( nw.release ) |
|
|
|
|
{ |
|
|
|
|
if( vid_android.window && !active ) |
|
|
|
|
{ |
|
|
|
|
nw.release( vid_android.window ); |
|
|
|
|
vid_android.window = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if( active ) |
|
|
|
|
{ |
|
|
|
|
jobject surf; |
|
|
|
|
if( vid_android.window ) |
|
|
|
|
nw.release( vid_android.window ); |
|
|
|
|
surf = (*jni.env)->CallStaticObjectMethod(jni.env, jni.actcls, jni.getSurface); |
|
|
|
|
Con_Printf("s %p\n", surf); |
|
|
|
|
vid_android.window = nw.fromSurface(jni.env, surf); |
|
|
|
|
Con_Printf("w %p\n", vid_android.window); |
|
|
|
|
nw.setBuffersGeometry(vid_android.window, 0, 0, WINDOW_FORMAT_RGB_565 ); |
|
|
|
|
(*jni.env)->DeleteLocalRef( jni.env, surf ); |
|
|
|
|
} |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if( !vid_android.has_context ) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
if( ( active && host.status == HOST_FRAME ) || !active ) |
|
|
|
|
(*jni.env)->CallStaticVoidMethod( jni.env, jni.actcls, jni.toggleEGL, 0 ); |
|
|
|
|
|
|
|
|
|
if( active ) |
|
|
|
|
(*jni.env)->CallStaticVoidMethod( jni.env, jni.actcls, jni.toggleEGL, 1 ); |
|
|
|
|
|
|
|
|
|
if( !Sys_CheckParm("-nativeegl") || !active ) |
|
|
|
|
return; // enabled by user
|
|
|
|
|
|
|
|
|
|
negl.dpy = eglGetCurrentDisplay(); |
|
|
|
|
if( !egl.GetCurrentDisplay ) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
negl.dpy = egl.GetCurrentDisplay(); |
|
|
|
|
|
|
|
|
|
if( negl.dpy == EGL_NO_DISPLAY ) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
negl.surface = eglGetCurrentSurface(EGL_DRAW); |
|
|
|
|
negl.surface = egl.GetCurrentSurface(EGL_DRAW); |
|
|
|
|
|
|
|
|
|
if( negl.surface == EGL_NO_SURFACE ) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
// now check if swapBuffers does not give error
|
|
|
|
|
if( eglSwapBuffers( negl.dpy, negl.surface ) == EGL_FALSE ) |
|
|
|
|
if( egl.SwapBuffers( negl.dpy, negl.surface ) == EGL_FALSE ) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
// double check
|
|
|
|
|
if( eglGetError() != EGL_SUCCESS ) |
|
|
|
|
if( egl.GetError() != EGL_SUCCESS ) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
__android_log_print( ANDROID_LOG_VERBOSE, "Xash", "native EGL enabled" ); |
|
|
|
@ -148,9 +256,6 @@ qboolean R_Init_Video( const int type )
@@ -148,9 +256,6 @@ qboolean R_Init_Video( const int type )
|
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
memset( gl_attribs, 0, sizeof( gl_attribs )); |
|
|
|
|
memset( gl_attribs_set, 0, sizeof( gl_attribs_set )); |
|
|
|
|
|
|
|
|
|
if( FS_FileExists( GI->iconpath, true ) ) |
|
|
|
|
{ |
|
|
|
|
if( host.rodir[0] ) |
|
|
|
@ -174,11 +279,11 @@ qboolean R_Init_Video( const int type )
@@ -174,11 +279,11 @@ qboolean R_Init_Video( const int type )
|
|
|
|
|
break; |
|
|
|
|
case REF_GL: |
|
|
|
|
glw_state.software = false; |
|
|
|
|
Sys_LoadLibrary( &egl_info ); |
|
|
|
|
|
|
|
|
|
if( !glw_state.safe && Sys_GetParmFromCmdLine( "-safegl", safe ) ) |
|
|
|
|
glw_state.safe = bound( SAFE_NO, Q_atoi( safe ), SAFE_DONTCARE ); |
|
|
|
|
|
|
|
|
|
// refdll can request some attributes
|
|
|
|
|
ref.dllFuncs.GL_SetupAttributes( glw_state.safe ); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
Host_Error( "Can't initialize unknown context type %d!\n", type ); |
|
|
|
@ -187,8 +292,13 @@ qboolean R_Init_Video( const int type )
@@ -187,8 +292,13 @@ qboolean R_Init_Video( const int type )
|
|
|
|
|
|
|
|
|
|
if( glw_state.software ) |
|
|
|
|
{ |
|
|
|
|
Con_Reportf( S_ERROR "Native software mode isn't supported on Android yet! :(\n" ); |
|
|
|
|
return false; |
|
|
|
|
uint arg; |
|
|
|
|
// Con_Reportf( S_ERROR "Native software mode isn't supported on Android yet! :(\n" );
|
|
|
|
|
// return false;
|
|
|
|
|
Sys_LoadLibrary( &android_info ); |
|
|
|
|
Android_UpdateSurface( true ); |
|
|
|
|
if( !SW_CreateBuffer( jni.width, jni.height, &arg, &arg, &arg, &arg, &arg ) ) |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
while( !(retval = VID_SetMode()) ) |
|
|
|
@ -221,15 +331,17 @@ void R_Free_Video( void )
@@ -221,15 +331,17 @@ void R_Free_Video( void )
|
|
|
|
|
// VID_DestroyWindow ();
|
|
|
|
|
|
|
|
|
|
// R_FreeVideoModes();
|
|
|
|
|
|
|
|
|
|
Sys_FreeLibrary( &android_info ); |
|
|
|
|
Sys_FreeLibrary( &egl_info ); |
|
|
|
|
vid_android.has_context = false; |
|
|
|
|
ref.dllFuncs.GL_ClearExtensions(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#define COPY_ATTR_IF_SET( refattr, attr ) \ |
|
|
|
|
if( gl_attribs_set[refattr] ) \ |
|
|
|
|
if( vid_android.gl_attribs_set[refattr] ) \ |
|
|
|
|
{ \ |
|
|
|
|
attribs[i++] = attr; \ |
|
|
|
|
attribs[i++] = gl_attribs[refattr]; \ |
|
|
|
|
attribs[i++] = vid_android.gl_attribs[refattr]; \ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static size_t VID_GenerateConfig( EGLint *attribs, size_t size ) |
|
|
|
@ -237,7 +349,12 @@ static size_t VID_GenerateConfig( EGLint *attribs, size_t size )
@@ -237,7 +349,12 @@ static size_t VID_GenerateConfig( EGLint *attribs, size_t size )
|
|
|
|
|
size_t i = 0; |
|
|
|
|
|
|
|
|
|
memset( attribs, 0, size * sizeof( EGLint ) ); |
|
|
|
|
gles1 = false; |
|
|
|
|
vid_android.gles1 = false; |
|
|
|
|
memset( vid_android.gl_attribs, 0, sizeof( vid_android.gl_attribs )); |
|
|
|
|
memset( vid_android.gl_attribs_set, 0, sizeof( vid_android.gl_attribs_set )); |
|
|
|
|
|
|
|
|
|
// refdll can request some attributes
|
|
|
|
|
ref.dllFuncs.GL_SetupAttributes( glw_state.safe ); |
|
|
|
|
|
|
|
|
|
COPY_ATTR_IF_SET( REF_GL_RED_SIZE, EGL_RED_SIZE ); |
|
|
|
|
COPY_ATTR_IF_SET( REF_GL_GREEN_SIZE, EGL_GREEN_SIZE ); |
|
|
|
@ -248,31 +365,31 @@ static size_t VID_GenerateConfig( EGLint *attribs, size_t size )
@@ -248,31 +365,31 @@ static size_t VID_GenerateConfig( EGLint *attribs, size_t size )
|
|
|
|
|
COPY_ATTR_IF_SET( REF_GL_MULTISAMPLEBUFFERS, EGL_SAMPLE_BUFFERS ); |
|
|
|
|
COPY_ATTR_IF_SET( REF_GL_MULTISAMPLESAMPLES, EGL_SAMPLES ); |
|
|
|
|
|
|
|
|
|
if( gl_attribs_set[REF_GL_ACCELERATED_VISUAL] ) |
|
|
|
|
if( vid_android.gl_attribs_set[REF_GL_ACCELERATED_VISUAL] ) |
|
|
|
|
{ |
|
|
|
|
attribs[i++] = EGL_CONFIG_CAVEAT; |
|
|
|
|
attribs[i++] = gl_attribs[REF_GL_ACCELERATED_VISUAL] ? EGL_NONE : EGL_DONT_CARE; |
|
|
|
|
attribs[i++] = vid_android.gl_attribs[REF_GL_ACCELERATED_VISUAL] ? EGL_NONE : EGL_DONT_CARE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// BigGL support
|
|
|
|
|
attribs[i++] = EGL_RENDERABLE_TYPE; |
|
|
|
|
gl_api = EGL_OPENGL_ES_API; |
|
|
|
|
vid_android.gl_api = EGL_OPENGL_ES_API; |
|
|
|
|
|
|
|
|
|
if( gl_attribs_set[REF_GL_CONTEXT_PROFILE_MASK] && |
|
|
|
|
!( gl_attribs[REF_GL_CONTEXT_PROFILE_MASK] & REF_GL_CONTEXT_PROFILE_ES )) |
|
|
|
|
if( vid_android.gl_attribs_set[REF_GL_CONTEXT_PROFILE_MASK] && |
|
|
|
|
!( vid_android.gl_attribs[REF_GL_CONTEXT_PROFILE_MASK] & REF_GL_CONTEXT_PROFILE_ES )) |
|
|
|
|
{ |
|
|
|
|
attribs[i++] = EGL_OPENGL_BIT; |
|
|
|
|
gl_api = EGL_OPENGL_API; |
|
|
|
|
vid_android.gl_api = EGL_OPENGL_API; |
|
|
|
|
} |
|
|
|
|
else if( gl_attribs_set[REF_GL_CONTEXT_MAJOR_VERSION] && |
|
|
|
|
gl_attribs[REF_GL_CONTEXT_MAJOR_VERSION] >= 2 ) |
|
|
|
|
else if( vid_android.gl_attribs_set[REF_GL_CONTEXT_MAJOR_VERSION] && |
|
|
|
|
vid_android.gl_attribs[REF_GL_CONTEXT_MAJOR_VERSION] >= 2 ) |
|
|
|
|
{ |
|
|
|
|
attribs[i++] = EGL_OPENGL_ES2_BIT; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
attribs[i++] = EGL_OPENGL_ES_BIT; |
|
|
|
|
gles1 = true; |
|
|
|
|
i--; // erase EGL_RENDERABLE_TYPE
|
|
|
|
|
vid_android.gles1 = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
attribs[i++] = EGL_NONE; |
|
|
|
@ -288,15 +405,15 @@ static size_t VID_GenerateContextConfig( EGLint *attribs, size_t size )
@@ -288,15 +405,15 @@ static size_t VID_GenerateContextConfig( EGLint *attribs, size_t size )
|
|
|
|
|
|
|
|
|
|
/*if( Q_strcmp( negl.extensions, " EGL_KHR_create_context ") )
|
|
|
|
|
{ |
|
|
|
|
if( gl_attribs_set[REF_GL_CONTEXT_FLAGS] ) |
|
|
|
|
if( vid_android.gl_attribs_set[REF_GL_CONTEXT_FLAGS] ) |
|
|
|
|
{ |
|
|
|
|
attribs[i++] = 0x30FC; // EGL_CONTEXT_FLAGS_KHR
|
|
|
|
|
attribs[i++] = gl_attribs[REF_GL_CONTEXT_FLAGS] & ((REF_GL_CONTEXT_ROBUST_ACCESS_FLAG << 1) - 1); |
|
|
|
|
attribs[i++] = vid_android.gl_attribs[REF_GL_CONTEXT_FLAGS] & ((REF_GL_CONTEXT_ROBUST_ACCESS_FLAG << 1) - 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if( gl_attribs_set[REF_GL_CONTEXT_PROFILE_MASK] ) |
|
|
|
|
if( vid_android.gl_attribs_set[REF_GL_CONTEXT_PROFILE_MASK] ) |
|
|
|
|
{ |
|
|
|
|
int val = gl_attribs[REF_GL_CONTEXT_PROFILE_MASK]; |
|
|
|
|
int val = vid_android.gl_attribs[REF_GL_CONTEXT_PROFILE_MASK]; |
|
|
|
|
|
|
|
|
|
if( val & ( (REF_GL_CONTEXT_PROFILE_COMPATIBILITY << 1) - 1 ) ) |
|
|
|
|
{ |
|
|
|
@ -325,9 +442,16 @@ qboolean VID_SetMode( void )
@@ -325,9 +442,16 @@ qboolean VID_SetMode( void )
|
|
|
|
|
jintArray attribs, contextAttribs; |
|
|
|
|
static EGLint nAttribs[32+1], nContextAttribs[32+1]; |
|
|
|
|
const size_t attribsSize = ARRAYSIZE( nAttribs ); |
|
|
|
|
size_t s1, s2; |
|
|
|
|
|
|
|
|
|
size_t s1 = VID_GenerateConfig(nAttribs, attribsSize); |
|
|
|
|
size_t s2 = VID_GenerateContextConfig(nContextAttribs, attribsSize); |
|
|
|
|
if( vid_android.has_context ) |
|
|
|
|
{ |
|
|
|
|
R_ChangeDisplaySettings( 0, 0, false ); // width and height are ignored anyway
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
s1 = VID_GenerateConfig(nAttribs, attribsSize); |
|
|
|
|
s2 = VID_GenerateContextConfig(nContextAttribs, attribsSize); |
|
|
|
|
|
|
|
|
|
attribs = (*jni.env)->NewIntArray( jni.env, s1 ); |
|
|
|
|
contextAttribs = (*jni.env)->NewIntArray( jni.env, s2 ); |
|
|
|
@ -337,8 +461,12 @@ qboolean VID_SetMode( void )
@@ -337,8 +461,12 @@ qboolean VID_SetMode( void )
|
|
|
|
|
|
|
|
|
|
R_ChangeDisplaySettings( 0, 0, false ); // width and height are ignored anyway
|
|
|
|
|
|
|
|
|
|
if( glw_state.software ) |
|
|
|
|
return true; |
|
|
|
|
|
|
|
|
|
if( (*jni.env)->CallStaticBooleanMethod( jni.env, jni.actcls, jni.createGLContext, attribs, contextAttribs ) ) |
|
|
|
|
{ |
|
|
|
|
vid_android.has_context = true; |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -387,8 +515,8 @@ int GL_SetAttribute( int attr, int val )
@@ -387,8 +515,8 @@ int GL_SetAttribute( int attr, int val )
|
|
|
|
|
if( attr < 0 || attr >= REF_GL_ATTRIBUTES_COUNT ) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
gl_attribs[attr] = val; |
|
|
|
|
gl_attribs_set[attr] = true; |
|
|
|
|
vid_android.gl_attribs[attr] = val; |
|
|
|
|
vid_android.gl_attribs_set[attr] = true; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -445,23 +573,26 @@ void* GL_GetProcAddress( const char *name ) // RenderAPI requirement
@@ -445,23 +573,26 @@ void* GL_GetProcAddress( const char *name ) // RenderAPI requirement
|
|
|
|
|
void *gles; |
|
|
|
|
void *addr; |
|
|
|
|
|
|
|
|
|
if( gles1 ) |
|
|
|
|
if( vid_android.gles1 ) |
|
|
|
|
{ |
|
|
|
|
if( !libgles1 ) |
|
|
|
|
libgles1 = dlopen("libGLESv1_CM.so", RTLD_NOW); |
|
|
|
|
gles = libgles1; |
|
|
|
|
if( !vid_android.libgles1 ) |
|
|
|
|
vid_android.libgles1 = dlopen("libGLESv1_CM.so", RTLD_NOW); |
|
|
|
|
gles = vid_android.libgles1; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
if( !libgles2 ) |
|
|
|
|
libgles2 = dlopen("libGLESv2.so", RTLD_NOW); |
|
|
|
|
gles = libgles2; |
|
|
|
|
if( !vid_android.libgles2 ) |
|
|
|
|
vid_android.libgles2 = dlopen("libGLESv2.so", RTLD_NOW); |
|
|
|
|
gles = vid_android.libgles2; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if( gles && ( addr = dlsym(gles, name ) ) ) |
|
|
|
|
return addr; |
|
|
|
|
|
|
|
|
|
return eglGetProcAddress( name ); |
|
|
|
|
if( !egl.GetProcAddress ) |
|
|
|
|
return NULL; |
|
|
|
|
|
|
|
|
|
return egl.GetProcAddress( name ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void GL_UpdateSwapInterval( void ) |
|
|
|
@ -481,15 +612,47 @@ void GL_UpdateSwapInterval( void )
@@ -481,15 +612,47 @@ void GL_UpdateSwapInterval( void )
|
|
|
|
|
|
|
|
|
|
void *SW_LockBuffer( void ) |
|
|
|
|
{ |
|
|
|
|
return NULL; |
|
|
|
|
ANativeWindow_Buffer buffer; |
|
|
|
|
if( !nw.lock || !vid_android.window ) |
|
|
|
|
return NULL; |
|
|
|
|
if( nw.lock( vid_android.window, &buffer, NULL ) ) |
|
|
|
|
return NULL; |
|
|
|
|
if( buffer.width < refState.width || buffer.height < refState.height ) |
|
|
|
|
return NULL; |
|
|
|
|
return buffer.bits; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void SW_UnlockBuffer( void ) |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
if( nw.unlockAndPost ) |
|
|
|
|
nw.unlockAndPost( vid_android.window ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
qboolean SW_CreateBuffer( int width, int height, uint *stride, uint *bpp, uint *r, uint *g, uint *b ) |
|
|
|
|
{ |
|
|
|
|
return false; |
|
|
|
|
ANativeWindow_Buffer buffer; |
|
|
|
|
int lock; |
|
|
|
|
if( !nw.lock || !vid_android.window ) |
|
|
|
|
return false; |
|
|
|
|
nw.unlockAndPost( vid_android.window ); |
|
|
|
|
|
|
|
|
|
if( ( lock = nw.lock( vid_android.window, &buffer, NULL ) ) ) |
|
|
|
|
{ |
|
|
|
|
Con_Printf("SW_CreateBuffer: lock %d\n", lock ); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
nw.unlockAndPost( vid_android.window ); |
|
|
|
|
Con_Printf("SW_CreateBuffer: buffer %d %d %x %d\n", buffer.width, buffer.height, buffer.format, buffer.stride ); |
|
|
|
|
if( width > buffer.width || height > buffer.height ) |
|
|
|
|
return false; |
|
|
|
|
if( buffer.format != WINDOW_FORMAT_RGB_565 ) |
|
|
|
|
return false; |
|
|
|
|
Con_Printf("SW_CreateBuffer: ok\n"); |
|
|
|
|
*stride = buffer.stride; |
|
|
|
|
|
|
|
|
|
*bpp = 2; |
|
|
|
|
*r = (((1 << 5) - 1) << (5+6)); |
|
|
|
|
*g = (((1 << 6) - 1) << (5)); |
|
|
|
|
*b = (((1 << 5) - 1) << (0)); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|