BACKENDS: OPENGL: Allow the backend to specify the render target

For now only backbuffer is used.
This commit is contained in:
Le Philousophe 2023-06-11 12:21:27 +02:00 committed by Lars Sundström
parent 10714db6f0
commit adda0dc063
4 changed files with 32 additions and 19 deletions

View file

@ -96,11 +96,13 @@ void AndroidGraphicsManager::initSurface() {
if (JNI::egl_bits_per_pixel == 16) {
// We default to RGB565 and RGBA5551 which is closest to what we setup in Java side
notifyContextCreate(OpenGL::kContextGLES2,
new OpenGL::Backbuffer(),
Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0),
Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0));
} else {
// If not 16, this must be 24 or 32 bpp so make use of them
notifyContextCreate(OpenGL::kContextGLES2,
new OpenGL::Backbuffer(),
#ifdef SCUMM_BIG_ENDIAN
Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0),
Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)
@ -234,7 +236,7 @@ void AndroidGraphicsManager::refreshScreen() {
}
void AndroidGraphicsManager::touchControlDraw(int16 x, int16 y, int16 w, int16 h, const Common::Rect &clip) {
_backBuffer.enableBlend(OpenGL::Framebuffer::kBlendModeTraditionalTransparency);
_targetBuffer->enableBlend(OpenGL::Framebuffer::kBlendModeTraditionalTransparency);
OpenGL::Pipeline *pipeline = getPipeline();
pipeline->activate();
pipeline->drawTexture(_touchcontrols->getGLTexture(),

View file

@ -71,7 +71,7 @@ namespace OpenGL {
OpenGLGraphicsManager::OpenGLGraphicsManager()
: _currentState(), _oldState(), _transactionMode(kTransactionNone), _screenChangeID(1 << (sizeof(int) * 8 - 2)),
_pipeline(nullptr), _stretchMode(STRETCH_FIT),
_defaultFormat(), _defaultFormatAlpha(),
_defaultFormat(), _defaultFormatAlpha(), _targetBuffer(nullptr),
_gameScreen(nullptr), _overlay(nullptr),
_cursor(nullptr), _cursorMask(nullptr),
_cursorHotspotX(0), _cursorHotspotY(0),
@ -105,6 +105,7 @@ OpenGLGraphicsManager::~OpenGLGraphicsManager() {
ShaderManager::destroy();
#endif
delete _pipeline;
delete _targetBuffer;
}
bool OpenGLGraphicsManager::hasFeature(OSystem::Feature f) const {
@ -609,16 +610,16 @@ void OpenGLGraphicsManager::renderCursor() {
the inversion and opacity mask at once. We use 1-srcAlpha instead of srcAlpha so zero-fill is transparent.
*/
if (_cursorMask) {
_backBuffer.enableBlend(Framebuffer::kBlendModeMaskAlphaAndInvertByColor);
_targetBuffer->enableBlend(Framebuffer::kBlendModeMaskAlphaAndInvertByColor);
_pipeline->drawTexture(_cursorMask->getGLTexture(),
_cursorX - _cursorHotspotXScaled + _shakeOffsetScaled.x,
_cursorY - _cursorHotspotYScaled + _shakeOffsetScaled.y,
_cursorWidthScaled, _cursorHeightScaled);
_backBuffer.enableBlend(Framebuffer::kBlendModeAdditive);
_targetBuffer->enableBlend(Framebuffer::kBlendModeAdditive);
} else
_backBuffer.enableBlend(Framebuffer::kBlendModePremultipliedTransparency);
_targetBuffer->enableBlend(Framebuffer::kBlendModePremultipliedTransparency);
_pipeline->drawTexture(_cursor->getGLTexture(),
_cursorX - _cursorHotspotXScaled + _shakeOffsetScaled.x,
@ -687,14 +688,14 @@ void OpenGLGraphicsManager::updateScreen() {
// The scissor test is enabled to:
// - Clip the cursor to the game screen
// - Clip the game screen when the shake offset is non-zero
_backBuffer.enableScissorTest(true);
_targetBuffer->enableScissorTest(true);
}
// Don't draw cursor if it's not visible or there is none
bool drawCursor = _cursorVisible && _cursor;
// Alpha blending is disabled when drawing the screen
_backBuffer.enableBlend(Framebuffer::kBlendModeDisabled);
_targetBuffer->enableBlend(Framebuffer::kBlendModeDisabled);
// First step: Draw the (virtual) game screen.
_pipeline->drawTexture(_gameScreen->getGLTexture(), _gameDrawRect.left, _gameDrawRect.top, _gameDrawRect.width(), _gameDrawRect.height());
@ -710,7 +711,7 @@ void OpenGLGraphicsManager::updateScreen() {
drawCursor = false;
// Everything we need to clip has been clipped
_backBuffer.enableScissorTest(false);
_targetBuffer->enableScissorTest(false);
}
// Overlay must not be scaled and its cursor won't be either
@ -722,7 +723,7 @@ void OpenGLGraphicsManager::updateScreen() {
if (_overlayVisible) {
int dstX = (_windowWidth - _overlayDrawRect.width()) / 2;
int dstY = (_windowHeight - _overlayDrawRect.height()) / 2;
_backBuffer.enableBlend(Framebuffer::kBlendModeTraditionalTransparency);
_targetBuffer->enableBlend(Framebuffer::kBlendModeTraditionalTransparency);
_pipeline->drawTexture(_overlay->getGLTexture(), dstX, dstY, _overlayDrawRect.width(), _overlayDrawRect.height());
}
@ -731,13 +732,13 @@ void OpenGLGraphicsManager::updateScreen() {
renderCursor();
if (!_overlayVisible) {
_backBuffer.enableScissorTest(false);
_targetBuffer->enableScissorTest(false);
}
#ifdef USE_OSD
// Fourth step: Draw the OSD.
if (_osdMessageSurface || _osdIconSurface) {
_backBuffer.enableBlend(Framebuffer::kBlendModeTraditionalTransparency);
_targetBuffer->enableBlend(Framebuffer::kBlendModeTraditionalTransparency);
}
if (_osdMessageSurface) {
@ -1261,7 +1262,7 @@ void OpenGLGraphicsManager::grabPalette(byte *colors, uint start, uint num) cons
void OpenGLGraphicsManager::handleResizeImpl(const int width, const int height) {
// Setup backbuffer size.
_backBuffer.setSize(width, height);
_targetBuffer->setSize(width, height);
uint overlayWidth = width;
uint overlayHeight = height;
@ -1312,8 +1313,13 @@ void OpenGLGraphicsManager::handleResizeImpl(const int width, const int height)
}
void OpenGLGraphicsManager::notifyContextCreate(ContextType type,
Framebuffer *target,
const Graphics::PixelFormat &defaultFormat,
const Graphics::PixelFormat &defaultFormatAlpha) {
// Set up the target: backbuffer usually
delete _targetBuffer;
_targetBuffer = target;
// Initialize pipeline.
delete _pipeline;
_pipeline = nullptr;
@ -1361,9 +1367,9 @@ void OpenGLGraphicsManager::notifyContextCreate(ContextType type,
// Setup backbuffer state.
// Default to opaque black as clear color.
_backBuffer.setClearColor(0.0f, 0.0f, 0.0f, 1.0f);
_targetBuffer->setClearColor(0.0f, 0.0f, 0.0f, 1.0f);
_pipeline->setFramebuffer(&_backBuffer);
_pipeline->setFramebuffer(_targetBuffer);
// 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
@ -1450,6 +1456,10 @@ void OpenGLGraphicsManager::notifyContextDestroy() {
_libretroPipeline = nullptr;
#endif
// Destroy the target
delete _targetBuffer;
_targetBuffer = nullptr;
// Rest our context description since the context is gone soon.
OpenGLContext.reset();
}
@ -1632,7 +1642,7 @@ void OpenGLGraphicsManager::recalculateDisplayAreas() {
// Setup drawing limitation for game graphics.
// This involves some trickery because OpenGL's viewport coordinate system
// is upside down compared to ours.
_backBuffer.setScissorBox(_gameDrawRect.left,
_targetBuffer->setScissorBox(_gameDrawRect.left,
_windowHeight - _gameDrawRect.height() - _gameDrawRect.top,
_gameDrawRect.width(),
_gameDrawRect.height());

View file

@ -149,6 +149,7 @@ protected:
*/
void notifyContextCreate(
ContextType type,
Framebuffer *target,
const Graphics::PixelFormat &defaultFormat,
const Graphics::PixelFormat &defaultFormatAlpha);
@ -339,9 +340,9 @@ protected:
Graphics::PixelFormat _defaultFormatAlpha;
/**
* Render back buffer.
* Render target.
*/
Backbuffer _backBuffer;
Framebuffer *_targetBuffer;
/**
* The rendering surface for the virtual game screen.

View file

@ -547,7 +547,7 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
warning("Unable to %s VSync: %s", _vsync ? "enable" : "disable", SDL_GetError());
}
notifyContextCreate(_glContextType, rgba8888, rgba8888);
notifyContextCreate(_glContextType, new OpenGL::Backbuffer(), rgba8888, rgba8888);
int actualWidth, actualHeight;
getWindowSizeFromSdl(&actualWidth, &actualHeight);
@ -616,7 +616,7 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
_lastVideoModeLoad = SDL_GetTicks();
if (_hwScreen) {
notifyContextCreate(_glContextType, rgba8888, rgba8888);
notifyContextCreate(_glContextType, new OpenGL::Backbuffer(), rgba8888, rgba8888);
handleResize(_hwScreen->w, _hwScreen->h);
}