BACKENDS: OPENGL: Hide active pipeline and activate it as needed

This removes the idea of global pipeline.
The activePipeline is kept for pipeline lifecycle management only.
This commit is contained in:
Le Philousophe 2022-10-31 11:54:14 +01:00
parent 239c115249
commit 6632e909da
10 changed files with 70 additions and 70 deletions

View file

@ -206,7 +206,9 @@ void AndroidGraphicsManager::refreshScreen() {
void AndroidGraphicsManager::touchControlDraw(int16 x, int16 y, int16 w, int16 h, const Common::Rect &clip) {
_backBuffer.enableBlend(OpenGL::Framebuffer::kBlendModeTraditionalTransparency);
OpenGL::Pipeline::getActivePipeline()->drawTexture(_touchcontrols->getGLTexture(),
OpenGL::Pipeline *pipeline = getPipeline();
pipeline->activate();
pipeline->drawTexture(_touchcontrols->getGLTexture(),
x, y, w, h, clip);
}

View file

@ -638,6 +638,8 @@ void OpenGLGraphicsManager::updateScreen() {
}
_overlay->updateGLTexture();
_pipeline->activate();
// Clear the screen buffer.
GL_CALL(glClear(GL_COLOR_BUFFER_BIT));
@ -656,12 +658,15 @@ void OpenGLGraphicsManager::updateScreen() {
// First step: Draw the (virtual) game screen.
#if !USE_FORCED_GLES
if (_libretroPipeline && _libretroPipeline->isInitialized()) {
Framebuffer *lastFramebuffer = Pipeline::getActivePipeline()->setFramebuffer(_gameScreenTarget);
// Use the ShaderPipeline to draw the game screen and game cursor
_pipeline->setFramebuffer(_gameScreenTarget);
_gameScreenTarget->enableBlend(Framebuffer::kBlendModeDisabled);
const GLTexture &gameScreenTexture = _gameScreen->getGLTexture();
const uint retroWidth = gameScreenTexture.getLogicalWidth(),
retroHeight = gameScreenTexture.getLogicalHeight();
Pipeline::getActivePipeline()->drawTexture(gameScreenTexture, 0, 0, retroWidth, retroHeight);
_pipeline->drawTexture(gameScreenTexture, 0, 0, retroWidth, retroHeight);
// Draw the cursor if necessary.
// If overlay is visible we draw it later to have the cursor above overlay
@ -678,18 +683,20 @@ void OpenGLGraphicsManager::updateScreen() {
cursorHeight = cursorTexture.getLogicalHeight();
_gameScreenTarget->enableBlend(Framebuffer::kBlendModePremultipliedTransparency);
Pipeline::getActivePipeline()->drawTexture(cursorTexture, gameScreenCursorX, gameScreenCursorY, cursorWidth, cursorHeight);
_pipeline->drawTexture(cursorTexture, gameScreenCursorX, gameScreenCursorY, cursorWidth, cursorHeight);
needsCursor = false;
}
Pipeline::getActivePipeline()->setFramebuffer(lastFramebuffer);
Pipeline *lastPipeline = Pipeline::setPipeline(_libretroPipeline);
Pipeline::getActivePipeline()->drawTexture(*_gameScreenTarget->getTexture(), _gameDrawRect.left, _gameDrawRect.top, _gameDrawRect.width(), _gameDrawRect.height());
Pipeline::setPipeline(lastPipeline);
_libretroPipeline->activate();
_libretroPipeline->drawTexture(*_gameScreenTarget->getTexture(), _gameDrawRect.left, _gameDrawRect.top, _gameDrawRect.width(), _gameDrawRect.height());
// Restore ShaderPipeline for the next steps
_pipeline->setFramebuffer(&_backBuffer);
_pipeline->activate();
} else
#endif
{
Pipeline::getActivePipeline()->drawTexture(_gameScreen->getGLTexture(), _gameDrawRect.left, _gameDrawRect.top, _gameDrawRect.width(), _gameDrawRect.height());
_pipeline->drawTexture(_gameScreen->getGLTexture(), _gameDrawRect.left, _gameDrawRect.top, _gameDrawRect.width(), _gameDrawRect.height());
}
// Second step: Draw the overlay if visible.
@ -697,14 +704,14 @@ void OpenGLGraphicsManager::updateScreen() {
int dstX = (_windowWidth - _overlayDrawRect.width()) / 2;
int dstY = (_windowHeight - _overlayDrawRect.height()) / 2;
_backBuffer.enableBlend(Framebuffer::kBlendModeTraditionalTransparency);
Pipeline::getActivePipeline()->drawTexture(_overlay->getGLTexture(), dstX, dstY, _overlayDrawRect.width(), _overlayDrawRect.height());
_pipeline->drawTexture(_overlay->getGLTexture(), dstX, dstY, _overlayDrawRect.width(), _overlayDrawRect.height());
}
// Third step: Draw the cursor if necessary.
if (needsCursor) {
_backBuffer.enableBlend(Framebuffer::kBlendModePremultipliedTransparency);
Pipeline::getActivePipeline()->drawTexture(_cursor->getGLTexture(),
_pipeline->drawTexture(_cursor->getGLTexture(),
_cursorX - _cursorHotspotXScaled + _shakeOffsetScaled.x,
_cursorY - _cursorHotspotYScaled + _shakeOffsetScaled.y,
_cursorWidthScaled, _cursorHeightScaled);
@ -734,17 +741,17 @@ void OpenGLGraphicsManager::updateScreen() {
}
// Set the OSD transparency.
Pipeline::getActivePipeline()->setColor(1.0f, 1.0f, 1.0f, _osdMessageAlpha / 100.0f);
_pipeline->setColor(1.0f, 1.0f, 1.0f, _osdMessageAlpha / 100.0f);
int dstX = (_windowWidth - _osdMessageSurface->getWidth()) / 2;
int dstY = (_windowHeight - _osdMessageSurface->getHeight()) / 2;
// Draw the OSD texture.
Pipeline::getActivePipeline()->drawTexture(_osdMessageSurface->getGLTexture(),
_pipeline->drawTexture(_osdMessageSurface->getGLTexture(),
dstX, dstY, _osdMessageSurface->getWidth(), _osdMessageSurface->getHeight());
// Reset color.
Pipeline::getActivePipeline()->setColor(1.0f, 1.0f, 1.0f, 1.0f);
_pipeline->setColor(1.0f, 1.0f, 1.0f, 1.0f);
if (_osdMessageAlpha <= 0) {
delete _osdMessageSurface;
@ -761,7 +768,7 @@ void OpenGLGraphicsManager::updateScreen() {
int dstY = kOSDIconTopMargin;
// Draw the OSD icon texture.
Pipeline::getActivePipeline()->drawTexture(_osdIconSurface->getGLTexture(),
_pipeline->drawTexture(_osdIconSurface->getGLTexture(),
dstX, dstY, _osdIconSurface->getWidth(), _osdIconSurface->getHeight());
}
#endif
@ -1165,7 +1172,6 @@ void OpenGLGraphicsManager::notifyContextCreate(ContextType type,
const Graphics::PixelFormat &defaultFormat,
const Graphics::PixelFormat &defaultFormatAlpha) {
// Initialize pipeline.
Pipeline::setPipeline(nullptr);
delete _pipeline;
_pipeline = nullptr;
@ -1258,10 +1264,6 @@ void OpenGLGraphicsManager::notifyContextCreate(ContextType type,
_osdIconSurface->recreate();
}
#endif
// Everything is ready: activate the pipeline
Pipeline::setPipeline(_pipeline);
}
void OpenGLGraphicsManager::notifyContextDestroy() {
@ -1300,7 +1302,6 @@ void OpenGLGraphicsManager::notifyContextDestroy() {
#endif
// Destroy rendering pipeline.
Pipeline::setPipeline(nullptr);
delete _pipeline;
_pipeline = nullptr;

View file

@ -324,6 +324,8 @@ protected:
void updateLinearFiltering();
Pipeline *getPipeline() const { return _pipeline; }
/**
* The default pixel format of the backend.
*/

View file

@ -32,6 +32,8 @@ CLUT8LookUpPipeline::CLUT8LookUpPipeline()
}
void CLUT8LookUpPipeline::drawTextureInternal(const GLTexture &texture, const GLfloat *coordinates, const GLfloat *texcoords) {
assert(isActive());
// Set the palette texture.
GL_CALL(glActiveTexture(GL_TEXTURE1));
if (_paletteTexture) {

View file

@ -40,13 +40,23 @@ void FixedPipeline::activateInternal() {
}
#endif
GL_CALL(glEnable(GL_TEXTURE_2D));
GL_CALL(glColor4f(_r, _g, _b, _a));
}
void FixedPipeline::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
_r = r;
_g = g;
_b = b;
_a = a;
if (isActive()) {
GL_CALL(glColor4f(r, g, b, a));
}
}
void FixedPipeline::drawTextureInternal(const GLTexture &texture, const GLfloat *coordinates, const GLfloat *texcoords) {
assert(isActive());
texture.bind();
GL_CALL(glTexCoordPointer(2, GL_FLOAT, 0, texcoords));
@ -55,9 +65,7 @@ void FixedPipeline::drawTextureInternal(const GLTexture &texture, const GLfloat
}
void FixedPipeline::setProjectionMatrix(const Math::Matrix4 &projectionMatrix) {
if (!isActive()) {
return;
}
assert(isActive());
GL_CALL(glMatrixMode(GL_PROJECTION));
GL_CALL(glLoadMatrixf(projectionMatrix.getData()));

View file

@ -29,6 +29,8 @@ namespace OpenGL {
#if !USE_FORCED_GLES2
class FixedPipeline : public Pipeline {
public:
FixedPipeline() : _r(0.f), _g(0.f), _b(0.f), _a(0.f) {}
void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) override;
void setProjectionMatrix(const Math::Matrix4 &projectionMatrix) override;
@ -36,6 +38,8 @@ public:
protected:
void activateInternal() override;
void drawTextureInternal(const GLTexture &texture, const GLfloat *coordinates, const GLfloat *texcoords) override;
GLfloat _r, _g, _b, _a;
};
#endif // !USE_FORCED_GLES2

View file

@ -27,11 +27,19 @@ namespace OpenGL {
Pipeline *Pipeline::activePipeline = nullptr;
Pipeline::Pipeline()
: _activeFramebuffer(nullptr), _isActive(false) {
: _activeFramebuffer(nullptr) {
}
void Pipeline::activate() {
_isActive = true;
if (activePipeline == this) {
return;
}
if (activePipeline) {
activePipeline->deactivate();
}
activePipeline = this;
if (_activeFramebuffer) {
_activeFramebuffer->activate(this);
@ -41,41 +49,29 @@ void Pipeline::activate() {
}
void Pipeline::deactivate() {
assert(isActive());
deactivateInternal();
if (_activeFramebuffer) {
_activeFramebuffer->deactivate();
}
_isActive = false;
activePipeline = nullptr;
}
Framebuffer *Pipeline::setFramebuffer(Framebuffer *framebuffer) {
Framebuffer *oldFramebuffer = _activeFramebuffer;
if (_isActive && oldFramebuffer) {
if (isActive() && oldFramebuffer) {
oldFramebuffer->deactivate();
}
_activeFramebuffer = framebuffer;
if (_isActive && _activeFramebuffer) {
if (isActive() && _activeFramebuffer) {
_activeFramebuffer->activate(this);
}
return oldFramebuffer;
}
Pipeline *Pipeline::setPipeline(Pipeline *pipeline) {
Pipeline *oldPipeline = activePipeline;
if (oldPipeline) {
oldPipeline->deactivate();
}
activePipeline = pipeline;
if (activePipeline) {
activePipeline->activate();
}
return oldPipeline;
}
} // End of namespace OpenGL

View file

@ -42,7 +42,7 @@ class Framebuffer;
class Pipeline {
public:
Pipeline();
virtual ~Pipeline() {}
virtual ~Pipeline() { if (isActive()) deactivate(); }
/**
* Activate the pipeline.
@ -150,31 +150,13 @@ protected:
virtual void drawTextureInternal(const GLTexture &texture, const GLfloat *coordinates, const GLfloat *texcoords) = 0;
bool isActive() const { return _isActive; }
bool isActive() const { return activePipeline == this; }
Framebuffer *_activeFramebuffer;
private:
bool _isActive;
/** Currently active rendering pipeline. */
static Pipeline *activePipeline;
public:
/**
* Set new pipeline.
*
* Client is responsible for any memory management related to pipelines.
*
* @param pipeline Pipeline to activate.
* @return Formerly active pipeline.
*/
static Pipeline *setPipeline(Pipeline *pipeline);
/**
* Query the currently active rendering pipeline.
*/
static Pipeline *getActivePipeline() { return activePipeline; }
};
} // End of namespace OpenGL

View file

@ -76,6 +76,8 @@ void ShaderPipeline::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
}
void ShaderPipeline::drawTextureInternal(const GLTexture &texture, const GLfloat *coordinates, const GLfloat *texcoords) {
assert(isActive());
texture.bind();
GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, _coordsVBO));
@ -88,6 +90,8 @@ void ShaderPipeline::drawTextureInternal(const GLTexture &texture, const GLfloat
}
void ShaderPipeline::setProjectionMatrix(const Math::Matrix4 &projectionMatrix) {
assert(isActive());
_activeShader->setUniform("projection", projectionMatrix);
}
#endif // !USE_FORCED_GLES

View file

@ -796,13 +796,12 @@ void TextureCLUT8GPU::updateGLTexture() {
void TextureCLUT8GPU::lookUpColors() {
// Setup pipeline to do color look up.
Pipeline *oldPipeline = Pipeline::setPipeline(_clut8Pipeline);
_clut8Pipeline->activate();
// Do color look up.
Pipeline::getActivePipeline()->drawTexture(_clut8Texture, _clut8Vertices);
_clut8Pipeline->drawTexture(_clut8Texture, _clut8Vertices);
// Restore old state.
Pipeline::setPipeline(oldPipeline);
_clut8Pipeline->deactivate();
}
#endif // !USE_FORCED_GLES