diff --git a/interface/src/ui/ResourceImageItem.cpp b/interface/src/ui/ResourceImageItem.cpp index 6a5f4a431c..9051305a2e 100644 --- a/interface/src/ui/ResourceImageItem.cpp +++ b/interface/src/ui/ResourceImageItem.cpp @@ -10,11 +10,15 @@ #include "Application.h" #include "ResourceImageItem.h" + #include <QOpenGLFramebufferObjectFormat> +#include <QOpenGLFunctions> +#include <QOpenGLExtraFunctions> +#include <QOpenGLContext> + #include <DependencyManager.h> #include <TextureCache.h> - ResourceImageItem::ResourceImageItem(QQuickItem* parent) : QQuickFramebufferObject(parent) { connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(update())); } @@ -55,26 +59,49 @@ void ResourceImageItemRenderer::synchronize(QQuickFramebufferObject* item) { } _window = resourceImageItem->window(); + _window->setClearBeforeRendering(true); if (_ready && !_url.isNull() && !_url.isEmpty() && (urlChanged || readyChanged || !_networkTexture)) { _networkTexture = DependencyManager::get<TextureCache>()->getTexture(_url); } if (_ready && _networkTexture && _networkTexture->isLoaded()) { if(_fboMutex.tryLock()) { - qApp->getActiveDisplayPlugin()->copyTextureToQuickFramebuffer(_networkTexture, framebufferObject()); + qApp->getActiveDisplayPlugin()->copyTextureToQuickFramebuffer(_networkTexture, _copyFbo, &_fenceSync); _fboMutex.unlock(); } } + glFlush(); + } QOpenGLFramebufferObject* ResourceImageItemRenderer::createFramebufferObject(const QSize& size) { QOpenGLFramebufferObjectFormat format; format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); + _copyFbo = new QOpenGLFramebufferObject(size, format); return new QOpenGLFramebufferObject(size, format); } void ResourceImageItemRenderer::render() { + qDebug() << "initial error" << glGetError(); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions(); + QOpenGLExtraFunctions* extras = QOpenGLContext::currentContext()->extraFunctions(); _fboMutex.lock(); - _window->resetOpenGLState(); + if (_fenceSync) { + extras->glWaitSync(_fenceSync, 0, GL_TIMEOUT_IGNORED); + qDebug() << "wait error" << glGetError(); + qDebug() << "waited on fence"; + } + if (_ready) { + QOpenGLFramebufferObject::blitFramebuffer(framebufferObject(), _copyFbo, GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT, GL_NEAREST); + /*f->glBindTexture(GL_TEXTURE_2D, _copyFbo->texture()); + qDebug() << "bind tex error" << f->glGetError() << "texture" << _copyFbo->texture(); + f->glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, _copyFbo->width(), _copyFbo->height());*/ + qDebug() << "copy error" << f->glGetError(); + } else { + framebufferObject()->release(); + } _fboMutex.unlock(); + update(); } diff --git a/interface/src/ui/ResourceImageItem.h b/interface/src/ui/ResourceImageItem.h index bf3c44e205..9b1d685ee1 100644 --- a/interface/src/ui/ResourceImageItem.h +++ b/interface/src/ui/ResourceImageItem.h @@ -27,8 +27,9 @@ private: NetworkTexturePointer _networkTexture; QQuickWindow* _window; - QOpenGLFramebufferObject* _copyFbo; QMutex _fboMutex; + QOpenGLFramebufferObject* _copyFbo; + GLsync _fenceSync { 0 }; }; class ResourceImageItem : public QQuickFramebufferObject { diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 6050211eba..e028fd14c1 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -823,32 +823,37 @@ void OpenGLDisplayPlugin::updateCompositeFramebuffer() { } } -void OpenGLDisplayPlugin::copyTextureToQuickFramebuffer(NetworkTexturePointer networkTexture, QOpenGLFramebufferObject* target) { +void OpenGLDisplayPlugin::copyTextureToQuickFramebuffer(NetworkTexturePointer networkTexture, QOpenGLFramebufferObject* target, GLsync* fenceSync) { auto glBackend = const_cast<OpenGLDisplayPlugin&>(*this).getGLBackend(); withMainThreadContext([&] { GLuint sourceTexture = glBackend->getTextureID(networkTexture->getGPUTexture()); GLuint targetTexture = target->texture(); GLuint fbo[2] {0, 0}; - + qDebug() << "initial" << glGetError(); // need mipmaps for blitting texture glGenerateTextureMipmap(sourceTexture); // create 2 fbos (one for initial texture, second for scaled one) glCreateFramebuffers(2, fbo); + qDebug() << "error" << glGetError(); // setup source fbo glBindFramebuffer(GL_FRAMEBUFFER, fbo[0]); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sourceTexture, 0); + qDebug() << "error" << glGetError(); // setup destination fbo glBindFramebuffer(GL_FRAMEBUFFER, fbo[1]); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, targetTexture, 0); + qDebug() << "error" << glGetError(); glBlitNamedFramebuffer(fbo[0], fbo[1], 0, 0, networkTexture->getWidth(), networkTexture->getHeight(), 0, 0, target->width(), target->height(), GL_COLOR_BUFFER_BIT, GL_NEAREST); + qDebug() << "error" << glGetError(); // don't delete the textures! glDeleteFramebuffers(2, fbo); - glFinish(); + qDebug() << "error" << glGetError(); + *fenceSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); }); } diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index d9e810bf97..dc2e251d65 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -79,7 +79,7 @@ public: // Three threads, one for rendering, one for texture transfers, one reserved for the GL driver int getRequiredThreadCount() const override { return 3; } - void copyTextureToQuickFramebuffer(NetworkTexturePointer source, QOpenGLFramebufferObject* target); + void copyTextureToQuickFramebuffer(NetworkTexturePointer source, QOpenGLFramebufferObject* target, GLsync* fenceSync); protected: friend class PresentThread; diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h index e9b31b5c35..481a2609fc 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.h +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -63,6 +63,7 @@ namespace gpu { class NetworkTexture; using NetworkTexturePointer = QSharedPointer<NetworkTexture>; +typedef struct __GLsync *GLsync; // Stereo display functionality // TODO move out of this file don't derive DisplayPlugin from this. Instead use dynamic casting when @@ -212,7 +213,7 @@ public: // Hardware specific stats virtual QJsonObject getHardwareStats() const { return QJsonObject(); } - virtual void copyTextureToQuickFramebuffer(NetworkTexturePointer source, QOpenGLFramebufferObject* target) = 0; + virtual void copyTextureToQuickFramebuffer(NetworkTexturePointer source, QOpenGLFramebufferObject* target, GLsync* fenceSync) = 0; uint32_t presentCount() const { return _presentedFrameIndex; } // Time since last call to incrementPresentCount (only valid if DEBUG_PAINT_DELAY is defined)