still broken, but added initial cut of GLsync stuff

This commit is contained in:
David Kelly 2017-06-20 15:02:05 -07:00
parent b4c75c3f87
commit 06b59fe13e
5 changed files with 43 additions and 9 deletions

View file

@ -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();
}

View file

@ -27,8 +27,9 @@ private:
NetworkTexturePointer _networkTexture;
QQuickWindow* _window;
QOpenGLFramebufferObject* _copyFbo;
QMutex _fboMutex;
QOpenGLFramebufferObject* _copyFbo;
GLsync _fenceSync { 0 };
};
class ResourceImageItem : public QQuickFramebufferObject {

View file

@ -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);
});
}

View file

@ -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;

View file

@ -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)