OPENGL: Add compatibility checks for LibRetro shader support
This commit is contained in:
parent
cdbb0fa32f
commit
c5705561b0
3 changed files with 62 additions and 21 deletions
|
@ -61,19 +61,24 @@
|
||||||
|
|
||||||
#include "common/text-to-speech.h"
|
#include "common/text-to-speech.h"
|
||||||
|
|
||||||
|
#if !USE_FORCED_GLES
|
||||||
#include "backends/graphics/opengl/pipelines/libretro/parser.h"
|
#include "backends/graphics/opengl/pipelines/libretro/parser.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace OpenGL {
|
namespace OpenGL {
|
||||||
|
|
||||||
OpenGLGraphicsManager::OpenGLGraphicsManager()
|
OpenGLGraphicsManager::OpenGLGraphicsManager()
|
||||||
: _currentState(), _oldState(), _transactionMode(kTransactionNone), _screenChangeID(1 << (sizeof(int) * 8 - 2)),
|
: _currentState(), _oldState(), _transactionMode(kTransactionNone), _screenChangeID(1 << (sizeof(int) * 8 - 2)),
|
||||||
_pipeline(nullptr), _libretroPipeline(nullptr), _stretchMode(STRETCH_FIT),
|
_pipeline(nullptr), _stretchMode(STRETCH_FIT),
|
||||||
_defaultFormat(), _defaultFormatAlpha(),
|
_defaultFormat(), _defaultFormatAlpha(),
|
||||||
_gameScreen(nullptr), _gameScreenTarget(nullptr), _overlay(nullptr),
|
_gameScreen(nullptr), _overlay(nullptr),
|
||||||
_cursor(nullptr),
|
_cursor(nullptr),
|
||||||
_cursorHotspotX(0), _cursorHotspotY(0),
|
_cursorHotspotX(0), _cursorHotspotY(0),
|
||||||
_cursorHotspotXScaled(0), _cursorHotspotYScaled(0), _cursorWidthScaled(0), _cursorHeightScaled(0),
|
_cursorHotspotXScaled(0), _cursorHotspotYScaled(0), _cursorWidthScaled(0), _cursorHeightScaled(0),
|
||||||
_cursorKeyColor(0), _cursorDontScale(false), _cursorPaletteEnabled(false), _shakeOffsetScaled()
|
_cursorKeyColor(0), _cursorDontScale(false), _cursorPaletteEnabled(false), _shakeOffsetScaled()
|
||||||
|
#if !USE_FORCED_GLES
|
||||||
|
, _libretroPipeline(nullptr), _gameScreenTarget(nullptr)
|
||||||
|
#endif
|
||||||
#ifdef USE_OSD
|
#ifdef USE_OSD
|
||||||
, _osdMessageChangeRequest(false), _osdMessageAlpha(0), _osdMessageFadeStartTime(0), _osdMessageSurface(nullptr),
|
, _osdMessageChangeRequest(false), _osdMessageAlpha(0), _osdMessageFadeStartTime(0), _osdMessageSurface(nullptr),
|
||||||
_osdIconSurface(nullptr)
|
_osdIconSurface(nullptr)
|
||||||
|
@ -87,7 +92,6 @@ OpenGLGraphicsManager::OpenGLGraphicsManager()
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGLGraphicsManager::~OpenGLGraphicsManager() {
|
OpenGLGraphicsManager::~OpenGLGraphicsManager() {
|
||||||
delete _gameScreenTarget;
|
|
||||||
delete _gameScreen;
|
delete _gameScreen;
|
||||||
delete _overlay;
|
delete _overlay;
|
||||||
delete _cursor;
|
delete _cursor;
|
||||||
|
@ -96,6 +100,7 @@ OpenGLGraphicsManager::~OpenGLGraphicsManager() {
|
||||||
delete _osdIconSurface;
|
delete _osdIconSurface;
|
||||||
#endif
|
#endif
|
||||||
#if !USE_FORCED_GLES
|
#if !USE_FORCED_GLES
|
||||||
|
delete _gameScreenTarget;
|
||||||
ShaderManager::destroy();
|
ShaderManager::destroy();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -456,11 +461,13 @@ OSystem::TransactionError OpenGLGraphicsManager::endGFXTransaction() {
|
||||||
delete _gameScreen;
|
delete _gameScreen;
|
||||||
_gameScreen = nullptr;
|
_gameScreen = nullptr;
|
||||||
|
|
||||||
|
#if !USE_FORCED_GLES
|
||||||
if (_gameScreenTarget != nullptr) {
|
if (_gameScreenTarget != nullptr) {
|
||||||
_gameScreenTarget->destroy();
|
_gameScreenTarget->destroy();
|
||||||
delete _gameScreenTarget;
|
delete _gameScreenTarget;
|
||||||
_gameScreenTarget = nullptr;
|
_gameScreenTarget = nullptr;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool wantScaler = _currentState.scaleFactor > 1;
|
bool wantScaler = _currentState.scaleFactor > 1;
|
||||||
|
|
||||||
|
@ -493,11 +500,13 @@ OSystem::TransactionError OpenGLGraphicsManager::endGFXTransaction() {
|
||||||
_gameScreen->fill(0);
|
_gameScreen->fill(0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !USE_FORCED_GLES
|
||||||
if (_libretroPipeline) {
|
if (_libretroPipeline) {
|
||||||
_gameScreenTarget = new TextureTarget();
|
_gameScreenTarget = new TextureTarget();
|
||||||
_gameScreenTarget->create();
|
_gameScreenTarget->create();
|
||||||
_gameScreenTarget->setSize(_currentState.gameWidth, _currentState.gameHeight);
|
_gameScreenTarget->setSize(_currentState.gameWidth, _currentState.gameHeight);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update our display area and cursor scaling. This makes sure we pick up
|
// Update our display area and cursor scaling. This makes sure we pick up
|
||||||
|
@ -603,25 +612,31 @@ void OpenGLGraphicsManager::updateScreen() {
|
||||||
// Alpha blending is disabled when drawing the screen
|
// Alpha blending is disabled when drawing the screen
|
||||||
_backBuffer.enableBlend(Framebuffer::kBlendModeDisabled);
|
_backBuffer.enableBlend(Framebuffer::kBlendModeDisabled);
|
||||||
|
|
||||||
|
bool needsCursor = _cursorVisible && _cursor;
|
||||||
|
|
||||||
// First step: Draw the (virtual) game screen.
|
// First step: Draw the (virtual) game screen.
|
||||||
if (_libretroPipeline) {
|
#if !USE_FORCED_GLES
|
||||||
|
if (_libretroPipeline && _libretroPipeline->isInitialized()) {
|
||||||
Framebuffer *lastFramebuffer = Pipeline::getActivePipeline()->setFramebuffer(_gameScreenTarget);
|
Framebuffer *lastFramebuffer = Pipeline::getActivePipeline()->setFramebuffer(_gameScreenTarget);
|
||||||
_gameScreenTarget->enableBlend(Framebuffer::kBlendModeDisabled);
|
_gameScreenTarget->enableBlend(Framebuffer::kBlendModeDisabled);
|
||||||
Pipeline::getActivePipeline()->drawTexture(_gameScreen->getGLTexture(), 0, 0, _gameScreen->getWidth(), _gameScreen->getHeight());
|
Pipeline::getActivePipeline()->drawTexture(_gameScreen->getGLTexture(), 0, 0, _gameScreen->getWidth(), _gameScreen->getHeight());
|
||||||
|
|
||||||
// Draw the cursor if necessary.
|
// Draw the cursor if necessary.
|
||||||
if (_cursorVisible && _cursor && !_overlayVisible) {
|
if (needsCursor && !_overlayVisible) {
|
||||||
int gameScreenCursorX = (_cursorX - _gameDrawRect.left) * _gameScreen->getWidth() / _gameDrawRect.width() - _cursorHotspotX;
|
int gameScreenCursorX = (_cursorX - _gameDrawRect.left) * _gameScreen->getWidth() / _gameDrawRect.width() - _cursorHotspotX;
|
||||||
int gameScreenCursorY = (_cursorY - _gameDrawRect.top) * _gameScreen->getHeight() / _gameDrawRect.height() - _cursorHotspotY;
|
int gameScreenCursorY = (_cursorY - _gameDrawRect.top) * _gameScreen->getHeight() / _gameDrawRect.height() - _cursorHotspotY;
|
||||||
_gameScreenTarget->enableBlend(Framebuffer::kBlendModePremultipliedTransparency);
|
_gameScreenTarget->enableBlend(Framebuffer::kBlendModePremultipliedTransparency);
|
||||||
Pipeline::getActivePipeline()->drawTexture(_cursor->getGLTexture(), gameScreenCursorX, gameScreenCursorY, _cursor->getWidth(), _cursor->getHeight());
|
Pipeline::getActivePipeline()->drawTexture(_cursor->getGLTexture(), gameScreenCursorX, gameScreenCursorY, _cursor->getWidth(), _cursor->getHeight());
|
||||||
|
needsCursor = false;
|
||||||
}
|
}
|
||||||
Pipeline::getActivePipeline()->setFramebuffer(lastFramebuffer);
|
Pipeline::getActivePipeline()->setFramebuffer(lastFramebuffer);
|
||||||
|
|
||||||
Pipeline *lastPipeline = Pipeline::setPipeline(_libretroPipeline);
|
Pipeline *lastPipeline = Pipeline::setPipeline(_libretroPipeline);
|
||||||
Pipeline::getActivePipeline()->drawTexture(*_gameScreenTarget->getTexture(), _gameDrawRect.left, _gameDrawRect.top, _gameDrawRect.width(), _gameDrawRect.height());
|
Pipeline::getActivePipeline()->drawTexture(*_gameScreenTarget->getTexture(), _gameDrawRect.left, _gameDrawRect.top, _gameDrawRect.width(), _gameDrawRect.height());
|
||||||
Pipeline::setPipeline(lastPipeline);
|
Pipeline::setPipeline(lastPipeline);
|
||||||
} else {
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
Pipeline::getActivePipeline()->drawTexture(_gameScreen->getGLTexture(), _gameDrawRect.left, _gameDrawRect.top, _gameDrawRect.width(), _gameDrawRect.height());
|
Pipeline::getActivePipeline()->drawTexture(_gameScreen->getGLTexture(), _gameDrawRect.left, _gameDrawRect.top, _gameDrawRect.width(), _gameDrawRect.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -634,7 +649,7 @@ void OpenGLGraphicsManager::updateScreen() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Third step: Draw the cursor if necessary.
|
// Third step: Draw the cursor if necessary.
|
||||||
if (_cursorVisible && _cursor && (_overlayVisible || !_libretroPipeline)) {
|
if (needsCursor) {
|
||||||
_backBuffer.enableBlend(Framebuffer::kBlendModePremultipliedTransparency);
|
_backBuffer.enableBlend(Framebuffer::kBlendModePremultipliedTransparency);
|
||||||
|
|
||||||
Pipeline::getActivePipeline()->drawTexture(_cursor->getGLTexture(),
|
Pipeline::getActivePipeline()->drawTexture(_cursor->getGLTexture(),
|
||||||
|
@ -1109,10 +1124,12 @@ void OpenGLGraphicsManager::notifyContextCreate(ContextType type,
|
||||||
delete _pipeline;
|
delete _pipeline;
|
||||||
_pipeline = nullptr;
|
_pipeline = nullptr;
|
||||||
|
|
||||||
|
#if !USE_FORCED_GLES
|
||||||
if (_libretroPipeline) {
|
if (_libretroPipeline) {
|
||||||
delete _libretroPipeline;
|
delete _libretroPipeline;
|
||||||
_libretroPipeline = nullptr;
|
_libretroPipeline = nullptr;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
OpenGLContext.initialize(type);
|
OpenGLContext.initialize(type);
|
||||||
|
|
||||||
|
@ -1120,14 +1137,6 @@ void OpenGLGraphicsManager::notifyContextCreate(ContextType type,
|
||||||
if (OpenGLContext.shadersSupported) {
|
if (OpenGLContext.shadersSupported) {
|
||||||
ShaderMan.notifyCreate();
|
ShaderMan.notifyCreate();
|
||||||
_pipeline = new ShaderPipeline(ShaderMan.query(ShaderManager::kDefault));
|
_pipeline = new ShaderPipeline(ShaderMan.query(ShaderManager::kDefault));
|
||||||
|
|
||||||
// Load selected shader preset from config file
|
|
||||||
if (ConfMan.hasKey("shader_scaler", Common::ConfigManager::kApplicationDomain)) {
|
|
||||||
Common::FSNode shaderPreset(ConfMan.get("shader_scaler", Common::ConfigManager::kApplicationDomain));
|
|
||||||
if (shaderPreset.isReadable()) {
|
|
||||||
_libretroPipeline = new LibRetroPipeline(shaderPreset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1144,10 +1153,6 @@ void OpenGLGraphicsManager::notifyContextCreate(ContextType type,
|
||||||
|
|
||||||
_pipeline->setColor(1.0f, 1.0f, 1.0f, 1.0f);
|
_pipeline->setColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
|
||||||
if (_libretroPipeline) {
|
|
||||||
_libretroPipeline->setColor(1.0f, 1.0f, 1.0f, 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup backbuffer state.
|
// Setup backbuffer state.
|
||||||
|
|
||||||
// Default to black as clear color.
|
// Default to black as clear color.
|
||||||
|
@ -1155,9 +1160,26 @@ void OpenGLGraphicsManager::notifyContextCreate(ContextType type,
|
||||||
|
|
||||||
_pipeline->setFramebuffer(&_backBuffer);
|
_pipeline->setFramebuffer(&_backBuffer);
|
||||||
|
|
||||||
if (_libretroPipeline) {
|
// Setup LibRetro pipeline.
|
||||||
|
|
||||||
|
#if !USE_FORCED_GLES
|
||||||
|
if (LibRetroPipeline::isSupportedByContext()) {
|
||||||
|
_libretroPipeline = new LibRetroPipeline();
|
||||||
|
|
||||||
|
// Load selected shader preset from config file
|
||||||
|
// TODO: Handle this in endGFXTransaction()
|
||||||
|
if (ConfMan.hasKey("shader_scaler", Common::ConfigManager::kApplicationDomain)) {
|
||||||
|
Common::FSNode shaderPreset(ConfMan.get("shader_scaler", Common::ConfigManager::kApplicationDomain));
|
||||||
|
if (shaderPreset.isReadable()) {
|
||||||
|
if (!_libretroPipeline->open(shaderPreset))
|
||||||
|
warning("Failed to load %s", shaderPreset.getName().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_libretroPipeline->setColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
_libretroPipeline->setFramebuffer(&_backBuffer);
|
_libretroPipeline->setFramebuffer(&_backBuffer);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// We use a "pack" alignment (when reading from textures) to 4 here,
|
// We use a "pack" alignment (when reading from textures) to 4 here,
|
||||||
// since the only place where we really use it is the BMP screenshot
|
// since the only place where we really use it is the BMP screenshot
|
||||||
|
@ -1179,9 +1201,11 @@ void OpenGLGraphicsManager::notifyContextCreate(ContextType type,
|
||||||
_gameScreen->recreate();
|
_gameScreen->recreate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !USE_FORCED_GLES
|
||||||
if (_gameScreenTarget) {
|
if (_gameScreenTarget) {
|
||||||
_gameScreenTarget->create();
|
_gameScreenTarget->create();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (_overlay) {
|
if (_overlay) {
|
||||||
_overlay->recreate();
|
_overlay->recreate();
|
||||||
|
@ -1211,9 +1235,11 @@ void OpenGLGraphicsManager::notifyContextDestroy() {
|
||||||
_gameScreen->destroy();
|
_gameScreen->destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !USE_FORCED_GLES
|
||||||
if (_gameScreenTarget) {
|
if (_gameScreenTarget) {
|
||||||
_gameScreenTarget->destroy();
|
_gameScreenTarget->destroy();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (_overlay) {
|
if (_overlay) {
|
||||||
_overlay->destroy();
|
_overlay->destroy();
|
||||||
|
@ -1244,10 +1270,12 @@ void OpenGLGraphicsManager::notifyContextDestroy() {
|
||||||
delete _pipeline;
|
delete _pipeline;
|
||||||
_pipeline = nullptr;
|
_pipeline = nullptr;
|
||||||
|
|
||||||
|
#if !USE_FORCED_GLES
|
||||||
if (_libretroPipeline) {
|
if (_libretroPipeline) {
|
||||||
delete _libretroPipeline;
|
delete _libretroPipeline;
|
||||||
_libretroPipeline = nullptr;
|
_libretroPipeline = nullptr;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Rest our context description since the context is gone soon.
|
// Rest our context description since the context is gone soon.
|
||||||
OpenGLContext.reset();
|
OpenGLContext.reset();
|
||||||
|
|
|
@ -44,6 +44,9 @@ namespace OpenGL {
|
||||||
|
|
||||||
class Surface;
|
class Surface;
|
||||||
class Pipeline;
|
class Pipeline;
|
||||||
|
#if !USE_FORCED_GLES
|
||||||
|
class LibRetroPipeline;
|
||||||
|
#endif
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
GFX_OPENGL = 0
|
GFX_OPENGL = 0
|
||||||
|
@ -290,10 +293,12 @@ private:
|
||||||
*/
|
*/
|
||||||
Pipeline *_pipeline;
|
Pipeline *_pipeline;
|
||||||
|
|
||||||
|
#if !USE_FORCED_GLES
|
||||||
/**
|
/**
|
||||||
* OpenGL pipeline used for post-processing.
|
* OpenGL pipeline used for post-processing.
|
||||||
*/
|
*/
|
||||||
Pipeline *_libretroPipeline;
|
LibRetroPipeline *_libretroPipeline;
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
|
@ -333,11 +338,13 @@ protected:
|
||||||
*/
|
*/
|
||||||
byte _gamePalette[3 * 256];
|
byte _gamePalette[3 * 256];
|
||||||
|
|
||||||
|
#if !USE_FORCED_GLES
|
||||||
/**
|
/**
|
||||||
* The render target for the virtual game screen. Used when
|
* The render target for the virtual game screen. Used when
|
||||||
* LibRetro shaders are enabled.
|
* LibRetro shaders are enabled.
|
||||||
*/
|
*/
|
||||||
TextureTarget *_gameScreenTarget;
|
TextureTarget *_gameScreenTarget;
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Overlay
|
// Overlay
|
||||||
|
|
|
@ -63,6 +63,12 @@ public:
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
bool isInitialized() const { return _shaderPreset != nullptr; }
|
bool isInitialized() const { return _shaderPreset != nullptr; }
|
||||||
|
|
||||||
|
static bool isSupportedByContext() {
|
||||||
|
return OpenGLContext.shadersSupported
|
||||||
|
&& OpenGLContext.multitextureSupported
|
||||||
|
&& OpenGLContext.framebufferObjectSupported;
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
virtual void activateInternal();
|
virtual void activateInternal();
|
||||||
virtual void deactivateInternal();
|
virtual void deactivateInternal();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue