Resolve compositing glitches

This commit is contained in:
Bradley Austin Davis 2018-10-01 15:13:11 -07:00 committed by Brad Davis
parent 95d160a170
commit 28b45ce1d9
7 changed files with 80 additions and 23 deletions

View file

@ -2736,7 +2736,36 @@ void Application::initializeGL() {
// We have to account for this possibility by checking here for an existing
// global share context
auto globalShareContext = qt_gl_global_share_context();
_glWidget->createContext(globalShareContext);
#if !defined(DISABLE_QML)
// Build a shared canvas / context for the Chromium processes
if (!globalShareContext) {
// Chromium rendering uses some GL functions that prevent nSight from capturing
// frames, so we only create the shared context if nsight is NOT active.
if (!nsightActive()) {
_chromiumShareContext = new OffscreenGLCanvas();
_chromiumShareContext->setObjectName("ChromiumShareContext");
auto format =QSurfaceFormat::defaultFormat();
#ifdef Q_OS_MAC
// On mac, the primary shared OpenGL context must be a 3.2 core context,
// or chromium flips out and spews error spam (but renders fine)
format.setMajorVersion(3);
format.setMinorVersion(2);
#endif
_chromiumShareContext->setFormat(format);
_chromiumShareContext->create();
if (!_chromiumShareContext->makeCurrent()) {
qCWarning(interfaceapp, "Unable to make chromium shared context current");
}
globalShareContext = _chromiumShareContext->getContext();
qt_gl_set_global_share_context(globalShareContext);
_chromiumShareContext->doneCurrent();
}
}
#endif
_glWidget->createContext(globalShareContext);
if (!_glWidget->makeCurrent()) {
qCWarning(interfaceapp, "Unable to make window context current");
@ -2749,27 +2778,6 @@ void Application::initializeGL() {
if ((vendor.find("AMD") != std::string::npos) || (vendor.find("ATI") != std::string::npos)) {
qputenv("QTWEBENGINE_CHROMIUM_FLAGS", QByteArray("--disable-distance-field-text"));
}
// Build a shared canvas / context for the Chromium processes
if (!globalShareContext) {
// Chromium rendering uses some GL functions that prevent nSight from capturing
// frames, so we only create the shared context if nsight is NOT active.
if (!nsightActive()) {
_chromiumShareContext = new OffscreenGLCanvas();
_chromiumShareContext->setObjectName("ChromiumShareContext");
_chromiumShareContext->create(_glWidget->qglContext());
if (!_chromiumShareContext->makeCurrent()) {
qCWarning(interfaceapp, "Unable to make chromium shared context current");
}
globalShareContext = _chromiumShareContext->getContext();
qt_gl_set_global_share_context(globalShareContext);
_chromiumShareContext->doneCurrent();
// Restore the GL widget context
if (!_glWidget->makeCurrent()) {
qCWarning(interfaceapp, "Unable to make window context current");
}
}
}
#endif
if (!globalShareContext) {

View file

@ -179,7 +179,9 @@ public:
_context->makeCurrent();
{
PROFILE_RANGE(render, "PluginPresent")
gl::globalLock();
currentPlugin->present();
gl::globalRelease(false);
CHECK_GL_ERROR();
}
_context->doneCurrent();

View file

@ -34,6 +34,41 @@ bool gl::disableGl45() {
#endif
}
#ifdef Q_OS_MAC
#define SERIALIZE_GL_RENDERING
#endif
#ifdef SERIALIZE_GL_RENDERING
// This terrible terrible hack brought to you by the complete lack of reasonable
// OpenGL debugging tools on OSX. Without this serialization code, the UI textures
// frequently become 'glitchy' and get composited onto the main scene in what looks
// like a partially rendered state.
// This looks very much like either state bleeding across the contexts, or bad
// synchronization for the shared OpenGL textures. However, previous attempts to resolve
// it, even with gratuitous use of glFinish hasn't improved the situation
static std::mutex _globalOpenGLLock;
void gl::globalLock() {
_globalOpenGLLock.lock();
}
void gl::globalRelease(bool finish) {
if (finish) {
glFinish();
}
_globalOpenGLLock.unlock();
}
#else
void gl::globalLock() {}
void gl::globalRelease(bool finish) {}
#endif
void gl::getTargetVersion(int& major, int& minor) {
#if defined(USE_GLES)
major = 3;

View file

@ -35,6 +35,9 @@ int glVersionToInteger(QString glVersion);
bool isRenderThread();
namespace gl {
void globalLock();
void globalRelease(bool finish = true);
void withSavedContext(const std::function<void()>& f);
bool checkGLError(const char* name);

View file

@ -33,6 +33,7 @@ OffscreenGLCanvas::OffscreenGLCanvas() :
_context(new QOpenGLContext),
_offscreenSurface(new QOffscreenSurface)
{
setFormat(getDefaultOpenGLSurfaceFormat());
}
OffscreenGLCanvas::~OffscreenGLCanvas() {
@ -49,12 +50,15 @@ OffscreenGLCanvas::~OffscreenGLCanvas() {
}
void OffscreenGLCanvas::setFormat(const QSurfaceFormat& format) {
_context->setFormat(format);
}
bool OffscreenGLCanvas::create(QOpenGLContext* sharedContext) {
if (nullptr != sharedContext) {
sharedContext->doneCurrent();
_context->setShareContext(sharedContext);
}
_context->setFormat(getDefaultOpenGLSurfaceFormat());
if (!_context->create()) {
qFatal("Failed to create OffscreenGLCanvas context");
}

View file

@ -18,11 +18,13 @@
class QOpenGLContext;
class QOffscreenSurface;
class QOpenGLDebugMessage;
class QSurfaceFormat;
class OffscreenGLCanvas : public QObject {
public:
OffscreenGLCanvas();
~OffscreenGLCanvas();
void setFormat(const QSurfaceFormat& format);
bool create(QOpenGLContext* sharedContext = nullptr);
bool makeCurrent();
void doneCurrent();

View file

@ -12,6 +12,7 @@
#include <gl/Config.h>
#include <gl/QOpenGLContextWrapper.h>
#include <gl/GLHelpers.h>
#include <QtQuick/QQuickWindow>
@ -114,6 +115,7 @@ void RenderEventHandler::onRender() {
PROFILE_RANGE(render_qml_gl, __FUNCTION__);
gl::globalLock();
if (!_shared->preRender()) {
return;
}
@ -144,6 +146,7 @@ void RenderEventHandler::onRender() {
_shared->updateTextureAndFence({ texture, fence });
_shared->_quickWindow->resetOpenGLState();
}
gl::globalRelease();
}
void RenderEventHandler::onQuit() {