mirror of https://github.com/FWGS/xash3d-fwgs
platform/android: implement native software blitter, fix lost context on resize, fix safegl
This commit is contained in:
parent
c80da05e94
commit
4515d3e3cb
|
@ -20,8 +20,7 @@ GNU General Public License for more details.
|
|||
#include "platform/android/android_priv.h"
|
||||
#include "errno.h"
|
||||
#include <pthread.h>
|
||||
#include <android/native_window.h>
|
||||
#include <android/native_window_jni.h>
|
||||
#include <sys/prctl.h>
|
||||
|
||||
#ifndef JNICALL
|
||||
#define JNICALL // a1ba: workaround for my IDE, where Java files are not included
|
||||
|
@ -89,7 +88,6 @@ typedef enum event_type
|
|||
event_ondestroy,
|
||||
event_onresume,
|
||||
event_onfocuschange,
|
||||
event_setwindow,
|
||||
} eventtype_t;
|
||||
|
||||
typedef struct touchevent_s
|
||||
|
@ -142,7 +140,6 @@ typedef struct event_s
|
|||
joyaxis_t axis;
|
||||
joybutton_t button;
|
||||
keyevent_t key;
|
||||
ANativeWindow *window;
|
||||
};
|
||||
} event_t;
|
||||
|
||||
|
@ -163,7 +160,6 @@ static struct {
|
|||
} events = { PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER };
|
||||
|
||||
struct jnimethods_s jni;
|
||||
struct nativeegl_s negl;
|
||||
struct jnimouse_s jnimouse;
|
||||
|
||||
#define Android_Lock() pthread_mutex_lock(&events.mutex);
|
||||
|
@ -265,6 +261,7 @@ DECLARE_JNI_INTERFACE( int, nativeInit, jobject array )
|
|||
jni.getGLAttribute = (*env)->GetStaticMethodID(env, jni.actcls, "getGLAttribute", "(I)I");
|
||||
jni.deleteGLContext = (*env)->GetStaticMethodID(env, jni.actcls, "deleteGLContext", "()Z");
|
||||
jni.getSelectedPixelFormat = (*env)->GetStaticMethodID(env, jni.actcls, "getSelectedPixelFormat", "()I");
|
||||
jni.getSurface = (*env)->GetStaticMethodID(env, jni.actcls, "getNativeSurface", "()Landroid/view/Surface;");
|
||||
|
||||
/* Run the application. */
|
||||
|
||||
|
@ -570,24 +567,6 @@ DECLARE_JNI_INTERFACE( int, nativeTestWritePermission, jstring jPath )
|
|||
return ret;
|
||||
}
|
||||
|
||||
DECLARE_JNI_INTERFACE( void, nativeSetSurface, jobject surface )
|
||||
{
|
||||
Android_Lock();
|
||||
if( surface )
|
||||
{
|
||||
negl.window = ANativeWindow_fromSurface( env, surface );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( negl.window )
|
||||
{
|
||||
ANativeWindow_release( negl.window );
|
||||
negl.window = NULL;
|
||||
}
|
||||
}
|
||||
Android_Unlock();
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL JNI_OnLoad( JavaVM *vm, void *reserved )
|
||||
{
|
||||
return JNI_VERSION_1_6;
|
||||
|
@ -863,10 +842,10 @@ void Platform_RunEvents( void )
|
|||
// destroy EGL surface when hiding application
|
||||
if( !events.queue[i].arg )
|
||||
{
|
||||
host.status = HOST_FRAME;
|
||||
SNDDMA_Activate( true );
|
||||
(*jni.env)->CallStaticVoidMethod( jni.env, jni.actcls, jni.toggleEGL, 1 );
|
||||
Android_UpdateSurface();
|
||||
// (*jni.env)->CallStaticVoidMethod( jni.env, jni.actcls, jni.toggleEGL, 1 );
|
||||
Android_UpdateSurface( true );
|
||||
host.status = HOST_FRAME;
|
||||
SetBits( gl_vsync->flags, FCVAR_CHANGED ); // set swap interval
|
||||
host.force_draw_version = true;
|
||||
host.force_draw_version_time = host.realtime + FORCE_DRAW_VERSION_TIME;
|
||||
|
@ -876,8 +855,8 @@ void Platform_RunEvents( void )
|
|||
{
|
||||
host.status = HOST_NOFOCUS;
|
||||
SNDDMA_Activate( false );
|
||||
(*jni.env)->CallStaticVoidMethod( jni.env, jni.actcls, jni.toggleEGL, 0 );
|
||||
negl.valid = false;
|
||||
Android_UpdateSurface( false );
|
||||
// (*jni.env)->CallStaticVoidMethod( jni.env, jni.actcls, jni.toggleEGL, 0 );
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -885,9 +864,9 @@ void Platform_RunEvents( void )
|
|||
// reinitialize EGL and change engine screen size
|
||||
if( host.status == HOST_FRAME &&( refState.width != jni.width || refState.height != jni.height ) )
|
||||
{
|
||||
(*jni.env)->CallStaticVoidMethod( jni.env, jni.actcls, jni.toggleEGL, 0 );
|
||||
(*jni.env)->CallStaticVoidMethod( jni.env, jni.actcls, jni.toggleEGL, 1 );
|
||||
Android_UpdateSurface();
|
||||
// (*jni.env)->CallStaticVoidMethod( jni.env, jni.actcls, jni.toggleEGL, 0 );
|
||||
// (*jni.env)->CallStaticVoidMethod( jni.env, jni.actcls, jni.toggleEGL, 1 );
|
||||
Android_UpdateSurface( true );
|
||||
SetBits( gl_vsync->flags, FCVAR_CHANGED ); // set swap interval
|
||||
VID_SetMode();
|
||||
}
|
||||
|
@ -957,9 +936,6 @@ void Platform_RunEvents( void )
|
|||
host.force_draw_version = true;
|
||||
host.force_draw_version_time = host.realtime + FORCE_DRAW_VERSION_TIME;
|
||||
break;
|
||||
case event_setwindow:
|
||||
negl.window = events.queue[i].window;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include <EGL/egl.h>
|
||||
#include <android/log.h>
|
||||
#include <jni.h>
|
||||
#include <sys/prctl.h>
|
||||
|
||||
extern struct jnimethods_s
|
||||
{
|
||||
|
@ -29,21 +28,10 @@ extern struct jnimethods_s
|
|||
jmethodID getGLAttribute;
|
||||
jmethodID deleteGLContext;
|
||||
jmethodID getSelectedPixelFormat;
|
||||
jmethodID getSurface;
|
||||
int width, height;
|
||||
} jni;
|
||||
|
||||
extern struct nativeegl_s
|
||||
{
|
||||
qboolean valid;
|
||||
void *window;
|
||||
EGLDisplay dpy;
|
||||
EGLSurface surface;
|
||||
EGLContext context;
|
||||
EGLConfig cfg;
|
||||
EGLint numCfg;
|
||||
|
||||
const char *extensions;
|
||||
} negl;
|
||||
|
||||
extern struct jnimouse_s
|
||||
{
|
||||
|
@ -53,6 +41,6 @@ extern struct jnimouse_s
|
|||
//
|
||||
// vid_android.c
|
||||
//
|
||||
void Android_UpdateSurface( void );
|
||||
void Android_UpdateSurface( qboolean active );
|
||||
|
||||
#endif // ANDROID_PRIV_H
|
||||
|
|
|
@ -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
|
|||
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 )
|
|||
{
|
||||
if( negl.valid )
|
||||
{
|
||||
eglSwapBuffers( negl.dpy, negl.surface );
|
||||
egl.SwapBuffers( negl.dpy, negl.surface );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -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 )
|
|||
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 )
|
|||
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,7 +292,12 @@ 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" );
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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 )
|
|||
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 )
|
|||
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 )
|
|||
|
||||
/*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 )
|
|||
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 )
|
|||
|
||||
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 )
|
|||
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
|
|||
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 )
|
|||
|
||||
void *SW_LockBuffer( void )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ def configure(conf):
|
|||
if not conf.check_cc( fragment='int main(){ int i = socket();}', lib = 'wattcpwl', mandatory=False ):
|
||||
conf.define('XASH_NO_NETWORK',1)
|
||||
elif conf.env.DEST_OS == 'android': # Android doesn't need SDL2
|
||||
for i in ['android', 'log', 'EGL']:
|
||||
for i in ['log']:
|
||||
conf.check_cc(lib = i)
|
||||
elif conf.options.FBDEV_SW:
|
||||
# unused, XASH_LINUX without XASH_SDL gives fbdev & alsa support
|
||||
|
@ -130,7 +130,7 @@ def build(bld):
|
|||
is_cxx_link = True
|
||||
|
||||
if bld.env.DEST_OS == 'android':
|
||||
libs += ['LOG', 'EGL', 'ANDROID']
|
||||
libs += ['LOG']
|
||||
source += bld.path.ant_glob(['platform/android/*.cpp', 'platform/android/*.c', 'platform/linux/*.c'])
|
||||
|
||||
# add client files
|
||||
|
|
Loading…
Reference in New Issue