OPENGL: Rework renderer selection code
Add a class to group all renderer related (static) functions. This allows to have getBestMatchingAvailableType inline in all engines. The matching code is now shared between all engines but allows customization for engines needing it (Grim, WME3D). The new code takes runtime availability of features to select the best renderer. It avoid crashes when user choosed OpenGL but GLES2 is used.
This commit is contained in:
parent
b978cd1caa
commit
1e4696f6d0
14 changed files with 246 additions and 179 deletions
|
@ -22,6 +22,9 @@
|
|||
#include "graphics/renderer.h"
|
||||
|
||||
#include "common/translation.h"
|
||||
#include "common/system.h"
|
||||
|
||||
#include "graphics/opengl/context.h"
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
|
@ -40,12 +43,12 @@ static const RendererTypeDescription rendererTypes[] = {
|
|||
|
||||
DECLARE_TRANSLATION_ADDITIONAL_CONTEXT("OpenGL with shaders", "lowres")
|
||||
|
||||
const RendererTypeDescription *listRendererTypes() {
|
||||
const RendererTypeDescription *Renderer::listTypes() {
|
||||
return rendererTypes;
|
||||
}
|
||||
|
||||
RendererType parseRendererTypeCode(const Common::String &code) {
|
||||
const RendererTypeDescription *rt = listRendererTypes();
|
||||
RendererType Renderer::parseTypeCode(const Common::String &code) {
|
||||
const RendererTypeDescription *rt = listTypes();
|
||||
while (rt->code) {
|
||||
if (rt->code == code) {
|
||||
return rt->id;
|
||||
|
@ -56,8 +59,8 @@ RendererType parseRendererTypeCode(const Common::String &code) {
|
|||
return kRendererTypeDefault;
|
||||
}
|
||||
|
||||
Common::String getRendererTypeCode(RendererType type) {
|
||||
const RendererTypeDescription *rt = listRendererTypes();
|
||||
Common::String Renderer::getTypeCode(RendererType type) {
|
||||
const RendererTypeDescription *rt = listTypes();
|
||||
while (rt->code) {
|
||||
if (rt->id == type) {
|
||||
return rt->code;
|
||||
|
@ -68,30 +71,62 @@ Common::String getRendererTypeCode(RendererType type) {
|
|||
return "";
|
||||
}
|
||||
|
||||
RendererType getBestMatchingAvailableRendererType(RendererType desired) {
|
||||
if (desired == kRendererTypeDefault) {
|
||||
desired = kRendererTypeOpenGLShaders;
|
||||
}
|
||||
uint32 Renderer::getAvailableTypes() {
|
||||
uint32 available = 0;
|
||||
|
||||
#if !defined(USE_OPENGL_SHADERS)
|
||||
if (desired == kRendererTypeOpenGLShaders) {
|
||||
desired = kRendererTypeOpenGL;
|
||||
}
|
||||
#if defined(USE_TINYGL)
|
||||
/* TinyGL doesn't depend on hardware support */
|
||||
available |= kRendererTypeTinyGL;
|
||||
#endif
|
||||
|
||||
#if (!defined(USE_OPENGL_GAME) && defined(USE_OPENGL_SHADERS))
|
||||
if (desired == kRendererTypeOpenGL) {
|
||||
desired = kRendererTypeOpenGLShaders;
|
||||
}
|
||||
#endif
|
||||
#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
|
||||
bool backendCapableOpenGL = g_system->hasFeature(OSystem::kFeatureOpenGLForGame);
|
||||
|
||||
#if !defined(USE_OPENGL_GAME) && !defined(USE_OPENGL_SHADERS)
|
||||
if (desired == kRendererTypeOpenGL || desired == kRendererTypeOpenGLShaders) {
|
||||
desired = kRendererTypeTinyGL;
|
||||
}
|
||||
if (backendCapableOpenGL) {
|
||||
/* Backend either support OpenGL or OpenGL ES(2) */
|
||||
#if defined(USE_OPENGL_GAME)
|
||||
/* OpenGL classic is compiled in, check if hardware supports it */
|
||||
if (g_system->getOpenGLType() == OpenGL::kOGLContextGL) {
|
||||
available |= kRendererTypeOpenGL;
|
||||
}
|
||||
#endif
|
||||
#if defined(USE_OPENGL_SHADERS)
|
||||
/* OpenGL with shaders is compiled in, check if hardware supports it */
|
||||
if (g_system->hasFeature(OSystem::kFeatureShadersForGame)) {
|
||||
available |= kRendererTypeOpenGLShaders;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif // defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS
|
||||
return available;
|
||||
}
|
||||
|
||||
return desired;
|
||||
RendererType Renderer::getBestMatchingType(RendererType desired, uint32 available) {
|
||||
/* What we want is possible */
|
||||
if (available & desired) {
|
||||
return desired;
|
||||
}
|
||||
|
||||
/* We apply the same logic when nothing is desired and when what we want is not possible */
|
||||
if (desired != kRendererTypeDefault) {
|
||||
warning("Unable to create a '%s' renderer", getTypeCode(desired).c_str());
|
||||
}
|
||||
|
||||
/* Shaders are the best experience */
|
||||
if (available & kRendererTypeOpenGLShaders) {
|
||||
return kRendererTypeOpenGLShaders;
|
||||
}
|
||||
/* then OpenGL */
|
||||
if (available & kRendererTypeOpenGL) {
|
||||
return kRendererTypeOpenGL;
|
||||
}
|
||||
/* then TinyGL */
|
||||
if (available & kRendererTypeTinyGL) {
|
||||
return kRendererTypeTinyGL;
|
||||
}
|
||||
|
||||
/* Failure is not an option */
|
||||
error("Unable to create a renderer");
|
||||
}
|
||||
|
||||
} // End of namespace Graphics
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue