@ -2,9 +2,8 @@ package com.jme3.system.android;
import android.graphics.PixelFormat ;
import android.graphics.PixelFormat ;
import android.opengl.GLSurfaceView.EGLConfigChooser ;
import android.opengl.GLSurfaceView.EGLConfigChooser ;
import com.jme3.renderer.android.RendererUtil ;
import com.jme3.system.AppSettings ;
import com.jme3.system.AppSettings ;
import java.util.ArrayList ;
import java.util.List ;
import java.util.logging.Level ;
import java.util.logging.Level ;
import java.util.logging.Logger ;
import java.util.logging.Logger ;
import javax.microedition.khronos.egl.EGL10 ;
import javax.microedition.khronos.egl.EGL10 ;
@ -20,9 +19,6 @@ public class AndroidConfigChooser implements EGLConfigChooser {
private static final Logger logger = Logger . getLogger ( AndroidConfigChooser . class . getName ( ) ) ;
private static final Logger logger = Logger . getLogger ( AndroidConfigChooser . class . getName ( ) ) ;
public final static String SETTINGS_CONFIG_TYPE = "configType" ;
public final static String SETTINGS_CONFIG_TYPE = "configType" ;
protected int clientOpenGLESVersion = 0 ;
protected EGLConfig bestConfig = null ;
protected EGLConfig fastestConfig = null ;
protected EGLConfig choosenConfig = null ;
protected EGLConfig choosenConfig = null ;
protected AppSettings settings ;
protected AppSettings settings ;
protected int pixelFormat ;
protected int pixelFormat ;
@ -91,14 +87,30 @@ public class AndroidConfigChooser implements EGLConfigChooser {
this . settings = settings ;
this . settings = settings ;
}
}
private static int eglGetConfigAttribSafe ( EGL10 egl , EGLDisplay display , EGLConfig config , int attribute ) {
int [ ] value = new int [ 1 ] ;
if ( ! egl . eglGetConfigAttrib ( display , config , attribute , value ) ) {
RendererUtil . checkEGLError ( egl ) ;
throw new AssertionError ( ) ;
}
return value [ 0 ] ;
}
/ * *
/ * *
* Gets called by the GLSurfaceView class to return the best config
* Gets called by the GLSurfaceView class to return the best config
* /
* /
@Override
@Override
public EGLConfig chooseConfig ( EGL10 egl , EGLDisplay display ) {
public EGLConfig chooseConfig ( EGL10 egl , EGLDisplay display ) {
logger . fine ( "GLSurfaceView asking for egl config" ) ;
boolean configFound = findConfig ( egl , display ) ;
if ( configFound ) {
logger . fine ( "GLSurfaceView asks for egl config, returning: " ) ;
logger . fine ( "GLSurfaceView asks for egl config, returning: " ) ;
logEGLConfig ( choosenConfig , display , egl , Level . FINE ) ;
logEGLConfig ( choosenConfig , display , egl , Level . FINE ) ;
return choosenConfig ;
return choosenConfig ;
} else {
logger . fine ( "GLSurfaceView asks for egl config, No config found" ) ;
return null ;
}
}
}
/ * *
/ * *
@ -108,7 +120,7 @@ public class AndroidConfigChooser implements EGLConfigChooser {
* @param display
* @param display
* @return true if successfull , false if no config was found
* @return true if successfull , false if no config was found
* /
* /
public boolean findConfig ( EGL10 egl , EGLDisplay display ) {
private boolean findConfig ( EGL10 egl , EGLDisplay display ) {
ConfigType type = ( ConfigType ) settings . get ( SETTINGS_CONFIG_TYPE ) ;
ConfigType type = ( ConfigType ) settings . get ( SETTINGS_CONFIG_TYPE ) ;
ComponentSizeChooser compChooser = new ComponentSizeChooser ( type , settings . getSamples ( ) ) ;
ComponentSizeChooser compChooser = new ComponentSizeChooser ( type , settings . getSamples ( ) ) ;
@ -116,48 +128,46 @@ public class AndroidConfigChooser implements EGLConfigChooser {
logger . log ( Level . FINE , "JME3 using {0} EGL configuration available here: " , type . name ( ) ) ;
logger . log ( Level . FINE , "JME3 using {0} EGL configuration available here: " , type . name ( ) ) ;
if ( choosenConfig ! = null ) {
if ( choosenConfig ! = null ) {
// Remember the display for which we have the EGLConfig for
logger . info ( "JME3 using choosen config: " ) ;
logger . info ( "JME3 using choosen config: " ) ;
logEGLConfig ( choosenConfig , display , egl , Level . INFO ) ;
logEGLConfig ( choosenConfig , display , egl , Level . INFO ) ;
pixelFormat = getPixelFormat ( choosenConfig , display , egl ) ;
pixelFormat = getPixelFormat ( choosenConfig , display , egl ) ;
clientOpenGLESVersion = getOpenGLVersion ( choosenConfig , display , egl ) ;
return true ;
return true ;
} else {
} else {
logger . severe ( "ERROR: Unable to get a valid OpenGL ES 2.0 config, neither Fastest nor Best found! Bug. Please report this." ) ;
logger . severe ( "ERROR: Unable to get a valid OpenGL ES 2.0 config, neither Fastest nor Best found! Bug. Please report this." ) ;
clientOpenGLESVersion = 1 ;
pixelFormat = PixelFormat . UNKNOWN ;
pixelFormat = PixelFormat . UNKNOWN ;
return false ;
return false ;
}
}
}
}
private int getPixelFormat ( EGLConfig conf , EGLDisplay display , EGL10 egl ) {
private int getPixelFormat ( EGLConfig conf , EGLDisplay display , EGL10 egl ) {
int [ ] value = new int [ 1 ] ;
//Android Pixel format is not very well documented.
//Android Pixel format is not very well documented.
//From what i gathered, the format is chosen automatically except for the alpha channel
//From what i gathered, the format is chosen automatically except for the alpha channel
//if the alpha channel has 8 bit or more, e set the pixel format to Transluscent, as it allow transparent view background
//if the alpha channel has 8 bit or more, e set the pixel format to Transluscent, as it allow transparent view background
//if it's 0 bit, the format is OPAQUE otherwise it's TRANSPARENT
//if it's 0 bit, the format is OPAQUE otherwise it's TRANSPARENT
egl . eglGetConfigAttrib ( display , conf , EGL10 . EGL_ALPHA_SIZE , value ) ;
int result = eglGetConfigAttribSafe ( egl , display , conf , EGL10 . EGL_ALPHA_SIZE ) ;
if ( value [ 0 ] > = 8 ) {
if ( result > = 8 ) {
logger . log ( Level . FINE , "Pixel Format: TRANSLUCENT" ) ;
return PixelFormat . TRANSLUCENT ;
return PixelFormat . TRANSLUCENT ;
}
}
if ( value [ 0 ] > = 1 ) {
if ( result > = 1 ) {
logger . log ( Level . FINE , "Pixel Format: TRANSPARENT" ) ;
return PixelFormat . TRANSPARENT ;
return PixelFormat . TRANSPARENT ;
}
}
logger . log ( Level . FINE , "Pixel Format: OPAQUE" ) ;
return PixelFormat . OPAQUE ;
return PixelFormat . OPAQUE ;
}
}
private int getOpenGLVersion ( EGLConfig conf , EGLDisplay display , EGL10 egl ) {
private int getOpenGLVersion ( EGLConfig conf , EGLDisplay display , EGL10 egl ) {
int [ ] value = new int [ 1 ] ;
int val = eglGetConfigAttribSafe ( egl , display , conf , EGL10 . EGL_RENDERABLE_TYPE ) ;
int result = 1 ;
egl . eglGetConfigAttrib ( display , conf , EGL10 . EGL_RENDERABLE_TYPE , value ) ;
// Check if conf is OpenGL ES 2.0
// Check if conf is OpenGL ES 2.0
if ( ( value [ 0 ] & EGL_OPENGL_ES2_BIT ) ! = 0 ) {
if ( ( val & EGL_OPENGL_ES2_BIT ) ! = 0 ) {
result = 2 ;
return 2 ;
} else {
return 1 ;
}
}
return result ;
}
}
/ * *
/ * *
@ -167,50 +177,37 @@ public class AndroidConfigChooser implements EGLConfigChooser {
* @param display
* @param display
* @param egl
* @param egl
* /
* /
public void logEGLConfig ( EGLConfig conf , EGLDisplay display , EGL10 egl , Level level ) {
private void logEGLConfig ( EGLConfig conf , EGLDisplay display , EGL10 egl , Level level ) {
int [ ] value = new int [ 1 ] ;
egl . eglGetConfigAttrib ( display , conf , EGL10 . EGL_RED_SIZE , value ) ;
logger . log ( level , String . format ( "EGL_RED_SIZE = %d" , value [ 0 ] ) ) ;
egl . eglGetConfigAttrib ( display , conf , EGL10 . EGL_GREEN_SIZE , value ) ;
logger . log ( level , "EGL_RED_SIZE = {0}" ,
logger . log ( level , String . format ( "EGL_GREEN_SIZE = %d" , value [ 0 ] ) ) ;
eglGetConfigAttribSafe ( egl , display , conf , EGL10 . EGL_RED_SIZE ) ) ;
egl . eglGetConfigAttrib ( display , conf , EGL10 . EGL_BLUE_SIZE , value ) ;
logger . log ( level , "EGL_GREEN_SIZE = {0}" ,
logger . log ( level , String . format ( "EGL_BLUE_SIZE = %d" , value [ 0 ] ) ) ;
eglGetConfigAttribSafe ( egl , display , conf , EGL10 . EGL_GREEN_SIZE ) ) ;
egl . eglGetConfigAttrib ( display , conf , EGL10 . EGL_ALPHA_SIZE , value ) ;
logger . log ( level , "EGL_BLUE_SIZE = {0}" ,
logger . log ( level , String . format ( "EGL_ALPHA_SIZE = %d" , value [ 0 ] ) ) ;
eglGetConfigAttribSafe ( egl , display , conf , EGL10 . EGL_BLUE_SIZE ) ) ;
egl . eglGetConfigAttrib ( display , conf , EGL10 . EGL_DEPTH_SIZE , value ) ;
logger . log ( level , "EGL_ALPHA_SIZE = {0}" ,
logger . log ( level , String . format ( "EGL_DEPTH_SIZE = %d" , value [ 0 ] ) ) ;
eglGetConfigAttribSafe ( egl , display , conf , EGL10 . EGL_ALPHA_SIZE ) ) ;
egl . eglGetConfigAttrib ( display , conf , EGL10 . EGL_STENCIL_SIZE , value ) ;
logger . log ( level , "EGL_DEPTH_SIZE = {0}" ,
logger . log ( level , String . format ( "EGL_STENCIL_SIZE = %d" , value [ 0 ] ) ) ;
eglGetConfigAttribSafe ( egl , display , conf , EGL10 . EGL_DEPTH_SIZE ) ) ;
egl . eglGetConfigAttrib ( display , conf , EGL10 . EGL_RENDERABLE_TYPE , value ) ;
logger . log ( level , "EGL_STENCIL_SIZE = {0}" ,
logger . log ( level , String . format ( "EGL_RENDERABLE_TYPE = %d" , value [ 0 ] ) ) ;
eglGetConfigAttribSafe ( egl , display , conf , EGL10 . EGL_STENCIL_SIZE ) ) ;
egl . eglGetConfigAttrib ( display , conf , EGL10 . EGL_SURFACE_TYPE , value ) ;
logger . log ( level , "EGL_RENDERABLE_TYPE = {0}" ,
logger . log ( level , String . format ( "EGL_SURFACE_TYPE = %d" , value [ 0 ] ) ) ;
eglGetConfigAttribSafe ( egl , display , conf , EGL10 . EGL_RENDERABLE_TYPE ) ) ;
egl . eglGetConfigAttrib ( display , conf , EGL10 . EGL_SAMPLE_BUFFERS , value ) ;
logger . log ( level , "EGL_SURFACE_TYPE = {0}" ,
logger . log ( level , String . format ( "EGL_SAMPLE_BUFFERS = %d" , value [ 0 ] ) ) ;
eglGetConfigAttribSafe ( egl , display , conf , EGL10 . EGL_SURFACE_TYPE ) ) ;
egl . eglGetConfigAttrib ( display , conf , EGL10 . EGL_SAMPLES , value ) ;
logger . log ( level , String . format ( "EGL_SAMPLES = %d" , value [ 0 ] ) ) ;
}
public int getClientOpenGLESVersion ( ) {
logger . log ( level , "EGL_SAMPLE_BUFFERS = {0}" ,
return clientOpenGLESVersion ;
eglGetConfigAttribSafe ( egl , display , conf , EGL10 . EGL_SAMPLE_BUFFERS ) ) ;
}
public void setClientOpenGLESVersion ( int clientOpenGLESVersion ) {
this . clientOpenGLESVersion = clientOpenGLESVersion ;
}
public int getPixelFormat ( ) {
logger . log ( level , "EGL_SAMPLES = {0}" ,
return pixelFormat ;
eglGetConfigAttribSafe ( egl , display , conf , EGL10 . EGL_SAMPLES ) ) ;
}
}
private abstract class BaseConfigChooser implements EGLConfigChooser {
private abstract class BaseConfigChooser implements EGLConfigChooser {
@ -226,11 +223,17 @@ public class AndroidConfigChooser implements EGLConfigChooser {
EGL10 . EGL_RENDERABLE_TYPE , EGL_OPENGL_ES2_BIT ,
EGL10 . EGL_RENDERABLE_TYPE , EGL_OPENGL_ES2_BIT ,
EGL10 . EGL_NONE } ;
EGL10 . EGL_NONE } ;
egl . eglChooseConfig ( display , configSpec , null , 0 , num_config ) ;
if ( ! egl . eglChooseConfig ( display , configSpec , null , 0 , num_config ) ) {
RendererUtil . checkEGLError ( egl ) ;
throw new AssertionError ( ) ;
}
int numConfigs = num_config [ 0 ] ;
int numConfigs = num_config [ 0 ] ;
EGLConfig [ ] configs = new EGLConfig [ numConfigs ] ;
EGLConfig [ ] configs = new EGLConfig [ numConfigs ] ;
egl . eglChooseConfig ( display , configSpec , configs , numConfigs , num_config ) ;
if ( ! egl . eglChooseConfig ( display , configSpec , configs , numConfigs , num_config ) ) {
RendererUtil . checkEGLError ( egl ) ;
throw new AssertionError ( ) ;
}
logger . fine ( "--------------Display Configurations---------------" ) ;
logger . fine ( "--------------Display Configurations---------------" ) ;
for ( EGLConfig eGLConfig : configs ) {
for ( EGLConfig eGLConfig : configs ) {
@ -252,12 +255,10 @@ public class AndroidConfigChooser implements EGLConfigChooser {
* /
* /
private class ComponentSizeChooser extends BaseConfigChooser {
private class ComponentSizeChooser extends BaseConfigChooser {
private int [ ] mValue ;
private ConfigType configType ;
private ConfigType configType ;
protected int mSamples ;
protected int mSamples ;
public ComponentSizeChooser ( ConfigType configType , int samples ) {
public ComponentSizeChooser ( ConfigType configType , int samples ) {
mValue = new int [ 1 ] ;
mSamples = samples ;
mSamples = samples ;
this . configType = configType ;
this . configType = configType ;
}
}
@ -272,22 +273,22 @@ public class AndroidConfigChooser implements EGLConfigChooser {
// first pass through config list. Try to find an exact match.
// first pass through config list. Try to find an exact match.
for ( EGLConfig config : configs ) {
for ( EGLConfig config : configs ) {
int r = findConfigAttrib ( egl , display , config ,
int r = eglGetConfigAttribSafe ( egl , display , config ,
EGL10 . EGL_RED_SIZE , 0 ) ;
EGL10 . EGL_RED_SIZE ) ;
int g = findConfigAttrib ( egl , display , config ,
int g = eglGetConfigAttribSafe ( egl , display , config ,
EGL10 . EGL_GREEN_SIZE , 0 ) ;
EGL10 . EGL_GREEN_SIZE ) ;
int b = findConfigAttrib ( egl , display , config ,
int b = eglGetConfigAttribSafe ( egl , display , config ,
EGL10 . EGL_BLUE_SIZE , 0 ) ;
EGL10 . EGL_BLUE_SIZE ) ;
int a = findConfigAttrib ( egl , display , config ,
int a = eglGetConfigAttribSafe ( egl , display , config ,
EGL10 . EGL_ALPHA_SIZE , 0 ) ;
EGL10 . EGL_ALPHA_SIZE ) ;
int d = findConfigAttrib ( egl , display , config ,
int d = eglGetConfigAttribSafe ( egl , display , config ,
EGL10 . EGL_DEPTH_SIZE , 0 ) ;
EGL10 . EGL_DEPTH_SIZE ) ;
int s = findConfigAttrib ( egl , display , config ,
int s = eglGetConfigAttribSafe ( egl , display , config ,
EGL10 . EGL_STENCIL_SIZE , 0 ) ;
EGL10 . EGL_STENCIL_SIZE ) ;
int isMs = findConfigAttrib ( egl , display , config ,
int isMs = eglGetConfigAttribSafe ( egl , display , config ,
EGL10 . EGL_SAMPLE_BUFFERS , 0 ) ;
EGL10 . EGL_SAMPLE_BUFFERS ) ;
int nbMs = findConfigAttrib ( egl , display , config ,
int nbMs = eglGetConfigAttribSafe ( egl , display , config ,
EGL10 . EGL_SAMPLES , 0 ) ;
EGL10 . EGL_SAMPLES ) ;
if ( inRange ( r , configType . mr , configType . r )
if ( inRange ( r , configType . mr , configType . r )
& & inRange ( g , configType . mg , configType . g )
& & inRange ( g , configType . mg , configType . g )
@ -349,8 +350,8 @@ public class AndroidConfigChooser implements EGLConfigChooser {
// failsafe. pick the 1st config with a 16 bit depth buffer.
// failsafe. pick the 1st config with a 16 bit depth buffer.
for ( EGLConfig config : configs ) {
for ( EGLConfig config : configs ) {
int d = findConfigAttrib ( egl , display , config ,
int d = eglGetConfigAttribSafe ( egl , display , config ,
EGL10 . EGL_DEPTH_SIZE , 0 ) ;
EGL10 . EGL_DEPTH_SIZE ) ;
if ( d > = 16 ) {
if ( d > = 16 ) {
return config ;
return config ;
}
}
@ -363,15 +364,6 @@ public class AndroidConfigChooser implements EGLConfigChooser {
private boolean inRange ( int val , int min , int max ) {
private boolean inRange ( int val , int min , int max ) {
return min < = val & & val < = max ;
return min < = val & & val < = max ;
}
}
private int findConfigAttrib ( EGL10 egl , EGLDisplay display ,
EGLConfig config , int attribute , int defaultValue ) {
if ( egl . eglGetConfigAttrib ( display , config , attribute , mValue ) ) {
return mValue [ 0 ] ;
}
return defaultValue ;
}
}
}
//DON'T REMOVE THIS, USED FOR UNIT TESTING FAILING CONFIGURATION LISTS.
//DON'T REMOVE THIS, USED FOR UNIT TESTING FAILING CONFIGURATION LISTS.
// private static class Config {
// private static class Config {