mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2026-05-09 04:13:28 -05:00
Merge 1800f5cf51 into 30a20d75d2
This commit is contained in:
commit
8432044a83
|
|
@ -1691,7 +1691,7 @@ class SettingsFragmentPresenter(
|
|||
// If we only support OpenGLES then we need both OpenGLES 3.1 and AEP
|
||||
val helper = EGLHelper(EGLHelper.EGL_OPENGL_ES2_BIT)
|
||||
|
||||
if (helper.supportsOpenGL() && helper.GetVersion() >= 320 || helper.supportsGLES3() && helper.GetVersion() >= 310 && helper.SupportsExtension(
|
||||
if (helper.supportsOpenGL() && helper.getVersion() >= 320 || helper.supportsGLES3() && helper.getVersion() >= 310 && helper.supportsExtension(
|
||||
"GL_ANDROID_extension_pack_es31a"
|
||||
)
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -1,386 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013 Dolphin Emulator Project
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
package org.dolphinemu.dolphinemu.utils;
|
||||
|
||||
import android.opengl.GLES30;
|
||||
|
||||
import org.dolphinemu.dolphinemu.NativeLibrary;
|
||||
|
||||
import javax.microedition.khronos.egl.EGL10;
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.egl.EGLContext;
|
||||
import javax.microedition.khronos.egl.EGLDisplay;
|
||||
import javax.microedition.khronos.egl.EGLSurface;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
/**
|
||||
* Utility class that abstracts all the stuff about
|
||||
* EGL initialization out of the way if all that is
|
||||
* wanted is to query the underlying GL API for information.
|
||||
*/
|
||||
public final class EGLHelper
|
||||
{
|
||||
private final EGL10 mEGL;
|
||||
private final EGLDisplay mDisplay;
|
||||
private EGLConfig[] mEGLConfigs;
|
||||
private EGLContext mEGLContext;
|
||||
private EGLSurface mEGLSurface;
|
||||
private GL10 mGL;
|
||||
|
||||
// GL support flags
|
||||
private boolean supportGL;
|
||||
private boolean supportGLES2;
|
||||
private boolean supportGLES3;
|
||||
|
||||
// Renderable type bitmasks
|
||||
public static final int EGL_OPENGL_ES_BIT = 0x0001;
|
||||
public static final int EGL_OPENGL_ES2_BIT = 0x0004;
|
||||
public static final int EGL_OPENGL_BIT = 0x0008;
|
||||
public static final int EGL_OPENGL_ES3_BIT_KHR = 0x0040;
|
||||
|
||||
// API types
|
||||
public static final int EGL_OPENGL_ES_API = 0x30A0;
|
||||
public static final int EGL_OPENGL_API = 0x30A2;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* <p>
|
||||
* Initializes the underlying {@link EGLSurface} with a width and height of 1.
|
||||
* This is useful if all you need to use this class for is to query information
|
||||
* from specific API contexts.
|
||||
*
|
||||
* @param renderableType Bitmask indicating which types of client API contexts
|
||||
* the framebuffer config must support.
|
||||
*/
|
||||
public EGLHelper(int renderableType)
|
||||
{
|
||||
this(1, 1, renderableType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param width Width of the underlying {@link EGLSurface}.
|
||||
* @param height Height of the underlying {@link EGLSurface}.
|
||||
* @param renderableType Bitmask indicating which types of client API contexts
|
||||
* the framebuffer config must support.
|
||||
*/
|
||||
public EGLHelper(int width, int height, int renderableType)
|
||||
{
|
||||
// Initialize handle to an EGL display.
|
||||
mEGL = (EGL10) EGLContext.getEGL();
|
||||
mDisplay = mEGL.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
|
||||
|
||||
// If a display is present, initialize EGL.
|
||||
if (mDisplay != EGL10.EGL_NO_DISPLAY)
|
||||
{
|
||||
int[] version = new int[2];
|
||||
if (mEGL.eglInitialize(mDisplay, version))
|
||||
{
|
||||
// Detect supported GL APIs, initialize configs, etc.
|
||||
detect();
|
||||
|
||||
// Create context and surface
|
||||
create(width, height, renderableType);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.error("[EGLHelper] Error initializing EGL.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.error("[EGLHelper] Error initializing EGL display.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases all resources associated with this helper.
|
||||
* <p>
|
||||
* This should be called whenever this helper is no longer needed.
|
||||
*/
|
||||
public void closeHelper()
|
||||
{
|
||||
mEGL.eglTerminate(mDisplay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets information through EGL.<br/>
|
||||
* <p>
|
||||
* Index 0: Vendor <br/>
|
||||
* Index 1: Version <br/>
|
||||
* Index 2: Renderer <br/>
|
||||
* Index 3: Extensions <br/>
|
||||
*
|
||||
* @return information retrieved through EGL.
|
||||
*/
|
||||
public String[] getEGLInfo()
|
||||
{
|
||||
return new String[]{
|
||||
mGL.glGetString(GL10.GL_VENDOR),
|
||||
mGL.glGetString(GL10.GL_VERSION),
|
||||
mGL.glGetString(GL10.GL_RENDERER),
|
||||
mGL.glGetString(GL10.GL_EXTENSIONS),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this device supports OpenGL.
|
||||
*
|
||||
* @return true if this device supports OpenGL; false otherwise.
|
||||
*/
|
||||
public boolean supportsOpenGL()
|
||||
{
|
||||
return supportGL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this device supports OpenGL ES 2.
|
||||
* <br/>
|
||||
* Note that if this returns true, then OpenGL ES 1 is also supported.
|
||||
*
|
||||
* @return true if this device supports OpenGL ES 2; false otherwise.
|
||||
*/
|
||||
public boolean supportsGLES2()
|
||||
{
|
||||
return supportGLES2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this device supports OpenGL ES 3.
|
||||
* <br/>
|
||||
* Note that if this returns true, then OpenGL ES 1 and 2 are also supported.
|
||||
*
|
||||
* @return true if this device supports OpenGL ES 3; false otherwise.
|
||||
*/
|
||||
public boolean supportsGLES3()
|
||||
{
|
||||
return supportGLES3;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the underlying {@link EGL10} instance.
|
||||
*
|
||||
* @return the underlying {@link EGL10} instance.
|
||||
*/
|
||||
public EGL10 getEGL()
|
||||
{
|
||||
return mEGL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the underlying {@link GL10} instance.
|
||||
*
|
||||
* @return the underlying {@link GL10} instance.
|
||||
*/
|
||||
public GL10 getGL()
|
||||
{
|
||||
return mGL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the underlying {@link EGLDisplay}.
|
||||
*
|
||||
* @return the underlying {@link EGLDisplay}
|
||||
*/
|
||||
public EGLDisplay getDisplay()
|
||||
{
|
||||
return mDisplay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all supported framebuffer configurations for this device.
|
||||
*
|
||||
* @return all supported framebuffer configurations for this device.
|
||||
*/
|
||||
public EGLConfig[] getConfigs()
|
||||
{
|
||||
return mEGLConfigs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the underlying {@link EGLContext}.
|
||||
*
|
||||
* @return the underlying {@link EGLContext}.
|
||||
*/
|
||||
public EGLContext getContext()
|
||||
{
|
||||
return mEGLContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the underlying {@link EGLSurface}.
|
||||
*
|
||||
* @return the underlying {@link EGLSurface}.
|
||||
*/
|
||||
public EGLSurface getSurface()
|
||||
{
|
||||
return mEGLSurface;
|
||||
}
|
||||
|
||||
// Detects the specific kind of GL modes that are supported
|
||||
private void detect()
|
||||
{
|
||||
// Get total number of configs available.
|
||||
int[] numConfigs = new int[1];
|
||||
if (!mEGL.eglGetConfigs(mDisplay, null, 0, numConfigs))
|
||||
{
|
||||
Log.error("[EGLHelper] Error retrieving number of EGL configs available.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Now get all the configurations
|
||||
mEGLConfigs = new EGLConfig[numConfigs[0]];
|
||||
if (!mEGL.eglGetConfigs(mDisplay, mEGLConfigs, mEGLConfigs.length, numConfigs))
|
||||
{
|
||||
Log.error("[EGLHelper] Error retrieving all EGL configs.");
|
||||
return;
|
||||
}
|
||||
|
||||
for (EGLConfig mEGLConfig : mEGLConfigs)
|
||||
{
|
||||
int[] attribVal = new int[1];
|
||||
boolean ret =
|
||||
mEGL.eglGetConfigAttrib(mDisplay, mEGLConfig, EGL10.EGL_RENDERABLE_TYPE, attribVal);
|
||||
if (ret)
|
||||
{
|
||||
if ((attribVal[0] & EGL_OPENGL_BIT) != 0)
|
||||
supportGL = true;
|
||||
|
||||
if ((attribVal[0] & EGL_OPENGL_ES2_BIT) != 0)
|
||||
supportGLES2 = true;
|
||||
|
||||
if ((attribVal[0] & EGL_OPENGL_ES3_BIT_KHR) != 0)
|
||||
supportGLES3 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Creates the context and surface.
|
||||
private void create(int width, int height, int renderableType)
|
||||
{
|
||||
int[] attribs = {
|
||||
EGL10.EGL_WIDTH, width,
|
||||
EGL10.EGL_HEIGHT, height,
|
||||
EGL10.EGL_NONE
|
||||
};
|
||||
|
||||
// Initially we just assume GLES2 will be the default context.
|
||||
int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
|
||||
int[] ctx_attribs = {
|
||||
EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||
EGL10.EGL_NONE
|
||||
};
|
||||
|
||||
// Determine the type of context that will be created
|
||||
// and change the attribute arrays accordingly.
|
||||
switch (renderableType)
|
||||
{
|
||||
case EGL_OPENGL_ES_BIT:
|
||||
ctx_attribs[1] = 1;
|
||||
break;
|
||||
|
||||
case EGL_OPENGL_BIT:
|
||||
ctx_attribs[0] = EGL10.EGL_NONE;
|
||||
break;
|
||||
|
||||
case EGL_OPENGL_ES3_BIT_KHR:
|
||||
ctx_attribs[1] = 3;
|
||||
break;
|
||||
|
||||
case EGL_OPENGL_ES2_BIT:
|
||||
default: // Fall-back to GLES 2.
|
||||
ctx_attribs[1] = 2;
|
||||
break;
|
||||
}
|
||||
if (renderableType == EGL_OPENGL_BIT)
|
||||
NativeLibrary.eglBindAPI(EGL_OPENGL_API);
|
||||
else
|
||||
NativeLibrary.eglBindAPI(EGL_OPENGL_ES_API);
|
||||
|
||||
mEGLContext =
|
||||
mEGL.eglCreateContext(mDisplay, mEGLConfigs[0], EGL10.EGL_NO_CONTEXT, ctx_attribs);
|
||||
mEGLSurface = mEGL.eglCreatePbufferSurface(mDisplay, mEGLConfigs[0], attribs);
|
||||
mEGL.eglMakeCurrent(mDisplay, mEGLSurface, mEGLSurface, mEGLContext);
|
||||
mGL = (GL10) mEGLContext.getGL();
|
||||
}
|
||||
|
||||
/**
|
||||
* Simplified call to {@link GL10#glGetString(int)}
|
||||
* <p>
|
||||
* Accepts the following constants:
|
||||
* <ul>
|
||||
* <li>GL_VENDOR - Company responsible for the GL implementation.</li>
|
||||
* <li>GL_VERSION - Version or release number.</li>
|
||||
* <li>GL_RENDERER - Name of the renderer</li>
|
||||
* <li>GL_SHADING_LANGUAGE_VERSION - Version or release number of the shading language </li>
|
||||
* </ul>
|
||||
*
|
||||
* @param glEnum A symbolic constant within {@link GL10}.
|
||||
* @return the string information represented by {@code glEnum}.
|
||||
*/
|
||||
public String glGetString(int glEnum)
|
||||
{
|
||||
return mGL.glGetString(glEnum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simplified call to {@link GLES30#glGetStringi(int, int)}
|
||||
* <p>
|
||||
* Accepts the following constants:
|
||||
* <ul>
|
||||
* <li>GL_VENDOR - Company responsible for the GL implementation.</li>
|
||||
* <li>GL_VERSION - Version or release number.</li>
|
||||
* <li>GL_RENDERER - Name of the renderer</li>
|
||||
* <li>GL_SHADING_LANGUAGE_VERSION - Version or release number of the shading language </li>
|
||||
* <li>GL_EXTENSIONS - Extension string supported by the implementation at {@code index}.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param glEnum A symbolic GL constant
|
||||
* @param index The index of the string to return.
|
||||
* @return the string information represented by {@code glEnum} and {@code index}.
|
||||
*/
|
||||
public String glGetStringi(int glEnum, int index)
|
||||
{
|
||||
return GLES30.glGetStringi(glEnum, index);
|
||||
}
|
||||
|
||||
public boolean SupportsExtension(String extension)
|
||||
{
|
||||
int[] num_ext = new int[1];
|
||||
GLES30.glGetIntegerv(GLES30.GL_NUM_EXTENSIONS, num_ext, 0);
|
||||
|
||||
for (int i = 0; i < num_ext[0]; ++i)
|
||||
{
|
||||
String ext = GLES30.glGetStringi(GLES30.GL_EXTENSIONS, i);
|
||||
if (ext.equals(extension))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int GetVersion()
|
||||
{
|
||||
int[] major = new int[1];
|
||||
int[] minor = new int[1];
|
||||
GLES30.glGetIntegerv(GLES30.GL_MAJOR_VERSION, major, 0);
|
||||
GLES30.glGetIntegerv(GLES30.GL_MINOR_VERSION, minor, 0);
|
||||
return major[0] * 100 + minor[0] * 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simplified call to {@link GL10#glGetIntegerv(int, int[], int)
|
||||
*
|
||||
* @param glEnum A symbolic GL constant.
|
||||
* @return the integer information represented by {@code glEnum}.
|
||||
*/
|
||||
public int glGetInteger(int glEnum)
|
||||
{
|
||||
int[] val = new int[1];
|
||||
mGL.glGetIntegerv(glEnum, val, 0);
|
||||
return val[0];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
* Copyright 2013 Dolphin Emulator Project
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
package org.dolphinemu.dolphinemu.utils
|
||||
|
||||
import android.opengl.GLES30
|
||||
|
||||
import org.dolphinemu.dolphinemu.NativeLibrary
|
||||
|
||||
import javax.microedition.khronos.egl.EGL10
|
||||
import javax.microedition.khronos.egl.EGLConfig
|
||||
import javax.microedition.khronos.egl.EGLContext
|
||||
import javax.microedition.khronos.egl.EGLDisplay
|
||||
import javax.microedition.khronos.egl.EGLSurface
|
||||
|
||||
/**
|
||||
* Utility class that abstracts all the stuff about
|
||||
* EGL initialization out of the way if all that is
|
||||
* wanted is to query the underlying GL API for information.
|
||||
*/
|
||||
class EGLHelper(width: Int, height: Int, renderableType: Int) {
|
||||
private val mEGL: EGL10 = EGLContext.getEGL() as EGL10
|
||||
private val mDisplay: EGLDisplay = mEGL.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY)
|
||||
private lateinit var mEGLConfigs: Array<EGLConfig>
|
||||
private lateinit var mEGLContext: EGLContext
|
||||
private lateinit var mEGLSurface: EGLSurface
|
||||
|
||||
// GL support flags
|
||||
private var supportGL = false
|
||||
private var supportGLES3 = false
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Initializes the underlying [EGLSurface] with a width and height of 1.
|
||||
* This is useful if all you need to use this class for is to query information
|
||||
* from specific API contexts.
|
||||
*
|
||||
* @param renderableType Bitmask indicating which types of client API contexts
|
||||
* the framebuffer config must support.
|
||||
*/
|
||||
constructor(renderableType: Int) : this(1, 1, renderableType)
|
||||
|
||||
init {
|
||||
// If a display is present, initialize EGL.
|
||||
if (mDisplay != EGL10.EGL_NO_DISPLAY) {
|
||||
val version = IntArray(2)
|
||||
if (mEGL.eglInitialize(mDisplay, version)) {
|
||||
// Detect supported GL APIs, initialize configs, etc.
|
||||
detect()
|
||||
|
||||
// Create context and surface
|
||||
create(width, height, renderableType)
|
||||
} else {
|
||||
Log.error("[EGLHelper] Error initializing EGL.")
|
||||
}
|
||||
} else {
|
||||
Log.error("[EGLHelper] Error initializing EGL display.")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this device supports OpenGL.
|
||||
*
|
||||
* @return true if this device supports OpenGL; false otherwise.
|
||||
*/
|
||||
fun supportsOpenGL(): Boolean {
|
||||
return supportGL
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this device supports OpenGL ES 3.
|
||||
*
|
||||
* Note that if this returns true, then OpenGL ES 1 and 2 are also supported.
|
||||
*
|
||||
* @return true if this device supports OpenGL ES 3; false otherwise.
|
||||
*/
|
||||
fun supportsGLES3(): Boolean {
|
||||
return supportGLES3
|
||||
}
|
||||
|
||||
// Detects the specific kind of GL modes that are supported
|
||||
private fun detect() {
|
||||
// Get total number of configs available.
|
||||
val numConfigs = IntArray(1)
|
||||
if (!mEGL.eglGetConfigs(mDisplay, null, 0, numConfigs)) {
|
||||
Log.error("[EGLHelper] Error retrieving number of EGL configs available.")
|
||||
return
|
||||
}
|
||||
|
||||
// Now get all the configurations
|
||||
val eglConfigs = arrayOfNulls<EGLConfig>(numConfigs[0])
|
||||
if (!mEGL.eglGetConfigs(mDisplay, eglConfigs, eglConfigs.size, numConfigs)) {
|
||||
Log.error("[EGLHelper] Error retrieving all EGL configs.")
|
||||
return
|
||||
}
|
||||
mEGLConfigs = Array(eglConfigs.size) { i -> eglConfigs[i]!! }
|
||||
|
||||
for (eglConfig in mEGLConfigs) {
|
||||
val attribVal = IntArray(1)
|
||||
val ret =
|
||||
mEGL.eglGetConfigAttrib(mDisplay, eglConfig, EGL10.EGL_RENDERABLE_TYPE, attribVal)
|
||||
if (ret) {
|
||||
if ((attribVal[0] and EGL_OPENGL_BIT) != 0) supportGL = true
|
||||
|
||||
if ((attribVal[0] and EGL_OPENGL_ES3_BIT_KHR) != 0) supportGLES3 = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Creates the context and surface.
|
||||
private fun create(width: Int, height: Int, renderableType: Int) {
|
||||
val attribs = intArrayOf(
|
||||
EGL10.EGL_WIDTH, width, EGL10.EGL_HEIGHT, height, EGL10.EGL_NONE
|
||||
)
|
||||
|
||||
// Initially we just assume GLES2 will be the default context.
|
||||
val eglContextClientVersion = 0x3098
|
||||
val ctxAttribs = intArrayOf(
|
||||
eglContextClientVersion, 2, EGL10.EGL_NONE
|
||||
)
|
||||
|
||||
// Determine the type of context that will be created
|
||||
// and change the attribute arrays accordingly.
|
||||
when (renderableType) {
|
||||
EGL_OPENGL_ES_BIT -> ctxAttribs[1] = 1
|
||||
EGL_OPENGL_BIT -> ctxAttribs[0] = EGL10.EGL_NONE
|
||||
EGL_OPENGL_ES3_BIT_KHR -> ctxAttribs[1] = 3
|
||||
EGL_OPENGL_ES2_BIT -> ctxAttribs[1] = 2
|
||||
else -> ctxAttribs[1] = 2 // Fall-back to GLES 2.
|
||||
}
|
||||
if (renderableType == EGL_OPENGL_BIT) {
|
||||
NativeLibrary.eglBindAPI(EGL_OPENGL_API)
|
||||
} else {
|
||||
NativeLibrary.eglBindAPI(EGL_OPENGL_ES_API)
|
||||
}
|
||||
|
||||
mEGLContext =
|
||||
mEGL.eglCreateContext(mDisplay, mEGLConfigs[0], EGL10.EGL_NO_CONTEXT, ctxAttribs)
|
||||
mEGLSurface = mEGL.eglCreatePbufferSurface(mDisplay, mEGLConfigs[0], attribs)
|
||||
mEGL.eglMakeCurrent(mDisplay, mEGLSurface, mEGLSurface, mEGLContext)
|
||||
}
|
||||
|
||||
fun supportsExtension(extension: String): Boolean {
|
||||
val numExt = IntArray(1)
|
||||
GLES30.glGetIntegerv(GLES30.GL_NUM_EXTENSIONS, numExt, 0)
|
||||
|
||||
for (i in 0 until numExt[0]) {
|
||||
val ext = GLES30.glGetStringi(GLES30.GL_EXTENSIONS, i)
|
||||
if (ext.equals(extension)) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun getVersion(): Int {
|
||||
val major = IntArray(1)
|
||||
val minor = IntArray(1)
|
||||
GLES30.glGetIntegerv(GLES30.GL_MAJOR_VERSION, major, 0)
|
||||
GLES30.glGetIntegerv(GLES30.GL_MINOR_VERSION, minor, 0)
|
||||
return major[0] * 100 + minor[0] * 10
|
||||
}
|
||||
|
||||
companion object {
|
||||
// Renderable type bitmasks
|
||||
const val EGL_OPENGL_ES_BIT = 0x0001
|
||||
const val EGL_OPENGL_ES2_BIT = 0x0004
|
||||
const val EGL_OPENGL_BIT = 0x0008
|
||||
const val EGL_OPENGL_ES3_BIT_KHR = 0x0040
|
||||
|
||||
// API types
|
||||
const val EGL_OPENGL_ES_API = 0x30A0
|
||||
const val EGL_OPENGL_API = 0x30A2
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user