该版本的Android 2.2.1是该设备是三星Galaxy II全面崩溃日志是:
java.lang.RuntimeException: createWindowSurface failed: EGL_BAD_MATCH
at android.opengl.GLSurfaceView$EglHelper.throwEglException(GLSurfaceView.java:1077)
at android.opengl.GLSurfaceView$EglHelper.createSurface(GLSurfaceView.java:981)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1304)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1116)
这是相关代码到崩溃:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
glView = new GLSurfaceView(this);
glView.setEGLConfigChooser(8 , 8, 8, 8, 16, 0);
glView.setRenderer(this);
setContentView(glView);
\\etc..............}
我用setEGLConfigChooser(),因为该应用程序将在API-17崩溃,如果它不是在那里所以它在我一直在寻找周围轰然这个特定的设备,它有什么做的的PixelFormat的设备。
什么即时知道是我可以使用一些代码,所以这不会对三星Galaxy II的Android 2.2.1版本崩溃,我不能在模拟器中测试这一点,我没有设备在测试它,我只是需要确保代码和IM不知道如何去改变它呢?
Update: I found a way to work around this issue and actually it is fairly straightforward.
First of all: Android's default EGLConfigChooser
implementation makes bad decisions on some
devices. Especially the older Android devices seem to suffer this EGL_BAD_MATCH
issue. During my debugging sessions I also discovered that those older troublemaker devices had quite a limited set of available OpenGL ES configurations.
The cause of this "bad match" problem is more than just a mismatch between the GLSurfaceView's pixel format and the color bit depth settings of OpenGL ES. Overall we have to deal with the following issues:
- A mismatch of the OpenGL ES API version
- A mismatch of the requested target surface type
- The requested color bit depth cannot be rendered on the surface view
The Android developer documentation is severely lacking when it comes to explaining the OpenGL ES API. It is therefore important to read the original documentation over at Khronos.org. Especially the doc page about eglChooseConfig is helpful here.
In order to remedy above listed problems you have to make sure to specify the following minimum configuration:
EGL_RENDERABLE_TYPE
must match the OpenGL ES API version you are using. In the likely case of OpenGL ES 2.x you must set that attribute to 4
(see egl.h
)
EGL_SURFACE_TYPE
should have the EGL_WINDOW_BIT
set
And of course you also want to set up an OpenGL ES context that provides you with the correct color, depth and stencil buffer settings.
Unfortunately it is not possible to cherry-pick these configuration options in a straightforward way. We have to choose from whatever is available on any given device. That's why it is necessary to implement a custom EGLConfigChooser
, that goes through the list of available configuration sets and picks the most suitable one that matches best the given criteria.
Anyway, I whipped up a sample implementation for such a config chooser:
public class MyConfigChooser implements EGLConfigChooser {
final private static String TAG = "MyConfigChooser";
// This constant is not defined in the Android API, so we need to do that here:
final private static int EGL_OPENGL_ES2_BIT = 4;
// Our minimum requirements for the graphics context
private static int[] mMinimumSpec = {
// We want OpenGL ES 2 (or set it to any other version you wish)
EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
// We want to render to a window
EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT,
// We do not want a translucent window, otherwise the
// home screen or activity in the background may shine through
EGL10.EGL_TRANSPARENT_TYPE, EGL10.EGL_NONE,
// indicate that this list ends:
EGL10.EGL_NONE
};
private int[] mValue = new int[1];
protected int mAlphaSize;
protected int mBlueSize;
protected int mDepthSize;
protected int mGreenSize;
protected int mRedSize;
protected int mStencilSize;
/**
* The constructor lets you specify your minimum pixel format,
* depth and stencil buffer requirements.
*/
public MyConfigChooser(int r, int g, int b, int a, int depth, int
stencil) {
mRedSize = r;
mGreenSize = g;
mBlueSize = b;
mAlphaSize = a;
mDepthSize = depth;
mStencilSize = stencil;
}
@Override
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
int[] arg = new int[1];
egl.eglChooseConfig(display, mMinimumSpec, null, 0, arg);
int numConfigs = arg[0];
Log.i(TAG, "%d configurations available", numConfigs);
if(numConfigs <= 0) {
// Ooops... even the minimum spec is not available here
return null;
}
EGLConfig[] configs = new EGLConfig[numConfigs];
egl.eglChooseConfig(display, mMinimumSpec, configs,
numConfigs, arg);
// Let's do the hard work now (see next method below)
EGLConfig chosen = chooseConfig(egl, display, configs);
if(chosen == null) {
throw new RuntimeException(
"Could not find a matching configuration out of "
+ configs.length + " available.",
configs);
}
// Success
return chosen;
}
/**
* This method iterates through the list of configurations that
* fulfill our minimum requirements and tries to pick one that matches best
* our requested color, depth and stencil buffer requirements that were set using
* the constructor of this class.
*/
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
EGLConfig[] configs) {
EGLConfig bestMatch = null;
int bestR = Integer.MAX_VALUE, bestG = Integer.MAX_VALUE,
bestB = Integer.MAX_VALUE, bestA = Integer.MAX_VALUE,
bestD = Integer.MAX_VALUE, bestS = Integer.MAX_VALUE;
for(EGLConfig config : configs) {
int r = findConfigAttrib(egl, display, config,
EGL10.EGL_RED_SIZE, 0);
int g = findConfigAttrib(egl, display, config,
EGL10.EGL_GREEN_SIZE, 0);
int b = findConfigAttrib(egl, display, config,
EGL10.EGL_BLUE_SIZE, 0);
int a = findConfigAttrib(egl, display, config,
EGL10.EGL_ALPHA_SIZE, 0);
int d = findConfigAttrib(egl, display, config,
EGL10.EGL_DEPTH_SIZE, 0);
int s = findConfigAttrib(egl, display, config,
EGL10.EGL_STENCIL_SIZE, 0);
if(r <= bestR && g <= bestG && b <= bestB && a <= bestA
&& d <= bestD && s <= bestS && r >= mRedSize
&& g >= mGreenSize && b >= mBlueSize
&& a >= mAlphaSize && d >= mDepthSize
&& s >= mStencilSize) {
bestR = r;
bestG = g;
bestB = b;
bestA = a;
bestD = d;
bestS = s;
bestMatch = config;
}
}
return bestMatch;
}
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;
}
}
我没有信誉评分添加评论还没有,不然我会穿上Nobu餐厅游戏的回答简短的评论。 我遇到这个同样的错误EGL_BAD_MATCH和他们的答案帮助让我在正确的道路上。 相反,我要创建一个单独的答案。
随着游戏的Nobu提及,似乎是GLSurfaceView的的PixelFormat,并传递到像素格式参数之间的不匹配setEGLConfigChooser()
。 就我而言,我是问了RGBA8888但我GLSurfaceView是RGB565。 这后来导致我的初始化中EGL_BAD_MATCH错误。
增强他们的回答是,你可以得到的窗口中选择所需的PixelFormat,并用它来动态地选择一个EGL上下文。
为了让我的代码尽可能通用,我改变了GLSurfaceView采取额外的参数 - 显示屏的像素格式。 我通过调用得到这个从我的活动:
getWindowManager().getDefaultDisplay().getPixelFormat();
我通过该值下降到GLSurfaceView然后提取每个RGBA的这样的最佳位深度:
if (pixelFormatVal > 0) {
PixelFormat info = new PixelFormat();
PixelFormat.getPixelFormatInfo(pixelFormatVal, info);
if (PixelFormat.formatHasAlpha(pixelFormatVal)) {
if (info.bitsPerPixel >= 24) {
m_desiredABits = 8;
} else {
m_desiredABits = 6; // total guess
}
} else {
m_desiredABits = 0;
}
if (info.bitsPerPixel >= 24) {
m_desiredRBits = 8;
m_desiredGBits = 8;
m_desiredBBits = 8;
} else if (info.bitsPerPixel >= 16) {
m_desiredRBits = 5;
m_desiredGBits = 6;
m_desiredRBits = 5;
} else {
m_desiredRBits = 4;
m_desiredGBits = 4;
m_desiredBBits = 4;
}
} else {
m_desiredRBits = 8;
m_desiredGBits = 8;
m_desiredBBits = 8;
}
然后我通过这些值下降到我的配置选择器。 此代码的工作对我来说是RGB565装置以及一个RGBA8888设备上。
我的假设是,供应商已经选择的一个原因默认,它会给最高效的结果。 当然,我什么都没有做后盾的说法,但它是我与去战略。