mirror of
https://github.com/overte-org/overte.git
synced 2025-04-15 01:08:48 +02:00
Resolve compositing glitches
This commit is contained in:
parent
95d160a170
commit
28b45ce1d9
7 changed files with 80 additions and 23 deletions
|
@ -2736,7 +2736,36 @@ void Application::initializeGL() {
|
||||||
// We have to account for this possibility by checking here for an existing
|
// We have to account for this possibility by checking here for an existing
|
||||||
// global share context
|
// global share context
|
||||||
auto globalShareContext = qt_gl_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()) {
|
if (!_glWidget->makeCurrent()) {
|
||||||
qCWarning(interfaceapp, "Unable to make window context current");
|
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)) {
|
if ((vendor.find("AMD") != std::string::npos) || (vendor.find("ATI") != std::string::npos)) {
|
||||||
qputenv("QTWEBENGINE_CHROMIUM_FLAGS", QByteArray("--disable-distance-field-text"));
|
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
|
#endif
|
||||||
|
|
||||||
if (!globalShareContext) {
|
if (!globalShareContext) {
|
||||||
|
|
|
@ -179,7 +179,9 @@ public:
|
||||||
_context->makeCurrent();
|
_context->makeCurrent();
|
||||||
{
|
{
|
||||||
PROFILE_RANGE(render, "PluginPresent")
|
PROFILE_RANGE(render, "PluginPresent")
|
||||||
|
gl::globalLock();
|
||||||
currentPlugin->present();
|
currentPlugin->present();
|
||||||
|
gl::globalRelease(false);
|
||||||
CHECK_GL_ERROR();
|
CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
_context->doneCurrent();
|
_context->doneCurrent();
|
||||||
|
|
|
@ -34,6 +34,41 @@ bool gl::disableGl45() {
|
||||||
#endif
|
#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) {
|
void gl::getTargetVersion(int& major, int& minor) {
|
||||||
#if defined(USE_GLES)
|
#if defined(USE_GLES)
|
||||||
major = 3;
|
major = 3;
|
||||||
|
|
|
@ -35,6 +35,9 @@ int glVersionToInteger(QString glVersion);
|
||||||
bool isRenderThread();
|
bool isRenderThread();
|
||||||
|
|
||||||
namespace gl {
|
namespace gl {
|
||||||
|
void globalLock();
|
||||||
|
void globalRelease(bool finish = true);
|
||||||
|
|
||||||
void withSavedContext(const std::function<void()>& f);
|
void withSavedContext(const std::function<void()>& f);
|
||||||
|
|
||||||
bool checkGLError(const char* name);
|
bool checkGLError(const char* name);
|
||||||
|
|
|
@ -33,6 +33,7 @@ OffscreenGLCanvas::OffscreenGLCanvas() :
|
||||||
_context(new QOpenGLContext),
|
_context(new QOpenGLContext),
|
||||||
_offscreenSurface(new QOffscreenSurface)
|
_offscreenSurface(new QOffscreenSurface)
|
||||||
{
|
{
|
||||||
|
setFormat(getDefaultOpenGLSurfaceFormat());
|
||||||
}
|
}
|
||||||
|
|
||||||
OffscreenGLCanvas::~OffscreenGLCanvas() {
|
OffscreenGLCanvas::~OffscreenGLCanvas() {
|
||||||
|
@ -49,12 +50,15 @@ OffscreenGLCanvas::~OffscreenGLCanvas() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OffscreenGLCanvas::setFormat(const QSurfaceFormat& format) {
|
||||||
|
_context->setFormat(format);
|
||||||
|
}
|
||||||
|
|
||||||
bool OffscreenGLCanvas::create(QOpenGLContext* sharedContext) {
|
bool OffscreenGLCanvas::create(QOpenGLContext* sharedContext) {
|
||||||
if (nullptr != sharedContext) {
|
if (nullptr != sharedContext) {
|
||||||
sharedContext->doneCurrent();
|
sharedContext->doneCurrent();
|
||||||
_context->setShareContext(sharedContext);
|
_context->setShareContext(sharedContext);
|
||||||
}
|
}
|
||||||
_context->setFormat(getDefaultOpenGLSurfaceFormat());
|
|
||||||
if (!_context->create()) {
|
if (!_context->create()) {
|
||||||
qFatal("Failed to create OffscreenGLCanvas context");
|
qFatal("Failed to create OffscreenGLCanvas context");
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,13 @@
|
||||||
class QOpenGLContext;
|
class QOpenGLContext;
|
||||||
class QOffscreenSurface;
|
class QOffscreenSurface;
|
||||||
class QOpenGLDebugMessage;
|
class QOpenGLDebugMessage;
|
||||||
|
class QSurfaceFormat;
|
||||||
|
|
||||||
class OffscreenGLCanvas : public QObject {
|
class OffscreenGLCanvas : public QObject {
|
||||||
public:
|
public:
|
||||||
OffscreenGLCanvas();
|
OffscreenGLCanvas();
|
||||||
~OffscreenGLCanvas();
|
~OffscreenGLCanvas();
|
||||||
|
void setFormat(const QSurfaceFormat& format);
|
||||||
bool create(QOpenGLContext* sharedContext = nullptr);
|
bool create(QOpenGLContext* sharedContext = nullptr);
|
||||||
bool makeCurrent();
|
bool makeCurrent();
|
||||||
void doneCurrent();
|
void doneCurrent();
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include <gl/Config.h>
|
#include <gl/Config.h>
|
||||||
#include <gl/QOpenGLContextWrapper.h>
|
#include <gl/QOpenGLContextWrapper.h>
|
||||||
|
#include <gl/GLHelpers.h>
|
||||||
|
|
||||||
#include <QtQuick/QQuickWindow>
|
#include <QtQuick/QQuickWindow>
|
||||||
|
|
||||||
|
@ -114,6 +115,7 @@ void RenderEventHandler::onRender() {
|
||||||
|
|
||||||
PROFILE_RANGE(render_qml_gl, __FUNCTION__);
|
PROFILE_RANGE(render_qml_gl, __FUNCTION__);
|
||||||
|
|
||||||
|
gl::globalLock();
|
||||||
if (!_shared->preRender()) {
|
if (!_shared->preRender()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -144,6 +146,7 @@ void RenderEventHandler::onRender() {
|
||||||
_shared->updateTextureAndFence({ texture, fence });
|
_shared->updateTextureAndFence({ texture, fence });
|
||||||
_shared->_quickWindow->resetOpenGLState();
|
_shared->_quickWindow->resetOpenGLState();
|
||||||
}
|
}
|
||||||
|
gl::globalRelease();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderEventHandler::onQuit() {
|
void RenderEventHandler::onQuit() {
|
||||||
|
|
Loading…
Reference in a new issue