Android: fixed bug - EGL_SURFACE_TYPE is checked now. Added ConfigType.FASTEST and .BEST to AndroidHarness
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7685 75d07b2b-3a1a-0410-a2c5-0572b91ccdca3.0
parent
697a02e7c5
commit
fef0820ca6
@ -0,0 +1,359 @@ |
||||
package com.jme3.system.android; |
||||
|
||||
import java.util.logging.Logger; |
||||
|
||||
import javax.microedition.khronos.egl.EGL10; |
||||
import javax.microedition.khronos.egl.EGLConfig; |
||||
import javax.microedition.khronos.egl.EGLDisplay; |
||||
|
||||
import android.graphics.PixelFormat; |
||||
import android.opengl.GLSurfaceView.EGLConfigChooser; |
||||
|
||||
/** |
||||
* AndroidConfigChooser is used to determine the best suited EGL Config |
||||
* @author larynx |
||||
* |
||||
*/ |
||||
public class AndroidConfigChooser implements EGLConfigChooser |
||||
{ |
||||
private static final Logger logger = Logger.getLogger(AndroidConfigChooser.class.getName()); |
||||
|
||||
protected int clientOpenGLESVersion = 0; |
||||
protected EGLConfig bestConfig = null; |
||||
protected EGLConfig fastestConfig = null; |
||||
protected EGLConfig choosenConfig = null; |
||||
protected ConfigType type; |
||||
protected int pixelFormat; |
||||
|
||||
private final static int EGL_OPENGL_ES2_BIT = 4; |
||||
|
||||
public enum ConfigType |
||||
{ |
||||
/** |
||||
* RGB565, 0 alpha, 16 depth, 0 stencil |
||||
*/ |
||||
FASTEST, |
||||
/** |
||||
* RGB???, 0 alpha, 16 depth, 0 stencil |
||||
*/ |
||||
BEST |
||||
} |
||||
|
||||
public AndroidConfigChooser(ConfigType type) |
||||
{ |
||||
this.type = type; |
||||
} |
||||
|
||||
/** |
||||
* Gets called by the GLSurfaceView class to return the best config |
||||
*/ |
||||
@Override |
||||
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) |
||||
{ |
||||
return choosenConfig; |
||||
} |
||||
|
||||
/** |
||||
* findConfig is used to locate the best config and init the chooser with |
||||
* @param egl |
||||
* @param display |
||||
* @return true if successfull, false if no config was found |
||||
*/ |
||||
public boolean findConfig(EGL10 egl, EGLDisplay display) |
||||
{ |
||||
//Querying number of configurations
|
||||
int[] num_conf = new int[1]; |
||||
egl.eglGetConfigs(display, null, 0, num_conf); //if configuration array is null it still returns the number of configurations
|
||||
int configurations = num_conf[0]; |
||||
|
||||
//Querying actual configurations
|
||||
EGLConfig[] conf = new EGLConfig[configurations]; |
||||
egl.eglGetConfigs(display, conf, configurations, num_conf); |
||||
|
||||
|
||||
int[] value = new int[1]; |
||||
|
||||
// Loop over all configs to get the best
|
||||
for(int i = 0; i < configurations; i++) |
||||
{ |
||||
if (conf[i] != null) |
||||
{ |
||||
egl.eglGetConfigAttrib(display, conf[i], EGL10.EGL_SURFACE_TYPE, value); |
||||
// check if conf is a valid gl window
|
||||
if ((value[0] & EGL10.EGL_WINDOW_BIT) != 0) |
||||
{ |
||||
egl.eglGetConfigAttrib(display, conf[i], EGL10.EGL_DEPTH_SIZE, value); |
||||
// check if conf has a depth of 16
|
||||
if (value[0] == 16) |
||||
{ |
||||
egl.eglGetConfigAttrib(display, conf[i], EGL10.EGL_RENDERABLE_TYPE, value); |
||||
// Check if conf is OpenGL ES 2.0
|
||||
if ((value[0] & EGL_OPENGL_ES2_BIT) != 0) |
||||
{ |
||||
clientOpenGLESVersion = 2; // OpenGL ES 2.0 detected
|
||||
bestConfig = better(bestConfig, conf[i], egl, display); |
||||
fastestConfig = faster(fastestConfig, conf[i], egl, display); |
||||
|
||||
logger.info("Supported EGL Configuration #" + i ); |
||||
logEGLConfig(conf[i], display, egl); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
break; |
||||
} |
||||
} |
||||
|
||||
|
||||
if ((type == ConfigType.BEST) && (bestConfig != null)) |
||||
{ |
||||
logger.info("### JME3 ### using best EGL configuration available here: "); |
||||
choosenConfig = bestConfig; |
||||
} |
||||
else |
||||
{ |
||||
logger.info("### JME3 ### using fastest EGL configuration available here: "); |
||||
choosenConfig = fastestConfig; |
||||
} |
||||
|
||||
if (choosenConfig != null) |
||||
{ |
||||
logEGLConfig(choosenConfig, display, egl); |
||||
pixelFormat = getPixelFormat(choosenConfig, display, egl); |
||||
clientOpenGLESVersion = getOpenGLVersion(choosenConfig, display, egl); |
||||
return true; |
||||
} |
||||
else |
||||
{ |
||||
logger.severe("Unable to get a valid OpenGL ES 2.0 config"); |
||||
clientOpenGLESVersion = 1; |
||||
pixelFormat = PixelFormat.UNKNOWN; |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Returns the best of the two EGLConfig passed according to depth and colours |
||||
* @param a The first candidate |
||||
* @param b The second candidate |
||||
* @return The chosen candidate |
||||
*/ |
||||
private EGLConfig better(EGLConfig a, EGLConfig b, EGL10 egl, EGLDisplay display) |
||||
{ |
||||
if(a == null) return b; |
||||
|
||||
EGLConfig result = null; |
||||
|
||||
int[] value = new int[1]; |
||||
|
||||
// Choose highest color size
|
||||
egl.eglGetConfigAttrib(display, a, EGL10.EGL_RED_SIZE, value); |
||||
int redA = value[0]; |
||||
|
||||
egl.eglGetConfigAttrib(display, b, EGL10.EGL_RED_SIZE, value); |
||||
int redB = value[0]; |
||||
|
||||
if (redA > redB) |
||||
result = a; |
||||
else if (redA < redB) |
||||
result = b; |
||||
else // red size is equal
|
||||
{ |
||||
// Choose lowest alpha size
|
||||
egl.eglGetConfigAttrib(display, a, EGL10.EGL_ALPHA_SIZE, value); |
||||
int alphaA = value[0]; |
||||
|
||||
egl.eglGetConfigAttrib(display, b, EGL10.EGL_ALPHA_SIZE, value); |
||||
int alphaB = value[0]; |
||||
|
||||
if (alphaA < alphaB) |
||||
result = a; |
||||
else if (alphaA > alphaB) |
||||
result = b; |
||||
else // alpha is equal
|
||||
{ |
||||
// Choose lowest stencil size
|
||||
egl.eglGetConfigAttrib(display, a, EGL10.EGL_STENCIL_SIZE, value); |
||||
int stencilA = value[0]; |
||||
|
||||
egl.eglGetConfigAttrib(display, b, EGL10.EGL_STENCIL_SIZE, value); |
||||
int stencilB = value[0]; |
||||
|
||||
if (stencilA < stencilB) |
||||
result = a; |
||||
else |
||||
result = b; |
||||
} |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
/** |
||||
* Returns the fastest of the two EGLConfig passed according to depth and colours |
||||
* @param a The first candidate |
||||
* @param b The second candidate |
||||
* @return The chosen candidate |
||||
*/ |
||||
private EGLConfig faster(EGLConfig a, EGLConfig b, EGL10 egl, EGLDisplay display) |
||||
{ |
||||
if(a == null) return b; |
||||
|
||||
EGLConfig result = null; |
||||
|
||||
int[] value = new int[1]; |
||||
|
||||
// Choose highest color size
|
||||
egl.eglGetConfigAttrib(display, a, EGL10.EGL_RED_SIZE, value); |
||||
int redA = value[0]; |
||||
|
||||
egl.eglGetConfigAttrib(display, b, EGL10.EGL_RED_SIZE, value); |
||||
int redB = value[0]; |
||||
|
||||
if ((redA == 5) && (redB != 5)) |
||||
result = a; |
||||
else if ((redA != 5) && (redB == 5)) |
||||
result = b; |
||||
else // red size is equal
|
||||
{ |
||||
// Choose lowest alpha size
|
||||
egl.eglGetConfigAttrib(display, a, EGL10.EGL_ALPHA_SIZE, value); |
||||
int alphaA = value[0]; |
||||
|
||||
egl.eglGetConfigAttrib(display, b, EGL10.EGL_ALPHA_SIZE, value); |
||||
int alphaB = value[0]; |
||||
|
||||
if (alphaA < alphaB) |
||||
result = a; |
||||
else if (alphaA > alphaB) |
||||
result = b; |
||||
else // alpha is equal
|
||||
{ |
||||
// Choose lowest stencil size
|
||||
egl.eglGetConfigAttrib(display, a, EGL10.EGL_STENCIL_SIZE, value); |
||||
int stencilA = value[0]; |
||||
|
||||
egl.eglGetConfigAttrib(display, b, EGL10.EGL_STENCIL_SIZE, value); |
||||
int stencilB = value[0]; |
||||
|
||||
if (stencilA < stencilB) |
||||
result = a; |
||||
else |
||||
result = b; |
||||
} |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
private int getPixelFormat(EGLConfig conf, EGLDisplay display, EGL10 egl) |
||||
{ |
||||
int[] value = new int[1]; |
||||
int result = PixelFormat.RGB_565; |
||||
|
||||
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RED_SIZE, value); |
||||
if (value[0] == 8) |
||||
{ |
||||
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_ALPHA_SIZE, value); |
||||
if (value[0] == 8) |
||||
{ |
||||
result = PixelFormat.RGBA_8888; |
||||
} |
||||
else |
||||
{ |
||||
result = PixelFormat.RGB_888; |
||||
} |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
private int getOpenGLVersion(EGLConfig conf, EGLDisplay display, EGL10 egl) |
||||
{ |
||||
int[] value = new int[1]; |
||||
int result = 1; |
||||
|
||||
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RENDERABLE_TYPE, value); |
||||
// Check if conf is OpenGL ES 2.0
|
||||
if ((value[0] & EGL_OPENGL_ES2_BIT) != 0) |
||||
{ |
||||
result = 2; |
||||
} |
||||
|
||||
return result; |
||||
} |
||||
|
||||
/** |
||||
* log output with egl config details |
||||
* @param conf |
||||
* @param display |
||||
* @param egl |
||||
*/ |
||||
private void logEGLConfig(EGLConfig conf, EGLDisplay display, EGL10 egl) |
||||
{ |
||||
int[] value = new int[1]; |
||||
|
||||
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RED_SIZE, value); |
||||
logger.info(String.format("EGL_RED_SIZE = %d", value[0] ) ); |
||||
|
||||
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_GREEN_SIZE, value); |
||||
logger.info(String.format("EGL_GREEN_SIZE = %d", value[0] ) ); |
||||
|
||||
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_BLUE_SIZE, value); |
||||
logger.info(String.format("EGL_BLUE_SIZE = %d", value[0] ) ); |
||||
|
||||
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_ALPHA_SIZE, value); |
||||
logger.info(String.format("EGL_ALPHA_SIZE = %d", value[0] ) ); |
||||
|
||||
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_DEPTH_SIZE, value); |
||||
logger.info(String.format("EGL_DEPTH_SIZE = %d", value[0] ) ); |
||||
|
||||
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_STENCIL_SIZE, value); |
||||
logger.info(String.format("EGL_STENCIL_SIZE = %d", value[0] ) ); |
||||
|
||||
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RENDERABLE_TYPE, value); |
||||
logger.info(String.format("EGL_RENDERABLE_TYPE = %d", value[0] ) ); |
||||
|
||||
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_SURFACE_TYPE, value); |
||||
logger.info(String.format("EGL_SURFACE_TYPE = %d", value[0] ) ); |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
// Getter - Setter
|
||||
|
||||
public EGLConfig getBestConfig() |
||||
{ |
||||
return bestConfig; |
||||
} |
||||
|
||||
public void setBestConfig(EGLConfig bestConfig) |
||||
{ |
||||
this.bestConfig = bestConfig; |
||||
} |
||||
public EGLConfig getFastestConfig() |
||||
{ |
||||
return fastestConfig; |
||||
} |
||||
|
||||
public void setFastestConfig(EGLConfig fastestConfig) |
||||
{ |
||||
this.fastestConfig = fastestConfig; |
||||
} |
||||
|
||||
public int getClientOpenGLESVersion() |
||||
{ |
||||
return clientOpenGLESVersion; |
||||
} |
||||
|
||||
public void setClientOpenGLESVersion(int clientOpenGLESVersion) |
||||
{ |
||||
this.clientOpenGLESVersion = clientOpenGLESVersion; |
||||
} |
||||
|
||||
public int getPixelFormat() |
||||
{ |
||||
return pixelFormat; |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue