Merge pull request #11188 from unknownbrackets/sdl-egl

Apply some heuristics to choosing an EGL config
This commit is contained in:
Henrik Rydgård 2018-06-17 21:52:14 +02:00 committed by GitHub
commit 03c89e7689
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,3 +1,4 @@
#include <vector>
#include "SDLGLGraphicsContext.h"
#include "Core/Config.h"
#include "Core/System.h"
@ -72,34 +73,105 @@ int8_t EGL_Open() {
return 0;
}
int8_t EGL_Init() {
EGLConfig g_eglConfig;
EGLint g_numConfigs = 0;
EGLint attrib_list[]= {
// TODO: Should cycle through fallbacks, like on Android
#ifdef USING_FBDEV
EGL_RED_SIZE, 5,
EGL_GREEN_SIZE, 6,
EGL_BLUE_SIZE, 5,
#ifndef EGL_OPENGL_ES3_BIT_KHR
#define EGL_OPENGL_ES3_BIT_KHR (1 << 6)
#endif
EGL_DEPTH_SIZE, 16,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGLConfig EGL_FindConfig(int *contextVersion) {
std::vector<EGLConfig> configs;
EGLint numConfigs = 0;
EGLBoolean result = eglGetConfigs(g_eglDisplay, nullptr, 0, &numConfigs);
if (result != EGL_TRUE || numConfigs == 0) {
return nullptr;
}
configs.resize(numConfigs);
result = eglGetConfigs(g_eglDisplay, &configs[0], numConfigs, &numConfigs);
if (result != EGL_TRUE || numConfigs == 0) {
return nullptr;
}
// Mali (ARM) seems to have compositing issues with alpha backbuffers.
// EGL_TRANSPARENT_TYPE doesn't help.
const char *vendorName = eglQueryString(g_eglDisplay, EGL_VENDOR);
const bool avoidAlphaGLES = vendorName && !strcmp(vendorName, "ARM");
EGLConfig best = nullptr;
int bestScore = 0;
int bestContextVersion = 0;
for (const EGLConfig &config : configs) {
auto readConfig = [&](EGLint attr) -> EGLint {
EGLint val = 0;
eglGetConfigAttrib(g_eglDisplay, config, attr, &val);
return val;
};
int colorScore = readConfig(EGL_RED_SIZE) + readConfig(EGL_BLUE_SIZE) + readConfig(EGL_GREEN_SIZE);
int alphaScore = readConfig(EGL_ALPHA_SIZE);
int depthScore = readConfig(EGL_DEPTH_SIZE);
int levelScore = readConfig(EGL_LEVEL) == 0 ? 100 : 0;
int samplesScore = readConfig(EGL_SAMPLES) == 0 ? 100 : 0;
int sampleBufferScore = readConfig(EGL_SAMPLE_BUFFERS) == 0 ? 100 : 0;
int stencilScore = readConfig(EGL_STENCIL_SIZE);
int transparentScore = readConfig(EGL_TRANSPARENT_TYPE) == EGL_NONE ? 50 : 0;
EGLint caveat = readConfig(EGL_CONFIG_CAVEAT);
int caveatScore = caveat == EGL_NONE ? 100 : (caveat == EGL_NON_CONFORMANT_CONFIG ? 50 : 0);
EGLint renderable = readConfig(EGL_RENDERABLE_TYPE);
bool renderableGLES3 = (renderable & EGL_OPENGL_ES3_BIT_KHR) != 0;
bool renderableGLES2 = (renderable & EGL_OPENGL_ES2_BIT) != 0;
bool renderableGL = (renderable & EGL_OPENGL_BIT) != 0;
#ifdef USING_GLES2
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
int renderableScoreGLES = renderableGLES3 ? 100 : (renderableGLES2 ? 80 : 0);
int renderableScoreGL = 0;
#else
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
int renderableScoreGLES = 0;
int renderableScoreGL = renderableGL ? 100 : (renderableGLES3 ? 80 : 0);
#endif
EGL_SAMPLE_BUFFERS, 0,
EGL_SAMPLES, 0,
EGL_NONE};
const EGLint attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
if (avoidAlphaGLES && renderableScoreGLES > 0) {
alphaScore = 8 - alphaScore;
}
EGLBoolean result = eglChooseConfig(g_eglDisplay, attrib_list, &g_eglConfig, 1, &g_numConfigs);
if (result != EGL_TRUE || g_numConfigs == 0) EGL_ERROR("Unable to query for available configs.", true);
int score = 0;
// Here's a good place to play with the weights to pick a better config.
score += (colorScore + alphaScore) * 10;
score += depthScore * 5 + stencilScore;
score += levelScore + samplesScore + sampleBufferScore + transparentScore;
score += caveatScore + renderableScoreGLES + renderableScoreGL;
g_eglContext = eglCreateContext(g_eglDisplay, g_eglConfig, NULL, attributes );
if (g_eglContext == EGL_NO_CONTEXT) EGL_ERROR("Unable to create GLES context!", true);
if (score > bestScore) {
bestScore = score;
best = config;
bestContextVersion = renderableGLES3 ? 3 : (renderableGLES2 ? 2 : 0);
}
}
*contextVersion = bestContextVersion;
return best;
}
int8_t EGL_Init() {
int contextVersion = 0;
EGLConfig eglConfig = EGL_FindConfig(&contextVersion);
if (!eglConfig) {
EGL_ERROR("Unable to find a usable EGL config.", true);
}
EGLint contextAttributes[] = {
EGL_CONTEXT_CLIENT_VERSION, contextVersion,
EGL_NONE,
};
if (contextVersion == 0) {
contextAttributes[0] = EGL_NONE;
}
g_eglContext = eglCreateContext(g_eglDisplay, eglConfig, nullptr, contextAttributes);
if (g_eglContext == EGL_NO_CONTEXT) {
EGL_ERROR("Unable to create GLES context!", true);
}
#if !defined(USING_FBDEV) && !defined(__APPLE__)
//Get the SDL window handle
@ -109,7 +181,7 @@ int8_t EGL_Init() {
#else
g_Window = (NativeWindowType)NULL;
#endif
g_eglSurface = eglCreateWindowSurface(g_eglDisplay, g_eglConfig, g_Window, 0);
g_eglSurface = eglCreateWindowSurface(g_eglDisplay, eglConfig, g_Window, nullptr);
if (g_eglSurface == EGL_NO_SURFACE)
EGL_ERROR("Unable to create EGL surface!", true);