Unify begin/end frame hooks in OpenGLBackend

This commit is contained in:
Vlad Zahorodnii 2020-11-09 16:23:41 +02:00
parent 81abc341d7
commit 76303888ab
19 changed files with 33 additions and 101 deletions

View file

@ -50,28 +50,12 @@ public:
virtual void screenGeometryChanged(const QSize &size) = 0;
virtual SceneOpenGLTexturePrivate *createBackendTexture(SceneOpenGLTexture *texture) = 0;
/**
* @brief Backend specific code to prepare the rendering of a frame including flushing the
* previously rendered frame to the screen if the backend works this way.
*
* @return A region that if not empty will be repainted in addition to the damaged region
*/
virtual QRegion prepareRenderingFrame() = 0;
/**
* Notifies about starting to paint.
*
* @p damage contains the reported damage as suggested by windows and effects on prepaint calls.
*/
virtual void aboutToStartPainting(int screenId, const QRegion &damage);
/**
* @brief Backend specific code to handle the end of rendering a frame.
*
* @param renderedRegion The possibly larger region that has been rendered
* @param damagedRegion The damaged region that should be posted
*/
virtual void endRenderingFrame(const QRegion &damage, const QRegion &damagedRegion) = 0;
virtual void endRenderingFrameForScreen(int screenId, const QRegion &damage, const QRegion &damagedRegion);
virtual bool makeCurrent() = 0;
virtual void doneCurrent() = 0;

View file

@ -511,11 +511,6 @@ SceneOpenGLTexturePrivate *EglGbmBackend::createBackendTexture(SceneOpenGLTextur
return new EglGbmTexture(texture, this);
}
QRegion EglGbmBackend::prepareRenderingFrame()
{
return QRegion();
}
void EglGbmBackend::setViewport(const Output &output) const
{
const QSize &overall = screens()->size();
@ -550,12 +545,6 @@ QRegion EglGbmBackend::prepareRenderingForScreen(int screenId)
return output.output->geometry();
}
void EglGbmBackend::endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
{
Q_UNUSED(renderedRegion)
Q_UNUSED(damagedRegion)
}
void EglGbmBackend::endRenderingFrameForScreen(int screenId,
const QRegion &renderedRegion,
const QRegion &damagedRegion)

View file

@ -35,8 +35,6 @@ public:
~EglGbmBackend() override;
void screenGeometryChanged(const QSize &size) override;
SceneOpenGLTexturePrivate *createBackendTexture(SceneOpenGLTexture *texture) override;
QRegion prepareRenderingFrame() override;
void endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
void endRenderingFrameForScreen(int screenId, const QRegion &damage, const QRegion &damagedRegion) override;
bool usesOverlayWindow() const override;
bool perScreenRendering() const override;

View file

@ -475,11 +475,6 @@ SceneOpenGLTexturePrivate *EglStreamBackend::createBackendTexture(SceneOpenGLTex
return new EglStreamTexture(texture, this);
}
QRegion EglStreamBackend::prepareRenderingFrame()
{
return QRegion();
}
QRegion EglStreamBackend::prepareRenderingForScreen(int screenId)
{
const Output &o = m_outputs.at(screenId);
@ -487,12 +482,6 @@ QRegion EglStreamBackend::prepareRenderingForScreen(int screenId)
return o.output->geometry();
}
void EglStreamBackend::endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
{
Q_UNUSED(renderedRegion)
Q_UNUSED(damagedRegion)
}
void EglStreamBackend::endRenderingFrameForScreen(int screenId, const QRegion &renderedRegion, const QRegion &damagedRegion)
{
Q_UNUSED(renderedRegion);

View file

@ -32,8 +32,6 @@ public:
~EglStreamBackend() override;
void screenGeometryChanged(const QSize &size) override;
SceneOpenGLTexturePrivate *createBackendTexture(SceneOpenGLTexture *texture) override;
QRegion prepareRenderingFrame() override;
void endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
void endRenderingFrameForScreen(int screenId, const QRegion &damage, const QRegion &damagedRegion) override;
bool usesOverlayWindow() const override;
bool perScreenRendering() const override;

View file

@ -140,8 +140,9 @@ void EglHwcomposerBackend::screenGeometryChanged(const QSize &size)
Q_UNUSED(size)
}
QRegion EglHwcomposerBackend::prepareRenderingFrame()
QRegion EglHwcomposerBackend::prepareRenderingFrame(int screenId)
{
Q_UNUSED(screenId)
present();
// TODO: buffer age?
@ -149,8 +150,9 @@ QRegion EglHwcomposerBackend::prepareRenderingFrame()
return QRegion(QRect(QPoint(0, 0), m_backend->size()));
}
void EglHwcomposerBackend::endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
void EglHwcomposerBackend::endRenderingFrame(int screenId, const QRegion &renderedRegion, const QRegion &damagedRegion)
{
Q_UNUSED(screenId)
Q_UNUSED(damagedRegion)
setLastDamage(renderedRegion);
}

View file

@ -24,8 +24,8 @@ public:
bool usesOverlayWindow() const override;
SceneOpenGLTexturePrivate *createBackendTexture(SceneOpenGLTexture *texture) override;
void screenGeometryChanged(const QSize &size) override;
QRegion prepareRenderingFrame() override;
void endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
QRegion prepareRenderingFrame(int screenId) override;
void endRenderingFrame(int screenId, const QRegion &renderedRegion, const QRegion &damagedRegion) override;
void init() override;
protected:

View file

@ -162,8 +162,9 @@ SceneOpenGLTexturePrivate *EglGbmBackend::createBackendTexture(SceneOpenGLTextur
return new EglGbmTexture(texture, this);
}
QRegion EglGbmBackend::prepareRenderingFrame()
QRegion EglGbmBackend::prepareRenderingForScreen(int screenId)
{
Q_UNUSED(screenId)
if (!lastDamage().isEmpty()) {
present();
}
@ -204,8 +205,9 @@ static void convertFromGLImage(QImage &img, int w, int h)
img = img.mirrored();
}
void EglGbmBackend::endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
void EglGbmBackend::endRenderingFrameForScreen(int screenId, const QRegion &renderedRegion, const QRegion &damagedRegion)
{
Q_UNUSED(screenId)
Q_UNUSED(damagedRegion)
glFlush();
if (m_backend->saveFrames()) {

View file

@ -26,8 +26,8 @@ public:
~EglGbmBackend() override;
void screenGeometryChanged(const QSize &size) override;
SceneOpenGLTexturePrivate *createBackendTexture(SceneOpenGLTexture *texture) override;
QRegion prepareRenderingFrame() override;
void endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
QRegion prepareRenderingForScreen(int screenId) override;
void endRenderingFrameForScreen(int screenId, const QRegion &renderedRegion, const QRegion &damagedRegion) override;
bool usesOverlayWindow() const override;
void init() override;

View file

@ -325,10 +325,7 @@ void EglWaylandBackend::aboutToStartPainting(int screenId, const QRegion &damage
void EglWaylandBackend::presentOnSurface(EglWaylandOutput *output, const QRegion &damage)
{
output->m_waylandOutput->surface()->setupFrameCallback();
if (!m_swapping) {
m_swapping = true;
Compositor::self()->aboutToSwapBuffers();
}
Compositor::self()->aboutToSwapBuffers();
Q_EMIT output->m_waylandOutput->outputChange(damage);
@ -363,15 +360,10 @@ SceneOpenGLTexturePrivate *EglWaylandBackend::createBackendTexture(SceneOpenGLTe
return new EglWaylandTexture(texture, this);
}
QRegion EglWaylandBackend::prepareRenderingFrame()
{
eglWaitNative(EGL_CORE_NATIVE_ENGINE);
m_swapping = false;
return QRegion();
}
QRegion EglWaylandBackend::prepareRenderingForScreen(int screenId)
{
eglWaitNative(EGL_CORE_NATIVE_ENGINE);
auto *output = m_outputs.at(screenId);
makeContextCurrent(output);
if (supportsBufferAge()) {
@ -390,12 +382,6 @@ QRegion EglWaylandBackend::prepareRenderingForScreen(int screenId)
return QRegion();
}
void EglWaylandBackend::endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
{
Q_UNUSED(renderedRegion)
Q_UNUSED(damagedRegion)
}
void EglWaylandBackend::endRenderingFrameForScreen(int screenId, const QRegion &renderedRegion, const QRegion &damagedRegion)
{
EglWaylandOutput *output = m_outputs[screenId];

View file

@ -70,9 +70,7 @@ public:
~EglWaylandBackend() override;
void screenGeometryChanged(const QSize &size) override;
SceneOpenGLTexturePrivate *createBackendTexture(SceneOpenGLTexture *texture) override;
QRegion prepareRenderingFrame() override;
QRegion prepareRenderingForScreen(int screenId) override;
void endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
void endRenderingFrameForScreen(int screenId, const QRegion &damage, const QRegion &damagedRegion) override;
bool usesOverlayWindow() const override;
bool perScreenRendering() const override;
@ -101,7 +99,6 @@ private:
WaylandBackend *m_backend;
QVector<EglWaylandOutput*> m_outputs;
bool m_havePlatformBase;
bool m_swapping = false;
friend class EglWaylandTexture;
};

View file

@ -175,9 +175,7 @@ void WaylandQPainterBackend::present(int screenId, int mask, const QRegion &dama
WaylandQPainterOutput *rendererOutput = m_outputs.value(screenId);
Q_ASSERT(rendererOutput);
if (screenId == 0) {
Compositor::self()->aboutToSwapBuffers();
}
Compositor::self()->aboutToSwapBuffers();
rendererOutput->setNeedsFullRepaint(false);
rendererOutput->present(rendererOutput->mapToLocal(damage));

View file

@ -384,8 +384,9 @@ SceneOpenGLTexturePrivate *EglOnXBackend::createBackendTexture(SceneOpenGLTextur
return new EglTexture(texture, this);
}
QRegion EglOnXBackend::prepareRenderingFrame()
QRegion EglOnXBackend::prepareRenderingForScreen(int screenId)
{
Q_UNUSED(screenId)
QRegion repaint;
if (gs_tripleBufferNeedsDetection) {
@ -407,8 +408,10 @@ QRegion EglOnXBackend::prepareRenderingFrame()
return repaint;
}
void EglOnXBackend::endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
void EglOnXBackend::endRenderingFrameForScreen(int screenId, const QRegion &renderedRegion, const QRegion &damagedRegion)
{
Q_UNUSED(screenId)
if (damagedRegion.isEmpty()) {
setLastDamage(QRegion());

View file

@ -27,8 +27,8 @@ public:
~EglOnXBackend() override;
void screenGeometryChanged(const QSize &size) override;
SceneOpenGLTexturePrivate *createBackendTexture(SceneOpenGLTexture *texture) override;
QRegion prepareRenderingFrame() override;
void endRenderingFrame(const QRegion &damage, const QRegion &damagedRegion) override;
QRegion prepareRenderingForScreen(int screenId) override;
void endRenderingFrameForScreen(int screenId, const QRegion &damage, const QRegion &damagedRegion) override;
OverlayWindow* overlayWindow() const override;
bool usesOverlayWindow() const override;
void init() override;

View file

@ -781,8 +781,9 @@ SceneOpenGLTexturePrivate *GlxBackend::createBackendTexture(SceneOpenGLTexture *
return new GlxTexture(texture, this);
}
QRegion GlxBackend::prepareRenderingFrame()
QRegion GlxBackend::prepareRenderingForScreen(int screenId)
{
Q_UNUSED(screenId)
QRegion repaint;
if (gs_tripleBufferNeedsDetection) {
@ -794,6 +795,7 @@ QRegion GlxBackend::prepareRenderingFrame()
usleep(1000);
}
makeCurrent();
present();
if (supportsBufferAge())
@ -804,8 +806,10 @@ QRegion GlxBackend::prepareRenderingFrame()
return repaint;
}
void GlxBackend::endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
void GlxBackend::endRenderingFrameForScreen(int screenId, const QRegion &renderedRegion, const QRegion &damagedRegion)
{
Q_UNUSED(screenId)
if (damagedRegion.isEmpty()) {
setLastDamage(QRegion());

View file

@ -61,8 +61,8 @@ public:
~GlxBackend() override;
void screenGeometryChanged(const QSize &size) override;
SceneOpenGLTexturePrivate *createBackendTexture(SceneOpenGLTexture *texture) override;
QRegion prepareRenderingFrame() override;
void endRenderingFrame(const QRegion &damage, const QRegion &damagedRegion) override;
QRegion prepareRenderingForScreen(int screenId) override;
void endRenderingFrameForScreen(int screenId, const QRegion &damage, const QRegion &damagedRegion) override;
bool makeCurrent() override;
void doneCurrent() override;
OverlayWindow* overlayWindow() const override;

View file

@ -60,17 +60,6 @@ void EglX11Backend::present()
xcb_flush(m_backend->connection());
}
QRegion EglX11Backend::prepareRenderingFrame()
{
return QRegion();
}
void EglX11Backend::endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
{
Q_UNUSED(renderedRegion)
Q_UNUSED(damagedRegion)
}
bool EglX11Backend::usesOverlayWindow() const
{
return false;

View file

@ -23,8 +23,6 @@ class EglX11Backend : public EglOnXBackend
public:
explicit EglX11Backend(X11WindowedBackend *backend);
~EglX11Backend() override;
QRegion prepareRenderingFrame() override;
void endRenderingFrame(const QRegion &damage, const QRegion &damagedRegion) override;
bool usesOverlayWindow() const override;
bool perScreenRendering() const override;
QRegion prepareRenderingForScreen(int screenId) override;

View file

@ -639,12 +639,11 @@ void SceneOpenGL::paint(int screenId, const QRegion &damage, const QList<Topleve
qreal scaling;
// prepare rendering makes context current on the output
repaint = m_backend->prepareRenderingForScreen(screenId);
if (screenId != -1) {
repaint = m_backend->prepareRenderingForScreen(screenId);
geo = screens()->geometry(screenId);
scaling = screens()->scale(screenId);
} else {
repaint = m_backend->prepareRenderingFrame();
geo = screens()->geometry();
scaling = 1;
}
@ -680,11 +679,7 @@ void SceneOpenGL::paint(int screenId, const QRegion &damage, const QList<Topleve
}
GLVertexBuffer::streamingBuffer()->endOfFrame();
if (screenId != -1) {
m_backend->endRenderingFrameForScreen(screenId, valid, update);
} else {
m_backend->endRenderingFrame(valid, update);
}
m_backend->endRenderingFrameForScreen(screenId, valid, update);
GLVertexBuffer::streamingBuffer()->framePosted();
if (m_currentFence) {