dynamic handle egl version

This commit is contained in:
Alexander Matveenko 2014-07-10 14:16:58 +02:00 committed by Alex Zolotarev
parent af408e7fee
commit 822d777954
5 changed files with 943 additions and 355 deletions

View file

@ -0,0 +1,121 @@
package com.nvidia.devtech;
import javax.microedition.khronos.egl.EGL10;
import android.opengl.EGL14;
abstract public class BaseEglWrapper extends EglWrapper
{
private static final int EGL_RENDERABLE_TYPE = 0x3040;
private static final int EGL_OPENGL_ES2_BIT = 0x0004;
private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
/** The number of bits requested for the red component */
private static int redSize = 5;
/** The number of bits requested for the green component */
private static int greenSize = 6;
/** The number of bits requested for the blue component */
private static int blueSize = 5;
/** The number of bits requested for the alpha component */
private static int alphaSize = 0;
/** The number of bits requested for the stencil component */
private static int stencilSize = 0;
/** The number of bits requested for the depth component */
private static int depthSize = 16;
private boolean mIsInitialized = false;
public boolean IsInitialized()
{
return mIsInitialized;
}
protected void SetIsInitialized(boolean isInitialized)
{
mIsInitialized = isInitialized;
}
protected int[] GetConfigAttributes10()
{
final int[] configAttributes = new int[] {EGL10.EGL_RED_SIZE, redSize,
EGL10.EGL_GREEN_SIZE, greenSize,
EGL10.EGL_BLUE_SIZE, blueSize,
EGL10.EGL_ALPHA_SIZE, alphaSize,
EGL10.EGL_STENCIL_SIZE, stencilSize,
EGL10.EGL_DEPTH_SIZE, depthSize,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL10.EGL_NONE };
return configAttributes;
}
protected int[] GetSurfaceAttributes10()
{
return new int[] { EGL10.EGL_NONE };
}
protected int[] GetContextAttributes10()
{
return new int[] { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
}
protected int[] GetConfigAttributes14()
{
final int[] configAttributes = new int[] {EGL14.EGL_RED_SIZE, redSize,
EGL14.EGL_GREEN_SIZE, greenSize,
EGL14.EGL_BLUE_SIZE, blueSize,
EGL14.EGL_ALPHA_SIZE, alphaSize,
EGL14.EGL_STENCIL_SIZE, stencilSize,
EGL14.EGL_DEPTH_SIZE, depthSize,
EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,
EGL14.EGL_NONE };
return configAttributes;
}
protected int[] GetSurfaceAttributes14()
{
return new int[] { EGL14.EGL_NONE };
}
protected int[] GetContextAttributes14()
{
return new int[] { EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, EGL14.EGL_NONE };
}
protected boolean ValidateSurfaceSize()
{
return GetSurfaceWidth() * GetSurfaceWidth() != 0;
}
public class ConfigComparatorBase
{
private int EglNone;
private int EglSlowConfig;
private int EglNonConformantConfig;
public ConfigComparatorBase(int eglNone, int eglSlow, int eglNonComformant)
{
EglNone = eglNone;
EglSlowConfig = eglSlow;
EglNonConformantConfig = eglNonComformant;
}
public int CompareConfigs(int rCav, int lCav)
{
if (lCav != rCav)
return GetCoveatValue(lCav) - GetCoveatValue(rCav);
return 0;
}
int GetCoveatValue(int cav)
{
if (cav == EglSlowConfig)
return 1;
else if (cav == EglNonConformantConfig)
return 2;
return 0;
}
}
}

View file

@ -0,0 +1,379 @@
package com.nvidia.devtech;
import android.os.Build;
import android.view.SurfaceHolder;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGL11;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLSurface;
import com.mapswithme.util.Utils;
import com.mapswithme.util.log.Logger;
import java.util.Arrays;
import java.util.Comparator;
public class Egl10Wrapper extends BaseEglWrapper
{
private static final String TAG = "Egl10Wrapper";
final private EGL10 mEgl = (EGL10)EGLContext.getEGL();
private EGLDisplay mDisplay = EGL10.EGL_NO_DISPLAY;
private EGLContext mContext = EGL10.EGL_NO_CONTEXT;
private EGLSurface mSurface = EGL10.EGL_NO_SURFACE;
private EGLConfig mConfig = null;
private EGLConfig[] m_configs = new EGLConfig[40];
private int m_choosenConfigIndex = 0;
private int m_actualConfigsNumber[] = new int[] {0};
private Logger mLog = null;
public Egl10Wrapper(Logger logger)
{
mLog = logger;
}
private class EGLConfigComparator extends ConfigComparatorBase
implements Comparator<EGLConfig>
{
EGLConfigComparator()
{
super(EGL10.EGL_NONE, EGL10.EGL_SLOW_CONFIG, EGL10.EGL_NON_CONFORMANT_CONFIG);
}
@Override
public int compare(EGLConfig l, EGLConfig r)
{
final int [] value = new int[1];
/// splitting by EGL_CONFIG_CAVEAT,
/// firstly selecting EGL_NONE, then EGL_SLOW_CONFIG
/// and then EGL_NON_CONFORMANT_CONFIG
mEgl.eglGetConfigAttrib(mDisplay, l, EGL10.EGL_CONFIG_CAVEAT, value);
final int lcav = value[0];
mEgl.eglGetConfigAttrib(mDisplay, r, EGL10.EGL_CONFIG_CAVEAT, value);
final int rcav = value[0];
return CompareConfigs(rcav, lcav);
}
};
@Override
public boolean InitEGL()
{
mDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
if (mDisplay == EGL10.EGL_NO_DISPLAY)
{
LogIt("eglGetDisplay failed");
return false;
}
int[] version = new int[2];
if (!mEgl.eglInitialize(mDisplay, version))
{
LogIt("eglInitialize failed");
return false;
}
if (version[0] != 1 && version[1] >= 4 && Utils.apiLowerThan(Build.VERSION_CODES.JELLY_BEAN_MR1))
{
LogIt("Incorrect EGL wrapper choosed");
return false;
}
if (!mEgl.eglChooseConfig(mDisplay, GetConfigAttributes10(), m_configs, m_configs.length, m_actualConfigsNumber))
{
LogEgl("eglChooseConfig failed with error ");
return false;
}
if (m_actualConfigsNumber[0] == 0)
{
LogIt("eglChooseConfig returned zero configs");
return false;
}
Arrays.sort(m_configs, 0, m_actualConfigsNumber[0], new EGLConfigComparator());
m_choosenConfigIndex = 0;
while (true)
{
mConfig = m_configs[m_choosenConfigIndex];
// Debug print
LogIt("Matched egl configs:");
for (int i = 0; i < m_actualConfigsNumber[0]; ++i)
LogIt((i == m_choosenConfigIndex ? "*" : " ") + i + ": " + eglConfigToString(m_configs[i]));
mContext = mEgl.eglCreateContext(mDisplay, mConfig, EGL10.EGL_NO_CONTEXT, GetContextAttributes10());
if (mContext == EGL10.EGL_NO_CONTEXT)
{
LogEgl("eglCreateContext failed with error ");
m_choosenConfigIndex++;
}
else
break;
if (m_choosenConfigIndex == m_configs.length)
{
LogIt("No more configs left to choose");
return false;
}
}
SetIsInitialized(true);
return true;
}
@Override
public boolean TerminateEGL()
{
LogIt("CleanupEGL");
if (!IsInitialized())
return false;
if (!DestroySurfaceEGL())
return false;
if (mDisplay != EGL10.EGL_NO_DISPLAY)
mEgl.eglMakeCurrent(mDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
if (mContext != EGL10.EGL_NO_CONTEXT)
mEgl.eglDestroyContext(mDisplay, mContext);
mEgl.eglTerminate(mDisplay);
mDisplay = EGL10.EGL_NO_DISPLAY;
mContext = EGL10.EGL_NO_CONTEXT;
mConfig = null;
SetIsInitialized(false);
return true;
}
@Override
public boolean CreateSurfaceEGL(SurfaceHolder holder)
{
if (holder == null)
{
LogIt("createEGLSurface failed, m_cachedSurfaceHolder is null");
return false;
}
if (!IsInitialized())
InitEGL();
if (!IsInitialized())
{
LogIt("createEGLSurface failed, cannot initialize EGL");
return false;
}
if (mDisplay == EGL10.EGL_NO_DISPLAY)
{
LogIt("createEGLSurface: display is null");
return false;
}
else if (mConfig == null)
{
LogIt("createEGLSurface: config is null");
return false;
}
int choosenSurfaceConfigIndex = m_choosenConfigIndex;
while (true)
{
/// trying to create window surface with one of the EGL configs, recreating the m_eglConfig if necessary
mSurface = mEgl.eglCreateWindowSurface(mDisplay, m_configs[choosenSurfaceConfigIndex], holder, GetSurfaceAttributes10());
final boolean surfaceCreated = (mSurface != EGL10.EGL_NO_SURFACE);
final boolean surfaceValidated = surfaceCreated ? ValidateSurfaceSize() : false;
if (surfaceCreated && !surfaceValidated)
mEgl.eglDestroySurface(mDisplay, mSurface);
if (!surfaceCreated || !surfaceValidated)
{
LogIt("eglCreateWindowSurface failed for config : " + eglConfigToString(m_configs[choosenSurfaceConfigIndex]));
choosenSurfaceConfigIndex += 1;
if (choosenSurfaceConfigIndex == m_actualConfigsNumber[0])
{
mSurface = EGL10.EGL_NO_SURFACE;
LogIt("no eglConfigs left");
break;
}
else
LogIt("trying : " + eglConfigToString(m_configs[choosenSurfaceConfigIndex]));
}
else
break;
}
if ((choosenSurfaceConfigIndex != m_choosenConfigIndex) && (mSurface != null))
{
LogIt("window surface is created for eglConfig : " + eglConfigToString(m_configs[choosenSurfaceConfigIndex]));
// unbinding context
if (mDisplay != null)
mEgl.eglMakeCurrent(mDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
// destroying context
if (mContext != null)
mEgl.eglDestroyContext(mDisplay, mContext);
// recreating context with same eglConfig as eglWindowSurface has
mContext = mEgl.eglCreateContext(mDisplay, m_configs[choosenSurfaceConfigIndex], EGL10.EGL_NO_CONTEXT, GetContextAttributes10());
if (mContext == EGL10.EGL_NO_CONTEXT)
{
LogEgl("context recreation failed with error ");
return false;
}
m_choosenConfigIndex = choosenSurfaceConfigIndex;
mConfig = m_configs[m_choosenConfigIndex];
}
return true;
}
@Override
public boolean DestroySurfaceEGL()
{
if (mDisplay != EGL10.EGL_NO_DISPLAY && mSurface != EGL10.EGL_NO_SURFACE)
mEgl.eglMakeCurrent(mDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, mContext);
if (mSurface != EGL10.EGL_NO_SURFACE)
mEgl.eglDestroySurface(mDisplay, mSurface);
mSurface = EGL10.EGL_NO_SURFACE;
return true;
}
@Override
public boolean SwapBuffersEGL()
{
if (mSurface == EGL10.EGL_NO_SURFACE)
{
LogIt("Surface is NULL");
return false;
}
if (mDisplay == EGL10.EGL_NO_DISPLAY)
{
LogIt("Display is NULL");
return false;
}
if (!mEgl.eglSwapBuffers(mDisplay, mSurface))
{
LogEgl("eglSwapBuffer: ");
return false;
}
return true;
}
@Override
public int GetSurfaceWidth()
{
final int sizes[] = new int[1];
mEgl.eglQuerySurface(mDisplay, mSurface, EGL10.EGL_WIDTH, sizes);
return sizes[0];
}
@Override
public int GetSurfaceHeight()
{
final int sizes[] = new int[1];
mEgl.eglQuerySurface(mDisplay, mSurface, EGL10.EGL_HEIGHT, sizes);
return sizes[0];
}
@Override
public boolean Bind()
{
if (mContext == EGL10.EGL_NO_CONTEXT)
{
LogIt("m_eglContext is NULL");
return false;
}
else if (mSurface == EGL10.EGL_NO_SURFACE)
{
LogIt("m_eglSurface is NULL");
return false;
}
else if (!mEgl.eglMakeCurrent(mDisplay, mSurface, mSurface, mContext))
{
LogEgl("eglMakeCurrent err: ");
return false;
}
return true;
}
@Override
public boolean Unbind()
{
if (mDisplay == EGL10.EGL_NO_DISPLAY)
return false;
return mEgl.eglMakeCurrent(mDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
}
@Override
public int GetErrorEGL()
{
return mEgl.eglGetError();
}
private void LogIt(String message)
{
mLog.d(TAG, message);
}
private void LogEgl(String message)
{
mLog.d(TAG, message + mEgl.eglGetError());
}
String eglConfigToString(final EGLConfig config)
{
final int[] value = new int[1];
mEgl.eglGetConfigAttrib(mDisplay, config, EGL10.EGL_RED_SIZE, value);
final int red = value[0];
mEgl.eglGetConfigAttrib(mDisplay, config, EGL10.EGL_GREEN_SIZE, value);
final int green = value[0];
mEgl.eglGetConfigAttrib(mDisplay, config, EGL10.EGL_BLUE_SIZE, value);
final int blue = value[0];
mEgl.eglGetConfigAttrib(mDisplay, config, EGL10.EGL_ALPHA_SIZE, value);
final int alpha = value[0];
mEgl.eglGetConfigAttrib(mDisplay, config, EGL10.EGL_STENCIL_SIZE, value);
final int stencil = value[0];
mEgl.eglGetConfigAttrib(mDisplay, config, EGL10.EGL_DEPTH_SIZE, value);
final int depth = value[0];
mEgl.eglGetConfigAttrib(mDisplay, config, EGL10.EGL_CONFIG_CAVEAT, value);
final String caveat = (value[0] == EGL10.EGL_NONE) ? "EGL_NONE" :
(value[0] == EGL10.EGL_SLOW_CONFIG) ? "EGL_SLOW_CONFIG" : "EGL_NON_CONFORMANT_CONFIG";
mEgl.eglGetConfigAttrib(mDisplay, config, EGL10.EGL_BUFFER_SIZE, value);
final int buffer = value[0];
mEgl.eglGetConfigAttrib(mDisplay, config, EGL10.EGL_LEVEL, value);
final int level = value[0];
mEgl.eglGetConfigAttrib(mDisplay, config, EGL10.EGL_SAMPLE_BUFFERS, value);
final int sampleBuffers = value[0];
mEgl.eglGetConfigAttrib(mDisplay, config, EGL10.EGL_SAMPLES, value);
final int samples = value[0];
return "R" + red + "G" + green + "B" + blue + "A" + alpha +
" Stencil:" + stencil + " Depth:" + depth + " Caveat:" + caveat +
" BufferSize:" + buffer + " Level:" + level + " SampleBuffers:" + sampleBuffers +
" Samples:" + samples;
}
}

View file

@ -0,0 +1,359 @@
package com.nvidia.devtech;
import android.opengl.EGL14;
import android.opengl.EGLDisplay;
import android.opengl.EGLContext;
import android.opengl.EGLSurface;
import android.opengl.EGLConfig;
import android.view.SurfaceHolder;
import android.util.Log;
import com.mapswithme.util.log.Logger;
import java.util.Arrays;
import java.util.Comparator;
public class Egl14Wrapper extends BaseEglWrapper
{
private static final String TAG = "Egl14Wrapper";
private Logger mLog = null;
private EGLDisplay mDisplay = EGL14.EGL_NO_DISPLAY;
private EGLContext mContext = EGL14.EGL_NO_CONTEXT;
private EGLSurface mSurface = EGL14.EGL_NO_SURFACE;
private EGLConfig mConfig = null;
private EGLConfig[] m_configs = new EGLConfig[40];
private int m_choosenConfigIndex = 0;
private int m_actualConfigsNumber[] = new int[] {0};
private class EGLConfigComparator extends ConfigComparatorBase
implements Comparator<EGLConfig>
{
EGLConfigComparator()
{
super(EGL14.EGL_NONE, EGL14.EGL_SLOW_CONFIG, EGL14.EGL_NON_CONFORMANT_CONFIG);
}
@Override
public int compare(EGLConfig l, EGLConfig r)
{
final int [] value = new int[2];
EGL14.eglGetConfigAttrib(mDisplay, l, EGL14.EGL_CONFIG_CAVEAT, value, 0);
EGL14.eglGetConfigAttrib(mDisplay, r, EGL14.EGL_CONFIG_CAVEAT, value, 1);
return CompareConfigs(value[1], value[0]);
}
};
public Egl14Wrapper(Logger logger)
{
mLog = logger;
}
@Override
public boolean InitEGL()
{
mDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
if (mDisplay == EGL14.EGL_NO_DISPLAY)
{
LogIt("eglGetDisplay failed");
return false;
}
int[] version = new int[2];
if (!EGL14.eglInitialize(mDisplay, version, 0, version, 1))
{
LogIt("eglInitialize failed");
return false;
}
if (version[0] != 1 && version[1] < 4)
{
LogIt("Incorrect EGL wrapper choosed");
return false;
}
if (!EGL14.eglChooseConfig(mDisplay, GetConfigAttributes14(), 0, m_configs, 0, m_configs.length, m_actualConfigsNumber, 0))
{
LogEgl("eglChooseConfig failed with error ");
return false;
}
if (m_actualConfigsNumber[0] == 0)
{
LogIt("eglChooseConfig returned zero configs");
return false;
}
Arrays.sort(m_configs, 0, m_actualConfigsNumber[0], new EGLConfigComparator());
m_choosenConfigIndex = 0;
while (true)
{
mConfig = m_configs[m_choosenConfigIndex];
// Debug print
LogIt("Matched egl configs:");
for (int i = 0; i < m_actualConfigsNumber[0]; ++i)
LogIt((i == m_choosenConfigIndex ? "*" : " ") + i + ": " + eglConfigToString(m_configs[i]));
mContext = EGL14.eglCreateContext(mDisplay, mConfig, EGL14.EGL_NO_CONTEXT, GetContextAttributes14(), 0);
if (mContext == EGL14.EGL_NO_CONTEXT)
{
LogEgl("eglCreateContext failed with error ");
m_choosenConfigIndex++;
}
else
break;
if (m_choosenConfigIndex == m_configs.length)
{
LogIt("No more configs left to choose");
return false;
}
}
SetIsInitialized(true);
return true;
}
@Override
public boolean TerminateEGL()
{
LogIt("CleanupEGL");
if (!IsInitialized())
return false;
if (!DestroySurfaceEGL())
return false;
if (mDisplay != EGL14.EGL_NO_DISPLAY)
EGL14.eglMakeCurrent(mDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT);
if (mContext != EGL14.EGL_NO_CONTEXT)
EGL14.eglDestroyContext(mDisplay, mContext);
EGL14.eglTerminate(mDisplay);
mDisplay = EGL14.EGL_NO_DISPLAY;
mContext = EGL14.EGL_NO_CONTEXT;
mConfig = null;
SetIsInitialized(false);
return true;
}
@Override
public boolean CreateSurfaceEGL(SurfaceHolder holder)
{
if (holder == null)
{
LogIt("createEGLSurface failed, m_cachedSurfaceHolder is null");
return false;
}
if (!IsInitialized())
InitEGL();
if (!IsInitialized())
{
LogIt("createEGLSurface failed, cannot initialize EGL");
return false;
}
if (mDisplay == EGL14.EGL_NO_DISPLAY)
{
LogIt("createEGLSurface: display is null");
return false;
}
else if (mConfig == null)
{
LogIt("createEGLSurface: config is null");
return false;
}
int choosenSurfaceConfigIndex = m_choosenConfigIndex;
while (true)
{
/// trying to create window surface with one of the EGL configs, recreating the m_eglConfig if necessary
mSurface = EGL14.eglCreateWindowSurface(mDisplay, m_configs[choosenSurfaceConfigIndex], holder, GetSurfaceAttributes14(), 0);
final boolean surfaceCreated = (mSurface != EGL14.EGL_NO_SURFACE);
final boolean surfaceValidated = surfaceCreated ? ValidateSurfaceSize() : false;
if (surfaceCreated && !surfaceValidated)
EGL14.eglDestroySurface(mDisplay, mSurface);
if (!surfaceCreated || !surfaceValidated)
{
LogIt("eglCreateWindowSurface failed for config : " + eglConfigToString(m_configs[choosenSurfaceConfigIndex]));
choosenSurfaceConfigIndex += 1;
if (choosenSurfaceConfigIndex == m_actualConfigsNumber[0])
{
mSurface = EGL14.EGL_NO_SURFACE;
LogIt("no eglConfigs left");
break;
}
else
LogIt("trying : " + eglConfigToString(m_configs[choosenSurfaceConfigIndex]));
}
else
break;
}
if ((choosenSurfaceConfigIndex != m_choosenConfigIndex) && (mSurface != EGL14.EGL_NO_SURFACE))
{
LogIt("window surface is created for eglConfig : " + eglConfigToString(m_configs[choosenSurfaceConfigIndex]));
// unbinding context
if (mDisplay != null)
EGL14.eglMakeCurrent(mDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT);
// destroying context
if (mContext != null)
EGL14.eglDestroyContext(mDisplay, mContext);
// recreating context with same eglConfig as eglWindowSurface has
mContext = EGL14.eglCreateContext(mDisplay, m_configs[choosenSurfaceConfigIndex], EGL14.EGL_NO_CONTEXT, GetContextAttributes14(), 0);
if (mContext == EGL14.EGL_NO_CONTEXT)
{
LogEgl("context recreation failed with error ");
return false;
}
m_choosenConfigIndex = choosenSurfaceConfigIndex;
mConfig = m_configs[m_choosenConfigIndex];
}
return true;
}
@Override
public boolean DestroySurfaceEGL()
{
if (mDisplay != EGL14.EGL_NO_DISPLAY && mSurface != EGL14.EGL_NO_SURFACE)
EGL14.eglMakeCurrent(mDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, mContext);
if (mSurface != EGL14.EGL_NO_SURFACE)
{
EGL14.eglDestroySurface(mDisplay, mSurface);
}
mSurface = EGL14.EGL_NO_SURFACE;
return true;
}
@Override
public boolean SwapBuffersEGL()
{
if (mSurface == EGL14.EGL_NO_SURFACE)
{
LogIt("Surface is NULL");
return false;
}
if (mDisplay == EGL14.EGL_NO_DISPLAY)
{
LogIt("Display is NULL");
return false;
}
if (!EGL14.eglSwapBuffers(mDisplay, mSurface))
{
LogEgl("eglSwapBuffer: ");
return false;
}
return true;
}
@Override
public boolean Bind()
{
if (mContext == EGL14.EGL_NO_CONTEXT)
{
LogIt("m_eglContext is NULL");
return false;
}
else if (mSurface == EGL14.EGL_NO_SURFACE)
{
LogIt("m_eglSurface is NULL");
return false;
}
else if (!EGL14.eglMakeCurrent(mDisplay, mSurface, mSurface, mContext))
{
LogEgl("eglMakeCurrent err: ");
return false;
}
return true;
}
@Override
public boolean Unbind()
{
if (mDisplay == EGL14.EGL_NO_DISPLAY)
return false;
return EGL14.eglMakeCurrent(mDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT);
}
@Override
public int GetErrorEGL()
{
return EGL14.eglGetError();
}
@Override
public int GetSurfaceWidth()
{
final int sizes[] = new int[1];
EGL14.eglQuerySurface(mDisplay, mSurface, EGL14.EGL_WIDTH, sizes, 0);
return sizes[0];
}
@Override
public int GetSurfaceHeight()
{
final int sizes[] = new int[1];
EGL14.eglQuerySurface(mDisplay, mSurface, EGL14.EGL_HEIGHT, sizes, 0);
return sizes[0];
}
private void LogIt(String message)
{
mLog.d(message);
}
private void LogEgl(String message)
{
mLog.d(message + EGL14.eglGetError());
}
String eglConfigToString(final EGLConfig config)
{
final int[] value = new int[11];
EGL14.eglGetConfigAttrib(mDisplay, config, EGL14.EGL_RED_SIZE, value, 0);
EGL14.eglGetConfigAttrib(mDisplay, config, EGL14.EGL_GREEN_SIZE, value, 1);
EGL14.eglGetConfigAttrib(mDisplay, config, EGL14.EGL_BLUE_SIZE, value, 2);
EGL14.eglGetConfigAttrib(mDisplay, config, EGL14.EGL_ALPHA_SIZE, value, 3);
EGL14.eglGetConfigAttrib(mDisplay, config, EGL14.EGL_STENCIL_SIZE, value, 4);
EGL14.eglGetConfigAttrib(mDisplay, config, EGL14.EGL_DEPTH_SIZE, value, 5);
EGL14.eglGetConfigAttrib(mDisplay, config, EGL14.EGL_CONFIG_CAVEAT, value, 6);
final String caveat = (value[6] == EGL14.EGL_NONE) ? "EGL_NONE" :
(value[6] == EGL14.EGL_SLOW_CONFIG) ? "EGL_SLOW_CONFIG" : "EGL_NON_CONFORMANT_CONFIG";
EGL14.eglGetConfigAttrib(mDisplay, config, EGL14.EGL_BUFFER_SIZE, value, 7);
EGL14.eglGetConfigAttrib(mDisplay, config, EGL14.EGL_LEVEL, value, 8);
EGL14.eglGetConfigAttrib(mDisplay, config, EGL14.EGL_SAMPLE_BUFFERS, value, 9);
EGL14.eglGetConfigAttrib(mDisplay, config, EGL14.EGL_SAMPLES, value, 10);
return "R" + value[0] + "G" + value[1] + "B" + value[2] + "A" + value[3] +
" Stencil:" + value[4] + " Depth:" + value[5] + " Caveat:" + caveat +
" BufferSize:" + value[7] + " Level:" + value[8] + " SampleBuffers:" + value[9] +
" Samples:" + value[10];
}
}

View file

@ -0,0 +1,72 @@
package com.nvidia.devtech;
import android.view.SurfaceHolder;
import android.opengl.EGL14;
import android.opengl.EGLDisplay;
import com.mapswithme.util.Utils;
import com.mapswithme.util.log.Logger;
abstract public class EglWrapper
{
public abstract boolean InitEGL();
public abstract boolean TerminateEGL();
public abstract boolean CreateSurfaceEGL(SurfaceHolder holder);
public abstract boolean DestroySurfaceEGL();
public abstract boolean SwapBuffersEGL();
public abstract int GetSurfaceWidth();
public abstract int GetSurfaceHeight();
public abstract boolean IsInitialized();
public abstract boolean Bind();
public abstract boolean Unbind();
public abstract int GetErrorEGL();
enum EglVersion
{
NonEgl,
Egl,
Egl14
}
static public EglWrapper GetEgl(Logger logger)
{
EglVersion version = QueryEglVersion();
switch (version)
{
case Egl:
return new Egl10Wrapper(logger);
case Egl14:
return new Egl14Wrapper(logger);
}
return null;
}
static private EglVersion QueryEglVersion()
{
if (Utils.apiLowerThan(android.os.Build.VERSION_CODES.JELLY_BEAN_MR1))
return EglVersion.Egl;
EglVersion result = EglVersion.NonEgl;
EGLDisplay display = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
if (display != EGL14.EGL_NO_DISPLAY)
{
final int[] version = new int[2];
if (EGL14.eglInitialize(display, version, 0, version, 1))
{
if (version[0] >= 1)
{
if (version[1] < 4)
result = EglVersion.Egl;
else
result = EglVersion.Egl14;
}
}
EGL14.eglTerminate(display);
}
return result;
}
}

View file

@ -28,19 +28,9 @@ public abstract class NvEventQueueActivity extends MapsWithMeBaseActivity implem
{
private static final String TAG = "NvEventQueueActivity";
private static final int EGL_RENDERABLE_TYPE = 0x3040;
private static final int EGL_OPENGL_ES2_BIT = 0x0004;
private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
private final Logger mLog = StubLogger.get();
private final EGL10 m_egl = (EGL10) EGLContext.getEGL();
protected boolean m_eglInitialized = false;
protected EGLSurface m_eglSurface = null;
protected EGLDisplay m_eglDisplay = null;
protected EGLContext m_eglContext = null;
protected EGLConfig m_eglConfig = null;
private EglWrapper mEglWrapper = null;
protected SurfaceHolder m_cachedSurfaceHolder = null;
private int m_surfaceWidth = 0;
private int m_surfaceHeight = 0;
@ -244,109 +234,6 @@ public abstract class NvEventQueueActivity extends MapsWithMeBaseActivity implem
}
}
String eglConfigToString(final EGLConfig config)
{
final int[] value = new int[1];
m_egl.eglGetConfigAttrib(m_eglDisplay, config, EGL11.EGL_RED_SIZE, value);
final int red = value[0];
m_egl.eglGetConfigAttrib(m_eglDisplay, config, EGL11.EGL_GREEN_SIZE, value);
final int green = value[0];
m_egl.eglGetConfigAttrib(m_eglDisplay, config, EGL11.EGL_BLUE_SIZE, value);
final int blue = value[0];
m_egl.eglGetConfigAttrib(m_eglDisplay, config, EGL11.EGL_ALPHA_SIZE, value);
final int alpha = value[0];
m_egl.eglGetConfigAttrib(m_eglDisplay, config, EGL11.EGL_STENCIL_SIZE, value);
final int stencil = value[0];
m_egl.eglGetConfigAttrib(m_eglDisplay, config, EGL11.EGL_DEPTH_SIZE, value);
final int depth = value[0];
m_egl.eglGetConfigAttrib(m_eglDisplay, config, EGL11.EGL_CONFIG_CAVEAT, value);
final String caveat = (value[0] == EGL11.EGL_NONE) ? "EGL_NONE" :
(value[0] == EGL11.EGL_SLOW_CONFIG) ? "EGL_SLOW_CONFIG" : "EGL_NON_CONFORMANT_CONFIG";
m_egl.eglGetConfigAttrib(m_eglDisplay, config, EGL11.EGL_BUFFER_SIZE, value);
final int buffer = value[0];
m_egl.eglGetConfigAttrib(m_eglDisplay, config, EGL11.EGL_LEVEL, value);
final int level = value[0];
m_egl.eglGetConfigAttrib(m_eglDisplay, config, EGL11.EGL_SAMPLE_BUFFERS, value);
final int sampleBuffers = value[0];
m_egl.eglGetConfigAttrib(m_eglDisplay, config, EGL11.EGL_SAMPLES, value);
final int samples = value[0];
return "R" + red + "G" + green + "B" + blue + "A" + alpha +
" Stencil:" + stencil + " Depth:" + depth + " Caveat:" + caveat +
" BufferSize:" + buffer + " Level:" + level + " SampleBuffers:" + sampleBuffers +
" Samples:" + samples;
}
/** The number of bits requested for the red component */
protected int redSize = 5;
/** The number of bits requested for the green component */
protected int greenSize = 6;
/** The number of bits requested for the blue component */
protected int blueSize = 5;
/** The number of bits requested for the alpha component */
protected int alphaSize = 0;
/** The number of bits requested for the stencil component */
protected int stencilSize = 0;
/** The number of bits requested for the depth component */
protected int depthSize = 16;
public class EGLConfigComparator implements Comparator<EGLConfig>
{
@Override
public int compare(EGLConfig l, EGLConfig r)
{
final int [] value = new int[1];
/// splitting by EGL_CONFIG_CAVEAT,
/// firstly selecting EGL_NONE, then EGL_SLOW_CONFIG
/// and then EGL_NON_CONFORMANT_CONFIG
m_egl.eglGetConfigAttrib(m_eglDisplay, l, EGL11.EGL_CONFIG_CAVEAT, value);
final int lcav = value[0];
m_egl.eglGetConfigAttrib(m_eglDisplay, r, EGL11.EGL_CONFIG_CAVEAT, value);
final int rcav = value[0];
if (lcav != rcav)
{
int ltemp = 0;
int rtemp = 0;
switch (lcav)
{
case EGL11.EGL_NONE:
ltemp = 0;
break;
case EGL11.EGL_SLOW_CONFIG:
ltemp = 1;
break;
case EGL11.EGL_NON_CONFORMANT_CONFIG:
ltemp = 2;
break;
};
switch (rcav)
{
case EGL11.EGL_NONE:
rtemp = 0;
break;
case EGL11.EGL_SLOW_CONFIG:
rtemp = 1;
break;
case EGL11.EGL_NON_CONFORMANT_CONFIG:
rtemp = 2;
};
return ltemp - rtemp;
}
return 0;
}
};
int m_choosenConfigIndex = 0;
EGLConfig[] m_configs = new EGLConfig[40];
int m_actualConfigsNumber[] = new int[] {0};
/**
* Called to initialize EGL. This function should not be called by the
* inheriting activity, but can be overridden if needed.
@ -355,74 +242,8 @@ public abstract class NvEventQueueActivity extends MapsWithMeBaseActivity implem
*/
protected boolean InitEGL()
{
final int[] configAttrs = new int[] { EGL11.EGL_RED_SIZE, redSize,
EGL11.EGL_GREEN_SIZE, greenSize,
EGL11.EGL_BLUE_SIZE, blueSize,
EGL11.EGL_ALPHA_SIZE, alphaSize,
EGL11.EGL_STENCIL_SIZE, stencilSize,
EGL11.EGL_DEPTH_SIZE, depthSize,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL11.EGL_NONE };
m_eglDisplay = m_egl.eglGetDisplay(EGL11.EGL_DEFAULT_DISPLAY);
if (m_eglDisplay == EGL11.EGL_NO_DISPLAY)
{
mLog.d(TAG, "eglGetDisplay failed");
return false;
}
final int[] version = new int[2];
if (!m_egl.eglInitialize(m_eglDisplay, version))
{
mLog.d(TAG, "eglInitialize failed with error " + m_egl.eglGetError());
return false;
}
if (!m_egl.eglChooseConfig(m_eglDisplay, configAttrs, m_configs, m_configs.length, m_actualConfigsNumber))
{
mLog.d(TAG, "eglChooseConfig failed with error " + m_egl.eglGetError());
return false;
}
if (m_actualConfigsNumber[0] == 0)
{
mLog.d(TAG, "eglChooseConfig returned zero configs");
return false;
}
Arrays.sort(m_configs, 0, m_actualConfigsNumber[0], new EGLConfigComparator());
m_choosenConfigIndex = 0;
while (true)
{
m_eglConfig = m_configs[m_choosenConfigIndex];
// Debug print
mLog.d(TAG, "Matched egl configs:");
for (int i = 0; i < m_actualConfigsNumber[0]; ++i)
mLog.d(TAG, (i == m_choosenConfigIndex ? "*" : " ") + i + ": " + eglConfigToString(m_configs[i]));
final int[] contextAttrs = new int[] { EGL_CONTEXT_CLIENT_VERSION, 2, EGL11.EGL_NONE };
m_eglContext = m_egl.eglCreateContext(m_eglDisplay, m_eglConfig, EGL11.EGL_NO_CONTEXT, contextAttrs);
if (m_eglContext == EGL11.EGL_NO_CONTEXT)
{
mLog.d(TAG, "eglCreateContext failed with error " + m_egl.eglGetError());
m_choosenConfigIndex++;
}
else
break;
if (m_choosenConfigIndex == m_configs.length)
{
mLog.d(TAG, "No more configs left to choose");
return false;
}
}
m_eglInitialized = true;
return true;
mEglWrapper = EglWrapper.GetEgl(mLog);
return mEglWrapper.InitEGL();
}
/**
@ -431,144 +252,16 @@ public abstract class NvEventQueueActivity extends MapsWithMeBaseActivity implem
*/
protected boolean CleanupEGL()
{
mLog.d(TAG, "CleanupEGL");
if (!m_eglInitialized)
return false;
if (!DestroySurfaceEGL())
return false;
if (m_eglDisplay != null)
m_egl.eglMakeCurrent(m_eglDisplay, EGL11.EGL_NO_SURFACE,
EGL11.EGL_NO_SURFACE, EGL11.EGL_NO_CONTEXT);
if (m_eglContext != null)
{
mLog.d(TAG, "eglDestroyContext");
m_egl.eglDestroyContext(m_eglDisplay, m_eglContext);
}
if (m_eglDisplay != null)
m_egl.eglTerminate(m_eglDisplay);
m_eglDisplay = null;
m_eglContext = null;
m_eglSurface = null;
m_eglConfig = null;
m_surfaceWidth = 0;
m_surfaceHeight = 0;
m_eglInitialized = false;
return true;
}
protected boolean validateSurfaceSize(EGLSurface eglSurface)
{
final int sizes[] = new int[1];
sizes[0] = 0;
m_egl.eglQuerySurface(m_eglDisplay, eglSurface, EGL10.EGL_WIDTH, sizes);
m_surfaceWidth = sizes[0];
sizes[0] = 0;
m_egl.eglQuerySurface(m_eglDisplay, eglSurface, EGL10.EGL_HEIGHT, sizes);
m_surfaceHeight = sizes[0];
mLog.d(TAG, "trying to get surface size to see if it's valid: surfaceSize= " + m_surfaceWidth + "x" + m_surfaceHeight);
return m_surfaceWidth * m_surfaceHeight != 0;
return mEglWrapper.TerminateEGL();
}
protected boolean CreateSurfaceEGL()
{
if (m_cachedSurfaceHolder == null)
{
mLog.d(TAG, "createEGLSurface failed, m_cachedSurfaceHolder is null");
if (!mEglWrapper.CreateSurfaceEGL(m_cachedSurfaceHolder))
return false;
}
if (!m_eglInitialized && (m_eglInitialized = InitEGL()))
{
mLog.d(TAG, "createEGLSurface failed, cannot initialize EGL");
return false;
}
if (m_eglDisplay == null)
{
mLog.d(TAG, "createEGLSurface: display is null");
return false;
}
else if (m_eglConfig == null)
{
mLog.d(TAG, "createEGLSurface: config is null");
return false;
}
int choosenSurfaceConfigIndex = m_choosenConfigIndex;
while (true)
{
/// trying to create window surface with one of the EGL configs, recreating the m_eglConfig if necessary
m_eglSurface = m_egl.eglCreateWindowSurface(m_eglDisplay, m_configs[choosenSurfaceConfigIndex], m_cachedSurfaceHolder, null);
final boolean surfaceCreated = (m_eglSurface != EGL11.EGL_NO_SURFACE);
final boolean surfaceValidated = surfaceCreated ? validateSurfaceSize(m_eglSurface) : false;
if (surfaceCreated && !surfaceValidated)
m_egl.eglDestroySurface(m_eglDisplay, m_eglSurface);
if (!surfaceCreated || !surfaceValidated)
{
mLog.d(TAG, "eglCreateWindowSurface failed for config : " + eglConfigToString(m_configs[choosenSurfaceConfigIndex]));
choosenSurfaceConfigIndex += 1;
if (choosenSurfaceConfigIndex == m_actualConfigsNumber[0])
{
m_eglSurface = null;
mLog.d(TAG, "no eglConfigs left");
break;
}
else
mLog.d(TAG, "trying : " + eglConfigToString(m_configs[choosenSurfaceConfigIndex]));
}
else
break;
}
if ((choosenSurfaceConfigIndex != m_choosenConfigIndex) && (m_eglSurface != null))
{
mLog.d(TAG, "window surface is created for eglConfig : " + eglConfigToString(m_configs[choosenSurfaceConfigIndex]));
// unbinding context
if (m_eglDisplay != null)
m_egl.eglMakeCurrent(m_eglDisplay,
EGL11.EGL_NO_SURFACE,
EGL11.EGL_NO_SURFACE,
EGL11.EGL_NO_CONTEXT);
// destroying context
if (m_eglContext != null)
m_egl.eglDestroyContext(m_eglDisplay, m_eglContext);
// recreating context with same eglConfig as eglWindowSurface has
final int[] contextAttrs = new int[] { EGL_CONTEXT_CLIENT_VERSION, 2, EGL11.EGL_NONE };
m_eglContext = m_egl.eglCreateContext(m_eglDisplay, m_configs[choosenSurfaceConfigIndex], EGL11.EGL_NO_CONTEXT, contextAttrs);
if (m_eglContext == EGL11.EGL_NO_CONTEXT)
{
mLog.d(TAG, "context recreation failed with error " + m_egl.eglGetError());
return false;
}
m_choosenConfigIndex = choosenSurfaceConfigIndex;
m_eglConfig = m_configs[m_choosenConfigIndex];
}
final int sizes[] = new int[1];
m_egl.eglQuerySurface(m_eglDisplay, m_eglSurface, EGL10.EGL_WIDTH, sizes);
m_surfaceWidth = sizes[0];
m_egl.eglQuerySurface(m_eglDisplay, m_eglSurface, EGL10.EGL_HEIGHT, sizes);
m_surfaceHeight = sizes[0];
m_surfaceHeight = mEglWrapper.GetSurfaceHeight();
m_surfaceWidth = mEglWrapper.GetSurfaceWidth();
return true;
}
@ -578,63 +271,27 @@ public abstract class NvEventQueueActivity extends MapsWithMeBaseActivity implem
*/
protected boolean DestroySurfaceEGL()
{
if (m_eglDisplay != null && m_eglSurface != null)
m_egl.eglMakeCurrent(m_eglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, m_eglContext);
if (m_eglSurface != null)
m_egl.eglDestroySurface(m_eglDisplay, m_eglSurface);
m_eglSurface = null;
return true;
return mEglWrapper.DestroySurfaceEGL();
}
public boolean BindSurfaceAndContextEGL()
{
if (m_eglContext == null)
{
mLog.d(TAG, "m_eglContext is NULL");
return false;
}
else if (m_eglSurface == null)
{
mLog.d(TAG, "m_eglSurface is NULL");
return false;
}
else if (!m_egl.eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext))
{
mLog.d(TAG, "eglMakeCurrent err: " + m_egl.eglGetError());
return false;
}
return true;
return mEglWrapper.Bind();
}
public boolean UnbindSurfaceAndContextEGL()
{
mLog.d(TAG, "UnbindSurfaceAndContextEGL");
if (m_eglDisplay == null)
return false;
return m_egl.eglMakeCurrent(m_eglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
return mEglWrapper.Unbind();
}
public boolean SwapBuffersEGL()
{
if (m_eglSurface == null)
{
mLog.d(TAG, "m_eglSurface is NULL");
return false;
}
else if (!m_egl.eglSwapBuffers(m_eglDisplay, m_eglSurface))
{
mLog.d(TAG, "eglSwapBufferrr: " + m_egl.eglGetError());
return false;
}
return true;
return mEglWrapper.SwapBuffersEGL();
}
public int GetErrorEGL()
{
return m_egl.eglGetError();
return mEglWrapper.GetErrorEGL();
}
public void OnRenderingInitialized()