From 01af8899bf40348b40076938c1ba9b68eaf12d55 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Mon, 29 Aug 2016 10:47:22 -0700 Subject: [PATCH 1/5] silence address bar dialog qml warning --- interface/src/ui/AddressBarDialog.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/ui/AddressBarDialog.h b/interface/src/ui/AddressBarDialog.h index 3197770433..2dad742ebb 100644 --- a/interface/src/ui/AddressBarDialog.h +++ b/interface/src/ui/AddressBarDialog.h @@ -22,7 +22,7 @@ class AddressBarDialog : public OffscreenQmlDialog { Q_PROPERTY(bool backEnabled READ backEnabled NOTIFY backEnabledChanged) Q_PROPERTY(bool forwardEnabled READ forwardEnabled NOTIFY forwardEnabledChanged) Q_PROPERTY(bool useFeed READ useFeed WRITE setUseFeed NOTIFY useFeedChanged) - Q_PROPERTY(QString metaverseServerUrl READ metaverseServerUrl) + Q_PROPERTY(QString metaverseServerUrl READ metaverseServerUrl NOTIFY metaverseServerUrlChanged) public: AddressBarDialog(QQuickItem* parent = nullptr); @@ -37,6 +37,7 @@ signals: void forwardEnabledChanged(); void useFeedChanged(); void receivedHifiSchemeURL(const QString& url); + void metaverseServerUrlChanged(); // While it is a constant, qml will complain about not seeing a change signal. protected: void displayAddressOfflineMessage(); From 5f699072d9c101874a0de1526be617d2d06e6ad0 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Mon, 29 Aug 2016 10:58:09 -0700 Subject: [PATCH 2/5] allow black skybox --- libraries/model/src/model/Skybox.cpp | 3 +++ libraries/model/src/model/Skybox.h | 10 +++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index 4a66c18f98..bfbc883978 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -26,10 +26,12 @@ Skybox::Skybox() { } void Skybox::setColor(const Color& color) { + _empty = false; _schemaBuffer.edit().color = color; } void Skybox::setCubemap(const gpu::TexturePointer& cubemap) { + _empty = false; _cubemap = cubemap; } @@ -50,6 +52,7 @@ void Skybox::updateSchemaBuffer() const { } void Skybox::clear() { + _empty = true; _schemaBuffer.edit().color = vec3(0); setCubemap(nullptr); } diff --git a/libraries/model/src/model/Skybox.h b/libraries/model/src/model/Skybox.h index 1e6d30bbc1..d7d95fbe9e 100755 --- a/libraries/model/src/model/Skybox.h +++ b/libraries/model/src/model/Skybox.h @@ -35,7 +35,7 @@ public: void setCubemap(const gpu::TexturePointer& cubemap); const gpu::TexturePointer& getCubemap() const { return _cubemap; } - virtual bool empty() { return _schemaBuffer.get().color == vec3(0) && !_cubemap; } + virtual bool empty() { return _empty; } virtual void clear(); void prepare(gpu::Batch& batch, int textureSlot = SKYBOX_SKYMAP_SLOT, int bufferSlot = SKYBOX_CONSTANTS_SLOT) const; @@ -47,17 +47,17 @@ protected: static const int SKYBOX_SKYMAP_SLOT { 0 }; static const int SKYBOX_CONSTANTS_SLOT { 0 }; - gpu::TexturePointer _cubemap; - class Schema { public: glm::vec3 color { 0.0f, 0.0f, 0.0f }; float blend { 0.0f }; }; - mutable gpu::BufferView _schemaBuffer; - void updateSchemaBuffer() const; + + mutable gpu::BufferView _schemaBuffer; + gpu::TexturePointer _cubemap; + bool _empty{ true }; }; typedef std::shared_ptr SkyboxPointer; From 617633b85cf05f56c2ef801d4324d48cd63e3a09 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 22 Aug 2016 11:50:32 -0700 Subject: [PATCH 3/5] Moving to custom context creation --- interface/src/Application.cpp | 12 +- .../display-plugins/OpenGLDisplayPlugin.cpp | 10 +- libraries/gl/src/gl/Context.cpp | 279 ++++++++++++++++++ libraries/gl/src/gl/Context.h | 72 +++++ libraries/gl/src/gl/ContextQt.cpp | 75 +++++ libraries/gl/src/gl/GLHelpers.cpp | 54 +--- libraries/gl/src/gl/GLHelpers.h | 10 - libraries/gl/src/gl/GLWidget.cpp | 90 ++++-- libraries/gl/src/gl/GLWidget.h | 26 +- libraries/gl/src/gl/OffscreenGLCanvas.cpp | 1 - libraries/gl/src/gl/OpenGLVersionChecker.cpp | 42 ++- libraries/gpu-gl/src/gpu/gl/GLTexture.cpp | 8 +- libraries/gpu-gl/src/gpu/gl/GLTexture.h | 1 - .../gpu-gl/src/gpu/gl/GLTextureTransfer.cpp | 54 ++-- .../gpu-gl/src/gpu/gl/GLTextureTransfer.h | 6 +- libraries/gpu-gl/src/gpu/gl41/GL41Backend.h | 22 +- .../gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp | 5 +- .../gpu-gl/src/gpu/gl41/GL41BackendQuery.cpp | 9 +- .../src/gpu/gl41/GL41BackendTexture.cpp | 15 +- .../src/gpu/gl41/GL41BackendTransform.cpp | 4 +- libraries/gpu-gl/src/gpu/gl45/GL45Backend.h | 22 +- .../gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp | 63 ++-- .../src/gpu/gl45/GL45BackendTexture.cpp | 19 +- libraries/ui/src/MainWindow.cpp | 1 + plugins/openvr/src/OpenVrDisplayPlugin.cpp | 16 +- plugins/openvr/src/OpenVrDisplayPlugin.h | 5 +- tests/gpu-test/src/TestWindow.cpp | 1 - tests/render-perf/src/Camera.hpp | 3 + tests/render-perf/src/main.cpp | 170 +++++++---- tests/render-utils/src/main.cpp | 2 - tests/shaders/src/main.cpp | 2 - 31 files changed, 803 insertions(+), 296 deletions(-) create mode 100644 libraries/gl/src/gl/Context.cpp create mode 100644 libraries/gl/src/gl/Context.h create mode 100644 libraries/gl/src/gl/ContextQt.cpp diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index aaf38e826b..7b0c2a31c1 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -778,8 +778,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : // enable mouse tracking; otherwise, we only get drag events _glWidget->setMouseTracking(true); + // Make sure the window is set to the correct size by processing the pending events + QCoreApplication::processEvents(); + _glWidget->createContext(); _glWidget->makeCurrent(); - _glWidget->initializeGL(); initializeGL(); // Make sure we don't time out during slow operations at startup @@ -1484,7 +1486,7 @@ void Application::initializeGL() { _glWidget->makeCurrent(); _chromiumShareContext = new OffscreenGLCanvas(); _chromiumShareContext->setObjectName("ChromiumShareContext"); - _chromiumShareContext->create(_glWidget->context()->contextHandle()); + _chromiumShareContext->create(_glWidget->qglContext()); _chromiumShareContext->makeCurrent(); qt_gl_set_global_share_context(_chromiumShareContext->getContext()); @@ -1531,7 +1533,7 @@ void Application::initializeGL() { _offscreenContext = new OffscreenGLCanvas(); _offscreenContext->setObjectName("MainThreadContext"); - _offscreenContext->create(_glWidget->context()->contextHandle()); + _offscreenContext->create(_glWidget->qglContext()); _offscreenContext->makeCurrent(); // update before the first render @@ -1553,7 +1555,7 @@ void Application::initializeUi() { auto offscreenUi = DependencyManager::get(); - offscreenUi->create(_glWidget->context()->contextHandle()); + offscreenUi->create(_glWidget->qglContext()); auto rootContext = offscreenUi->getRootContext(); @@ -5675,7 +5677,7 @@ MainWindow* Application::getPrimaryWindow() { } QOpenGLContext* Application::getPrimaryContext() { - return _glWidget->context()->contextHandle(); + return _glWidget->qglContext(); } bool Application::makeRenderingContextCurrent() { diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index b304b3802e..5ee097d355 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -108,7 +109,7 @@ public: } } - void setContext(QGLContext * context) { + void setContext(gl::Context* context) { // Move the OpenGL context to the present thread // Extra code because of the widget 'wrapper' context _context = context; @@ -126,7 +127,6 @@ public: OpenGLDisplayPlugin* currentPlugin{ nullptr }; Q_ASSERT(_context); _context->makeCurrent(); - Q_ASSERT(isCurrentContext(_context->contextHandle())); while (!_shutdown) { if (_pendingMainThreadOperation) { PROFILE_RANGE("MainThreadOp") @@ -250,7 +250,7 @@ private: bool _finishedMainThreadOperation { false }; QThread* _mainThread { nullptr }; std::queue _newPluginQueue; - QGLContext* _context { nullptr }; + gl::Context* _context { nullptr }; }; bool OpenGLDisplayPlugin::activate() { @@ -649,8 +649,8 @@ float OpenGLDisplayPlugin::presentRate() const { } void OpenGLDisplayPlugin::swapBuffers() { - static auto widget = _container->getPrimaryWidget(); - widget->swapBuffers(); + static auto context = _container->getPrimaryWidget()->context(); + context->swapBuffers(); } void OpenGLDisplayPlugin::withMainThreadContext(std::function f) const { diff --git a/libraries/gl/src/gl/Context.cpp b/libraries/gl/src/gl/Context.cpp new file mode 100644 index 0000000000..f8712872ee --- /dev/null +++ b/libraries/gl/src/gl/Context.cpp @@ -0,0 +1,279 @@ +// +// Created by Bradley Austin Davis on 2016/08/21 +// Copyright 2013-2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "Context.h" + +#include + +#include + +#include +#include +#include + +#include +#include + +#include + +#ifdef Q_OS_WIN + +#ifdef DEBUG +static bool enableDebugLogger = true; +#else +static const QString DEBUG_FLAG("HIFI_DEBUG_OPENGL"); +static bool enableDebugLogger = QProcessEnvironment::systemEnvironment().contains(DEBUG_FLAG); +#endif + +#endif + +#include "Config.h" +#include "GLHelpers.h" + + +using namespace gl; + +Context* Context::PRIMARY = nullptr; + +Context::Context() {} + +Context::Context(QWindow* window) { + setWindow(window); +} + +#ifdef Q_OS_WIN +void Context::destroyWin32Context(HGLRC hglrc) { + wglDeleteContext(hglrc); +} +#endif + +void Context::release() { + doneCurrent(); +#ifdef Q_OS_WIN + if (_wrappedContext) { + destroyContext(_wrappedContext); + _wrappedContext = nullptr; + } + if (_hglrc) { + destroyWin32Context(_hglrc); + _hglrc = 0; + } + if (_hdc) { + ReleaseDC(_hwnd, _hdc); + _hdc = 0; + } + _hwnd = 0; +#else + destroyContext(_context); + _context = nullptr; +#endif + _window = nullptr; + if (PRIMARY == this) { + PRIMARY = nullptr; + } + } + +Context::~Context() { + release(); +} + +void Context::setWindow(QWindow* window) { + release(); + _window = window; +#ifdef Q_OS_WIN + _hwnd = (HWND)window->winId(); +#endif +} + +#ifdef Q_OS_WIN +static const char* PRIMARY_CONTEXT_PROPERTY_NAME = "com.highfidelity.gl.primaryContext"; + +bool Context::makeCurrent() { + BOOL result = wglMakeCurrent(_hdc, _hglrc); + assert(result); + return result; +} + +void Context::swapBuffers() { + SwapBuffers(_hdc); +} + +void Context::doneCurrent() { + wglMakeCurrent(0, 0); +} + +void GLAPIENTRY debugMessageCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam) { + if (GL_DEBUG_SEVERITY_NOTIFICATION == severity) { + return; + } + qDebug() << "QQQ " << message; +} + +// FIXME build the PFD based on the +static const PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be +{ + sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor + 1, // Version Number + PFD_DRAW_TO_WINDOW | // Format Must Support Window + PFD_SUPPORT_OPENGL | // Format Must Support OpenGL + PFD_DOUBLEBUFFER, // Must Support Double Buffering + PFD_TYPE_RGBA, // Request An RGBA Format + 24, // Select Our Color Depth + 0, 0, 0, 0, 0, 0, // Color Bits Ignored + 1, // Alpha Buffer + 0, // Shift Bit Ignored + 0, // No Accumulation Buffer + 0, 0, 0, 0, // Accumulation Bits Ignored + 24, // 24 Bit Z-Buffer (Depth Buffer) + 8, // 8 Bit Stencil Buffer + 0, // No Auxiliary Buffer + PFD_MAIN_PLANE, // Main Drawing Layer + 0, // Reserved + 0, 0, 0 // Layer Masks Ignored +}; + +void setupPixelFormatSimple(HDC hdc) { + auto pixelFormat = ChoosePixelFormat(hdc, &pfd); + if (pixelFormat == 0) { + throw std::runtime_error("Unable to create initial context"); + } + + if (SetPixelFormat(hdc, pixelFormat, &pfd) == FALSE) { + throw std::runtime_error("Unable to create initial context"); + } +} + +void Context::create() { + if (!PRIMARY) { + PRIMARY = static_cast(qApp->property(PRIMARY_CONTEXT_PROPERTY_NAME).value()); + } + + if (PRIMARY) { + _version = PRIMARY->_version; + } + + assert(0 != _hwnd); + assert(0 == _hdc); + auto hwnd = _hwnd; + // Create a temporary context to initialize glew + static std::once_flag once; + std::call_once(once, [&] { + auto hdc = GetDC(hwnd); + setupPixelFormatSimple(hdc); + auto glrc = wglCreateContext(hdc); + BOOL makeCurrentResult; + makeCurrentResult = wglMakeCurrent(hdc, glrc); + if (!makeCurrentResult) { + throw std::runtime_error("Unable to create initial context"); + } + glewExperimental = true; + glewInit(); + if (glewIsSupported("GL_VERSION_4_5")) { + _version = 0x0405; + } else if (glewIsSupported("GL_VERSION_4_3")) { + _version = 0x0403; + } + glGetError(); + wglMakeCurrent(0, 0); + wglDeleteContext(glrc); + ReleaseDC(hwnd, hdc); + }); + + _hdc = GetDC(_hwnd); + static int pixelFormat = 0; + static PIXELFORMATDESCRIPTOR pfd; + if (!pixelFormat) { + memset(&pfd, 0, sizeof(pfd)); + pfd.nSize = sizeof(pfd); + std::vector formatAttribs; + formatAttribs.push_back(WGL_DRAW_TO_WINDOW_ARB); + formatAttribs.push_back(GL_TRUE); + formatAttribs.push_back(WGL_SUPPORT_OPENGL_ARB); + formatAttribs.push_back(GL_TRUE); + formatAttribs.push_back(WGL_DOUBLE_BUFFER_ARB); + formatAttribs.push_back(GL_TRUE); + formatAttribs.push_back(WGL_PIXEL_TYPE_ARB); + formatAttribs.push_back(WGL_TYPE_RGBA_ARB); + formatAttribs.push_back(WGL_COLOR_BITS_ARB); + formatAttribs.push_back(32); + formatAttribs.push_back(WGL_DEPTH_BITS_ARB); + formatAttribs.push_back(24); + formatAttribs.push_back(WGL_STENCIL_BITS_ARB); + formatAttribs.push_back(8); + formatAttribs.push_back(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB); + formatAttribs.push_back(GL_TRUE); + // terminate the list + formatAttribs.push_back(0); + UINT numFormats; + wglChoosePixelFormatARB(_hdc, &formatAttribs[0], NULL, 1, &pixelFormat, &numFormats); + DescribePixelFormat(_hdc, pixelFormat, sizeof(pfd), &pfd); + } + SetPixelFormat(_hdc, pixelFormat, &pfd); + { + std::vector contextAttribs; + uint32_t majorVersion = _version >> 8; + uint32_t minorVersion = _version & 0xFF; + contextAttribs.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB); + contextAttribs.push_back(majorVersion); + contextAttribs.push_back(WGL_CONTEXT_MINOR_VERSION_ARB); + contextAttribs.push_back(minorVersion); + contextAttribs.push_back(WGL_CONTEXT_PROFILE_MASK_ARB); + contextAttribs.push_back(WGL_CONTEXT_CORE_PROFILE_BIT_ARB); + contextAttribs.push_back(WGL_CONTEXT_FLAGS_ARB); + if (enableDebugLogger) { + contextAttribs.push_back(WGL_CONTEXT_DEBUG_BIT_ARB); + } else { + contextAttribs.push_back(0); + } + contextAttribs.push_back(0); + auto shareHglrc = PRIMARY ? PRIMARY->_hglrc : 0; + _hglrc = wglCreateContextAttribsARB(_hdc, shareHglrc, &contextAttribs[0]); + } + + if (_hglrc == 0) { + throw std::runtime_error("Could not create GL context"); + } + + if (!PRIMARY) { + PRIMARY = this; + qApp->setProperty(PRIMARY_CONTEXT_PROPERTY_NAME, QVariant::fromValue((void*)PRIMARY)); + } + + if (enableDebugLogger) { + makeCurrent(); + glDebugMessageCallback(debugMessageCallback, NULL); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); + doneCurrent(); + } +} +#endif + +void Context::clear() { + glClearColor(0, 0, 0, 1); + QSize windowSize = _window->size() * _window->devicePixelRatio(); + glViewport(0, 0, windowSize.width(), windowSize.height()); + glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + swapBuffers(); +} + + +OffscreenContext::~OffscreenContext() { + _window->deleteLater(); +} + +void OffscreenContext::create() { + if (!_window) { + _window = new QWindow(); + _window->setFlags(Qt::MSWindowsOwnDC); + _window->setSurfaceType(QSurface::OpenGLSurface); + _window->create(); + setWindow(_window); + QGuiApplication::processEvents(); + } + Parent::create(); +} diff --git a/libraries/gl/src/gl/Context.h b/libraries/gl/src/gl/Context.h new file mode 100644 index 0000000000..96e6c693fb --- /dev/null +++ b/libraries/gl/src/gl/Context.h @@ -0,0 +1,72 @@ +// +// Created by Bradley Austin Davis on 2016/08/21 +// Copyright 2013-2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_gl_context_h +#define hifi_gl_context_h + +#include +#include + +#if defined(Q_OS_WIN) +#include +#endif + +class QSurface; +class QWindow; +class QOpenGLContext; +class QThread; + +namespace gl { + +class Context { + protected: + QWindow* _window { nullptr }; + static Context* PRIMARY; + static void destroyContext(QOpenGLContext* context); +#if defined(Q_OS_WIN) + uint32_t _version { 0x0401 }; + HWND _hwnd { 0 }; + HDC _hdc { 0 }; + HGLRC _hglrc { 0 }; + static void destroyWin32Context(HGLRC hglrc); + QOpenGLContext* _wrappedContext { nullptr }; +#else + QOpenGLContext* _context { nullptr }; +#endif + + private: + Context(const Context& other); + + public: + Context(); + Context(QWindow* window); + void release(); + virtual ~Context(); + + void clear(); + void setWindow(QWindow* window); + bool makeCurrent(); + static void makeCurrent(QOpenGLContext* context, QSurface* surface); + void swapBuffers(); + void doneCurrent(); + virtual void create(); + QOpenGLContext* qglContext(); + void moveToThread(QThread* thread); + }; + + class OffscreenContext : public Context { + using Parent = Context; + protected: + QWindow* _window { nullptr }; + public: + virtual ~OffscreenContext(); + virtual void create(); + }; +} + +#endif // hifi_gpu_GPUConfig_h diff --git a/libraries/gl/src/gl/ContextQt.cpp b/libraries/gl/src/gl/ContextQt.cpp new file mode 100644 index 0000000000..ff59b8f1e1 --- /dev/null +++ b/libraries/gl/src/gl/ContextQt.cpp @@ -0,0 +1,75 @@ +// +// Created by Bradley Austin Davis on 2016/08/21 +// Copyright 2013-2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "Context.h" + +#include +#include + +#ifdef Q_OS_WIN +#include +#endif + +using namespace gl; + +void Context::destroyContext(QOpenGLContext* context) { + delete context; +} + +void Context::makeCurrent(QOpenGLContext* context, QSurface* surface) { + context->makeCurrent(surface); +} + +QOpenGLContext* Context::qglContext() { +#ifdef Q_OS_WIN + if (!_wrappedContext) { + _wrappedContext = new QOpenGLContext(); + _wrappedContext->setNativeHandle(QVariant::fromValue(QWGLNativeContext(_hglrc, _hwnd))); + _wrappedContext->create(); + } + return _wrappedContext; +#else + + return _context; +#endif +} + +void Context::moveToThread(QThread* thread) { + qglContext()->moveToThread(thread); +} + +#ifndef Q_OS_WIN +bool Context::makeCurrent() { + return _context->makeCurrent(_window); +} + +void Context::swapBuffers() { + _context->swapBuffers(_window); +} + +void Context::doneCurrent() { + if (_context) { + _context->doneCurrent(); + } +} + +const QSurfaceFormat& getDefaultOpenGLSurfaceFormat(); + + +void Context::create() { + _context = new QOpenGLContext(); + if (PRIMARY) { + _context->setShareContext(PRIMARY->qglContext()); + } else { + PRIMARY = this; + } + _context->setFormat(getDefaultOpenGLSurfaceFormat()); + _context->create(); +} + +#endif diff --git a/libraries/gl/src/gl/GLHelpers.cpp b/libraries/gl/src/gl/GLHelpers.cpp index f464001f60..dde1e0ec97 100644 --- a/libraries/gl/src/gl/GLHelpers.cpp +++ b/libraries/gl/src/gl/GLHelpers.cpp @@ -21,44 +21,20 @@ const QSurfaceFormat& getDefaultOpenGLSurfaceFormat() { format.setDepthBufferSize(DEFAULT_GL_DEPTH_BUFFER_BITS); format.setStencilBufferSize(DEFAULT_GL_STENCIL_BUFFER_BITS); setGLFormatVersion(format); - if (GLDebug::enabled()) { - qDebug() << "Enabling debug context"; - format.setOption(QSurfaceFormat::DebugContext); - } format.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile); QSurfaceFormat::setDefaultFormat(format); }); return format; } -const QGLFormat& getDefaultGLFormat() { - // Specify an OpenGL 3.3 format using the Core profile. - // That is, no old-school fixed pipeline functionality - static QGLFormat glFormat; - static std::once_flag once; - std::call_once(once, [] { - setGLFormatVersion(glFormat); - glFormat.setProfile(QGLFormat::CoreProfile); // Requires >=Qt-4.8.0 - glFormat.setSampleBuffers(false); - glFormat.setDepth(false); - glFormat.setStencil(false); - QGLFormat::setDefaultFormat(glFormat); - }); - return glFormat; -} - int glVersionToInteger(QString glVersion) { QStringList versionParts = glVersion.split(QRegularExpression("[\\.\\s]")); int majorNumber = versionParts[0].toInt(); int minorNumber = versionParts[1].toInt(); - return majorNumber * 100 + minorNumber * 10; + return (majorNumber << 16) | minorNumber; } QJsonObject getGLContextData() { - if (!QOpenGLContext::currentContext()) { - return QJsonObject(); - } - QString glVersion = QString((const char*)glGetString(GL_VERSION)); QString glslVersion = QString((const char*) glGetString(GL_SHADING_LANGUAGE_VERSION)); QString glVendor = QString((const char*) glGetString(GL_VENDOR)); @@ -77,31 +53,3 @@ QThread* RENDER_THREAD = nullptr; bool isRenderThread() { return QThread::currentThread() == RENDER_THREAD; } - - -#ifdef DEBUG -static bool enableDebugLogger = true; -#else -static const QString DEBUG_FLAG("HIFI_DEBUG_OPENGL"); -static bool enableDebugLogger = QProcessEnvironment::systemEnvironment().contains(DEBUG_FLAG); -#endif - -bool GLDebug::enabled() { - return enableDebugLogger; -} - -void GLDebug::log(const QOpenGLDebugMessage & debugMessage) { - qDebug() << debugMessage; -} - -void GLDebug::setupLogger(QObject* window) { - if (enabled()) { - QOpenGLDebugLogger* logger = new QOpenGLDebugLogger(window); - logger->initialize(); // initializes in the current context, i.e. ctx - logger->enableMessages(); - QObject::connect(logger, &QOpenGLDebugLogger::messageLogged, window, [&](const QOpenGLDebugMessage & debugMessage) { - GLDebug::log(debugMessage); - }); - logger->startLogging(QOpenGLDebugLogger::SynchronousLogging); - } -} \ No newline at end of file diff --git a/libraries/gl/src/gl/GLHelpers.h b/libraries/gl/src/gl/GLHelpers.h index 9e185f5845..8834a718fd 100644 --- a/libraries/gl/src/gl/GLHelpers.h +++ b/libraries/gl/src/gl/GLHelpers.h @@ -27,19 +27,9 @@ template void setGLFormatVersion(F& format, int major = 4, int minor = 5) { format.setVersion(major, minor); } const QSurfaceFormat& getDefaultOpenGLSurfaceFormat(); -const QGLFormat& getDefaultGLFormat(); QJsonObject getGLContextData(); int glVersionToInteger(QString glVersion); bool isRenderThread(); - -class GLDebug { -public: - static bool enabled(); - static void log(const QOpenGLDebugMessage& debugMessage); - static void setupLogger(QObject* window = nullptr); -}; - - #endif diff --git a/libraries/gl/src/gl/GLWidget.cpp b/libraries/gl/src/gl/GLWidget.cpp index 8b0bd9981f..f2b823a65e 100644 --- a/libraries/gl/src/gl/GLWidget.cpp +++ b/libraries/gl/src/gl/GLWidget.cpp @@ -7,30 +7,52 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include #include "GLWidget.h" +#include "Config.h" + #include +#include #include #include #include -#include #include +#include #include - +#include "Context.h" #include "GLHelpers.h" +class GLPaintEngine : public QPaintEngine { + bool begin(QPaintDevice *pdev) override { return true; } + bool end() override { return true; } + void updateState(const QPaintEngineState &state) override { } + void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) override { } + Type type() const override { return OpenGL2; } +}; -GLWidget::GLWidget() : QGLWidget(getDefaultGLFormat()) { +GLWidget::GLWidget() { #ifdef Q_OS_LINUX // Cause GLWidget::eventFilter to be called. // It wouldn't hurt to do this on Mac and PC too; but apparently it's only needed on linux. qApp->installEventFilter(this); #endif + setAttribute(Qt::WA_AcceptTouchEvents); + setAttribute(Qt::WA_NativeWindow); + setAttribute(Qt::WA_PaintOnScreen); + setAttribute(Qt::WA_NoSystemBackground); + setAutoFillBackground(false); + grabGesture(Qt::PinchGesture); + setAcceptDrops(true); + _paintEngine = new GLPaintEngine(); +} + +GLWidget::~GLWidget() { + delete _paintEngine; + _paintEngine = nullptr; } int GLWidget::getDeviceWidth() const { @@ -41,31 +63,25 @@ int GLWidget::getDeviceHeight() const { return height() * (windowHandle() ? (float)windowHandle()->devicePixelRatio() : 1.0f); } -void GLWidget::initializeGL() { - setAttribute(Qt::WA_AcceptTouchEvents); - grabGesture(Qt::PinchGesture); - setAcceptDrops(true); - // Note, we *DO NOT* want Qt to automatically swap buffers for us. This results in the "ringing" bug mentioned in WL#19514 when we're throttling the framerate. - setAutoBufferSwap(false); - - makeCurrent(); - if (isValid() && context() && context()->contextHandle()) { -#if defined(Q_OS_WIN) - _vsyncSupported = context()->contextHandle()->hasExtension("WGL_EXT_swap_control"); -#elif defined(Q_OS_MAC) - _vsyncSupported = true; -#else - // TODO: write the proper code for linux -#endif - } +void GLWidget::createContext() { + _context = new gl::Context(); + _context->setWindow(windowHandle()); + _context->create(); + _context->clear(); + _context->makeCurrent(); } -void GLWidget::paintEvent(QPaintEvent* event) { - QWidget::paintEvent(event); +bool GLWidget::makeCurrent() { + gl::Context::makeCurrent(_context->qglContext(), windowHandle()); + return _context->makeCurrent(); } -void GLWidget::resizeEvent(QResizeEvent* event) { - QWidget::resizeEvent(event); +QOpenGLContext* GLWidget::qglContext() { + return _context->qglContext(); +} + +void GLWidget::doneCurrent() { + _context->doneCurrent(); } bool GLWidget::event(QEvent* event) { @@ -94,10 +110,9 @@ bool GLWidget::event(QEvent* event) { default: break; } - return QGLWidget::event(event); + return QWidget::event(event); } - // Pressing Alt (and Meta) key alone activates the menubar because its style inherits the // SHMenuBarAltKeyNavigation from QWindowsStyle. This makes it impossible for a scripts to // receive keyPress events for the Alt (and Meta) key in a reliable manner. @@ -119,7 +134,7 @@ bool GLWidget::eventFilter(QObject*, QEvent* event) { } else if (event->type() == QEvent::KeyRelease) { keyReleaseEvent(keyEvent); } else { - QGLWidget::event(event); + QWidget::event(event); } return true; } @@ -130,7 +145,22 @@ bool GLWidget::eventFilter(QObject*, QEvent* event) { return false; } -bool GLWidget::isVsyncSupported() const { - return _vsyncSupported; + +bool GLWidget::nativeEvent(const QByteArray &eventType, void *message, long *result) { +#ifdef Q_OS_WIN32 + MSG* win32message = static_cast(message); + switch (win32message->message) { + case WM_ERASEBKGND: + *result = 1L; + return TRUE; + + default: + break; + } +#endif + return QWidget::nativeEvent(eventType, message, result); } +QPaintEngine* GLWidget::paintEngine() const { + return _paintEngine; +} diff --git a/libraries/gl/src/gl/GLWidget.h b/libraries/gl/src/gl/GLWidget.h index 5b391aa6cd..21dffc1b75 100644 --- a/libraries/gl/src/gl/GLWidget.h +++ b/libraries/gl/src/gl/GLWidget.h @@ -10,31 +10,43 @@ #ifndef hifi_GLWidget_h #define hifi_GLWidget_h -#include +#include + +namespace gl { + class Context; +} + +class QOpenGLContext; /// customized canvas that simply forwards requests/events to the singleton application -class GLWidget : public QGLWidget { +class GLWidget : public QWidget { Q_OBJECT public: GLWidget(); + ~GLWidget(); int getDeviceWidth() const; int getDeviceHeight() const; QSize getDeviceSize() const { return QSize(getDeviceWidth(), getDeviceHeight()); } - bool isVsyncSupported() const; - virtual void initializeGL() override; + QPaintEngine* paintEngine() const override; + void createContext(); + bool makeCurrent(); + void doneCurrent(); + gl::Context* context() { return _context; } + QOpenGLContext* qglContext(); + protected: + virtual bool nativeEvent(const QByteArray &eventType, void *message, long *result) override; virtual bool event(QEvent* event) override; - virtual void paintEvent(QPaintEvent* event) override; - virtual void resizeEvent(QResizeEvent* event) override; + gl::Context* _context { nullptr }; private slots: virtual bool eventFilter(QObject*, QEvent* event) override; private: + QPaintEngine* _paintEngine { nullptr }; bool _vsyncSupported { false }; }; - #endif // hifi_GLCanvas_h diff --git a/libraries/gl/src/gl/OffscreenGLCanvas.cpp b/libraries/gl/src/gl/OffscreenGLCanvas.cpp index 2f8b29325e..3204b50d19 100644 --- a/libraries/gl/src/gl/OffscreenGLCanvas.cpp +++ b/libraries/gl/src/gl/OffscreenGLCanvas.cpp @@ -60,7 +60,6 @@ bool OffscreenGLCanvas::makeCurrent() { qDebug() << "GL Shader Language Version: " << QString((const char*) glGetString(GL_SHADING_LANGUAGE_VERSION)); qDebug() << "GL Vendor: " << QString((const char*) glGetString(GL_VENDOR)); qDebug() << "GL Renderer: " << QString((const char*) glGetString(GL_RENDERER)); - GLDebug::setupLogger(this); }); return result; diff --git a/libraries/gl/src/gl/OpenGLVersionChecker.cpp b/libraries/gl/src/gl/OpenGLVersionChecker.cpp index ed33dc1ab9..6473b6bf2b 100644 --- a/libraries/gl/src/gl/OpenGLVersionChecker.cpp +++ b/libraries/gl/src/gl/OpenGLVersionChecker.cpp @@ -10,27 +10,46 @@ // #include "OpenGLVersionChecker.h" - -#include -#include -#include - #include "Config.h" -#include "GLWidget.h" + +#include + +#include +#include +#include +#include + #include "GLHelpers.h" -#define MINIMUM_GL_VERSION 410 +#define MINIMUM_GL_VERSION 0x0401 OpenGLVersionChecker::OpenGLVersionChecker(int& argc, char** argv) : QApplication(argc, argv) { } +const QGLFormat& getDefaultGLFormat() { + // Specify an OpenGL 3.3 format using the Core profile. + // That is, no old-school fixed pipeline functionality + static QGLFormat glFormat; + static std::once_flag once; + std::call_once(once, [] { + setGLFormatVersion(glFormat); + glFormat.setProfile(QGLFormat::CoreProfile); // Requires >=Qt-4.8.0 + glFormat.setSampleBuffers(false); + glFormat.setDepth(false); + glFormat.setStencil(false); + QGLFormat::setDefaultFormat(glFormat); + }); + return glFormat; +} + + QJsonObject OpenGLVersionChecker::checkVersion(bool& valid, bool& override) { valid = true; override = false; - GLWidget* glWidget = new GLWidget(); + QGLWidget* glWidget = new QGLWidget(); valid = glWidget->isValid(); // Inform user if no OpenGL support if (!valid) { @@ -46,7 +65,8 @@ QJsonObject OpenGLVersionChecker::checkVersion(bool& valid, bool& override) { } // Retrieve OpenGL version - glWidget->initializeGL(); + // glWidget->initializeGL(); + glWidget->makeCurrent(); QJsonObject glData = getGLContextData(); delete glWidget; @@ -60,8 +80,8 @@ QJsonObject OpenGLVersionChecker::checkVersion(bool& valid, bool& override) { QStringList versionParts = glVersion.split(QRegularExpression("[\\.\\s]")); int majorNumber = versionParts[0].toInt(); int minorNumber = versionParts[1].toInt(); - int minimumMajorNumber = MINIMUM_GL_VERSION / 100; - int minimumMinorNumber = (MINIMUM_GL_VERSION - minimumMajorNumber * 100) / 10; + int minimumMajorNumber = (MINIMUM_GL_VERSION >> 16); + int minimumMinorNumber = (MINIMUM_GL_VERSION & 0xFF); valid = (majorNumber > minimumMajorNumber || (majorNumber == minimumMajorNumber && minorNumber >= minimumMinorNumber)); diff --git a/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp b/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp index 818d95d756..d90ca3bbd6 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp @@ -100,7 +100,7 @@ float GLTexture::getMemoryPressure() { // If no memory limit has been set, use a percentage of the total dedicated memory if (!availableTextureMemory) { - auto totalGpuMemory = gpu::gl::getDedicatedMemory(); + auto totalGpuMemory = getDedicatedMemory(); // If no limit has been explicitly set, and the dedicated memory can't be determined, // just use a fallback fixed value of 256 MB @@ -118,7 +118,7 @@ float GLTexture::getMemoryPressure() { return (float)consumedGpuMemory / (float)availableTextureMemory; } -GLTexture::DownsampleSource::DownsampleSource(const std::weak_ptr& backend, GLTexture* oldTexture) : +GLTexture::DownsampleSource::DownsampleSource(const std::weak_ptr& backend, GLTexture* oldTexture) : _backend(backend), _size(oldTexture ? oldTexture->_size : 0), _texture(oldTexture ? oldTexture->takeOwnership() : 0), @@ -161,7 +161,7 @@ GLTexture::GLTexture(const std::weak_ptr& backend, const gpu::Texture // Create the texture and allocate storage -GLTexture::GLTexture(const std::weak_ptr& backend, const Texture& texture, GLuint id, bool transferrable) : +GLTexture::GLTexture(const std::weak_ptr& backend, const Texture& texture, GLuint id, bool transferrable) : GLTexture(backend, texture, id, nullptr, transferrable) { // FIXME, do during allocation @@ -170,7 +170,7 @@ GLTexture::GLTexture(const std::weak_ptr& backend, const Texture& } // Create the texture and copy from the original higher resolution version -GLTexture::GLTexture(const std::weak_ptr& backend, const gpu::Texture& texture, GLuint id, GLTexture* originalTexture) : +GLTexture::GLTexture(const std::weak_ptr& backend, const gpu::Texture& texture, GLuint id, GLTexture* originalTexture) : GLTexture(backend, texture, id, originalTexture, originalTexture->_transferrable) { Q_ASSERT(_minMip >= originalTexture->_minMip); diff --git a/libraries/gpu-gl/src/gpu/gl/GLTexture.h b/libraries/gpu-gl/src/gpu/gl/GLTexture.h index d050afbb59..4f67039aa8 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLTexture.h +++ b/libraries/gpu-gl/src/gpu/gl/GLTexture.h @@ -58,7 +58,6 @@ public: // If we just did a transfer, return the object after doing post-transfer work if (GLSyncState::Transferred == object->getSyncState()) { object->postTransfer(); - return object; } if (object->isOutdated()) { diff --git a/libraries/gpu-gl/src/gpu/gl/GLTextureTransfer.cpp b/libraries/gpu-gl/src/gpu/gl/GLTextureTransfer.cpp index 766c134b16..9b933cfb90 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLTextureTransfer.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLTextureTransfer.cpp @@ -7,10 +7,8 @@ // #include "GLTextureTransfer.h" -#ifdef THREADED_TEXTURE_TRANSFER -#include -#include -#endif +#include +#include #include "GLShared.h" #include "GLTexture.h" @@ -20,16 +18,9 @@ using namespace gpu::gl; GLTextureTransferHelper::GLTextureTransferHelper() { #ifdef THREADED_TEXTURE_TRANSFER - _canvas = QSharedPointer(new OffscreenGLCanvas(), &QObject::deleteLater); - _canvas->setObjectName("TextureTransferCanvas"); - _canvas->create(QOpenGLContextWrapper::currentContext()); - if (!_canvas->makeCurrent()) { - qFatal("Unable to create texture transfer context"); - } - _canvas->doneCurrent(); + setObjectName("TextureTransferThread"); + _context.create(); initialize(true, QThread::LowPriority); - _canvas->moveToThreadWithContext(_thread); - // Clean shutdown on UNIX, otherwise _canvas is freed early connect(qApp, &QCoreApplication::aboutToQuit, [&] { terminate(); }); #endif @@ -64,17 +55,9 @@ void GLTextureTransferHelper::transferTexture(const gpu::TexturePointer& texture } void GLTextureTransferHelper::setup() { -#ifdef THREADED_TEXTURE_TRANSFER - _canvas->makeCurrent(); -#endif } void GLTextureTransferHelper::shutdown() { -#ifdef THREADED_TEXTURE_TRANSFER - _canvas->doneCurrent(); - _canvas->moveToThreadWithContext(qApp->thread()); - _canvas.reset(); -#endif } void GLTextureTransferHelper::do_transfer(GLTexture& texture) { @@ -85,6 +68,9 @@ void GLTextureTransferHelper::do_transfer(GLTexture& texture) { } bool GLTextureTransferHelper::processQueueItems(const Queue& messages) { +#ifdef THREADED_TEXTURE_TRANSFER + _context.makeCurrent(); +#endif for (auto package : messages) { TexturePointer texturePointer = package.texture.lock(); // Texture no longer exists, move on to the next @@ -93,21 +79,39 @@ bool GLTextureTransferHelper::processQueueItems(const Queue& messages) { } if (package.fence) { - glClientWaitSync(package.fence, GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED); + auto result = glClientWaitSync(package.fence, 0, 0); + while (GL_TIMEOUT_EXPIRED == result || GL_WAIT_FAILED == result) { + // Minimum sleep + QThread::usleep(1); + result = glClientWaitSync(package.fence, 0, 0); + } + assert(GL_CONDITION_SATISFIED == result || GL_ALREADY_SIGNALED == result); glDeleteSync(package.fence); package.fence = 0; } GLTexture* object = Backend::getGPUObject(*texturePointer); + do_transfer(*object); glBindTexture(object->_target, 0); - auto writeSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - glClientWaitSync(writeSync, GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED); - glDeleteSync(writeSync); + { + auto fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + assert(fence); + auto result = glClientWaitSync(fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0); + while (GL_TIMEOUT_EXPIRED == result || GL_WAIT_FAILED == result) { + // Minimum sleep + QThread::usleep(1); + result = glClientWaitSync(fence, 0, 0); + } + glDeleteSync(package.fence); + } object->_contentStamp = texturePointer->getDataStamp(); object->setSyncState(GLSyncState::Transferred); } +#ifdef THREADED_TEXTURE_TRANSFER + _context.doneCurrent(); +#endif return true; } diff --git a/libraries/gpu-gl/src/gpu/gl/GLTextureTransfer.h b/libraries/gpu-gl/src/gpu/gl/GLTextureTransfer.h index 078ab40ee3..e64e204af3 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLTextureTransfer.h +++ b/libraries/gpu-gl/src/gpu/gl/GLTextureTransfer.h @@ -13,14 +13,14 @@ #include +#include + #include "GLShared.h" #ifdef Q_OS_WIN #define THREADED_TEXTURE_TRANSFER #endif -class OffscreenGLCanvas; - namespace gpu { namespace gl { struct TextureTransferPackage { @@ -43,7 +43,7 @@ protected: void do_transfer(GLTexture& texturePointer); private: - QSharedPointer _canvas; + ::gl::OffscreenContext _context; }; } } diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h index 37441c4ebb..6e15542310 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h +++ b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h @@ -27,8 +27,10 @@ namespace gpu { namespace gl41 { -class GL41Backend : public gl::GLBackend { - using Parent = gl::GLBackend; +using namespace gpu::gl; + +class GL41Backend : public GLBackend { + using Parent = GLBackend; // Context Backend static interface required friend class Context; @@ -36,12 +38,12 @@ public: explicit GL41Backend(bool syncCache) : Parent(syncCache) {} GL41Backend() : Parent() {} - class GL41Texture : public gpu::gl::GLTexture { - using Parent = gpu::gl::GLTexture; + class GL41Texture : public GLTexture { + using Parent = GLTexture; GLuint allocate(); public: - GL41Texture(const std::weak_ptr& backend, const Texture& buffer, bool transferrable); - GL41Texture(const std::weak_ptr& backend, const Texture& buffer, GL41Texture* original); + GL41Texture(const std::weak_ptr& backend, const Texture& buffer, bool transferrable); + GL41Texture(const std::weak_ptr& backend, const Texture& buffer, GL41Texture* original); protected: void transferMip(uint16_t mipLevel, uint8_t face = 0) const; @@ -56,16 +58,16 @@ public: protected: GLuint getFramebufferID(const FramebufferPointer& framebuffer) override; - gl::GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) override; + GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) override; GLuint getBufferID(const Buffer& buffer) override; - gl::GLBuffer* syncGPUObject(const Buffer& buffer) override; + GLBuffer* syncGPUObject(const Buffer& buffer) override; GLuint getTextureID(const TexturePointer& texture, bool needTransfer = true) override; - gl::GLTexture* syncGPUObject(const TexturePointer& texture, bool sync = true) override; + GLTexture* syncGPUObject(const TexturePointer& texture, bool sync = true) override; GLuint getQueryID(const QueryPointer& query) override; - gl::GLQuery* syncGPUObject(const Query& query) override; + GLQuery* syncGPUObject(const Query& query) override; // Draw Stage void do_draw(const Batch& batch, size_t paramOffset) override; diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp index d9d7328bc8..b739bfaf89 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp @@ -10,7 +10,7 @@ namespace gpu { namespace gl41 { - class GL41Buffer : public gl::GLBuffer { + class GL41Buffer : public gpu::gl::GLBuffer { using Parent = gpu::gl::GLBuffer; static GLuint allocate() { GLuint result; @@ -55,6 +55,7 @@ namespace gpu { } using namespace gpu; +using namespace gpu::gl; using namespace gpu::gl41; @@ -62,6 +63,6 @@ GLuint GL41Backend::getBufferID(const Buffer& buffer) { return GL41Buffer::getId(*this, buffer); } -gl::GLBuffer* GL41Backend::syncGPUObject(const Buffer& buffer) { +GLBuffer* GL41Backend::syncGPUObject(const Buffer& buffer) { return GL41Buffer::sync(*this, buffer); } diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendQuery.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendQuery.cpp index 342c4ba6c2..f712550973 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendQuery.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendQuery.cpp @@ -13,10 +13,11 @@ #include "../gl/GLQuery.h" using namespace gpu; +using namespace gpu::gl; using namespace gpu::gl41; -class GL41Query : public gpu::gl::GLQuery { - using Parent = gpu::gl::GLQuery; +class GL41Query : public GLQuery { + using Parent = GLQuery; public: static GLuint allocateQuery() { GLuint result; @@ -24,11 +25,11 @@ public: return result; } - GL41Query(const std::weak_ptr& backend, const Query& query) + GL41Query(const std::weak_ptr& backend, const Query& query) : Parent(backend, query, allocateQuery(), allocateQuery()) { } }; -gl::GLQuery* GL41Backend::syncGPUObject(const Query& query) { +GLQuery* GL41Backend::syncGPUObject(const Query& query) { return GL41Query::sync(*this, query); } diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp index 8f1248ef57..ff1a790ba5 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp @@ -17,9 +17,10 @@ #include "../gl/GLTexelFormat.h" using namespace gpu; +using namespace gpu::gl; using namespace gpu::gl41; -using GL41TexelFormat = gl::GLTexelFormat; +using GL41TexelFormat = GLTexelFormat; using GL41Texture = GL41Backend::GL41Texture; GLuint GL41Texture::allocate() { @@ -33,13 +34,13 @@ GLuint GL41Backend::getTextureID(const TexturePointer& texture, bool transfer) { return GL41Texture::getId(*this, texture, transfer); } -gl::GLTexture* GL41Backend::syncGPUObject(const TexturePointer& texture, bool transfer) { +GLTexture* GL41Backend::syncGPUObject(const TexturePointer& texture, bool transfer) { return GL41Texture::sync(*this, texture, transfer); } -GL41Texture::GL41Texture(const std::weak_ptr& backend, const Texture& texture, bool transferrable) : gl::GLTexture(backend, texture, allocate(), transferrable) {} +GL41Texture::GL41Texture(const std::weak_ptr& backend, const Texture& texture, bool transferrable) : GLTexture(backend, texture, allocate(), transferrable) {} -GL41Texture::GL41Texture(const std::weak_ptr& backend, const Texture& texture, GL41Texture* original) : gl::GLTexture(backend, texture, allocate(), original) {} +GL41Texture::GL41Texture(const std::weak_ptr& backend, const Texture& texture, GL41Texture* original) : GLTexture(backend, texture, allocate(), original) {} void GL41Backend::GL41Texture::withPreservedTexture(std::function f) const { GLint boundTex = -1; @@ -71,7 +72,7 @@ void GL41Backend::GL41Texture::generateMips() const { } void GL41Backend::GL41Texture::allocateStorage() const { - gl::GLTexelFormat texelFormat = gl::GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat()); + GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat()); glTexParameteri(_target, GL_TEXTURE_BASE_LEVEL, 0); (void)CHECK_GL_ERROR(); glTexParameteri(_target, GL_TEXTURE_MAX_LEVEL, _maxMip - _minMip); @@ -131,7 +132,7 @@ void GL41Backend::GL41Texture::updateSize() const { // Move content bits from the CPU to the GPU for a given mip / face void GL41Backend::GL41Texture::transferMip(uint16_t mipLevel, uint8_t face) const { auto mip = _gpuObject.accessStoredMipFace(mipLevel, face); - gl::GLTexelFormat texelFormat = gl::GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), mip->getFormat()); + GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), mip->getFormat()); //GLenum target = getFaceTargets()[face]; GLenum target = _target == GL_TEXTURE_2D ? GL_TEXTURE_2D : CUBE_FACE_LAYOUT[face]; auto size = _gpuObject.evalMipDimensions(mipLevel); @@ -216,7 +217,7 @@ void GL41Backend::GL41Texture::syncSampler() const { if (sampler.doComparison()) { glTexParameteri(_target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); - glTexParameteri(_target, GL_TEXTURE_COMPARE_FUNC, gl::COMPARISON_TO_GL[sampler.getComparisonFunction()]); + glTexParameteri(_target, GL_TEXTURE_COMPARE_FUNC, COMPARISON_TO_GL[sampler.getComparisonFunction()]); } else { glTexParameteri(_target, GL_TEXTURE_COMPARE_MODE, GL_NONE); } diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTransform.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTransform.cpp index 45f48df310..ee803f28c1 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTransform.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTransform.cpp @@ -69,7 +69,9 @@ void GL41Backend::transferTransformState(const Batch& batch) const { #else glActiveTexture(GL_TEXTURE0 + TRANSFORM_OBJECT_SLOT); glBindTexture(GL_TEXTURE_BUFFER, _transform._objectBufferTexture); - glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, _transform._objectBuffer); + if (!batch._objects.empty()) { + glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, _transform._objectBuffer); + } #endif CHECK_GL_ERROR(); diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h index 679699129f..0d737ef3ba 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h +++ b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h @@ -15,9 +15,11 @@ #include "../gl/GLTexture.h" namespace gpu { namespace gl45 { + +using namespace gpu::gl; -class GL45Backend : public gl::GLBackend { - using Parent = gl::GLBackend; +class GL45Backend : public GLBackend { + using Parent = GLBackend; // Context Backend static interface required friend class Context; @@ -25,12 +27,12 @@ public: explicit GL45Backend(bool syncCache) : Parent(syncCache) {} GL45Backend() : Parent() {} - class GL45Texture : public gpu::gl::GLTexture { - using Parent = gpu::gl::GLTexture; + class GL45Texture : public GLTexture { + using Parent = GLTexture; GLuint allocate(const Texture& texture); public: - GL45Texture(const std::weak_ptr& backend, const Texture& texture, bool transferrable); - GL45Texture(const std::weak_ptr& backend, const Texture& texture, GLTexture* original); + GL45Texture(const std::weak_ptr& backend, const Texture& texture, bool transferrable); + GL45Texture(const std::weak_ptr& backend, const Texture& texture, GLTexture* original); protected: void transferMip(uint16_t mipLevel, uint8_t face = 0) const; @@ -45,16 +47,16 @@ public: protected: GLuint getFramebufferID(const FramebufferPointer& framebuffer) override; - gl::GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) override; + GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) override; GLuint getBufferID(const Buffer& buffer) override; - gl::GLBuffer* syncGPUObject(const Buffer& buffer) override; + GLBuffer* syncGPUObject(const Buffer& buffer) override; GLuint getTextureID(const TexturePointer& texture, bool needTransfer = true) override; - gl::GLTexture* syncGPUObject(const TexturePointer& texture, bool sync = true) override; + GLTexture* syncGPUObject(const TexturePointer& texture, bool sync = true) override; GLuint getQueryID(const QueryPointer& query) override; - gl::GLQuery* syncGPUObject(const Query& query) override; + GLQuery* syncGPUObject(const Query& query) override; // Draw Stage void do_draw(const Batch& batch, size_t paramOffset) override; diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp index c7c9ec1b2e..cd69c03691 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp @@ -8,41 +8,42 @@ #include "GL45Backend.h" #include "../gl/GLBuffer.h" -namespace gpu { - namespace gl45 { - class GL45Buffer : public gl::GLBuffer { - using Parent = gpu::gl::GLBuffer; - static GLuint allocate() { - GLuint result; - glCreateBuffers(1, &result); - return result; - } +namespace gpu { namespace gl45 { + using namespace gpu::gl; - public: - GL45Buffer(const std::weak_ptr& backend, const Buffer& buffer, GLBuffer* original) : Parent(backend, buffer, allocate()) { - glNamedBufferStorage(_buffer, _size == 0 ? 256 : _size, nullptr, GL_DYNAMIC_STORAGE_BIT); - if (original && original->_size) { - glCopyNamedBufferSubData(original->_buffer, _buffer, 0, 0, std::min(original->_size, _size)); - } - Backend::setGPUObject(buffer, this); - } + class GL45Buffer : public GLBuffer { + using Parent = GLBuffer; + static GLuint allocate() { + GLuint result; + glCreateBuffers(1, &result); + return result; + } - void transfer() override { - Size offset; - Size size; - Size currentPage { 0 }; - auto data = _gpuObject._renderSysmem.readData(); - while (_gpuObject._renderPages.getNextTransferBlock(offset, size, currentPage)) { - glNamedBufferSubData(_buffer, (GLintptr)offset, (GLsizeiptr)size, data + offset); - } - (void)CHECK_GL_ERROR(); - _gpuObject._renderPages._flags &= ~PageManager::DIRTY; + public: + GL45Buffer(const std::weak_ptr& backend, const Buffer& buffer, GLBuffer* original) : Parent(backend, buffer, allocate()) { + glNamedBufferStorage(_buffer, _size == 0 ? 256 : _size, nullptr, GL_DYNAMIC_STORAGE_BIT); + if (original && original->_size) { + glCopyNamedBufferSubData(original->_buffer, _buffer, 0, 0, std::min(original->_size, _size)); } - }; - } -} + Backend::setGPUObject(buffer, this); + } + + void transfer() override { + Size offset; + Size size; + Size currentPage { 0 }; + auto data = _gpuObject._renderSysmem.readData(); + while (_gpuObject._renderPages.getNextTransferBlock(offset, size, currentPage)) { + glNamedBufferSubData(_buffer, (GLintptr)offset, (GLsizeiptr)size, data + offset); + } + (void)CHECK_GL_ERROR(); + _gpuObject._renderPages._flags &= ~PageManager::DIRTY; + } + }; +} } using namespace gpu; +using namespace gpu::gl; using namespace gpu::gl45; @@ -50,6 +51,6 @@ GLuint GL45Backend::getBufferID(const Buffer& buffer) { return GL45Buffer::getId(*this, buffer); } -gl::GLBuffer* GL45Backend::syncGPUObject(const Buffer& buffer) { +GLBuffer* GL45Backend::syncGPUObject(const Buffer& buffer) { return GL45Buffer::sync(*this, buffer); } diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp index 7c3e362834..d3222b9acf 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp @@ -12,14 +12,15 @@ #include #include + #include #include "../gl/GLTexelFormat.h" using namespace gpu; +using namespace gpu::gl; using namespace gpu::gl45; -using GLTexelFormat = gl::GLTexelFormat; using GL45Texture = GL45Backend::GL45Texture; GLuint GL45Texture::allocate(const Texture& texture) { @@ -33,15 +34,15 @@ GLuint GL45Backend::getTextureID(const TexturePointer& texture, bool transfer) { return GL45Texture::getId(*this, texture, transfer); } -gl::GLTexture* GL45Backend::syncGPUObject(const TexturePointer& texture, bool transfer) { +GLTexture* GL45Backend::syncGPUObject(const TexturePointer& texture, bool transfer) { return GL45Texture::sync(*this, texture, transfer); } -GL45Backend::GL45Texture::GL45Texture(const std::weak_ptr& backend, const Texture& texture, bool transferrable) - : gl::GLTexture(backend, texture, allocate(texture), transferrable) {} +GL45Backend::GL45Texture::GL45Texture(const std::weak_ptr& backend, const Texture& texture, bool transferrable) + : GLTexture(backend, texture, allocate(texture), transferrable) {} -GL45Backend::GL45Texture::GL45Texture(const std::weak_ptr& backend, const Texture& texture, GLTexture* original) - : gl::GLTexture(backend, texture, allocate(texture), original) {} +GL45Backend::GL45Texture::GL45Texture(const std::weak_ptr& backend, const Texture& texture, GLTexture* original) + : GLTexture(backend, texture, allocate(texture), original) {} void GL45Backend::GL45Texture::withPreservedTexture(std::function f) const { f(); @@ -53,7 +54,7 @@ void GL45Backend::GL45Texture::generateMips() const { } void GL45Backend::GL45Texture::allocateStorage() const { - gl::GLTexelFormat texelFormat = gl::GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat()); + GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat()); glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, 0); glTextureParameteri(_id, GL_TEXTURE_MAX_LEVEL, _maxMip - _minMip); if (_gpuObject.getTexelFormat().isCompressed()) { @@ -79,7 +80,7 @@ void GL45Backend::GL45Texture::updateSize() const { // Move content bits from the CPU to the GPU for a given mip / face void GL45Backend::GL45Texture::transferMip(uint16_t mipLevel, uint8_t face) const { auto mip = _gpuObject.accessStoredMipFace(mipLevel, face); - gl::GLTexelFormat texelFormat = gl::GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), mip->getFormat()); + GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), mip->getFormat()); auto size = _gpuObject.evalMipDimensions(mipLevel); if (GL_TEXTURE_2D == _target) { glTextureSubImage2D(_id, mipLevel, 0, 0, size.x, size.y, texelFormat.format, texelFormat.type, mip->readData()); @@ -167,7 +168,7 @@ void GL45Backend::GL45Texture::syncSampler() const { if (sampler.doComparison()) { glTextureParameteri(_id, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); - glTextureParameteri(_id, GL_TEXTURE_COMPARE_FUNC, gl::COMPARISON_TO_GL[sampler.getComparisonFunction()]); + glTextureParameteri(_id, GL_TEXTURE_COMPARE_FUNC, COMPARISON_TO_GL[sampler.getComparisonFunction()]); } else { glTextureParameteri(_id, GL_TEXTURE_COMPARE_MODE, GL_NONE); } diff --git a/libraries/ui/src/MainWindow.cpp b/libraries/ui/src/MainWindow.cpp index bc67a726bd..545d2dc902 100644 --- a/libraries/ui/src/MainWindow.cpp +++ b/libraries/ui/src/MainWindow.cpp @@ -30,6 +30,7 @@ MainWindow::MainWindow(QWidget* parent) : _windowGeometry("WindowGeometry"), _windowState("WindowState", 0) { + setAttribute(Qt::WA_NoSystemBackground); setAcceptDrops(true); } diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.cpp b/plugins/openvr/src/OpenVrDisplayPlugin.cpp index 4eb371719b..76ca9abc79 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.cpp +++ b/plugins/openvr/src/OpenVrDisplayPlugin.cpp @@ -12,9 +12,12 @@ #include +#include + #include #include + #include #include #include @@ -56,7 +59,7 @@ public: using Condition = std::condition_variable; using Lock = std::unique_lock; friend class OpenVrDisplayPlugin; - std::shared_ptr _canvas; + std::shared_ptr _canvas; BasicFramebufferWrapperPtr _framebuffer; ProgramPtr _program; ShapeWrapperPtr _plane; @@ -129,7 +132,6 @@ public: void run() override { QThread::currentThread()->setPriority(QThread::Priority::TimeCriticalPriority); - assert(_canvas->thread() == QThread::currentThread()); _canvas->makeCurrent(); glDisable(GL_DEPTH_TEST); glViewport(0, 0, _plugin._renderTargetSize.x, _plugin._renderTargetSize.y); @@ -206,7 +208,6 @@ public: _program.reset(); _framebuffer.reset(); _canvas->doneCurrent(); - _canvas->moveToThreadWithContext(qApp->thread()); } void update(const CompositeInfo& newCompositeInfo) { @@ -309,14 +310,11 @@ bool OpenVrDisplayPlugin::internalActivate() { _submitThread = std::make_shared(*this); if (!_submitCanvas) { withMainThreadContext([&] { - _submitCanvas = std::make_shared(); - _submitCanvas->setObjectName("OpenVRSubmitContext"); - _submitCanvas->create(_container->getPrimaryContext()); + _submitCanvas = std::make_shared(); + _submitCanvas->create(); _submitCanvas->doneCurrent(); }); } - _submitCanvas->moveToThreadWithContext(_submitThread.get()); - assert(_submitCanvas->thread() == _submitThread.get()); #endif return Parent::internalActivate(); @@ -354,7 +352,6 @@ void OpenVrDisplayPlugin::customizeContext() { } _compositeInfos[i].textureID = getGLBackend()->getTextureID(_compositeInfos[i].texture, false); } - assert(_submitCanvas->thread() == _submitThread.get()); _submitThread->_canvas = _submitCanvas; _submitThread->start(QThread::HighPriority); #endif @@ -367,7 +364,6 @@ void OpenVrDisplayPlugin::uncustomizeContext() { _submitThread->_quit = true; _submitThread->wait(); _submitThread.reset(); - assert(_submitCanvas->thread() == qApp->thread()); #endif } diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.h b/plugins/openvr/src/OpenVrDisplayPlugin.h index 7b8869ae93..75f8c51b0e 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.h +++ b/plugins/openvr/src/OpenVrDisplayPlugin.h @@ -18,6 +18,9 @@ const float TARGET_RATE_OpenVr = 90.0f; // FIXME: get from sdk tracked device p #define OPENVR_THREADED_SUBMIT 1 #if OPENVR_THREADED_SUBMIT +namespace gl { + class OffscreenContext; +} class OpenVrSubmitThread; class OffscreenGLCanvas; static const size_t COMPOSITING_BUFFER_SIZE = 3; @@ -79,7 +82,7 @@ private: CompositeInfo::Array _compositeInfos; size_t _renderingIndex { 0 }; std::shared_ptr _submitThread; - std::shared_ptr _submitCanvas; + std::shared_ptr _submitCanvas; friend class OpenVrSubmitThread; #endif }; diff --git a/tests/gpu-test/src/TestWindow.cpp b/tests/gpu-test/src/TestWindow.cpp index 6917cf027f..791bed773e 100644 --- a/tests/gpu-test/src/TestWindow.cpp +++ b/tests/gpu-test/src/TestWindow.cpp @@ -73,7 +73,6 @@ void TestWindow::initGl() { DependencyManager::set(); resize(QSize(800, 600)); - GLDebug::setupLogger(this); #ifdef DEFERRED_LIGHTING auto deferredLightingEffect = DependencyManager::get(); deferredLightingEffect->init(); diff --git a/tests/render-perf/src/Camera.hpp b/tests/render-perf/src/Camera.hpp index fbae04540b..ebfcfb9e32 100644 --- a/tests/render-perf/src/Camera.hpp +++ b/tests/render-perf/src/Camera.hpp @@ -32,6 +32,9 @@ public: DOWN, BACK, FORWARD, + MLEFT, + MMIDDLE, + MRIGHT, KEYS_SIZE, INVALID = -1, }; diff --git a/tests/render-perf/src/main.cpp b/tests/render-perf/src/main.cpp index f7e6b6a6d2..fb78573e64 100644 --- a/tests/render-perf/src/main.cpp +++ b/tests/render-perf/src/main.cpp @@ -11,6 +11,9 @@ #include #include +#include +#include + #include #include #include @@ -27,12 +30,13 @@ #include #include + #include #include -#include -#include -#include +//#include +//#include +//#include #include #include @@ -61,6 +65,7 @@ #include "Camera.hpp" #include "TextOverlay.hpp" + static const QString LAST_SCENE_KEY = "lastSceneFile"; static const QString LAST_LOCATION_KEY = "lastLocation"; @@ -94,7 +99,56 @@ public: } }; +#if 0 +class GlfwCamera : public Camera { + Key forKey(int key) { + switch (key) { + case GLFW_KEY_W: return FORWARD; + case GLFW_KEY_S: return BACK; + case GLFW_KEY_A: return LEFT; + case GLFW_KEY_D: return RIGHT; + case GLFW_KEY_E: return UP; + case GLFW_KEY_C: return DOWN; + case GLFW_MOUSE_BUTTON_LEFT: return MLEFT; + case GLFW_MOUSE_BUTTON_RIGHT: return MRIGHT; + case GLFW_MOUSE_BUTTON_MIDDLE: return MMIDDLE; + default: break; + } + return INVALID; + } + vec2 _lastMouse; +public: + void keyHandler(int key, int scancode, int action, int mods) { + Key k = forKey(key); + if (k == INVALID) { + return; + } + if (action == GLFW_PRESS) { + keys.set(k); + } else if (action == GLFW_RELEASE) { + keys.reset(k); + } + } + + //static void MouseMoveHandler(GLFWwindow* window, double posx, double posy); + //static void MouseScrollHandler(GLFWwindow* window, double xoffset, double yoffset); + void onMouseMove(double posx, double posy) { + vec2 mouse = vec2(posx, posy); + vec2 delta = mouse - _lastMouse; + if (keys.at(Key::MRIGHT)) { + dolly(delta.y * 0.01f); + } else if (keys.at(Key::MLEFT)) { + rotate(delta.x * -0.01f); + } else if (keys.at(Key::MMIDDLE)) { + delta.y *= -1.0f; + translate(delta * -0.01f); + } + _lastMouse = mouse; + } + +}; +#else class QWindowCamera : public Camera { Key forKey(int key) { switch (key) { @@ -143,6 +197,7 @@ public: _lastMouse = mouse; } }; +#endif static QString toHumanSize(size_t size, size_t maxUnit = std::numeric_limits::max()) { static const std::vector SUFFIXES{ { "B", "KB", "MB", "GB", "TB", "PB" } }; @@ -175,8 +230,7 @@ extern QThread* RENDER_THREAD; class RenderThread : public GenericThread { using Parent = GenericThread; public: - QOpenGLContextWrapper* _displayContext{ nullptr }; - QSurface* _displaySurface{ nullptr }; + gl::Context _context; gpu::PipelinePointer _presentPipeline; gpu::ContextPointer _gpuContext; // initialized during window creation std::atomic _presentCount; @@ -198,38 +252,44 @@ public: } - void initialize(QOpenGLContextWrapper* displayContext, QWindow* surface) { + void initialize(QWindow* window, gl::Context& initContext) { setObjectName("RenderThread"); - _displayContext = displayContext; - _displaySurface = surface; - _displayContext->makeCurrent(_displaySurface); + _context.setWindow(window); + _context.create(); + _context.makeCurrent(); + window->setSurfaceType(QSurface::OpenGLSurface); + _context.makeCurrent(_context.qglContext(), window); +#ifdef Q_OS_WIN + wglSwapIntervalEXT(0); +#endif // GPU library init gpu::Context::init(); _gpuContext = std::make_shared(); _backend = _gpuContext->getBackend(); - _displayContext->makeCurrent(_displaySurface); + _context.makeCurrent(); DependencyManager::get()->init(); - _displayContext->doneCurrent(); + _context.makeCurrent(); + initContext.create(); + _context.doneCurrent(); std::unique_lock lock(_mutex); Parent::initialize(); - if (isThreaded()) { - _displayContext->moveToThread(thread()); - } + _context.moveToThread(_thread); } void setup() override { RENDER_THREAD = QThread::currentThread(); - QThread::currentThread()->setPriority(QThread::HighestPriority); + // Wait until the context has been moved to this thread { std::unique_lock lock(_mutex); } - _displayContext->makeCurrent(_displaySurface); + + _context.makeCurrent(); glewExperimental = true; glewInit(); glGetError(); - _frameTimes.resize(FRAME_TIME_BUFFER_SIZE, 0); + _frameTimes.resize(FRAME_TIME_BUFFER_SIZE, 0); { auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS(); auto ps = gpu::Shader::createPixel(std::string(SRGB_TO_LINEAR_FRAG)); @@ -254,14 +314,11 @@ public: } _presentPipeline.reset(); _gpuContext.reset(); - if (isThreaded()) { - _displayContext->moveToThread(qApp->thread()); - } } void renderFrame(gpu::FramePointer& frame) { ++_presentCount; - _displayContext->makeCurrent(_displaySurface); + _context.makeCurrent(); _backend->recycle(); _backend->syncCache(); if (frame && !frame->batches.empty()) { @@ -280,7 +337,8 @@ public: } (void)CHECK_GL_ERROR(); } - _displayContext->swapBuffers(_displaySurface); + _context.makeCurrent(); + _context.swapBuffers(); _fpsCounter.increment(); static size_t _frameCount{ 0 }; ++_frameCount; @@ -290,7 +348,7 @@ public: _elapsed.restart(); } (void)CHECK_GL_ERROR(); - _displayContext->doneCurrent(); + _context.doneCurrent(); } void report() { @@ -350,7 +408,6 @@ public: } }; - // Background Render Data & rendering functions class BackgroundRenderData { public: @@ -396,7 +453,6 @@ namespace render { // Create a simple OpenGL window that renders text in various ways class QTestWindow : public QWindow, public AbstractViewStateInterface { - Q_OBJECT protected: void copyCurrentViewFrustum(ViewFrustum& viewOut) const override { @@ -476,28 +532,47 @@ public: nodeList->setPermissions(permissions); ResourceManager::init(); - setSurfaceType(QSurface::OpenGLSurface); - auto format = getDefaultOpenGLSurfaceFormat(); - format.setOption(QSurfaceFormat::DebugContext); - setFormat(format); - resize(QSize(800, 600)); + setFlags(Qt::MSWindowsOwnDC); + _size = QSize(800, 600); + setGeometry(QRect(QPoint(), _size)); + create(); show(); + QCoreApplication::processEvents(); + // Create the initial context + _renderThread.initialize(this, _initContext); + _initContext.makeCurrent(); - _context.setFormat(format); - _context.create(); - _context.makeCurrent(this); - glewExperimental = true; - glewInit(); - glGetError(); +#if 0 + glfwInit(); + glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5); + glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + resizeWindow(QSize(800, 600)); + _window = glfwCreateWindow(_size.width(), _size.height(), "Window Title", NULL, NULL); + if (!_window) { + throw std::runtime_error("Could not create window"); + } + + glfwSetWindowUserPointer(_window, this); + glfwSetKeyCallback(_window, KeyboardHandler); + glfwSetMouseButtonCallback(_window, MouseHandler); + glfwSetCursorPosCallback(_window, MouseMoveHandler); + glfwSetWindowCloseCallback(_window, CloseHandler); + glfwSetFramebufferSizeCallback(_window, FramebufferSizeHandler); + glfwSetScrollCallback(_window, MouseScrollHandler); + + + glfwMakeContextCurrent(_window); GLDebug::setupLogger(this); +#endif + #ifdef Q_OS_WIN wglSwapIntervalEXT(0); #endif - _context.doneCurrent(); - _initContext.create(_context.getContext()); - _renderThread.initialize(&_context, this); // FIXME use a wait condition QThread::msleep(1000); _renderThread.submitFrame(gpu::FramePointer()); @@ -627,7 +702,7 @@ private: RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); auto framebufferCache = DependencyManager::get(); - QSize windowSize = size(); + QSize windowSize = _size; framebufferCache->setFrameBufferSize(windowSize); renderArgs._blitFramebuffer = framebufferCache->getFramebuffer(); @@ -676,11 +751,11 @@ private: }; void updateText() { - setTitle(QString("FPS %1 Culling %2 TextureMemory GPU %3 CPU %4") + QString title = QString("FPS %1 Culling %2 TextureMemory GPU %3 CPU %4") .arg(_fps).arg(_cullingEnabled) .arg(toHumanSize(gpu::Context::getTextureGPUMemoryUsage(), 2)) - .arg(toHumanSize(gpu::Texture::getTextureCPUMemoryUsage(), 2))); - + .arg(toHumanSize(gpu::Texture::getTextureCPUMemoryUsage(), 2)); + setTitle(title); #if 0 { _textBlocks.erase(TextBlock::Info); @@ -801,12 +876,6 @@ private: } - bool makeCurrent() { - bool currentResult = _context.makeCurrent(this); - Q_ASSERT(currentResult); - return currentResult; - } - void resizeWindow(const QSize& size) { _size = size; _camera.setAspectRatio((float)_size.width() / (float)_size.height()); @@ -960,12 +1029,11 @@ private: render::EnginePointer _renderEngine { new render::Engine() }; render::ScenePointer _main3DScene { new render::Scene(glm::vec3(-0.5f * (float)TREE_SCALE), (float)TREE_SCALE) }; - QOpenGLContextWrapper _context; QSize _size; QSettings _settings; std::atomic _renderCount; - OffscreenGLCanvas _initContext; + gl::OffscreenContext _initContext; RenderThread _renderThread; QWindowCamera _camera; ViewFrustum _viewFrustum; // current state of view frustum, perspective, orientation, etc. diff --git a/tests/render-utils/src/main.cpp b/tests/render-utils/src/main.cpp index 4b7354f35d..c38bd6765c 100644 --- a/tests/render-utils/src/main.cpp +++ b/tests/render-utils/src/main.cpp @@ -112,8 +112,6 @@ public: gpu::Context::init(); - - GLDebug::setupLogger(this); qDebug() << (const char*)glGetString(GL_VERSION); //_textRenderer[0] = TextRenderer::getInstance(SANS_FONT_FAMILY, 12, false); diff --git a/tests/shaders/src/main.cpp b/tests/shaders/src/main.cpp index 5355f29f19..9744d8c78d 100644 --- a/tests/shaders/src/main.cpp +++ b/tests/shaders/src/main.cpp @@ -108,9 +108,7 @@ public: show(); makeCurrent(); - gpu::Context::init(); - GLDebug::setupLogger(this); makeCurrent(); resize(QSize(800, 600)); } From 179e3565ef18a7f668484b3b2e82158b76f3a886 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Sat, 27 Aug 2016 15:08:01 -0700 Subject: [PATCH 4/5] More render-perf tweaks --- tests/render-perf/src/main.cpp | 79 +++++++++++++++++++++++++--------- 1 file changed, 59 insertions(+), 20 deletions(-) diff --git a/tests/render-perf/src/main.cpp b/tests/render-perf/src/main.cpp index fb78573e64..c6cca74c69 100644 --- a/tests/render-perf/src/main.cpp +++ b/tests/render-perf/src/main.cpp @@ -244,6 +244,7 @@ public: std::mutex _frameLock; std::queue _pendingFrames; gpu::FramePointer _activeFrame; + QSize _size; static const size_t FRAME_TIME_BUFFER_SIZE{ 8192 }; void submitFrame(const gpu::FramePointer& frame) { @@ -325,8 +326,10 @@ public: _gpuContext->executeFrame(frame); { + auto geometryCache = DependencyManager::get(); gpu::Batch presentBatch; + presentBatch.setViewportTransform({ 0, 0, _size.width(), _size.height() }); presentBatch.enableStereo(false); presentBatch.resetViewTransform(); presentBatch.setFramebuffer(gpu::FramebufferPointer()); @@ -523,7 +526,8 @@ public: _octree->init(); // Prevent web entities from rendering REGISTER_ENTITY_TYPE_WITH_FACTORY(Web, WebEntityItem::factory); - + REGISTER_ENTITY_TYPE_WITH_FACTORY(Light, LightEntityItem::factory); + DependencyManager::set(_octree->getTree()); getEntities()->setViewFrustum(_viewFrustum); auto nodeList = DependencyManager::get(); @@ -533,8 +537,9 @@ public: ResourceManager::init(); - setFlags(Qt::MSWindowsOwnDC); + setFlags(Qt::MSWindowsOwnDC | Qt::Window | Qt::Dialog | Qt::WindowMinMaxButtonsHint | Qt::WindowTitleHint); _size = QSize(800, 600); + _renderThread._size = _size; setGeometry(QRect(QPoint(), _size)); create(); show(); @@ -570,7 +575,7 @@ public: #endif #ifdef Q_OS_WIN - wglSwapIntervalEXT(0); + //wglSwapIntervalEXT(0); #endif // FIXME use a wait condition @@ -634,7 +639,7 @@ protected: return; case Qt::Key_F4: - toggleStereo(); + cycleMode(); return; case Qt::Key_F5: @@ -701,27 +706,43 @@ private: 0, RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); - auto framebufferCache = DependencyManager::get(); + QSize windowSize = _size; - framebufferCache->setFrameBufferSize(windowSize); - - renderArgs._blitFramebuffer = framebufferCache->getFramebuffer(); - // Viewport is assigned to the size of the framebuffer - renderArgs._viewport = ivec4(0, 0, windowSize.width(), windowSize.height()); - - renderArgs.setViewFrustum(_viewFrustum); - - renderArgs._context->enableStereo(_stereoEnabled); - if (_stereoEnabled) { + if (_renderMode == NORMAL) { + renderArgs._context->enableStereo(false); + } else { + renderArgs._context->enableStereo(true); mat4 eyeOffsets[2]; mat4 eyeProjections[2]; - for (size_t i = 0; i < 2; ++i) { - eyeProjections[i] = _viewFrustum.getProjection(); + if (_renderMode == STEREO) { + for (size_t i = 0; i < 2; ++i) { + eyeProjections[i] = _viewFrustum.getProjection(); + } + } else if (_renderMode == HMD) { + eyeOffsets[0][3] = vec4 { -0.0327499993, 0.0, 0.0149999997, 1.0 }; + eyeOffsets[1][3] = vec4 { 0.0327499993, 0.0, 0.0149999997, 1.0 }; + eyeProjections[0][0] = vec4 { 0.759056330, 0.000000000, 0.000000000, 0.000000000 }; + eyeProjections[0][1] = vec4 { 0.000000000, 0.682773232, 0.000000000, 0.000000000 }; + eyeProjections[0][2] = vec4 { -0.0580431037, -0.00619550655, -1.00000489, -1.00000000 }; + eyeProjections[0][3] = vec4 { 0.000000000, 0.000000000, -0.0800003856, 0.000000000 }; + eyeProjections[1][0] = vec4 { 0.752847493, 0.000000000, 0.000000000, 0.000000000 }; + eyeProjections[1][1] = vec4 { 0.000000000, 0.678060353, 0.000000000, 0.000000000 }; + eyeProjections[1][2] = vec4 { 0.0578232110, -0.00669418881, -1.00000489, -1.000000000 }; + eyeProjections[1][3] = vec4 { 0.000000000, 0.000000000, -0.0800003856, 0.000000000 }; + windowSize = { 2048, 2048 }; } renderArgs._context->setStereoProjections(eyeProjections); renderArgs._context->setStereoViews(eyeOffsets); } + auto framebufferCache = DependencyManager::get(); + framebufferCache->setFrameBufferSize(windowSize); + + renderArgs._blitFramebuffer = framebufferCache->getFramebuffer(); + // Viewport is assigned to the size of the framebuffer + renderArgs._viewport = ivec4(0, 0, windowSize.width(), windowSize.height()); + renderArgs.setViewFrustum(_viewFrustum); + // Final framebuffer that will be handled to the display-plugin render(&renderArgs); @@ -882,6 +903,7 @@ private: if (!_ready) { return; } + _renderThread._size = size; //_textOverlay->resize(toGlm(_size)); //glViewport(0, 0, size.width(), size.height()); } @@ -997,8 +1019,18 @@ private: _cullingEnabled = !_cullingEnabled; } - void toggleStereo() { - _stereoEnabled = !_stereoEnabled; + void cycleMode() { + static auto defaultProjection = Camera().matrices.perspective; + _renderMode = (RenderMode)((_renderMode + 1) % RENDER_MODE_COUNT); + if (_renderMode == HMD) { + _camera.matrices.perspective[0] = vec4 { 0.759056330, 0.000000000, 0.000000000, 0.000000000 }; + _camera.matrices.perspective[1] = vec4 { 0.000000000, 0.682773232, 0.000000000, 0.000000000 }; + _camera.matrices.perspective[2] = vec4 { -0.0580431037, -0.00619550655, -1.00000489, -1.00000000 }; + _camera.matrices.perspective[3] = vec4 { 0.000000000, 0.000000000, -0.0800003856, 0.000000000 }; + } else { + _camera.matrices.perspective = defaultProjection; + _camera.setAspectRatio((float)_size.width() / (float)_size.height()); + } } QSharedPointer getEntities() { @@ -1043,7 +1075,14 @@ private: bool _ready { false }; //TextOverlay* _textOverlay; static bool _cullingEnabled; - bool _stereoEnabled { false }; + + enum RenderMode { + NORMAL = 0, + STEREO, + HMD, + RENDER_MODE_COUNT + }; + RenderMode _renderMode { NORMAL }; QSharedPointer _octree; }; From cceae50b902722244169e93c3fd125c805b4aa4d Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 29 Aug 2016 14:28:05 -0700 Subject: [PATCH 5/5] no more delete with backspace --- scripts/system/edit.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index 1a50fb0d8b..958d15d9bf 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -803,7 +803,7 @@ function setupModelMenus() { menuName: "Edit", menuItemName: "Delete", shortcutKeyEvent: { - text: "backspace" + text: "delete" }, afterItem: "Entities", grouping: "Advanced" @@ -1215,7 +1215,7 @@ Controller.keyReleaseEvent.connect(function (event) { cameraManager.keyReleaseEvent(event); } // since sometimes our menu shortcut keys don't work, trap our menu items here also and fire the appropriate menu items - if (event.text === "BACKSPACE" || event.text === "DELETE") { + if (event.text === "DELETE") { deleteSelectedEntities(); } else if (event.text === "ESC") { selectionManager.clearSelections();